From 4fa5ecfe34e238eaa59c90f83a503e861523873a Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Thu, 25 Apr 2024 15:06:55 -0400 Subject: [PATCH 01/17] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 266563e4..0cf91af1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: - name: Upload coverage uses: codecov/codecov-action@v4 with: - fail_ci_if_error: true + fail_ci_if_error: false token: ${{ secrets.CODECOV_TOKEN }} test-code-examples: name: Check typedocs From dde56ad5beb25131f8b44e5b770e64ec453a8f89 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Thu, 25 Apr 2024 16:47:45 -0400 Subject: [PATCH 02/17] Update test.yml --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0cf91af1..e4174a6e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: types: [opened, reopened, synchronize] branches: - dev + - main push: branches: - dev From 9353d33435997698f9f3a25ee43a383745657711 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Thu, 25 Apr 2024 17:05:51 -0400 Subject: [PATCH 03/17] Less verbose unit types (#1181) Co-authored-by: IntGrah --- Tone/core/type/NoteUnits.ts | 34 ++++++++++------------------------ Tone/core/type/Time.ts | 2 +- Tone/core/type/Units.ts | 7 ++----- Tone/core/util/TypeCheck.ts | 16 ++++++++-------- 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/Tone/core/type/NoteUnits.ts b/Tone/core/type/NoteUnits.ts index f3215afa..c6f4cd46 100644 --- a/Tone/core/type/NoteUnits.ts +++ b/Tone/core/type/NoteUnits.ts @@ -1,4 +1,8 @@ -// this file contains all of the valid note names for all pitches between C-4 and C11 +// This file contains all of the valid note names for all pitches between C-4 and C11 + +type Letter = "C" | "D" | "E" | "F" | "G" | "A" | "B"; +type Accidental = "bb" | "b" | "" | "#" | "x"; +type Octave = -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; /** * A note in Scientific pitch notation. @@ -6,31 +10,13 @@ * e.g. "C4", "D#3", "G-1" * @category Unit */ -export type Note = "Cbb-4" | "Cb-4" | "C-4" | "C#-4" | "Cx-4" | "Dbb-4" | "Db-4" | "D-4" | "D#-4" | "Dx-4" | "Ebb-4" | "Eb-4" | "E-4" | "E#-4" | "Ex-4" | "Fbb-4" | "Fb-4" | "F-4" | "F#-4" | "Fx-4" | "Gbb-4" | "Gb-4" | "G-4" | "G#-4" | "Gx-4" | "Abb-4" | "Ab-4" | "A-4" | "A#-4" | "Ax-4" | "Bbb-4" | "Bb-4" | "B-4" | "B#-4" | "Bx-4" | -"Cbb-3" | "Cb-3" | "C-3" | "C#-3" | "Cx-3" | "Dbb-3" | "Db-3" | "D-3" | "D#-3" | "Dx-3" | "Ebb-3" | "Eb-3" | "E-3" | "E#-3" | "Ex-3" | "Fbb-3" | "Fb-3" | "F-3" | "F#-3" | "Fx-3" | "Gbb-3" | "Gb-3" | "G-3" | "G#-3" | "Gx-3" | "Abb-3" | "Ab-3" | "A-3" | "A#-3" | "Ax-3" | "Bbb-3" | "Bb-3" | "B-3" | "B#-3" | "Bx-3" | -"Cbb-2" | "Cb-2" | "C-2" | "C#-2" | "Cx-2" | "Dbb-2" | "Db-2" | "D-2" | "D#-2" | "Dx-2" | "Ebb-2" | "Eb-2" | "E-2" | "E#-2" | "Ex-2" | "Fbb-2" | "Fb-2" | "F-2" | "F#-2" | "Fx-2" | "Gbb-2" | "Gb-2" | "G-2" | "G#-2" | "Gx-2" | "Abb-2" | "Ab-2" | "A-2" | "A#-2" | "Ax-2" | "Bbb-2" | "Bb-2" | "B-2" | "B#-2" | "Bx-2" | -"Cbb-1" | "Cb-1" | "C-1" | "C#-1" | "Cx-1" | "Dbb-1" | "Db-1" | "D-1" | "D#-1" | "Dx-1" | "Ebb-1" | "Eb-1" | "E-1" | "E#-1" | "Ex-1" | "Fbb-1" | "Fb-1" | "F-1" | "F#-1" | "Fx-1" | "Gbb-1" | "Gb-1" | "G-1" | "G#-1" | "Gx-1" | "Abb-1" | "Ab-1" | "A-1" | "A#-1" | "Ax-1" | "Bbb-1" | "Bb-1" | "B-1" | "B#-1" | "Bx-1" | -"Cbb0" | "Cb0" | "C0" | "C#0" | "Cx0" | "Dbb0" | "Db0" | "D0" | "D#0" | "Dx0" | "Ebb0" | "Eb0" | "E0" | "E#0" | "Ex0" | "Fbb0" | "Fb0" | "F0" | "F#0" | "Fx0" | "Gbb0" | "Gb0" | "G0" | "G#0" | "Gx0" | "Abb0" | "Ab0" | "A0" | "A#0" | "Ax0" | "Bbb0" | "Bb0" | "B0" | "B#0" | "Bx0" | -"Cbb1" | "Cb1" | "C1" | "C#1" | "Cx1" | "Dbb1" | "Db1" | "D1" | "D#1" | "Dx1" | "Ebb1" | "Eb1" | "E1" | "E#1" | "Ex1" | "Fbb1" | "Fb1" | "F1" | "F#1" | "Fx1" | "Gbb1" | "Gb1" | "G1" | "G#1" | "Gx1" | "Abb1" | "Ab1" | "A1" | "A#1" | "Ax1" | "Bbb1" | "Bb1" | "B1" | "B#1" | "Bx1" | -"Cbb2" | "Cb2" | "C2" | "C#2" | "Cx2" | "Dbb2" | "Db2" | "D2" | "D#2" | "Dx2" | "Ebb2" | "Eb2" | "E2" | "E#2" | "Ex2" | "Fbb2" | "Fb2" | "F2" | "F#2" | "Fx2" | "Gbb2" | "Gb2" | "G2" | "G#2" | "Gx2" | "Abb2" | "Ab2" | "A2" | "A#2" | "Ax2" | "Bbb2" | "Bb2" | "B2" | "B#2" | "Bx2" | -"Cbb3" | "Cb3" | "C3" | "C#3" | "Cx3" | "Dbb3" | "Db3" | "D3" | "D#3" | "Dx3" | "Ebb3" | "Eb3" | "E3" | "E#3" | "Ex3" | "Fbb3" | "Fb3" | "F3" | "F#3" | "Fx3" | "Gbb3" | "Gb3" | "G3" | "G#3" | "Gx3" | "Abb3" | "Ab3" | "A3" | "A#3" | "Ax3" | "Bbb3" | "Bb3" | "B3" | "B#3" | "Bx3" | -"Cbb4" | "Cb4" | "C4" | "C#4" | "Cx4" | "Dbb4" | "Db4" | "D4" | "D#4" | "Dx4" | "Ebb4" | "Eb4" | "E4" | "E#4" | "Ex4" | "Fbb4" | "Fb4" | "F4" | "F#4" | "Fx4" | "Gbb4" | "Gb4" | "G4" | "G#4" | "Gx4" | "Abb4" | "Ab4" | "A4" | "A#4" | "Ax4" | "Bbb4" | "Bb4" | "B4" | "B#4" | "Bx4" | -"Cbb5" | "Cb5" | "C5" | "C#5" | "Cx5" | "Dbb5" | "Db5" | "D5" | "D#5" | "Dx5" | "Ebb5" | "Eb5" | "E5" | "E#5" | "Ex5" | "Fbb5" | "Fb5" | "F5" | "F#5" | "Fx5" | "Gbb5" | "Gb5" | "G5" | "G#5" | "Gx5" | "Abb5" | "Ab5" | "A5" | "A#5" | "Ax5" | "Bbb5" | "Bb5" | "B5" | "B#5" | "Bx5" | -"Cbb6" | "Cb6" | "C6" | "C#6" | "Cx6" | "Dbb6" | "Db6" | "D6" | "D#6" | "Dx6" | "Ebb6" | "Eb6" | "E6" | "E#6" | "Ex6" | "Fbb6" | "Fb6" | "F6" | "F#6" | "Fx6" | "Gbb6" | "Gb6" | "G6" | "G#6" | "Gx6" | "Abb6" | "Ab6" | "A6" | "A#6" | "Ax6" | "Bbb6" | "Bb6" | "B6" | "B#6" | "Bx6" | -"Cbb7" | "Cb7" | "C7" | "C#7" | "Cx7" | "Dbb7" | "Db7" | "D7" | "D#7" | "Dx7" | "Ebb7" | "Eb7" | "E7" | "E#7" | "Ex7" | "Fbb7" | "Fb7" | "F7" | "F#7" | "Fx7" | "Gbb7" | "Gb7" | "G7" | "G#7" | "Gx7" | "Abb7" | "Ab7" | "A7" | "A#7" | "Ax7" | "Bbb7" | "Bb7" | "B7" | "B#7" | "Bx7" | -"Cbb8" | "Cb8" | "C8" | "C#8" | "Cx8" | "Dbb8" | "Db8" | "D8" | "D#8" | "Dx8" | "Ebb8" | "Eb8" | "E8" | "E#8" | "Ex8" | "Fbb8" | "Fb8" | "F8" | "F#8" | "Fx8" | "Gbb8" | "Gb8" | "G8" | "G#8" | "Gx8" | "Abb8" | "Ab8" | "A8" | "A#8" | "Ax8" | "Bbb8" | "Bb8" | "B8" | "B#8" | "Bx8" | -"Cbb9" | "Cb9" | "C9" | "C#9" | "Cx9" | "Dbb9" | "Db9" | "D9" | "D#9" | "Dx9" | "Ebb9" | "Eb9" | "E9" | "E#9" | "Ex9" | "Fbb9" | "Fb9" | "F9" | "F#9" | "Fx9" | "Gbb9" | "Gb9" | "G9" | "G#9" | "Gx9" | "Abb9" | "Ab9" | "A9" | "A#9" | "Ax9" | "Bbb9" | "Bb9" | "B9" | "B#9" | "Bx9" | -"Cbb10" | "Cb10" | "C10" | "C#10" | "Cx10" | "Dbb10" | "Db10" | "D10" | "D#10" | "Dx10" | "Ebb10" | "Eb10" | "E10" | "E#10" | "Ex10" | "Fbb10" | "Fb10" | "F10" | "F#10" | "Fx10" | "Gbb10" | "Gb10" | "G10" | "G#10" | "Gx10" | "Abb10" | "Ab10" | "A10" | "A#10" | "Ax10" | "Bbb10" | "Bb10" | "B10" | "B#10" | "Bx10" | -"Cbb11" | "Cb11" | "C11" | "C#11" | "Cx11" | "Dbb11" | "Db11" | "D11" | "D#11" | "Dx11" | "Ebb11" | "Eb11" | "E11" | "E#11" | "Ex11" | "Fbb11" | "Fb11" | "F11" | "F#11" | "Fx11" | "Gbb11" | "Gb11" | "G11" | "G#11" | "Gx11" | "Abb11" | "Ab11" | "A11" | "A#11" | "Ax11" | "Bbb11" | "Bb11" | "B11" | "B#11" | "Bx11"; +export type Note = `${Letter}${Accidental}${Octave}`; + +type IntegerRange = + A["length"] extends N ? A[number] : IntegerRange; /** * A number representing a midi note. Integers between 0-127 * @category Unit */ -export type MidiNote = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -121 | 122 | 123 | 124 | 125 | 126 | 127; +export type MidiNote = IntegerRange<128>; diff --git a/Tone/core/type/Time.ts b/Tone/core/type/Time.ts index 1af83730..474d5b9f 100644 --- a/Tone/core/type/Time.ts +++ b/Tone/core/type/Time.ts @@ -104,7 +104,7 @@ export class TimeClass(arg: T | undefined): arg is T { - return !isUndef(arg); + return arg !== undefined; } /** @@ -25,35 +25,35 @@ export function isFunction(arg: any): arg is (a: any) => any { * Test if the argument is a number. */ export function isNumber(arg: any): arg is number { - return (typeof arg === "number"); + return typeof arg === "number"; } /** * Test if the given argument is an object literal (i.e. `{}`); */ export function isObject(arg: any): arg is object { - return (Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object); + return Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object; } /** * Test if the argument is a boolean. */ export function isBoolean(arg: any): arg is boolean { - return (typeof arg === "boolean"); + return typeof arg === "boolean"; } /** * Test if the argument is an Array */ export function isArray(arg: any): arg is any[] { - return (Array.isArray(arg)); + return Array.isArray(arg); } /** * Test if the argument is a string. */ export function isString(arg: any): arg is string { - return (typeof arg === "string"); + return typeof arg === "string"; } /** @@ -61,5 +61,5 @@ export function isString(arg: any): arg is string { * e.g. "C4" */ export function isNote(arg: any): arg is Note { - return isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg); + return isString(arg) && /^([a-g](?:b|#|x|bb)?)(-[4321]|[0-9]|10|11)$/.test(arg); } From 7882bed0668953b945b2b4be3de1c86773bd04b0 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Thu, 25 Apr 2024 17:19:50 -0400 Subject: [PATCH 04/17] reverting isNote test, fixing workflow --- .github/workflows/publish.yml | 33 --------------------------------- .github/workflows/test.yml | 30 +++++++++++++++++++++++++++++- Tone/core/util/TypeCheck.ts | 7 +++++-- 3 files changed, 34 insertions(+), 36 deletions(-) delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 6577cce0..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Publish -on: - workflow_run: - workflows: ["Tests"] - types: - - completed -jobs: - publish: - runs-on: ubuntu-latest - # not on PRs - if: github.event_name != 'pull_request' - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - GITHUB_CI: true - steps: - - uses: actions/checkout@v4 - # Setup .npmrc file to publish to npm - - uses: actions/setup-node@v4 - with: - node-version: 18.12.0 - registry-url: 'https://registry.npmjs.org' - - name: Install dependencies - run: npm install - - name: Build - run: npm run build - - name: Increment version - run: npm run increment - - name: Publish @next - run: npm publish --tag next - if: ${{ github.ref == 'refs/heads/dev' }} - - name: Publish @latest - run: npm publish - if: ${{ github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4174a6e..8a7265a2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -116,4 +116,32 @@ jobs: - name: Build run: npm run build - name: Test - run: npm run test:readme \ No newline at end of file + run: npm run test:readme + publish: + runs-on: ubuntu-latest + # make sure all the tests pass first + needs: [run-tests, test-code-examples, test-html-examples, test-lint] + # not on PRs + if: github.event_name != 'pull_request' + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_CI: true + steps: + - uses: actions/checkout@v4 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v4 + with: + node-version: 18.12.0 + registry-url: 'https://registry.npmjs.org' + - name: Install dependencies + run: npm install + - name: Build + run: npm run build + - name: Increment version + run: npm run increment + - name: Publish @next + run: npm publish --tag next + if: ${{ github.ref == 'refs/heads/dev' }} + - name: Publish @latest + run: npm publish + if: ${{ github.ref == 'refs/heads/main' }} diff --git a/Tone/core/util/TypeCheck.ts b/Tone/core/util/TypeCheck.ts index 204d4db0..f0e76a7a 100644 --- a/Tone/core/util/TypeCheck.ts +++ b/Tone/core/util/TypeCheck.ts @@ -32,7 +32,10 @@ export function isNumber(arg: any): arg is number { * Test if the given argument is an object literal (i.e. `{}`); */ export function isObject(arg: any): arg is object { - return Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object; + return ( + Object.prototype.toString.call(arg) === "[object Object]" && + arg.constructor === Object + ); } /** @@ -61,5 +64,5 @@ export function isString(arg: any): arg is string { * e.g. "C4" */ export function isNote(arg: any): arg is Note { - return isString(arg) && /^([a-g](?:b|#|x|bb)?)(-[4321]|[0-9]|10|11)$/.test(arg); + return isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg); } From d0b874bfca4d05cfe387c3f94ef7a3a078b3bcf5 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Thu, 25 Apr 2024 17:30:56 -0400 Subject: [PATCH 05/17] fixing job dependencies --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8a7265a2..96d4762f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,7 +120,7 @@ jobs: publish: runs-on: ubuntu-latest # make sure all the tests pass first - needs: [run-tests, test-code-examples, test-html-examples, test-lint] + needs: [run-tests, test-code-examples, test-html-examples, test-lint, test-readme] # not on PRs if: github.event_name != 'pull_request' env: From 3d42017f50cbc9682c2532bf4fec7f1735a98335 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Sun, 28 Apr 2024 13:05:26 -0400 Subject: [PATCH 06/17] Deprecating singleton variables, use singleton getter instead (#1233) * Deprecating singleton variables, use singleton getter instead * updating references * moving over to getters instead of global vars --- .github/workflows/test.yml | 2 + README.md | 33 +++-- Tone/core/clock/Transport.test.ts | 120 +++++++++---------- Tone/core/clock/Transport.ts | 44 +++---- Tone/core/clock/TransportEvent.test.ts | 8 +- Tone/core/clock/TransportEvent.ts | 4 +- Tone/core/clock/TransportRepeatEvent.test.ts | 8 +- Tone/core/clock/TransportRepeatEvent.ts | 2 +- Tone/core/context/BaseContext.ts | 8 +- Tone/core/context/Context.test.ts | 16 +-- Tone/core/context/Context.ts | 8 +- Tone/core/context/Destination.test.ts | 4 +- Tone/core/context/Destination.ts | 8 +- Tone/core/context/DummyContext.ts | 8 +- Tone/core/context/Listener.test.ts | 4 +- Tone/core/context/Listener.ts | 4 +- Tone/core/context/ToneWithContext.ts | 4 +- Tone/core/util/Draw.test.ts | 4 +- Tone/core/util/Draw.ts | 4 +- Tone/core/util/IntervalTimeline.ts | 1 + Tone/core/util/StateTimeline.ts | 1 + Tone/core/util/Timeline.ts | 1 + Tone/fromContext.ts | 16 +-- Tone/index.test.ts | 18 +-- Tone/index.ts | 34 ++++-- Tone/signal/SyncedSignal.ts | 3 +- scripts/typedoc.json | 2 + 27 files changed, 190 insertions(+), 179 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 96d4762f..00d22930 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -140,8 +140,10 @@ jobs: - name: Increment version run: npm run increment - name: Publish @next + # dev branch gets published with @next tag run: npm publish --tag next if: ${{ github.ref == 'refs/heads/dev' }} - name: Publish @latest + # main branch gets published with @latest tag run: npm publish if: ${{ github.ref == 'refs/heads/main' }} diff --git a/README.md b/README.md index a9f23908..1fb8534c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Tone.js is a Web Audio framework for creating interactive music in the browser. * [API](https://tonejs.github.io/docs/) * [Examples](https://tonejs.github.io/examples/) -* [Demos](https://tonejs.github.io/demos) # Installation @@ -29,7 +28,6 @@ Tone.js is also hosted at unpkg.com. It can be added directly within an HTML doc ```html - ``` # Hello Tone @@ -44,7 +42,7 @@ synth.triggerAttackRelease("C4", "8n"); #### Tone.Synth -[Tone.Synth](https://tonejs.github.io/docs/Synth) is a basic synthesizer with a single [oscillator](https://tonejs.github.io/docs/OmniOscillator) and an [ADSR envelope](https://tonejs.github.io/docs/Envelope). +`Tone.Synth` is a basic synthesizer with a single oscillator and an ADSR envelope. #### triggerAttack / triggerRelease @@ -109,9 +107,9 @@ document.querySelector('button')?.addEventListener('click', async () => { ### Transport -[Tone.Transport](https://tonejs.github.io/docs/Transport) is the main timekeeper. Unlike the AudioContext clock, it can be started, stopped, looped and adjusted on the fly. You can think of it like the arrangement view in a Digital Audio Workstation or channels in a Tracker. +`Tone.getTransport()` returns the main timekeeper. Unlike the AudioContext clock, it can be started, stopped, looped and adjusted on the fly. You can think of it like the arrangement view in a Digital Audio Workstation. -Multiple events and parts can be arranged and synchronized along the Transport. [Tone.Loop](https://tonejs.github.io/docs/Loop) is a simple way to create a looped callback that can be scheduled to start and stop. +Multiple events and parts can be arranged and synchronized along the Transport. `Tone.Loop` is a simple way to create a looped callback that can be scheduled to start and stop. ```javascript // create two monophonic synths @@ -125,19 +123,19 @@ const loopA = new Tone.Loop(time => { const loopB = new Tone.Loop(time => { synthB.triggerAttackRelease("C4", "8n", time); }, "4n").start("8n"); -// all loops start until the Transport is started -Tone.Transport.start() +// all loops start when the Transport is started +Tone.getTransport().start() ``` Since Javascript callbacks are **not precisely timed**, the sample-accurate time of the event is passed into the callback function. **Use this time value to schedule the events**. # Instruments -There are numerous synths to choose from including [Tone.FMSynth](https://tonejs.github.io/docs/FMSynth), [Tone.AMSynth](https://tonejs.github.io/docs/AMSynth) and [Tone.NoiseSynth](https://tonejs.github.io/docs/NoiseSynth). +There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`. All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time. -To create a **polyphonic** synthesizer, use [Tone.PolySynth](https://tonejs.github.io/docs/PolySynth), which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes. +To create a **polyphonic** synthesizer, use `Tone.PolySynth`, which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes. ```javascript //pass in some initial values for the filter and filter envelope @@ -153,7 +151,7 @@ synth.triggerRelease(["D4", "F4", "A4", "C4", "E4"], now + 4); # Samples -Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. [Tone.Player](https://tonejs.github.io/docs/Player) is one way to load and play back an audio file. +Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. `Tone.Player` is one way to load and play back an audio file. ```javascript const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination(); @@ -166,7 +164,7 @@ Tone.loaded().then(() => { ## Sampler -Multiple samples can also be combined into an instrument. If you have audio files organized by note, [Tone.Sampler](https://tonejs.github.io/docs/Sampler) will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample. +Multiple samples can also be combined into an instrument. If you have audio files organized by note, `Tone.Sampler` will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample. Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth @@ -188,7 +186,7 @@ Tone.loaded().then(() => { # Effects -In the above examples, the sources were always connected directly to the [Destination](https://tonejs.github.io/docs/Destination), but the output of the synth could also be routed through one (or more) effects before going to the speakers. +In the above examples, the sources were always connected directly to the `Destination`, but the output of the synth could also be routed through one (or more) effects before going to the speakers. ```javascript const player = new Tone.Player({ @@ -204,15 +202,15 @@ player.connect(distortion); The connection routing is very flexible. For example, you can connect multiple sources to the same effect and then route the effect through a network of other effects either serially or in parallel. -[Tone.Gain](https://tonejs.github.io/docs/Gain) is very useful in creating complex routing. +`Tone.Gain` is very useful in creating complex routing. # Signals Like the underlying Web Audio API, Tone.js is built with audio-rate signal control over nearly everything. This is a powerful feature which allows for sample-accurate synchronization and scheduling of parameters. -[Signal](https://tonejs.github.io/docs/Signal) properties have a few built in methods for creating automation curves. +`Signal` properties have a few built in methods for creating automation curves. -For example, the `frequency` parameter on [Oscillator](https://tonejs.github.io/docs/Signal) is a Signal so you can create a smooth ramp from one frequency to another. +For example, the `frequency` parameter on `Oscillator` is a Signal so you can create a smooth ramp from one frequency to another. ```javascript const osc = new Tone.Oscillator().toDestination(); @@ -224,7 +222,7 @@ osc.frequency.rampTo("C5", 2) # AudioContext -Tone.js creates an AudioContext when it loads and shims it for maximum browser compatibility using [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context). The AudioContext can be accessed at `Tone.context`. Or set your own AudioContext using `Tone.setContext(audioContext)`. +Tone.js creates an AudioContext when it loads and shims it for maximum browser compatibility using [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context). The AudioContext can be accessed at `Tone.getContext`. Or set your own AudioContext using `Tone.setContext(audioContext)`. # MIDI @@ -238,7 +236,7 @@ Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode a # Testing -Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Each commit and pull request is run on [Travis-CI](https://app.travis-ci.com/github/Tonejs/Tone.js) across browsers and versions. Passing builds on the 'dev' branch are published on npm as `tone@next`. +Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Passing builds on the 'dev' branch are published on npm as `tone@next`. # Contributing @@ -248,7 +246,6 @@ If you have questions (or answers) that are not necessarily bugs/issues, please # References and Inspiration -* [Tuna.js](https://github.com/Dinahmoe/tuna) * [Many of Chris Wilson's Repositories](https://github.com/cwilso) * [Many of Mohayonao's Repositories](https://github.com/mohayonao) * [The Spec](http://webaudio.github.io/web-audio-api/) diff --git a/Tone/core/clock/Transport.test.ts b/Tone/core/clock/Transport.test.ts index 3c7039f9..493598ed 100644 --- a/Tone/core/clock/Transport.test.ts +++ b/Tone/core/clock/Transport.test.ts @@ -4,7 +4,7 @@ import { Time } from "Tone/core/type/Time"; import { noOp } from "Tone/core/util/Interface"; import { Signal } from "../../signal/Signal"; import { TransportTime } from "../type/TransportTime"; -import { Transport } from "./Transport"; +import { TransportClass } from "./Transport"; // importing for side affects import "../context/Destination"; import { warns } from "test/helper/Basic"; @@ -16,7 +16,7 @@ describe("Transport", () => { it("can get and set bpm", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.bpm.value = 125; expect(transport.bpm.value).to.be.closeTo(125, 0.001); transport.bpm.value = 120; @@ -26,7 +26,7 @@ describe("Transport", () => { it("can get and set timeSignature as both an array or number", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.timeSignature = [6, 8]; expect(transport.timeSignature).to.equal(3); transport.timeSignature = 5; @@ -36,7 +36,7 @@ describe("Transport", () => { it("can get and set timeSignature as both an array or number", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.timeSignature = [6, 8]; expect(transport.timeSignature).to.equal(3); transport.timeSignature = 5; @@ -50,7 +50,7 @@ describe("Transport", () => { it("can get and set loop points", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.loopStart = 0.2; transport.loopEnd = 0.4; expect(transport.loopStart).to.be.closeTo(0.2, 0.01); @@ -64,7 +64,7 @@ describe("Transport", () => { it("can loop events scheduled on the transport", () => { let invocations = 0; return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.schedule((time) => { invocations++; }, 0); @@ -78,7 +78,7 @@ describe("Transport", () => { it("jumps to the loopStart after the loopEnd point", () => { let looped = false; return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.on("loop", () => { looped = true; }); @@ -97,14 +97,14 @@ describe("Transport", () => { it("returns 0 if the transports not started", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.nextSubdivision()).to.equal(0); }); }); it("can get the next subdivision of the transport", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0); return time => { whenBetween(time, 0.05, 0.07, () => { @@ -126,7 +126,7 @@ describe("Transport", () => { it("can get and set pulses per quarter", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.PPQ = 96; expect(transport.PPQ).to.equal(96); }); @@ -134,7 +134,7 @@ describe("Transport", () => { it("schedules a quarter note at the same time with a different PPQ", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.PPQ = 1; const id = transport.schedule(time => { expect(time).to.be.closeTo(transport.toSeconds("4n"), 0.1); @@ -146,7 +146,7 @@ describe("Transport", () => { it("invokes the right number of ticks with a different PPQ", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.bpm.value = 120; const ppq = 20; transport.PPQ = ppq; @@ -166,7 +166,7 @@ describe("Transport", () => { it("can jump to a specific tick number", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.ticks = 200; expect(transport.ticks).to.equal(200); transport.start(0); @@ -182,7 +182,7 @@ describe("Transport", () => { it("can get the current position in BarsBeatsSixteenths", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.position).to.equal("0:0:0"); transport.start(0); return atTime(0.05, () => { @@ -193,7 +193,7 @@ describe("Transport", () => { it("can get the current position in seconds", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.start(0.05); return time => { @@ -206,7 +206,7 @@ describe("Transport", () => { it("can get the current position in seconds during a bpm ramp", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.start(0.05); transport.bpm.linearRampTo(60, 0.5, 0.5); @@ -220,7 +220,7 @@ describe("Transport", () => { it("can set the current position in seconds", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.seconds = 3; expect(transport.seconds).to.be.closeTo(3, 0.01); @@ -229,7 +229,7 @@ describe("Transport", () => { it("can set the current position in BarsBeatsSixteenths", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); expect(transport.position).to.equal("0:0:0"); transport.position = "3:0"; expect(transport.position).to.equal("3:0:0"); @@ -240,7 +240,7 @@ describe("Transport", () => { it("can get the progress of the loop", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.setLoopPoints(0, "1m").start(); transport.loop = true; expect(transport.progress).to.be.equal(0); @@ -316,7 +316,7 @@ describe("Transport", () => { it("resets ticks on stop but not on pause", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0).pause(0.1).stop(0.2); expect(transport.getTicksAtTime(0)).to.be.equal(Math.floor(transport.PPQ * 0)); expect(transport.getTicksAtTime(0.05)).to.be.equal(Math.floor(transport.PPQ * 0.1)); @@ -329,7 +329,7 @@ describe("Transport", () => { it("tracks ticks after start", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.bpm.value = 120; const ppq = transport.PPQ; transport.start(); @@ -344,7 +344,7 @@ describe("Transport", () => { it("can start with a tick offset", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0, "200i"); return time => { @@ -357,7 +357,7 @@ describe("Transport", () => { it("can toggle the state of the transport", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.toggle(0); transport.toggle(0.2); @@ -376,7 +376,7 @@ describe("Transport", () => { it("tracks ticks correctly with a different PPQ and BPM", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.PPQ = 96; transport.bpm.value = 90; transport.start(); @@ -413,7 +413,7 @@ describe("Transport", () => { it("can schedule an event on the timeline", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.schedule(() => { }, 0); expect(eventID).to.be.a("number"); }); @@ -422,7 +422,7 @@ describe("Transport", () => { it("scheduled event gets invoked with the time of the event", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; transport.schedule(time => { expect(time).to.be.closeTo(startTime, 0.01); @@ -437,7 +437,7 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); transport.schedule(time => { @@ -452,7 +452,7 @@ describe("Transport", () => { it("can clear a scheduled event", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.schedule(() => { throw new Error("should not call this function"); }, 0); @@ -463,7 +463,7 @@ describe("Transport", () => { it("can cancel the timeline of scheduled object", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.schedule(() => { throw new Error("should not call this"); }, 0); @@ -474,7 +474,7 @@ describe("Transport", () => { it("can cancel the timeline of scheduleOnce object", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.scheduleOnce(() => { throw new Error("should not call this"); }, 0); @@ -486,7 +486,7 @@ describe("Transport", () => { it("scheduled event anywhere along the timeline", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = transport.now(); transport.schedule(time => { expect(time).to.be.closeTo(startTime + 0.5, 0.001); @@ -501,7 +501,7 @@ describe("Transport", () => { it("can schedule multiple events and invoke them in the right order", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); let first = false; transport.schedule(() => { first = true; @@ -519,7 +519,7 @@ describe("Transport", () => { it("invokes the event again if the timeline is restarted", () => { let iterations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.schedule(() => { iterations++; }, 0.05); @@ -532,7 +532,7 @@ describe("Transport", () => { it("can add an event after the Transport is started", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; return time => { @@ -567,7 +567,7 @@ describe("Transport", () => { it("can schedule a repeated event", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.scheduleRepeat(noOp, 1); expect(eventID).to.be.a("number"); }); @@ -576,7 +576,7 @@ describe("Transport", () => { it("scheduled event gets invoked with the time of the event", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eventID = transport.scheduleRepeat(time => { expect(time).to.be.closeTo(startTime, 0.01); @@ -591,7 +591,7 @@ describe("Transport", () => { it("can cancel the timeline of scheduleRepeat", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.scheduleRepeat(() => { throw new Error("should not call this"); }, 0.01, 0); @@ -603,7 +603,7 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); transport.scheduleRepeat(time => { @@ -618,7 +618,7 @@ describe("Transport", () => { it("can clear a scheduled event", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.scheduleRepeat(() => { throw new Error("should not call this function"); }, 1, 0); @@ -630,7 +630,7 @@ describe("Transport", () => { it("can be scheduled in the future", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eventID = transport.scheduleRepeat(time => { transport.clear(eventID); @@ -646,7 +646,7 @@ describe("Transport", () => { it("repeats a repeat event", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.scheduleRepeat(() => { invocations++; }, 0.1, 0); @@ -659,7 +659,7 @@ describe("Transport", () => { it("repeats at the repeat interval", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); let repeatTime = -1; transport.scheduleRepeat(time => { if (repeatTime !== -1) { @@ -678,7 +678,7 @@ describe("Transport", () => { let first = false; let second = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const firstID = transport.scheduleRepeat(() => { first = true; transport.clear(firstID); @@ -698,7 +698,7 @@ describe("Transport", () => { it("repeats for the given interval", () => { let repeatCount = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.scheduleRepeat(time => { repeatCount++; }, 0.1, 0, 0.5); @@ -711,7 +711,7 @@ describe("Transport", () => { it("can add an event after the Transport is started", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; const times = [0.15, 0.3]; @@ -732,7 +732,7 @@ describe("Transport", () => { it("can add an event to the past after the Transport is started", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; const times = [0.15, 0.25]; @@ -756,7 +756,7 @@ describe("Transport", () => { it("can schedule a single event on the timeline", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.scheduleOnce(() => {}, 0); expect(eventID).to.be.a("number"); }); @@ -765,7 +765,7 @@ describe("Transport", () => { it("scheduled event gets invoked with the time of the event", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eventID = transport.scheduleOnce(time => { invoked = true; @@ -781,7 +781,7 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); transport.scheduleOnce(time => { @@ -796,7 +796,7 @@ describe("Transport", () => { it("can clear a scheduled event", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const eventID = transport.scheduleOnce(() => { throw new Error("should not call this function"); }, 0); @@ -808,7 +808,7 @@ describe("Transport", () => { it("can be scheduled in the future", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const startTime = transport.now() + 0.1; const eventID = transport.scheduleOnce(time => { transport.clear(eventID); @@ -824,7 +824,7 @@ describe("Transport", () => { it("the event is removed after is is invoked", () => { let iterations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.scheduleOnce(() => { iterations++; }, 0); @@ -841,7 +841,7 @@ describe("Transport", () => { it("invokes start/stop/pause events", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.on("start", () => { invocations++; }); @@ -860,7 +860,7 @@ describe("Transport", () => { it("invokes start event with correct offset", () => { let wasCalled = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.on("start", (time, offset) => { expect(time).to.be.closeTo(0.2, 0.01); expect(offset).to.be.closeTo(0.5, 0.001); @@ -875,7 +875,7 @@ describe("Transport", () => { it("invokes the event just before the scheduled time", () => { let invoked = false; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.on("start", (time, offset) => { expect(time - transport.context.currentTime).to.be.closeTo(0, 0.01); expect(offset).to.equal(0); @@ -890,7 +890,7 @@ describe("Transport", () => { it("passes in the time argument to the events", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const now = transport.now(); transport.on("start", time => { invocations++; @@ -909,7 +909,7 @@ describe("Transport", () => { it("invokes the 'loop' method on loop", () => { let loops = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const sixteenth = transport.toSeconds("16n"); transport.setLoopPoints(0, sixteenth); transport.loop = true; @@ -932,7 +932,7 @@ describe("Transport", () => { it("can get/set the swing subdivision", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.swingSubdivision = "8n"; expect(transport.swingSubdivision).to.equal("8n"); transport.swingSubdivision = "4n"; @@ -942,7 +942,7 @@ describe("Transport", () => { it("can get/set the swing amount", () => { return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.swing = 0.5; expect(transport.swing).to.equal(0.5); transport.swing = 0; @@ -953,7 +953,7 @@ describe("Transport", () => { it("can swing", () => { let invocations = 0; return Offline(context => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.swing = 1; transport.swingSubdivision = "8n"; const eightNote = transport.toSeconds("8n"); diff --git a/Tone/core/clock/Transport.ts b/Tone/core/clock/Transport.ts index cbd6fb0a..66caf493 100644 --- a/Tone/core/clock/Transport.ts +++ b/Tone/core/clock/Transport.ts @@ -79,15 +79,15 @@ type TransportCallback = (time: Seconds) => void; * @example * const osc = new Tone.Oscillator().toDestination(); * // repeated event every 8th note - * Tone.Transport.scheduleRepeat((time) => { + * Tone.getTransport().scheduleRepeat((time) => { * // use the callback time to schedule events * osc.start(time).stop(time + 0.1); * }, "8n"); * // transport must be started before it starts invoking events - * Tone.Transport.start(); + * Tone.getTransport().start(); * @category Core */ -export class Transport +export class TransportClass extends ToneWithContext implements Emitter { readonly name: string = "Transport"; @@ -130,14 +130,14 @@ export class Transport * The Beats Per Minute of the Transport. * @example * const osc = new Tone.Oscillator().toDestination(); - * Tone.Transport.bpm.value = 80; + * Tone.getTransport().bpm.value = 80; * // start/stop the oscillator every quarter note - * Tone.Transport.scheduleRepeat(time => { + * Tone.getTransport().scheduleRepeat(time => { * osc.start(time).stop(time + 0.1); * }, "4n"); - * Tone.Transport.start(); + * Tone.getTransport().start(); * // ramp the bpm to 120 over 10 seconds - * Tone.Transport.bpm.rampTo(120, 10); + * Tone.getTransport().bpm.rampTo(120, 10); */ bpm: TickParam<"bpm">; @@ -187,9 +187,9 @@ export class Transport constructor(options?: Partial); constructor() { - super(optionsFromArguments(Transport.getDefaults(), arguments)); + super(optionsFromArguments(TransportClass.getDefaults(), arguments)); const options = optionsFromArguments( - Transport.getDefaults(), + TransportClass.getDefaults(), arguments ); @@ -280,7 +280,7 @@ export class Transport * @return The id of the event which can be used for canceling the event. * @example * // schedule an event on the 16th measure - * Tone.Transport.schedule((time) => { + * Tone.getTransport().schedule((time) => { * // invoked on measure 16 * console.log("measure 16!"); * }, "16:0:0"); @@ -308,7 +308,7 @@ export class Transport * @example * const osc = new Tone.Oscillator().toDestination().start(); * // a callback invoked every eighth note after the first measure - * Tone.Transport.scheduleRepeat((time) => { + * Tone.getTransport().scheduleRepeat((time) => { * osc.start(time).stop(time + 0.1); * }, "8n", "1m"); */ @@ -427,7 +427,7 @@ export class Transport * @param offset The timeline offset to start the transport. * @example * // start the transport in one second starting at beginning of the 5th measure. - * Tone.Transport.start("+1", "4:0:0"); + * Tone.getTransport().start("+1", "4:0:0"); */ start(time?: Time, offset?: TransportTime): this { // start the context @@ -445,7 +445,7 @@ export class Transport * Stop the transport and all sources synced to the transport. * @param time The time when the transport should stop. * @example - * Tone.Transport.stop(); + * Tone.getTransport().stop(); */ stop(time?: Time): this { this._clock.stop(time); @@ -484,11 +484,11 @@ export class Transport * For example 4/4 would be just 4 and 6/8 would be 3. * @example * // common time - * Tone.Transport.timeSignature = 4; + * Tone.getTransport().timeSignature = 4; * // 7/8 - * Tone.Transport.timeSignature = [7, 8]; + * Tone.getTransport().timeSignature = [7, 8]; * // this will be reduced to a single number - * Tone.Transport.timeSignature; // returns 3.5 + * Tone.getTransport().timeSignature; // returns 3.5 */ get timeSignature(): TimeSignature { return this._timeSignature; @@ -534,8 +534,8 @@ export class Transport * Set the loop start and stop at the same time. * @example * // loop over the first measure - * Tone.Transport.setLoopPoints(0, "1m"); - * Tone.Transport.loop = true; + * Tone.getTransport().setLoopPoints(0, "1m"); + * Tone.getTransport().loop = true; */ setLoopPoints( startPosition: TransportTime, @@ -682,8 +682,8 @@ export class Transport * @return The context time of the next subdivision. * @example * // the transport must be started, otherwise returns 0 - * Tone.Transport.start(); - * Tone.Transport.nextSubdivision("4n"); + * Tone.getTransport().start(); + * Tone.getTransport().nextSubdivision("4n"); */ nextSubdivision(subdivision?: Time): Seconds { subdivision = this.toTicks(subdivision); @@ -801,14 +801,14 @@ export class Transport emit!: (event: any, ...args: any[]) => this; } -Emitter.mixin(Transport); +Emitter.mixin(TransportClass); //------------------------------------- // INITIALIZATION //------------------------------------- onContextInit((context) => { - context.transport = new Transport({ context }); + context.transport = new TransportClass({ context }); }); onContextClose((context) => { diff --git a/Tone/core/clock/TransportEvent.test.ts b/Tone/core/clock/TransportEvent.test.ts index e0769308..3675edff 100644 --- a/Tone/core/clock/TransportEvent.test.ts +++ b/Tone/core/clock/TransportEvent.test.ts @@ -1,13 +1,13 @@ import { expect } from "chai"; import { Offline } from "test/helper/Offline"; -import { Transport } from "./Transport"; +import { TransportClass } from "./Transport"; import { TransportEvent } from "./TransportEvent"; describe("TransportEvent", () => { it("can be created and disposed", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportEvent(transport, { time: 0, }); @@ -17,7 +17,7 @@ describe("TransportEvent", () => { it("has a unique id", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportEvent(transport, { time: 0, }); @@ -29,7 +29,7 @@ describe("TransportEvent", () => { it("can invoke the callback", () => { let wasInvoked = false; return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportEvent(transport, { callback: (time) => { expect(time).to.equal(100); diff --git a/Tone/core/clock/TransportEvent.ts b/Tone/core/clock/TransportEvent.ts index acd019e8..33936abe 100644 --- a/Tone/core/clock/TransportEvent.ts +++ b/Tone/core/clock/TransportEvent.ts @@ -1,7 +1,7 @@ import { Seconds, Ticks } from "../type/Units"; import { noOp } from "../util/Interface"; -type Transport = import("../clock/Transport").Transport; +type Transport = import("../clock/Transport").TransportClass; export interface TransportEventOptions { callback: (time: number) => void; @@ -10,7 +10,7 @@ export interface TransportEventOptions { } /** - * TransportEvent is an internal class used by [[Transport]] + * TransportEvent is an internal class used by [[TransportClass]] * to schedule events. Do no invoke this class directly, it is * handled from within Tone.Transport. */ diff --git a/Tone/core/clock/TransportRepeatEvent.test.ts b/Tone/core/clock/TransportRepeatEvent.test.ts index 5c1305e4..2b52a997 100644 --- a/Tone/core/clock/TransportRepeatEvent.test.ts +++ b/Tone/core/clock/TransportRepeatEvent.test.ts @@ -1,13 +1,13 @@ import { expect } from "chai"; import { Offline } from "test/helper/Offline"; -import { Transport } from "./Transport"; +import { TransportClass } from "./Transport"; import { TransportRepeatEvent } from "./TransportRepeatEvent"; describe("TransportRepeatEvent", () => { it("can be created and disposed", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportRepeatEvent(transport, { duration: 100, interval: 4, @@ -19,7 +19,7 @@ describe("TransportRepeatEvent", () => { it("generates a unique event ID", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportRepeatEvent(transport, { time: 0, }); @@ -30,7 +30,7 @@ describe("TransportRepeatEvent", () => { it("is removed from the Transport when disposed", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); const event = new TransportRepeatEvent(transport, { time: 0, }); diff --git a/Tone/core/clock/TransportRepeatEvent.ts b/Tone/core/clock/TransportRepeatEvent.ts index b680d52c..6e339f00 100644 --- a/Tone/core/clock/TransportRepeatEvent.ts +++ b/Tone/core/clock/TransportRepeatEvent.ts @@ -4,7 +4,7 @@ import { Seconds, Ticks, Time } from "../type/Units"; import { TransportEvent, TransportEventOptions } from "./TransportEvent"; import { GT, LT } from "../util/Math"; -type Transport = import("../clock/Transport").Transport; +type Transport = import("../clock/Transport").TransportClass; interface TransportRepeatEventOptions extends TransportEventOptions { interval: Ticks; diff --git a/Tone/core/context/BaseContext.ts b/Tone/core/context/BaseContext.ts index ba831424..c07af471 100644 --- a/Tone/core/context/BaseContext.ts +++ b/Tone/core/context/BaseContext.ts @@ -2,10 +2,10 @@ import { Seconds } from "../type/Units"; import { Emitter } from "../util/Emitter"; import { AnyAudioContext } from "./AudioContext"; -type Draw = import("../util/Draw").Draw; -type Destination = import("./Destination").Destination; -type Transport = import("../clock/Transport").Transport; -type Listener = import("./Listener").Listener; +type Draw = import("../util/Draw").DrawClass; +type Destination = import("./Destination").DestinationClass; +type Transport = import("../clock/Transport").TransportClass; +type Listener = import("./Listener").ListenerClass; // these are either not used in Tone.js or deprecated and not implemented. export type ExcludedFromBaseAudioContext = diff --git a/Tone/core/context/Context.test.ts b/Tone/core/context/Context.test.ts index bf61d218..fc39c610 100644 --- a/Tone/core/context/Context.test.ts +++ b/Tone/core/context/Context.test.ts @@ -2,13 +2,13 @@ import { expect } from "chai"; import { ConstantOutput } from "test/helper/ConstantOutput"; import { Offline } from "test/helper/Offline"; import { ONLINE_TESTING } from "test/helper/Supports"; -import { Transport } from "../clock/Transport"; +import { TransportClass } from "../clock/Transport"; import { getContext } from "../Global"; import { createAudioContext } from "./AudioContext"; import { Context } from "./Context"; -import { Destination } from "./Destination"; -import { Listener } from "./Listener"; -import { Draw } from "../util/Draw"; +import { DestinationClass } from "./Destination"; +import { ListenerClass } from "./Listener"; +import { DrawClass } from "../util/Draw"; import { connect } from "./ToneAudioNode"; describe("Context", () => { @@ -19,9 +19,9 @@ describe("Context", () => { const ctxDraw = context.draw; const ctxTransport = context.transport; const ctxListener = context.listener; - expect(context.destination).is.instanceOf(Destination); - expect(context.draw).is.instanceOf(Draw); - expect(context.listener).is.instanceOf(Listener); + expect(context.destination).is.instanceOf(DestinationClass); + expect(context.draw).is.instanceOf(DrawClass); + expect(context.listener).is.instanceOf(ListenerClass); await context.close(); expect(ctxDest.disposed).to.be.true; expect(ctxDraw.disposed).to.be.true; @@ -218,7 +218,7 @@ describe("Context", () => { it("is invoked in the offline context", () => { return Offline((context) => { - const transport = new Transport({ context }); + const transport = new TransportClass({ context }); transport.context.setTimeout(() => { expect(transport.now()).to.be.closeTo(0.01, 0.005); }, 0.01); diff --git a/Tone/core/context/Context.ts b/Tone/core/context/Context.ts index dc3ecd01..d638ee04 100644 --- a/Tone/core/context/Context.ts +++ b/Tone/core/context/Context.ts @@ -13,10 +13,10 @@ import { closeContext, initializeContext } from "./ContextInitialization"; import { BaseContext, ContextLatencyHint } from "./BaseContext"; import { assert } from "../util/Debug"; -type Transport = import("../clock/Transport").Transport; -type Destination = import("./Destination").Destination; -type Listener = import("./Listener").Listener; -type Draw = import("../util/Draw").Draw; +type Transport = import("../clock/Transport").TransportClass; +type Destination = import("./Destination").DestinationClass; +type Listener = import("./Listener").ListenerClass; +type Draw = import("../util/Draw").DrawClass; export interface ContextOptions { clockSource: TickerClockSource; diff --git a/Tone/core/context/Destination.test.ts b/Tone/core/context/Destination.test.ts index 94b28bb3..60320f8c 100644 --- a/Tone/core/context/Destination.test.ts +++ b/Tone/core/context/Destination.test.ts @@ -4,12 +4,12 @@ import { Offline } from "test/helper/Offline"; import { PassAudio } from "test/helper/PassAudio"; import { Oscillator } from "Tone/source/oscillator/Oscillator"; import { getContext } from "../Global"; -import { Destination } from "./Destination"; +import { DestinationClass } from "./Destination"; describe("Destination", () => { it("creates itself on the context", () => { - expect(getContext().destination).instanceOf(Destination); + expect(getContext().destination).instanceOf(DestinationClass); }); it("can be muted and unmuted", () => { diff --git a/Tone/core/context/Destination.ts b/Tone/core/context/Destination.ts index bee7fc69..7b3c70e7 100644 --- a/Tone/core/context/Destination.ts +++ b/Tone/core/context/Destination.ts @@ -26,7 +26,7 @@ interface DestinationOptions extends ToneAudioNodeOptions { * oscillator.toDestination(); * @category Core */ -export class Destination extends ToneAudioNode { +export class DestinationClass extends ToneAudioNode { readonly name: string = "Destination"; @@ -46,8 +46,8 @@ export class Destination extends ToneAudioNode { constructor(options: Partial); constructor() { - super(optionsFromArguments(Destination.getDefaults(), arguments)); - const options = optionsFromArguments(Destination.getDefaults(), arguments); + super(optionsFromArguments(DestinationClass.getDefaults(), arguments)); + const options = optionsFromArguments(DestinationClass.getDefaults(), arguments); connectSeries(this.input, this.output, this.context.rawContext.destination); @@ -120,7 +120,7 @@ export class Destination extends ToneAudioNode { //------------------------------------- onContextInit(context => { - context.destination = new Destination({ context }); + context.destination = new DestinationClass({ context }); }); onContextClose(context => { diff --git a/Tone/core/context/DummyContext.ts b/Tone/core/context/DummyContext.ts index 3af54180..75f9a382 100644 --- a/Tone/core/context/DummyContext.ts +++ b/Tone/core/context/DummyContext.ts @@ -2,10 +2,10 @@ import { BaseContext } from "./BaseContext"; import { Seconds } from "../type/Units"; import { AnyAudioContext } from "./AudioContext"; -type Draw = import("../util/Draw").Draw; -type Destination = import("./Destination").Destination; -type Transport = import("../clock/Transport").Transport; -type Listener = import("./Listener").Listener; +type Draw = import("../util/Draw").DrawClass; +type Destination = import("./Destination").DestinationClass; +type Transport = import("../clock/Transport").TransportClass; +type Listener = import("./Listener").ListenerClass; export class DummyContext extends BaseContext { //--------------------------- diff --git a/Tone/core/context/Listener.test.ts b/Tone/core/context/Listener.test.ts index b24c7f58..ac3e03c3 100644 --- a/Tone/core/context/Listener.test.ts +++ b/Tone/core/context/Listener.test.ts @@ -1,12 +1,12 @@ import { expect } from "chai"; import { Offline } from "test/helper/Offline"; import { getContext } from "../Global"; -import { Listener } from "./Listener"; +import { ListenerClass } from "./Listener"; describe("Listener", () => { it("creates itself on the context", () => { - expect(getContext().listener).instanceOf(Listener); + expect(getContext().listener).instanceOf(ListenerClass); }); it("can get and set values as an object", () => { diff --git a/Tone/core/context/Listener.ts b/Tone/core/context/Listener.ts index 61909f02..640b6e62 100644 --- a/Tone/core/context/Listener.ts +++ b/Tone/core/context/Listener.ts @@ -20,7 +20,7 @@ export interface ListenerOptions extends ToneAudioNodeOptions{ * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from * a first-person perspective. There is only one listener per audio context. */ -export class Listener extends ToneAudioNode { +export class ListenerClass extends ToneAudioNode { readonly name: string = "Listener"; @@ -109,7 +109,7 @@ export class Listener extends ToneAudioNode { //------------------------------------- onContextInit(context => { - context.listener = new Listener({ context }); + context.listener = new ListenerClass({ context }); }); onContextClose(context => { diff --git a/Tone/core/context/ToneWithContext.ts b/Tone/core/context/ToneWithContext.ts index c58e50f8..19ad21d6 100644 --- a/Tone/core/context/ToneWithContext.ts +++ b/Tone/core/context/ToneWithContext.ts @@ -79,8 +79,6 @@ export abstract class ToneWithContext ex /** * The duration in seconds of one sample. - * @example - * console.log(Tone.Transport.sampleTime); */ get sampleTime(): Seconds { return 1 / this.context.sampleRate; @@ -97,7 +95,7 @@ export abstract class ToneWithContext ex /** * Convert the incoming time to seconds. - * This is calculated against the current [[Transport]] bpm + * This is calculated against the current [[TransportClass]] bpm * @example * const gain = new Tone.Gain(); * setInterval(() => console.log(gain.toSeconds("4n")), 100); diff --git a/Tone/core/util/Draw.test.ts b/Tone/core/util/Draw.test.ts index 1941745e..5cc66a5f 100644 --- a/Tone/core/util/Draw.test.ts +++ b/Tone/core/util/Draw.test.ts @@ -1,12 +1,12 @@ import { expect } from "chai"; import { ONLINE_TESTING } from "test/helper/Supports"; -import { Draw } from "./Draw"; +import { DrawClass } from "./Draw"; describe("Draw", () => { if (ONLINE_TESTING) { - const draw = new Draw(); + const draw = new DrawClass(); after(() => { draw.dispose(); diff --git a/Tone/core/util/Draw.ts b/Tone/core/util/Draw.ts index c7a34245..0cc3061d 100644 --- a/Tone/core/util/Draw.ts +++ b/Tone/core/util/Draw.ts @@ -25,7 +25,7 @@ interface DrawEvent extends TimelineEvent { * Tone.Transport.start(); * @category Core */ -export class Draw extends ToneWithContext { +export class DrawClass extends ToneWithContext { readonly name: string = "Draw"; @@ -117,7 +117,7 @@ export class Draw extends ToneWithContext { //------------------------------------- onContextInit(context => { - context.draw = new Draw({ context }); + context.draw = new DrawClass({ context }); }); onContextClose(context => { diff --git a/Tone/core/util/IntervalTimeline.ts b/Tone/core/util/IntervalTimeline.ts index c43f1bda..395bfa3a 100644 --- a/Tone/core/util/IntervalTimeline.ts +++ b/Tone/core/util/IntervalTimeline.ts @@ -20,6 +20,7 @@ type IteratorCallback = (event: IntervalTimelineEvent) => void; * for querying an intersection point with the timeline * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree) * to represent the data. + * @internal */ export class IntervalTimeline extends Tone { diff --git a/Tone/core/util/StateTimeline.ts b/Tone/core/util/StateTimeline.ts index 21790cd0..79074538 100644 --- a/Tone/core/util/StateTimeline.ts +++ b/Tone/core/util/StateTimeline.ts @@ -12,6 +12,7 @@ export interface StateTimelineEvent extends TimelineEvent { /** * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)` * @param initial The initial state of the StateTimeline. Defaults to `undefined` + * @internal */ export class StateTimeline = Record> extends Timeline { diff --git a/Tone/core/util/Timeline.ts b/Tone/core/util/Timeline.ts index d724b760..de65d93e 100644 --- a/Tone/core/util/Timeline.ts +++ b/Tone/core/util/Timeline.ts @@ -26,6 +26,7 @@ export interface TimelineEvent { * along a timeline. All events must have a "time" property. * Internally, events are stored in time order for fast * retrieval. + * @internal */ export class Timeline extends Tone { diff --git a/Tone/fromContext.ts b/Tone/fromContext.ts index df72a91e..afc7d852 100644 --- a/Tone/fromContext.ts +++ b/Tone/fromContext.ts @@ -1,8 +1,8 @@ import * as Classes from "./classes"; -import { Transport } from "./core/clock/Transport"; +import { TransportClass } from "./core/clock/Transport"; import { Context } from "./core/context/Context"; -import { Listener } from "./core/context/Listener"; -import { Destination } from "./core/context/Destination"; +import { ListenerClass } from "./core/context/Listener"; +import { DestinationClass } from "./core/context/Destination"; import { FrequencyClass } from "./core/type/Frequency"; import { MidiClass } from "./core/type/Midi"; import { TicksClass } from "./core/type/Ticks"; @@ -10,7 +10,7 @@ import { TimeClass } from "./core/type/Time"; import { TransportTimeClass } from "./core/type/TransportTime"; import { isDefined, isFunction } from "./core/util/TypeCheck"; import { omitFromObject } from "./core/util/Defaults"; -import { Draw } from "./core/util/Draw"; +import { DrawClass } from "./core/util/Draw"; type ClassesWithoutSingletons = Omit; @@ -19,10 +19,10 @@ type ClassesWithoutSingletons = Omit number; immediate: () => number; diff --git a/Tone/index.test.ts b/Tone/index.test.ts index 6e2bb25a..16bcb6fc 100644 --- a/Tone/index.test.ts +++ b/Tone/index.test.ts @@ -1,9 +1,9 @@ import * as Tone from "./index"; import { expect } from "chai"; -import { Destination } from "./core/context/Destination"; +import { DestinationClass } from "./core/context/Destination"; import { Context } from "./core/context/Context"; -import { Transport } from "./core/clock/Transport"; -import { Draw } from "./core/util/Draw"; +import { TransportClass } from "./core/clock/Transport"; +import { DrawClass } from "./core/util/Draw"; describe("Tone", () => { @@ -15,16 +15,16 @@ describe("Tone", () => { }); it("exports the global singletons", () => { - expect(Tone.Destination).to.be.an.instanceOf(Destination); - expect(Tone.Draw).to.be.an.instanceOf(Draw); - expect(Tone.Transport).to.be.an.instanceOf(Transport); + expect(Tone.Destination).to.be.an.instanceOf(DestinationClass); + expect(Tone.Draw).to.be.an.instanceOf(DrawClass); + expect(Tone.Transport).to.be.an.instanceOf(TransportClass); expect(Tone.context).to.be.an.instanceOf(Context); }); it("exports the global singleton getters", () => { - expect(Tone.getDestination()).to.be.an.instanceOf(Destination); - expect(Tone.getDraw()).to.be.an.instanceOf(Draw); - expect(Tone.getTransport()).to.be.an.instanceOf(Transport); + expect(Tone.getDestination()).to.be.an.instanceOf(DestinationClass); + expect(Tone.getDraw()).to.be.an.instanceOf(DrawClass); + expect(Tone.getTransport()).to.be.an.instanceOf(TransportClass); }); it("can start the global context", () => { diff --git a/Tone/index.ts b/Tone/index.ts index f2df621d..5172c096 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -27,75 +27,80 @@ export function immediate(): Seconds { /** * The Transport object belonging to the global Tone.js Context. - * See [[Transport]] + * See [[TransportClass]] * @category Core + * @deprecated Use {@link getTransport} instead */ export const Transport = getContext().transport; /** * The Transport object belonging to the global Tone.js Context. - * See [[Transport]] + * See [[TransportClass]] * @category Core */ -export function getTransport(): import("./core/clock/Transport").Transport { +export function getTransport(): import("./core/clock/Transport").TransportClass { return getContext().transport; } /** * The Destination (output) belonging to the global Tone.js Context. - * See [[Destination]] + * See [[DestinationClass]] * @category Core + * @deprecated Use {@link getDestination} instead */ export const Destination = getContext().destination; /** - * @deprecated Use [[Destination]] + * @deprecated Use {@link getDestination} instead */ export const Master = getContext().destination; /** * The Destination (output) belonging to the global Tone.js Context. - * See [[Destination]] + * See [[DestinationClass]] * @category Core */ -export function getDestination(): import("./core/context/Destination").Destination { +export function getDestination(): import("./core/context/Destination").DestinationClass { return getContext().destination; } /** - * The [[Listener]] belonging to the global Tone.js Context. + * The [[ListenerClass]] belonging to the global Tone.js Context. * @category Core + * @deprecated Use {@link getListener} instead */ export const Listener = getContext().listener; /** - * The [[Listener]] belonging to the global Tone.js Context. + * The [[ListenerClass]] belonging to the global Tone.js Context. * @category Core */ -export function getListener(): import("./core/context/Listener").Listener { +export function getListener(): import("./core/context/Listener").ListenerClass { return getContext().listener; } /** * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See [[Draw]] + * See [[DrawClass]] * @category Core + * @deprecated Use {@link getDraw} instead */ export const Draw = getContext().draw; /** * Get the singleton attached to the global context. * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See [[Draw]] + * See [[DrawClass]] * @category Core */ -export function getDraw(): import("./core/util/Draw").Draw { +export function getDraw(): import("./core/util/Draw").DrawClass { return getContext().draw; } /** * A reference to the global context * See [[Context]] + * @deprecated Use {@link getContext} instead */ export const context = getContext(); @@ -111,6 +116,9 @@ export function loaded() { // this fills in name changes from 13.x to 14.x import { ToneAudioBuffers } from "./core/context/ToneAudioBuffers"; import { ToneBufferSource } from "./source/buffer/ToneBufferSource"; +/** @deprecated Use {@link ToneAudioBuffer} */ export const Buffer: typeof ToneAudioBuffer = ToneAudioBuffer; +/** @deprecated Use {@link ToneAudioBuffers} */ export const Buffers: typeof ToneAudioBuffers = ToneAudioBuffers; +/** @deprecated Use {@link ToneBufferSource} */ export const BufferSource: typeof ToneBufferSource = ToneBufferSource; diff --git a/Tone/signal/SyncedSignal.ts b/Tone/signal/SyncedSignal.ts index 1b9fa214..94e33eda 100644 --- a/Tone/signal/SyncedSignal.ts +++ b/Tone/signal/SyncedSignal.ts @@ -6,7 +6,8 @@ import { ToneConstantSource } from "./ToneConstantSource"; import { OutputNode } from "../core/context/ToneAudioNode"; /** - * Adds the ability to synchronize the signal to the [[Transport]] + * Adds the ability to synchronize the signal to the [[TransportClass]] + * @category Signal */ export class SyncedSignal extends Signal { diff --git a/scripts/typedoc.json b/scripts/typedoc.json index a497d987..6c362cfa 100644 --- a/scripts/typedoc.json +++ b/scripts/typedoc.json @@ -9,4 +9,6 @@ "excludeProtected" : true, "excludePrivate" : true, "hideGenerator": true, + "includeVersion": true, + "excludeInternal": true } \ No newline at end of file From f8fcc4cec636cf9b70998aa68898d62be43683e1 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Sun, 28 Apr 2024 13:05:42 -0400 Subject: [PATCH 07/17] Simplifying oscillator type strings using templates (#1234) * simplifying interface types using templates * uploading codecov threshold * adjusting thresh * updating checkout --- .github/codecov.yml | 6 + .github/workflows/test.yml | 11 +- Tone/source/oscillator/OscillatorInterface.ts | 321 ++++++++++-------- 3 files changed, 197 insertions(+), 141 deletions(-) create mode 100644 .github/codecov.yml diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 00000000..61acfc08 --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + project: + default: + target: auto + threshold: 1% \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 00d22930..5da7e469 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Nodejs uses: actions/setup-node@v4 with: @@ -38,6 +38,7 @@ jobs: uses: codecov/codecov-action@v4 with: fail_ci_if_error: false + codecov_yml_path: ./.github/codecov.yml token: ${{ secrets.CODECOV_TOKEN }} test-code-examples: name: Check typedocs @@ -47,7 +48,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Nodejs uses: actions/setup-node@v4 with: @@ -67,7 +68,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Nodejs uses: actions/setup-node@v4 with: @@ -87,7 +88,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Nodejs uses: actions/setup-node@v4 with: @@ -105,7 +106,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Nodejs uses: actions/setup-node@v4 with: diff --git a/Tone/source/oscillator/OscillatorInterface.ts b/Tone/source/oscillator/OscillatorInterface.ts index f2a4802c..acb7734e 100644 --- a/Tone/source/oscillator/OscillatorInterface.ts +++ b/Tone/source/oscillator/OscillatorInterface.ts @@ -1,4 +1,10 @@ -import { AudioRange, Cents, Degrees, Frequency, Positive } from "../../core/type/Units"; +import { + AudioRange, + Cents, + Degrees, + Frequency, + Positive, +} from "../../core/type/Units"; import { Omit } from "../../core/util/Interface"; import { Signal } from "../../signal/Signal"; import { SourceOptions } from "../Source"; @@ -8,7 +14,6 @@ import { OfflineContext } from "../../core/context/OfflineContext"; * The common interface of all Oscillators */ export interface ToneOscillatorInterface { - /** * The oscillator type without the partialsCount appended to the end * @example @@ -19,8 +24,8 @@ export interface ToneOscillatorInterface { baseType: OscillatorType | "pulse" | "pwm"; /** - * The oscillator's type. Also capable of setting the first x number of partials of the oscillator. - * For example: "sine4" would set be the first 4 partials of the sine wave and "triangle8" would + * The oscillator's type. Also capable of setting the first x number of partials of the oscillator. + * For example: "sine4" would set be the first 4 partials of the sine wave and "triangle8" would * set the first 8 partials of the triangle wave. * @example * return Tone.Offline(() => { @@ -52,7 +57,7 @@ export interface ToneOscillatorInterface { /** * The phase is the starting position within the oscillator's cycle. For example - * a phase of 180 would start halfway through the oscillator's cycle. + * a phase of 180 would start halfway through the oscillator's cycle. * @example * return Tone.Offline(() => { * const osc = new Tone.Oscillator({ @@ -64,11 +69,11 @@ export interface ToneOscillatorInterface { phase: Degrees; /** - * The partials describes the relative amplitude of each of the harmonics of the oscillator. - * The first value in the array is the first harmonic (i.e. the fundamental frequency), the + * The partials describes the relative amplitude of each of the harmonics of the oscillator. + * The first value in the array is the first harmonic (i.e. the fundamental frequency), the * second harmonic is an octave up, the third harmonic is an octave and a fifth, etc. The resulting - * oscillator output is composed of a sine tone at the relative amplitude at each of the harmonic intervals. - * + * oscillator output is composed of a sine tone at the relative amplitude at each of the harmonic intervals. + * * Setting this value will automatically set the type to "custom". * The value is an empty array when the type is not "custom". * @example @@ -107,49 +112,83 @@ export interface ToneOscillatorInterface { /** * Render a segment of the oscillator to an offline context and return the results as an array */ -export async function generateWaveform(instance: any, length: number): Promise { +export async function generateWaveform( + instance: any, + length: number +): Promise { const duration = length / instance.context.sampleRate; - const context = new OfflineContext(1, duration, instance.context.sampleRate); - const clone = new instance.constructor(Object.assign(instance.get(), { - // should do 2 iterations - frequency: 2 / duration, - // zero out the detune - detune: 0, - context - })).toDestination(); + const context = new OfflineContext( + 1, + duration, + instance.context.sampleRate + ); + const clone = new instance.constructor( + Object.assign(instance.get(), { + // should do 2 iterations + frequency: 2 / duration, + // zero out the detune + detune: 0, + context, + }) + ).toDestination(); clone.start(0); const buffer = await context.render(); return buffer.getChannelData(0); } +/** + * The supported number of partials + */ +type PartialsRange = + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11 + | 12 + | 13 + | 14 + | 15 + | 16 + | 17 + | 18 + | 19 + | 20 + | 21 + | 22 + | 23 + | 24 + | 25 + | 26 + | 27 + | 28 + | 29 + | 30 + | 31 + | 32; + /** * Oscillators with partials */ -type SineWithPartials = - "sine1" | "sine2" | "sine3" | "sine4" | "sine5" | "sine6" | "sine7" | "sine8" | "sine9" | - "sine10" | "sine11" | "sine12" | "sine13" | "sine14" | "sine15" | "sine16" | "sine17" | "sine18" | "sine19" | - "sine20" | "sine21" | "sine22" | "sine23" | "sine24" | "sine25" | "sine26" | "sine27" | "sine28" | "sine29" | - "sine30" | "sine31" | "sine32"; - -type SquareWithPartials = - "square1" | "square2" | "square3" | "square4" | "square5" | "square6" | "square7" | "square8" | "square9" | - "square10" | "square11" | "square12" | "square13" | "square14" | "square15" | "square16" | "square17" | "square18" | "square19" | - "square20" | "square21" | "square22" | "square23" | "square24" | "square25" | "square26" | "square27" | "square28" | "square29" | - "square30" | "square31" | "square32"; - -type SawtoothWithPartials = - "sawtooth1" | "sawtooth2" | "sawtooth3" | "sawtooth4" | "sawtooth5" | "sawtooth6" | "sawtooth7" | "sawtooth8" | "sawtooth9" | - "sawtooth10" | "sawtooth11" | "sawtooth12" | "sawtooth13" | "sawtooth14" | "sawtooth15" | "sawtooth16" | "sawtooth17" | "sawtooth18" | "sawtooth19" | - "sawtooth20" | "sawtooth21" | "sawtooth22" | "sawtooth23" | "sawtooth24" | "sawtooth25" | "sawtooth26" | "sawtooth27" | "sawtooth28" | "sawtooth29" | - "sawtooth30" | "sawtooth31" | "sawtooth32"; - -type TriangleWithPartials = - "triangle1" | "triangle2" | "triangle3" | "triangle4" | "triangle5" | "triangle6" | "triangle7" | "triangle8" | "triangle9" | - "triangle10" | "triangle11" | "triangle12" | "triangle13" | "triangle14" | "triangle15" | "triangle16" | "triangle17" | "triangle18" | "triangle19" | - "triangle20" | "triangle21" | "triangle22" | "triangle23" | "triangle24" | "triangle25" | "triangle26" | "triangle27" | "triangle28" | "triangle29" | - "triangle30" | "triangle31" | "triangle32"; - -type TypeWithPartials = SineWithPartials | SquareWithPartials | TriangleWithPartials | SawtoothWithPartials; +type SineWithPartials = `sine${PartialsRange}`; + +type SquareWithPartials = `square${PartialsRange}`; + +type SawtoothWithPartials = `sawtooth${PartialsRange}`; + +type TriangleWithPartials = `triangle${PartialsRange}`; + +type TypeWithPartials = + | SineWithPartials + | SquareWithPartials + | TriangleWithPartials + | SawtoothWithPartials; interface BaseOscillatorOptions extends SourceOptions { frequency: Frequency; @@ -182,7 +221,10 @@ interface TonePartialOscillatorOptions extends BaseOscillatorOptions { type: TypeWithPartials; } -export type ToneOscillatorConstructorOptions = ToneCustomOscillatorOptions | ToneTypeOscillatorOptions | TonePartialOscillatorOptions; +export type ToneOscillatorConstructorOptions = + | ToneCustomOscillatorOptions + | ToneTypeOscillatorOptions + | TonePartialOscillatorOptions; export interface ToneOscillatorOptions extends BaseOscillatorOptions { type: ToneOscillatorType; @@ -213,7 +255,10 @@ interface FMPartialsOscillatorOptions extends FMBaseOscillatorOptions { type: TypeWithPartials; } -export type FMConstructorOptions = FMTypeOscillatorOptions | FMCustomOscillatorOptions | FMPartialsOscillatorOptions; +export type FMConstructorOptions = + | FMTypeOscillatorOptions + | FMCustomOscillatorOptions + | FMPartialsOscillatorOptions; export interface FMOscillatorOptions extends ToneOscillatorOptions { harmonicity: Positive; @@ -243,7 +288,10 @@ interface AMPartialsOscillatorOptions extends AMBaseOscillatorOptions { type: TypeWithPartials; } -export type AMConstructorOptions = AMCustomOscillatorOptions | AMTypeOscillatorOptions | AMPartialsOscillatorOptions; +export type AMConstructorOptions = + | AMCustomOscillatorOptions + | AMTypeOscillatorOptions + | AMPartialsOscillatorOptions; export interface AMOscillatorOptions extends ToneOscillatorOptions { harmonicity: Positive; @@ -271,7 +319,10 @@ interface FatPartialsOscillatorOptions extends FatBaseOscillatorOptions { type: TypeWithPartials; } -export type FatConstructorOptions = FatCustomOscillatorOptions | FatTypeOscillatorOptions | FatPartialsOscillatorOptions; +export type FatConstructorOptions = + | FatCustomOscillatorOptions + | FatTypeOscillatorOptions + | FatPartialsOscillatorOptions; export interface FatOscillatorOptions extends ToneOscillatorOptions { spread: Cents; @@ -301,89 +352,53 @@ export interface PWMOscillatorOptions extends BaseOscillatorOptions { /** * FM Oscillators with partials */ -type FMSineWithPartials = - "fmsine1" | "fmsine2" | "fmsine3" | "fmsine4" | "fmsine5" | "fmsine6" | "fmsine7" | "fmsine8" | "fmsine9" | - "fmsine10" | "fmsine11" | "fmsine12" | "fmsine13" | "fmsine14" | "fmsine15" | "fmsine16" | "fmsine17" | "fmsine18" | "fmsine19" | - "fmsine20" | "fmsine21" | "fmsine22" | "fmsine23" | "fmsine24" | "fmsine25" | "fmsine26" | "fmsine27" | "fmsine28" | "fmsine29" | - "fmsine30" | "fmsine31" | "fmsine32"; - -type FMSquareWithPartials = - "fmsquare1" | "fmsquare2" | "fmsquare3" | "fmsquare4" | "fmsquare5" | "fmsquare6" | "fmsquare7" | "fmsquare8" | "fmsquare9" | - "fmsquare10" | "fmsquare11" | "fmsquare12" | "fmsquare13" | "fmsquare14" | "fmsquare15" | "fmsquare16" | "fmsquare17" | "fmsquare18" | "fmsquare19" | - "fmsquare20" | "fmsquare21" | "fmsquare22" | "fmsquare23" | "fmsquare24" | "fmsquare25" | "fmsquare26" | "fmsquare27" | "fmsquare28" | "fmsquare29" | - "fmsquare30" | "fmsquare31" | "fmsquare32"; - -type FMSawtoothWithPartials = - "fmsawtooth1" | "fmsawtooth2" | "fmsawtooth3" | "fmsawtooth4" | "fmsawtooth5" | "fmsawtooth6" | "fmsawtooth7" | "fmsawtooth8" | "fmsawtooth9" | - "fmsawtooth10" | "fmsawtooth11" | "fmsawtooth12" | "fmsawtooth13" | "fmsawtooth14" | "fmsawtooth15" | "fmsawtooth16" | "fmsawtooth17" | "fmsawtooth18" | "fmsawtooth19" | - "fmsawtooth20" | "fmsawtooth21" | "fmsawtooth22" | "fmsawtooth23" | "fmsawtooth24" | "fmsawtooth25" | "fmsawtooth26" | "fmsawtooth27" | "fmsawtooth28" | "fmsawtooth29" | - "fmsawtooth30" | "fmsawtooth31" | "fmsawtooth32"; - -type FMTriangleWithPartials = - "fmtriangle1" | "fmtriangle2" | "fmtriangle3" | "fmtriangle4" | "fmtriangle5" | "fmtriangle6" | "fmtriangle7" | "fmtriangle8" | "fmtriangle9" | - "fmtriangle10" | "fmtriangle11" | "fmtriangle12" | "fmtriangle13" | "fmtriangle14" | "fmtriangle15" | "fmtriangle16" | "fmtriangle17" | "fmtriangle18" | "fmtriangle19" | - "fmtriangle20" | "fmtriangle21" | "fmtriangle22" | "fmtriangle23" | "fmtriangle24" | "fmtriangle25" | "fmtriangle26" | "fmtriangle27" | "fmtriangle28" | "fmtriangle29" | - "fmtriangle30" | "fmtriangle31" | "fmtriangle32"; - -type FMTypeWithPartials = FMSineWithPartials | FMSquareWithPartials | FMSawtoothWithPartials | FMTriangleWithPartials; +type FMSineWithPartials = `fmsine${PartialsRange}`; + +type FMSquareWithPartials = `fmsquare${PartialsRange}`; + +type FMSawtoothWithPartials = `fmsawtooth${PartialsRange}`; + +type FMTriangleWithPartials = `fmtriangle${PartialsRange}`; + +type FMTypeWithPartials = + | FMSineWithPartials + | FMSquareWithPartials + | FMSawtoothWithPartials + | FMTriangleWithPartials; /** * AM Oscillators with partials */ -type AMSineWithPartials = - "amsine1" | "amsine2" | "amsine3" | "amsine4" | "amsine5" | "amsine6" | "amsine7" | "amsine8" | "amsine9" | - "amsine10" | "amsine11" | "amsine12" | "amsine13" | "amsine14" | "amsine15" | "amsine16" | "amsine17" | "amsine18" | "amsine19" | - "amsine20" | "amsine21" | "amsine22" | "amsine23" | "amsine24" | "amsine25" | "amsine26" | "amsine27" | "amsine28" | "amsine29" | - "amsine30" | "amsine31" | "amsine32"; - -type AMSquareWithPartials = - "amsquare1" | "amsquare2" | "amsquare3" | "amsquare4" | "amsquare5" | "amsquare6" | "amsquare7" | "amsquare8" | "amsquare9" | - "amsquare10" | "amsquare11" | "amsquare12" | "amsquare13" | "amsquare14" | "amsquare15" | "amsquare16" | "amsquare17" | "amsquare18" | "amsquare19" | - "amsquare20" | "amsquare21" | "amsquare22" | "amsquare23" | "amsquare24" | "amsquare25" | "amsquare26" | "amsquare27" | "amsquare28" | "amsquare29" | - "amsquare30" | "amsquare31" | "amsquare32"; - -type AMSawtoothWithPartials = - "amsawtooth1" | "amsawtooth2" | "amsawtooth3" | "amsawtooth4" | "amsawtooth5" | "amsawtooth6" | "amsawtooth7" | "amsawtooth8" | "amsawtooth9" | - "amsawtooth10" | "amsawtooth11" | "amsawtooth12" | "amsawtooth13" | "amsawtooth14" | "amsawtooth15" | "amsawtooth16" | "amsawtooth17" | "amsawtooth18" | "amsawtooth19" | - "amsawtooth20" | "amsawtooth21" | "amsawtooth22" | "amsawtooth23" | "amsawtooth24" | "amsawtooth25" | "amsawtooth26" | "amsawtooth27" | "amsawtooth28" | "amsawtooth29" | - "amsawtooth30" | "amsawtooth31" | "amsawtooth32"; - -type AMTriangleWithPartials = - "amtriangle1" | "amtriangle2" | "amtriangle3" | "amtriangle4" | "amtriangle5" | "amtriangle6" | "amtriangle7" | "amtriangle8" | "amtriangle9" | - "amtriangle10" | "amtriangle11" | "amtriangle12" | "amtriangle13" | "amtriangle14" | "amtriangle15" | "amtriangle16" | "amtriangle17" | "amtriangle18" | "amtriangle19" | - "amtriangle20" | "amtriangle21" | "amtriangle22" | "amtriangle23" | "amtriangle24" | "amtriangle25" | "amtriangle26" | "amtriangle27" | "amtriangle28" | "amtriangle29" | - "amtriangle30" | "amtriangle31" | "amtriangle32"; - -type AMTypeWithPartials = AMSineWithPartials | AMSquareWithPartials | AMSawtoothWithPartials | AMTriangleWithPartials; +type AMSineWithPartials = `amsine${PartialsRange}`; + +type AMSquareWithPartials = `amsquare${PartialsRange}`; + +type AMSawtoothWithPartials = `amsawtooth${PartialsRange}`; + +type AMTriangleWithPartials = `amtriangle${PartialsRange}`; + +type AMTypeWithPartials = + | AMSineWithPartials + | AMSquareWithPartials + | AMSawtoothWithPartials + | AMTriangleWithPartials; /** * Fat Oscillators with partials */ -type FatSineWithPartials = - "fatsine1" | "fatsine2" | "fatsine3" | "fatsine4" | "fatsine5" | "fatsine6" | "fatsine7" | "fatsine8" | "fatsine9" | - "fatsine10" | "fatsine11" | "fatsine12" | "fatsine13" | "fatsine14" | "fatsine15" | "fatsine16" | "fatsine17" | "fatsine18" | "fatsine19" | - "fatsine20" | "fatsine21" | "fatsine22" | "fatsine23" | "fatsine24" | "fatsine25" | "fatsine26" | "fatsine27" | "fatsine28" | "fatsine29" | - "fatsine30" | "fatsine31" | "fatsine32"; - -type FatSquareWithPartials = - "fatsquare1" | "fatsquare2" | "fatsquare3" | "fatsquare4" | "fatsquare5" | "fatsquare6" | "fatsquare7" | "fatsquare8" | "fatsquare9" | - "fatsquare10" | "fatsquare11" | "fatsquare12" | "fatsquare13" | "fatsquare14" | "fatsquare15" | "fatsquare16" | "fatsquare17" | "fatsquare18" | "fatsquare19" | - "fatsquare20" | "fatsquare21" | "fatsquare22" | "fatsquare23" | "fatsquare24" | "fatsquare25" | "fatsquare26" | "fatsquare27" | "fatsquare28" | "fatsquare29" | - "fatsquare30" | "fatsquare31" | "fatsquare32"; - -type FatSawtoothWithPartials = - "fatsawtooth1" | "fatsawtooth2" | "fatsawtooth3" | "fatsawtooth4" | "fatsawtooth5" | "fatsawtooth6" | "fatsawtooth7" | "fatsawtooth8" | "fatsawtooth9" | - "fatsawtooth10" | "fatsawtooth11" | "fatsawtooth12" | "fatsawtooth13" | "fatsawtooth14" | "fatsawtooth15" | "fatsawtooth16" | "fatsawtooth17" | "fatsawtooth18" | "fatsawtooth19" | - "fatsawtooth20" | "fatsawtooth21" | "fatsawtooth22" | "fatsawtooth23" | "fatsawtooth24" | "fatsawtooth25" | "fatsawtooth26" | "fatsawtooth27" | "fatsawtooth28" | "fatsawtooth29" | - "fatsawtooth30" | "fatsawtooth31" | "fatsawtooth32"; - -type FatTriangleWithPartials = - "fattriangle1" | "fattriangle2" | "fattriangle3" | "fattriangle4" | "fattriangle5" | "fattriangle6" | "fattriangle7" | "fattriangle8" | "fattriangle9" | - "fattriangle10" | "fattriangle11" | "fattriangle12" | "fattriangle13" | "fattriangle14" | "fattriangle15" | "fattriangle16" | "fattriangle17" | "fattriangle18" | "fattriangle19" | - "fattriangle20" | "fattriangle21" | "fattriangle22" | "fattriangle23" | "fattriangle24" | "fattriangle25" | "fattriangle26" | "fattriangle27" | "fattriangle28" | "fattriangle29" | - "fattriangle30" | "fattriangle31" | "fattriangle32"; - -type FatTypeWithPartials = FatSineWithPartials | FatSquareWithPartials | FatSawtoothWithPartials | FatTriangleWithPartials; +type FatSineWithPartials = `fatsine${PartialsRange}`; + +type FatSquareWithPartials = `fatsquare${PartialsRange}`; + +type FatSawtoothWithPartials = `fatsawtooth${PartialsRange}`; + +type FatTriangleWithPartials = `fattriangle${PartialsRange}`; + +type FatTypeWithPartials = + | FatSineWithPartials + | FatSquareWithPartials + | FatSawtoothWithPartials + | FatTriangleWithPartials; /** * Omni FM @@ -437,17 +452,42 @@ interface OmniFatPartialsOscillatorOptions extends FatBaseOscillatorOptions { } export type OmniOscillatorType = - "fatsine" | "fatsquare" | "fatsawtooth" | "fattriangle" | "fatcustom" | FatTypeWithPartials | - "fmsine" | "fmsquare" | "fmsawtooth" | "fmtriangle" | "fmcustom" | FMTypeWithPartials | - "amsine" | "amsquare" | "amsawtooth" | "amtriangle" | "amcustom" | AMTypeWithPartials | - TypeWithPartials | OscillatorType | "pulse" | "pwm"; + | "fatsine" + | "fatsquare" + | "fatsawtooth" + | "fattriangle" + | "fatcustom" + | FatTypeWithPartials + | "fmsine" + | "fmsquare" + | "fmsawtooth" + | "fmtriangle" + | "fmcustom" + | FMTypeWithPartials + | "amsine" + | "amsquare" + | "amsawtooth" + | "amtriangle" + | "amcustom" + | AMTypeWithPartials + | TypeWithPartials + | OscillatorType + | "pulse" + | "pwm"; export type OmniOscillatorOptions = - PulseOscillatorOptions | PWMOscillatorOptions | - OmniFatCustomOscillatorOptions | OmniFatTypeOscillatorOptions | OmniFatPartialsOscillatorOptions | - OmniFMCustomOscillatorOptions | OmniFMTypeOscillatorOptions | OmniFMPartialsOscillatorOptions | - OmniAMCustomOscillatorOptions | OmniAMTypeOscillatorOptions | OmniAMPartialsOscillatorOptions | - ToneOscillatorConstructorOptions; + | PulseOscillatorOptions + | PWMOscillatorOptions + | OmniFatCustomOscillatorOptions + | OmniFatTypeOscillatorOptions + | OmniFatPartialsOscillatorOptions + | OmniFMCustomOscillatorOptions + | OmniFMTypeOscillatorOptions + | OmniFMPartialsOscillatorOptions + | OmniAMCustomOscillatorOptions + | OmniAMTypeOscillatorOptions + | OmniAMPartialsOscillatorOptions + | ToneOscillatorConstructorOptions; type OmitSourceOptions = Omit; @@ -455,8 +495,17 @@ type OmitSourceOptions = Omit | OmitSourceOptions | - OmitSourceOptions | OmitSourceOptions | OmitSourceOptions | - OmitSourceOptions | OmitSourceOptions | OmitSourceOptions | - OmitSourceOptions | OmitSourceOptions | OmitSourceOptions | - OmitSourceOptions | OmitSourceOptions | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions + | OmitSourceOptions; From 080856221ca191f076ab3eb6f1086a397206b3ea Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Mon, 29 Apr 2024 10:48:28 -0400 Subject: [PATCH 08/17] organizing docs (#1235) --- Tone/core/context/ToneAudioNode.ts | 1 + Tone/core/index.ts | 1 + Tone/core/util/Defaults.ts | 2 ++ scripts/typedoc.json | 9 +++++++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Tone/core/context/ToneAudioNode.ts b/Tone/core/context/ToneAudioNode.ts index 6276dedd..9deddb35 100644 --- a/Tone/core/context/ToneAudioNode.ts +++ b/Tone/core/context/ToneAudioNode.ts @@ -20,6 +20,7 @@ export type ToneAudioNodeOptions = ToneWithContextOptions; /** * ToneAudioNode is the base class for classes which process audio. + * @category Core */ export abstract class ToneAudioNode extends ToneWithContext { diff --git a/Tone/core/index.ts b/Tone/core/index.ts index 1d3b4f18..8f98a207 100644 --- a/Tone/core/index.ts +++ b/Tone/core/index.ts @@ -35,4 +35,5 @@ export { Unit }; // export the debug stuff as Debug import * as debug from "./util/Debug"; +/** @internal */ export { debug }; diff --git a/Tone/core/util/Defaults.ts b/Tone/core/util/Defaults.ts index 74297309..8da7d56b 100644 --- a/Tone/core/util/Defaults.ts +++ b/Tone/core/util/Defaults.ts @@ -52,6 +52,7 @@ export function deepEquals(arrayA: T[], arrayB: T[]): boolean { /** * Convert an args array into an object. + * @internal */ export function optionsFromArguments( defaults: T, @@ -101,6 +102,7 @@ export function getDefaultsFromInstance(instance: T): BaseToneOptions { /** * Returns the fallback if the given object is undefined. * Take an array of arguments and return a formatted options object. + * @internal */ export function defaultArg(given: T, fallback: T): T { if (isUndef(given)) { diff --git a/scripts/typedoc.json b/scripts/typedoc.json index 6c362cfa..054c4304 100644 --- a/scripts/typedoc.json +++ b/scripts/typedoc.json @@ -5,10 +5,15 @@ "defaultCategory" : "Global", "categorizeByGroup" : true, "categoryOrder" : ["Core", "Source", "Instrument", "Effect", "Component", "Signal"], + "navigation" : { + "includeCategories": true, + "includeFolders": false, + "includeGroups": true + }, "externalPattern": ["**/node_modules/**"], "excludeProtected" : true, "excludePrivate" : true, "hideGenerator": true, - "includeVersion": true, - "excludeInternal": true + "includeVersion": false, + "excludeInternal": true, } \ No newline at end of file From 57eacfa13bfff3f7c8448fec9cbc2ff4ca23acc2 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Mon, 29 Apr 2024 10:48:37 -0400 Subject: [PATCH 09/17] Updating link syntax (#1236) --- Tone/component/analysis/Analyser.ts | 6 ++-- Tone/component/analysis/FFT.ts | 6 ++-- Tone/component/analysis/Meter.ts | 8 +++--- Tone/component/analysis/Waveform.ts | 2 +- Tone/component/channel/Channel.ts | 12 ++++---- Tone/component/channel/MidSideMerge.ts | 4 +-- Tone/component/channel/MidSideSplit.ts | 2 +- Tone/component/channel/Recorder.ts | 2 +- Tone/component/dynamics/Gate.ts | 6 ++-- Tone/component/dynamics/Limiter.ts | 2 +- Tone/component/dynamics/MidSideCompressor.ts | 4 +-- .../component/dynamics/MultibandCompressor.ts | 2 +- Tone/component/envelope/FrequencyEnvelope.ts | 4 +-- Tone/component/filter/BiquadFilter.ts | 2 +- Tone/component/filter/LowpassCombFilter.ts | 2 +- Tone/core/Global.ts | 2 +- Tone/core/clock/TickParam.ts | 4 +-- Tone/core/clock/TransportEvent.ts | 2 +- Tone/core/context/AbstractParam.ts | 8 +++--- Tone/core/context/Context.ts | 20 ++++++------- Tone/core/context/Listener.ts | 2 +- Tone/core/context/Offline.ts | 2 +- Tone/core/context/ToneAudioNode.ts | 2 +- Tone/core/context/ToneWithContext.ts | 2 +- Tone/core/type/Time.ts | 2 +- .../ToneAudioWorkletProcessor.worklet.ts | 2 +- Tone/effect/AutoPanner.ts | 2 +- Tone/effect/AutoWah.ts | 2 +- Tone/effect/Chorus.ts | 6 ++-- Tone/effect/Freeverb.ts | 2 +- Tone/effect/JCReverb.ts | 4 +-- Tone/effect/LFOEffect.ts | 4 +-- Tone/effect/Reverb.ts | 6 ++-- Tone/effect/StereoXFeedbackEffect.ts | 2 +- Tone/effect/Tremolo.ts | 2 +- Tone/index.ts | 28 +++++++++---------- Tone/instrument/DuoSynth.ts | 2 +- Tone/instrument/Instrument.ts | 2 +- Tone/instrument/MetalSynth.ts | 4 +-- Tone/instrument/NoiseSynth.ts | 2 +- Tone/instrument/PluckSynth.ts | 2 +- Tone/instrument/Sampler.ts | 2 +- Tone/instrument/Synth.ts | 2 +- Tone/signal/Add.ts | 2 +- Tone/signal/AudioToGain.ts | 2 +- Tone/signal/GainToAudio.ts | 2 +- Tone/signal/Multiply.ts | 2 +- Tone/signal/ScaleExp.ts | 4 +-- Tone/signal/Signal.ts | 2 +- Tone/signal/SyncedSignal.ts | 2 +- Tone/source/buffer/Player.ts | 2 +- Tone/source/buffer/Players.ts | 2 +- Tone/source/oscillator/LFO.ts | 6 ++-- Tone/source/oscillator/OmniOscillator.ts | 18 ++++++------ Tone/source/oscillator/ToneOscillatorNode.ts | 2 +- 55 files changed, 116 insertions(+), 116 deletions(-) diff --git a/Tone/component/analysis/Analyser.ts b/Tone/component/analysis/Analyser.ts index 9718cb23..7f685b48 100644 --- a/Tone/component/analysis/Analyser.ts +++ b/Tone/component/analysis/Analyser.ts @@ -92,8 +92,8 @@ export class Analyser extends ToneAudioNode { } /** - * Run the analysis given the current settings. If [[channels]] = 1, - * it will return a Float32Array. If [[channels]] > 1, it will + * Run the analysis given the current settings. If {@link channels} = 1, + * it will return a Float32Array. If {@link channels} > 1, it will * return an array of Float32Arrays where each index in the array * represents the analysis done on a channel. */ @@ -128,7 +128,7 @@ export class Analyser extends ToneAudioNode { /** * The number of channels the analyser does the analysis on. Channel - * separation is done using [[Split]] + * separation is done using {@link Split} */ get channels(): number { return this._analysers.length; diff --git a/Tone/component/analysis/FFT.ts b/Tone/component/analysis/FFT.ts index 3aca60d6..30d0a862 100644 --- a/Tone/component/analysis/FFT.ts +++ b/Tone/component/analysis/FFT.ts @@ -51,7 +51,7 @@ export class FFT extends MeterBase { /** * Gets the current frequency data from the connected audio source. - * Returns the frequency data of length [[size]] as a Float32Array of decibel values. + * Returns the frequency data of length {@link size} as a Float32Array of decibel values. */ getValue(): Float32Array { const values = this._analyser.getValue() as Float32Array; @@ -60,7 +60,7 @@ export class FFT extends MeterBase { /** * The size of analysis. This must be a power of two in the range 16 to 16384. - * Determines the size of the array returned by [[getValue]] (i.e. the number of + * Determines the size of the array returned by {@link getValue} (i.e. the number of * frequency bins). Large FFT sizes may be costly to compute. */ get size(): PowerOfTwo { @@ -81,7 +81,7 @@ export class FFT extends MeterBase { } /** - * Returns the frequency value in hertz of each of the indices of the FFT's [[getValue]] response. + * Returns the frequency value in hertz of each of the indices of the FFT's {@link getValue} response. * @example * const fft = new Tone.FFT(32); * console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index))); diff --git a/Tone/component/analysis/Meter.ts b/Tone/component/analysis/Meter.ts index 2709c074..26e7f5c4 100644 --- a/Tone/component/analysis/Meter.ts +++ b/Tone/component/analysis/Meter.ts @@ -80,7 +80,7 @@ export class Meter extends MeterBase { } /** - * Use [[getValue]] instead. For the previous getValue behavior, use DCMeter. + * Use {@link getValue} instead. For the previous getValue behavior, use DCMeter. * @deprecated */ getLevel(): number | number[] { @@ -90,9 +90,9 @@ export class Meter extends MeterBase { /** * Get the current value of the incoming signal. - * Output is in decibels when [[normalRange]] is `false`. - * If [[channels]] = 1, then the output is a single number - * representing the value of the input signal. When [[channels]] > 1, + * Output is in decibels when {@link normalRange} is `false`. + * If {@link channels} = 1, then the output is a single number + * representing the value of the input signal. When {@link channels} > 1, * then each channel is returned as a value in a number array. */ getValue(): number | number[] { diff --git a/Tone/component/analysis/Waveform.ts b/Tone/component/analysis/Waveform.ts index bd8831c5..b66dc34b 100644 --- a/Tone/component/analysis/Waveform.ts +++ b/Tone/component/analysis/Waveform.ts @@ -46,7 +46,7 @@ export class Waveform extends MeterBase { /** * The size of analysis. This must be a power of two in the range 16 to 16384. - * Determines the size of the array returned by [[getValue]]. + * Determines the size of the array returned by {@link getValue}. */ get size(): PowerOfTwo { return this._analyser.size; diff --git a/Tone/component/channel/Channel.ts b/Tone/component/channel/Channel.ts index b7741bf5..6aa8d59d 100644 --- a/Tone/component/channel/Channel.ts +++ b/Tone/component/channel/Channel.ts @@ -17,7 +17,7 @@ export interface ChannelOptions extends ToneAudioNodeOptions { /** * Channel provides a channel strip interface with volume, pan, solo and mute controls. - * See [[PanVol]] and [[Solo]] + * See {@link PanVol} and {@link Solo} * @example * // pan the incoming signal left and drop the volume 12db * const channel = new Tone.Channel(-0.25, -12); @@ -91,7 +91,7 @@ export class Channel extends ToneAudioNode { } /** - * Solo/unsolo the channel. Soloing is only relative to other [[Channel]]s and [[Solo]] instances + * Solo/unsolo the channel. Soloing is only relative to other {@link Channel}s and {@link Solo} instances */ get solo(): boolean { return this._solo.solo; @@ -137,9 +137,9 @@ export class Channel extends ToneAudioNode { /** * Send audio to another channel using a string. `send` is a lot like - * [[connect]], except it uses a string instead of an object. This can - * be useful in large applications to decouple sections since [[send]] - * and [[receive]] can be invoked separately in order to connect an object + * {@link connect}, except it uses a string instead of an object. This can + * be useful in large applications to decouple sections since {@link send} + * and {@link receive} can be invoked separately in order to connect an object * @param name The channel name to send the audio * @param volume The amount of the signal to send. * Defaults to 0db, i.e. send the entire signal @@ -158,7 +158,7 @@ export class Channel extends ToneAudioNode { } /** - * Receive audio from a channel which was connected with [[send]]. + * Receive audio from a channel which was connected with {@link send}. * @param name The channel name to receive audio from. */ receive(name: string): this { diff --git a/Tone/component/channel/MidSideMerge.ts b/Tone/component/channel/MidSideMerge.ts index 45934e51..08f6741d 100644 --- a/Tone/component/channel/MidSideMerge.ts +++ b/Tone/component/channel/MidSideMerge.ts @@ -9,7 +9,7 @@ import { optionsFromArguments } from "../../core/util/Defaults"; export type MidSideMergeOptions = ToneAudioNodeOptions; /** - * MidSideMerge merges the mid and side signal after they've been separated by [[MidSideSplit]] + * MidSideMerge merges the mid and side signal after they've been separated by {@link MidSideSplit} * ``` * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right @@ -21,7 +21,7 @@ export class MidSideMerge extends ToneAudioNode { readonly name: string = "MidSideMerge"; /** - * There is no input, connect sources to either [[mid]] or [[side]] inputs. + * There is no input, connect sources to either {@link mid} or {@link side} inputs. */ readonly input: undefined; diff --git a/Tone/component/channel/MidSideSplit.ts b/Tone/component/channel/MidSideSplit.ts index ab2bccbb..1c9be390 100644 --- a/Tone/component/channel/MidSideSplit.ts +++ b/Tone/component/channel/MidSideSplit.ts @@ -23,7 +23,7 @@ export class MidSideSplit extends ToneAudioNode { readonly input: Split; /** - * There is no output node, use either [[mid]] or [[side]] outputs. + * There is no output node, use either {@link mid} or {@link side} outputs. */ readonly output: undefined; /** diff --git a/Tone/component/channel/Recorder.ts b/Tone/component/channel/Recorder.ts index 44ce0284..00ab9c60 100644 --- a/Tone/component/channel/Recorder.ts +++ b/Tone/component/channel/Recorder.ts @@ -127,7 +127,7 @@ export class Recorder extends ToneAudioNode { /** * Stop the recorder. Returns a promise with the recorded content until this point - * encoded as [[mimeType]] + * encoded as {@link mimeType} */ async stop(): Promise { assert(this.state !== "stopped", "Recorder is not started"); diff --git a/Tone/component/dynamics/Gate.ts b/Tone/component/dynamics/Gate.ts index 52f9c580..fd73359c 100644 --- a/Tone/component/dynamics/Gate.ts +++ b/Tone/component/dynamics/Gate.ts @@ -13,8 +13,8 @@ export interface GateOptions extends ToneAudioNodeOptions { /** * Gate only passes a signal through when the incoming - * signal exceeds a specified threshold. It uses [[Follower]] to follow the ampltiude - * of the incoming signal and compares it to the [[threshold]] value using [[GreaterThan]]. + * signal exceeds a specified threshold. It uses {@link Follower} to follow the ampltiude + * of the incoming signal and compares it to the {@link threshold} value using {@link GreaterThan}. * * @example * const gate = new Tone.Gate(-30, 0.2).toDestination(); @@ -90,7 +90,7 @@ export class Gate extends ToneAudioNode { } /** - * The attack/decay speed of the gate. See [[Follower.smoothing]] + * The attack/decay speed of the gate. See {@link Follower.smoothing} */ get smoothing(): Time { return this._follower.smoothing; diff --git a/Tone/component/dynamics/Limiter.ts b/Tone/component/dynamics/Limiter.ts index c9a9076b..5c880f65 100644 --- a/Tone/component/dynamics/Limiter.ts +++ b/Tone/component/dynamics/Limiter.ts @@ -11,7 +11,7 @@ export interface LimiterOptions extends ToneAudioNodeOptions { /** * Limiter will limit the loudness of an incoming signal. - * Under the hood it's composed of a [[Compressor]] with a fast attack + * Under the hood it's composed of a {@link Compressor} with a fast attack * and release and max compression ratio. * * @example diff --git a/Tone/component/dynamics/MidSideCompressor.ts b/Tone/component/dynamics/MidSideCompressor.ts index e4922bc3..fc5ecfa5 100644 --- a/Tone/component/dynamics/MidSideCompressor.ts +++ b/Tone/component/dynamics/MidSideCompressor.ts @@ -11,8 +11,8 @@ export interface MidSideCompressorOptions extends ToneAudioNodeOptions { } /** - * MidSideCompressor applies two different compressors to the [[mid]] - * and [[side]] signal components of the input. See [[MidSideSplit]] and [[MidSideMerge]]. + * MidSideCompressor applies two different compressors to the {@link mid} + * and {@link side} signal components of the input. See {@link MidSideSplit} and {@link MidSideMerge}. * @category Component */ export class MidSideCompressor extends ToneAudioNode { diff --git a/Tone/component/dynamics/MultibandCompressor.ts b/Tone/component/dynamics/MultibandCompressor.ts index 5c78336f..ad7d1e2c 100644 --- a/Tone/component/dynamics/MultibandCompressor.ts +++ b/Tone/component/dynamics/MultibandCompressor.ts @@ -16,7 +16,7 @@ export interface MultibandCompressorOptions extends ToneAudioNodeOptions { } /** - * A compressor with separate controls over low/mid/high dynamics. See [[Compressor]] and [[MultibandSplit]] + * A compressor with separate controls over low/mid/high dynamics. See {@link Compressor} and {@link MultibandSplit} * * @example * const multiband = new Tone.MultibandCompressor({ diff --git a/Tone/component/envelope/FrequencyEnvelope.ts b/Tone/component/envelope/FrequencyEnvelope.ts index 465386d2..8dca9920 100644 --- a/Tone/component/envelope/FrequencyEnvelope.ts +++ b/Tone/component/envelope/FrequencyEnvelope.ts @@ -11,8 +11,8 @@ export interface FrequencyEnvelopeOptions extends EnvelopeOptions { exponent: number; } /** - * FrequencyEnvelope is an [[Envelope]] which ramps between [[baseFrequency]] - * and [[octaves]]. It can also have an optional [[exponent]] to adjust the curve + * FrequencyEnvelope is an {@link Envelope} which ramps between {@link baseFrequency} + * and {@link octaves}. It can also have an optional {@link exponent} to adjust the curve * which it ramps. * @example * const oscillator = new Tone.Oscillator().toDestination().start(); diff --git a/Tone/component/filter/BiquadFilter.ts b/Tone/component/filter/BiquadFilter.ts index a52c5671..c09e069d 100644 --- a/Tone/component/filter/BiquadFilter.ts +++ b/Tone/component/filter/BiquadFilter.ts @@ -14,7 +14,7 @@ export interface BiquadFilterOptions extends ToneAudioNodeOptions { /** * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode). - * BiquadFilter is similar to [[Filter]] but doesn't have the option to set the "rolloff" value. + * BiquadFilter is similar to {@link Filter} but doesn't have the option to set the "rolloff" value. * @category Component */ export class BiquadFilter extends ToneAudioNode { diff --git a/Tone/component/filter/LowpassCombFilter.ts b/Tone/component/filter/LowpassCombFilter.ts index 69836e4a..38728315 100644 --- a/Tone/component/filter/LowpassCombFilter.ts +++ b/Tone/component/filter/LowpassCombFilter.ts @@ -14,7 +14,7 @@ interface LowpassCombFilterOptions extends ToneAudioNodeOptions { /** * A lowpass feedback comb filter. It is similar to - * [[FeedbackCombFilter]], but includes a lowpass filter. + * {@link FeedbackCombFilter}, but includes a lowpass filter. * @category Component */ export class LowpassCombFilter extends ToneAudioNode { diff --git a/Tone/core/Global.ts b/Tone/core/Global.ts index c4e3c471..13e93de2 100644 --- a/Tone/core/Global.ts +++ b/Tone/core/Global.ts @@ -18,7 +18,7 @@ const dummyContext = new DummyContext(); let globalContext: BaseContext = dummyContext; /** - * Returns the default system-wide [[Context]] + * Returns the default system-wide {@link Context} * @category Core */ export function getContext(): BaseContext { diff --git a/Tone/core/clock/TickParam.ts b/Tone/core/clock/TickParam.ts index b9ed6255..e9a0f77c 100644 --- a/Tone/core/clock/TickParam.ts +++ b/Tone/core/clock/TickParam.ts @@ -13,7 +13,7 @@ interface TickParamOptions extends ParamOptions extends Param } /** - * The inverse of [[ticksToTime]]. Convert a duration in + * The inverse of {@link ticksToTime}. Convert a duration in * seconds to the corresponding number of ticks accounting for any * automation curves starting at the given time. * @param duration The time interval to convert to ticks. diff --git a/Tone/core/clock/TransportEvent.ts b/Tone/core/clock/TransportEvent.ts index 33936abe..9563ff66 100644 --- a/Tone/core/clock/TransportEvent.ts +++ b/Tone/core/clock/TransportEvent.ts @@ -10,7 +10,7 @@ export interface TransportEventOptions { } /** - * TransportEvent is an internal class used by [[TransportClass]] + * TransportEvent is an internal class used by {@link TransportClass} * to schedule events. Do no invoke this class directly, it is * handled from within Tone.Transport. */ diff --git a/Tone/core/context/AbstractParam.ts b/Tone/core/context/AbstractParam.ts index b53c8217..8dc79d77 100644 --- a/Tone/core/context/AbstractParam.ts +++ b/Tone/core/context/AbstractParam.ts @@ -1,7 +1,7 @@ import { Time, UnitMap, UnitName } from "../type/Units"; /** - * Abstract base class for [[Param]] and [[Signal]] + * Abstract base class for {@link Param} and {@link Signal} */ export abstract class AbstractParam { @@ -37,8 +37,8 @@ export abstract class AbstractParam { /** * Creates a schedule point with the current value at the current time. - * Automation methods like [[linearRampToValueAtTime]] and [[exponentialRampToValueAtTime]] - * require a starting automation value usually set by [[setValueAtTime]]. This method + * Automation methods like {@link linearRampToValueAtTime} and {@link exponentialRampToValueAtTime} + * require a starting automation value usually set by {@link setValueAtTime}. This method * is useful since it will do a `setValueAtTime` with whatever the currently computed * value at the given time is. * @param time When to add a ramp point. @@ -196,7 +196,7 @@ export abstract class AbstractParam { abstract cancelScheduledValues(time: Time): this; /** - * This is similar to [[cancelScheduledValues]] except + * This is similar to {@link cancelScheduledValues} except * it holds the automated value at time until the next automated event. * @example * return Tone.Offline(() => { diff --git a/Tone/core/context/Context.ts b/Tone/core/context/Context.ts index d638ee04..0823ac8c 100644 --- a/Tone/core/context/Context.ts +++ b/Tone/core/context/Context.ts @@ -349,7 +349,7 @@ export class Context extends BaseContext { /** * Create an audio worklet node from a name and options. The module - * must first be loaded using [[addAudioWorkletModule]]. + * must first be loaded using {@link addAudioWorkletModule}. */ createAudioWorkletNode( name: string, @@ -413,7 +413,7 @@ export class Context extends BaseContext { * The amount of time into the future events are scheduled. Giving Web Audio * a short amount of time into the future to schedule events can reduce clicks and * improve performance. This value can be set to 0 to get the lowest latency. - * Adjusting this value also affects the [[updateInterval]]. + * Adjusting this value also affects the {@link updateInterval}. */ get lookAhead(): Seconds { return this._lookAhead; @@ -452,7 +452,7 @@ export class Context extends BaseContext { } /** - * The current audio context time plus a short [[lookAhead]]. + * The current audio context time plus a short {@link lookAhead}. * @example * setInterval(() => { * console.log("now", Tone.now()); @@ -463,11 +463,11 @@ export class Context extends BaseContext { } /** - * The current audio context time without the [[lookAhead]]. - * In most cases it is better to use [[now]] instead of [[immediate]] since - * with [[now]] the [[lookAhead]] is applied equally to _all_ components including internal components, - * to making sure that everything is scheduled in sync. Mixing [[now]] and [[immediate]] - * can cause some timing issues. If no lookAhead is desired, you can set the [[lookAhead]] to `0`. + * The current audio context time without the {@link lookAhead}. + * In most cases it is better to use {@link now} instead of {@link immediate} since + * with {@link now} the {@link lookAhead} is applied equally to _all_ components including internal components, + * to making sure that everything is scheduled in sync. Mixing {@link now} and {@link immediate} + * can cause some timing issues. If no lookAhead is desired, you can set the {@link lookAhead} to `0`. */ immediate(): Seconds { return this._context.currentTime; @@ -475,7 +475,7 @@ export class Context extends BaseContext { /** * Starts the audio context from a suspended state. This is required - * to initially start the AudioContext. See [[start]] + * to initially start the AudioContext. See {@link start} */ resume(): Promise { if (isAudioContext(this._context)) { @@ -593,7 +593,7 @@ export class Context extends BaseContext { } /** - * Clear the function scheduled by [[setInterval]] + * Clear the function scheduled by {@link setInterval} */ clearInterval(id: number): this { return this.clearTimeout(id); diff --git a/Tone/core/context/Listener.ts b/Tone/core/context/Listener.ts index 640b6e62..68c0f7f1 100644 --- a/Tone/core/context/Listener.ts +++ b/Tone/core/context/Listener.ts @@ -16,7 +16,7 @@ export interface ListenerOptions extends ToneAudioNodeOptions{ /** * Tone.Listener is a thin wrapper around the AudioListener. Listener combined - * with [[Panner3D]] makes up the Web Audio API's 3D panning system. Panner3D allows you + * with {@link Panner3D} makes up the Web Audio API's 3D panning system. Panner3D allows you * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from * a first-person perspective. There is only one listener per audio context. */ diff --git a/Tone/core/context/Offline.ts b/Tone/core/context/Offline.ts index 4ffa0a78..f33d6632 100644 --- a/Tone/core/context/Offline.ts +++ b/Tone/core/context/Offline.ts @@ -6,7 +6,7 @@ import { ToneAudioBuffer } from "./ToneAudioBuffer"; /** * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext. * The OfflineAudioContext is capable of rendering much faster than real time in many cases. - * The callback function also passes in an offline instance of [[Context]] which can be used + * The callback function also passes in an offline instance of {@link Context} which can be used * to schedule events along the Transport. * @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer. * @param duration the amount of time to record for. diff --git a/Tone/core/context/ToneAudioNode.ts b/Tone/core/context/ToneAudioNode.ts index 9deddb35..ec98d39d 100644 --- a/Tone/core/context/ToneAudioNode.ts +++ b/Tone/core/context/ToneAudioNode.ts @@ -212,7 +212,7 @@ export abstract class ToneAudioNode ex /** * Convert the incoming time to seconds. - * This is calculated against the current [[TransportClass]] bpm + * This is calculated against the current {@link TransportClass} bpm * @example * const gain = new Tone.Gain(); * setInterval(() => console.log(gain.toSeconds("4n")), 100); diff --git a/Tone/core/type/Time.ts b/Tone/core/type/Time.ts index 474d5b9f..196e5135 100644 --- a/Tone/core/type/Time.ts +++ b/Tone/core/type/Time.ts @@ -137,7 +137,7 @@ export class TimeClass { } /** - * Sync the filter to the transport. See [[LFO.sync]] + * Sync the filter to the transport. See {@link LFO.sync} */ sync(): this { this._lfoL.sync(); diff --git a/Tone/effect/Freeverb.ts b/Tone/effect/Freeverb.ts index 3f7178bb..d2044acc 100644 --- a/Tone/effect/Freeverb.ts +++ b/Tone/effect/Freeverb.ts @@ -23,7 +23,7 @@ const allpassFilterFrequencies = [225, 556, 441, 341]; /** * Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html). * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp). - * Freeverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]]. + * Freeverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using {@link Reverb}. * @example * const freeverb = new Tone.Freeverb().toDestination(); * freeverb.dampening = 1000; diff --git a/Tone/effect/JCReverb.ts b/Tone/effect/JCReverb.ts index 2edd25d9..0aeb4ca1 100644 --- a/Tone/effect/JCReverb.ts +++ b/Tone/effect/JCReverb.ts @@ -28,8 +28,8 @@ const allpassFilterFreqs = [347, 113, 37]; /** * JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html) * tuned by John Chowning in 1970. - * It is made up of three allpass filters and four [[FeedbackCombFilter]]. - * JCReverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]]. + * It is made up of three allpass filters and four {@link FeedbackCombFilter}. + * JCReverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using {@link Reverb}. * @example * const reverb = new Tone.JCReverb(0.4).toDestination(); * const delay = new Tone.FeedbackDelay(0.5); diff --git a/Tone/effect/LFOEffect.ts b/Tone/effect/LFOEffect.ts index 03c90c93..c0bf371f 100644 --- a/Tone/effect/LFOEffect.ts +++ b/Tone/effect/LFOEffect.ts @@ -76,7 +76,7 @@ export abstract class LFOEffect extends Effect } /** - * Sync the filter to the transport. See [[LFO.sync]] + * Sync the filter to the transport. See {@link LFO.sync} */ sync(): this { this._lfo.sync(); @@ -92,7 +92,7 @@ export abstract class LFOEffect extends Effect } /** - * The type of the LFO's oscillator: See [[Oscillator.type]] + * The type of the LFO's oscillator: See {@link Oscillator.type} * @example * const autoFilter = new Tone.AutoFilter().start().toDestination(); * const noise = new Tone.Noise().start().connect(autoFilter); diff --git a/Tone/effect/Reverb.ts b/Tone/effect/Reverb.ts index 0a274f38..e135f5d8 100644 --- a/Tone/effect/Reverb.ts +++ b/Tone/effect/Reverb.ts @@ -18,7 +18,7 @@ interface ReverbOptions extends EffectOptions { * Generates an Impulse Response Buffer * with Tone.Offline then feeds the IR into ConvolverNode. * The impulse response generation is async, so you have - * to wait until [[ready]] resolves before it will make a sound. + * to wait until {@link ready} resolves before it will make a sound. * * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen). * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License. @@ -45,8 +45,8 @@ export class Reverb extends Effect { private _preDelay: Seconds; /** - * Resolves when the reverb buffer is generated. Whenever either [[decay]] - * or [[preDelay]] are set, you have to wait until [[ready]] resolves + * Resolves when the reverb buffer is generated. Whenever either {@link decay} + * or {@link preDelay} are set, you have to wait until {@link ready} resolves * before the IR is generated with the latest values. */ ready: Promise = Promise.resolve(); diff --git a/Tone/effect/StereoXFeedbackEffect.ts b/Tone/effect/StereoXFeedbackEffect.ts index 9e906dd5..0e463a1b 100644 --- a/Tone/effect/StereoXFeedbackEffect.ts +++ b/Tone/effect/StereoXFeedbackEffect.ts @@ -7,7 +7,7 @@ export interface StereoXFeedbackEffectOptions extends StereoFeedbackEffectOption } /** - * Just like a [[StereoFeedbackEffect]], but the feedback is routed from left to right + * Just like a {@link StereoFeedbackEffect}, but the feedback is routed from left to right * and right to left instead of on the same channel. * ``` * +--------------------------------+ feedbackL <-----------------------------------+ diff --git a/Tone/effect/Tremolo.ts b/Tone/effect/Tremolo.ts index ba750f75..fec39dcc 100644 --- a/Tone/effect/Tremolo.ts +++ b/Tone/effect/Tremolo.ts @@ -15,7 +15,7 @@ export interface TremoloOptions extends StereoEffectOptions { } /** - * Tremolo modulates the amplitude of an incoming signal using an [[LFO]]. + * Tremolo modulates the amplitude of an incoming signal using an {@link LFO}. * The effect is a stereo effect where the modulation phase is inverted in each channel. * * @example diff --git a/Tone/index.ts b/Tone/index.ts index 5172c096..61afedc8 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -8,8 +8,8 @@ import { Seconds } from "./core/type/Units"; export { supported } from "./core/context/AudioContext"; /** - * The current audio context time of the global [[Context]]. - * See [[Context.now]] + * The current audio context time of the global {@link Context}. + * See {@link Context.now} * @category Core */ export function now(): Seconds { @@ -17,8 +17,8 @@ export function now(): Seconds { } /** - * The current audio context time of the global [[Context]] without the [[Context.lookAhead]] - * See [[Context.immediate]] + * The current audio context time of the global {@link Context} without the {@link Context.lookAhead} + * See {@link Context.immediate} * @category Core */ export function immediate(): Seconds { @@ -27,7 +27,7 @@ export function immediate(): Seconds { /** * The Transport object belonging to the global Tone.js Context. - * See [[TransportClass]] + * See {@link TransportClass} * @category Core * @deprecated Use {@link getTransport} instead */ @@ -35,7 +35,7 @@ export const Transport = getContext().transport; /** * The Transport object belonging to the global Tone.js Context. - * See [[TransportClass]] + * See {@link TransportClass} * @category Core */ export function getTransport(): import("./core/clock/Transport").TransportClass { @@ -44,7 +44,7 @@ export function getTransport(): import("./core/clock/Transport").TransportClass /** * The Destination (output) belonging to the global Tone.js Context. - * See [[DestinationClass]] + * See {@link DestinationClass} * @category Core * @deprecated Use {@link getDestination} instead */ @@ -57,7 +57,7 @@ export const Master = getContext().destination; /** * The Destination (output) belonging to the global Tone.js Context. - * See [[DestinationClass]] + * See {@link DestinationClass} * @category Core */ export function getDestination(): import("./core/context/Destination").DestinationClass { @@ -65,14 +65,14 @@ export function getDestination(): import("./core/context/Destination").Destinati } /** - * The [[ListenerClass]] belonging to the global Tone.js Context. + * The {@link ListenerClass} belonging to the global Tone.js Context. * @category Core * @deprecated Use {@link getListener} instead */ export const Listener = getContext().listener; /** - * The [[ListenerClass]] belonging to the global Tone.js Context. + * The {@link ListenerClass} belonging to the global Tone.js Context. * @category Core */ export function getListener(): import("./core/context/Listener").ListenerClass { @@ -81,7 +81,7 @@ export function getListener(): import("./core/context/Listener").ListenerClass { /** * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See [[DrawClass]] + * See {@link DrawClass} * @category Core * @deprecated Use {@link getDraw} instead */ @@ -90,7 +90,7 @@ export const Draw = getContext().draw; /** * Get the singleton attached to the global context. * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See [[DrawClass]] + * See {@link DrawClass} * @category Core */ export function getDraw(): import("./core/util/Draw").DrawClass { @@ -99,14 +99,14 @@ export function getDraw(): import("./core/util/Draw").DrawClass { /** * A reference to the global context - * See [[Context]] + * See {@link Context} * @deprecated Use {@link getContext} instead */ export const context = getContext(); /** * Promise which resolves when all of the loading promises are resolved. - * Alias for static [[ToneAudioBuffer.loaded]] method. + * Alias for static {@link ToneAudioBuffer.loaded} method. * @category Core */ export function loaded() { diff --git a/Tone/instrument/DuoSynth.ts b/Tone/instrument/DuoSynth.ts index 09284b51..8e8f616f 100644 --- a/Tone/instrument/DuoSynth.ts +++ b/Tone/instrument/DuoSynth.ts @@ -18,7 +18,7 @@ export interface DuoSynthOptions extends MonophonicOptions { } /** - * DuoSynth is a monophonic synth composed of two [[MonoSynth]]s run in parallel with control over the + * DuoSynth is a monophonic synth composed of two {@link MonoSynth}s run in parallel with control over the * frequency ratio between the two voices and vibrato effect. * @example * const duoSynth = new Tone.DuoSynth().toDestination(); diff --git a/Tone/instrument/Instrument.ts b/Tone/instrument/Instrument.ts index def4a98f..24564f92 100644 --- a/Tone/instrument/Instrument.ts +++ b/Tone/instrument/Instrument.ts @@ -67,7 +67,7 @@ export abstract class Instrument extends Tone /** * Sync the instrument to the Transport. All subsequent calls of - * [[triggerAttack]] and [[triggerRelease]] will be scheduled along the transport. + * {@link triggerAttack} and {@link triggerRelease} will be scheduled along the transport. * @example * const fmSynth = new Tone.FMSynth().toDestination(); * fmSynth.volume.value = -6; diff --git a/Tone/instrument/MetalSynth.ts b/Tone/instrument/MetalSynth.ts index f15974b3..b5f346a2 100644 --- a/Tone/instrument/MetalSynth.ts +++ b/Tone/instrument/MetalSynth.ts @@ -91,7 +91,7 @@ export class MetalSynth extends Monophonic { /** * The envelope which is connected both to the * amplitude and a highpass filter's cutoff frequency. - * The lower-limit of the filter is controlled by the [[resonance]] + * The lower-limit of the filter is controlled by the {@link resonance} */ readonly envelope: Envelope; @@ -231,7 +231,7 @@ export class MetalSynth extends Monophonic { /** * The modulationIndex of the oscillators which make up the source. - * see [[FMOscillator.modulationIndex]] + * see {@link FMOscillator.modulationIndex} * @min 1 * @max 100 */ diff --git a/Tone/instrument/NoiseSynth.ts b/Tone/instrument/NoiseSynth.ts index 785241cb..45373f67 100644 --- a/Tone/instrument/NoiseSynth.ts +++ b/Tone/instrument/NoiseSynth.ts @@ -17,7 +17,7 @@ export interface NoiseSynthOptions extends InstrumentOptions { } /** - * Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]]. + * Tone.NoiseSynth is composed of {@link Noise} through an {@link AmplitudeEnvelope}. * ``` * +-------+ +-------------------+ * | Noise +>--> AmplitudeEnvelope +>--> Output diff --git a/Tone/instrument/PluckSynth.ts b/Tone/instrument/PluckSynth.ts index 1ab13f41..27bb53ea 100644 --- a/Tone/instrument/PluckSynth.ts +++ b/Tone/instrument/PluckSynth.ts @@ -111,7 +111,7 @@ export class PluckSynth extends Instrument { } /** - * Ramp down the [[resonance]] to 0 over the duration of the release time. + * Ramp down the {@link resonance} to 0 over the duration of the release time. */ triggerRelease(time?: Time): this { this._lfcf.resonance.linearRampTo(0, this.release, time); diff --git a/Tone/instrument/Sampler.ts b/Tone/instrument/Sampler.ts index 9efb1f48..fc00c9d0 100644 --- a/Tone/instrument/Sampler.ts +++ b/Tone/instrument/Sampler.ts @@ -33,7 +33,7 @@ export interface SamplerOptions extends InstrumentOptions { * were not explicitly included which can save loading time. * * For sample or buffer playback where repitching is not necessary, - * use [[Player]]. + * use {@link Player}. * @example * const sampler = new Tone.Sampler({ * urls: { diff --git a/Tone/instrument/Synth.ts b/Tone/instrument/Synth.ts index 27ff67ef..2c4bf66d 100644 --- a/Tone/instrument/Synth.ts +++ b/Tone/instrument/Synth.ts @@ -17,7 +17,7 @@ export interface SynthOptions extends MonophonicOptions { } /** - * Synth is composed simply of a [[OmniOscillator]] routed through an [[AmplitudeEnvelope]]. + * Synth is composed simply of a {@link OmniOscillator} routed through an {@link AmplitudeEnvelope}. * ``` * +----------------+ +-------------------+ * | OmniOscillator +>--> AmplitudeEnvelope +>--> Output diff --git a/Tone/signal/Add.ts b/Tone/signal/Add.ts index f084d8b0..4f12cd4d 100644 --- a/Tone/signal/Add.ts +++ b/Tone/signal/Add.ts @@ -39,7 +39,7 @@ export class Add extends Signal { readonly addend: Param<"number"> = this._param; /** - * @param value If no value is provided, will sum the input and [[addend]]. + * @param value If no value is provided, will sum the input and {@link addend}. */ constructor(value?: number); constructor(options?: Partial>); diff --git a/Tone/signal/AudioToGain.ts b/Tone/signal/AudioToGain.ts index 8c515ee3..f4c27204 100644 --- a/Tone/signal/AudioToGain.ts +++ b/Tone/signal/AudioToGain.ts @@ -4,7 +4,7 @@ import { WaveShaper } from "./WaveShaper"; /** * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. - * See [[GainToAudio]]. + * See {@link GainToAudio}. * @category Signal */ export class AudioToGain extends SignalOperator { diff --git a/Tone/signal/GainToAudio.ts b/Tone/signal/GainToAudio.ts index 3aacdad1..a3304621 100644 --- a/Tone/signal/GainToAudio.ts +++ b/Tone/signal/GainToAudio.ts @@ -4,7 +4,7 @@ import { WaveShaper } from "./WaveShaper"; /** * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1]. - * See [[AudioToGain]]. + * See {@link AudioToGain}. * @category Signal */ export class GainToAudio extends SignalOperator { diff --git a/Tone/signal/Multiply.ts b/Tone/signal/Multiply.ts index 0dc4bce9..9b22b423 100644 --- a/Tone/signal/Multiply.ts +++ b/Tone/signal/Multiply.ts @@ -43,7 +43,7 @@ export class Multiply extends input: InputNode; /** - * The product of the input and [[factor]] + * The product of the input and {@link factor} */ output: OutputNode; diff --git a/Tone/signal/ScaleExp.ts b/Tone/signal/ScaleExp.ts index fdfdccfa..a66b75e1 100644 --- a/Tone/signal/ScaleExp.ts +++ b/Tone/signal/ScaleExp.ts @@ -50,8 +50,8 @@ export class ScaleExp extends Scale { } /** - * Instead of interpolating linearly between the [[min]] and - * [[max]] values, setting the exponent will interpolate between + * Instead of interpolating linearly between the {@link min} and + * {@link max} values, setting the exponent will interpolate between * the two values with an exponential curve. */ get exponent(): Positive { diff --git a/Tone/signal/Signal.ts b/Tone/signal/Signal.ts index afc919f9..a15c6ca5 100644 --- a/Tone/signal/Signal.ts +++ b/Tone/signal/Signal.ts @@ -192,7 +192,7 @@ export class Signal extends ToneAudioNode< } /** - * See [[Param.apply]]. + * See {@link Param.apply}. */ apply(param: Param | AudioParam): this { this._param.apply(param); diff --git a/Tone/signal/SyncedSignal.ts b/Tone/signal/SyncedSignal.ts index 94e33eda..362cd060 100644 --- a/Tone/signal/SyncedSignal.ts +++ b/Tone/signal/SyncedSignal.ts @@ -6,7 +6,7 @@ import { ToneConstantSource } from "./ToneConstantSource"; import { OutputNode } from "../core/context/ToneAudioNode"; /** - * Adds the ability to synchronize the signal to the [[TransportClass]] + * Adds the ability to synchronize the signal to the {@link TransportClass} * @category Signal */ export class SyncedSignal extends Signal { diff --git a/Tone/source/buffer/Player.ts b/Tone/source/buffer/Player.ts index fbb88ab5..1d36c03e 100644 --- a/Tone/source/buffer/Player.ts +++ b/Tone/source/buffer/Player.ts @@ -432,7 +432,7 @@ export class Player extends Source { } /** - * If the buffer should be reversed. Note that this sets the underlying [[ToneAudioBuffer.reverse]], so + * If the buffer should be reversed. Note that this sets the underlying {@link ToneAudioBuffer.reverse}, so * if multiple players are pointing at the same ToneAudioBuffer, they will all be reversed. * @example * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/chime_1.mp3").toDestination(); diff --git a/Tone/source/buffer/Players.ts b/Tone/source/buffer/Players.ts index c75b45a9..056b308b 100644 --- a/Tone/source/buffer/Players.ts +++ b/Tone/source/buffer/Players.ts @@ -23,7 +23,7 @@ export interface PlayersOptions extends SourceOptions { } /** - * Players combines multiple [[Player]] objects. + * Players combines multiple {@link Player} objects. * @category Source */ export class Players extends ToneAudioNode { diff --git a/Tone/source/oscillator/LFO.ts b/Tone/source/oscillator/LFO.ts index a5fc6971..24d9a675 100644 --- a/Tone/source/oscillator/LFO.ts +++ b/Tone/source/oscillator/LFO.ts @@ -94,7 +94,7 @@ export class LFO extends ToneAudioNode { private _units: UnitName = "number"; /** - * If the input value is converted using the [[units]] + * If the input value is converted using the {@link units} */ convert = true; @@ -238,7 +238,7 @@ export class LFO extends ToneAudioNode { } /** - * The type of the oscillator: See [[Oscillator.type]] + * The type of the oscillator: See {@link Oscillator.type} */ get type(): ToneOscillatorType { return this._oscillator.type; @@ -249,7 +249,7 @@ export class LFO extends ToneAudioNode { } /** - * The oscillator's partials array: See [[Oscillator.partials]] + * The oscillator's partials array: See {@link Oscillator.partials} */ get partials(): number[] { return this._oscillator.partials; diff --git a/Tone/source/oscillator/OmniOscillator.ts b/Tone/source/oscillator/OmniOscillator.ts index 562d2ee2..7d79456c 100644 --- a/Tone/source/oscillator/OmniOscillator.ts +++ b/Tone/source/oscillator/OmniOscillator.ts @@ -192,7 +192,7 @@ export class OmniOscillator /** * The value is an empty array when the type is not "custom". * This is not available on "pwm" and "pulse" oscillator types. - * See [[Oscillator.partials]] + * See {@link Oscillator.partials} */ get partials(): number[] { return this._oscillator.partials; @@ -297,7 +297,7 @@ export class OmniOscillator } /** - * The base type of the oscillator. See [[Oscillator.baseType]] + * The base type of the oscillator. See {@link Oscillator.baseType} * @example * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4"); * console.log(omniOsc.sourceType, omniOsc.baseType, omniOsc.partialCount); @@ -315,7 +315,7 @@ export class OmniOscillator /** * The width of the oscillator when sourceType === "pulse". - * See [[PWMOscillator]] + * See {@link PWMOscillator} */ get width(): IsPulseOscillator> { if (this._getOscType(this._oscillator, "pulse")) { @@ -327,7 +327,7 @@ export class OmniOscillator /** * The number of detuned oscillators when sourceType === "fat". - * See [[FatOscillator.count]] + * See {@link FatOscillator.count} */ get count(): IsFatOscillator { if (this._getOscType(this._oscillator, "fat")) { @@ -344,7 +344,7 @@ export class OmniOscillator /** * The detune spread between the oscillators when sourceType === "fat". - * See [[FatOscillator.count]] + * See {@link FatOscillator.count} */ get spread(): IsFatOscillator { if (this._getOscType(this._oscillator, "fat")) { @@ -361,7 +361,7 @@ export class OmniOscillator /** * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types. - * See [[AMOscillator]] or [[FMOscillator]] + * See {@link AMOscillator} or {@link FMOscillator} */ get modulationType(): IsAmOrFmOscillator { if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { @@ -378,7 +378,7 @@ export class OmniOscillator /** * The modulation index when the sourceType === "fm" - * See [[FMOscillator]]. + * See {@link FMOscillator}. */ get modulationIndex(): IsFMOscillator> { if (this._getOscType(this._oscillator, "fm")) { @@ -390,7 +390,7 @@ export class OmniOscillator /** * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. - * See [[AMOscillator]] or [[FMOscillator]] + * See {@link AMOscillator} or {@link FMOscillator} */ get harmonicity(): IsAmOrFmOscillator> { if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { @@ -402,7 +402,7 @@ export class OmniOscillator /** * The modulationFrequency Signal of the oscillator when sourceType === "pwm" - * see [[PWMOscillator]] + * see {@link PWMOscillator} * @min 0.1 * @max 5 */ diff --git a/Tone/source/oscillator/ToneOscillatorNode.ts b/Tone/source/oscillator/ToneOscillatorNode.ts index 47ea576e..5766085c 100644 --- a/Tone/source/oscillator/ToneOscillatorNode.ts +++ b/Tone/source/oscillator/ToneOscillatorNode.ts @@ -14,7 +14,7 @@ export interface ToneOscillatorNodeOptions extends OneShotSourceOptions { /** * Wrapper around the native fire-and-forget OscillatorNode. * Adds the ability to reschedule the stop method. - * ***[[Oscillator]] is better for most use-cases*** + * ***{@link Oscillator} is better for most use-cases*** * @category Source */ export class ToneOscillatorNode extends OneShotSource { From f2160618aa6d59ca709f9fd791c0872120f8b299 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Mon, 29 Apr 2024 12:59:49 -0400 Subject: [PATCH 10/17] Using @see typedoc (#1237) --- Tone/component/analysis/DCMeter.ts | 3 ++- Tone/component/analysis/Meter.ts | 3 ++- Tone/component/channel/Channel.ts | 2 +- Tone/component/dynamics/Gate.ts | 3 ++- Tone/component/dynamics/MidSideCompressor.ts | 3 ++- .../component/dynamics/MultibandCompressor.ts | 3 ++- Tone/core/clock/Transport.ts | 2 +- Tone/core/context/Context.ts | 3 ++- Tone/core/context/ToneAudioNode.ts | 2 +- Tone/effect/Chorus.ts | 3 ++- Tone/effect/LFOEffect.ts | 6 +++-- Tone/event/Pattern.ts | 2 +- Tone/index.ts | 23 ++++++++++--------- Tone/signal/AudioToGain.ts | 2 +- Tone/signal/GainToAudio.ts | 2 +- Tone/signal/Signal.ts | 2 +- Tone/source/Source.ts | 3 ++- Tone/source/oscillator/LFO.ts | 6 +++-- Tone/source/oscillator/OmniOscillator.ts | 17 +++++++------- Tone/source/oscillator/Oscillator.ts | 2 +- 20 files changed, 53 insertions(+), 39 deletions(-) diff --git a/Tone/component/analysis/DCMeter.ts b/Tone/component/analysis/DCMeter.ts index d36c9ed8..5da5770c 100644 --- a/Tone/component/analysis/DCMeter.ts +++ b/Tone/component/analysis/DCMeter.ts @@ -4,7 +4,8 @@ import { MeterBase, MeterBaseOptions } from "./MeterBase"; export type DCMeterOptions = MeterBaseOptions; /** - * DCMeter gets the raw value of the input signal at the current time. See also {@link Meter}. + * DCMeter gets the raw value of the input signal at the current time. + * @see {@link Meter}. * * @example * const meter = new Tone.DCMeter(); diff --git a/Tone/component/analysis/Meter.ts b/Tone/component/analysis/Meter.ts index 26e7f5c4..1a8f00b4 100644 --- a/Tone/component/analysis/Meter.ts +++ b/Tone/component/analysis/Meter.ts @@ -16,7 +16,8 @@ export interface MeterOptions extends MeterBaseOptions { * of an input signal. It can also get the raw value of the input signal. * Setting `normalRange` to `true` will covert the output to a range of * 0-1. See an example using a graphical display - * [here](https://tonejs.github.io/examples/meter). See also {@link DCMeter}. + * [here](https://tonejs.github.io/examples/meter). + * @see {@link DCMeter}. * * @example * const meter = new Tone.Meter(); diff --git a/Tone/component/channel/Channel.ts b/Tone/component/channel/Channel.ts index 6aa8d59d..6b199f23 100644 --- a/Tone/component/channel/Channel.ts +++ b/Tone/component/channel/Channel.ts @@ -17,7 +17,7 @@ export interface ChannelOptions extends ToneAudioNodeOptions { /** * Channel provides a channel strip interface with volume, pan, solo and mute controls. - * See {@link PanVol} and {@link Solo} + * @see {@link PanVol} and {@link Solo} * @example * // pan the incoming signal left and drop the volume 12db * const channel = new Tone.Channel(-0.25, -12); diff --git a/Tone/component/dynamics/Gate.ts b/Tone/component/dynamics/Gate.ts index fd73359c..809425b6 100644 --- a/Tone/component/dynamics/Gate.ts +++ b/Tone/component/dynamics/Gate.ts @@ -90,7 +90,8 @@ export class Gate extends ToneAudioNode { } /** - * The attack/decay speed of the gate. See {@link Follower.smoothing} + * The attack/decay speed of the gate. + * @see {@link Follower.smoothing} */ get smoothing(): Time { return this._follower.smoothing; diff --git a/Tone/component/dynamics/MidSideCompressor.ts b/Tone/component/dynamics/MidSideCompressor.ts index fc5ecfa5..1b42d8e4 100644 --- a/Tone/component/dynamics/MidSideCompressor.ts +++ b/Tone/component/dynamics/MidSideCompressor.ts @@ -12,7 +12,8 @@ export interface MidSideCompressorOptions extends ToneAudioNodeOptions { /** * MidSideCompressor applies two different compressors to the {@link mid} - * and {@link side} signal components of the input. See {@link MidSideSplit} and {@link MidSideMerge}. + * and {@link side} signal components of the input. + * @see {@link MidSideSplit} and {@link MidSideMerge}. * @category Component */ export class MidSideCompressor extends ToneAudioNode { diff --git a/Tone/component/dynamics/MultibandCompressor.ts b/Tone/component/dynamics/MultibandCompressor.ts index ad7d1e2c..9290c7dd 100644 --- a/Tone/component/dynamics/MultibandCompressor.ts +++ b/Tone/component/dynamics/MultibandCompressor.ts @@ -16,7 +16,8 @@ export interface MultibandCompressorOptions extends ToneAudioNodeOptions { } /** - * A compressor with separate controls over low/mid/high dynamics. See {@link Compressor} and {@link MultibandSplit} + * A compressor with separate controls over low/mid/high dynamics. + * @see {@link Compressor} and {@link MultibandSplit} * * @example * const multiband = new Tone.MultibandCompressor({ diff --git a/Tone/core/clock/Transport.ts b/Tone/core/clock/Transport.ts index 66caf493..effe2588 100644 --- a/Tone/core/clock/Transport.ts +++ b/Tone/core/clock/Transport.ts @@ -756,7 +756,7 @@ export class TransportClass /** * Unsyncs a previously synced signal from the transport's control. - * See Transport.syncSignal. + * @see {@link syncSignal}. */ unsyncSignal(signal: Signal): this { for (let i = this._syncedSignals.length - 1; i >= 0; i--) { diff --git a/Tone/core/context/Context.ts b/Tone/core/context/Context.ts index 0823ac8c..b83cbadf 100644 --- a/Tone/core/context/Context.ts +++ b/Tone/core/context/Context.ts @@ -475,7 +475,8 @@ export class Context extends BaseContext { /** * Starts the audio context from a suspended state. This is required - * to initially start the AudioContext. See {@link start} + * to initially start the AudioContext. + * @see {@link start} */ resume(): Promise { if (isAudioContext(this._context)) { diff --git a/Tone/core/context/ToneAudioNode.ts b/Tone/core/context/ToneAudioNode.ts index ec98d39d..bebb3d75 100644 --- a/Tone/core/context/ToneAudioNode.ts +++ b/Tone/core/context/ToneAudioNode.ts @@ -212,7 +212,7 @@ export abstract class ToneAudioNode { } /** - * Sync the filter to the transport. See {@link LFO.sync} + * Sync the filter to the transport. + * @see {@link LFO.sync} */ sync(): this { this._lfoL.sync(); diff --git a/Tone/effect/LFOEffect.ts b/Tone/effect/LFOEffect.ts index c0bf371f..7439f1aa 100644 --- a/Tone/effect/LFOEffect.ts +++ b/Tone/effect/LFOEffect.ts @@ -76,7 +76,8 @@ export abstract class LFOEffect extends Effect } /** - * Sync the filter to the transport. See {@link LFO.sync} + * Sync the filter to the transport. + * @see {@link LFO.sync} */ sync(): this { this._lfo.sync(); @@ -92,7 +93,8 @@ export abstract class LFOEffect extends Effect } /** - * The type of the LFO's oscillator: See {@link Oscillator.type} + * The type of the LFO's oscillator. + * @see {@link Oscillator.type} * @example * const autoFilter = new Tone.AutoFilter().start().toDestination(); * const noise = new Tone.Noise().start().connect(autoFilter); diff --git a/Tone/event/Pattern.ts b/Tone/event/Pattern.ts index 0f2e0f1c..ab79d5a7 100644 --- a/Tone/event/Pattern.ts +++ b/Tone/event/Pattern.ts @@ -121,7 +121,7 @@ export class Pattern extends Loop> { } /** - * The pattern type. See Tone.CtrlPattern for the full list of patterns. + * The pattern type. */ get pattern(): PatternName { return this._type; diff --git a/Tone/index.ts b/Tone/index.ts index 61afedc8..e1b978fd 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -1,4 +1,5 @@ export { getContext, setContext } from "./core/Global"; +import { BaseContext } from "./core/context/BaseContext"; export * from "./classes"; export * from "./version"; import { getContext } from "./core/Global"; @@ -8,8 +9,8 @@ import { Seconds } from "./core/type/Units"; export { supported } from "./core/context/AudioContext"; /** - * The current audio context time of the global {@link Context}. - * See {@link Context.now} + * The current audio context time of the global {@link BaseContext}. + * @see {@link BaseContext.now} * @category Core */ export function now(): Seconds { @@ -17,8 +18,8 @@ export function now(): Seconds { } /** - * The current audio context time of the global {@link Context} without the {@link Context.lookAhead} - * See {@link Context.immediate} + * The current audio context time of the global {@link BaseContext} without the {@link BaseContext.lookAhead} + * @see {@link BaseContext.immediate} * @category Core */ export function immediate(): Seconds { @@ -27,7 +28,7 @@ export function immediate(): Seconds { /** * The Transport object belonging to the global Tone.js Context. - * See {@link TransportClass} + * @see {@link TransportClass} * @category Core * @deprecated Use {@link getTransport} instead */ @@ -35,7 +36,7 @@ export const Transport = getContext().transport; /** * The Transport object belonging to the global Tone.js Context. - * See {@link TransportClass} + * @see {@link TransportClass} * @category Core */ export function getTransport(): import("./core/clock/Transport").TransportClass { @@ -44,7 +45,7 @@ export function getTransport(): import("./core/clock/Transport").TransportClass /** * The Destination (output) belonging to the global Tone.js Context. - * See {@link DestinationClass} + * @see {@link DestinationClass} * @category Core * @deprecated Use {@link getDestination} instead */ @@ -57,7 +58,7 @@ export const Master = getContext().destination; /** * The Destination (output) belonging to the global Tone.js Context. - * See {@link DestinationClass} + * @see {@link DestinationClass} * @category Core */ export function getDestination(): import("./core/context/Destination").DestinationClass { @@ -81,7 +82,7 @@ export function getListener(): import("./core/context/Listener").ListenerClass { /** * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See {@link DrawClass} + * @see {@link DrawClass} * @category Core * @deprecated Use {@link getDraw} instead */ @@ -90,7 +91,7 @@ export const Draw = getContext().draw; /** * Get the singleton attached to the global context. * Draw is used to synchronize the draw frame with the Transport's callbacks. - * See {@link DrawClass} + * @see {@link DrawClass} * @category Core */ export function getDraw(): import("./core/util/Draw").DrawClass { @@ -99,7 +100,7 @@ export function getDraw(): import("./core/util/Draw").DrawClass { /** * A reference to the global context - * See {@link Context} + * @see {@link BaseContext} * @deprecated Use {@link getContext} instead */ export const context = getContext(); diff --git a/Tone/signal/AudioToGain.ts b/Tone/signal/AudioToGain.ts index f4c27204..743ea600 100644 --- a/Tone/signal/AudioToGain.ts +++ b/Tone/signal/AudioToGain.ts @@ -4,7 +4,7 @@ import { WaveShaper } from "./WaveShaper"; /** * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. - * See {@link GainToAudio}. + * @see {@link GainToAudio}. * @category Signal */ export class AudioToGain extends SignalOperator { diff --git a/Tone/signal/GainToAudio.ts b/Tone/signal/GainToAudio.ts index a3304621..6948217f 100644 --- a/Tone/signal/GainToAudio.ts +++ b/Tone/signal/GainToAudio.ts @@ -4,7 +4,7 @@ import { WaveShaper } from "./WaveShaper"; /** * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1]. - * See {@link AudioToGain}. + * @see {@link AudioToGain}. * @category Signal */ export class GainToAudio extends SignalOperator { diff --git a/Tone/signal/Signal.ts b/Tone/signal/Signal.ts index a15c6ca5..bc667ac6 100644 --- a/Tone/signal/Signal.ts +++ b/Tone/signal/Signal.ts @@ -192,7 +192,7 @@ export class Signal extends ToneAudioNode< } /** - * See {@link Param.apply}. + * @see {@link Param.apply}. */ apply(param: Param | AudioParam): this { this._param.apply(param); diff --git a/Tone/source/Source.ts b/Tone/source/Source.ts index d2d7bbac..72c838e4 100644 --- a/Tone/source/Source.ts +++ b/Tone/source/Source.ts @@ -362,7 +362,8 @@ export abstract class Source< } /** - * Unsync the source to the Transport. See Source.sync + * Unsync the source to the Transport. + * @see {@link sync} */ unsync(): this { if (this._synced) { diff --git a/Tone/source/oscillator/LFO.ts b/Tone/source/oscillator/LFO.ts index 24d9a675..5d1e13c4 100644 --- a/Tone/source/oscillator/LFO.ts +++ b/Tone/source/oscillator/LFO.ts @@ -238,7 +238,8 @@ export class LFO extends ToneAudioNode { } /** - * The type of the oscillator: See {@link Oscillator.type} + * The type of the oscillator. + * @see {@link Oscillator.type} */ get type(): ToneOscillatorType { return this._oscillator.type; @@ -249,7 +250,8 @@ export class LFO extends ToneAudioNode { } /** - * The oscillator's partials array: See {@link Oscillator.partials} + * The oscillator's partials array. + * @see {@link Oscillator.partials} */ get partials(): number[] { return this._oscillator.partials; diff --git a/Tone/source/oscillator/OmniOscillator.ts b/Tone/source/oscillator/OmniOscillator.ts index 7d79456c..b17ca69e 100644 --- a/Tone/source/oscillator/OmniOscillator.ts +++ b/Tone/source/oscillator/OmniOscillator.ts @@ -192,7 +192,7 @@ export class OmniOscillator /** * The value is an empty array when the type is not "custom". * This is not available on "pwm" and "pulse" oscillator types. - * See {@link Oscillator.partials} + * @see {@link Oscillator.partials} */ get partials(): number[] { return this._oscillator.partials; @@ -297,7 +297,8 @@ export class OmniOscillator } /** - * The base type of the oscillator. See {@link Oscillator.baseType} + * The base type of the oscillator. + * @see {@link Oscillator.baseType} * @example * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4"); * console.log(omniOsc.sourceType, omniOsc.baseType, omniOsc.partialCount); @@ -315,7 +316,7 @@ export class OmniOscillator /** * The width of the oscillator when sourceType === "pulse". - * See {@link PWMOscillator} + * @see {@link PWMOscillator} */ get width(): IsPulseOscillator> { if (this._getOscType(this._oscillator, "pulse")) { @@ -327,7 +328,7 @@ export class OmniOscillator /** * The number of detuned oscillators when sourceType === "fat". - * See {@link FatOscillator.count} + * @see {@link FatOscillator.count} */ get count(): IsFatOscillator { if (this._getOscType(this._oscillator, "fat")) { @@ -344,7 +345,7 @@ export class OmniOscillator /** * The detune spread between the oscillators when sourceType === "fat". - * See {@link FatOscillator.count} + * @see {@link FatOscillator.count} */ get spread(): IsFatOscillator { if (this._getOscType(this._oscillator, "fat")) { @@ -361,7 +362,7 @@ export class OmniOscillator /** * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types. - * See {@link AMOscillator} or {@link FMOscillator} + * @see {@link AMOscillator} or {@link FMOscillator} */ get modulationType(): IsAmOrFmOscillator { if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { @@ -378,7 +379,7 @@ export class OmniOscillator /** * The modulation index when the sourceType === "fm" - * See {@link FMOscillator}. + * @see {@link FMOscillator}. */ get modulationIndex(): IsFMOscillator> { if (this._getOscType(this._oscillator, "fm")) { @@ -390,7 +391,7 @@ export class OmniOscillator /** * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. - * See {@link AMOscillator} or {@link FMOscillator} + * @see {@link AMOscillator} or {@link FMOscillator} */ get harmonicity(): IsAmOrFmOscillator> { if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { diff --git a/Tone/source/oscillator/Oscillator.ts b/Tone/source/oscillator/Oscillator.ts index ca85439b..89d256f1 100644 --- a/Tone/source/oscillator/Oscillator.ts +++ b/Tone/source/oscillator/Oscillator.ts @@ -180,7 +180,7 @@ export class Oscillator extends Source implements ToneOsc /** * Unsync the oscillator's frequency from the Transport. - * See Oscillator.syncFrequency + * @see {@link syncFrequency} */ unsyncFrequency(): this { this.context.transport.unsyncSignal(this.frequency); From 4b3d371fdd9d94f65ee3835c5cf99c23f7d7648e Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Mon, 29 Apr 2024 13:34:53 -0400 Subject: [PATCH 11/17] updating link to Context instead of BaseContext (#1238) --- Tone/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Tone/index.ts b/Tone/index.ts index e1b978fd..319adf57 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -1,5 +1,5 @@ export { getContext, setContext } from "./core/Global"; -import { BaseContext } from "./core/context/BaseContext"; +import { Context } from "./core/context/Context"; export * from "./classes"; export * from "./version"; import { getContext } from "./core/Global"; @@ -10,7 +10,7 @@ export { supported } from "./core/context/AudioContext"; /** * The current audio context time of the global {@link BaseContext}. - * @see {@link BaseContext.now} + * @see {@link Context.now} * @category Core */ export function now(): Seconds { @@ -18,8 +18,8 @@ export function now(): Seconds { } /** - * The current audio context time of the global {@link BaseContext} without the {@link BaseContext.lookAhead} - * @see {@link BaseContext.immediate} + * The current audio context time of the global {@link Context} without the {@link Context.lookAhead} + * @see {@link Context.immediate} * @category Core */ export function immediate(): Seconds { @@ -100,7 +100,7 @@ export function getDraw(): import("./core/util/Draw").DrawClass { /** * A reference to the global context - * @see {@link BaseContext} + * @see {@link Context} * @deprecated Use {@link getContext} instead */ export const context = getContext(); From 3c9ee76d488948ea24bd2e5c066ec49d8647413d Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Tue, 30 Apr 2024 09:08:29 -0400 Subject: [PATCH 12/17] Update README.md --- README.md | 100 +++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 82c6af82..1e544a6e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -Tone.js -========= +# Tone.js [![codecov](https://codecov.io/gh/Tonejs/Tone.js/branch/dev/graph/badge.svg)](https://codecov.io/gh/Tonejs/Tone.js) - Tone.js is a Web Audio framework for creating interactive music in the browser. The architecture of Tone.js aims to be familiar to both musicians and audio programmers creating web-based audio applications. On the high-level, Tone offers common DAW (digital audio workstation) features like a global transport for synchronizing and scheduling events as well as prebuilt synths and effects. Additionally, Tone provides high-performance building blocks to create your own synthesizers, effects, and complex control signals. -* [API](https://tonejs.github.io/docs/) -* [Examples](https://tonejs.github.io/examples/) +- [API](https://tonejs.github.io/docs/) +- [Examples](https://tonejs.github.io/examples/) # Installation @@ -21,7 +19,7 @@ npm install tone@next // Or, alternatively, use the 'next' version Add Tone.js to a project using the JavaScript `import` syntax: ```js -import * as Tone from 'tone'; +import * as Tone from "tone"; ``` Tone.js is also hosted at unpkg.com. It can be added directly within an HTML document, as long as it precedes any project scripts. [See the example here](https://github.com/Tonejs/Tone.js/blob/master/examples/simpleHtml.html) for more details. @@ -50,36 +48,36 @@ synth.triggerAttackRelease("C4", "8n"); ```javascript const synth = new Tone.Synth().toDestination(); -const now = Tone.now() +const now = Tone.now(); // trigger the attack immediately -synth.triggerAttack("C4", now) +synth.triggerAttack("C4", now); // wait one second before triggering the release -synth.triggerRelease(now + 1) +synth.triggerRelease(now + 1); ``` ### triggerAttackRelease `triggerAttackRelease` is a combination of `triggerAttack` and `triggerRelease` -The first argument to the note which can either be a frequency in hertz (like `440`) or as "pitch-octave" notation (like `"D#2"`). +The first argument to the note which can either be a frequency in hertz (like `440`) or as "pitch-octave" notation (like `"D#2"`). -The second argument is the duration that the note is held. This value can either be in seconds, or as a [tempo-relative value](https://github.com/Tonejs/Tone.js/wiki/Time). +The second argument is the duration that the note is held. This value can either be in seconds, or as a [tempo-relative value](https://github.com/Tonejs/Tone.js/wiki/Time). The third (optional) argument of `triggerAttackRelease` is _when_ along the AudioContext time the note should play. It can be used to schedule events in the future. ```javascript const synth = new Tone.Synth().toDestination(); -const now = Tone.now() -synth.triggerAttackRelease("C4", "8n", now) -synth.triggerAttackRelease("E4", "8n", now + 0.5) -synth.triggerAttackRelease("G4", "8n", now + 1) +const now = Tone.now(); +synth.triggerAttackRelease("C4", "8n", now); +synth.triggerAttackRelease("E4", "8n", now + 0.5); +synth.triggerAttackRelease("G4", "8n", now + 1); ``` ## Time Web Audio has advanced, sample accurate scheduling capabilities. The AudioContext time is what the Web Audio API uses to schedule events, starts at 0 when the page loads and counts up in **seconds**. -`Tone.now()` gets the current time of the AudioContext. +`Tone.now()` gets the current time of the AudioContext. ```javascript setInterval(() => console.log(Tone.now()), 100); @@ -91,17 +89,17 @@ Tone.js abstracts away the AudioContext time. Instead of defining all values in # Starting Audio -**IMPORTANT**: Browsers will not play _any_ audio until a user clicks something (like a play button). Run your Tone.js code only after calling `Tone.start()` from a event listener which is triggered by a user action such as "click" or "keydown". +**IMPORTANT**: Browsers will not play _any_ audio until a user clicks something (like a play button). Run your Tone.js code only after calling `Tone.start()` from a event listener which is triggered by a user action such as "click" or "keydown". `Tone.start()` returns a promise, the audio will be ready only after that promise is resolved. Scheduling or playing audio before the AudioContext is running will result in silence or incorrect scheduling. ```javascript //attach a click listener to a play button -document.querySelector('button')?.addEventListener('click', async () => { - await Tone.start() - console.log('audio is ready') -}) -``` +document.querySelector("button")?.addEventListener("click", async () => { + await Tone.start(); + console.log("audio is ready"); +}); +``` # Scheduling @@ -116,32 +114,32 @@ Multiple events and parts can be arranged and synchronized along the Transport. const synthA = new Tone.FMSynth().toDestination(); const synthB = new Tone.AMSynth().toDestination(); //play a note every quarter-note -const loopA = new Tone.Loop(time => { +const loopA = new Tone.Loop((time) => { synthA.triggerAttackRelease("C2", "8n", time); }, "4n").start(0); //play another note every off quarter-note, by starting it "8n" -const loopB = new Tone.Loop(time => { +const loopB = new Tone.Loop((time) => { synthB.triggerAttackRelease("C4", "8n", time); }, "4n").start("8n"); // all loops start when the Transport is started -Tone.getTransport().start() +Tone.getTransport().start(); // ramp up to 800 bpm over 10 seconds -Tone.Transport.bpm.rampTo(800, 10); +Tone.getTransport().bpm.rampTo(800, 10); ``` Since Javascript callbacks are **not precisely timed**, the sample-accurate time of the event is passed into the callback function. **Use this time value to schedule the events**. # Instruments -There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`. +There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`. -All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time. +All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time. -To create a **polyphonic** synthesizer, use `Tone.PolySynth`, which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes. +To create a **polyphonic** synthesizer, use `Tone.PolySynth`, which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes. ```javascript const synth = new Tone.PolySynth(Tone.Synth).toDestination(); -const now = Tone.now() +const now = Tone.now(); synth.triggerAttack("D4", now); synth.triggerAttack("F4", now + 0.5); synth.triggerAttack("A4", now + 1); @@ -152,30 +150,32 @@ synth.triggerRelease(["D4", "F4", "A4", "C5", "E5"], now + 4); # Samples -Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. `Tone.Player` is one way to load and play back an audio file. +Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. `Tone.Player` is one way to load and play back an audio file. ```javascript -const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination(); +const player = new Tone.Player( + "https://tonejs.github.io/audio/berklee/gong_1.mp3" +).toDestination(); Tone.loaded().then(() => { player.start(); }); ``` -`Tone.loaded()` returns a promise which resolves when _all_ audio files are loaded. It's a helpful shorthand instead of waiting on each individual audio buffer's `onload` event to resolve. +`Tone.loaded()` returns a promise which resolves when _all_ audio files are loaded. It's a helpful shorthand instead of waiting on each individual audio buffer's `onload` event to resolve. ## Tone.Sampler -Multiple samples can also be combined into an instrument. If you have audio files organized by note, `Tone.Sampler` will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample. +Multiple samples can also be combined into an instrument. If you have audio files organized by note, `Tone.Sampler` will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample. Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth ```javascript const sampler = new Tone.Sampler({ urls: { - "C4": "C4.mp3", + C4: "C4.mp3", "D#4": "Ds4.mp3", "F#4": "Fs4.mp3", - "A4": "A4.mp3", + A4: "A4.mp3", }, release: 1, baseUrl: "https://tonejs.github.io/audio/salamander/", @@ -183,7 +183,7 @@ const sampler = new Tone.Sampler({ Tone.loaded().then(() => { sampler.triggerAttackRelease(["Eb4", "G4", "Bb4"], 4); -}) +}); ``` # Effects @@ -195,21 +195,21 @@ const player = new Tone.Player({ url: "https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3", loop: true, autostart: true, -}) +}); //create a distortion effect const distortion = new Tone.Distortion(0.4).toDestination(); //connect a player to the distortion player.connect(distortion); ``` -The connection routing is flexible, connections can run serially or in parallel. +The connection routing is flexible, connections can run serially or in parallel. ```javascript const player = new Tone.Player({ url: "https://tonejs.github.io/audio/drum-samples/loops/ominous.mp3", autostart: true, }); -const filter = new Tone.Filter(400, 'lowpass').toDestination(); +const filter = new Tone.Filter(400, "lowpass").toDestination(); const feedbackDelay = new Tone.FeedbackDelay(0.125, 0.5).toDestination(); // connect the player to the feedback delay and filter in parallel @@ -217,13 +217,13 @@ player.connect(filter); player.connect(feedbackDelay); ``` -Multiple nodes can be connected to the same input enabling sources to share effects. `Tone.Gain` is useful utility node for creating complex routing. +Multiple nodes can be connected to the same input enabling sources to share effects. `Tone.Gain` is useful utility node for creating complex routing. # Signals Like the underlying Web Audio API, Tone.js is built with audio-rate signal control over nearly everything. This is a powerful feature which allows for sample-accurate synchronization and scheduling of parameters. -`Signal` properties have a few built in methods for creating automation curves. +`Signal` properties have a few built in methods for creating automation curves. For example, the `frequency` parameter on `Oscillator` is a Signal so you can create a smooth ramp from one frequency to another. @@ -247,13 +247,13 @@ To use MIDI files, you'll first need to convert them into a JSON format which To # Performance -Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode and WaveShaperNode for all signal processing, which enables Tone.js to work well on both desktop and mobile browsers. +Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode and WaveShaperNode for all signal processing, which enables Tone.js to work well on both desktop and mobile browsers. [This wiki](https://github.com/Tonejs/Tone.js/wiki/Performance) article has some suggestions related to performance for best practices. # Testing -Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Passing builds on the 'dev' branch are published on npm as `tone@next`. +Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Passing builds on the 'dev' branch are published on npm as `tone@next`. # Contributing @@ -263,9 +263,9 @@ If you have questions (or answers) that are not necessarily bugs/issues, please # References and Inspiration -* [Many of Chris Wilson's Repositories](https://github.com/cwilso) -* [Many of Mohayonao's Repositories](https://github.com/mohayonao) -* [The Spec](http://webaudio.github.io/web-audio-api/) -* [Sound on Sound - Synth Secrets](http://www.soundonsound.com/sos/may99/articles/synthsec.htm) -* [Miller Puckette - Theory and Techniques of Electronic Music](http://msp.ucsd.edu/techniques.htm) -* [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context) +- [Many of Chris Wilson's Repositories](https://github.com/cwilso) +- [Many of Mohayonao's Repositories](https://github.com/mohayonao) +- [The Spec](http://webaudio.github.io/web-audio-api/) +- [Sound on Sound - Synth Secrets](http://www.soundonsound.com/sos/may99/articles/synthsec.htm) +- [Miller Puckette - Theory and Techniques of Electronic Music](http://msp.ucsd.edu/techniques.htm) +- [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context) From 066e46f4c3addc43e6971dd276fa367a8914b22a Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Tue, 30 Apr 2024 09:44:57 -0400 Subject: [PATCH 13/17] Small doc updates and tweaks (#1239) --- Tone/core/context/ToneWithContext.ts | 59 +++++++++++++++++++++------- Tone/event/Part.ts | 4 +- Tone/event/Sequence.ts | 4 +- Tone/index.ts | 22 ++++++----- Tone/signal/SyncedSignal.ts | 1 + Tone/signal/WaveShaper.ts | 2 +- 6 files changed, 64 insertions(+), 28 deletions(-) diff --git a/Tone/core/context/ToneWithContext.ts b/Tone/core/context/ToneWithContext.ts index 6b513d96..84dfeb1e 100644 --- a/Tone/core/context/ToneWithContext.ts +++ b/Tone/core/context/ToneWithContext.ts @@ -5,10 +5,21 @@ import { TimeClass } from "../type/Time"; import { TransportTimeClass } from "../type/TransportTime"; import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units"; import { assertUsedScheduleTime } from "../util/Debug"; -import { getDefaultsFromInstance, optionsFromArguments } from "../util/Defaults"; +import { + getDefaultsFromInstance, + optionsFromArguments, +} from "../util/Defaults"; import { RecursivePartial } from "../util/Interface"; -import { isArray, isBoolean, isDefined, isNumber, isString, isUndef } from "../util/TypeCheck"; +import { + isArray, + isBoolean, + isDefined, + isNumber, + isString, + isUndef, +} from "../util/TypeCheck"; import { BaseContext } from "./BaseContext"; +import type { TransportClass } from "../clock/Transport"; /** * A unit which process audio @@ -20,8 +31,9 @@ export interface ToneWithContextOptions { /** * The Base class for all nodes that have an AudioContext. */ -export abstract class ToneWithContext extends Tone { - +export abstract class ToneWithContext< + Options extends ToneWithContextOptions +> extends Tone { /** * The context belonging to the node. */ @@ -37,11 +49,15 @@ export abstract class ToneWithContext ex /** * Pass in a constructor as the first argument */ - constructor(context?: BaseContext) + constructor(context?: BaseContext); constructor(options?: Partial); constructor() { super(); - const options = optionsFromArguments(ToneWithContext.getDefaults(), arguments, ["context"]); + const options = optionsFromArguments( + ToneWithContext.getDefaults(), + arguments, + ["context"] + ); if (this.defaultContext) { this.context = this.defaultContext; } else { @@ -94,7 +110,7 @@ export abstract class ToneWithContext ex } /** - * Convert the incoming time to seconds. + * Convert the incoming time to seconds. * This is calculated against the current {@link TransportClass} bpm * @example * const gain = new Tone.Gain(); @@ -137,7 +153,7 @@ export abstract class ToneWithContext ex protected _getPartialProperties(props: Options): Partial { const options = this.get(); // remove attributes from the prop that are not in the partial - Object.keys(options).forEach(name => { + Object.keys(options).forEach((name) => { if (isUndef(props[name])) { delete options[name]; } @@ -153,15 +169,26 @@ export abstract class ToneWithContext ex */ get(): Options { const defaults = getDefaultsFromInstance(this) as Options; - Object.keys(defaults).forEach(attribute => { + Object.keys(defaults).forEach((attribute) => { if (Reflect.has(this, attribute)) { const member = this[attribute]; - if (isDefined(member) && isDefined(member.value) && isDefined(member.setValueAtTime)) { + if ( + isDefined(member) && + isDefined(member.value) && + isDefined(member.setValueAtTime) + ) { defaults[attribute] = member.value; } else if (member instanceof ToneWithContext) { - defaults[attribute] = member._getPartialProperties(defaults[attribute]); + defaults[attribute] = member._getPartialProperties( + defaults[attribute] + ); // otherwise make sure it's a serializable type - } else if (isArray(member) || isNumber(member) || isString(member) || isBoolean(member)) { + } else if ( + isArray(member) || + isNumber(member) || + isString(member) || + isBoolean(member) + ) { defaults[attribute] = member; } else { // remove all undefined and unserializable attributes @@ -186,9 +213,13 @@ export abstract class ToneWithContext ex * player.autostart = true; */ set(props: RecursivePartial): this { - Object.keys(props).forEach(attribute => { + Object.keys(props).forEach((attribute) => { if (Reflect.has(this, attribute) && isDefined(this[attribute])) { - if (this[attribute] && isDefined(this[attribute].value) && isDefined(this[attribute].setValueAtTime)) { + if ( + this[attribute] && + isDefined(this[attribute].value) && + isDefined(this[attribute].setValueAtTime) + ) { // small optimization if (this[attribute].value !== props[attribute]) { this[attribute].value = props[attribute]; diff --git a/Tone/event/Part.ts b/Tone/event/Part.ts index 0033fe0e..693a31c9 100644 --- a/Tone/event/Part.ts +++ b/Tone/event/Part.ts @@ -60,7 +60,7 @@ export class Part extends ToneEvent { /** * @param callback The callback to invoke on each event - * @param events the array of events + * @param value the array of events */ constructor(callback?: ToneEventCallback>, value?: ValueType[]); constructor(options?: Partial>); @@ -209,7 +209,7 @@ export class Part extends ToneEvent { * Add a an event to the part. * @param time The time the note should start. If an object is passed in, it should * have a 'time' attribute and the rest of the object will be used as the 'value'. - * @param value + * @param value Any value to add to the timeline * @example * const part = new Tone.Part(); * part.add("1m", "C#+11"); diff --git a/Tone/event/Sequence.ts b/Tone/event/Sequence.ts index 011244a9..1c6ded00 100644 --- a/Tone/event/Sequence.ts +++ b/Tone/event/Sequence.ts @@ -5,7 +5,7 @@ import { isArray, isString } from "../core/util/TypeCheck"; import { Part } from "./Part"; import { ToneEvent, ToneEventCallback, ToneEventOptions } from "./ToneEvent"; -type SequenceEventDescription = Array>>>>; +type SequenceEventDescription = Array>; interface SequenceOptions extends Omit, "value"> { loopStart: number; @@ -59,7 +59,7 @@ export class Sequence extends ToneEvent { /** * @param callback The callback to invoke with every note - * @param sequence The sequence + * @param events The sequence of events * @param subdivision The subdivision between which events are placed. */ constructor( diff --git a/Tone/index.ts b/Tone/index.ts index 319adf57..d95430de 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -7,9 +7,13 @@ import { ToneAudioBuffer } from "./core/context/ToneAudioBuffer"; export { start } from "./core/Global"; import { Seconds } from "./core/type/Units"; export { supported } from "./core/context/AudioContext"; +import type { TransportClass } from "./core/clock/Transport"; +import type { DestinationClass } from "./core/context/Destination"; +import type { DrawClass } from "./core/util/Draw"; +import type { ListenerClass } from "./core/context/Listener"; /** - * The current audio context time of the global {@link BaseContext}. + * The current audio context time of the global {@link BaseContext}. * @see {@link Context.now} * @category Core */ @@ -39,7 +43,7 @@ export const Transport = getContext().transport; * @see {@link TransportClass} * @category Core */ -export function getTransport(): import("./core/clock/Transport").TransportClass { +export function getTransport(): TransportClass { return getContext().transport; } @@ -61,7 +65,7 @@ export const Master = getContext().destination; * @see {@link DestinationClass} * @category Core */ -export function getDestination(): import("./core/context/Destination").DestinationClass { +export function getDestination(): DestinationClass { return getContext().destination; } @@ -76,12 +80,12 @@ export const Listener = getContext().listener; * The {@link ListenerClass} belonging to the global Tone.js Context. * @category Core */ -export function getListener(): import("./core/context/Listener").ListenerClass { +export function getListener(): ListenerClass { return getContext().listener; } /** - * Draw is used to synchronize the draw frame with the Transport's callbacks. + * Draw is used to synchronize the draw frame with the Transport's callbacks. * @see {@link DrawClass} * @category Core * @deprecated Use {@link getDraw} instead @@ -89,12 +93,12 @@ export function getListener(): import("./core/context/Listener").ListenerClass { export const Draw = getContext().draw; /** - * Get the singleton attached to the global context. - * Draw is used to synchronize the draw frame with the Transport's callbacks. + * Get the singleton attached to the global context. + * Draw is used to synchronize the draw frame with the Transport's callbacks. * @see {@link DrawClass} * @category Core */ -export function getDraw(): import("./core/util/Draw").DrawClass { +export function getDraw(): DrawClass { return getContext().draw; } @@ -106,7 +110,7 @@ export function getDraw(): import("./core/util/Draw").DrawClass { export const context = getContext(); /** - * Promise which resolves when all of the loading promises are resolved. + * Promise which resolves when all of the loading promises are resolved. * Alias for static {@link ToneAudioBuffer.loaded} method. * @category Core */ diff --git a/Tone/signal/SyncedSignal.ts b/Tone/signal/SyncedSignal.ts index 362cd060..fbdd3029 100644 --- a/Tone/signal/SyncedSignal.ts +++ b/Tone/signal/SyncedSignal.ts @@ -4,6 +4,7 @@ import { optionsFromArguments } from "../core/util/Defaults"; import { TransportTimeClass } from "../core/type/TransportTime"; import { ToneConstantSource } from "./ToneConstantSource"; import { OutputNode } from "../core/context/ToneAudioNode"; +import type { TransportClass } from "../core/clock/Transport"; /** * Adds the ability to synchronize the signal to the {@link TransportClass} diff --git a/Tone/signal/WaveShaper.ts b/Tone/signal/WaveShaper.ts index 70f2dab3..b46463d6 100644 --- a/Tone/signal/WaveShaper.ts +++ b/Tone/signal/WaveShaper.ts @@ -55,7 +55,7 @@ export class WaveShaper extends SignalOperator { * signal is an AudioRange [-1, 1] value and the output * signal can take on any numerical values. * - * @param bufferLen The length of the WaveShaperNode buffer. + * @param length The length of the WaveShaperNode buffer. */ constructor(mapping?: WaveShaperMapping, length?: number); constructor(options?: Partial); From aaf880c925b7c787d319eb64c2f5233714f1185c Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Fri, 3 May 2024 14:31:14 -0400 Subject: [PATCH 14/17] Using web-test-runner for tests, updating import paths (#1242) * WIP moving tests to web-test-runner * updating thresholds * Adding file extensions * Testing integrations * linting * fixing dep * moving back to root dir * prettier all of the files * updating eslint rules to use with prettier * remove import package * moving tsignore around * removing unneeded ignores * all tests run on puppeteer, no need for testing guards * linting * import type syntax * cleaning up * Update package.json --- .eslintrc.cjs | 40 +- .github/workflows/test.yml | 36 +- .gitignore | 3 +- Tone/classes.ts | 14 +- Tone/component/analysis/Analyser.test.ts | 12 +- Tone/component/analysis/Analyser.ts | 51 +- Tone/component/analysis/DCMeter.test.ts | 33 +- Tone/component/analysis/DCMeter.ts | 7 +- Tone/component/analysis/FFT.test.ts | 51 +- Tone/component/analysis/FFT.ts | 26 +- Tone/component/analysis/Follower.test.ts | 13 +- Tone/component/analysis/Follower.ts | 38 +- Tone/component/analysis/Meter.test.ts | 110 +- Tone/component/analysis/Meter.ts | 62 +- Tone/component/analysis/MeterBase.ts | 29 +- Tone/component/analysis/Waveform.test.ts | 43 +- Tone/component/analysis/Waveform.ts | 17 +- Tone/component/channel/Channel.test.ts | 18 +- Tone/component/channel/Channel.ts | 46 +- Tone/component/channel/CrossFade.test.ts | 78 +- Tone/component/channel/CrossFade.ts | 33 +- Tone/component/channel/Merge.test.ts | 34 +- Tone/component/channel/Merge.ts | 23 +- Tone/component/channel/MidSideMerge.test.ts | 11 +- Tone/component/channel/MidSideMerge.ts | 30 +- Tone/component/channel/MidSideSplit.test.ts | 47 +- Tone/component/channel/MidSideSplit.ts | 22 +- Tone/component/channel/Mono.test.ts | 37 +- Tone/component/channel/Mono.ts | 14 +- Tone/component/channel/MultibandSplit.test.ts | 15 +- Tone/component/channel/MultibandSplit.ts | 32 +- Tone/component/channel/PanVol.test.ts | 13 +- Tone/component/channel/PanVol.ts | 33 +- Tone/component/channel/Panner.test.ts | 66 +- Tone/component/channel/Panner.ts | 24 +- Tone/component/channel/Panner3D.test.ts | 7 +- Tone/component/channel/Panner3D.ts | 29 +- Tone/component/channel/Recorder.test.ts | 22 +- Tone/component/channel/Recorder.ts | 43 +- Tone/component/channel/Solo.test.ts | 110 +- Tone/component/channel/Solo.ts | 33 +- Tone/component/channel/Split.test.ts | 12 +- Tone/component/channel/Split.ts | 22 +- Tone/component/channel/Volume.test.ts | 18 +- Tone/component/channel/Volume.ts | 25 +- Tone/component/dynamics/Compressor.test.ts | 16 +- Tone/component/dynamics/Compressor.ts | 31 +- Tone/component/dynamics/Gate.test.ts | 39 +- Tone/component/dynamics/Gate.ts | 36 +- Tone/component/dynamics/Limiter.test.ts | 9 +- Tone/component/dynamics/Limiter.ts | 55 +- .../dynamics/MidSideCompressor.test.ts | 17 +- Tone/component/dynamics/MidSideCompressor.ts | 53 +- .../dynamics/MultibandCompressor.test.ts | 21 +- .../component/dynamics/MultibandCompressor.ts | 57 +- .../envelope/AmplitudeEnvelope.test.ts | 80 +- Tone/component/envelope/AmplitudeEnvelope.ts | 27 +- Tone/component/envelope/Envelope.test.ts | 239 +- Tone/component/envelope/Envelope.ts | 119 +- .../envelope/FrequencyEnvelope.test.ts | 24 +- Tone/component/envelope/FrequencyEnvelope.ts | 41 +- Tone/component/filter/BiquadFilter.test.ts | 36 +- Tone/component/filter/BiquadFilter.ts | 56 +- Tone/component/filter/Convolver.test.ts | 19 +- Tone/component/filter/Convolver.ts | 37 +- Tone/component/filter/EQ3.test.ts | 12 +- Tone/component/filter/EQ3.ts | 39 +- .../filter/FeedbackCombFilter.test.ts | 21 +- Tone/component/filter/FeedbackCombFilter.ts | 42 +- .../filter/FeedbackCombFilter.worklet.ts | 8 +- Tone/component/filter/Filter.test.ts | 35 +- Tone/component/filter/Filter.ts | 73 +- .../filter/LowpassCombFilter.test.ts | 22 +- Tone/component/filter/LowpassCombFilter.ts | 42 +- Tone/component/filter/OnePoleFilter.test.ts | 62 +- Tone/component/filter/OnePoleFilter.ts | 44 +- .../filter/PhaseShiftAllpass.test.ts | 98 +- Tone/component/filter/PhaseShiftAllpass.ts | 46 +- Tone/component/index.ts | 70 +- Tone/core/Global.ts | 26 +- Tone/core/Tone.ts | 18 +- Tone/core/clock/Clock.test.ts | 134 +- Tone/core/clock/Clock.ts | 62 +- Tone/core/clock/TickParam.test.ts | 10 +- Tone/core/clock/TickParam.ts | 87 +- Tone/core/clock/TickSignal.test.ts | 209 +- Tone/core/clock/TickSignal.ts | 29 +- Tone/core/clock/TickSource.test.ts | 42 +- Tone/core/clock/TickSource.ts | 197 +- Tone/core/clock/Ticker.test.ts | 83 +- Tone/core/clock/Ticker.ts | 28 +- Tone/core/clock/Transport.test.ts | 437 +- Tone/core/clock/Transport.ts | 63 +- Tone/core/clock/TransportEvent.test.ts | 7 +- Tone/core/clock/TransportEvent.ts | 16 +- Tone/core/clock/TransportRepeatEvent.test.ts | 8 +- Tone/core/clock/TransportRepeatEvent.ts | 41 +- Tone/core/context/AbstractParam.ts | 58 +- Tone/core/context/AudioContext.ts | 46 +- Tone/core/context/BaseContext.ts | 26 +- Tone/core/context/Context.test.ts | 273 +- Tone/core/context/Context.ts | 51 +- Tone/core/context/ContextInitialization.ts | 7 +- Tone/core/context/Delay.test.ts | 15 +- Tone/core/context/Delay.ts | 33 +- Tone/core/context/Destination.test.ts | 53 +- Tone/core/context/Destination.ts | 43 +- Tone/core/context/DummyContext.test.ts | 3 +- Tone/core/context/DummyContext.ts | 15 +- Tone/core/context/Gain.test.ts | 9 +- Tone/core/context/Gain.ts | 27 +- Tone/core/context/Listener.test.ts | 7 +- Tone/core/context/Listener.ts | 41 +- Tone/core/context/Offline.test.ts | 13 +- Tone/core/context/Offline.ts | 14 +- Tone/core/context/OfflineContext.test.ts | 7 +- Tone/core/context/OfflineContext.ts | 40 +- Tone/core/context/Param.test.ts | 572 +- Tone/core/context/Param.ts | 320 +- Tone/core/context/ToneAudioBuffer.test.ts | 140 +- Tone/core/context/ToneAudioBuffer.ts | 24 +- Tone/core/context/ToneAudioBuffers.test.ts | 151 +- Tone/core/context/ToneAudioBuffers.ts | 50 +- Tone/core/context/ToneAudioNode.test.ts | 50 +- Tone/core/context/ToneAudioNode.ts | 61 +- Tone/core/context/ToneWithContext.ts | 26 +- Tone/core/index.ts | 58 +- Tone/core/type/Conversions.test.ts | 8 +- Tone/core/type/Conversions.ts | 11 +- Tone/core/type/Frequency.test.ts | 193 +- Tone/core/type/Frequency.ts | 142 +- Tone/core/type/Midi.test.ts | 50 +- Tone/core/type/Midi.ts | 11 +- Tone/core/type/NoteUnits.ts | 24 +- Tone/core/type/Ticks.test.ts | 91 +- Tone/core/type/Ticks.ts | 11 +- Tone/core/type/Time.test.ts | 57 +- Tone/core/type/Time.ts | 79 +- Tone/core/type/TimeBase.ts | 72 +- Tone/core/type/TransportTime.test.ts | 65 +- Tone/core/type/TransportTime.ts | 18 +- Tone/core/type/Units.ts | 11 +- Tone/core/util/AdvancedTypeCheck.ts | 8 +- Tone/core/util/Debug.test.ts | 23 +- Tone/core/util/Debug.ts | 24 +- Tone/core/util/Decorator.ts | 56 +- Tone/core/util/Defaults.ts | 57 +- Tone/core/util/Draw.test.ts | 110 +- Tone/core/util/Draw.ts | 24 +- Tone/core/util/Emitter.test.ts | 11 +- Tone/core/util/Emitter.ts | 18 +- Tone/core/util/Interface.ts | 15 +- Tone/core/util/IntervalTimeline.test.ts | 24 +- Tone/core/util/IntervalTimeline.ts | 36 +- Tone/core/util/Math.ts | 2 +- Tone/core/util/StateTimeline.test.ts | 40 +- Tone/core/util/StateTimeline.ts | 37 +- Tone/core/util/Timeline.test.ts | 5 +- Tone/core/util/Timeline.ts | 70 +- Tone/core/util/TimelineValue.test.ts | 7 +- Tone/core/util/TimelineValue.ts | 17 +- Tone/core/util/TypeCheck.ts | 2 +- Tone/core/util/global.d.ts | 9 +- Tone/core/worklet/DelayLine.worklet.ts | 2 +- .../core/worklet/SingleIOProcessor.worklet.ts | 4 +- Tone/core/worklet/ToneAudioWorklet.ts | 27 +- .../ToneAudioWorkletProcessor.worklet.ts | 2 +- Tone/core/worklet/WorkletGlobalScope.ts | 2 +- Tone/effect/AutoFilter.test.ts | 52 +- Tone/effect/AutoFilter.ts | 51 +- Tone/effect/AutoPanner.test.ts | 38 +- Tone/effect/AutoPanner.ts | 31 +- Tone/effect/AutoWah.test.ts | 31 +- Tone/effect/AutoWah.ts | 70 +- Tone/effect/BitCrusher.test.ts | 29 +- Tone/effect/BitCrusher.ts | 38 +- Tone/effect/BitCrusher.worklet.ts | 6 +- Tone/effect/Chebyshev.test.ts | 27 +- Tone/effect/Chebyshev.ts | 58 +- Tone/effect/Chorus.test.ts | 16 +- Tone/effect/Chorus.ts | 62 +- Tone/effect/Distortion.test.ts | 28 +- Tone/effect/Distortion.ts | 22 +- Tone/effect/Effect.ts | 21 +- Tone/effect/FeedbackDelay.test.ts | 30 +- Tone/effect/FeedbackDelay.ts | 27 +- Tone/effect/FeedbackEffect.ts | 16 +- Tone/effect/Freeverb.test.ts | 29 +- Tone/effect/Freeverb.ts | 52 +- Tone/effect/FrequencyShifter.test.ts | 30 +- Tone/effect/FrequencyShifter.ts | 34 +- Tone/effect/JCReverb.test.ts | 27 +- Tone/effect/JCReverb.ts | 75 +- Tone/effect/LFOEffect.ts | 28 +- Tone/effect/MidSideEffect.ts | 27 +- Tone/effect/Phaser.test.ts | 29 +- Tone/effect/Phaser.ts | 46 +- Tone/effect/PingPongDelay.test.ts | 27 +- Tone/effect/PingPongDelay.ts | 42 +- Tone/effect/PitchShift.test.ts | 38 +- Tone/effect/PitchShift.ts | 50 +- Tone/effect/Reverb.test.ts | 10 +- Tone/effect/Reverb.ts | 48 +- Tone/effect/StereoEffect.ts | 43 +- Tone/effect/StereoFeedbackEffect.ts | 28 +- Tone/effect/StereoWidener.test.ts | 30 +- Tone/effect/StereoWidener.ts | 43 +- Tone/effect/StereoXFeedbackEffect.ts | 20 +- Tone/effect/Tremolo.test.ts | 30 +- Tone/effect/Tremolo.ts | 36 +- Tone/effect/Vibrato.test.ts | 29 +- Tone/effect/Vibrato.ts | 54 +- Tone/effect/index.ts | 36 +- Tone/event/Loop.test.ts | 35 +- Tone/event/Loop.ts | 62 +- Tone/event/Part.test.ts | 311 +- Tone/event/Part.ts | 129 +- Tone/event/Pattern.test.ts | 84 +- Tone/event/Pattern.ts | 46 +- Tone/event/PatternGenerator.test.ts | 43 +- Tone/event/PatternGenerator.ts | 46 +- Tone/event/Sequence.test.ts | 122 +- Tone/event/Sequence.ts | 91 +- Tone/event/ToneEvent.test.ts | 39 +- Tone/event/ToneEvent.ts | 90 +- Tone/event/index.ts | 10 +- Tone/fromContext.test.ts | 6 +- Tone/fromContext.ts | 36 +- Tone/index.test.ts | 13 +- Tone/index.ts | 30 +- Tone/instrument/AMSynth.test.ts | 36 +- Tone/instrument/AMSynth.ts | 11 +- Tone/instrument/DuoSynth.test.ts | 48 +- Tone/instrument/DuoSynth.ts | 100 +- Tone/instrument/FMSynth.test.ts | 31 +- Tone/instrument/FMSynth.ts | 12 +- Tone/instrument/Instrument.ts | 49 +- Tone/instrument/MembraneSynth.test.ts | 42 +- Tone/instrument/MembraneSynth.ts | 32 +- Tone/instrument/MetalSynth.test.ts | 25 +- Tone/instrument/MetalSynth.ts | 24 +- Tone/instrument/ModulationSynth.ts | 67 +- Tone/instrument/MonoSynth.test.ts | 36 +- Tone/instrument/MonoSynth.ts | 99 +- Tone/instrument/Monophonic.ts | 51 +- Tone/instrument/NoiseSynth.test.ts | 57 +- Tone/instrument/NoiseSynth.ts | 18 +- Tone/instrument/PluckSynth.test.ts | 42 +- Tone/instrument/PluckSynth.ts | 25 +- Tone/instrument/PolySynth.test.ts | 113 +- Tone/instrument/PolySynth.ts | 196 +- Tone/instrument/Sampler.test.ts | 196 +- Tone/instrument/Sampler.ts | 120 +- Tone/instrument/Synth.test.ts | 71 +- Tone/instrument/Synth.ts | 76 +- Tone/instrument/index.ts | 22 +- Tone/signal/Abs.test.ts | 14 +- Tone/signal/Abs.ts | 9 +- Tone/signal/Add.test.ts | 12 +- Tone/signal/Add.ts | 17 +- Tone/signal/AudioToGain.test.ts | 19 +- Tone/signal/AudioToGain.ts | 9 +- Tone/signal/GainToAudio.test.ts | 14 +- Tone/signal/GainToAudio.ts | 9 +- Tone/signal/GreaterThan.test.ts | 11 +- Tone/signal/GreaterThan.ts | 41 +- Tone/signal/GreaterThanZero.test.ts | 11 +- Tone/signal/GreaterThanZero.ts | 21 +- Tone/signal/Multiply.test.ts | 18 +- Tone/signal/Multiply.ts | 45 +- Tone/signal/Negate.test.ts | 10 +- Tone/signal/Negate.ts | 7 +- Tone/signal/Pow.test.ts | 16 +- Tone/signal/Pow.ts | 34 +- Tone/signal/Scale.test.ts | 12 +- Tone/signal/Scale.ts | 33 +- Tone/signal/ScaleExp.test.ts | 15 +- Tone/signal/ScaleExp.ts | 25 +- Tone/signal/Signal.test.ts | 59 +- Tone/signal/Signal.ts | 97 +- Tone/signal/SignalOperator.ts | 23 +- Tone/signal/Subtract.test.ts | 12 +- Tone/signal/Subtract.ts | 21 +- Tone/signal/SyncedSignal.test.ts | 109 +- Tone/signal/SyncedSignal.ts | 152 +- Tone/signal/ToneConstantSource.test.ts | 117 +- Tone/signal/ToneConstantSource.ts | 34 +- Tone/signal/WaveShaper.test.ts | 17 +- Tone/signal/WaveShaper.ts | 44 +- Tone/signal/Zero.test.ts | 18 +- Tone/signal/Zero.ts | 17 +- Tone/signal/index.ts | 32 +- Tone/source/Noise.test.ts | 28 +- Tone/source/Noise.ts | 35 +- Tone/source/OneShotSource.ts | 16 +- Tone/source/Source.test.ts | 72 +- Tone/source/Source.ts | 28 +- Tone/source/UserMedia.test.ts | 225 +- Tone/source/UserMedia.ts | 54 +- Tone/source/buffer/GrainPlayer.test.ts | 100 +- Tone/source/buffer/GrainPlayer.ts | 51 +- Tone/source/buffer/Player.test.ts | 77 +- Tone/source/buffer/Player.ts | 18 +- Tone/source/buffer/Players.test.ts | 115 +- Tone/source/buffer/Players.ts | 83 +- Tone/source/buffer/ToneBufferSource.test.ts | 138 +- Tone/source/buffer/ToneBufferSource.ts | 68 +- Tone/source/index.ts | 30 +- Tone/source/oscillator/AMOscillator.test.ts | 24 +- Tone/source/oscillator/AMOscillator.ts | 61 +- Tone/source/oscillator/FMOscillator.test.ts | 26 +- Tone/source/oscillator/FMOscillator.ts | 62 +- Tone/source/oscillator/FatOscillator.test.ts | 25 +- Tone/source/oscillator/FatOscillator.ts | 85 +- Tone/source/oscillator/LFO.test.ts | 18 +- Tone/source/oscillator/LFO.ts | 63 +- Tone/source/oscillator/OmniOscillator.test.ts | 48 +- Tone/source/oscillator/OmniOscillator.ts | 182 +- Tone/source/oscillator/Oscillator.test.ts | 44 +- Tone/source/oscillator/Oscillator.ts | 167 +- Tone/source/oscillator/OscillatorInterface.ts | 15 +- Tone/source/oscillator/PWMOscillator.test.ts | 27 +- Tone/source/oscillator/PWMOscillator.ts | 45 +- .../source/oscillator/PulseOscillator.test.ts | 31 +- Tone/source/oscillator/PulseOscillator.ts | 58 +- .../oscillator/ToneOscillatorNode.test.ts | 131 +- Tone/source/oscillator/ToneOscillatorNode.ts | 32 +- package-lock.json | 18079 ++++++++-------- package.json | 86 +- scripts/generate_docs.cjs | 24 - scripts/tsconfig.build.json | 1 + .../webpack.config.cjs | 46 +- test/README.md | 14 +- test/helper/Basic.ts | 50 +- test/helper/CompareToFile.ts | 43 +- test/helper/Connect.ts | 5 +- test/helper/ConstantOutput.ts | 7 +- test/helper/Dispose.ts | 10 +- test/helper/EffectTests.ts | 78 +- test/helper/InstrumentTests.ts | 65 +- test/helper/MonophonicTests.ts | 10 +- test/helper/Offline.ts | 43 +- test/helper/OscillatorTests.ts | 6 +- test/helper/OutputAudio.ts | 2 +- test/helper/PassAudio.ts | 35 +- test/helper/SourceTests.ts | 13 +- test/helper/StereoSignal.ts | 4 +- test/helper/Supports.ts | 54 +- test/helper/ToneAudioBuffer.ts | 9 - test/helper/compare/Compare.ts | 147 + test/helper/compare/OfflineRender.ts | 74 + test/helper/compare/Plot.ts | 72 + test/helper/compare/Spectrum.ts | 26 + test/helper/compare/TestAudioBuffer.ts | 327 + test/helper/compare/index.ts | 8 + test/integration/node/package.json | 9 + test/integration/node/test.mjs | 8 + test/integration/typescript/package.json | 11 + test/integration/typescript/test.ts | 3 + test/integration/unpkg/package.json | 10 + test/integration/unpkg/test.mjs | 24 + test/integration/vite/index.html | 9 + test/integration/vite/index.ts | 3 + test/integration/vite/package.json | 10 + test/integration/webpack/package.json | 12 + test/integration/webpack/test.js | 3 + test/karma.conf.cjs | 171 - test/scripts/node_test.cjs | 10 - test/scripts/test_html.cjs | 6 +- test/scripts/test_integrations.mjs | 15 + test/scripts/test_readme.cjs | 8 +- test/web-test-runner.config.js | 40 + tsconfig.json | 23 +- 373 files changed, 19461 insertions(+), 16387 deletions(-) delete mode 100644 scripts/generate_docs.cjs rename webpack.config.cjs => scripts/webpack.config.cjs (53%) delete mode 100644 test/helper/ToneAudioBuffer.ts create mode 100644 test/helper/compare/Compare.ts create mode 100644 test/helper/compare/OfflineRender.ts create mode 100644 test/helper/compare/Plot.ts create mode 100644 test/helper/compare/Spectrum.ts create mode 100644 test/helper/compare/TestAudioBuffer.ts create mode 100644 test/helper/compare/index.ts create mode 100644 test/integration/node/package.json create mode 100644 test/integration/node/test.mjs create mode 100644 test/integration/typescript/package.json create mode 100644 test/integration/typescript/test.ts create mode 100644 test/integration/unpkg/package.json create mode 100644 test/integration/unpkg/test.mjs create mode 100644 test/integration/vite/index.html create mode 100644 test/integration/vite/index.ts create mode 100644 test/integration/vite/package.json create mode 100644 test/integration/webpack/package.json create mode 100644 test/integration/webpack/test.js delete mode 100644 test/karma.conf.cjs delete mode 100644 test/scripts/node_test.cjs create mode 100644 test/scripts/test_integrations.mjs create mode 100644 test/web-test-runner.config.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ecff3d69..cf01a317 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,7 +1,13 @@ module.exports = { parser: "@typescript-eslint/parser", - plugins: ["jsdoc", "html"], + plugins: ["jsdoc", "html", "file-extension-in-import-ts"], extends: ["plugin:@typescript-eslint/recommended"], + settings: { + "import/extensions": [".js", ".ts"], + "import/resolver": { + typescript: true, + }, + }, rules: { "prefer-rest-params": "off", "@typescript-eslint/ban-ts-ignore": "off", @@ -23,7 +29,7 @@ module.exports = { "no-useless-call": ["error"], "no-unmodified-loop-condition": ["error"], "quote-props": ["error", "as-needed"], - quotes: ["error", "double"], + quotes: ["error", "double", { avoidEscape: true }], "no-shadow": "error", "no-console": ["error", { allow: ["warn"] }], "@typescript-eslint/no-object-literal-type-assertion": "off", @@ -38,25 +44,11 @@ module.exports = { }, ], "no-lonely-if": ["error"], - semi: ["error", "always"], "no-cond-assign": ["error", "always"], - indent: "off", "no-var": "error", "prefer-arrow-callback": "error", - "@typescript-eslint/indent": [ - "error", - "tab", - { SwitchCase: 1, MemberExpression: 2 }, - ], "@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/explicit-function-return-type": "off", - "no-multi-spaces": ["error"], - "array-bracket-spacing": ["error", "never"], - "block-spacing": ["error", "always"], - "func-call-spacing": ["error", "never"], - "key-spacing": ["error", { beforeColon: false, afterColon: true }], - "brace-style": ["error", "1tbs"], - "space-in-parens": ["error", "never"], "eol-last": ["error", "always"], "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-use-before-define": "off", @@ -70,21 +62,7 @@ module.exports = { }, ], "lines-between-class-members": "off", - "no-multiple-empty-lines": ["error", { max: 1, maxEOF: 1, maxBOF: 0 }], "no-unneeded-ternary": ["error"], - "object-curly-spacing": ["error", "always"], - "space-unary-ops": ["error", { words: true, nonwords: false }], - "block-spacing": ["error", "always"], - "keyword-spacing": ["error", { before: true }], - "space-before-function-paren": [ - "error", - { anonymous: "never", named: "never", asyncArrow: "always" }, - ], - "comma-spacing": ["error", { before: false, after: true }], - "arrow-spacing": ["error", { before: true, after: true }], - "space-before-blocks": [ - "error", - { functions: "always", keywords: "always", classes: "always" }, - ], + "file-extension-in-import-ts/file-extension-in-import-ts": "error", }, }; diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5da7e469..4520b412 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,12 +26,10 @@ jobs: - name: Setup Nodejs uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 cache: 'npm' - name: Install dependencies run: npm install - - name: Build - run: npm run build - name: All tests run: npm run test - name: Upload coverage @@ -52,7 +50,7 @@ jobs: - name: Setup Nodejs uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 cache: 'npm' - name: Install dependencies run: npm install @@ -72,7 +70,7 @@ jobs: - name: Setup Nodejs uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 cache: 'npm' - name: Install dependencies run: npm install @@ -92,7 +90,7 @@ jobs: - name: Setup Nodejs uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 cache: 'npm' - name: Install dependencies run: npm install @@ -110,7 +108,7 @@ jobs: - name: Setup Nodejs uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 cache: 'npm' - name: Install dependencies run: npm install @@ -118,10 +116,30 @@ jobs: run: npm run build - name: Test run: npm run test:readme + test-integrations: + name: Test integrations + permissions: + contents: read + id-token: write + runs-on: ubuntu-latest + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + - name: Setup Nodejs + uses: actions/setup-node@v4 + with: + node-version: 18.18.0 + cache: 'npm' + - name: Install dependencies + run: npm install + - name: Build + run: npm run build + - name: Test + run: npm run test:integrations publish: runs-on: ubuntu-latest # make sure all the tests pass first - needs: [run-tests, test-code-examples, test-html-examples, test-lint, test-readme] + needs: [run-tests, test-code-examples, test-html-examples, test-lint, test-readme, test-integrations] # not on PRs if: github.event_name != 'pull_request' env: @@ -132,7 +150,7 @@ jobs: # Setup .npmrc file to publish to npm - uses: actions/setup-node@v4 with: - node-version: 18.12.0 + node-version: 18.18.0 registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: npm install diff --git a/.gitignore b/.gitignore index 774401a2..b20b1679 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ test/supports.html coverage/ build/* -dist/* +**/dist/* examples/scratch.js examples/scratch.ts @@ -34,3 +34,4 @@ docs .vscode tone.d.ts examples/scratch.ts +test/integration/*/package-lock.json diff --git a/Tone/classes.ts b/Tone/classes.ts index d2460d11..e572e12e 100644 --- a/Tone/classes.ts +++ b/Tone/classes.ts @@ -1,7 +1,7 @@ -export * from "./core/index"; -export * from "./source/index"; -export * from "./signal/index"; -export * from "./instrument/index"; -export * from "./event/index"; -export * from "./effect/index"; -export * from "./component/index"; +export * from "./core/index.js"; +export * from "./source/index.js"; +export * from "./signal/index.js"; +export * from "./instrument/index.js"; +export * from "./event/index.js"; +export * from "./effect/index.js"; +export * from "./component/index.js"; diff --git a/Tone/component/analysis/Analyser.test.ts b/Tone/component/analysis/Analyser.test.ts index d88ccbfb..03ccc1f6 100644 --- a/Tone/component/analysis/Analyser.test.ts +++ b/Tone/component/analysis/Analyser.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Noise } from "../../source/Noise"; -import { Analyser } from "./Analyser"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Noise } from "../../source/Noise.js"; +import { Analyser } from "./Analyser.js"; describe("Analyser", () => { - BasicTests(Analyser); it("can get and set properties", () => { @@ -31,7 +30,7 @@ describe("Analyser", () => { const anl = new Analyser("fft", 512); const analysis = anl.getValue(); expect(analysis.length).to.equal(512); - analysis.forEach(val => { + analysis.forEach((val) => { expect(val).is.lessThan(0); }); anl.dispose(); @@ -46,7 +45,7 @@ describe("Analyser", () => { setTimeout(() => { const analysis = anl.getValue(); expect(analysis.length).to.equal(256); - analysis.forEach(val => { + analysis.forEach((val) => { expect(val).is.within(-1, 1); }); anl.dispose(); @@ -74,5 +73,4 @@ describe("Analyser", () => { expect((anl.getValue()[0] as Float32Array).length).to.equal(512); anl.dispose(); }); - }); diff --git a/Tone/component/analysis/Analyser.ts b/Tone/component/analysis/Analyser.ts index 7f685b48..20aa451b 100644 --- a/Tone/component/analysis/Analyser.ts +++ b/Tone/component/analysis/Analyser.ts @@ -1,9 +1,14 @@ -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { NormalRange, PowerOfTwo } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Split } from "../channel/Split"; -import { Gain } from "../../core/context/Gain"; -import { assert, assertRange } from "../../core/util/Debug"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { NormalRange, PowerOfTwo } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Split } from "../channel/Split.js"; +import { Gain } from "../../core/context/Gain.js"; +import { assert, assertRange } from "../../core/util/Debug.js"; export type AnalyserType = "fft" | "waveform"; @@ -20,7 +25,6 @@ export interface AnalyserOptions extends ToneAudioNodeOptions { * @category Component */ export class Analyser extends ToneAudioNode { - readonly name: string = "Analyser"; readonly input: InputNode; @@ -58,18 +62,30 @@ export class Analyser extends ToneAudioNode { constructor(type?: AnalyserType, size?: number); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Analyser.getDefaults(), arguments, ["type", "size"])); - const options = optionsFromArguments(Analyser.getDefaults(), arguments, ["type", "size"]); - - this.input = this.output = this._gain = new Gain({ context: this.context }); + super( + optionsFromArguments(Analyser.getDefaults(), arguments, [ + "type", + "size", + ]) + ); + const options = optionsFromArguments( + Analyser.getDefaults(), + arguments, + ["type", "size"] + ); + + this.input = + this.output = + this._gain = + new Gain({ context: this.context }); this._split = new Split({ context: this.context, channels: options.channels, }); this.input.connect(this._split); - + assertRange(options.channels, 1); - + // create the analysers for (let channel = 0; channel < options.channels; channel++) { this._analysers[channel] = this.context.createAnalyser(); @@ -141,7 +157,10 @@ export class Analyser extends ToneAudioNode { return this._type; } set type(type: AnalyserType) { - assert(type === "waveform" || type === "fft", `Analyser: invalid type: ${type}`); + assert( + type === "waveform" || type === "fft", + `Analyser: invalid type: ${type}` + ); this._type = type; } @@ -152,7 +171,7 @@ export class Analyser extends ToneAudioNode { return this._analysers[0].smoothingTimeConstant; } set smoothing(val: NormalRange) { - this._analysers.forEach(a => a.smoothingTimeConstant = val); + this._analysers.forEach((a) => (a.smoothingTimeConstant = val)); } /** @@ -160,7 +179,7 @@ export class Analyser extends ToneAudioNode { */ dispose(): this { super.dispose(); - this._analysers.forEach(a => a.disconnect()); + this._analysers.forEach((a) => a.disconnect()); this._split.dispose(); this._gain.dispose(); return this; diff --git a/Tone/component/analysis/DCMeter.test.ts b/Tone/component/analysis/DCMeter.test.ts index 96c2bffa..ca4657b0 100644 --- a/Tone/component/analysis/DCMeter.test.ts +++ b/Tone/component/analysis/DCMeter.test.ts @@ -1,16 +1,13 @@ import { expect } from "chai"; -import { BasicTests, warns } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { Signal } from "Tone/signal/Signal"; -import { DCMeter } from "./DCMeter"; +import { BasicTests, warns } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { DCMeter } from "./DCMeter.js"; describe("DCMeter", () => { - BasicTests(DCMeter); context("DCMetering", () => { - it("passes the audio through", () => { return PassAudio((input) => { const meter = new DCMeter().toDestination(); @@ -18,17 +15,15 @@ describe("DCMeter", () => { }); }); - if (ONLINE_TESTING) { - it("can get the rms level of the incoming signal", (done) => { - const meter = new DCMeter(); - const osc = new Signal(2).connect(meter); - setTimeout(() => { - expect(meter.getValue()).to.be.closeTo(2, 0.1); - meter.dispose(); - osc.dispose(); - done(); - }, 400); - }); - } + it("can get the rms level of the incoming signal", (done) => { + const meter = new DCMeter(); + const osc = new Signal(2).connect(meter); + setTimeout(() => { + expect(meter.getValue()).to.be.closeTo(2, 0.1); + meter.dispose(); + osc.dispose(); + done(); + }, 400); + }); }); }); diff --git a/Tone/component/analysis/DCMeter.ts b/Tone/component/analysis/DCMeter.ts index 5da5770c..3b68b8a5 100644 --- a/Tone/component/analysis/DCMeter.ts +++ b/Tone/component/analysis/DCMeter.ts @@ -1,10 +1,10 @@ -import { optionsFromArguments } from "../../core/util/Defaults"; -import { MeterBase, MeterBaseOptions } from "./MeterBase"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { MeterBase, MeterBaseOptions } from "./MeterBase.js"; export type DCMeterOptions = MeterBaseOptions; /** - * DCMeter gets the raw value of the input signal at the current time. + * DCMeter gets the raw value of the input signal at the current time. * @see {@link Meter}. * * @example @@ -18,7 +18,6 @@ export type DCMeterOptions = MeterBaseOptions; * @category Component */ export class DCMeter extends MeterBase { - readonly name: string = "DCMeter"; constructor(options?: Partial); diff --git a/Tone/component/analysis/FFT.test.ts b/Tone/component/analysis/FFT.test.ts index a487959c..b4e5eed1 100644 --- a/Tone/component/analysis/FFT.test.ts +++ b/Tone/component/analysis/FFT.test.ts @@ -1,11 +1,9 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { Noise } from "Tone/source/Noise"; -import { FFT } from "./FFT"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Noise } from "../../source/Noise.js"; +import { FFT } from "./FFT.js"; describe("FFT", () => { - BasicTests(FFT); it("can get and set properties", () => { @@ -38,7 +36,10 @@ describe("FFT", () => { it("can get the frequency values of each index of the return array", () => { const fft = new FFT(32); expect(fft.getFrequencyOfIndex(0)).to.be.closeTo(0, 1); - expect(fft.getFrequencyOfIndex(16)).to.be.closeTo(fft.context.sampleRate / 4, 1); + expect(fft.getFrequencyOfIndex(16)).to.be.closeTo( + fft.context.sampleRate / 4, + 1 + ); fft.dispose(); }); @@ -51,7 +52,7 @@ describe("FFT", () => { setTimeout(() => { const analysis = fft.getValue(); expect(analysis.length).to.equal(256); - analysis.forEach(value => { + analysis.forEach((value) => { expect(value).is.within(-Infinity, 0); }); fft.dispose(); @@ -60,24 +61,22 @@ describe("FFT", () => { }, 300); }); - if (ONLINE_TESTING) { - it("outputs a normal range", (done) => { - const noise = new Noise(); - const fft = new FFT({ - normalRange: true, - }); - noise.connect(fft); - noise.start(); - - setTimeout(() => { - const analysis = fft.getValue(); - analysis.forEach(value => { - expect(value).is.within(0, 1); - }); - fft.dispose(); - noise.dispose(); - done(); - }, 300); + it("outputs a normal range", (done) => { + const noise = new Noise(); + const fft = new FFT({ + normalRange: true, }); - } + noise.connect(fft); + noise.start(); + + setTimeout(() => { + const analysis = fft.getValue(); + analysis.forEach((value) => { + expect(value).is.within(0, 1); + }); + fft.dispose(); + noise.dispose(); + done(); + }, 300); + }); }); diff --git a/Tone/component/analysis/FFT.ts b/Tone/component/analysis/FFT.ts index 30d0a862..6f935983 100644 --- a/Tone/component/analysis/FFT.ts +++ b/Tone/component/analysis/FFT.ts @@ -1,9 +1,9 @@ -import { ToneAudioNode } from "../../core/context/ToneAudioNode"; -import { dbToGain } from "../../core/type/Conversions"; -import { Hertz, NormalRange, PowerOfTwo } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { MeterBase, MeterBaseOptions } from "./MeterBase"; -import { assert } from "../../core/util/Debug"; +import { ToneAudioNode } from "../../core/context/ToneAudioNode.js"; +import { dbToGain } from "../../core/type/Conversions.js"; +import { Hertz, NormalRange, PowerOfTwo } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { MeterBase, MeterBaseOptions } from "./MeterBase.js"; +import { assert } from "../../core/util/Debug.js"; export interface FFTOptions extends MeterBaseOptions { size: PowerOfTwo; @@ -17,7 +17,6 @@ export interface FFTOptions extends MeterBaseOptions { * @category Component */ export class FFT extends MeterBase { - readonly name: string = "FFT"; /** @@ -34,7 +33,9 @@ export class FFT extends MeterBase { constructor(options?: Partial); constructor() { super(optionsFromArguments(FFT.getDefaults(), arguments, ["size"])); - const options = optionsFromArguments(FFT.getDefaults(), arguments, ["size"]); + const options = optionsFromArguments(FFT.getDefaults(), arguments, [ + "size", + ]); this.normalRange = options.normalRange; this._analyser.type = "fft"; @@ -55,7 +56,7 @@ export class FFT extends MeterBase { */ getValue(): Float32Array { const values = this._analyser.getValue() as Float32Array; - return values.map(v => this.normalRange ? dbToGain(v) : v); + return values.map((v) => (this.normalRange ? dbToGain(v) : v)); } /** @@ -87,7 +88,10 @@ export class FFT extends MeterBase { * console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index))); */ getFrequencyOfIndex(index: number): Hertz { - assert(0 <= index && index < this.size, `index must be greater than or equal to 0 and less than ${this.size}`); - return index * this.context.sampleRate / (this.size * 2); + assert( + 0 <= index && index < this.size, + `index must be greater than or equal to 0 and less than ${this.size}` + ); + return (index * this.context.sampleRate) / (this.size * 2); } } diff --git a/Tone/component/analysis/Follower.test.ts b/Tone/component/analysis/Follower.test.ts index 5ef7df2e..5fd4dc49 100644 --- a/Tone/component/analysis/Follower.test.ts +++ b/Tone/component/analysis/Follower.test.ts @@ -1,16 +1,14 @@ -import { Follower } from "./Follower"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { Signal } from "Tone/signal/Signal"; -import { PassAudio } from "test/helper/PassAudio"; +import { Follower } from "./Follower.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { Signal } from "../../signal/Signal.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; import { expect } from "chai"; describe("Follower", () => { - BasicTests(Follower); context("Envelope Following", () => { - it("handles getter/setter as Object", () => { const foll = new Follower(); const values = { @@ -108,4 +106,3 @@ describe("Follower", () => { }); }); }); - diff --git a/Tone/component/analysis/Follower.ts b/Tone/component/analysis/Follower.ts index a32f974e..46dc54d3 100644 --- a/Tone/component/analysis/Follower.ts +++ b/Tone/component/analysis/Follower.ts @@ -1,16 +1,21 @@ -import { Time } from "../../core/type/Units"; -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { OnePoleFilter } from "../filter/OnePoleFilter"; -import { Abs } from "../../signal/Abs"; +import { Time } from "../../core/type/Units.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { OnePoleFilter } from "../filter/OnePoleFilter.js"; +import { Abs } from "../../signal/Abs.js"; export interface FollowerOptions extends ToneAudioNodeOptions { smoothing: Time; } /** - * Follower is a simple envelope follower. - * It's implemented by applying a lowpass filter to the absolute value of the incoming signal. + * Follower is a simple envelope follower. + * It's implemented by applying a lowpass filter to the absolute value of the incoming signal. * ``` * +-----+ +---------------+ * Input +--> Abs +----> OnePoleFilter +--> Output @@ -19,7 +24,6 @@ export interface FollowerOptions extends ToneAudioNodeOptions { * @category Component */ export class Follower extends ToneAudioNode { - readonly name: string = "Follower"; readonly input: InputNode; @@ -46,14 +50,22 @@ export class Follower extends ToneAudioNode { constructor(smoothing?: Time); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Follower.getDefaults(), arguments, ["smoothing"])); - const options = optionsFromArguments(Follower.getDefaults(), arguments, ["smoothing"]); + super( + optionsFromArguments(Follower.getDefaults(), arguments, [ + "smoothing", + ]) + ); + const options = optionsFromArguments( + Follower.getDefaults(), + arguments, + ["smoothing"] + ); this._abs = this.input = new Abs({ context: this.context }); this._lowpass = this.output = new OnePoleFilter({ context: this.context, frequency: 1 / this.toSeconds(options.smoothing), - type: "lowpass" + type: "lowpass", }); this._abs.connect(this._lowpass); this._smoothing = options.smoothing; @@ -61,12 +73,12 @@ export class Follower extends ToneAudioNode { static getDefaults(): FollowerOptions { return Object.assign(ToneAudioNode.getDefaults(), { - smoothing: 0.05 + smoothing: 0.05, }); } /** - * The amount of time it takes a value change to arrive at the updated value. + * The amount of time it takes a value change to arrive at the updated value. */ get smoothing(): Time { return this._smoothing; diff --git a/Tone/component/analysis/Meter.test.ts b/Tone/component/analysis/Meter.test.ts index 3b2398fb..bc6f5dc5 100644 --- a/Tone/component/analysis/Meter.test.ts +++ b/Tone/component/analysis/Meter.test.ts @@ -1,19 +1,16 @@ import { expect } from "chai"; -import { BasicTests, warns } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { Signal } from "Tone/signal/Signal"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { Meter } from "./Meter"; -import { Panner } from "Tone/component/channel/Panner"; -import { Merge } from "Tone/component/channel/Merge"; +import { BasicTests, warns } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; +import { Meter } from "./Meter.js"; +import { Panner } from "../channel/Panner.js"; +import { Merge } from "../channel/Merge.js"; describe("Meter", () => { - BasicTests(Meter); context("Metering", () => { - it("handles getter/setter as Object", () => { const meter = new Meter(); const values = { @@ -60,57 +57,54 @@ describe("Meter", () => { meter.dispose(); }); }); - - if (ONLINE_TESTING) { - - it("can get the rms level of the incoming signal", (done) => { - const meter = new Meter(); - const osc = new Oscillator().connect(meter).start(); - osc.volume.value = -6; - setTimeout(() => { - expect(meter.getValue()).to.be.closeTo(-9, 1); - meter.dispose(); - osc.dispose(); - done(); - }, 400); - }); - it("can get the values in normal range", (done) => { - const meter = new Meter({ - normalRange: true, - }); - const osc = new Oscillator().connect(meter).start(); - osc.volume.value = -6; - setTimeout(() => { - expect(meter.getValue()).to.be.closeTo(0.35, 0.15); - meter.dispose(); - osc.dispose(); - done(); - }, 400); + it("can get the rms level of the incoming signal", (done) => { + const meter = new Meter(); + const osc = new Oscillator().connect(meter).start(); + osc.volume.value = -6; + setTimeout(() => { + expect(meter.getValue()).to.be.closeTo(-9, 1); + meter.dispose(); + osc.dispose(); + done(); + }, 400); + }); + + it("can get the values in normal range", (done) => { + const meter = new Meter({ + normalRange: true, }); + const osc = new Oscillator().connect(meter).start(); + osc.volume.value = -6; + setTimeout(() => { + expect(meter.getValue()).to.be.closeTo(0.35, 0.15); + meter.dispose(); + osc.dispose(); + done(); + }, 400); + }); - it("can get the rms levels for multiple channels", (done) => { - const meter = new Meter({ - channelCount: 2, - smoothing: 0.5, - }); - const merge = new Merge().connect(meter); - const osc0 = new Oscillator().connect(merge, 0, 0).start(); - const osc1 = new Oscillator().connect(merge, 0, 1).start(); - osc0.volume.value = -6; - osc1.volume.value = -18; - setTimeout(() => { - const values = meter.getValue(); - expect(values).to.have.lengthOf(2); - expect(values[0]).to.be.closeTo(-9, 1); - expect(values[1]).to.be.closeTo(-21, 1); - meter.dispose(); - merge.dispose(); - osc0.dispose(); - osc1.dispose(); - done(); - }, 400); + it("can get the rms levels for multiple channels", (done) => { + const meter = new Meter({ + channelCount: 2, + smoothing: 0.5, }); - } + const merge = new Merge().connect(meter); + const osc0 = new Oscillator().connect(merge, 0, 0).start(); + const osc1 = new Oscillator().connect(merge, 0, 1).start(); + osc0.volume.value = -6; + osc1.volume.value = -18; + setTimeout(() => { + const values = meter.getValue(); + expect(values).to.have.lengthOf(2); + expect(values[0]).to.be.closeTo(-9, 1); + expect(values[1]).to.be.closeTo(-21, 1); + meter.dispose(); + merge.dispose(); + osc0.dispose(); + osc1.dispose(); + done(); + }, 400); + }); }); }); diff --git a/Tone/component/analysis/Meter.ts b/Tone/component/analysis/Meter.ts index 1a8f00b4..ad96953f 100644 --- a/Tone/component/analysis/Meter.ts +++ b/Tone/component/analysis/Meter.ts @@ -1,9 +1,9 @@ -import { gainToDb } from "../../core/type/Conversions"; -import { NormalRange } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { MeterBase, MeterBaseOptions } from "./MeterBase"; -import { warn } from "../../core/util/Debug"; -import { Analyser } from "./Analyser"; +import { gainToDb } from "../../core/type/Conversions.js"; +import { NormalRange } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { MeterBase, MeterBaseOptions } from "./MeterBase.js"; +import { warn } from "../../core/util/Debug.js"; +import { Analyser } from "./Analyser.js"; export interface MeterOptions extends MeterBaseOptions { smoothing: NormalRange; @@ -15,8 +15,8 @@ export interface MeterOptions extends MeterBaseOptions { * Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square) * of an input signal. It can also get the raw value of the input signal. * Setting `normalRange` to `true` will covert the output to a range of - * 0-1. See an example using a graphical display - * [here](https://tonejs.github.io/examples/meter). + * 0-1. See an example using a graphical display + * [here](https://tonejs.github.io/examples/meter). * @see {@link DCMeter}. * * @example @@ -30,7 +30,6 @@ export interface MeterOptions extends MeterBaseOptions { * @category Component */ export class Meter extends MeterBase { - readonly name: string = "Meter"; /** @@ -56,18 +55,25 @@ export class Meter extends MeterBase { constructor(smoothing?: NormalRange); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"])); - const options = optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]); + super( + optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]) + ); + const options = optionsFromArguments(Meter.getDefaults(), arguments, [ + "smoothing", + ]); - this.input = this.output = this._analyser = new Analyser({ - context: this.context, - size: 256, - type: "waveform", - channels: options.channelCount, - }); + this.input = + this.output = + this._analyser = + new Analyser({ + context: this.context, + size: 256, + type: "waveform", + channels: options.channelCount, + }); - this.smoothing = options.smoothing, - this.normalRange = options.normalRange; + (this.smoothing = options.smoothing), + (this.normalRange = options.normalRange); this._rms = new Array(options.channelCount); this._rms.fill(0); } @@ -90,22 +96,30 @@ export class Meter extends MeterBase { } /** - * Get the current value of the incoming signal. + * Get the current value of the incoming signal. * Output is in decibels when {@link normalRange} is `false`. * If {@link channels} = 1, then the output is a single number * representing the value of the input signal. When {@link channels} > 1, - * then each channel is returned as a value in a number array. + * then each channel is returned as a value in a number array. */ getValue(): number | number[] { const aValues = this._analyser.getValue(); - const channelValues = this.channels === 1 ? [aValues as Float32Array] : aValues as Float32Array[]; + const channelValues = + this.channels === 1 + ? [aValues as Float32Array] + : (aValues as Float32Array[]); const vals = channelValues.map((values, index) => { - const totalSquared = values.reduce((total, current) => total + current * current, 0); + const totalSquared = values.reduce( + (total, current) => total + current * current, + 0 + ); const rms = Math.sqrt(totalSquared / values.length); // the rms can only fall at the rate of the smoothing // but can jump up instantly this._rms[index] = Math.max(rms, this._rms[index] * this.smoothing); - return this.normalRange ? this._rms[index] : gainToDb(this._rms[index]); + return this.normalRange + ? this._rms[index] + : gainToDb(this._rms[index]); }); if (this.channels === 1) { return vals[0]; diff --git a/Tone/component/analysis/MeterBase.ts b/Tone/component/analysis/MeterBase.ts index 5e9c6ef3..9d0fdc15 100644 --- a/Tone/component/analysis/MeterBase.ts +++ b/Tone/component/analysis/MeterBase.ts @@ -1,14 +1,20 @@ -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Analyser } from "./Analyser"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Analyser } from "./Analyser.js"; export type MeterBaseOptions = ToneAudioNodeOptions; /** * The base class for Metering classes. */ -export class MeterBase extends ToneAudioNode { - +export class MeterBase< + Options extends MeterBaseOptions, +> extends ToneAudioNode { readonly name: string = "MeterBase"; /** @@ -30,11 +36,14 @@ export class MeterBase extends ToneAudioNode { - BasicTests(Waveform); it("can get and set properties", () => { @@ -26,24 +24,21 @@ describe("Waveform", () => { anl.dispose(); }); - if (ONLINE_TESTING) { - - it("can run waveform analysis", (done) => { - const noise = new Noise(); - const anl = new Waveform(256); - noise.connect(anl); - noise.start(); + it("can run waveform analysis", (done) => { + const noise = new Noise(); + const anl = new Waveform(256); + noise.connect(anl); + noise.start(); - setTimeout(() => { - const analysis = anl.getValue(); - expect(analysis.length).to.equal(256); - analysis.forEach(value => { - expect(value).is.within(-1, 1); - }); - anl.dispose(); - noise.dispose(); - done(); - }, 300); - }); - } + setTimeout(() => { + const analysis = anl.getValue(); + expect(analysis.length).to.equal(256); + analysis.forEach((value) => { + expect(value).is.within(-1, 1); + }); + anl.dispose(); + noise.dispose(); + done(); + }, 300); + }); }); diff --git a/Tone/component/analysis/Waveform.ts b/Tone/component/analysis/Waveform.ts index b66dc34b..07c48de9 100644 --- a/Tone/component/analysis/Waveform.ts +++ b/Tone/component/analysis/Waveform.ts @@ -1,6 +1,6 @@ -import { PowerOfTwo } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { MeterBase, MeterBaseOptions } from "./MeterBase"; +import { PowerOfTwo } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { MeterBase, MeterBaseOptions } from "./MeterBase.js"; export interface WaveformOptions extends MeterBaseOptions { /** @@ -14,7 +14,6 @@ export interface WaveformOptions extends MeterBaseOptions { * @category Component */ export class Waveform extends MeterBase { - readonly name: string = "Waveform"; /** @@ -23,8 +22,14 @@ export class Waveform extends MeterBase { constructor(size?: PowerOfTwo); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Waveform.getDefaults(), arguments, ["size"])); - const options = optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]); + super( + optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]) + ); + const options = optionsFromArguments( + Waveform.getDefaults(), + arguments, + ["size"] + ); this._analyser.type = "waveform"; this.size = options.size; diff --git a/Tone/component/channel/Channel.test.ts b/Tone/component/channel/Channel.test.ts index f85d9391..cfcc7e47 100644 --- a/Tone/component/channel/Channel.test.ts +++ b/Tone/component/channel/Channel.test.ts @@ -1,16 +1,14 @@ -import { Channel } from "./Channel"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; -import { Offline } from "test/helper/Offline"; +import { Channel } from "./Channel.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { Offline } from "../../../test/helper/Offline.js"; import { expect } from "chai"; describe("Channel", () => { - BasicTests(Channel); context("Channel", () => { - it("can pass volume and panning into the constructor", () => { const channel = new Channel(-10, -1); expect(channel.pan.value).to.be.closeTo(-1, 0.01); @@ -23,7 +21,7 @@ describe("Channel", () => { pan: 1, volume: 6, mute: false, - solo: true + solo: true, }); expect(channel.pan.value).to.be.closeTo(1, 0.01); expect(channel.volume.value).to.be.closeTo(6, 0.01); @@ -31,7 +29,7 @@ describe("Channel", () => { expect(channel.solo).to.be.true; channel.dispose(); }); - + it("passes the incoming signal through", () => { return PassAudio((input) => { const channel = new Channel().toDestination(); @@ -64,7 +62,7 @@ describe("Channel", () => { describe("bus", () => { it("can connect two channels together by name", () => { - return PassAudio(input => { + return PassAudio((input) => { const sendChannel = new Channel(); input.connect(sendChannel); sendChannel.send("test"); diff --git a/Tone/component/channel/Channel.ts b/Tone/component/channel/Channel.ts index 6b199f23..0fe07960 100644 --- a/Tone/component/channel/Channel.ts +++ b/Tone/component/channel/Channel.ts @@ -1,11 +1,16 @@ -import { AudioRange, Decibels } from "../../core/type/Units"; -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Solo } from "./Solo"; -import { PanVol } from "./PanVol"; -import { Param } from "../../core/context/Param"; -import { readOnly } from "../../core/util/Interface"; -import { Gain } from "../../core/context/Gain"; +import { AudioRange, Decibels } from "../../core/type/Units.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Solo } from "./Solo.js"; +import { PanVol } from "./PanVol.js"; +import { Param } from "../../core/context/Param.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { Gain } from "../../core/context/Gain.js"; export interface ChannelOptions extends ToneAudioNodeOptions { pan: AudioRange; @@ -16,7 +21,7 @@ export interface ChannelOptions extends ToneAudioNodeOptions { } /** - * Channel provides a channel strip interface with volume, pan, solo and mute controls. + * Channel provides a channel strip interface with volume, pan, solo and mute controls. * @see {@link PanVol} and {@link Solo} * @example * // pan the incoming signal left and drop the volume 12db @@ -24,7 +29,6 @@ export interface ChannelOptions extends ToneAudioNodeOptions { * @category Component */ export class Channel extends ToneAudioNode { - readonly name: string = "Channel"; readonly input: InputNode; @@ -59,8 +63,16 @@ export class Channel extends ToneAudioNode { constructor(volume?: Decibels, pan?: AudioRange); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"])); - const options = optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]); + super( + optionsFromArguments(Channel.getDefaults(), arguments, [ + "volume", + "pan", + ]) + ); + const options = optionsFromArguments(Channel.getDefaults(), arguments, [ + "volume", + "pan", + ]); this._solo = this.input = new Solo({ solo: options.solo, @@ -71,7 +83,7 @@ export class Channel extends ToneAudioNode { pan: options.pan, volume: options.volume, mute: options.mute, - channelCount: options.channelCount + channelCount: options.channelCount, }); this.pan = this._panVol.pan; this.volume = this._panVol.volume; @@ -119,7 +131,7 @@ export class Channel extends ToneAudioNode { } /** - * Store the send/receive channels by name. + * Store the send/receive channels by name. */ private static buses: Map = new Map(); @@ -137,11 +149,11 @@ export class Channel extends ToneAudioNode { /** * Send audio to another channel using a string. `send` is a lot like - * {@link connect}, except it uses a string instead of an object. This can + * {@link connect}, except it uses a string instead of an object. This can * be useful in large applications to decouple sections since {@link send} * and {@link receive} can be invoked separately in order to connect an object * @param name The channel name to send the audio - * @param volume The amount of the signal to send. + * @param volume The amount of the signal to send. * Defaults to 0db, i.e. send the entire signal * @returns Returns the gain node of this connection. */ @@ -158,7 +170,7 @@ export class Channel extends ToneAudioNode { } /** - * Receive audio from a channel which was connected with {@link send}. + * Receive audio from a channel which was connected with {@link send}. * @param name The channel name to receive audio from. */ receive(name: string): this { diff --git a/Tone/component/channel/CrossFade.test.ts b/Tone/component/channel/CrossFade.test.ts index 27272173..e9725473 100644 --- a/Tone/component/channel/CrossFade.test.ts +++ b/Tone/component/channel/CrossFade.test.ts @@ -1,15 +1,13 @@ -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Signal } from "Tone/signal/Signal"; -import { CrossFade } from "./CrossFade"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { ConstantOutput } from "../../../test/helper/ConstantOutput.js"; +import { Signal } from "../../signal/Signal.js"; +import { CrossFade } from "./CrossFade.js"; describe("CrossFade", () => { - BasicTests(CrossFade); context("Fading", () => { - it("handles input and output connections", () => { const comp = new CrossFade(); connectFrom().connect(comp.a); @@ -19,39 +17,51 @@ describe("CrossFade", () => { }); it("pass 100% of input 0", () => { - return ConstantOutput(() => { - const crossFade = new CrossFade(); - const drySignal = new Signal(10); - const wetSignal = new Signal(20); - drySignal.connect(crossFade.a); - wetSignal.connect(crossFade.b); - crossFade.fade.value = 0; - crossFade.toDestination(); - }, 10, 0.05); + return ConstantOutput( + () => { + const crossFade = new CrossFade(); + const drySignal = new Signal(10); + const wetSignal = new Signal(20); + drySignal.connect(crossFade.a); + wetSignal.connect(crossFade.b); + crossFade.fade.value = 0; + crossFade.toDestination(); + }, + 10, + 0.05 + ); }); it("pass 100% of input 1", () => { - return ConstantOutput(() => { - const crossFade = new CrossFade(); - const drySignal = new Signal(10); - const wetSignal = new Signal(20); - drySignal.connect(crossFade.a); - wetSignal.connect(crossFade.b); - crossFade.fade.value = 1; - crossFade.toDestination(); - }, 20, 0.01); + return ConstantOutput( + () => { + const crossFade = new CrossFade(); + const drySignal = new Signal(10); + const wetSignal = new Signal(20); + drySignal.connect(crossFade.a); + wetSignal.connect(crossFade.b); + crossFade.fade.value = 1; + crossFade.toDestination(); + }, + 20, + 0.01 + ); }); it("can mix two signals", () => { - return ConstantOutput(() => { - const crossFade = new CrossFade(); - const drySignal = new Signal(2); - const wetSignal = new Signal(1); - drySignal.connect(crossFade.a); - wetSignal.connect(crossFade.b); - crossFade.fade.value = 0.5; - crossFade.toDestination(); - }, 2.12, 0.01); + return ConstantOutput( + () => { + const crossFade = new CrossFade(); + const drySignal = new Signal(2); + const wetSignal = new Signal(1); + drySignal.connect(crossFade.a); + wetSignal.connect(crossFade.b); + crossFade.fade.value = 0.5; + crossFade.toDestination(); + }, + 2.12, + 0.01 + ); }); }); }); diff --git a/Tone/component/channel/CrossFade.ts b/Tone/component/channel/CrossFade.ts index 35039b9f..87b3312f 100644 --- a/Tone/component/channel/CrossFade.ts +++ b/Tone/component/channel/CrossFade.ts @@ -1,10 +1,14 @@ -import { Gain } from "../../core/context/Gain"; -import { connect, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { NormalRange } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { GainToAudio } from "../../signal/GainToAudio"; -import { Signal } from "../../signal/Signal"; +import { Gain } from "../../core/context/Gain.js"; +import { + connect, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { NormalRange } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { GainToAudio } from "../../signal/GainToAudio.js"; +import { Signal } from "../../signal/Signal.js"; interface CrossFadeOptions extends ToneAudioNodeOptions { fade: NormalRange; @@ -37,7 +41,6 @@ interface CrossFadeOptions extends ToneAudioNodeOptions { * @category Component */ export class CrossFade extends ToneAudioNode { - readonly name: string = "CrossFade"; /** @@ -97,8 +100,18 @@ export class CrossFade extends ToneAudioNode { constructor(fade?: NormalRange); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(CrossFade.getDefaults(), arguments, ["fade"]))); - const options = optionsFromArguments(CrossFade.getDefaults(), arguments, ["fade"]); + super( + Object.assign( + optionsFromArguments(CrossFade.getDefaults(), arguments, [ + "fade", + ]) + ) + ); + const options = optionsFromArguments( + CrossFade.getDefaults(), + arguments, + ["fade"] + ); this.fade = new Signal({ context: this.context, diff --git a/Tone/component/channel/Merge.test.ts b/Tone/component/channel/Merge.test.ts index 30879fa8..d1782a9e 100644 --- a/Tone/component/channel/Merge.test.ts +++ b/Tone/component/channel/Merge.test.ts @@ -1,17 +1,15 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; -import { Merge } from "./Merge"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { Merge } from "./Merge.js"; describe("Merge", () => { - BasicTests(Merge); context("Merging", () => { - it("handles input and output connections", () => { const merge = new Merge(); connectFrom().connect(merge); @@ -43,14 +41,18 @@ describe("Merge", () => { }); it("merge two signal into one stereo signal", () => { - return Offline(() => { - const sigL = new Signal(1); - const sigR = new Signal(2); - const merger = new Merge(); - sigL.connect(merger, 0, 0); - sigR.connect(merger, 0, 1); - merger.toDestination(); - }, 0.1, 2).then(buffer => { + return Offline( + () => { + const sigL = new Signal(1); + const sigR = new Signal(2); + const merger = new Merge(); + sigL.connect(merger, 0, 0); + sigR.connect(merger, 0, 1); + merger.toDestination(); + }, + 0.1, + 2 + ).then((buffer) => { expect(buffer.toArray()[0][0]).to.be.closeTo(1, 0.001); expect(buffer.toArray()[1][0]).to.be.closeTo(2, 0.001); }); diff --git a/Tone/component/channel/Merge.ts b/Tone/component/channel/Merge.ts index 60e55a36..85957dc0 100644 --- a/Tone/component/channel/Merge.ts +++ b/Tone/component/channel/Merge.ts @@ -1,6 +1,9 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Positive } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Positive } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; interface MergeOptions extends ToneAudioNodeOptions { channels: Positive; @@ -18,7 +21,6 @@ interface MergeOptions extends ToneAudioNodeOptions { * @category Component */ export class Merge extends ToneAudioNode { - readonly name: string = "Merge"; /** @@ -42,10 +44,17 @@ export class Merge extends ToneAudioNode { constructor(channels?: Positive); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Merge.getDefaults(), arguments, ["channels"])); - const options = optionsFromArguments(Merge.getDefaults(), arguments, ["channels"]); + super( + optionsFromArguments(Merge.getDefaults(), arguments, ["channels"]) + ); + const options = optionsFromArguments(Merge.getDefaults(), arguments, [ + "channels", + ]); - this._merger = this.output = this.input = this.context.createChannelMerger(options.channels); + this._merger = + this.output = + this.input = + this.context.createChannelMerger(options.channels); } static getDefaults(): MergeOptions { diff --git a/Tone/component/channel/MidSideMerge.test.ts b/Tone/component/channel/MidSideMerge.test.ts index c49f211e..6fdd75bf 100644 --- a/Tone/component/channel/MidSideMerge.test.ts +++ b/Tone/component/channel/MidSideMerge.test.ts @@ -1,14 +1,12 @@ -import { MidSideMerge } from "./MidSideMerge"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { connectFrom, connectTo } from "test/helper/Connect"; +import { MidSideMerge } from "./MidSideMerge.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; describe("MidSideMerge", () => { - BasicTests(MidSideMerge); context("Merging", () => { - it("handles inputs and outputs", () => { const merge = new MidSideMerge(); merge.connect(connectTo()); @@ -25,4 +23,3 @@ describe("MidSideMerge", () => { }); }); }); - diff --git a/Tone/component/channel/MidSideMerge.ts b/Tone/component/channel/MidSideMerge.ts index 08f6741d..68bb294b 100644 --- a/Tone/component/channel/MidSideMerge.ts +++ b/Tone/component/channel/MidSideMerge.ts @@ -1,10 +1,13 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Merge } from "./Merge"; -import { Add } from "../../signal/Add"; -import { Multiply } from "../../signal/Multiply"; -import { Subtract } from "../../signal/Subtract"; -import { Gain } from "../../core/context/Gain"; -import { optionsFromArguments } from "../../core/util/Defaults"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Merge } from "./Merge.js"; +import { Add } from "../../signal/Add.js"; +import { Multiply } from "../../signal/Multiply.js"; +import { Subtract } from "../../signal/Subtract.js"; +import { Gain } from "../../core/context/Gain.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; export type MidSideMergeOptions = ToneAudioNodeOptions; @@ -17,7 +20,6 @@ export type MidSideMergeOptions = ToneAudioNodeOptions; * @category Component */ export class MidSideMerge extends ToneAudioNode { - readonly name: string = "MidSideMerge"; /** @@ -64,7 +66,7 @@ export class MidSideMerge extends ToneAudioNode { * Multiply the left by sqrt(1/2) */ private _rightMult: Multiply; - + constructor(options?: Partial); constructor() { super(optionsFromArguments(MidSideMerge.getDefaults(), arguments)); @@ -72,13 +74,13 @@ export class MidSideMerge extends ToneAudioNode { this.side = new Gain({ context: this.context }); this._left = new Add({ context: this.context }); this._leftMult = new Multiply({ - context: this.context, - value: Math.SQRT1_2 + context: this.context, + value: Math.SQRT1_2, }); this._right = new Subtract({ context: this.context }); this._rightMult = new Multiply({ - context: this.context, - value: Math.SQRT1_2 + context: this.context, + value: Math.SQRT1_2, }); this._merge = this.output = new Merge({ context: this.context }); @@ -91,7 +93,7 @@ export class MidSideMerge extends ToneAudioNode { this._leftMult.connect(this._merge, 0, 0); this._rightMult.connect(this._merge, 0, 1); } - + dispose(): this { super.dispose(); this.mid.dispose(); diff --git a/Tone/component/channel/MidSideSplit.test.ts b/Tone/component/channel/MidSideSplit.test.ts index 180eda5e..bf34132f 100644 --- a/Tone/component/channel/MidSideSplit.test.ts +++ b/Tone/component/channel/MidSideSplit.test.ts @@ -1,18 +1,16 @@ -import { MidSideSplit } from "./MidSideSplit"; -import { MidSideMerge } from "./MidSideMerge"; -import { BasicTests } from "test/helper/Basic"; -import { Signal } from "Tone/signal/Signal"; -import { Offline } from "test/helper/Offline"; -import { Merge } from "./Merge"; -import { connectFrom, connectTo } from "test/helper/Connect"; +import { MidSideSplit } from "./MidSideSplit.js"; +import { MidSideMerge } from "./MidSideMerge.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Signal } from "../../signal/Signal.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { Merge } from "./Merge.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; import { expect } from "chai"; describe("MidSideSplit", () => { - BasicTests(MidSideSplit); context("Splitting", () => { - it("handles inputs and outputs", () => { const split = new MidSideSplit(); connectFrom().connect(split); @@ -61,19 +59,26 @@ describe("MidSideSplit", () => { }); it("can decompose and reconstruct a signal", () => { - return Offline(() => { - const midSideMerge = new MidSideMerge().toDestination(); - const split = new MidSideSplit(); - split.mid.connect(midSideMerge.mid); - split.side.connect(midSideMerge.side); - const merge = new Merge().connect(split); - new Signal(0.2).connect(merge, 0, 0); - new Signal(0.4).connect(merge, 0, 1); - }, 0.1, 2).then((buffer) => { - buffer.toArray()[0].forEach(l => expect(l).to.be.closeTo(0.2, 0.01)); - buffer.toArray()[1].forEach(r => expect(r).to.be.closeTo(0.4, 0.01)); + return Offline( + () => { + const midSideMerge = new MidSideMerge().toDestination(); + const split = new MidSideSplit(); + split.mid.connect(midSideMerge.mid); + split.side.connect(midSideMerge.side); + const merge = new Merge().connect(split); + new Signal(0.2).connect(merge, 0, 0); + new Signal(0.4).connect(merge, 0, 1); + }, + 0.1, + 2 + ).then((buffer) => { + buffer + .toArray()[0] + .forEach((l) => expect(l).to.be.closeTo(0.2, 0.01)); + buffer + .toArray()[1] + .forEach((r) => expect(r).to.be.closeTo(0.4, 0.01)); }); }); }); }); - diff --git a/Tone/component/channel/MidSideSplit.ts b/Tone/component/channel/MidSideSplit.ts index 1c9be390..37174f21 100644 --- a/Tone/component/channel/MidSideSplit.ts +++ b/Tone/component/channel/MidSideSplit.ts @@ -1,9 +1,12 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Split } from "./Split"; -import { Add } from "../../signal/Add"; -import { Multiply } from "../../signal/Multiply"; -import { Subtract } from "../../signal/Subtract"; -import { optionsFromArguments } from "../../core/util/Defaults"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Split } from "./Split.js"; +import { Add } from "../../signal/Add.js"; +import { Multiply } from "../../signal/Multiply.js"; +import { Subtract } from "../../signal/Subtract.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; export type MidSideSplitOptions = ToneAudioNodeOptions; @@ -17,7 +20,6 @@ export type MidSideSplitOptions = ToneAudioNodeOptions; * @category Component */ export class MidSideSplit extends ToneAudioNode { - readonly name: string = "MidSideSplit"; readonly input: Split; @@ -37,7 +39,7 @@ export class MidSideSplit extends ToneAudioNode { private _midAdd: Add; /** - * Subtract left and right channels. + * Subtract left and right channels. */ private _sideSubtract: Subtract; @@ -50,14 +52,14 @@ export class MidSideSplit extends ToneAudioNode { * The "side" output. `(Left-Right)/sqrt(2)` */ readonly side: ToneAudioNode; - + constructor(options?: Partial); constructor() { super(optionsFromArguments(MidSideSplit.getDefaults(), arguments)); this._split = this.input = new Split({ channels: 2, - context: this.context + context: this.context, }); this._midAdd = new Add({ context: this.context }); this.mid = new Multiply({ diff --git a/Tone/component/channel/Mono.test.ts b/Tone/component/channel/Mono.test.ts index 1c00dcf6..cad72f89 100644 --- a/Tone/component/channel/Mono.test.ts +++ b/Tone/component/channel/Mono.test.ts @@ -1,21 +1,23 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { StereoSignal } from "test/helper/StereoSignal"; -import { Signal } from "Tone/signal/Signal"; -import { Mono } from "./Mono"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { StereoSignal } from "../../../test/helper/StereoSignal.js"; +import { Signal } from "../../signal/Signal.js"; +import { Mono } from "./Mono.js"; describe("Mono", () => { - BasicTests(Mono); context("Mono", () => { - it("Makes a mono signal in both channels", () => { - return Offline(() => { - const mono = new Mono().toDestination(); - const signal = new Signal(2).connect(mono); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const mono = new Mono().toDestination(); + const signal = new Signal(2).connect(mono); + }, + 0.1, + 2 + ).then((buffer) => { expect(buffer.toArray()[0][0]).to.equal(2); expect(buffer.toArray()[1][0]).to.equal(2); expect(buffer.toArray()[0][100]).to.equal(2); @@ -26,10 +28,14 @@ describe("Mono", () => { }); it("Sums a stereo signal into a mono signal", () => { - return Offline(() => { - const mono = new Mono().toDestination(); - const signal = StereoSignal(2, 2).connect(mono); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const mono = new Mono().toDestination(); + const signal = StereoSignal(2, 2).connect(mono); + }, + 0.1, + 2 + ).then((buffer) => { expect(buffer.toArray()[0][0]).to.equal(2); expect(buffer.toArray()[1][0]).to.equal(2); expect(buffer.toArray()[0][100]).to.equal(2); @@ -40,4 +46,3 @@ describe("Mono", () => { }); }); }); - diff --git a/Tone/component/channel/Mono.ts b/Tone/component/channel/Mono.ts index f999e8f8..67239f60 100644 --- a/Tone/component/channel/Mono.ts +++ b/Tone/component/channel/Mono.ts @@ -1,7 +1,11 @@ -import { Gain } from "../../core/context/Gain"; -import { OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Merge } from "./Merge"; +import { Gain } from "../../core/context/Gain.js"; +import { + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Merge } from "./Merge.js"; export type MonoOptions = ToneAudioNodeOptions; @@ -12,7 +16,6 @@ export type MonoOptions = ToneAudioNodeOptions; * @category Component */ export class Mono extends ToneAudioNode { - readonly name: string = "Mono"; /** @@ -32,7 +35,6 @@ export class Mono extends ToneAudioNode { constructor(options?: Partial); constructor() { - super(optionsFromArguments(Mono.getDefaults(), arguments)); this.input = new Gain({ context: this.context }); diff --git a/Tone/component/channel/MultibandSplit.test.ts b/Tone/component/channel/MultibandSplit.test.ts index 38f77b53..46a94ea4 100644 --- a/Tone/component/channel/MultibandSplit.test.ts +++ b/Tone/component/channel/MultibandSplit.test.ts @@ -1,11 +1,10 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { PassAudio } from "test/helper/PassAudio"; -import { MultibandSplit } from "./MultibandSplit"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { MultibandSplit } from "./MultibandSplit.js"; describe("MultibandSplit", () => { - BasicTests(MultibandSplit); it("handles input and output connections", () => { @@ -41,21 +40,21 @@ describe("MultibandSplit", () => { }); it("passes the incoming signal through low", () => { - return PassAudio(input => { + return PassAudio((input) => { const split = new MultibandSplit().low.toDestination(); input.connect(split); }); }); it("passes the incoming signal through mid", () => { - return PassAudio(input => { + return PassAudio((input) => { const split = new MultibandSplit().mid.toDestination(); input.connect(split); }); }); it("passes the incoming signal through high", () => { - return PassAudio(input => { + return PassAudio((input) => { const split = new MultibandSplit({ highFrequency: 10, lowFrequency: 5, diff --git a/Tone/component/channel/MultibandSplit.ts b/Tone/component/channel/MultibandSplit.ts index 55b35fc8..82fa2edc 100644 --- a/Tone/component/channel/MultibandSplit.ts +++ b/Tone/component/channel/MultibandSplit.ts @@ -1,10 +1,13 @@ -import { Gain } from "../../core/context/Gain"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Frequency, Positive } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly, writable } from "../../core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { Filter } from "../filter/Filter"; +import { Gain } from "../../core/context/Gain.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Frequency, Positive } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly, writable } from "../../core/util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { Filter } from "../filter/Filter.js"; interface MultibandSplitOptions extends ToneAudioNodeOptions { Q: Positive; @@ -31,7 +34,6 @@ interface MultibandSplitOptions extends ToneAudioNodeOptions { * @category Component */ export class MultibandSplit extends ToneAudioNode { - readonly name: string = "MultibandSplit"; /** @@ -104,8 +106,17 @@ export class MultibandSplit extends ToneAudioNode { constructor(lowFrequency?: Frequency, highFrequency?: Frequency); constructor(options?: Partial); constructor() { - super(optionsFromArguments(MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"])); - const options = optionsFromArguments(MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]); + super( + optionsFromArguments(MultibandSplit.getDefaults(), arguments, [ + "lowFrequency", + "highFrequency", + ]) + ); + const options = optionsFromArguments( + MultibandSplit.getDefaults(), + arguments, + ["lowFrequency", "highFrequency"] + ); this.lowFrequency = new Signal({ context: this.context, @@ -162,5 +173,4 @@ export class MultibandSplit extends ToneAudioNode { this.Q.dispose(); return this; } - } diff --git a/Tone/component/channel/PanVol.test.ts b/Tone/component/channel/PanVol.test.ts index 1ce44511..4645011d 100644 --- a/Tone/component/channel/PanVol.test.ts +++ b/Tone/component/channel/PanVol.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; -import { PanVol } from "./PanVol"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { PanVol } from "./PanVol.js"; describe("PanVol", () => { - BasicTests(PanVol); context("Pan and Volume", () => { - it("can be constructed with the panning and volume value", () => { const panVol = new PanVol(0.3, -12); expect(panVol.pan.value).to.be.closeTo(0.3, 0.001); @@ -53,6 +51,5 @@ describe("PanVol", () => { expect(buffer.isSilent()).to.be.true; }); }); - }); }); diff --git a/Tone/component/channel/PanVol.ts b/Tone/component/channel/PanVol.ts index 5eb355b3..009cba9f 100644 --- a/Tone/component/channel/PanVol.ts +++ b/Tone/component/channel/PanVol.ts @@ -1,10 +1,15 @@ -import { readOnly } from "../../core/util/Interface"; -import { Param } from "../../core/context/Param"; -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { AudioRange, Decibels } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Panner } from "./Panner"; -import { Volume } from "./Volume"; +import { readOnly } from "../../core/util/Interface.js"; +import { Param } from "../../core/context/Param.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { AudioRange, Decibels } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Panner } from "./Panner.js"; +import { Volume } from "./Volume.js"; export interface PanVolOptions extends ToneAudioNodeOptions { pan: AudioRange; @@ -22,7 +27,6 @@ export interface PanVolOptions extends ToneAudioNodeOptions { * @category Component */ export class PanVol extends ToneAudioNode { - readonly name: string = "PanVol"; readonly input: InputNode; @@ -57,9 +61,16 @@ export class PanVol extends ToneAudioNode { constructor(pan?: AudioRange, volume?: Decibels); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"])); - const options = optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]); + super( + optionsFromArguments(PanVol.getDefaults(), arguments, [ + "pan", + "volume", + ]) + ); + const options = optionsFromArguments(PanVol.getDefaults(), arguments, [ + "pan", + "volume", + ]); this._panner = this.input = new Panner({ context: this.context, diff --git a/Tone/component/channel/Panner.test.ts b/Tone/component/channel/Panner.test.ts index de5dd5f3..972c005c 100644 --- a/Tone/component/channel/Panner.test.ts +++ b/Tone/component/channel/Panner.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; -import { Panner } from "./Panner"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { Panner } from "./Panner.js"; describe("Panner", () => { - BasicTests(Panner); context("Panning", () => { - it("can be constructed with the panning value", () => { const panner = new Panner(0.3); expect(panner.pan.value).to.be.closeTo(0.3, 0.001); @@ -33,10 +31,14 @@ describe("Panner", () => { }); it("pans hard left when the pan is set to -1", () => { - return Offline(() => { - const panner = new Panner(-1).toDestination(); - new Signal(1).connect(panner); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const panner = new Panner(-1).toDestination(); + new Signal(1).connect(panner); + }, + 0.1, + 2 + ).then((buffer) => { const l = buffer.toArray()[0]; const r = buffer.toArray()[1]; expect(l[0]).to.be.closeTo(1, 0.01); @@ -45,10 +47,14 @@ describe("Panner", () => { }); it("pans hard right when the pan is set to 1", () => { - return Offline(() => { - const panner = new Panner(1).toDestination(); - new Signal(1).connect(panner); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const panner = new Panner(1).toDestination(); + new Signal(1).connect(panner); + }, + 0.1, + 2 + ).then((buffer) => { const l = buffer.toArray()[0]; const r = buffer.toArray()[1]; expect(l[0]).to.be.closeTo(0, 0.01); @@ -57,10 +63,14 @@ describe("Panner", () => { }); it("mixes the signal in equal power when panned center", () => { - return Offline(() => { - const panner = new Panner(0).toDestination(); - new Signal(1).connect(panner); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const panner = new Panner(0).toDestination(); + new Signal(1).connect(panner); + }, + 0.1, + 2 + ).then((buffer) => { const l = buffer.toArray()[0]; const r = buffer.toArray()[1]; expect(l[0]).to.be.closeTo(0.707, 0.01); @@ -69,13 +79,17 @@ describe("Panner", () => { }); it("can chain two panners when channelCount is 2", () => { - return Offline(() => { - const panner1 = new Panner({ - channelCount: 2, - }).toDestination(); - const panner0 = new Panner(-1).connect(panner1); - new Signal(1).connect(panner0); - }, 0.1, 2).then((buffer) => { + return Offline( + () => { + const panner1 = new Panner({ + channelCount: 2, + }).toDestination(); + const panner0 = new Panner(-1).connect(panner1); + new Signal(1).connect(panner0); + }, + 0.1, + 2 + ).then((buffer) => { const l = buffer.toArray()[0]; const r = buffer.toArray()[1]; expect(l[0]).to.be.closeTo(1, 0.01); diff --git a/Tone/component/channel/Panner.ts b/Tone/component/channel/Panner.ts index fc7fbd80..f9444e63 100644 --- a/Tone/component/channel/Panner.ts +++ b/Tone/component/channel/Panner.ts @@ -1,8 +1,11 @@ -import { Param } from "../../core/context/Param"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { AudioRange } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; +import { Param } from "../../core/context/Param.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { AudioRange } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; interface TonePannerOptions extends ToneAudioNodeOptions { pan: AudioRange; @@ -21,7 +24,6 @@ interface TonePannerOptions extends ToneAudioNodeOptions { * @category Component */ export class Panner extends ToneAudioNode { - readonly name: string = "Panner"; /** @@ -52,8 +54,14 @@ export class Panner extends ToneAudioNode { */ constructor(pan?: AudioRange); constructor() { - super(Object.assign(optionsFromArguments(Panner.getDefaults(), arguments, ["pan"]))); - const options = optionsFromArguments(Panner.getDefaults(), arguments, ["pan"]); + super( + Object.assign( + optionsFromArguments(Panner.getDefaults(), arguments, ["pan"]) + ) + ); + const options = optionsFromArguments(Panner.getDefaults(), arguments, [ + "pan", + ]); this.pan = new Param({ context: this.context, diff --git a/Tone/component/channel/Panner3D.test.ts b/Tone/component/channel/Panner3D.test.ts index e0be9998..bc2371c6 100644 --- a/Tone/component/channel/Panner3D.test.ts +++ b/Tone/component/channel/Panner3D.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { Panner3D } from "./Panner3D"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Panner3D } from "./Panner3D.js"; describe("Panner3D", () => { - BasicTests(Panner3D); it("passes the incoming signal through", () => { diff --git a/Tone/component/channel/Panner3D.ts b/Tone/component/channel/Panner3D.ts index 6f5ee061..9641b18a 100644 --- a/Tone/component/channel/Panner3D.ts +++ b/Tone/component/channel/Panner3D.ts @@ -1,8 +1,11 @@ -import { Param } from "../../core/context/Param"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Degrees, GainFactor } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import "../../core/context/Listener"; +import { Param } from "../../core/context/Param.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Degrees, GainFactor } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import "../../core/context/Listener.js"; export interface Panner3DOptions extends ToneAudioNodeOptions { coneInnerAngle: Degrees; @@ -26,7 +29,6 @@ export interface Panner3DOptions extends ToneAudioNodeOptions { * @category Component */ export class Panner3D extends ToneAudioNode { - readonly name: string = "Panner3D"; /** @@ -52,9 +54,18 @@ export class Panner3D extends ToneAudioNode { constructor(positionX: number, positionY: number, positionZ: number); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"])); - const options = optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]); + super( + optionsFromArguments(Panner3D.getDefaults(), arguments, [ + "positionX", + "positionY", + "positionZ", + ]) + ); + const options = optionsFromArguments( + Panner3D.getDefaults(), + arguments, + ["positionX", "positionY", "positionZ"] + ); this._panner = this.input = this.output = this.context.createPanner(); // set some values diff --git a/Tone/component/channel/Recorder.test.ts b/Tone/component/channel/Recorder.test.ts index 6bb4620a..df2e025d 100644 --- a/Tone/component/channel/Recorder.test.ts +++ b/Tone/component/channel/Recorder.test.ts @@ -1,14 +1,12 @@ import { expect } from "chai"; -import { connectFrom } from "test/helper/Connect"; -import { Recorder } from "./Recorder"; -import { Context } from "Tone/core/context/Context"; -import { ToneWithContext } from "Tone/core/context/ToneWithContext"; -import { Synth } from "Tone/instrument/Synth"; +import { connectFrom } from "../../../test/helper/Connect.js"; +import { Recorder } from "./Recorder.js"; +import { Context } from "../../core/context/Context.js"; +import { ToneWithContext } from "../../core/context/ToneWithContext.js"; +import { Synth } from "../../instrument/Synth.js"; describe("Recorder", () => { - context("basic", () => { - it("can be created and disposed", () => { const rec = new Recorder(); rec.dispose(); @@ -33,11 +31,13 @@ describe("Recorder", () => { it("can set a different context", () => { const testContext = new Context(); const rec = new Recorder({ - context: testContext + context: testContext, }); for (const member in rec) { if (rec[member] instanceof ToneWithContext) { - expect(rec[member].context, `member: ${member}`).to.equal(testContext); + expect(rec[member].context, `member: ${member}`).to.equal( + testContext + ); } } testContext.dispose(); @@ -47,11 +47,10 @@ describe("Recorder", () => { }); function wait(time) { - return new Promise(done => setTimeout(done, time)); + return new Promise((done) => setTimeout(done, time)); } context("start/stop/pause", () => { - it("can be started", () => { const rec = new Recorder(); rec.start(); @@ -114,6 +113,5 @@ describe("Recorder", () => { rec.dispose(); synth.dispose(); }); - }); }); diff --git a/Tone/component/channel/Recorder.ts b/Tone/component/channel/Recorder.ts index 00ab9c60..716cdeef 100644 --- a/Tone/component/channel/Recorder.ts +++ b/Tone/component/channel/Recorder.ts @@ -1,9 +1,12 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Gain } from "../../core/context/Gain"; -import { assert } from "../../core/util/Debug"; -import { theWindow } from "../../core/context/AudioContext"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { PlaybackState } from "../../core/util/StateTimeline"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Gain } from "../../core/context/Gain.js"; +import { assert } from "../../core/util/Debug.js"; +import { theWindow } from "../../core/context/AudioContext.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { PlaybackState } from "../../core/util/StateTimeline.js"; export interface RecorderOptions extends ToneAudioNodeOptions { mimeType?: string; @@ -12,8 +15,8 @@ export interface RecorderOptions extends ToneAudioNodeOptions { /** * A wrapper around the MediaRecorder API. Unlike the rest of Tone.js, this module does not offer * any sample-accurate scheduling because it is not a feature of the MediaRecorder API. - * This is only natively supported in Chrome and Firefox. - * For a cross-browser shim, install (audio-recorder-polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill]. + * This is only natively supported in Chrome and Firefox. + * For a cross-browser shim, install (audio-recorder-polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill]. * @example * const recorder = new Tone.Recorder(); * const synth = new Tone.Synth().connect(recorder); @@ -37,7 +40,6 @@ export interface RecorderOptions extends ToneAudioNodeOptions { * @category Component */ export class Recorder extends ToneAudioNode { - readonly name = "Recorder"; /** @@ -46,7 +48,7 @@ export class Recorder extends ToneAudioNode { private _recorder: MediaRecorder; /** - * MediaRecorder requires + * MediaRecorder requires */ private _stream: MediaStreamAudioDestinationNode; @@ -55,12 +57,11 @@ export class Recorder extends ToneAudioNode { constructor(options?: Partial); constructor() { - super(optionsFromArguments(Recorder.getDefaults(), arguments)); const options = optionsFromArguments(Recorder.getDefaults(), arguments); this.input = new Gain({ - context: this.context + context: this.context, }); assert(Recorder.supported, "Media Recorder API is not available"); @@ -68,7 +69,7 @@ export class Recorder extends ToneAudioNode { this._stream = this.context.createMediaStreamDestination(); this.input.connect(this._stream); this._recorder = new MediaRecorder(this._stream.stream, { - mimeType: options.mimeType + mimeType: options.mimeType, }); } @@ -77,15 +78,15 @@ export class Recorder extends ToneAudioNode { } /** - * The mime type is the format that the audio is encoded in. For Chrome - * that is typically webm encoded as "vorbis". + * The mime type is the format that the audio is encoded in. For Chrome + * that is typically webm encoded as "vorbis". */ get mimeType(): string { return this._recorder.mimeType; } /** - * Test if your platform supports the Media Recorder API. If it's not available, + * Test if your platform supports the Media Recorder API. If it's not available, * try installing this (polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill]. */ static get supported(): boolean { @@ -111,7 +112,7 @@ export class Recorder extends ToneAudioNode { */ async start() { assert(this.state !== "started", "Recorder is already started"); - const startPromise = new Promise(done => { + const startPromise = new Promise((done) => { const handleStart = () => { this._recorder.removeEventListener("start", handleStart, false); @@ -131,9 +132,13 @@ export class Recorder extends ToneAudioNode { */ async stop(): Promise { assert(this.state !== "stopped", "Recorder is not started"); - const dataPromise: Promise = new Promise(done => { + const dataPromise: Promise = new Promise((done) => { const handleData = (e: BlobEvent) => { - this._recorder.removeEventListener("dataavailable", handleData, false); + this._recorder.removeEventListener( + "dataavailable", + handleData, + false + ); done(e.data); }; diff --git a/Tone/component/channel/Solo.test.ts b/Tone/component/channel/Solo.test.ts index e804c66a..8ce4210d 100644 --- a/Tone/component/channel/Solo.test.ts +++ b/Tone/component/channel/Solo.test.ts @@ -1,15 +1,13 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Signal } from "Tone/signal/Signal"; -import { Solo } from "./Solo"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { ConstantOutput } from "../../../test/helper/ConstantOutput.js"; +import { Signal } from "../../signal/Signal.js"; +import { Solo } from "./Solo.js"; describe("Solo", () => { - BasicTests(Solo); context("Soloing", () => { - it("can be soloed an unsoloed", () => { const sol = new Solo(); sol.solo = true; @@ -81,58 +79,78 @@ describe("Solo", () => { }); it("passes both signals when nothing is soloed", () => { - return ConstantOutput(() => { - const soloA = new Solo().toDestination(); - const soloB = new Solo().toDestination(); - new Signal(10).connect(soloA); - new Signal(20).connect(soloB); - }, 30, 0.01); + return ConstantOutput( + () => { + const soloA = new Solo().toDestination(); + const soloB = new Solo().toDestination(); + new Signal(10).connect(soloA); + new Signal(20).connect(soloB); + }, + 30, + 0.01 + ); }); it("passes one signal when it is soloed", () => { - return ConstantOutput(() => { - const soloA = new Solo().toDestination(); - const soloB = new Solo().toDestination(); - new Signal(10).connect(soloA); - new Signal(20).connect(soloB); - soloA.solo = true; - }, 10, 0.01); + return ConstantOutput( + () => { + const soloA = new Solo().toDestination(); + const soloB = new Solo().toDestination(); + new Signal(10).connect(soloA); + new Signal(20).connect(soloB); + soloA.solo = true; + }, + 10, + 0.01 + ); }); it("can solo multiple at once", () => { - return ConstantOutput(() => { - const soloA = new Solo().toDestination(); - const soloB = new Solo().toDestination(); - new Signal(10).connect(soloA); - new Signal(20).connect(soloB); - soloA.solo = true; - soloB.solo = true; - }, 30, 0.01); + return ConstantOutput( + () => { + const soloA = new Solo().toDestination(); + const soloB = new Solo().toDestination(); + new Signal(10).connect(soloA); + new Signal(20).connect(soloB); + soloA.solo = true; + soloB.solo = true; + }, + 30, + 0.01 + ); }); it("can unsolo all", () => { - return ConstantOutput(() => { - const soloA = new Solo().toDestination(); - const soloB = new Solo().toDestination(); - new Signal(10).connect(soloA); - new Signal(20).connect(soloB); - soloA.solo = true; - soloB.solo = true; - soloA.solo = false; - soloB.solo = false; - }, 30, 0.01); + return ConstantOutput( + () => { + const soloA = new Solo().toDestination(); + const soloB = new Solo().toDestination(); + new Signal(10).connect(soloA); + new Signal(20).connect(soloB); + soloA.solo = true; + soloB.solo = true; + soloA.solo = false; + soloB.solo = false; + }, + 30, + 0.01 + ); }); it("can solo and unsolo while keeping previous soloed", () => { - return ConstantOutput(() => { - const soloA = new Solo().toDestination(); - const soloB = new Solo().toDestination(); - new Signal(10).connect(soloA); - new Signal(20).connect(soloB); - soloA.solo = true; - soloB.solo = true; - soloB.solo = false; - }, 10, 0.01); + return ConstantOutput( + () => { + const soloA = new Solo().toDestination(); + const soloB = new Solo().toDestination(); + new Signal(10).connect(soloA); + new Signal(20).connect(soloB); + soloA.solo = true; + soloB.solo = true; + soloB.solo = false; + }, + 10, + 0.01 + ); }); }); }); diff --git a/Tone/component/channel/Solo.ts b/Tone/component/channel/Solo.ts index 24ce0512..a509e7ec 100644 --- a/Tone/component/channel/Solo.ts +++ b/Tone/component/channel/Solo.ts @@ -1,7 +1,10 @@ -import { BaseContext } from "../../core/context/BaseContext"; -import { Gain } from "../../core/context/Gain"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; +import { BaseContext } from "../../core/context/BaseContext.js"; +import { Gain } from "../../core/context/Gain.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; export interface SoloOptions extends ToneAudioNodeOptions { solo: boolean; @@ -20,7 +23,6 @@ export interface SoloOptions extends ToneAudioNodeOptions { * @category Component */ export class Solo extends ToneAudioNode { - readonly name: string = "Solo"; readonly input: Gain; @@ -32,9 +34,10 @@ export class Solo extends ToneAudioNode { constructor(solo?: boolean); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Solo.getDefaults(), arguments, ["solo"])); - const options = optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]); + const options = optionsFromArguments(Solo.getDefaults(), arguments, [ + "solo", + ]); this.input = this.output = new Gain({ context: this.context, @@ -79,7 +82,9 @@ export class Solo extends ToneAudioNode { } else { this._removeSolo(); } - (Solo._allSolos.get(this.context) as Set).forEach(instance => instance._updateSolo()); + (Solo._allSolos.get(this.context) as Set).forEach((instance) => + instance._updateSolo() + ); } /** @@ -112,7 +117,10 @@ export class Solo extends ToneAudioNode { * Is this on the soloed array */ private _isSoloed(): boolean { - return Solo._soloed.has(this.context) && (Solo._soloed.get(this.context) as Set).has(this); + return ( + Solo._soloed.has(this.context) && + (Solo._soloed.get(this.context) as Set).has(this) + ); } /** @@ -120,9 +128,12 @@ export class Solo extends ToneAudioNode { */ private _noSolos(): boolean { // either does not have any soloed added - return !Solo._soloed.has(this.context) || + return ( + !Solo._soloed.has(this.context) || // or has a solo set but doesn't include any items - (Solo._soloed.has(this.context) && (Solo._soloed.get(this.context) as Set).size === 0); + (Solo._soloed.has(this.context) && + (Solo._soloed.get(this.context) as Set).size === 0) + ); } /** diff --git a/Tone/component/channel/Split.test.ts b/Tone/component/channel/Split.test.ts index 6e924c0e..d26538a6 100644 --- a/Tone/component/channel/Split.test.ts +++ b/Tone/component/channel/Split.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { StereoSignal } from "test/helper/StereoSignal"; -import { Split } from "./Split"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectTo } from "../../../test/helper/Connect.js"; +import { ConstantOutput } from "../../../test/helper/ConstantOutput.js"; +import { StereoSignal } from "../../../test/helper/StereoSignal.js"; +import { Split } from "./Split.js"; describe("Split", () => { - BasicTests(Split); context("Splitting", () => { - it("defaults to two channels", () => { const split = new Split(); expect(split.numberOfOutputs).to.equal(2); diff --git a/Tone/component/channel/Split.ts b/Tone/component/channel/Split.ts index e2ca0786..5eb57ee2 100644 --- a/Tone/component/channel/Split.ts +++ b/Tone/component/channel/Split.ts @@ -1,5 +1,8 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../../core/util/Defaults"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; interface SplitOptions extends ToneAudioNodeOptions { channels: number; @@ -30,10 +33,17 @@ export class Split extends ToneAudioNode { constructor(channels?: number); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Split.getDefaults(), arguments, ["channels"])); - const options = optionsFromArguments(Split.getDefaults(), arguments, ["channels"]); - - this._splitter = this.input = this.output = this.context.createChannelSplitter(options.channels); + super( + optionsFromArguments(Split.getDefaults(), arguments, ["channels"]) + ); + const options = optionsFromArguments(Split.getDefaults(), arguments, [ + "channels", + ]); + + this._splitter = + this.input = + this.output = + this.context.createChannelSplitter(options.channels); this._internalChannels = [this._splitter]; } diff --git a/Tone/component/channel/Volume.test.ts b/Tone/component/channel/Volume.test.ts index 0e6925ec..a861205c 100644 --- a/Tone/component/channel/Volume.test.ts +++ b/Tone/component/channel/Volume.test.ts @@ -1,17 +1,15 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; -import { Volume } from "./Volume"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { Volume } from "./Volume.js"; describe("Volume", () => { - BasicTests(Volume); context("Volume", () => { - it("handles input and output connections", () => { const vol = new Volume(); vol.connect(connectTo()); @@ -63,7 +61,7 @@ describe("Volume", () => { }); it("passes the incoming signal through", () => { - return PassAudio(input => { + return PassAudio((input) => { const vol = new Volume().toDestination(); input.connect(vol); }); @@ -100,7 +98,7 @@ describe("Volume", () => { const vol = new Volume(-Infinity).toDestination(); new Signal(1).connect(vol); expect(vol.mute).to.equal(true); - }).then(buffer => { + }).then((buffer) => { expect(buffer.isSilent()).to.equal(true); }); }); diff --git a/Tone/component/channel/Volume.ts b/Tone/component/channel/Volume.ts index 6017c682..121871b8 100644 --- a/Tone/component/channel/Volume.ts +++ b/Tone/component/channel/Volume.ts @@ -1,9 +1,12 @@ -import { Gain } from "../../core/context/Gain"; -import { Param } from "../../core/context/Param"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Decibels } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; +import { Gain } from "../../core/context/Gain.js"; +import { Param } from "../../core/context/Param.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Decibels } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; interface VolumeOptions extends ToneAudioNodeOptions { volume: Decibels; @@ -19,7 +22,6 @@ interface VolumeOptions extends ToneAudioNodeOptions { * @category Component */ export class Volume extends ToneAudioNode { - readonly name: string = "Volume"; /** @@ -52,9 +54,12 @@ export class Volume extends ToneAudioNode { constructor(volume?: Decibels); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Volume.getDefaults(), arguments, ["volume"])); - const options = optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]); + super( + optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]) + ); + const options = optionsFromArguments(Volume.getDefaults(), arguments, [ + "volume", + ]); this.input = this.output = new Gain({ context: this.context, diff --git a/Tone/component/dynamics/Compressor.test.ts b/Tone/component/dynamics/Compressor.test.ts index 6b11f933..8f1bd12f 100644 --- a/Tone/component/dynamics/Compressor.test.ts +++ b/Tone/component/dynamics/Compressor.test.ts @@ -1,14 +1,12 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { Compressor } from "./Compressor"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Compressor } from "./Compressor.js"; describe("Compressor", () => { - BasicTests(Compressor); context("Compression", () => { - it("passes the incoming signal through", () => { return PassAudio((input) => { const comp = new Compressor().toDestination(); @@ -26,7 +24,13 @@ describe("Compressor", () => { threshold: -30, }; comp.set(values); - expect(comp.get()).to.have.keys(["ratio", "threshold", "release", "attack", "ratio"]); + expect(comp.get()).to.have.keys([ + "ratio", + "threshold", + "release", + "attack", + "ratio", + ]); comp.dispose(); }); diff --git a/Tone/component/dynamics/Compressor.ts b/Tone/component/dynamics/Compressor.ts index 78a55e8a..27149add 100644 --- a/Tone/component/dynamics/Compressor.ts +++ b/Tone/component/dynamics/Compressor.ts @@ -1,8 +1,11 @@ -import { Param } from "../../core/context/Param"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Decibels, Positive, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; +import { Param } from "../../core/context/Param.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Decibels, Positive, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; export interface CompressorOptions extends ToneAudioNodeOptions { attack: Time; @@ -23,13 +26,13 @@ export interface CompressorOptions extends ToneAudioNodeOptions { * @category Component */ export class Compressor extends ToneAudioNode { - readonly name: string = "Compressor"; /** * the compressor node */ - private _compressor: DynamicsCompressorNode = this.context.createDynamicsCompressor(); + private _compressor: DynamicsCompressorNode = + this.context.createDynamicsCompressor(); readonly input = this._compressor; readonly output = this._compressor; @@ -76,9 +79,17 @@ export class Compressor extends ToneAudioNode { constructor(threshold?: Decibels, ratio?: Positive); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Compressor.getDefaults(), arguments, ["threshold", "ratio"])); - const options = optionsFromArguments(Compressor.getDefaults(), arguments, ["threshold", "ratio"]); + super( + optionsFromArguments(Compressor.getDefaults(), arguments, [ + "threshold", + "ratio", + ]) + ); + const options = optionsFromArguments( + Compressor.getDefaults(), + arguments, + ["threshold", "ratio"] + ); this.threshold = new Param({ minValue: this._compressor.threshold.minValue, diff --git a/Tone/component/dynamics/Gate.test.ts b/Tone/component/dynamics/Gate.test.ts index af5ba3e2..b00ddbe2 100644 --- a/Tone/component/dynamics/Gate.test.ts +++ b/Tone/component/dynamics/Gate.test.ts @@ -1,32 +1,34 @@ -import { Gate } from "./Gate"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { Signal } from "Tone/signal/Signal"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { Gate } from "./Gate.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { Signal } from "../../signal/Signal.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; import { expect } from "chai"; describe("Gate", () => { - BasicTests(Gate); - it("matches a file", () => { - return CompareToFile(() => { - const gate = new Gate(-10, 0.1).toDestination(); - const osc = new Oscillator().connect(gate); - osc.start(0); - osc.volume.value = -100; - osc.volume.exponentialRampToValueAtTime(0, 0.5); - }, "gate.wav", 0.18); + it.only("matches a file", () => { + return CompareToFile( + () => { + const gate = new Gate(-10, 0.1).toDestination(); + const osc = new Oscillator().connect(gate); + osc.start(0); + osc.volume.value = -100; + osc.volume.exponentialRampToValueAtTime(0, 0.5); + }, + "gate.wav", + 0.18 + ); }); context("Signal Gating", () => { - it("handles getter/setter as Object", () => { const gate = new Gate(); const values = { smoothing: 0.2, - threshold: -20 + threshold: -20, }; gate.set(values); expect(gate.get().smoothing).to.be.closeTo(0.2, 0.001); @@ -37,7 +39,7 @@ describe("Gate", () => { it("can be constructed with an object", () => { const gate = new Gate({ smoothing: 0.3, - threshold: -5 + threshold: -5, }); expect(gate.smoothing).to.be.closeTo(0.3, 0.001); expect(gate.threshold).to.be.closeTo(-5, 0.1); @@ -69,4 +71,3 @@ describe("Gate", () => { }); }); }); - diff --git a/Tone/component/dynamics/Gate.ts b/Tone/component/dynamics/Gate.ts index 809425b6..a19401dc 100644 --- a/Tone/component/dynamics/Gate.ts +++ b/Tone/component/dynamics/Gate.ts @@ -1,10 +1,13 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Decibels, Time } from "../../core/type/Units"; -import { GreaterThan } from "../../signal/GreaterThan"; -import { Gain } from "../../core/context/Gain"; -import { Follower } from "../analysis/Follower"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { dbToGain, gainToDb } from "../../core/type/Conversions"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Decibels, Time } from "../../core/type/Units.js"; +import { GreaterThan } from "../../signal/GreaterThan.js"; +import { Gain } from "../../core/context/Gain.js"; +import { Follower } from "../analysis/Follower.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { dbToGain, gainToDb } from "../../core/type/Conversions.js"; export interface GateOptions extends ToneAudioNodeOptions { threshold: Decibels; @@ -24,7 +27,6 @@ export interface GateOptions extends ToneAudioNodeOptions { * @category Component */ export class Gate extends ToneAudioNode { - readonly name: string = "Gate"; readonly input: ToneAudioNode; @@ -52,8 +54,18 @@ export class Gate extends ToneAudioNode { constructor(threshold?: Decibels, smoothing?: Time); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]))); - const options = optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]); + super( + Object.assign( + optionsFromArguments(Gate.getDefaults(), arguments, [ + "threshold", + "smoothing", + ]) + ) + ); + const options = optionsFromArguments(Gate.getDefaults(), arguments, [ + "threshold", + "smoothing", + ]); this._follower = new Follower({ context: this.context, @@ -75,7 +87,7 @@ export class Gate extends ToneAudioNode { static getDefaults(): GateOptions { return Object.assign(ToneAudioNode.getDefaults(), { smoothing: 0.1, - threshold: -40 + threshold: -40, }); } @@ -90,7 +102,7 @@ export class Gate extends ToneAudioNode { } /** - * The attack/decay speed of the gate. + * The attack/decay speed of the gate. * @see {@link Follower.smoothing} */ get smoothing(): Time { diff --git a/Tone/component/dynamics/Limiter.test.ts b/Tone/component/dynamics/Limiter.test.ts index 924a2a57..9ad56d24 100644 --- a/Tone/component/dynamics/Limiter.test.ts +++ b/Tone/component/dynamics/Limiter.test.ts @@ -1,14 +1,12 @@ -import { Limiter } from "./Limiter"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; +import { Limiter } from "./Limiter.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; import { expect } from "chai"; describe("Limiter", () => { - BasicTests(Limiter); context("Limiting", () => { - it("passes the incoming signal through", () => { return PassAudio((input) => { const limiter = new Limiter().toDestination(); @@ -40,4 +38,3 @@ describe("Limiter", () => { }); }); }); - diff --git a/Tone/component/dynamics/Limiter.ts b/Tone/component/dynamics/Limiter.ts index 5c880f65..0346299b 100644 --- a/Tone/component/dynamics/Limiter.ts +++ b/Tone/component/dynamics/Limiter.ts @@ -1,9 +1,14 @@ -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Decibels } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Compressor } from "./Compressor"; -import { Param } from "../../core/context/Param"; -import { readOnly } from "../../core/util/Interface"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Decibels } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Compressor } from "./Compressor.js"; +import { Param } from "../../core/context/Param.js"; +import { readOnly } from "../../core/util/Interface.js"; export interface LimiterOptions extends ToneAudioNodeOptions { threshold: Decibels; @@ -12,7 +17,7 @@ export interface LimiterOptions extends ToneAudioNodeOptions { /** * Limiter will limit the loudness of an incoming signal. * Under the hood it's composed of a {@link Compressor} with a fast attack - * and release and max compression ratio. + * and release and max compression ratio. * * @example * const limiter = new Tone.Limiter(-20).toDestination(); @@ -21,7 +26,6 @@ export interface LimiterOptions extends ToneAudioNodeOptions { * @category Component */ export class Limiter extends ToneAudioNode { - readonly name: string = "Limiter"; readonly input: InputNode; @@ -32,7 +36,7 @@ export class Limiter extends ToneAudioNode { */ private _compressor: Compressor; - readonly threshold: Param<"decibels"> + readonly threshold: Param<"decibels">; /** * @param threshold The threshold above which the gain reduction is applied. @@ -40,16 +44,27 @@ export class Limiter extends ToneAudioNode { constructor(threshold?: Decibels); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"]))); - const options = optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"]); + super( + Object.assign( + optionsFromArguments(Limiter.getDefaults(), arguments, [ + "threshold", + ]) + ) + ); + const options = optionsFromArguments(Limiter.getDefaults(), arguments, [ + "threshold", + ]); - this._compressor = this.input = this.output = new Compressor({ - context: this.context, - ratio: 20, - attack: 0.003, - release: 0.01, - threshold: options.threshold - }); + this._compressor = + this.input = + this.output = + new Compressor({ + context: this.context, + ratio: 20, + attack: 0.003, + release: 0.01, + threshold: options.threshold, + }); this.threshold = this._compressor.threshold; readOnly(this, "threshold"); @@ -57,13 +72,13 @@ export class Limiter extends ToneAudioNode { static getDefaults(): LimiterOptions { return Object.assign(ToneAudioNode.getDefaults(), { - threshold: -12 + threshold: -12, }); } /** * A read-only decibel value for metering purposes, representing the current amount of gain - * reduction that the compressor is applying to the signal. + * reduction that the compressor is applying to the signal. */ get reduction(): Decibels { return this._compressor.reduction; diff --git a/Tone/component/dynamics/MidSideCompressor.test.ts b/Tone/component/dynamics/MidSideCompressor.test.ts index 8a25960b..ef31c1e2 100644 --- a/Tone/component/dynamics/MidSideCompressor.test.ts +++ b/Tone/component/dynamics/MidSideCompressor.test.ts @@ -1,14 +1,12 @@ -import { MidSideCompressor } from "./MidSideCompressor"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; +import { MidSideCompressor } from "./MidSideCompressor.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; import { expect } from "chai"; describe("MidSideCompressor", () => { - BasicTests(MidSideCompressor); context("Compression", () => { - it("passes the incoming signal through", () => { return PassAudio((input) => { const comp = new MidSideCompressor().toDestination(); @@ -26,8 +24,8 @@ describe("MidSideCompressor", () => { side: { release: 0.5, attack: 0.03, - knee: 20 - } + knee: 20, + }, }; comp.set(values); expect(comp.get()).to.have.keys(["mid", "side"]); @@ -45,8 +43,8 @@ describe("MidSideCompressor", () => { side: { release: 0.5, attack: 0.03, - knee: 20 - } + knee: 20, + }, }); expect(comp.mid.ratio.value).be.closeTo(16, 0.01); expect(comp.mid.threshold.value).be.closeTo(-30, 0.01); @@ -56,4 +54,3 @@ describe("MidSideCompressor", () => { }); }); }); - diff --git a/Tone/component/dynamics/MidSideCompressor.ts b/Tone/component/dynamics/MidSideCompressor.ts index 1b42d8e4..9105b2ac 100644 --- a/Tone/component/dynamics/MidSideCompressor.ts +++ b/Tone/component/dynamics/MidSideCompressor.ts @@ -1,9 +1,14 @@ -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Compressor, CompressorOptions } from "./Compressor"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { MidSideSplit } from "../channel/MidSideSplit"; -import { MidSideMerge } from "../channel/MidSideMerge"; -import { readOnly, RecursivePartial } from "../../core/util/Interface"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Compressor, CompressorOptions } from "./Compressor.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { MidSideSplit } from "../channel/MidSideSplit.js"; +import { MidSideMerge } from "../channel/MidSideMerge.js"; +import { readOnly, RecursivePartial } from "../../core/util/Interface.js"; export interface MidSideCompressorOptions extends ToneAudioNodeOptions { mid: Omit; @@ -12,12 +17,11 @@ export interface MidSideCompressorOptions extends ToneAudioNodeOptions { /** * MidSideCompressor applies two different compressors to the {@link mid} - * and {@link side} signal components of the input. + * and {@link side} signal components of the input. * @see {@link MidSideSplit} and {@link MidSideMerge}. * @category Component */ export class MidSideCompressor extends ToneAudioNode { - readonly name: string = "MidSideCompressor"; readonly input: InputNode; @@ -45,13 +49,28 @@ export class MidSideCompressor extends ToneAudioNode { constructor(options?: RecursivePartial); constructor() { - super(Object.assign(optionsFromArguments(MidSideCompressor.getDefaults(), arguments))); - const options = optionsFromArguments(MidSideCompressor.getDefaults(), arguments); + super( + Object.assign( + optionsFromArguments(MidSideCompressor.getDefaults(), arguments) + ) + ); + const options = optionsFromArguments( + MidSideCompressor.getDefaults(), + arguments + ); - this._midSideSplit = this.input = new MidSideSplit({ context: this.context }); - this._midSideMerge = this.output = new MidSideMerge({ context: this.context }); - this.mid = new Compressor(Object.assign(options.mid, { context: this.context })); - this.side = new Compressor(Object.assign(options.side, { context: this.context })); + this._midSideSplit = this.input = new MidSideSplit({ + context: this.context, + }); + this._midSideMerge = this.output = new MidSideMerge({ + context: this.context, + }); + this.mid = new Compressor( + Object.assign(options.mid, { context: this.context }) + ); + this.side = new Compressor( + Object.assign(options.side, { context: this.context }) + ); this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid); this._midSideSplit.side.chain(this.side, this._midSideMerge.side); @@ -65,15 +84,15 @@ export class MidSideCompressor extends ToneAudioNode { threshold: -24, release: 0.03, attack: 0.02, - knee: 16 + knee: 16, }, side: { ratio: 6, threshold: -30, release: 0.25, attack: 0.03, - knee: 10 - } + knee: 10, + }, }); } diff --git a/Tone/component/dynamics/MultibandCompressor.test.ts b/Tone/component/dynamics/MultibandCompressor.test.ts index a7f90139..41fad377 100644 --- a/Tone/component/dynamics/MultibandCompressor.test.ts +++ b/Tone/component/dynamics/MultibandCompressor.test.ts @@ -1,14 +1,12 @@ -import { MultibandCompressor } from "./MultibandCompressor"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; +import { MultibandCompressor } from "./MultibandCompressor.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; import { expect } from "chai"; describe("MultibandCompressor", () => { - BasicTests(MultibandCompressor); context("Compression", () => { - it("passes the incoming signal through", () => { return PassAudio((input) => { const comp = new MultibandCompressor().toDestination(); @@ -26,11 +24,17 @@ describe("MultibandCompressor", () => { high: { release: 0.5, attack: 0.03, - knee: 20 - } + knee: 20, + }, }; comp.set(values); - expect(comp.get()).to.have.keys(["low", "mid", "high", "lowFrequency", "highFrequency"]); + expect(comp.get()).to.have.keys([ + "low", + "mid", + "high", + "lowFrequency", + "highFrequency", + ]); expect(comp.get().mid.ratio).be.closeTo(16, 0.01); expect(comp.get().high.release).be.closeTo(0.5, 0.01); comp.dispose(); @@ -51,4 +55,3 @@ describe("MultibandCompressor", () => { }); }); }); - diff --git a/Tone/component/dynamics/MultibandCompressor.ts b/Tone/component/dynamics/MultibandCompressor.ts index 9290c7dd..8290c4ad 100644 --- a/Tone/component/dynamics/MultibandCompressor.ts +++ b/Tone/component/dynamics/MultibandCompressor.ts @@ -1,11 +1,15 @@ -import { InputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Compressor, CompressorOptions } from "./Compressor"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly, RecursivePartial } from "../../core/util/Interface"; -import { Frequency } from "../../core/type/Units"; -import { MultibandSplit } from "../channel/MultibandSplit"; -import { Signal } from "../../signal/Signal"; -import { Gain } from "../../core/context/Gain"; +import { + InputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Compressor, CompressorOptions } from "./Compressor.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly, RecursivePartial } from "../../core/util/Interface.js"; +import { Frequency } from "../../core/type/Units.js"; +import { MultibandSplit } from "../channel/MultibandSplit.js"; +import { Signal } from "../../signal/Signal.js"; +import { Gain } from "../../core/context/Gain.js"; export interface MultibandCompressorOptions extends ToneAudioNodeOptions { mid: Omit; @@ -16,7 +20,7 @@ export interface MultibandCompressorOptions extends ToneAudioNodeOptions { } /** - * A compressor with separate controls over low/mid/high dynamics. + * A compressor with separate controls over low/mid/high dynamics. * @see {@link Compressor} and {@link MultibandSplit} * * @example @@ -30,7 +34,6 @@ export interface MultibandCompressorOptions extends ToneAudioNodeOptions { * @category Component */ export class MultibandCompressor extends ToneAudioNode { - readonly name: string = "MultibandCompressor"; readonly input: InputNode; @@ -68,20 +71,36 @@ export class MultibandCompressor extends ToneAudioNode); constructor() { - super(Object.assign(optionsFromArguments(MultibandCompressor.getDefaults(), arguments))); - const options = optionsFromArguments(MultibandCompressor.getDefaults(), arguments); + super( + Object.assign( + optionsFromArguments( + MultibandCompressor.getDefaults(), + arguments + ) + ) + ); + const options = optionsFromArguments( + MultibandCompressor.getDefaults(), + arguments + ); this._splitter = this.input = new MultibandSplit({ context: this.context, lowFrequency: options.lowFrequency, - highFrequency: options.highFrequency + highFrequency: options.highFrequency, }); this.lowFrequency = this._splitter.lowFrequency; this.highFrequency = this._splitter.highFrequency; this.output = new Gain({ context: this.context }); - this.low = new Compressor(Object.assign(options.low, { context: this.context })); - this.mid = new Compressor(Object.assign(options.mid, { context: this.context })); - this.high = new Compressor(Object.assign(options.high, { context: this.context })); + this.low = new Compressor( + Object.assign(options.low, { context: this.context }) + ); + this.mid = new Compressor( + Object.assign(options.mid, { context: this.context }) + ); + this.high = new Compressor( + Object.assign(options.high, { context: this.context }) + ); // connect the compressor this._splitter.low.chain(this.low, this.output); @@ -100,21 +119,21 @@ export class MultibandCompressor extends ToneAudioNode { - BasicTests(AmplitudeEnvelope); context("Comparisons", () => { - it("matches a file", () => { return CompareToFile(() => { const ampEnv = new AmplitudeEnvelope({ @@ -29,41 +27,47 @@ describe("AmplitudeEnvelope", () => { }); it("matches a file with multiple retriggers", () => { - return CompareToFile(() => { - const ampEnv = new AmplitudeEnvelope({ - attack: 0.1, - decay: 0.2, - release: 0.2, - sustain: 0.1, - }).toDestination(); - const osc = new Oscillator().start(0).connect(ampEnv); - ampEnv.triggerAttack(0); - ampEnv.triggerAttack(0.3); - }, "ampEnvelope2.wav", 0.004); + return CompareToFile( + () => { + const ampEnv = new AmplitudeEnvelope({ + attack: 0.1, + decay: 0.2, + release: 0.2, + sustain: 0.1, + }).toDestination(); + const osc = new Oscillator().start(0).connect(ampEnv); + ampEnv.triggerAttack(0); + ampEnv.triggerAttack(0.3); + }, + "ampEnvelope2.wav", + 0.004 + ); }); it("matches a file with ripple attack/release", () => { - return CompareToFile(() => { - const ampEnv = new AmplitudeEnvelope({ - attack: 0.5, - attackCurve: "ripple", - decay: 0.2, - release: 0.3, - releaseCurve: "ripple", - sustain: 0.1, - }).toDestination(); - const osc = new Oscillator().start(0).connect(ampEnv); - ampEnv.triggerAttack(0); - ampEnv.triggerRelease(0.7); - ampEnv.triggerAttack(1); - ampEnv.triggerRelease(1.6); - }, "ampEnvelope3.wav", 0.002); + return CompareToFile( + () => { + const ampEnv = new AmplitudeEnvelope({ + attack: 0.5, + attackCurve: "ripple", + decay: 0.2, + release: 0.3, + releaseCurve: "ripple", + sustain: 0.1, + }).toDestination(); + const osc = new Oscillator().start(0).connect(ampEnv); + ampEnv.triggerAttack(0); + ampEnv.triggerRelease(0.7); + ampEnv.triggerAttack(1); + ampEnv.triggerRelease(1.6); + }, + "ampEnvelope3.wav", + 0.002 + ); }); - }); context("Envelope", () => { - it("extends envelope", () => { const ampEnv = new AmplitudeEnvelope(); expect(ampEnv).to.be.instanceOf(Envelope); diff --git a/Tone/component/envelope/AmplitudeEnvelope.ts b/Tone/component/envelope/AmplitudeEnvelope.ts index 7db102da..7ff9687a 100644 --- a/Tone/component/envelope/AmplitudeEnvelope.ts +++ b/Tone/component/envelope/AmplitudeEnvelope.ts @@ -1,7 +1,7 @@ -import { Gain } from "../../core/context/Gain"; -import { NormalRange, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Envelope, EnvelopeOptions } from "./Envelope"; +import { Gain } from "../../core/context/Gain.js"; +import { NormalRange, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Envelope, EnvelopeOptions } from "./Envelope.js"; /** * AmplitudeEnvelope is a Tone.Envelope connected to a gain node. @@ -26,7 +26,6 @@ import { Envelope, EnvelopeOptions } from "./Envelope"; * @category Component */ export class AmplitudeEnvelope extends Envelope { - readonly name: string = "AmplitudeEnvelope"; private _gainNode: Gain = new Gain({ @@ -45,10 +44,22 @@ export class AmplitudeEnvelope extends Envelope { * @param release The amount of time after the release is triggered it takes to reach 0. * Value must be greater than 0. */ - constructor(attack?: Time, decay?: Time, sustain?: NormalRange, release?: Time); - constructor(options?: Partial) + constructor( + attack?: Time, + decay?: Time, + sustain?: NormalRange, + release?: Time + ); + constructor(options?: Partial); constructor() { - super(optionsFromArguments(AmplitudeEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"])); + super( + optionsFromArguments(AmplitudeEnvelope.getDefaults(), arguments, [ + "attack", + "decay", + "sustain", + "release", + ]) + ); this._sig.connect(this._gainNode.gain); this.output = this._gainNode; this.input = this._gainNode; diff --git a/Tone/component/envelope/Envelope.test.ts b/Tone/component/envelope/Envelope.test.ts index fddac762..fdbc5efc 100644 --- a/Tone/component/envelope/Envelope.test.ts +++ b/Tone/component/envelope/Envelope.test.ts @@ -1,15 +1,13 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectTo } from "test/helper/Connect"; -import { Offline } from "test/helper/Offline"; -import { Envelope, EnvelopeCurve } from "./Envelope"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectTo } from "../../../test/helper/Connect.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { Envelope, EnvelopeCurve } from "./Envelope.js"; describe("Envelope", () => { - BasicTests(Envelope); context("Envelope", () => { - it("has an output connections", () => { const env = new Envelope(); env.connect(connectTo()); @@ -143,7 +141,7 @@ describe("Envelope", () => { it("can set release to exponential or linear", () => { return Offline(() => { const env = new Envelope({ - release: 0 + release: 0, }); env.toDestination(); env.triggerAttackRelease(0.4, 0); @@ -159,7 +157,7 @@ describe("Envelope", () => { attack: 0.5, decay: 0.0, sustain: 1, - release: 0.5 + release: 0.5, }).toDestination(); env.triggerAttackRelease(0.5); }, 0.7).then((buffer) => { @@ -180,17 +178,30 @@ describe("Envelope", () => { sustain: 0.5, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.attackCurve = "exponential"; env.toDestination(); env.triggerAttack(0); }, 0.7).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.within(0, 1); - }, 0, e.attack); - buffer.forEachBetween((sample) => { - expect(sample).to.be.within(e.sustain - 0.001, 1); - }, e.attack, e.attack + e.decay); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.within(0, 1); + }, + 0, + e.attack + ); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.within(e.sustain - 0.001, 1); + }, + e.attack, + e.attack + e.decay + ); buffer.forEachBetween((sample) => { expect(sample).to.be.closeTo(e.sustain, 0.01); }, e.attack + e.decay); @@ -205,15 +216,24 @@ describe("Envelope", () => { sustain: 0.5, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.attackCurve = "exponential"; env.toDestination(); env.triggerAttack(0); }, 0.7).then((buffer) => { - buffer.forEachBetween((sample, time) => { - const target = 1 - (time - 0.2) * 10; - expect(sample).to.be.closeTo(target, 0.01); - }, 0.2, 0.2); + buffer.forEachBetween( + (sample, time) => { + const target = 1 - (time - 0.2) * 10; + expect(sample).to.be.closeTo(target, 0.01); + }, + 0.2, + 0.2 + ); }); }); @@ -225,7 +245,12 @@ describe("Envelope", () => { sustain: 0, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.decayCurve = "linear"; env.toDestination(); env.triggerAttack(0); @@ -248,7 +273,12 @@ describe("Envelope", () => { sustain: 0, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.decayCurve = "exponential"; env.toDestination(); env.triggerAttack(0); @@ -270,17 +300,30 @@ describe("Envelope", () => { sustain: 0.1, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.attackCurve = "exponential"; env.toDestination(); env.triggerAttack(0); }, 0.2).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.within(0, 1); - }, 0, e.attack); - buffer.forEachBetween((sample) => { - expect(sample).to.be.within(e.sustain - 0.001, 1); - }, e.attack, e.attack + e.decay); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.within(0, 1); + }, + 0, + e.attack + ); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.within(e.sustain - 0.001, 1); + }, + e.attack, + e.attack + e.decay + ); buffer.forEachBetween((sample) => { expect(sample).to.be.closeTo(e.sustain, 0.01); }, e.attack + e.decay); @@ -308,16 +351,25 @@ describe("Envelope", () => { }; const releaseTime = 0.2; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.attackCurve = "exponential"; env.toDestination(); env.triggerAttackRelease(releaseTime); }, 0.6).then((buffer) => { const sustainStart = e.attack + e.decay; const sustainEnd = sustainStart + releaseTime; - buffer.forEachBetween((sample) => { - expect(sample).to.be.below(e.sustain + 0.01); - }, sustainStart, sustainEnd); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.below(e.sustain + 0.01); + }, + sustainStart, + sustainEnd + ); buffer.forEachBetween((sample) => { expect(sample).to.be.closeTo(0, 0.01); }, releaseTime + e.release); @@ -332,7 +384,7 @@ describe("Envelope", () => { env.triggerAttack(0); env.triggerRelease(0.4); env.triggerAttack(0.4); - }, 0.6).then(buffer => { + }, 0.6).then((buffer) => { expect(buffer.getValueAtTime(0.4)).be.closeTo(0.5, 0.01); expect(buffer.getValueAtTime(0.40025)).be.closeTo(0.75, 0.01); expect(buffer.getValueAtTime(0.4005)).be.closeTo(1, 0.01); @@ -349,14 +401,23 @@ describe("Envelope", () => { const releaseTime = 0.2; const attackTime = 0.1; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.attackCurve = "exponential"; env.toDestination(); env.triggerAttack(attackTime); env.triggerRelease(releaseTime); }, 0.6).then((buffer) => { expect(buffer.getValueAtTime(attackTime - 0.001)).to.equal(0); - expect(buffer.getValueAtTime(e.attack + e.decay + releaseTime + e.release)).to.be.below(0.01); + expect( + buffer.getValueAtTime( + e.attack + e.decay + releaseTime + e.release + ) + ).to.be.below(0.01); }); }); @@ -373,8 +434,12 @@ describe("Envelope", () => { env.triggerAttack(attackTime); }, 0.4).then((buffer) => { buffer.forEach((sample, time) => { - expect(buffer.getValueAtTime(attackTime - 0.001)).to.equal(0); - expect(buffer.getValueAtTime(attackTime + e.attack + e.decay)).to.be.below(0.01); + expect(buffer.getValueAtTime(attackTime - 0.001)).to.equal( + 0 + ); + expect( + buffer.getValueAtTime(attackTime + e.attack + e.decay) + ).to.be.below(0.01); }); }); }); @@ -388,7 +453,12 @@ describe("Envelope", () => { }; const releaseTime = 0.4; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.toDestination(); env.triggerAttack(0); env.triggerRelease(releaseTime); @@ -419,7 +489,12 @@ describe("Envelope", () => { const releaseTime = 0.4; const duration = 0.4; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.toDestination(); env.triggerAttack(0); env.triggerRelease(releaseTime); @@ -451,7 +526,12 @@ describe("Envelope", () => { const duration = 0.4; const velocity = 0.4; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.toDestination(); env.triggerAttack(0, velocity); env.triggerRelease(releaseTime); @@ -460,11 +540,17 @@ describe("Envelope", () => { if (time < e.attack) { expect(sample).to.be.within(0, velocity + 0.01); } else if (time < e.attack + e.decay) { - expect(sample).to.be.within(e.sustain * velocity - 0.01, velocity + 0.01); + expect(sample).to.be.within( + e.sustain * velocity - 0.01, + velocity + 0.01 + ); } else if (time < duration) { expect(sample).to.be.closeTo(e.sustain * velocity, 0.1); } else if (time < duration + e.release) { - expect(sample).to.be.within(0, e.sustain * velocity + 0.01); + expect(sample).to.be.within( + 0, + e.sustain * velocity + 0.01 + ); } else { expect(sample).to.be.below(0.01); } @@ -480,7 +566,12 @@ describe("Envelope", () => { sustain: 0.0, }; return Offline(() => { - const env = new Envelope(e.attack, e.decay, e.sustain, e.release); + const env = new Envelope( + e.attack, + e.decay, + e.sustain, + e.release + ); env.toDestination(); env.triggerAttack(0); env.triggerAttack(0.5); @@ -632,13 +723,19 @@ describe("Envelope", () => { }); context("Attack/Release Curves", () => { - - const envelopeCurves: EnvelopeCurve[] = ["linear", "exponential", "bounce", "cosine", "ripple", "sine", "step"]; + const envelopeCurves: EnvelopeCurve[] = [ + "linear", + "exponential", + "bounce", + "cosine", + "ripple", + "sine", + "step", + ]; it("can get set all of the types as the attackCurve", () => { - const env = new Envelope(); - envelopeCurves.forEach(type => { + envelopeCurves.forEach((type) => { env.attackCurve = type; expect(env.attackCurve).to.equal(type); }); @@ -647,7 +744,7 @@ describe("Envelope", () => { it("can get set all of the types as the releaseCurve", () => { const env = new Envelope(); - envelopeCurves.forEach(type => { + envelopeCurves.forEach((type) => { env.releaseCurve = type; expect(env.releaseCurve).to.equal(type); }); @@ -666,9 +763,13 @@ describe("Envelope", () => { }).toDestination(); env.triggerAttackRelease(0.3, 0.1); }, 0.8).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.above(0); - }, 0.101, 0.7); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.above(0); + }, + 0.101, + 0.7 + ); }); }); @@ -684,9 +785,13 @@ describe("Envelope", () => { }).toDestination(); env.triggerAttackRelease(0.3, 0.1); }, 0.8).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.above(0); - }, 0.101, 0.7); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.above(0); + }, + 0.101, + 0.7 + ); }); }); @@ -702,9 +807,13 @@ describe("Envelope", () => { }).toDestination(); env.triggerAttackRelease(0.3, 0.1); }, 0.8).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.above(0); - }, 0.101, 0.7); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.above(0); + }, + 0.101, + 0.7 + ); }); }); @@ -720,9 +829,13 @@ describe("Envelope", () => { }).toDestination(); env.triggerAttackRelease(0.3, 0.1); }, 0.8).then((buffer) => { - buffer.forEachBetween((sample) => { - expect(sample).to.be.above(0); - }, 0.101, 0.7); + buffer.forEachBetween( + (sample) => { + expect(sample).to.be.above(0); + }, + 0.101, + 0.7 + ); }); }); @@ -792,8 +905,8 @@ describe("Envelope", () => { it("can render the envelope to a curve", async () => { const env = new Envelope(); const curve = await env.asArray(); - expect(curve.some(v => v > 0)).to.be.true; - curve.forEach(v => expect(v).to.be.within(0, 1)); + expect(curve.some((v) => v > 0)).to.be.true; + curve.forEach((v) => expect(v).to.be.within(0, 1)); env.dispose(); }); diff --git a/Tone/component/envelope/Envelope.ts b/Tone/component/envelope/Envelope.ts index f633c234..d1d8baae 100644 --- a/Tone/component/envelope/Envelope.ts +++ b/Tone/component/envelope/Envelope.ts @@ -1,12 +1,15 @@ -import { InputNode, OutputNode } from "../../core/context/ToneAudioNode"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { NormalRange, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { isArray, isObject, isString } from "../../core/util/TypeCheck"; -import { connectSignal, Signal } from "../../signal/Signal"; -import { OfflineContext } from "../../core/context/OfflineContext"; -import { assert } from "../../core/util/Debug"; -import { range, timeRange } from "../../core/util/Decorator"; +import { InputNode, OutputNode } from "../../core/context/ToneAudioNode.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { NormalRange, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { isArray, isObject, isString } from "../../core/util/TypeCheck.js"; +import { connectSignal, Signal } from "../../signal/Signal.js"; +import { OfflineContext } from "../../core/context/OfflineContext.js"; +import { assert } from "../../core/util/Debug.js"; +import { range, timeRange } from "../../core/util/Decorator.js"; type BasicEnvelopeCurve = "linear" | "exponential"; type InternalEnvelopeCurve = BasicEnvelopeCurve | number[]; @@ -50,7 +53,6 @@ export interface EnvelopeOptions extends ToneAudioNodeOptions { * @category Component */ export class Envelope extends ToneAudioNode { - readonly name: string = "Envelope"; /** @@ -176,12 +178,27 @@ export class Envelope extends ToneAudioNode { * @param release The amount of time after the release is triggered it takes to reach 0. * Value must be greater than 0. */ - constructor(attack?: Time, decay?: Time, sustain?: NormalRange, release?: Time); - constructor(options?: Partial) + constructor( + attack?: Time, + decay?: Time, + sustain?: NormalRange, + release?: Time + ); + constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"])); - const options = optionsFromArguments(Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]); + super( + optionsFromArguments(Envelope.getDefaults(), arguments, [ + "attack", + "decay", + "sustain", + "release", + ]) + ); + const options = optionsFromArguments( + Envelope.getDefaults(), + arguments, + ["attack", "decay", "sustain", "release"] + ); this.attack = options.attack; this.decay = options.decay; @@ -218,7 +235,10 @@ export class Envelope extends ToneAudioNode { * @param direction In/Out * @return The curve name */ - private _getCurve(curve: InternalEnvelopeCurve, direction: EnvelopeDirection): EnvelopeCurve { + private _getCurve( + curve: InternalEnvelopeCurve, + direction: EnvelopeDirection + ): EnvelopeCurve { if (isString(curve)) { return curve; } else { @@ -243,7 +263,7 @@ export class Envelope extends ToneAudioNode { private _setCurve( name: "_attackCurve" | "_decayCurve" | "_releaseCurve", direction: EnvelopeDirection, - curve: EnvelopeCurve, + curve: EnvelopeCurve ): void { // check if it's a valid type if (isString(curve) && Reflect.has(EnvelopeCurves, curve)) { @@ -385,9 +405,16 @@ export class Envelope extends ToneAudioNode { const decayStart = time + attack; this.log("decay", decayStart); if (this._decayCurve === "linear") { - this._sig.linearRampToValueAtTime(decayValue, decay + decayStart); + this._sig.linearRampToValueAtTime( + decayValue, + decay + decayStart + ); } else { - this._sig.exponentialApproachValueAtTime(decayValue, decayStart, decay); + this._sig.exponentialApproachValueAtTime( + decayValue, + decayStart, + decay + ); } } return this; @@ -418,9 +445,17 @@ export class Envelope extends ToneAudioNode { } else if (this._releaseCurve === "exponential") { this._sig.targetRampTo(0, release, time); } else { - assert(isArray(this._releaseCurve), "releaseCurve must be either 'linear', 'exponential' or an array"); + assert( + isArray(this._releaseCurve), + "releaseCurve must be either 'linear', 'exponential' or an array" + ); this._sig.cancelAndHoldAtTime(time); - this._sig.setValueCurveAtTime(this._releaseCurve, time, release, currentValue); + this._sig.setValueCurveAtTime( + this._releaseCurve, + time, + release, + currentValue + ); } } return this; @@ -450,7 +485,11 @@ export class Envelope extends ToneAudioNode { * // trigger the release 0.5 seconds after the attack * env.triggerAttackRelease(0.5); */ - triggerAttackRelease(duration: Time, time?: Time, velocity: NormalRange = 1): this { + triggerAttackRelease( + duration: Time, + time?: Time, + velocity: NormalRange = 1 + ): this { time = this.toSeconds(time); this.triggerAttack(time, velocity); this.triggerRelease(time + this.toSeconds(duration)); @@ -480,21 +519,33 @@ export class Envelope extends ToneAudioNode { */ async asArray(length = 1024): Promise { const duration = length / this.context.sampleRate; - const context = new OfflineContext(1, duration, this.context.sampleRate); + const context = new OfflineContext( + 1, + duration, + this.context.sampleRate + ); // normalize the ADSR for the given duration with 20% sustain time - const attackPortion = this.toSeconds(this.attack) + this.toSeconds(this.decay); + const attackPortion = + this.toSeconds(this.attack) + this.toSeconds(this.decay); const envelopeDuration = attackPortion + this.toSeconds(this.release); const sustainTime = envelopeDuration * 0.1; const totalDuration = envelopeDuration + sustainTime; // @ts-ignore - const clone = new this.constructor(Object.assign(this.get(), { - attack: duration * this.toSeconds(this.attack) / totalDuration, - decay: duration * this.toSeconds(this.decay) / totalDuration, - release: duration * this.toSeconds(this.release) / totalDuration, - context - })) as Envelope; + const clone = new this.constructor( + Object.assign(this.get(), { + attack: + (duration * this.toSeconds(this.attack)) / totalDuration, + decay: (duration * this.toSeconds(this.decay)) / totalDuration, + release: + (duration * this.toSeconds(this.release)) / totalDuration, + context, + }) + ) as Envelope; clone._sig.toDestination(); - clone.triggerAttackRelease(duration * (attackPortion + sustainTime) / totalDuration, 0); + clone.triggerAttackRelease( + (duration * (attackPortion + sustainTime)) / totalDuration, + 0 + ); const buffer = await context.render(); return buffer.getChannelData(0); } @@ -529,7 +580,6 @@ type EnvelopeCurveName = keyof EnvelopeCurveMap; * Generate some complex envelope curves. */ const EnvelopeCurves: EnvelopeCurveMap = (() => { - const curveLen = 128; let i: number; @@ -545,8 +595,9 @@ const EnvelopeCurves: EnvelopeCurveMap = (() => { const rippleCurve: number[] = []; const rippleCurveFreq = 6.4; for (i = 0; i < curveLen - 1; i++) { - k = (i / (curveLen - 1)); - const sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1; + k = i / (curveLen - 1); + const sineWave = + Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1; rippleCurve[i] = sineWave / 10 + k * 0.83; } rippleCurve[curveLen - 1] = 1; diff --git a/Tone/component/envelope/FrequencyEnvelope.test.ts b/Tone/component/envelope/FrequencyEnvelope.test.ts index 4534f62b..8f707ee4 100644 --- a/Tone/component/envelope/FrequencyEnvelope.test.ts +++ b/Tone/component/envelope/FrequencyEnvelope.test.ts @@ -1,16 +1,14 @@ -import { FrequencyEnvelope } from "Tone/component/envelope/FrequencyEnvelope"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { Envelope } from "Tone/component/envelope/Envelope"; +import { FrequencyEnvelope } from "./FrequencyEnvelope.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { Envelope } from "./Envelope.js"; import { expect } from "chai"; describe("FrequencyEnvelope", () => { - BasicTests(FrequencyEnvelope); context("FrequencyEnvelope", () => { - it("has an output connections", () => { const freqEnv = new FrequencyEnvelope(); freqEnv.connect(connectTo()); @@ -30,7 +28,7 @@ describe("FrequencyEnvelope", () => { attack: 0, release: "4n", baseFrequency: 20, - octaves: 4 + octaves: 4, }; freqEnv.set(values); expect(freqEnv.get()).to.contain.keys(Object.keys(values)); @@ -44,7 +42,7 @@ describe("FrequencyEnvelope", () => { attack: 0, decay: 0.5, sustain: 1, - exponent: 3 + exponent: 3, }); expect(env0.attack).to.equal(0); expect(env0.decay).to.equal(0.5); @@ -70,10 +68,14 @@ describe("FrequencyEnvelope", () => { const e = { attack: 0.01, decay: 0.4, - sustain: 1 + sustain: 1, }; const buffer = await Offline(() => { - const freqEnv = new FrequencyEnvelope(e.attack, e.decay, e.sustain); + const freqEnv = new FrequencyEnvelope( + e.attack, + e.decay, + e.sustain + ); freqEnv.baseFrequency = 200; freqEnv.octaves = 3; freqEnv.attackCurve = "exponential"; diff --git a/Tone/component/envelope/FrequencyEnvelope.ts b/Tone/component/envelope/FrequencyEnvelope.ts index 8dca9920..47b0f50e 100644 --- a/Tone/component/envelope/FrequencyEnvelope.ts +++ b/Tone/component/envelope/FrequencyEnvelope.ts @@ -1,9 +1,9 @@ -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Frequency, Hertz, NormalRange, Time } from "../../core/type/Units"; -import { Envelope, EnvelopeOptions } from "./Envelope"; -import { Scale } from "../../signal/Scale"; -import { Pow } from "../../signal/Pow"; -import { assertRange } from "../../core/util/Debug"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Frequency, Hertz, NormalRange, Time } from "../../core/type/Units.js"; +import { Envelope, EnvelopeOptions } from "./Envelope.js"; +import { Scale } from "../../signal/Scale.js"; +import { Pow } from "../../signal/Pow.js"; +import { assertRange } from "../../core/util/Debug.js"; export interface FrequencyEnvelopeOptions extends EnvelopeOptions { baseFrequency: Frequency; @@ -13,7 +13,7 @@ export interface FrequencyEnvelopeOptions extends EnvelopeOptions { /** * FrequencyEnvelope is an {@link Envelope} which ramps between {@link baseFrequency} * and {@link octaves}. It can also have an optional {@link exponent} to adjust the curve - * which it ramps. + * which it ramps. * @example * const oscillator = new Tone.Oscillator().toDestination().start(); * const freqEnv = new Tone.FrequencyEnvelope({ @@ -26,7 +26,6 @@ export interface FrequencyEnvelopeOptions extends EnvelopeOptions { * @category Component */ export class FrequencyEnvelope extends Envelope { - readonly name: string = "FrequencyEnvelope"; /** @@ -55,18 +54,34 @@ export class FrequencyEnvelope extends Envelope { * @param sustain a percentage (0-1) of the full amplitude * @param release the release time in seconds */ - constructor(attack?: Time, decay?: Time, sustain?: NormalRange, release?: Time); - constructor(options?: Partial) + constructor( + attack?: Time, + decay?: Time, + sustain?: NormalRange, + release?: Time + ); + constructor(options?: Partial); constructor() { - super(optionsFromArguments(FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"])); - const options = optionsFromArguments(FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]); + super( + optionsFromArguments(FrequencyEnvelope.getDefaults(), arguments, [ + "attack", + "decay", + "sustain", + "release", + ]) + ); + const options = optionsFromArguments( + FrequencyEnvelope.getDefaults(), + arguments, + ["attack", "decay", "sustain", "release"] + ); this._octaves = options.octaves; this._baseFrequency = this.toFrequency(options.baseFrequency); this._exponent = this.input = new Pow({ context: this.context, - value: options.exponent + value: options.exponent, }); this._scale = this.output = new Scale({ context: this.context, diff --git a/Tone/component/filter/BiquadFilter.test.ts b/Tone/component/filter/BiquadFilter.test.ts index d793e66f..c6bd8059 100644 --- a/Tone/component/filter/BiquadFilter.test.ts +++ b/Tone/component/filter/BiquadFilter.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Oscillator } from "../../source/oscillator/Oscillator"; -import { BiquadFilter } from "./BiquadFilter"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; +import { BiquadFilter } from "./BiquadFilter.js"; describe("BiquadFilter", () => { - BasicTests(BiquadFilter); context("BiquadFiltering", () => { - it("can be constructed with a arguments", () => { const filter = new BiquadFilter(200, "highpass"); expect(filter.frequency.value).to.be.closeTo(200, 0.001); @@ -34,10 +32,15 @@ describe("BiquadFilter", () => { Q: 2, frequency: 440, gain: -6, - type: "lowshelf" as const + type: "lowshelf" as const, }; filter.set(values); - expect(filter.get()).to.include.keys(["type", "frequency", "Q", "gain"]); + expect(filter.get()).to.include.keys([ + "type", + "frequency", + "Q", + "gain", + ]); expect(filter.type).to.equal(values.type); expect(filter.frequency.value).to.equal(values.frequency); expect(filter.Q.value).to.equal(values.Q); @@ -57,7 +60,7 @@ describe("BiquadFilter", () => { }); it("passes the incoming signal through", () => { - return PassAudio(input => { + return PassAudio((input) => { const filter = new BiquadFilter().toDestination(); input.connect(filter); }); @@ -65,8 +68,16 @@ describe("BiquadFilter", () => { it("can set the basic filter types", () => { const filter = new BiquadFilter(); - const types: BiquadFilterType[] = ["lowpass", "highpass", - "bandpass", "lowshelf", "highshelf", "notch", "allpass", "peaking"]; + const types: BiquadFilterType[] = [ + "lowpass", + "highpass", + "bandpass", + "lowshelf", + "highshelf", + "notch", + "allpass", + "peaking", + ]; for (const type of types) { filter.type = type; expect(filter.type).to.equal(type); @@ -89,6 +100,5 @@ describe("BiquadFilter", () => { expect(buffer.getRmsAtTime(0.1)).to.be.within(0.37, 0.53); }); }); - }); }); diff --git a/Tone/component/filter/BiquadFilter.ts b/Tone/component/filter/BiquadFilter.ts index c09e069d..af59bdbc 100644 --- a/Tone/component/filter/BiquadFilter.ts +++ b/Tone/component/filter/BiquadFilter.ts @@ -1,8 +1,11 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Cents, Frequency, GainFactor } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Param } from "../../core/context/Param"; -import { assert } from "../../core/util/Debug"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Cents, Frequency, GainFactor } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Param } from "../../core/context/Param.js"; +import { assert } from "../../core/util/Debug.js"; export interface BiquadFilterOptions extends ToneAudioNodeOptions { frequency: Frequency; @@ -13,8 +16,8 @@ export interface BiquadFilterOptions extends ToneAudioNodeOptions { } /** - * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode). - * BiquadFilter is similar to {@link Filter} but doesn't have the option to set the "rolloff" value. + * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode). + * BiquadFilter is similar to {@link Filter} but doesn't have the option to set the "rolloff" value. * @category Component */ export class BiquadFilter extends ToneAudioNode { @@ -32,13 +35,13 @@ export class BiquadFilter extends ToneAudioNode { * A detune value, in cents, for the frequency. */ readonly detune: Param<"cents">; - + /** * The Q factor of the filter. - * For lowpass and highpass filters the Q value is interpreted to be in dB. + * For lowpass and highpass filters the Q value is interpreted to be in dB. * For these filters the nominal range is [−𝑄𝑙𝑖𝑚,𝑄𝑙𝑖𝑚] where 𝑄𝑙𝑖𝑚 is the largest value for which 10𝑄/20 does not overflow. This is approximately 770.63678. - * For the bandpass, notch, allpass, and peaking filters, this value is a linear value. - * The value is related to the bandwidth of the filter and hence should be a positive value. The nominal range is + * For the bandpass, notch, allpass, and peaking filters, this value is a linear value. + * The value is related to the bandwidth of the filter and hence should be a positive value. The nominal range is * [0,3.4028235𝑒38], the upper limit being the most-positive-single-float. * This is not used for the lowshelf and highshelf filters. */ @@ -58,8 +61,17 @@ export class BiquadFilter extends ToneAudioNode { constructor(frequency?: Frequency, type?: BiquadFilterType); constructor(options?: Partial); constructor() { - super(optionsFromArguments(BiquadFilter.getDefaults(), arguments, ["frequency", "type"])); - const options = optionsFromArguments(BiquadFilter.getDefaults(), arguments, ["frequency", "type"]); + super( + optionsFromArguments(BiquadFilter.getDefaults(), arguments, [ + "frequency", + "type", + ]) + ); + const options = optionsFromArguments( + BiquadFilter.getDefaults(), + arguments, + ["frequency", "type"] + ); this._filter = this.context.createBiquadFilter(); this.input = this.output = this._filter; @@ -70,21 +82,21 @@ export class BiquadFilter extends ToneAudioNode { value: options.Q, param: this._filter.Q, }); - + this.frequency = new Param({ context: this.context, units: "frequency", value: options.frequency, param: this._filter.frequency, }); - + this.detune = new Param({ context: this.context, units: "cents", value: options.detune, param: this._filter.detune, }); - + this.gain = new Param({ context: this.context, units: "decibels", @@ -114,8 +126,16 @@ export class BiquadFilter extends ToneAudioNode { return this._filter.type; } set type(type) { - const types: BiquadFilterType[] = ["lowpass", "highpass", "bandpass", - "lowshelf", "highshelf", "notch", "allpass", "peaking"]; + const types: BiquadFilterType[] = [ + "lowpass", + "highpass", + "bandpass", + "lowshelf", + "highshelf", + "notch", + "allpass", + "peaking", + ]; assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`); this._filter.type = type; } diff --git a/Tone/component/filter/Convolver.test.ts b/Tone/component/filter/Convolver.test.ts index f0d4594f..ebcfbccb 100644 --- a/Tone/component/filter/Convolver.test.ts +++ b/Tone/component/filter/Convolver.test.ts @@ -1,27 +1,20 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { Convolver } from "./Convolver"; - -// @ts-ignore -if (window.__karma__) { - ToneAudioBuffer.baseUrl = "/base/test/"; -} +import { BasicTests } from "../../../test/helper/Basic.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { Convolver } from "./Convolver.js"; describe("Convolver", () => { - BasicTests(Convolver); const ir = new ToneAudioBuffer(); - const testFile = "./audio/sineStereo.wav"; + const testFile = "./test/audio/sineStereo.wav"; before(() => { return ir.load(testFile); }); context("API", () => { - it("can pass in options in the constructor", () => { const convolver = new Convolver({ normalize: false, @@ -71,7 +64,9 @@ describe("Convolver", () => { it("can be constructed with a buffer", () => { const convolver = new Convolver(ir); - expect((convolver.buffer as ToneAudioBuffer).get()).to.equal(ir.get()); + expect((convolver.buffer as ToneAudioBuffer).get()).to.equal( + ir.get() + ); convolver.dispose(); }); diff --git a/Tone/component/filter/Convolver.ts b/Tone/component/filter/Convolver.ts index 0529e8eb..b3fcd5bb 100644 --- a/Tone/component/filter/Convolver.ts +++ b/Tone/component/filter/Convolver.ts @@ -1,8 +1,11 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Gain } from "../../core/context/Gain"; -import { noOp } from "../../core/util/Interface"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Gain } from "../../core/context/Gain.js"; +import { noOp } from "../../core/util/Interface.js"; export interface ConvolverOptions extends ToneAudioNodeOptions { onload: () => void; @@ -22,7 +25,6 @@ export interface ConvolverOptions extends ToneAudioNodeOptions { * @category Component */ export class Convolver extends ToneAudioNode { - readonly name: string = "Convolver"; /** @@ -42,14 +44,25 @@ export class Convolver extends ToneAudioNode { * @param url The URL of the impulse response or the ToneAudioBuffer containing the impulse response. * @param onload The callback to invoke when the url is loaded. */ - constructor(url?: string | AudioBuffer | ToneAudioBuffer, onload?: () => void); + constructor( + url?: string | AudioBuffer | ToneAudioBuffer, + onload?: () => void + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"])); - const options = optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]); - - this._buffer = new ToneAudioBuffer(options.url, buffer => { + super( + optionsFromArguments(Convolver.getDefaults(), arguments, [ + "url", + "onload", + ]) + ); + const options = optionsFromArguments( + Convolver.getDefaults(), + arguments, + ["url", "onload"] + ); + + this._buffer = new ToneAudioBuffer(options.url, (buffer) => { this.buffer = buffer; options.onload(); }); diff --git a/Tone/component/filter/EQ3.test.ts b/Tone/component/filter/EQ3.test.ts index 2f598e85..7309c427 100644 --- a/Tone/component/filter/EQ3.test.ts +++ b/Tone/component/filter/EQ3.test.ts @@ -1,15 +1,13 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom } from "test/helper/Connect"; -import { PassAudio } from "test/helper/PassAudio"; -import { EQ3 } from "./EQ3"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom } from "../../../test/helper/Connect.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { EQ3 } from "./EQ3.js"; describe("EQ3", () => { - BasicTests(EQ3); context("EQing", () => { - it("can be constructed with an object", () => { const eq3 = new EQ3({ high: -10, @@ -38,7 +36,7 @@ describe("EQ3", () => { }); it("passes the incoming signal through", () => { - return PassAudio(input => { + return PassAudio((input) => { const eq3 = new EQ3({ high: 12, low: -20, diff --git a/Tone/component/filter/EQ3.ts b/Tone/component/filter/EQ3.ts index 199e3b34..3380bee3 100644 --- a/Tone/component/filter/EQ3.ts +++ b/Tone/component/filter/EQ3.ts @@ -1,11 +1,14 @@ -import { Gain } from "../../core/context/Gain"; -import { Param } from "../../core/context/Param"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Decibels, Frequency } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly, writable } from "../../core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { MultibandSplit } from "../channel/MultibandSplit"; +import { Gain } from "../../core/context/Gain.js"; +import { Param } from "../../core/context/Param.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Decibels, Frequency } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly, writable } from "../../core/util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { MultibandSplit } from "../channel/MultibandSplit.js"; interface EQ3Options extends ToneAudioNodeOptions { low: Decibels; @@ -16,11 +19,10 @@ interface EQ3Options extends ToneAudioNodeOptions { } /** - * EQ3 provides 3 equalizer bins: Low/Mid/High. + * EQ3 provides 3 equalizer bins: Low/Mid/High. * @category Component */ export class EQ3 extends ToneAudioNode { - readonly name: string = "EQ3"; /** @@ -88,8 +90,18 @@ export class EQ3 extends ToneAudioNode { constructor(lowLevel?: Decibels, midLevel?: Decibels, highLevel?: Decibels); constructor(options: Partial); constructor() { - super(optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"])); - const options = optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]); + super( + optionsFromArguments(EQ3.getDefaults(), arguments, [ + "low", + "mid", + "high", + ]) + ); + const options = optionsFromArguments(EQ3.getDefaults(), arguments, [ + "low", + "mid", + "high", + ]); this.input = this._multibandSplit = new MultibandSplit({ context: this.context, @@ -120,7 +132,7 @@ export class EQ3 extends ToneAudioNode { this.high = this._highGain.gain; this.Q = this._multibandSplit.Q; this.lowFrequency = this._multibandSplit.lowFrequency; - this.highFrequency = this._multibandSplit.highFrequency; + this.highFrequency = this._multibandSplit.highFrequency; // the frequency bands this._multibandSplit.low.chain(this._lowGain, this.output); @@ -159,5 +171,4 @@ export class EQ3 extends ToneAudioNode { this.Q.dispose(); return this; } - } diff --git a/Tone/component/filter/FeedbackCombFilter.test.ts b/Tone/component/filter/FeedbackCombFilter.test.ts index 1dd94d70..f4959038 100644 --- a/Tone/component/filter/FeedbackCombFilter.test.ts +++ b/Tone/component/filter/FeedbackCombFilter.test.ts @@ -1,17 +1,15 @@ import { expect } from "chai"; -import { FeedbackCombFilter } from "./FeedbackCombFilter"; -import { BitCrusher } from "Tone/effect/BitCrusher"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { Offline } from "test/helper/Offline"; -import { Signal } from "Tone/signal"; +import { FeedbackCombFilter } from "./FeedbackCombFilter.js"; +import { BitCrusher } from "../../effect/BitCrusher.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { Signal } from "../../signal/index.js"; describe("FeedbackCombFilter", () => { - BasicTests(FeedbackCombFilter); context("Comb Filtering", () => { - it("can be constructed with an object", () => { const fbcf = new FeedbackCombFilter({ delayTime: 0.2, @@ -35,7 +33,7 @@ describe("FeedbackCombFilter", () => { }); it("passes the incoming signal through", () => { - return PassAudio(input => { + return PassAudio((input) => { const fbcf = new FeedbackCombFilter({ delayTime: 0.0, resonance: 0, @@ -52,7 +50,7 @@ describe("FeedbackCombFilter", () => { }).toDestination(); const sig = new Signal(0).connect(fbcf); sig.setValueAtTime(1, 0); - }, 0.2).then(buffer => { + }, 0.2).then((buffer) => { expect(buffer.getValueAtTime(0)).to.equal(0); expect(buffer.getValueAtTime(0.999)).to.equal(0); expect(buffer.getValueAtTime(0.101)).to.equal(1); @@ -69,7 +67,7 @@ describe("FeedbackCombFilter", () => { const sig = new Signal(0).connect(fbcf); sig.setValueAtTime(1, 0); sig.setValueAtTime(0, 0.1); - }, 0.4).then(buffer => { + }, 0.4).then((buffer) => { expect(buffer.getValueAtTime(0)).to.equal(0); expect(buffer.getValueAtTime(0.101)).to.equal(1); expect(buffer.getValueAtTime(0.201)).to.equal(0.5); @@ -93,4 +91,3 @@ describe("FeedbackCombFilter", () => { }; }); }); - diff --git a/Tone/component/filter/FeedbackCombFilter.ts b/Tone/component/filter/FeedbackCombFilter.ts index d7668ccb..c5f48faf 100644 --- a/Tone/component/filter/FeedbackCombFilter.ts +++ b/Tone/component/filter/FeedbackCombFilter.ts @@ -1,11 +1,15 @@ -import { Gain } from "../../core/context/Gain"; -import { Param } from "../../core/context/Param"; -import { connectSeries, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { NormalRange, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly, RecursivePartial } from "../../core/util/Interface"; -import { ToneAudioWorklet } from "../../core/worklet/ToneAudioWorklet"; -import { workletName } from "./FeedbackCombFilter.worklet"; +import { Gain } from "../../core/context/Gain.js"; +import { Param } from "../../core/context/Param.js"; +import { + connectSeries, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { NormalRange, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly, RecursivePartial } from "../../core/util/Interface.js"; +import { ToneAudioWorklet } from "../../core/worklet/ToneAudioWorklet.js"; +import { workletName } from "./FeedbackCombFilter.worklet.js"; export interface FeedbackCombFilterOptions extends ToneAudioNodeOptions { delayTime: Time; @@ -15,14 +19,13 @@ export interface FeedbackCombFilterOptions extends ToneAudioNodeOptions { /** * Comb filters are basic building blocks for physical modeling. Read more * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html). - * - * This comb filter is implemented with the AudioWorkletNode which allows it to have feedback delays less than the - * Web Audio processing block of 128 samples. There is a polyfill for browsers that don't yet support the - * AudioWorkletNode, but it will add some latency and have slower performance than the AudioWorkletNode. + * + * This comb filter is implemented with the AudioWorkletNode which allows it to have feedback delays less than the + * Web Audio processing block of 128 samples. There is a polyfill for browsers that don't yet support the + * AudioWorkletNode, but it will add some latency and have slower performance than the AudioWorkletNode. * @category Component */ export class FeedbackCombFilter extends ToneAudioWorklet { - readonly name = "FeedbackCombFilter"; /** @@ -45,8 +48,17 @@ export class FeedbackCombFilter extends ToneAudioWorklet); constructor() { - super(optionsFromArguments(FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"])); - const options = optionsFromArguments(FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]); + super( + optionsFromArguments(FeedbackCombFilter.getDefaults(), arguments, [ + "delayTime", + "resonance", + ]) + ); + const options = optionsFromArguments( + FeedbackCombFilter.getDefaults(), + arguments, + ["delayTime", "resonance"] + ); this.input = new Gain({ context: this.context }); this.output = new Gain({ context: this.context }); diff --git a/Tone/component/filter/FeedbackCombFilter.worklet.ts b/Tone/component/filter/FeedbackCombFilter.worklet.ts index 99c46898..a2d2f4d8 100644 --- a/Tone/component/filter/FeedbackCombFilter.worklet.ts +++ b/Tone/component/filter/FeedbackCombFilter.worklet.ts @@ -1,10 +1,10 @@ -import "../../core/worklet/SingleIOProcessor.worklet"; -import "../../core/worklet/DelayLine.worklet"; -import { registerProcessor } from "../../core/worklet/WorkletGlobalScope"; +import "../../core/worklet/SingleIOProcessor.worklet.js"; +import "../../core/worklet/DelayLine.worklet.js"; +import { registerProcessor } from "../../core/worklet/WorkletGlobalScope.js"; export const workletName = "feedback-comb-filter"; -const feedbackCombFilter = /* javascript */` +const feedbackCombFilter = /* javascript */ ` class FeedbackCombFilterWorklet extends SingleIOProcessor { constructor(options) { diff --git a/Tone/component/filter/Filter.test.ts b/Tone/component/filter/Filter.test.ts index 3feca1ec..30c6e219 100644 --- a/Tone/component/filter/Filter.test.ts +++ b/Tone/component/filter/Filter.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Oscillator } from "../../source/oscillator/Oscillator"; -import { Filter, FilterRollOff } from "./Filter"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; +import { Filter, FilterRollOff } from "./Filter.js"; describe("Filter", () => { - BasicTests(Filter); context("Filtering", () => { - it("can be constructed with a arguments", () => { const filter = new Filter(200, "highpass"); expect(filter.frequency.value).to.be.closeTo(200, 0.001); @@ -38,7 +36,13 @@ describe("Filter", () => { type: "highpass" as BiquadFilterType, }; filter.set(values); - expect(filter.get()).to.include.keys(["type", "frequency", "rolloff", "Q", "gain"]); + expect(filter.get()).to.include.keys([ + "type", + "frequency", + "rolloff", + "Q", + "gain", + ]); expect(filter.type).to.equal(values.type); expect(filter.frequency.value).to.equal(values.frequency); expect(filter.rolloff).to.equal(values.rolloff); @@ -59,7 +63,7 @@ describe("Filter", () => { }); it("passes the incoming signal through", () => { - return PassAudio(input => { + return PassAudio((input) => { const filter = new Filter().toDestination(); input.connect(filter); }); @@ -85,8 +89,16 @@ describe("Filter", () => { it("can set the basic filter types", () => { const filter = new Filter(); - const types: BiquadFilterType[] = ["lowpass", "highpass", - "bandpass", "lowshelf", "highshelf", "notch", "allpass", "peaking"]; + const types: BiquadFilterType[] = [ + "lowpass", + "highpass", + "bandpass", + "lowshelf", + "highshelf", + "notch", + "allpass", + "peaking", + ]; for (const type of types) { filter.type = type; expect(filter.type).to.equal(type); @@ -109,6 +121,5 @@ describe("Filter", () => { expect(buffer.getRmsAtTime(0.1)).to.be.within(0.37, 0.53); }); }); - }); }); diff --git a/Tone/component/filter/Filter.ts b/Tone/component/filter/Filter.ts index 358b0911..6ddaf7bc 100644 --- a/Tone/component/filter/Filter.ts +++ b/Tone/component/filter/Filter.ts @@ -1,18 +1,21 @@ -import { Gain } from "../../core/context/Gain"; -import { connectSeries, ToneAudioNode } from "../../core/context/ToneAudioNode"; -import { Frequency } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly, writable } from "../../core/util/Interface"; -import { isNumber } from "../../core/util/TypeCheck"; -import { Signal } from "../../signal/Signal"; -import { assert } from "../../core/util/Debug"; -import { BiquadFilter, BiquadFilterOptions } from "./BiquadFilter"; +import { Gain } from "../../core/context/Gain.js"; +import { + connectSeries, + ToneAudioNode, +} from "../../core/context/ToneAudioNode.js"; +import { Frequency } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly, writable } from "../../core/util/Interface.js"; +import { isNumber } from "../../core/util/TypeCheck.js"; +import { Signal } from "../../signal/Signal.js"; +import { assert } from "../../core/util/Debug.js"; +import { BiquadFilter, BiquadFilterOptions } from "./BiquadFilter.js"; export type FilterRollOff = -12 | -24 | -48 | -96; export type FilterOptions = BiquadFilterOptions & { rolloff: FilterRollOff; -} +}; /** * Tone.Filter is a filter which allows for all of the same native methods @@ -26,7 +29,6 @@ export type FilterOptions = BiquadFilterOptions & { * @category Component */ export class Filter extends ToneAudioNode { - readonly name: string = "Filter"; readonly input = new Gain({ context: this.context }); @@ -64,11 +66,25 @@ export class Filter extends ToneAudioNode { * @param type The type of filter. * @param rolloff The drop in decibels per octave after the cutoff frequency */ - constructor(frequency?: Frequency, type?: BiquadFilterType, rolloff?: FilterRollOff); + constructor( + frequency?: Frequency, + type?: BiquadFilterType, + rolloff?: FilterRollOff + ); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"])); - const options = optionsFromArguments(Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]); + super( + optionsFromArguments(Filter.getDefaults(), arguments, [ + "frequency", + "type", + "rolloff", + ]) + ); + const options = optionsFromArguments(Filter.getDefaults(), arguments, [ + "frequency", + "type", + "rolloff", + ]); this._filters = []; @@ -117,11 +133,19 @@ export class Filter extends ToneAudioNode { return this._type; } set type(type: BiquadFilterType) { - const types: BiquadFilterType[] = ["lowpass", "highpass", "bandpass", - "lowshelf", "highshelf", "notch", "allpass", "peaking"]; + const types: BiquadFilterType[] = [ + "lowpass", + "highpass", + "bandpass", + "lowshelf", + "highshelf", + "notch", + "allpass", + "peaking", + ]; assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`); this._type = type; - this._filters.forEach(filter => filter.type = type); + this._filters.forEach((filter) => (filter.type = type)); } /** @@ -133,16 +157,21 @@ export class Filter extends ToneAudioNode { return this._rolloff; } set rolloff(rolloff) { - const rolloffNum = isNumber(rolloff) ? rolloff : parseInt(rolloff, 10) as FilterRollOff; + const rolloffNum = isNumber(rolloff) + ? rolloff + : (parseInt(rolloff, 10) as FilterRollOff); const possibilities = [-12, -24, -48, -96]; let cascadingCount = possibilities.indexOf(rolloffNum); // check the rolloff is valid - assert(cascadingCount !== -1, `rolloff can only be ${possibilities.join(", ")}`); + assert( + cascadingCount !== -1, + `rolloff can only be ${possibilities.join(", ")}` + ); cascadingCount += 1; this._rolloff = rolloffNum; this.input.disconnect(); - this._filters.forEach(filter => filter.disconnect()); + this._filters.forEach((filter) => filter.disconnect()); this._filters = new Array(cascadingCount); for (let count = 0; count < cascadingCount; count++) { @@ -178,7 +207,7 @@ export class Filter extends ToneAudioNode { const totalResponse = new Float32Array(len).map(() => 1); this._filters.forEach(() => { const response = filterClone.getFrequencyResponse(len); - response.forEach((val, i) => totalResponse[i] *= val); + response.forEach((val, i) => (totalResponse[i] *= val)); }); filterClone.dispose(); return totalResponse; @@ -189,7 +218,7 @@ export class Filter extends ToneAudioNode { */ dispose(): this { super.dispose(); - this._filters.forEach(filter => { + this._filters.forEach((filter) => { filter.dispose(); }); writable(this, ["detune", "frequency", "gain", "Q"]); diff --git a/Tone/component/filter/LowpassCombFilter.test.ts b/Tone/component/filter/LowpassCombFilter.test.ts index 0b107c4b..4c55c852 100644 --- a/Tone/component/filter/LowpassCombFilter.test.ts +++ b/Tone/component/filter/LowpassCombFilter.test.ts @@ -1,21 +1,19 @@ -import { LowpassCombFilter } from "./LowpassCombFilter"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { LowpassCombFilter } from "./LowpassCombFilter.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; import { expect } from "chai"; describe("LowpassCombFilter", () => { - BasicTests(LowpassCombFilter); context("Comb Filtering", () => { - it("can be constructed with an object", () => { const lpcf = new LowpassCombFilter({ delayTime: 0.2, resonance: 0.3, - dampening: 2400 + dampening: 2400, }); expect(lpcf.delayTime.value).to.be.closeTo(0.2, 0.001); expect(lpcf.resonance.value).to.be.closeTo(0.3, 0.001); @@ -28,7 +26,7 @@ describe("LowpassCombFilter", () => { lpcf.set({ delayTime: 0.2, resonance: 0.3, - dampening: 2000 + dampening: 2000, }); expect(lpcf.get().delayTime).to.be.closeTo(0.2, 0.001); expect(lpcf.get().resonance).to.be.closeTo(0.3, 0.001); @@ -45,7 +43,11 @@ describe("LowpassCombFilter", () => { it("produces a decay signal at high resonance", () => { return Offline(() => { - const lpcf = new LowpassCombFilter(0.01, 0.9, 5000).toDestination(); + const lpcf = new LowpassCombFilter( + 0.01, + 0.9, + 5000 + ).toDestination(); const burst = new Oscillator(440).connect(lpcf); burst.start(0); burst.stop(0.1); diff --git a/Tone/component/filter/LowpassCombFilter.ts b/Tone/component/filter/LowpassCombFilter.ts index 38728315..2a6c1999 100644 --- a/Tone/component/filter/LowpassCombFilter.ts +++ b/Tone/component/filter/LowpassCombFilter.ts @@ -1,10 +1,15 @@ -import { Param } from "../../core/context/Param"; -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Frequency, NormalRange, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { RecursivePartial } from "../../core/util/Interface"; -import { FeedbackCombFilter } from "./FeedbackCombFilter"; -import { OnePoleFilter } from "./OnePoleFilter"; +import { Param } from "../../core/context/Param.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Frequency, NormalRange, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { RecursivePartial } from "../../core/util/Interface.js"; +import { FeedbackCombFilter } from "./FeedbackCombFilter.js"; +import { OnePoleFilter } from "./OnePoleFilter.js"; interface LowpassCombFilterOptions extends ToneAudioNodeOptions { delayTime: Time; @@ -18,7 +23,6 @@ interface LowpassCombFilterOptions extends ToneAudioNodeOptions { * @category Component */ export class LowpassCombFilter extends ToneAudioNode { - readonly name = "LowpassCombFilter"; /** @@ -49,11 +53,25 @@ export class LowpassCombFilter extends ToneAudioNode { * @param resonance The resonance (feedback) of the comb filter * @param dampening The cutoff of the lowpass filter dampens the signal as it is fedback. */ - constructor(delayTime?: Time, resonance?: NormalRange, dampening?: Frequency); + constructor( + delayTime?: Time, + resonance?: NormalRange, + dampening?: Frequency + ); constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"])); - const options = optionsFromArguments(LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]); + super( + optionsFromArguments(LowpassCombFilter.getDefaults(), arguments, [ + "delayTime", + "resonance", + "dampening", + ]) + ); + const options = optionsFromArguments( + LowpassCombFilter.getDefaults(), + arguments, + ["delayTime", "resonance", "dampening"] + ); this._combFilter = this.output = new FeedbackCombFilter({ context: this.context, @@ -80,7 +98,7 @@ export class LowpassCombFilter extends ToneAudioNode { resonance: 0.5, }); } - + /** * The dampening control of the feedback */ diff --git a/Tone/component/filter/OnePoleFilter.test.ts b/Tone/component/filter/OnePoleFilter.test.ts index 7fb68506..b6bebc5b 100644 --- a/Tone/component/filter/OnePoleFilter.test.ts +++ b/Tone/component/filter/OnePoleFilter.test.ts @@ -1,38 +1,50 @@ -import { OnePoleFilter } from "./OnePoleFilter"; -import { BasicTests } from "test/helper/Basic"; -import { PassAudio } from "test/helper/PassAudio"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { OnePoleFilter } from "./OnePoleFilter.js"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { atTime, Offline } from "test/helper/Offline"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { atTime, Offline } from "../../../test/helper/Offline.js"; describe("OnePoleFilter", () => { - BasicTests(OnePoleFilter); it("matches a file when set to lowpass", () => { - return CompareToFile(() => { - const filter = new OnePoleFilter(300, "lowpass").toDestination(); - const osc = new Oscillator().connect(filter); - osc.type = "square"; - osc.start(0).stop(0.1); - }, "onePoleLowpass.wav", 0.05); + return CompareToFile( + () => { + const filter = new OnePoleFilter( + 300, + "lowpass" + ).toDestination(); + const osc = new Oscillator().connect(filter); + osc.type = "square"; + osc.start(0).stop(0.1); + }, + "onePoleLowpass.wav", + 0.05 + ); }); it("matches a file when set to highpass", () => { - return CompareToFile(() => { - const filter = new OnePoleFilter(700, "highpass").toDestination(); - const osc = new Oscillator().connect(filter); - osc.type = "square"; - osc.start(0).stop(0.1); - }, "onePoleHighpass.wav", 0.05); + return CompareToFile( + () => { + const filter = new OnePoleFilter( + 700, + "highpass" + ).toDestination(); + const osc = new Oscillator().connect(filter); + osc.type = "square"; + osc.start(0).stop(0.1); + }, + "onePoleHighpass.wav", + 0.05 + ); }); context("Filtering", () => { - it("can set the frequency more than once", () => { return Offline(() => { - const filter = new OnePoleFilter(200); + const filter = new OnePoleFilter(200); filter.frequency = 300; return atTime(0.1, () => { filter.frequency = 400; @@ -43,7 +55,7 @@ describe("OnePoleFilter", () => { it("can be constructed with an object", () => { const filter = new OnePoleFilter({ frequency: 400, - type: "lowpass" + type: "lowpass", }); expect(filter.frequency).to.be.closeTo(400, 0.1); expect(filter.type).to.equal("lowpass"); @@ -61,7 +73,7 @@ describe("OnePoleFilter", () => { const filter = new OnePoleFilter(); filter.set({ frequency: 200, - type: "highpass" + type: "highpass", }); expect(filter.get().type).to.equal("highpass"); expect(filter.get().frequency).to.be.closeTo(200, 0.1); @@ -77,14 +89,12 @@ describe("OnePoleFilter", () => { }); context("Response Curve", () => { - it("can get the response curve", () => { const filter = new OnePoleFilter(); const response = filter.getFrequencyResponse(128); expect(response.length).to.equal(128); - response.forEach(v => expect(v).to.be.within(0, 1)); + response.forEach((v) => expect(v).to.be.within(0, 1)); filter.dispose(); }); - }); }); diff --git a/Tone/component/filter/OnePoleFilter.ts b/Tone/component/filter/OnePoleFilter.ts index 0f9592cd..acf9d468 100644 --- a/Tone/component/filter/OnePoleFilter.ts +++ b/Tone/component/filter/OnePoleFilter.ts @@ -1,7 +1,10 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; -import { Frequency } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { Gain } from "../../core/context/Gain"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; +import { Frequency } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { Gain } from "../../core/context/Gain.js"; export type OnePoleFilterType = "highpass" | "lowpass"; @@ -11,17 +14,16 @@ export interface OnePoleFilterOptions extends ToneAudioNodeOptions { } /** - * A one pole filter with 6db-per-octave rolloff. Either "highpass" or "lowpass". + * A one pole filter with 6db-per-octave rolloff. Either "highpass" or "lowpass". * Note that changing the type or frequency may result in a discontinuity which - * can sound like a click or pop. - * References: - * * http://www.earlevel.com/main/2012/12/15/a-one-pole-filter/ + * can sound like a click or pop. + * References: + * * http://www.earlevel.com/main/2012/12/15/a-one-pole-filter/ * * http://www.dspguide.com/ch19/2.htm * * https://github.com/vitaliy-bobrov/js-rocks/blob/master/src/app/audio/effects/one-pole-filters.ts * @category Component */ export class OnePoleFilter extends ToneAudioNode { - readonly name: string = "OnePoleFilter"; /** @@ -47,11 +49,19 @@ export class OnePoleFilter extends ToneAudioNode { * @param type The filter type, either "lowpass" or "highpass" */ constructor(frequency?: Frequency, type?: OnePoleFilterType); - constructor(options?: Partial) + constructor(options?: Partial); constructor() { - - super(optionsFromArguments(OnePoleFilter.getDefaults(), arguments, ["frequency", "type"])); - const options = optionsFromArguments(OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]); + super( + optionsFromArguments(OnePoleFilter.getDefaults(), arguments, [ + "frequency", + "type", + ]) + ); + const options = optionsFromArguments( + OnePoleFilter.getDefaults(), + arguments, + ["frequency", "type"] + ); this._frequency = options.frequency; this._type = options.type; @@ -63,7 +73,7 @@ export class OnePoleFilter extends ToneAudioNode { static getDefaults(): OnePoleFilterOptions { return Object.assign(ToneAudioNode.getDefaults(), { frequency: 880, - type: "lowpass" as OnePoleFilterType + type: "lowpass" as OnePoleFilterType, }); } @@ -82,7 +92,7 @@ export class OnePoleFilter extends ToneAudioNode { const b1 = 1 / (t * this.context.sampleRate) - 1; this._filter = this.context.createIIRFilter([1, -1], [1, b1]); } - + this.input.chain(this._filter, this.output); if (oldFilter) { // dispose it on the next block @@ -96,7 +106,7 @@ export class OnePoleFilter extends ToneAudioNode { } /** - * The frequency value. + * The frequency value. */ get frequency(): Frequency { return this._frequency; @@ -105,7 +115,7 @@ export class OnePoleFilter extends ToneAudioNode { this._frequency = fq; this._createFilter(); } - + /** * The OnePole Filter type, either "highpass" or "lowpass" */ diff --git a/Tone/component/filter/PhaseShiftAllpass.test.ts b/Tone/component/filter/PhaseShiftAllpass.test.ts index a77693ba..2737cd3e 100644 --- a/Tone/component/filter/PhaseShiftAllpass.test.ts +++ b/Tone/component/filter/PhaseShiftAllpass.test.ts @@ -1,17 +1,15 @@ -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { connectTo } from "test/helper/Connect"; -import { PassAudio } from "test/helper/PassAudio"; -import { connect } from "Tone/core/context/ToneAudioNode"; -import { Subtract } from "Tone/signal/Subtract"; -import { PhaseShiftAllpass } from "./PhaseShiftAllpass"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { connectTo } from "../../../test/helper/Connect.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { connect } from "../../core/context/ToneAudioNode.js"; +import { Subtract } from "../../signal/Subtract.js"; +import { PhaseShiftAllpass } from "./PhaseShiftAllpass.js"; describe("PhaseShiftAllpass", () => { - BasicTests(PhaseShiftAllpass); context("PhaseShiftAllpass", () => { - it("handles output connections", () => { const phaseShifter = new PhaseShiftAllpass(); phaseShifter.connect(connectTo()); @@ -27,45 +25,63 @@ describe("PhaseShiftAllpass", () => { }); it("generates correct values with the phase shifted channel", () => { - return CompareToFile((context) => { - // create impulse with 5 samples offset - const constantNode = context.createConstantSource(); - constantNode.start(0); - const oneSampleDelay = context.createIIRFilter([0.0, 1.0], [1.0, 0.0]); - const fiveSampleDelay = context.createIIRFilter([0.0, 0.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0]); - const sub = new Subtract(); + return CompareToFile( + (context) => { + // create impulse with 5 samples offset + const constantNode = context.createConstantSource(); + constantNode.start(0); + const oneSampleDelay = context.createIIRFilter( + [0.0, 1.0], + [1.0, 0.0] + ); + const fiveSampleDelay = context.createIIRFilter( + [0.0, 0.0, 0.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 0.0, 0.0, 0.0] + ); + const sub = new Subtract(); - connect(constantNode, oneSampleDelay); - connect(constantNode, sub); - connect(oneSampleDelay, sub.subtrahend); - connect(sub, fiveSampleDelay); + connect(constantNode, oneSampleDelay); + connect(constantNode, sub); + connect(oneSampleDelay, sub.subtrahend); + connect(sub, fiveSampleDelay); - const phaseShifter = new PhaseShiftAllpass(); - connect(fiveSampleDelay, phaseShifter); - phaseShifter.toDestination(); - - }, "phaseShiftAllpass.wav", 0.001); + const phaseShifter = new PhaseShiftAllpass(); + connect(fiveSampleDelay, phaseShifter); + phaseShifter.toDestination(); + }, + "phaseShiftAllpass.wav", + 0.001 + ); }); it("generates correct values with the offset90 channel", () => { - return CompareToFile((context) => { - // create impulse with 5 samples offset - const constantNode = context.createConstantSource(); - constantNode.start(0); - const oneSampleDelay = context.createIIRFilter([0.0, 1.0], [1.0, 0.0]); - const fiveSampleDelay = context.createIIRFilter([0.0, 0.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0]); - const sub = new Subtract(); - - connect(constantNode, oneSampleDelay); - connect(constantNode, sub); - connect(oneSampleDelay, sub.subtrahend); - connect(sub, fiveSampleDelay); + return CompareToFile( + (context) => { + // create impulse with 5 samples offset + const constantNode = context.createConstantSource(); + constantNode.start(0); + const oneSampleDelay = context.createIIRFilter( + [0.0, 1.0], + [1.0, 0.0] + ); + const fiveSampleDelay = context.createIIRFilter( + [0.0, 0.0, 0.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 0.0, 0.0, 0.0] + ); + const sub = new Subtract(); - const phaseShifter = new PhaseShiftAllpass(); - connect(fiveSampleDelay, phaseShifter); - phaseShifter.offset90.toDestination(); + connect(constantNode, oneSampleDelay); + connect(constantNode, sub); + connect(oneSampleDelay, sub.subtrahend); + connect(sub, fiveSampleDelay); - }, "phaseShiftAllpass1.wav", 0.001); + const phaseShifter = new PhaseShiftAllpass(); + connect(fiveSampleDelay, phaseShifter); + phaseShifter.offset90.toDestination(); + }, + "phaseShiftAllpass1.wav", + 0.001 + ); }); }); }); diff --git a/Tone/component/filter/PhaseShiftAllpass.ts b/Tone/component/filter/PhaseShiftAllpass.ts index 54c8c918..6f595c2c 100644 --- a/Tone/component/filter/PhaseShiftAllpass.ts +++ b/Tone/component/filter/PhaseShiftAllpass.ts @@ -1,5 +1,9 @@ -import { Gain } from "../../core/context/Gain"; -import { connectSeries, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; +import { Gain } from "../../core/context/Gain.js"; +import { + connectSeries, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../../core/context/ToneAudioNode.js"; /** * PhaseShiftAllpass is an very efficient implementation of a Hilbert Transform @@ -10,7 +14,6 @@ import { connectSeries, ToneAudioNode, ToneAudioNodeOptions } from "../../core/c * @category Component */ export class PhaseShiftAllpass extends ToneAudioNode { - readonly name: string = "PhaseShiftAllpass"; readonly input = new Gain({ context: this.context }); @@ -41,18 +44,29 @@ export class PhaseShiftAllpass extends ToneAudioNode { readonly offset90 = new Gain({ context: this.context }); constructor(options?: Partial) { - super(options); - const allpassBank1Values = [0.6923878, 0.9360654322959, 0.9882295226860, 0.9987488452737]; - const allpassBank2Values = [0.4021921162426, 0.8561710882420, 0.9722909545651, 0.9952884791278]; + const allpassBank1Values = [ + 0.6923878, 0.9360654322959, 0.988229522686, 0.9987488452737, + ]; + const allpassBank2Values = [ + 0.4021921162426, 0.856171088242, 0.9722909545651, 0.9952884791278, + ]; this._bank0 = this._createAllPassFilterBank(allpassBank1Values); this._bank1 = this._createAllPassFilterBank(allpassBank2Values); - this._oneSampleDelay = this.context.createIIRFilter([0.0, 1.0], [1.0, 0.0]); + this._oneSampleDelay = this.context.createIIRFilter( + [0.0, 1.0], + [1.0, 0.0] + ); // connect Allpass filter banks - connectSeries(this.input, ...this._bank0, this._oneSampleDelay, this.output); + connectSeries( + this.input, + ...this._bank0, + this._oneSampleDelay, + this.output + ); connectSeries(this.input, ...this._bank1, this.offset90); } @@ -60,9 +74,15 @@ export class PhaseShiftAllpass extends ToneAudioNode { * Create all of the IIR filters from an array of values using the coefficient calculation. */ private _createAllPassFilterBank(bankValues: number[]): IIRFilterNode[] { - const nodes: IIRFilterNode[] = bankValues.map(value => { - const coefficients = [[value * value, 0, -1], [1, 0, -(value * value)]]; - return this.context.createIIRFilter(coefficients[0], coefficients[1]); + const nodes: IIRFilterNode[] = bankValues.map((value) => { + const coefficients = [ + [value * value, 0, -1], + [1, 0, -(value * value)], + ]; + return this.context.createIIRFilter( + coefficients[0], + coefficients[1] + ); }); return nodes; @@ -73,8 +93,8 @@ export class PhaseShiftAllpass extends ToneAudioNode { this.input.dispose(); this.output.dispose(); this.offset90.dispose(); - this._bank0.forEach(f => f.disconnect()); - this._bank1.forEach(f => f.disconnect()); + this._bank0.forEach((f) => f.disconnect()); + this._bank1.forEach((f) => f.disconnect()); this._oneSampleDelay.disconnect(); return this; } diff --git a/Tone/component/index.ts b/Tone/component/index.ts index 556f7c75..241c5e07 100644 --- a/Tone/component/index.ts +++ b/Tone/component/index.ts @@ -1,39 +1,39 @@ -export * from "./analysis/Analyser"; -export * from "./analysis/Meter"; -export * from "./analysis/FFT"; -export * from "./analysis/DCMeter"; -export * from "./analysis/Waveform"; -export * from "./analysis/Follower"; +export * from "./analysis/Analyser.js"; +export * from "./analysis/Meter.js"; +export * from "./analysis/FFT.js"; +export * from "./analysis/DCMeter.js"; +export * from "./analysis/Waveform.js"; +export * from "./analysis/Follower.js"; -export * from "./channel/Channel"; -export * from "./channel/CrossFade"; -export * from "./channel/Merge"; -export * from "./channel/MidSideMerge"; -export * from "./channel/MidSideSplit"; -export * from "./channel/Mono"; -export * from "./channel/MultibandSplit"; -export * from "./channel/Panner"; -export * from "./channel/Panner3D"; -export * from "./channel/PanVol"; -export * from "./channel/Recorder"; -export * from "./channel/Solo"; -export * from "./channel/Split"; -export * from "./channel/Volume"; +export * from "./channel/Channel.js"; +export * from "./channel/CrossFade.js"; +export * from "./channel/Merge.js"; +export * from "./channel/MidSideMerge.js"; +export * from "./channel/MidSideSplit.js"; +export * from "./channel/Mono.js"; +export * from "./channel/MultibandSplit.js"; +export * from "./channel/Panner.js"; +export * from "./channel/Panner3D.js"; +export * from "./channel/PanVol.js"; +export * from "./channel/Recorder.js"; +export * from "./channel/Solo.js"; +export * from "./channel/Split.js"; +export * from "./channel/Volume.js"; -export * from "./dynamics/Compressor"; -export * from "./dynamics/Gate"; -export * from "./dynamics/Limiter"; -export * from "./dynamics/MidSideCompressor"; -export * from "./dynamics/MultibandCompressor"; +export * from "./dynamics/Compressor.js"; +export * from "./dynamics/Gate.js"; +export * from "./dynamics/Limiter.js"; +export * from "./dynamics/MidSideCompressor.js"; +export * from "./dynamics/MultibandCompressor.js"; -export * from "./envelope/AmplitudeEnvelope"; -export * from "./envelope/Envelope"; -export * from "./envelope/FrequencyEnvelope"; +export * from "./envelope/AmplitudeEnvelope.js"; +export * from "./envelope/Envelope.js"; +export * from "./envelope/FrequencyEnvelope.js"; -export * from "./filter/EQ3"; -export * from "./filter/Filter"; -export * from "./filter/OnePoleFilter"; -export * from "./filter/FeedbackCombFilter"; -export * from "./filter/LowpassCombFilter"; -export * from "./filter/Convolver"; -export * from "./filter/BiquadFilter"; +export * from "./filter/EQ3.js"; +export * from "./filter/Filter.js"; +export * from "./filter/OnePoleFilter.js"; +export * from "./filter/FeedbackCombFilter.js"; +export * from "./filter/LowpassCombFilter.js"; +export * from "./filter/Convolver.js"; +export * from "./filter/BiquadFilter.js"; diff --git a/Tone/core/Global.ts b/Tone/core/Global.ts index 13e93de2..31de7f4e 100644 --- a/Tone/core/Global.ts +++ b/Tone/core/Global.ts @@ -1,10 +1,17 @@ -import { version } from "../version"; -import { AnyAudioContext, hasAudioContext, theWindow } from "./context/AudioContext"; -import { Context } from "./context/Context"; -import { DummyContext } from "./context/DummyContext"; -import { BaseContext } from "./context/BaseContext"; -import { OfflineContext } from "./context/OfflineContext"; -import { isAudioContext, isOfflineAudioContext } from "./util/AdvancedTypeCheck"; +import { version } from "../version.js"; +import { + AnyAudioContext, + hasAudioContext, + theWindow, +} from "./context/AudioContext.js"; +import { Context } from "./context/Context.js"; +import { DummyContext } from "./context/DummyContext.js"; +import { BaseContext } from "./context/BaseContext.js"; +import { OfflineContext } from "./context/OfflineContext.js"; +import { + isAudioContext, + isOfflineAudioContext, +} from "./util/AdvancedTypeCheck.js"; /** * This dummy context is used to avoid throwing immediate errors when importing in Node.js @@ -34,7 +41,10 @@ export function getContext(): BaseContext { * @param disposeOld Pass `true` if you don't need the old context to dispose it. * @category Core */ -export function setContext(context: BaseContext | AnyAudioContext, disposeOld = false): void { +export function setContext( + context: BaseContext | AnyAudioContext, + disposeOld = false +): void { if (disposeOld) { globalContext.dispose(); } diff --git a/Tone/core/Tone.ts b/Tone/core/Tone.ts index 7414ea04..644cda7b 100644 --- a/Tone/core/Tone.ts +++ b/Tone/core/Tone.ts @@ -2,27 +2,26 @@ * Tone.js * @author Yotam Mann * @license http://opensource.org/licenses/MIT MIT License - * @copyright 2014-2019 Yotam Mann + * @copyright 2014-2024 Yotam Mann */ -import { version } from "../version"; -import { theWindow } from "./context/AudioContext"; -import { log } from "./util/Debug"; +import { version } from "../version.js"; +import { theWindow } from "./context/AudioContext.js"; +import { log } from "./util/Debug.js"; //------------------------------------- // TONE //------------------------------------- // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface BaseToneOptions { } +export interface BaseToneOptions {} /** * Tone is the base class of all other classes. - * + * * @category Core * @constructor */ export abstract class Tone { - /** * The version number semver */ @@ -64,7 +63,10 @@ export abstract class Tone { protected log(...args: any[]): void { // if the object is either set to debug = true // or if there is a string on the Tone.global.with the class name - if (this.debug || (theWindow && this.toString() === theWindow.TONE_DEBUG_CLASS)) { + if ( + this.debug || + (theWindow && this.toString() === theWindow.TONE_DEBUG_CLASS) + ) { log(this, ...args); } } diff --git a/Tone/core/clock/Clock.test.ts b/Tone/core/clock/Clock.test.ts index a6533402..f38d9be6 100644 --- a/Tone/core/clock/Clock.test.ts +++ b/Tone/core/clock/Clock.test.ts @@ -1,16 +1,13 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline, whenBetween } from "test/helper/Offline"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { noOp } from "../util/Interface"; -import { Clock } from "./Clock"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { atTime, Offline, whenBetween } from "../../../test/helper/Offline.js"; +import { noOp } from "../util/Interface.js"; +import { Clock } from "./Clock.js"; describe("Clock", () => { - BasicTests(Clock); context("Get/Set values", () => { - it("can get and set the frequency", () => { const clock = new Clock(noOp, 2); expect(clock.frequency.value).to.equal(2); @@ -19,27 +16,23 @@ describe("Clock", () => { clock.dispose(); }); - if (ONLINE_TESTING) { + it("invokes the callback when started", (done) => { + const clock = new Clock((time) => { + clock.dispose(); + done(); + }, 10).start(); + }); - it("invokes the callback when started", (done) => { - const clock = new Clock((time) => { + it("can be constructed with an options object", (done) => { + const clock = new Clock({ + callback(): void { clock.dispose(); done(); - }, 10).start(); - }); - - it("can be constructed with an options object", (done) => { - const clock = new Clock({ - callback(): void { - clock.dispose(); - done(); - }, - frequency: 8, - }).start(); - expect(clock.frequency.value).to.equal(8); - }); - - } + }, + frequency: 8, + }).start(); + expect(clock.frequency.value).to.equal(8); + }); it("can get and set it's values with the set/get", () => { const clock = new Clock(); @@ -53,7 +46,6 @@ describe("Clock", () => { }); context("State", () => { - it("correctly returns the scheduled play state", () => { return Offline(() => { const clock = new Clock(); @@ -93,7 +85,6 @@ describe("Clock", () => { expect(clock.state).to.equal("stopped"); }); }; - }, 0.5); }); @@ -137,44 +128,39 @@ describe("Clock", () => { expect(clock.state).to.equal("started"); }); }; - }, 0.5); }); }); context("Scheduling", () => { + it("passes a time to the callback", (done) => { + const clock = new Clock((time) => { + expect(time).to.be.a("number"); + clock.dispose(); + done(); + }, 10).start(); + }); - if (ONLINE_TESTING) { - - it("passes a time to the callback", (done) => { - const clock = new Clock((time) => { - expect(time).to.be.a("number"); - clock.dispose(); - done(); - }, 10).start(); - }); - - it("invokes the callback with a time great than now", (done) => { - const clock = new Clock((time) => { - clock.dispose(); - expect(time).to.be.greaterThan(now); - done(); - }, 10); - const now = clock.now(); - const startTime = now + 0.1; - clock.start(startTime); - }); + it("invokes the callback with a time great than now", (done) => { + const clock = new Clock((time) => { + clock.dispose(); + expect(time).to.be.greaterThan(now); + done(); + }, 10); + const now = clock.now(); + const startTime = now + 0.1; + clock.start(startTime); + }); - it("invokes the first callback at the given start time", (done) => { - const clock = new Clock((time) => { - clock.dispose(); - expect(time).to.be.closeTo(startTime, 0.01); - done(); - }, 10); - const startTime = clock.now() + 0.1; - clock.start(startTime); - }); - } + it("invokes the first callback at the given start time", (done) => { + const clock = new Clock((time) => { + clock.dispose(); + expect(time).to.be.closeTo(startTime, 0.01); + done(); + }, 10); + const startTime = clock.now() + 0.1; + clock.start(startTime); + }); it("can be scheduled to start in the future", () => { let invokations = 0; @@ -192,7 +178,9 @@ describe("Clock", () => { return Offline(() => { new Clock((time) => { invokations++; - }, 10).start(0).stop(0.45); + }, 10) + .start(0) + .stop(0.45); }, 0.6).then(() => { expect(invokations).to.equal(5); }); @@ -210,11 +198,9 @@ describe("Clock", () => { expect(invokations).to.equal(4); }); }); - }); context("Seconds", () => { - it("can set the current seconds", () => { return Offline(() => { const clock = new Clock(noOp, 10); @@ -274,7 +260,6 @@ describe("Clock", () => { }); context("Ticks", () => { - it("has 0 ticks when first created", () => { const clock = new Clock(); expect(clock.ticks).to.equal(0); @@ -332,9 +317,11 @@ describe("Clock", () => { }); it("starts incrementing where it left off after pause", () => { - return Offline(() => { - const clock = new Clock(noOp, 20).start(0).pause(0.1).start(0.2); + const clock = new Clock(noOp, 20) + .start(0) + .pause(0.1) + .start(0.2); let pausedTicks = 0; let tested = false; @@ -369,11 +356,9 @@ describe("Clock", () => { clock.start(0, 4); }); }); - }); context("Events", () => { - it("triggers the start event on start", (done) => { Offline(() => { const clock = new Clock(noOp, 20); @@ -415,12 +400,14 @@ describe("Clock", () => { it("triggers pause stop event", (done) => { Offline(() => { const clock = new Clock(noOp, 20); - clock.on("pause", (time) => { - expect(time).to.be.closeTo(0.1, 0.05); - }).on("stop", (time) => { - expect(time).to.be.closeTo(0.2, 0.05); - done(); - }); + clock + .on("pause", (time) => { + expect(time).to.be.closeTo(0.1, 0.05); + }) + .on("stop", (time) => { + expect(time).to.be.closeTo(0.2, 0.05); + done(); + }); clock.start().pause(0.1).stop(0.2); }, 0.4); }); @@ -481,7 +468,6 @@ describe("Clock", () => { }); context("[get/set]Ticks", () => { - it("always reports 0 if not started", () => { return Offline(() => { const clock = new Clock(noOp, 20); @@ -657,7 +643,5 @@ describe("Clock", () => { clock.dispose(); }); }); - }); - }); diff --git a/Tone/core/clock/Clock.ts b/Tone/core/clock/Clock.ts index 2d8cb29b..1c34e95c 100644 --- a/Tone/core/clock/Clock.ts +++ b/Tone/core/clock/Clock.ts @@ -1,12 +1,15 @@ -import { ToneWithContext, ToneWithContextOptions } from "../context/ToneWithContext"; -import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { Emitter } from "../util/Emitter"; -import { noOp, readOnly } from "../util/Interface"; -import { PlaybackState, StateTimeline } from "../util/StateTimeline"; -import { TickSignal } from "./TickSignal"; -import { TickSource } from "./TickSource"; -import { assertContextRunning } from "../util/Debug"; +import { + ToneWithContext, + ToneWithContextOptions, +} from "../context/ToneWithContext.js"; +import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { Emitter } from "../util/Emitter.js"; +import { noOp, readOnly } from "../util/Interface.js"; +import { PlaybackState, StateTimeline } from "../util/StateTimeline.js"; +import { TickSignal } from "./TickSignal.js"; +import { TickSource } from "./TickSource.js"; +import { assertContextRunning } from "../util/Debug.js"; type ClockCallback = (time: Seconds, ticks?: Ticks) => void; @@ -34,8 +37,9 @@ type ClockEvent = "start" | "stop" | "pause"; * @category Core */ export class Clock - extends ToneWithContext implements Emitter { - + extends ToneWithContext + implements Emitter +{ readonly name: string = "Clock"; /** @@ -76,9 +80,16 @@ export class Clock constructor(callback?: ClockCallback, frequency?: Frequency); constructor(options: Partial); constructor() { - - super(optionsFromArguments(Clock.getDefaults(), arguments, ["callback", "frequency"])); - const options = optionsFromArguments(Clock.getDefaults(), arguments, ["callback", "frequency"]); + super( + optionsFromArguments(Clock.getDefaults(), arguments, [ + "callback", + "frequency", + ]) + ); + const options = optionsFromArguments(Clock.getDefaults(), arguments, [ + "callback", + "frequency", + ]); this.callback = options.callback; this._tickSource = new TickSource({ @@ -241,14 +252,16 @@ export class Clock nextTickTime(offset: Ticks, when: Time): Seconds { const computedTime = this.toSeconds(when); const currentTick = this.getTicksAtTime(computedTime); - return this._tickSource.getTimeOfTick(currentTick + offset, computedTime); + return this._tickSource.getTimeOfTick( + currentTick + offset, + computedTime + ); } /** * The scheduling loop. */ private _loop(): void { - const startTime = this._lastUpdate; const endTime = this.now(); this._lastUpdate = endTime; @@ -256,7 +269,7 @@ export class Clock if (startTime !== endTime) { // the state change events - this._state.forEachBetween(startTime, endTime, e => { + this._state.forEachBetween(startTime, endTime, (e) => { switch (e.state) { case "started": const offset = this._tickSource.getTicksAtTime(e.time); @@ -273,9 +286,13 @@ export class Clock } }); // the tick callbacks - this._tickSource.forEachTickBetween(startTime, endTime, (time, ticks) => { - this.callback(time, ticks); - }); + this._tickSource.forEachTickBetween( + startTime, + endTime, + (time, ticks) => { + this.callback(time, ticks); + } + ); } } @@ -310,7 +327,10 @@ export class Clock on!: (event: ClockEvent, callback: (...args: any[]) => void) => this; once!: (event: ClockEvent, callback: (...args: any[]) => void) => this; - off!: (event: ClockEvent, callback?: ((...args: any[]) => void) | undefined) => this; + off!: ( + event: ClockEvent, + callback?: ((...args: any[]) => void) | undefined + ) => this; emit!: (event: any, ...args: any[]) => this; } diff --git a/Tone/core/clock/TickParam.test.ts b/Tone/core/clock/TickParam.test.ts index 9d914148..3a5556b9 100644 --- a/Tone/core/clock/TickParam.test.ts +++ b/Tone/core/clock/TickParam.test.ts @@ -1,15 +1,11 @@ -import { Compare, Plot } from "@tonejs/plot"; -import { expect } from "chai"; -import { BasicTests, testAudioContext } from "test/helper/Basic"; -// import { atTime, Offline } from "test/helper/Offline"; -import { TickParam } from "./TickParam"; +import { BasicTests, testAudioContext } from "../../../test/helper/Basic.js"; +// import { atTime, Offline } from "../../../test/helper/Offline"; +import { TickParam } from "./TickParam.js"; describe("TickParam", () => { - // sanity checks BasicTests(TickParam, { context: testAudioContext, param: testAudioContext.createOscillator().frequency, }); - }); diff --git a/Tone/core/clock/TickParam.ts b/Tone/core/clock/TickParam.ts index e9a0f77c..94e41d99 100644 --- a/Tone/core/clock/TickParam.ts +++ b/Tone/core/clock/TickParam.ts @@ -1,14 +1,15 @@ -import { AutomationEvent, Param, ParamOptions } from "../context/Param"; -import { Seconds, Ticks, Time, UnitMap, UnitName } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { Timeline } from "../util/Timeline"; -import { isUndef } from "../util/TypeCheck"; +import { AutomationEvent, Param, ParamOptions } from "../context/Param.js"; +import { Seconds, Ticks, Time, UnitMap, UnitName } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { Timeline } from "../util/Timeline.js"; +import { isUndef } from "../util/TypeCheck.js"; type TickAutomationEvent = AutomationEvent & { ticks: number; }; -interface TickParamOptions extends ParamOptions { +interface TickParamOptions + extends ParamOptions { multiplier: number; } @@ -17,8 +18,9 @@ interface TickParamOptions extends ParamOptions extends Param { - +export class TickParam< + TypeName extends "hertz" | "bpm", +> extends Param { readonly name: string = "TickParam"; /** @@ -42,9 +44,14 @@ export class TickParam extends Param constructor(value?: number); constructor(options: Partial>); constructor() { - - super(optionsFromArguments(TickParam.getDefaults(), arguments, ["value"])); - const options = optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]); + super( + optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]) + ); + const options = optionsFromArguments( + TickParam.getDefaults(), + arguments, + ["value"] + ); // set the multiplier this._multiplier = options.multiplier; @@ -69,7 +76,11 @@ export class TickParam extends Param }); } - setTargetAtTime(value: UnitMap[TypeName], time: Time, constant: number): this { + setTargetAtTime( + value: UnitMap[TypeName], + time: Time, + constant: number + ): this { // approximate it with multiple linear ramps time = this.toSeconds(time); this.setRampPoint(time); @@ -80,7 +91,13 @@ export class TickParam extends Param const segments = Math.round(Math.max(1 / constant, 1)); for (let i = 0; i <= segments; i++) { const segTime = constant * i + time; - const rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, computedValue, constant, segTime); + const rampVal = this._exponentialApproach( + prevEvent.time, + prevEvent.value, + computedValue, + constant, + segTime + ); this.linearRampToValueAtTime(this._toType(rampVal), segTime); } return this; @@ -91,7 +108,10 @@ export class TickParam extends Param super.setValueAtTime(value, time); const event = this._events.get(computedTime) as TickAutomationEvent; const previousEvent = this._events.previousEvent(event); - const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime); + const ticksUntilTime = this._getTicksUntilEvent( + previousEvent, + computedTime + ); event.ticks = Math.max(ticksUntilTime, 0); return this; } @@ -101,7 +121,10 @@ export class TickParam extends Param super.linearRampToValueAtTime(value, time); const event = this._events.get(computedTime) as TickAutomationEvent; const previousEvent = this._events.previousEvent(event); - const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime); + const ticksUntilTime = this._getTicksUntilEvent( + previousEvent, + computedTime + ); event.ticks = Math.max(ticksUntilTime, 0); return this; } @@ -115,10 +138,16 @@ export class TickParam extends Param const prevEvent = this._events.get(time) as TickAutomationEvent; // approx 10 segments per second const segments = Math.round(Math.max((time - prevEvent.time) * 10, 1)); - const segmentDur = ((time - prevEvent.time) / segments); + const segmentDur = (time - prevEvent.time) / segments; for (let i = 0; i <= segments; i++) { const segTime = segmentDur * i + prevEvent.time; - const rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, computedVal, segTime); + const rampVal = this._exponentialInterpolate( + prevEvent.time, + prevEvent.value, + time, + computedVal, + segTime + ); this.linearRampToValueAtTime(this._toType(rampVal), segTime); } return this; @@ -130,7 +159,10 @@ export class TickParam extends Param * @param event The time to get the tick count at * @return The number of ticks which have elapsed at the time given any automations. */ - private _getTicksUntilEvent(event: TickAutomationEvent | null, time: number): Ticks { + private _getTicksUntilEvent( + event: TickAutomationEvent | null, + time: number + ): Ticks { if (event === null) { event = { ticks: 0, @@ -146,7 +178,11 @@ export class TickParam extends Param let val1 = this._fromType(this.getValueAtTime(time)); // if it's right on the line, take the previous value const onTheLineEvent = this._events.get(time); - if (onTheLineEvent && onTheLineEvent.time === time && onTheLineEvent.type === "setValueAtTime") { + if ( + onTheLineEvent && + onTheLineEvent.time === time && + onTheLineEvent.type === "setValueAtTime" + ) { val1 = this._fromType(this.getValueAtTime(time - this.sampleTime)); } return 0.5 * (time - event.time) * (val0 + val1) + event.ticks; @@ -185,13 +221,18 @@ export class TickParam extends Param const after = this._events.getAfter(tick, "ticks"); if (before && before.ticks === tick) { return before.time; - } else if (before && after && + } else if ( + before && + after && after.type === "linearRampToValueAtTime" && - before.value !== after.value) { + before.value !== after.value + ) { const val0 = this._fromType(this.getValueAtTime(before.time)); const val1 = this._fromType(this.getValueAtTime(after.time)); const delta = (val1 - val0) / (after.time - before.time); - const k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick)); + const k = Math.sqrt( + Math.pow(val0, 2) - 2 * delta * (before.ticks - tick) + ); const sol1 = (-val0 + k) / delta; const sol2 = (-val0 - k) / delta; return (sol1 > 0 ? sol1 : sol2) + before.time; @@ -249,7 +290,7 @@ export class TickParam extends Param */ protected _toType(val: number): UnitMap[TypeName] { if (this.units === "bpm" && this.multiplier) { - return (val / this.multiplier) * 60 as UnitMap[TypeName]; + return ((val / this.multiplier) * 60) as UnitMap[TypeName]; } else { return super._toType(val); } diff --git a/Tone/core/clock/TickSignal.test.ts b/Tone/core/clock/TickSignal.test.ts index c115e605..456c56e7 100644 --- a/Tone/core/clock/TickSignal.test.ts +++ b/Tone/core/clock/TickSignal.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { TickSignal } from "./TickSignal"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { TickSignal } from "./TickSignal.js"; describe("TickSignal", () => { - BasicTests(TickSignal); it("can be created and disposed", () => { @@ -297,7 +296,7 @@ describe("TickSignal", () => { return Offline((context) => { const sched = new TickSignal(1).connect(context.destination); sched.linearRampTo(3, 1, 0); - }, 1.01).then(buffer => { + }, 1.01).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(1, 0.01); expect(buffer.getValueAtTime(0.5)).to.be.closeTo(2, 0.01); expect(buffer.getValueAtTime(1)).to.be.closeTo(3, 0.01); @@ -311,7 +310,7 @@ describe("TickSignal", () => { value: 120, }).connect(context.destination); sched.linearRampTo(60, 1, 0); - }, 1.01).then(buffer => { + }, 1.01).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(2, 0.01); expect(buffer.getValueAtTime(0.5)).to.be.closeTo(1.5, 0.01); expect(buffer.getValueAtTime(1)).to.be.closeTo(1, 0.01); @@ -326,7 +325,7 @@ describe("TickSignal", () => { value: 60, }).connect(context.destination); sched.linearRampTo(120, 1, 0); - }, 1.01).then(buffer => { + }, 1.01).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(10, 0.01); expect(buffer.getValueAtTime(0.5)).to.be.closeTo(15, 0.01); expect(buffer.getValueAtTime(1)).to.be.closeTo(20, 0.01); @@ -334,13 +333,21 @@ describe("TickSignal", () => { }); context("Ticks <-> Time", () => { - it("converts from time to ticks", () => { return Offline(() => { const tickSignal = new TickSignal(20); - expect(tickSignal.ticksToTime(20, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.ticksToTime(10, 0).valueOf()).to.be.closeTo(0.5, 0.01); - expect(tickSignal.ticksToTime(10, 10).valueOf()).to.be.closeTo(0.5, 0.01); + expect(tickSignal.ticksToTime(20, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.ticksToTime(10, 0).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); + expect(tickSignal.ticksToTime(10, 10).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); tickSignal.dispose(); }); }); @@ -349,10 +356,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.linearRampTo(2, 2, 1); - expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo(0.82, 0.01); - expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo(1.82, 0.01); - expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo(0.5, 0.01); + expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo( + 0.82, + 0.01 + ); + expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo( + 1.82, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); tickSignal.dispose(); }); }); @@ -361,11 +380,26 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.setValueAtTime(2, 1); - expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo(0.5, 0.01); - expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo(1.5, 0.01); - expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo(0.5, 0.01); - expect(tickSignal.ticksToTime(1, 0.5).valueOf()).to.be.closeTo(0.75, 0.01); + expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); + expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo( + 1.5, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 0.5).valueOf()).to.be.closeTo( + 0.75, + 0.01 + ); tickSignal.dispose(); }); }); @@ -374,10 +408,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.exponentialRampTo(2, 1, 1); - expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo(0.75, 0.01); - expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo(1.75, 0.01); - expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo(0.5, 0.01); + expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo( + 0.75, + 0.01 + ); + expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo( + 1.75, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo( + 0.5, + 0.01 + ); tickSignal.dispose(); }); }); @@ -386,10 +432,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.setTargetAtTime(2, 1, 1); - expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo(0.79, 0.01); - expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo(1.79, 0.01); - expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo(0.61, 0.01); + expect(tickSignal.ticksToTime(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 1).valueOf()).to.be.closeTo( + 0.79, + 0.01 + ); + expect(tickSignal.ticksToTime(2, 0).valueOf()).to.be.closeTo( + 1.79, + 0.01 + ); + expect(tickSignal.ticksToTime(1, 3).valueOf()).to.be.closeTo( + 0.61, + 0.01 + ); tickSignal.dispose(); }); }); @@ -397,9 +455,18 @@ describe("TickSignal", () => { it("converts from ticks to time", () => { return Offline(() => { const tickSignal = new TickSignal(20); - expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo(20, 0.01); - expect(tickSignal.timeToTicks(0.5, 0).valueOf()).to.be.closeTo(10, 0.01); - expect(tickSignal.timeToTicks(0.5, 2).valueOf()).to.be.closeTo(10, 0.01); + expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo( + 20, + 0.01 + ); + expect(tickSignal.timeToTicks(0.5, 0).valueOf()).to.be.closeTo( + 10, + 0.01 + ); + expect(tickSignal.timeToTicks(0.5, 2).valueOf()).to.be.closeTo( + 10, + 0.01 + ); tickSignal.dispose(); }); }); @@ -408,10 +475,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.setValueAtTime(2, 1); - expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo(2, 0.01); - expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo(2, 0.01); - expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo(1.5, 0.01); + expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo( + 2, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo( + 2, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo( + 1.5, + 0.01 + ); tickSignal.dispose(); }); }); @@ -420,10 +499,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.linearRampTo(2, 1, 1); - expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo(1.5, 0.01); - expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo(2, 0.01); - expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo(1.12, 0.01); + expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo( + 1.5, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo( + 2, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo( + 1.12, + 0.01 + ); tickSignal.dispose(); }); }); @@ -432,10 +523,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.exponentialRampTo(2, 1, 1); - expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo(1.44, 0.01); - expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo(2, 0.01); - expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo(1.09, 0.01); + expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo( + 1.44, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo( + 2, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo( + 1.09, + 0.01 + ); tickSignal.dispose(); }); }); @@ -444,10 +547,22 @@ describe("TickSignal", () => { return Offline(() => { const tickSignal = new TickSignal(1); tickSignal.setTargetAtTime(2, 1, 1); - expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo(1, 0.01); - expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo(1.31, 0.01); - expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo(1.63, 0.01); - expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo(1.07, 0.01); + expect(tickSignal.timeToTicks(1, 0).valueOf()).to.be.closeTo( + 1, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 1).valueOf()).to.be.closeTo( + 1.31, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 2).valueOf()).to.be.closeTo( + 1.63, + 0.01 + ); + expect(tickSignal.timeToTicks(1, 0.5).valueOf()).to.be.closeTo( + 1.07, + 0.01 + ); tickSignal.dispose(); }); }); diff --git a/Tone/core/clock/TickSignal.ts b/Tone/core/clock/TickSignal.ts index dd1a49cb..9cccff77 100644 --- a/Tone/core/clock/TickSignal.ts +++ b/Tone/core/clock/TickSignal.ts @@ -1,10 +1,11 @@ -import { Signal, SignalOptions } from "../../signal/Signal"; -import { InputNode } from "../context/ToneAudioNode"; -import { Seconds, Ticks, Time, UnitMap, UnitName } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { TickParam } from "./TickParam"; +import { Signal, SignalOptions } from "../../signal/Signal.js"; +import { InputNode } from "../context/ToneAudioNode.js"; +import { Seconds, Ticks, Time, UnitMap, UnitName } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { TickParam } from "./TickParam.js"; -interface TickSignalOptions extends SignalOptions { +interface TickSignalOptions + extends SignalOptions { value: UnitMap[TypeName]; multiplier: number; } @@ -18,8 +19,9 @@ interface TickSignalOptions extends SignalOptions extends Signal { - +export class TickSignal< + TypeName extends "hertz" | "bpm", +> extends Signal { readonly name: string = "TickSignal"; /** @@ -34,9 +36,14 @@ export class TickSignal extends Signal>); constructor() { - - super(optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"])); - const options = optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]); + super( + optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]) + ); + const options = optionsFromArguments( + TickSignal.getDefaults(), + arguments, + ["value"] + ); this.input = this._param = new TickParam({ context: this.context, diff --git a/Tone/core/clock/TickSource.test.ts b/Tone/core/clock/TickSource.test.ts index 201dc715..cbf7c7f9 100644 --- a/Tone/core/clock/TickSource.test.ts +++ b/Tone/core/clock/TickSource.test.ts @@ -1,14 +1,12 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { TickSource } from "./TickSource"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { TickSource } from "./TickSource.js"; describe("TickSource", () => { - BasicTests(TickSource); context("Constructor", () => { - it("can pass in the frequency", () => { const source = new TickSource(2); expect(source.frequency.value).to.equal(2); @@ -23,7 +21,6 @@ describe("TickSource", () => { }); context("Ticks", () => { - it("ticks are 0 before started", () => { const source = new TickSource(); expect(source.ticks).to.equal(0); @@ -42,7 +39,7 @@ describe("TickSource", () => { return Offline(() => { const source = new TickSource(); source.start(0); - return time => { + return (time) => { expect(source.ticks).to.be.closeTo(time, 0.1); }; }, 0.5); @@ -52,7 +49,7 @@ describe("TickSource", () => { return Offline(() => { const source = new TickSource(2); source.start(0).stop(0.4); - return time => { + return (time) => { if (time < 0.399) { expect(source.ticks).to.be.closeTo(2 * time, 0.01); } else if (time > 0.4) { @@ -67,7 +64,7 @@ describe("TickSource", () => { const source = new TickSource(2); source.start(0).pause(0.4); let pausedTicks = -1; - return time => { + return (time) => { if (time < 0.4) { pausedTicks = source.ticks; expect(source.ticks).to.be.closeTo(2 * time, 0.01); @@ -269,7 +266,6 @@ describe("TickSource", () => { }); context("forEachTickBetween", () => { - it("invokes a callback function when started", () => { const source = new TickSource(1); source.start(0); @@ -296,7 +292,9 @@ describe("TickSource", () => { const source = new TickSource(4); source.start(0.2).pause(2).start(3.5).stop(5); let iterations = 0; - const expectedTimes = [1.2, 1.45, 1.7, 1.95, 3.5, 3.75, 4, 4.25, 4.5, 4.75]; + const expectedTimes = [ + 1.2, 1.45, 1.7, 1.95, 3.5, 3.75, 4, 4.25, 4.5, 4.75, + ]; const expectedTicks = [4, 5, 6, 7, 7, 8, 9, 10, 11, 12]; source.forEachTickBetween(1, 7, (time, ticks) => { expect(time).to.be.closeTo(expectedTimes[iterations], 0.001); @@ -401,7 +399,7 @@ describe("TickSource", () => { source.start(0.5).stop(2).start(2.5).stop(4.1); let iterations = 0; const times = [0.5, 1.0, 1.5, 2.5, 3, 3.5, 4]; - source.forEachTickBetween(0, 10, time => { + source.forEachTickBetween(0, 10, (time) => { expect(times[iterations]).to.be.closeTo(time, 0.001); iterations++; }); @@ -415,7 +413,7 @@ describe("TickSource", () => { source.frequency.linearRampToValueAtTime(4, 1); source.start(0.5); let iterations = 0; - const times = [0.500, 0.833, 1.094, 1.344, 1.594, 1.844]; + const times = [0.5, 0.833, 1.094, 1.344, 1.594, 1.844]; source.forEachTickBetween(0, 2, (time, ticks) => { expect(time).to.be.closeTo(times[ticks], 0.001); iterations++; @@ -471,7 +469,7 @@ describe("TickSource", () => { source.start(0.5); let iterations = 0; let lastTime = 0.5; - source.forEachTickBetween(0.51, 2.01, time => { + source.forEachTickBetween(0.51, 2.01, (time) => { expect(time - lastTime).to.be.closeTo(0.05, 0.001); lastTime = time; iterations++; @@ -545,15 +543,13 @@ describe("TickSource", () => { }); source.dispose(); }); - }); context("Seconds", () => { - it("get the elapsed time in seconds", () => { return Offline(() => { const source = new TickSource(1).start(0); - return time => { + return (time) => { expect(source.seconds).to.be.closeTo(time, 0.01); }; }, 2); @@ -563,14 +559,12 @@ describe("TickSource", () => { const source = new TickSource(1); expect(source.seconds).to.be.closeTo(0, 0.001); source.dispose(); - }); it("can set the seconds", () => { const source = new TickSource(1); expect(source.seconds).to.be.closeTo(0, 0.001); source.dispose(); - }); it("seconds pauses at last second count", () => { @@ -599,7 +593,7 @@ describe("TickSource", () => { it("get the elapsed time in seconds when starting in the future", () => { return Offline(() => { const source = new TickSource(1).start(0.1); - return time => { + return (time) => { if (time < 0.1) { expect(source.seconds).to.be.closeTo(0, 0.001); } else { @@ -610,7 +604,11 @@ describe("TickSource", () => { }); it("handles multiple starts and stops", () => { - const source = new TickSource(1).start(0).stop(0.5).start(1).stop(1.5); + const source = new TickSource(1) + .start(0) + .stop(0.5) + .start(1) + .stop(1.5); expect(source.getSecondsAtTime(0)).to.be.closeTo(0, 0.01); expect(source.getSecondsAtTime(0.4)).to.be.closeTo(0.4, 0.01); expect(source.getSecondsAtTime(0.5)).to.be.closeTo(0, 0.01); @@ -646,7 +644,6 @@ describe("TickSource", () => { }); context("Frequency", () => { - it("can automate frequency with setValueAtTime", () => { const source = new TickSource(1); source.start(0).stop(0.3).start(0.4).stop(0.5).start(0.6); @@ -703,5 +700,4 @@ describe("TickSource", () => { source.dispose(); }); }); - }); diff --git a/Tone/core/clock/TickSource.ts b/Tone/core/clock/TickSource.ts index 223f5e83..490acf42 100644 --- a/Tone/core/clock/TickSource.ts +++ b/Tone/core/clock/TickSource.ts @@ -1,12 +1,19 @@ -import { ToneWithContext, ToneWithContextOptions } from "../context/ToneWithContext"; -import { Seconds, Ticks, Time } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { readOnly } from "../util/Interface"; -import { PlaybackState, StateTimeline, StateTimelineEvent } from "../util/StateTimeline"; -import { Timeline, TimelineEvent } from "../util/Timeline"; -import { isDefined } from "../util/TypeCheck"; -import { TickSignal } from "./TickSignal"; -import { EQ } from "../util/Math"; +import { + ToneWithContext, + ToneWithContextOptions, +} from "../context/ToneWithContext.js"; +import { Seconds, Ticks, Time } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { readOnly } from "../util/Interface.js"; +import { + PlaybackState, + StateTimeline, + StateTimelineEvent, +} from "../util/StateTimeline.js"; +import { Timeline, TimelineEvent } from "../util/Timeline.js"; +import { isDefined } from "../util/TypeCheck.js"; +import { TickSignal } from "./TickSignal.js"; +import { EQ } from "../util/Math.js"; interface TickSourceOptions extends ToneWithContextOptions { frequency: number; @@ -34,8 +41,9 @@ interface TickSourceSecondsAtTimeEvent extends TimelineEvent { /** * Uses [TickSignal](TickSignal) to track elapsed ticks with complex automation curves. */ -export class TickSource extends ToneWithContext { - +export class TickSource< + TypeName extends "bpm" | "hertz", +> extends ToneWithContext { readonly name: string = "TickSource"; /** @@ -56,12 +64,14 @@ export class TickSource extends ToneWithContex /** * Memoized values of getTicksAtTime at events with state other than "started" */ - private _ticksAtTime: Timeline = new Timeline(); + private _ticksAtTime: Timeline = + new Timeline(); /** * Memoized values of getSecondsAtTime at events with state other than "started" */ - private _secondsAtTime: Timeline = new Timeline(); + private _secondsAtTime: Timeline = + new Timeline(); /** * @param frequency The initial frequency that the signal ticks at @@ -69,8 +79,16 @@ export class TickSource extends ToneWithContex constructor(frequency?: number); constructor(options?: Partial); constructor() { - super(optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"])); - const options = optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]); + super( + optionsFromArguments(TickSource.getDefaults(), arguments, [ + "frequency", + ]) + ); + const options = optionsFromArguments( + TickSource.getDefaults(), + arguments, + ["frequency"] + ); this.frequency = new TickSignal({ context: this.context, @@ -86,10 +104,13 @@ export class TickSource extends ToneWithContex } static getDefaults(): TickSourceOptions { - return Object.assign({ - frequency: 1, - units: "hertz" as const, - }, ToneWithContext.getDefaults()); + return Object.assign( + { + frequency: 1, + units: "hertz" as const, + }, + ToneWithContext.getDefaults() + ); } /** @@ -174,38 +195,54 @@ export class TickSource extends ToneWithContex */ getTicksAtTime(time?: Time): Ticks { const computedTime = this.toSeconds(time); - const stopEvent = this._state.getLastState("stopped", computedTime) as StateTimelineEvent; + const stopEvent = this._state.getLastState( + "stopped", + computedTime + ) as StateTimelineEvent; // get previously memoized ticks if available const memoizedEvent = this._ticksAtTime.get(computedTime); // this event allows forEachBetween to iterate until the current time - const tmpEvent: StateTimelineEvent = { state: "paused", time: computedTime }; + const tmpEvent: StateTimelineEvent = { + state: "paused", + time: computedTime, + }; this._state.add(tmpEvent); // keep track of the previous offset event let lastState = memoizedEvent ? memoizedEvent : stopEvent; let elapsedTicks = memoizedEvent ? memoizedEvent.ticks : 0; - let eventToMemoize : TickSourceTicksAtTimeEvent | null = null; + let eventToMemoize: TickSourceTicksAtTimeEvent | null = null; // iterate through all the events since the last stop - this._state.forEachBetween(lastState.time, computedTime + this.sampleTime, e => { - let periodStartTime = lastState.time; - // if there is an offset event in this period use that - const offsetEvent = this._tickOffset.get(e.time); - if (offsetEvent && offsetEvent.time >= lastState.time) { - elapsedTicks = offsetEvent.ticks; - periodStartTime = offsetEvent.time; - } - if (lastState.state === "started" && e.state !== "started") { - elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime); - // do not memoize the temporary event - if (e.time !== tmpEvent.time) { - eventToMemoize = { state: e.state, time: e.time, ticks: elapsedTicks }; + this._state.forEachBetween( + lastState.time, + computedTime + this.sampleTime, + (e) => { + let periodStartTime = lastState.time; + // if there is an offset event in this period use that + const offsetEvent = this._tickOffset.get(e.time); + if (offsetEvent && offsetEvent.time >= lastState.time) { + elapsedTicks = offsetEvent.ticks; + periodStartTime = offsetEvent.time; } + if (lastState.state === "started" && e.state !== "started") { + elapsedTicks += + this.frequency.getTicksAtTime(e.time) - + this.frequency.getTicksAtTime(periodStartTime); + // do not memoize the temporary event + if (e.time !== tmpEvent.time) { + eventToMemoize = { + state: e.state, + time: e.time, + ticks: elapsedTicks, + }; + } + } + lastState = e; } - lastState = e; - }); + ); // remove the temporary event this._state.remove(tmpEvent); @@ -250,7 +287,10 @@ export class TickSource extends ToneWithContex */ getSecondsAtTime(time: Time): Seconds { time = this.toSeconds(time); - const stopEvent = this._state.getLastState("stopped", time) as StateTimelineEvent; + const stopEvent = this._state.getLastState( + "stopped", + time + ) as StateTimelineEvent; // this event allows forEachBetween to iterate until the current time const tmpEvent: StateTimelineEvent = { state: "paused", time }; this._state.add(tmpEvent); @@ -261,26 +301,34 @@ export class TickSource extends ToneWithContex // keep track of the previous offset event let lastState = memoizedEvent ? memoizedEvent : stopEvent; let elapsedSeconds = memoizedEvent ? memoizedEvent.seconds : 0; - let eventToMemoize : TickSourceSecondsAtTimeEvent | null = null; + let eventToMemoize: TickSourceSecondsAtTimeEvent | null = null; // iterate through all the events since the last stop - this._state.forEachBetween(lastState.time, time + this.sampleTime, e => { - let periodStartTime = lastState.time; - // if there is an offset event in this period use that - const offsetEvent = this._tickOffset.get(e.time); - if (offsetEvent && offsetEvent.time >= lastState.time) { - elapsedSeconds = offsetEvent.seconds; - periodStartTime = offsetEvent.time; - } - if (lastState.state === "started" && e.state !== "started") { - elapsedSeconds += e.time - periodStartTime; - // do not memoize the temporary event - if (e.time !== tmpEvent.time) { - eventToMemoize = { state: e.state, time: e.time, seconds: elapsedSeconds }; + this._state.forEachBetween( + lastState.time, + time + this.sampleTime, + (e) => { + let periodStartTime = lastState.time; + // if there is an offset event in this period use that + const offsetEvent = this._tickOffset.get(e.time); + if (offsetEvent && offsetEvent.time >= lastState.time) { + elapsedSeconds = offsetEvent.seconds; + periodStartTime = offsetEvent.time; + } + if (lastState.state === "started" && e.state !== "started") { + elapsedSeconds += e.time - periodStartTime; + // do not memoize the temporary event + if (e.time !== tmpEvent.time) { + eventToMemoize = { + state: e.state, + time: e.time, + seconds: elapsedSeconds, + }; + } } + lastState = e; } - lastState = e; - }); + ); // remove the temporary event this._state.remove(tmpEvent); @@ -333,7 +381,8 @@ export class TickSource extends ToneWithContex const offset = this._tickOffset.get(before) as TickSourceOffsetEvent; const event = this._state.get(before) as StateTimelineEvent; const startTime = Math.max(offset.time, event.time); - const absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks; + const absoluteTicks = + this.frequency.getTicksAtTime(startTime) + tick - offset.ticks; return this.frequency.getTimeOfTick(absoluteTicks); } @@ -344,12 +393,24 @@ export class TickSource extends ToneWithContex * @param endTime The end of the search range * @param callback The callback to invoke with each tick */ - forEachTickBetween(startTime: number, endTime: number, callback: (when: Seconds, ticks: Ticks) => void): this { + forEachTickBetween( + startTime: number, + endTime: number, + callback: (when: Seconds, ticks: Ticks) => void + ): this { // only iterate through the sections where it is "started" let lastStateEvent = this._state.get(startTime); - this._state.forEachBetween(startTime, endTime, event => { - if (lastStateEvent && lastStateEvent.state === "started" && event.state !== "started") { - this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback); + this._state.forEachBetween(startTime, endTime, (event) => { + if ( + lastStateEvent && + lastStateEvent.state === "started" && + event.state !== "started" + ) { + this.forEachTickBetween( + Math.max(lastStateEvent.time, startTime), + event.time - this.sampleTime, + callback + ); } lastStateEvent = event; }); @@ -360,20 +421,30 @@ export class TickSource extends ToneWithContex const maxStartTime = Math.max(lastStateEvent.time, startTime); // figure out the difference between the frequency ticks and the const startTicks = this.frequency.getTicksAtTime(maxStartTime); - const ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time); + const ticksAtStart = this.frequency.getTicksAtTime( + lastStateEvent.time + ); const diff = startTicks - ticksAtStart; let offset = Math.ceil(diff) - diff; // guard against floating point issues offset = EQ(offset, 1) ? 0 : offset; - let nextTickTime = this.frequency.getTimeOfTick(startTicks + offset); + let nextTickTime = this.frequency.getTimeOfTick( + startTicks + offset + ); while (nextTickTime < endTime) { try { - callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime))); + callback( + nextTickTime, + Math.round(this.getTicksAtTime(nextTickTime)) + ); } catch (e) { error = e; break; } - nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime); + nextTickTime += this.frequency.getDurationOfTicks( + 1, + nextTickTime + ); } } diff --git a/Tone/core/clock/Ticker.test.ts b/Tone/core/clock/Ticker.test.ts index d90f1a38..145a429c 100644 --- a/Tone/core/clock/Ticker.test.ts +++ b/Tone/core/clock/Ticker.test.ts @@ -1,9 +1,7 @@ import { expect } from "chai"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { Ticker } from "./Ticker"; +import { Ticker } from "./Ticker.js"; describe("Ticker", () => { - function empty(): void { // do nothing } @@ -31,56 +29,69 @@ describe("Ticker", () => { ticker.dispose(); }); - if (ONLINE_TESTING) { - - context("timeout", () => { - - it("provides a callback when set to timeout", done => { - const ticker = new Ticker(() => { + context("timeout", () => { + it("provides a callback when set to timeout", (done) => { + const ticker = new Ticker( + () => { ticker.dispose(); done(); - }, "timeout", 0.01); - }); + }, + "timeout", + 0.01 + ); + }); - it("can adjust the interval when set to timeout", (done) => { - const ticker = new Ticker(() => { + it("can adjust the interval when set to timeout", (done) => { + const ticker = new Ticker( + () => { ticker.dispose(); done(); - }, "timeout", 0.01); - ticker.updateInterval = 0.1; - }); + }, + "timeout", + 0.01 + ); + ticker.updateInterval = 0.1; }); - } + }); context("worker", () => { - - it("provides a callback when set to worker", done => { - const ticker = new Ticker(() => { - ticker.dispose(); - done(); - }, "worker", 0.01); + it("provides a callback when set to worker", (done) => { + const ticker = new Ticker( + () => { + ticker.dispose(); + done(); + }, + "worker", + 0.01 + ); }); - it("falls back to timeout if the constructor throws an error", done => { + it("falls back to timeout if the constructor throws an error", (done) => { const URL = window.URL; // @ts-ignore window.URL = null; - const ticker = new Ticker(() => { - expect(ticker.type).to.equal("timeout"); - ticker.dispose(); - window.URL = URL; - done(); - }, "worker", 0.01); - + const ticker = new Ticker( + () => { + expect(ticker.type).to.equal("timeout"); + ticker.dispose(); + window.URL = URL; + done(); + }, + "worker", + 0.01 + ); }); it("can adjust the interval when set to worker", (done) => { - const ticker = new Ticker(() => { - ticker.dispose(); - done(); - }, "worker", 0.01); + const ticker = new Ticker( + () => { + ticker.dispose(); + done(); + }, + "worker", + 0.01 + ); ticker.updateInterval = 0.1; }); - }); }); diff --git a/Tone/core/clock/Ticker.ts b/Tone/core/clock/Ticker.ts index 51b97410..ef8d4e11 100644 --- a/Tone/core/clock/Ticker.ts +++ b/Tone/core/clock/Ticker.ts @@ -1,4 +1,4 @@ -import { Seconds } from "../type/Units"; +import { Seconds } from "../type/Units.js"; export type TickerClockSource = "worker" | "timeout" | "offline"; @@ -7,7 +7,6 @@ export type TickerClockSource = "worker" | "timeout" | "offline"; * a Web Worker, or if that isn't supported, falls back to setTimeout. */ export class Ticker { - /** * Either "worker" or "timeout" or "offline" */ @@ -38,11 +37,18 @@ export class Ticker { */ private _worker!: Worker; - constructor(callback: () => void, type: TickerClockSource, updateInterval: Seconds, contextSampleRate?: number) { - + constructor( + callback: () => void, + type: TickerClockSource, + updateInterval: Seconds, + contextSampleRate?: number + ) { this._callback = callback; this._type = type; - this._minimumUpdateInterval = Math.max(128/(contextSampleRate || 44100), .001); + this._minimumUpdateInterval = Math.max( + 128 / (contextSampleRate || 44100), + 0.001 + ); this.updateInterval = updateInterval; // create the clock source for the first time @@ -53,9 +59,9 @@ export class Ticker { * Generate a web worker */ private _createWorker(): void { - - const blob = new Blob([ - /* javascript */` + const blob = new Blob( + [ + /* javascript */ ` // the initial timeout time let timeoutTime = ${(this._updateInterval * 1000).toFixed(1)}; // onmessage callback @@ -70,8 +76,10 @@ export class Ticker { } // call tick initially tick(); - ` - ], { type: "text/javascript" }); + `, + ], + { type: "text/javascript" } + ); const blobUrl = URL.createObjectURL(blob); const worker = new Worker(blobUrl); diff --git a/Tone/core/clock/Transport.test.ts b/Tone/core/clock/Transport.test.ts index 493598ed..b437f395 100644 --- a/Tone/core/clock/Transport.test.ts +++ b/Tone/core/clock/Transport.test.ts @@ -1,19 +1,17 @@ import { expect } from "chai"; -import { atTime, Offline, whenBetween } from "test/helper/Offline"; -import { Time } from "Tone/core/type/Time"; -import { noOp } from "Tone/core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { TransportTime } from "../type/TransportTime"; -import { TransportClass } from "./Transport"; +import { atTime, Offline, whenBetween } from "../../../test/helper/Offline.js"; +import { Time } from "../type/Time.js"; +import { noOp } from "../util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { TransportTime } from "../type/TransportTime.js"; +import { TransportClass } from "./Transport.js"; // importing for side affects -import "../context/Destination"; -import { warns } from "test/helper/Basic"; -import { Synth } from "Tone/instrument/Synth"; +import "../context/Destination.js"; +import { warns } from "../../../test/helper/Basic.js"; +import { Synth } from "../../instrument/Synth.js"; describe("Transport", () => { - context("BPM and timeSignature", () => { - it("can get and set bpm", () => { return Offline((context) => { const transport = new TransportClass({ context }); @@ -43,11 +41,9 @@ describe("Transport", () => { expect(transport.timeSignature).to.equal(5); }); }); - }); context("looping", () => { - it("can get and set loop points", () => { return Offline((context) => { const transport = new TransportClass({ context }); @@ -57,7 +53,10 @@ describe("Transport", () => { expect(transport.loopEnd).to.be.closeTo(0.4, 0.01); transport.setLoopPoints(0, "1m"); expect(transport.loopStart).to.be.closeTo(0, 0.01); - expect(transport.loopEnd).to.be.closeTo(transport.toSeconds("1m"), 0.01); + expect(transport.loopEnd).to.be.closeTo( + transport.toSeconds("1m"), + 0.01 + ); }); }); @@ -90,42 +89,53 @@ describe("Transport", () => { expect(looped).to.equal(true); }); }); - }); context("nextSubdivision", () => { - it("returns 0 if the transports not started", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.nextSubdivision()).to.equal(0); }); }); it("can get the next subdivision of the transport", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0); - return time => { + return (time) => { whenBetween(time, 0.05, 0.07, () => { - expect(transport.nextSubdivision(0.5)).to.be.closeTo(0.5, 0.01); - expect(transport.nextSubdivision(0.04)).to.be.closeTo(0.08, 0.01); - expect(transport.nextSubdivision(2)).to.be.closeTo(2, 0.01); + expect(transport.nextSubdivision(0.5)).to.be.closeTo( + 0.5, + 0.01 + ); + expect(transport.nextSubdivision(0.04)).to.be.closeTo( + 0.08, + 0.01 + ); + expect(transport.nextSubdivision(2)).to.be.closeTo( + 2, + 0.01 + ); }); whenBetween(time, 0.09, 0.1, () => { - expect(transport.nextSubdivision(0.04)).to.be.closeTo(0.12, 0.01); - expect(transport.nextSubdivision("8n")).to.be.closeTo(0.25, 0.01); + expect(transport.nextSubdivision(0.04)).to.be.closeTo( + 0.12, + 0.01 + ); + expect(transport.nextSubdivision("8n")).to.be.closeTo( + 0.25, + 0.01 + ); }); }; }, 0.1); }); - }); context("PPQ", () => { - it("can get and set pulses per quarter", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.PPQ = 96; expect(transport.PPQ).to.equal(96); @@ -133,10 +143,10 @@ describe("Transport", () => { }); it("schedules a quarter note at the same time with a different PPQ", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.PPQ = 1; - const id = transport.schedule(time => { + const id = transport.schedule((time) => { expect(time).to.be.closeTo(transport.toSeconds("4n"), 0.1); transport.clear(id); }, "4n"); @@ -145,27 +155,25 @@ describe("Transport", () => { }); it("invokes the right number of ticks with a different PPQ", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.bpm.value = 120; const ppq = 20; transport.PPQ = ppq; transport.start(); - return time => { + return (time) => { if (time > 0.5) { expect(transport.ticks).to.be.within(ppq, ppq * 1.2); } }; }, 0.55); }); - }); context("position", () => { - it("can jump to a specific tick number", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.ticks = 200; expect(transport.ticks).to.equal(200); @@ -181,7 +189,7 @@ describe("Transport", () => { }); it("can get the current position in BarsBeatsSixteenths", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.position).to.equal("0:0:0"); transport.start(0); @@ -192,34 +200,40 @@ describe("Transport", () => { }); it("can get the current position in seconds", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.start(0.05); - return time => { + return (time) => { if (time > 0.05) { - expect(transport.seconds).to.be.closeTo(time - 0.05, 0.01); + expect(transport.seconds).to.be.closeTo( + time - 0.05, + 0.01 + ); } }; }, 0.1); }); it("can get the current position in seconds during a bpm ramp", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.start(0.05); transport.bpm.linearRampTo(60, 0.5, 0.5); - return time => { + return (time) => { if (time > 0.05) { - expect(transport.seconds).to.be.closeTo(time - 0.05, 0.01); + expect(transport.seconds).to.be.closeTo( + time - 0.05, + 0.01 + ); } }; }, 0.7); }); it("can set the current position in seconds", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.seconds).to.equal(0); transport.seconds = 3; @@ -228,7 +242,7 @@ describe("Transport", () => { }); it("can set the current position in BarsBeatsSixteenths", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); expect(transport.position).to.equal("0:0:0"); transport.position = "3:0"; @@ -239,14 +253,15 @@ describe("Transport", () => { }); it("can get the progress of the loop", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.setLoopPoints(0, "1m").start(); transport.loop = true; expect(transport.progress).to.be.equal(0); transport.position = "2n"; expect(transport.progress).to.be.closeTo(0.5, 0.001); - transport.position = Time("2n").valueOf() + Time("4n").valueOf(); + transport.position = + Time("2n").valueOf() + Time("4n").valueOf(); expect(transport.progress).to.be.closeTo(0.75, 0.001); }); }); @@ -260,28 +275,26 @@ describe("Transport", () => { }); }, 0.2); }); - }); context("state", () => { - it("can start, pause, and restart", () => { return Offline(({ transport }) => { transport.start(0).pause(0.2).start(0.4); const pulse = new Signal(0).toDestination(); - transport.schedule(time => { + transport.schedule((time) => { pulse.setValueAtTime(1, time); pulse.setValueAtTime(0, time + 0.1); }, 0); - transport.schedule(time => { + transport.schedule((time) => { pulse.setValueAtTime(1, time); pulse.setValueAtTime(0, time + 0.1); }, 0.3); - return time => { + return (time) => { whenBetween(time, 0, 0.2, () => { expect(transport.state).to.equal("started"); }); @@ -294,8 +307,7 @@ describe("Transport", () => { expect(transport.state).to.equal("started"); }); }; - }, 0.6).then(buffer => { - + }, 0.6).then((buffer) => { buffer.forEach((sample, time) => { whenBetween(time, 0, 0.01, () => { expect(sample).to.equal(1); @@ -309,32 +321,37 @@ describe("Transport", () => { }); }); }); - }); context("ticks", () => { - it("resets ticks on stop but not on pause", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0).pause(0.1).stop(0.2); - expect(transport.getTicksAtTime(0)).to.be.equal(Math.floor(transport.PPQ * 0)); - expect(transport.getTicksAtTime(0.05)).to.be.equal(Math.floor(transport.PPQ * 0.1)); - expect(transport.getTicksAtTime(0.1)).to.be.equal(Math.floor(transport.PPQ * 0.2)); - expect(transport.getTicksAtTime(0.15)).to.be.equal(Math.floor(transport.PPQ * 0.2)); + expect(transport.getTicksAtTime(0)).to.be.equal( + Math.floor(transport.PPQ * 0) + ); + expect(transport.getTicksAtTime(0.05)).to.be.equal( + Math.floor(transport.PPQ * 0.1) + ); + expect(transport.getTicksAtTime(0.1)).to.be.equal( + Math.floor(transport.PPQ * 0.2) + ); + expect(transport.getTicksAtTime(0.15)).to.be.equal( + Math.floor(transport.PPQ * 0.2) + ); expect(transport.getTicksAtTime(0.2)).to.be.equal(0); }, 0.3); }); it("tracks ticks after start", () => { - - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.bpm.value = 120; const ppq = transport.PPQ; transport.start(); - return time => { + return (time) => { if (time > 0.5) { expect(transport.ticks).to.at.least(ppq); } @@ -343,11 +360,11 @@ describe("Transport", () => { }); it("can start with a tick offset", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0, "200i"); - return time => { + return (time) => { if (time < 0.01) { expect(transport.ticks).to.at.least(200); } @@ -356,12 +373,12 @@ describe("Transport", () => { }); it("can toggle the state of the transport", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.toggle(0); transport.toggle(0.2); - return time => { + return (time) => { whenBetween(time, 0, 0.2, () => { expect(transport.state).to.equal("started"); }); @@ -374,14 +391,13 @@ describe("Transport", () => { }); it("tracks ticks correctly with a different PPQ and BPM", () => { - - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.PPQ = 96; transport.bpm.value = 90; transport.start(); - return time => { + return (time) => { if (time > 0.5) { expect(transport.ticks).to.at.least(72); } @@ -394,7 +410,7 @@ describe("Transport", () => { const times = [0, 1.5]; return Offline(({ transport }) => { transport.PPQ = 1; - transport.schedule(time => { + transport.schedule((time) => { expect(time).to.be.closeTo(times[invocations], 0.01); invocations++; }, 0); @@ -406,25 +422,23 @@ describe("Transport", () => { expect(invocations).to.equal(2); }); }); - }); context("schedule", () => { - it("can schedule an event on the timeline", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - const eventID = transport.schedule(() => { }, 0); + const eventID = transport.schedule(() => {}, 0); expect(eventID).to.be.a("number"); }); }); it("scheduled event gets invoked with the time of the event", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; - transport.schedule(time => { + transport.schedule((time) => { expect(time).to.be.closeTo(startTime, 0.01); wasCalled = true; }, 0); @@ -436,11 +450,11 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); - transport.schedule(time => { + transport.schedule((time) => { expect(time).to.be.closeTo(startTime + eighth, 0.01); wasCalled = true; }, TransportTime("8n")); @@ -451,7 +465,7 @@ describe("Transport", () => { }); it("can clear a scheduled event", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const eventID = transport.schedule(() => { throw new Error("should not call this function"); @@ -462,7 +476,7 @@ describe("Transport", () => { }); it("can cancel the timeline of scheduled object", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.schedule(() => { throw new Error("should not call this"); @@ -473,7 +487,7 @@ describe("Transport", () => { }); it("can cancel the timeline of scheduleOnce object", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.scheduleOnce(() => { throw new Error("should not call this"); @@ -485,10 +499,10 @@ describe("Transport", () => { it("scheduled event anywhere along the timeline", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = transport.now(); - transport.schedule(time => { + transport.schedule((time) => { expect(time).to.be.closeTo(startTime + 0.5, 0.001); wasCalled = true; }, 0.5); @@ -500,7 +514,7 @@ describe("Transport", () => { it("can schedule multiple events and invoke them in the right order", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); let first = false; transport.schedule(() => { @@ -518,7 +532,7 @@ describe("Transport", () => { it("invokes the event again if the timeline is restarted", () => { let iterations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.schedule(() => { iterations++; @@ -531,11 +545,11 @@ describe("Transport", () => { it("can add an event after the Transport is started", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; - return time => { + return (time) => { if (time > 0.1 && !wasScheduled) { wasScheduled = true; transport.schedule(() => { @@ -557,16 +571,13 @@ describe("Transport", () => { }); }, 0); transport.start(0); - }, 0.3).then(() => { - }); + }, 0.3).then(() => {}); }); - }); context("scheduleRepeat", () => { - it("can schedule a repeated event", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const eventID = transport.scheduleRepeat(noOp, 1); expect(eventID).to.be.a("number"); @@ -575,14 +586,18 @@ describe("Transport", () => { it("scheduled event gets invoked with the time of the event", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; - const eventID = transport.scheduleRepeat(time => { - expect(time).to.be.closeTo(startTime, 0.01); - invoked = true; - transport.clear(eventID); - }, 1, 0); + const eventID = transport.scheduleRepeat( + (time) => { + expect(time).to.be.closeTo(startTime, 0.01); + invoked = true; + transport.clear(eventID); + }, + 1, + 0 + ); transport.start(startTime); }, 0.3).then(() => { expect(invoked).to.equal(true); @@ -590,11 +605,15 @@ describe("Transport", () => { }); it("can cancel the timeline of scheduleRepeat", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - transport.scheduleRepeat(() => { - throw new Error("should not call this"); - }, 0.01, 0); + transport.scheduleRepeat( + () => { + throw new Error("should not call this"); + }, + 0.01, + 0 + ); transport.cancel(0); transport.start(0); }); @@ -602,14 +621,18 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); - transport.scheduleRepeat(time => { - expect(time).to.be.closeTo(startTime + eighth, 0.01); - invoked = true; - }, "1n", TransportTime("8n")); + transport.scheduleRepeat( + (time) => { + expect(time).to.be.closeTo(startTime + eighth, 0.01); + invoked = true; + }, + "1n", + TransportTime("8n") + ); transport.start(startTime); }, 0.4).then(() => { expect(invoked).to.equal(true); @@ -617,11 +640,15 @@ describe("Transport", () => { }); it("can clear a scheduled event", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - const eventID = transport.scheduleRepeat(() => { - throw new Error("should not call this function"); - }, 1, 0); + const eventID = transport.scheduleRepeat( + () => { + throw new Error("should not call this function"); + }, + 1, + 0 + ); transport.clear(eventID); transport.stop(); }); @@ -629,14 +656,18 @@ describe("Transport", () => { it("can be scheduled in the future", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; - const eventID = transport.scheduleRepeat(time => { - transport.clear(eventID); - expect(time).to.be.closeTo(startTime + 0.2, 0.01); - invoked = true; - }, 1, 0.2); + const eventID = transport.scheduleRepeat( + (time) => { + transport.clear(eventID); + expect(time).to.be.closeTo(startTime + 0.2, 0.01); + invoked = true; + }, + 1, + 0.2 + ); transport.start(startTime); }, 0.5).then(() => { expect(invoked).to.equal(true); @@ -645,11 +676,15 @@ describe("Transport", () => { it("repeats a repeat event", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - transport.scheduleRepeat(() => { - invocations++; - }, 0.1, 0); + transport.scheduleRepeat( + () => { + invocations++; + }, + 0.1, + 0 + ); transport.start(); }, 0.51).then(() => { expect(invocations).to.equal(6); @@ -658,16 +693,20 @@ describe("Transport", () => { it("repeats at the repeat interval", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); let repeatTime = -1; - transport.scheduleRepeat(time => { - if (repeatTime !== -1) { - expect(time - repeatTime).to.be.closeTo(0.1, 0.01); - } - repeatTime = time; - wasCalled = true; - }, 0.1, 0); + transport.scheduleRepeat( + (time) => { + if (repeatTime !== -1) { + expect(time - repeatTime).to.be.closeTo(0.1, 0.01); + } + repeatTime = time; + wasCalled = true; + }, + 0.1, + 0 + ); transport.start(); }, 0.5).then(() => { expect(wasCalled).to.equal(true); @@ -677,17 +716,25 @@ describe("Transport", () => { it("can schedule multiple events and invoke them in the right order", () => { let first = false; let second = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - const firstID = transport.scheduleRepeat(() => { - first = true; - transport.clear(firstID); - }, 1, 0.1); - const secondID = transport.scheduleRepeat(() => { - transport.clear(secondID); - expect(first).to.equal(true); - second = true; - }, 1, 0.11); + const firstID = transport.scheduleRepeat( + () => { + first = true; + transport.clear(firstID); + }, + 1, + 0.1 + ); + const secondID = transport.scheduleRepeat( + () => { + transport.clear(secondID); + expect(first).to.equal(true); + second = true; + }, + 1, + 0.11 + ); transport.start(); }, 0.3).then(() => { expect(first); @@ -697,11 +744,16 @@ describe("Transport", () => { it("repeats for the given interval", () => { let repeatCount = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); - transport.scheduleRepeat(time => { - repeatCount++; - }, 0.1, 0, 0.5); + transport.scheduleRepeat( + (time) => { + repeatCount++; + }, + 0.1, + 0, + 0.5 + ); transport.start(); }, 0.61).then(() => { expect(repeatCount).to.equal(5); @@ -710,18 +762,25 @@ describe("Transport", () => { it("can add an event after the Transport is started", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; const times = [0.15, 0.3]; - return time => { + return (time) => { if (time > 0.1 && !wasScheduled) { wasScheduled = true; - transport.scheduleRepeat(repeatedTime => { - expect(repeatedTime).to.be.closeTo(times[invocations], 0.01); - invocations++; - }, 0.15, 0.15); + transport.scheduleRepeat( + (repeatedTime) => { + expect(repeatedTime).to.be.closeTo( + times[invocations], + 0.01 + ); + invocations++; + }, + 0.15, + 0.15 + ); } }; }, 0.31).then(() => { @@ -731,31 +790,36 @@ describe("Transport", () => { it("can add an event to the past after the Transport is started", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.start(0); let wasScheduled = false; const times = [0.15, 0.25]; - return time => { + return (time) => { if (time >= 0.12 && !wasScheduled) { wasScheduled = true; - transport.scheduleRepeat(repeatedTime => { - expect(repeatedTime).to.be.closeTo(times[invocations], 0.01); - invocations++; - }, 0.1, 0.05); + transport.scheduleRepeat( + (repeatedTime) => { + expect(repeatedTime).to.be.closeTo( + times[invocations], + 0.01 + ); + invocations++; + }, + 0.1, + 0.05 + ); } }; }, 0.3).then(() => { expect(invocations).to.equal(2); }); }); - }); context("scheduleOnce", () => { - it("can schedule a single event on the timeline", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const eventID = transport.scheduleOnce(() => {}, 0); expect(eventID).to.be.a("number"); @@ -764,10 +828,10 @@ describe("Transport", () => { it("scheduled event gets invoked with the time of the event", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; - const eventID = transport.scheduleOnce(time => { + const eventID = transport.scheduleOnce((time) => { invoked = true; transport.clear(eventID); expect(time).to.be.closeTo(startTime, 0.01); @@ -780,11 +844,11 @@ describe("Transport", () => { it("can schedule events with TransportTime", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = 0.1; const eighth = transport.toSeconds("8n"); - transport.scheduleOnce(time => { + transport.scheduleOnce((time) => { expect(time).to.be.closeTo(startTime + eighth, 0.01); invoked = true; }, TransportTime("8n")); @@ -795,7 +859,7 @@ describe("Transport", () => { }); it("can clear a scheduled event", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const eventID = transport.scheduleOnce(() => { throw new Error("should not call this function"); @@ -807,10 +871,10 @@ describe("Transport", () => { it("can be scheduled in the future", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const startTime = transport.now() + 0.1; - const eventID = transport.scheduleOnce(time => { + const eventID = transport.scheduleOnce((time) => { transport.clear(eventID); expect(time).to.be.closeTo(startTime + 0.3, 0.01); invoked = true; @@ -823,7 +887,7 @@ describe("Transport", () => { it("the event is removed after is is invoked", () => { let iterations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.scheduleOnce(() => { iterations++; @@ -833,14 +897,12 @@ describe("Transport", () => { expect(iterations).to.be.lessThan(2); }); }); - }); context("events", () => { - it("invokes start/stop/pause events", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.on("start", () => { invocations++; @@ -859,7 +921,7 @@ describe("Transport", () => { it("invokes start event with correct offset", () => { let wasCalled = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.on("start", (time, offset) => { expect(time).to.be.closeTo(0.2, 0.01); @@ -874,10 +936,13 @@ describe("Transport", () => { it("invokes the event just before the scheduled time", () => { let invoked = false; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.on("start", (time, offset) => { - expect(time - transport.context.currentTime).to.be.closeTo(0, 0.01); + expect(time - transport.context.currentTime).to.be.closeTo( + 0, + 0.01 + ); expect(offset).to.equal(0); invoked = true; }); @@ -889,14 +954,14 @@ describe("Transport", () => { it("passes in the time argument to the events", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const now = transport.now(); - transport.on("start", time => { + transport.on("start", (time) => { invocations++; expect(time).to.be.closeTo(now + 0.1, 0.01); }); - transport.on("stop", time => { + transport.on("stop", (time) => { invocations++; expect(time).to.be.closeTo(now + 0.2, 0.01); }); @@ -908,13 +973,13 @@ describe("Transport", () => { it("invokes the 'loop' method on loop", () => { let loops = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); const sixteenth = transport.toSeconds("16n"); transport.setLoopPoints(0, sixteenth); transport.loop = true; let lastLoop = -1; - transport.on("loop", time => { + transport.on("loop", (time) => { loops++; if (lastLoop !== -1) { expect(time - lastLoop).to.be.closeTo(sixteenth, 0.001); @@ -929,9 +994,8 @@ describe("Transport", () => { }); context("swing", () => { - it("can get/set the swing subdivision", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.swingSubdivision = "8n"; expect(transport.swingSubdivision).to.equal("8n"); @@ -941,7 +1005,7 @@ describe("Transport", () => { }); it("can get/set the swing amount", () => { - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.swing = 0.5; expect(transport.swing).to.equal(0.5); @@ -952,28 +1016,28 @@ describe("Transport", () => { it("can swing", () => { let invocations = 0; - return Offline(context => { + return Offline((context) => { const transport = new TransportClass({ context }); transport.swing = 1; transport.swingSubdivision = "8n"; const eightNote = transport.toSeconds("8n"); // downbeat, no swing - transport.schedule(time => { + transport.schedule((time) => { invocations++; expect(time).is.closeTo(0, 0.001); }, 0); // eighth note has swing - transport.schedule(time => { + transport.schedule((time) => { invocations++; - expect(time).is.closeTo(eightNote * 5 / 3, 0.001); + expect(time).is.closeTo((eightNote * 5) / 3, 0.001); }, "8n"); // sixteenth note is also swung - transport.schedule(time => { + transport.schedule((time) => { invocations++; expect(time).is.closeTo(eightNote, 0.05); }, "16n"); // no swing on the quarter - transport.schedule(time => { + transport.schedule((time) => { invocations++; expect(time).is.closeTo(eightNote * 2, 0.001); }, "4n"); @@ -983,5 +1047,4 @@ describe("Transport", () => { }); }); }); - }); diff --git a/Tone/core/clock/Transport.ts b/Tone/core/clock/Transport.ts index effe2588..ce8a2f72 100644 --- a/Tone/core/clock/Transport.ts +++ b/Tone/core/clock/Transport.ts @@ -1,20 +1,20 @@ -import { TimeClass } from "../../core/type/Time"; -import { PlaybackState } from "../../core/util/StateTimeline"; -import { TimelineValue } from "../../core/util/TimelineValue"; -import { ToneAudioNode } from "../../core/context/ToneAudioNode"; -import { Pow } from "../../signal/Pow"; -import { Signal } from "../../signal/Signal"; +import { TimeClass } from "../../core/type/Time.js"; +import { PlaybackState } from "../../core/util/StateTimeline.js"; +import { TimelineValue } from "../../core/util/TimelineValue.js"; +import { ToneAudioNode } from "../../core/context/ToneAudioNode.js"; +import { Pow } from "../../signal/Pow.js"; +import { Signal } from "../../signal/Signal.js"; import { onContextClose, onContextInit, -} from "../context/ContextInitialization"; -import { Gain } from "../context/Gain"; +} from "../context/ContextInitialization.js"; +import { Gain } from "../context/Gain.js"; import { ToneWithContext, ToneWithContextOptions, -} from "../context/ToneWithContext"; -import { TicksClass } from "../type/Ticks"; -import { TransportTimeClass } from "../type/TransportTime"; +} from "../context/ToneWithContext.js"; +import { TicksClass } from "../type/Ticks.js"; +import { TransportTimeClass } from "../type/TransportTime.js"; import { BarsBeatsSixteenths, BPM, @@ -25,18 +25,18 @@ import { Time, TimeSignature, TransportTime, -} from "../type/Units"; -import { enterScheduledCallback } from "../util/Debug"; -import { optionsFromArguments } from "../util/Defaults"; -import { Emitter } from "../util/Emitter"; -import { readOnly, writable } from "../util/Interface"; -import { IntervalTimeline } from "../util/IntervalTimeline"; -import { Timeline } from "../util/Timeline"; -import { isArray, isDefined } from "../util/TypeCheck"; -import { Clock } from "./Clock"; -import { TickParam } from "./TickParam"; -import { TransportEvent } from "./TransportEvent"; -import { TransportRepeatEvent } from "./TransportRepeatEvent"; +} from "../type/Units.js"; +import { enterScheduledCallback } from "../util/Debug.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { Emitter } from "../util/Emitter.js"; +import { readOnly, writable } from "../util/Interface.js"; +import { IntervalTimeline } from "../util/IntervalTimeline.js"; +import { Timeline } from "../util/Timeline.js"; +import { isArray, isDefined } from "../util/TypeCheck.js"; +import { Clock } from "./Clock.js"; +import { TickParam } from "./TickParam.js"; +import { TransportEvent } from "./TransportEvent.js"; +import { TransportRepeatEvent } from "./TransportRepeatEvent.js"; interface TransportOptions extends ToneWithContextOptions { bpm: BPM; @@ -89,7 +89,8 @@ type TransportCallback = (time: Seconds) => void; */ export class TransportClass extends ToneWithContext - implements Emitter { + implements Emitter +{ readonly name: string = "Transport"; //------------------------------------- @@ -366,7 +367,10 @@ export class TransportClass * timeline it was added to. * @returns the event id which was just added */ - private _addEvent(event: TransportEvent, timeline: Timeline): number { + private _addEvent( + event: TransportEvent, + timeline: Timeline + ): number { this._scheduledEvents[event.id.toString()] = { event, timeline, @@ -625,7 +629,10 @@ export class TransportClass if (this.state === "started") { const ticks = this._clock.getTicksAtTime(now); // schedule to start on the next tick, #573 - const remainingTick = this._clock.frequency.getDurationOfTicks(Math.ceil(ticks) - ticks, now); + const remainingTick = this._clock.frequency.getDurationOfTicks( + Math.ceil(ticks) - ticks, + now + ); const time = now + remainingTick; this.emit("stop", time); this._clock.setTicksAtTime(t, time); @@ -710,9 +717,9 @@ export class TransportClass */ syncSignal(signal: Signal, ratio?: number): this { const now = this.now(); - let source : TickParam<"bpm"> | ToneAudioNode = this.bpm; + let source: TickParam<"bpm"> | ToneAudioNode = this.bpm; let sourceValue = 1 / (60 / source.getValueAtTime(now) / this.PPQ); - let nodes : ToneAudioNode[] = []; + let nodes: ToneAudioNode[] = []; // If the signal is in the time domain, sync it to the reciprocal of // the tempo instead of the tempo. if (signal.units === "time") { diff --git a/Tone/core/clock/TransportEvent.test.ts b/Tone/core/clock/TransportEvent.test.ts index 3675edff..0c69b262 100644 --- a/Tone/core/clock/TransportEvent.test.ts +++ b/Tone/core/clock/TransportEvent.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { TransportClass } from "./Transport"; -import { TransportEvent } from "./TransportEvent"; +import { Offline } from "../../../test/helper/Offline.js"; +import { TransportClass } from "./Transport.js"; +import { TransportEvent } from "./TransportEvent.js"; describe("TransportEvent", () => { - it("can be created and disposed", () => { return Offline((context) => { const transport = new TransportClass({ context }); diff --git a/Tone/core/clock/TransportEvent.ts b/Tone/core/clock/TransportEvent.ts index 9563ff66..dde35a73 100644 --- a/Tone/core/clock/TransportEvent.ts +++ b/Tone/core/clock/TransportEvent.ts @@ -1,7 +1,6 @@ -import { Seconds, Ticks } from "../type/Units"; -import { noOp } from "../util/Interface"; - -type Transport = import("../clock/Transport").TransportClass; +import { Seconds, Ticks } from "../type/Units.js"; +import { noOp } from "../util/Interface.js"; +import type { TransportClass as Transport } from "./Transport.js"; export interface TransportEventOptions { callback: (time: number) => void; @@ -15,7 +14,6 @@ export interface TransportEventOptions { * handled from within Tone.Transport. */ export class TransportEvent { - /** * Reference to the Transport that created it */ @@ -43,7 +41,7 @@ export class TransportEvent { /** * The remaining value between the passed in time, and Math.floor(time). - * This value is later added back when scheduling to get sub-tick precision. + * This value is later added back when scheduling to get sub-tick precision. */ protected _remainderTime = 0; @@ -51,8 +49,10 @@ export class TransportEvent { * @param transport The transport object which the event belongs to */ constructor(transport: Transport, opts: Partial) { - - const options: TransportEventOptions = Object.assign(TransportEvent.getDefaults(), opts); + const options: TransportEventOptions = Object.assign( + TransportEvent.getDefaults(), + opts + ); this.transport = transport; this.callback = options.callback; diff --git a/Tone/core/clock/TransportRepeatEvent.test.ts b/Tone/core/clock/TransportRepeatEvent.test.ts index 2b52a997..8f85d088 100644 --- a/Tone/core/clock/TransportRepeatEvent.test.ts +++ b/Tone/core/clock/TransportRepeatEvent.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { TransportClass } from "./Transport"; -import { TransportRepeatEvent } from "./TransportRepeatEvent"; +import { Offline } from "../../../test/helper/Offline.js"; +import { TransportClass } from "./Transport.js"; +import { TransportRepeatEvent } from "./TransportRepeatEvent.js"; describe("TransportRepeatEvent", () => { - it("can be created and disposed", () => { return Offline((context) => { const transport = new TransportClass({ context }); @@ -39,5 +38,4 @@ describe("TransportRepeatEvent", () => { expect(transport._timeline.length).to.equal(0); }); }); - }); diff --git a/Tone/core/clock/TransportRepeatEvent.ts b/Tone/core/clock/TransportRepeatEvent.ts index 6e339f00..3fd90268 100644 --- a/Tone/core/clock/TransportRepeatEvent.ts +++ b/Tone/core/clock/TransportRepeatEvent.ts @@ -1,10 +1,9 @@ -import { BaseContext } from "../context/BaseContext"; -import { TicksClass } from "../type/Ticks"; -import { Seconds, Ticks, Time } from "../type/Units"; -import { TransportEvent, TransportEventOptions } from "./TransportEvent"; -import { GT, LT } from "../util/Math"; - -type Transport = import("../clock/Transport").TransportClass; +import { BaseContext } from "../context/BaseContext.js"; +import { TicksClass } from "../type/Ticks.js"; +import { Seconds, Ticks, Time } from "../type/Units.js"; +import { TransportEvent, TransportEventOptions } from "./TransportEvent.js"; +import { GT, LT } from "../util/Math.js"; +import type { TransportClass as Transport } from "./Transport.js"; interface TransportRepeatEventOptions extends TransportEventOptions { interval: Ticks; @@ -16,7 +15,6 @@ interface TransportRepeatEventOptions extends TransportEventOptions { * to schedule repeat events. This class should not be instantiated directly. */ export class TransportRepeatEvent extends TransportEvent { - /** * When the event should stop repeating */ @@ -55,8 +53,10 @@ export class TransportRepeatEvent extends TransportEvent { /** * @param transport The transport object which the event belongs to */ - constructor(transport: Transport, opts: Partial) { - + constructor( + transport: Transport, + opts: Partial + ) { super(transport, opts); const options = Object.assign(TransportRepeatEvent.getDefaults(), opts); @@ -96,8 +96,10 @@ export class TransportRepeatEvent extends TransportEvent { */ private _createEvent(): number { if (LT(this._nextTick, this.floatTime + this.duration)) { - return this.transport.scheduleOnce(this.invoke.bind(this), - new TicksClass(this.context, this._nextTick).toSeconds()); + return this.transport.scheduleOnce( + this.invoke.bind(this), + new TicksClass(this.context, this._nextTick).toSeconds() + ); } return -1; } @@ -109,11 +111,15 @@ export class TransportRepeatEvent extends TransportEvent { // schedule the next event // const ticks = this.transport.getTicksAtTime(time); // if the next tick is within the bounds set by "duration" - if (LT(this._nextTick + this._interval, this.floatTime + this.duration)) { + if ( + LT(this._nextTick + this._interval, this.floatTime + this.duration) + ) { this._nextTick += this._interval; this._currentId = this._nextId; - this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), - new TicksClass(this.context, this._nextTick).toSeconds()); + this._nextId = this.transport.scheduleOnce( + this.invoke.bind(this), + new TicksClass(this.context, this._nextTick).toSeconds() + ); } } @@ -128,7 +134,10 @@ export class TransportRepeatEvent extends TransportEvent { const ticks = this.transport.getTicksAtTime(time); if (GT(ticks, this.time)) { // the event is not being scheduled from the beginning and should be offset - this._nextTick = this.floatTime + Math.ceil((ticks - this.floatTime) / this._interval) * this._interval; + this._nextTick = + this.floatTime + + Math.ceil((ticks - this.floatTime) / this._interval) * + this._interval; } this._currentId = this._createEvent(); this._nextTick += this._interval; diff --git a/Tone/core/context/AbstractParam.ts b/Tone/core/context/AbstractParam.ts index 8dc79d77..7da8be01 100644 --- a/Tone/core/context/AbstractParam.ts +++ b/Tone/core/context/AbstractParam.ts @@ -1,10 +1,9 @@ -import { Time, UnitMap, UnitName } from "../type/Units"; +import { Time, UnitMap, UnitName } from "../type/Units.js"; /** * Abstract base class for {@link Param} and {@link Signal} */ export abstract class AbstractParam { - /** * Schedules a parameter value change at the given time. * @param value The value to set the signal. @@ -40,7 +39,7 @@ export abstract class AbstractParam { * Automation methods like {@link linearRampToValueAtTime} and {@link exponentialRampToValueAtTime} * require a starting automation value usually set by {@link setValueAtTime}. This method * is useful since it will do a `setValueAtTime` with whatever the currently computed - * value at the given time is. + * value at the given time is. * @param time When to add a ramp point. * @example * const osc = new Tone.Oscillator().toDestination().start(); @@ -61,7 +60,10 @@ export abstract class AbstractParam { * signal.linearRampToValueAtTime(1, 0.4); * }, 0.5, 1); */ - abstract linearRampToValueAtTime(value: UnitMap[TypeName], time: Time): this; + abstract linearRampToValueAtTime( + value: UnitMap[TypeName], + time: Time + ): this; /** * Schedules an exponential continuous change in parameter value from @@ -74,7 +76,10 @@ export abstract class AbstractParam { * signal.exponentialRampToValueAtTime(0, 0.4); * }, 0.5, 1); */ - abstract exponentialRampToValueAtTime(value: UnitMap[TypeName], time: Time): this; + abstract exponentialRampToValueAtTime( + value: UnitMap[TypeName], + time: Time + ): this; /** * Schedules an exponential continuous change in parameter value from @@ -96,7 +101,11 @@ export abstract class AbstractParam { * signal.exponentialRampTo(5, 0.3, 0.1); * }, 0.5, 1); */ - abstract exponentialRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this; + abstract exponentialRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this; /** * Schedules an linear continuous change in parameter value from @@ -120,7 +129,11 @@ export abstract class AbstractParam { * signal.linearRampTo(0, 0.3, 0.1); * }, 0.5, 1); */ - abstract linearRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this; + abstract linearRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this; /** * Start exponentially approaching the target value at the given time. Since it @@ -137,7 +150,11 @@ export abstract class AbstractParam { * signal.targetRampTo(0, 0.3, 0.1); * }, 0.5, 1); */ - abstract targetRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this; + abstract targetRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this; /** * Start exponentially approaching the target value at the given time. Since it @@ -152,7 +169,11 @@ export abstract class AbstractParam { * // exponential approach over 4 seconds starting in 1 second * osc.frequency.exponentialApproachValueAtTime("C4", "+1", 4); */ - abstract exponentialApproachValueAtTime(value: UnitMap[TypeName], time: Time, rampTime: Time): this; + abstract exponentialApproachValueAtTime( + value: UnitMap[TypeName], + time: Time, + rampTime: Time + ): this; /** * Start exponentially approaching the target value at the given time with @@ -161,7 +182,11 @@ export abstract class AbstractParam { * @param startTime * @param timeConstant */ - abstract setTargetAtTime(value: UnitMap[TypeName], startTime: Time, timeConstant: number): this; + abstract setTargetAtTime( + value: UnitMap[TypeName], + startTime: Time, + timeConstant: number + ): this; /** * Sets an array of arbitrary parameter values starting at the given time @@ -177,7 +202,12 @@ export abstract class AbstractParam { * signal.setValueCurveAtTime([1, 0.2, 0.8, 0.1, 0], 0.2, 0.3); * }, 0.5, 1); */ - abstract setValueCurveAtTime(values: UnitMap[TypeName][], startTime: Time, duration: Time, scaling?: number): this; + abstract setValueCurveAtTime( + values: UnitMap[TypeName][], + startTime: Time, + duration: Time, + scaling?: number + ): this; /** * Cancels all scheduled parameter changes with times greater than or @@ -224,7 +254,11 @@ export abstract class AbstractParam { * // schedule it to ramp starting at a specific time * osc.frequency.rampTo("A2", 10, "+2"); */ - abstract rampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this; + abstract rampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this; /** * The current value of the parameter. Setting this value diff --git a/Tone/core/context/AudioContext.ts b/Tone/core/context/AudioContext.ts index 7fdc1f0b..a162fc68 100644 --- a/Tone/core/context/AudioContext.ts +++ b/Tone/core/context/AudioContext.ts @@ -1,23 +1,33 @@ import { AudioContext as stdAudioContext, AudioWorkletNode as stdAudioWorkletNode, - OfflineAudioContext as stdOfflineAudioContext + OfflineAudioContext as stdOfflineAudioContext, } from "standardized-audio-context"; -import { assert } from "../util/Debug"; -import { isDefined } from "../util/TypeCheck"; +import { assert } from "../util/Debug.js"; +import { isDefined } from "../util/TypeCheck.js"; /** * Create a new AudioContext */ -export function createAudioContext(options?: AudioContextOptions): AudioContext { +export function createAudioContext( + options?: AudioContextOptions +): AudioContext { return new stdAudioContext(options) as unknown as AudioContext; } /** * Create a new OfflineAudioContext */ -export function createOfflineAudioContext(channels: number, length: number, sampleRate: number): OfflineAudioContext { - return new stdOfflineAudioContext(channels, length, sampleRate) as unknown as OfflineAudioContext; +export function createOfflineAudioContext( + channels: number, + length: number, + sampleRate: number +): OfflineAudioContext { + return new stdOfflineAudioContext( + channels, + length, + sampleRate + ) as unknown as OfflineAudioContext; } /** @@ -37,24 +47,34 @@ interface ToneWindow extends Window { * A reference to the window object * @hidden */ -export const theWindow: ToneWindow | null = typeof self === "object" ? self : null; +export const theWindow: ToneWindow | null = + typeof self === "object" ? self : null; /** * If the browser has a window object which has an AudioContext * @hidden */ -export const hasAudioContext = theWindow && - (theWindow.hasOwnProperty("AudioContext") || theWindow.hasOwnProperty("webkitAudioContext")); +export const hasAudioContext = + theWindow && + (theWindow.hasOwnProperty("AudioContext") || + theWindow.hasOwnProperty("webkitAudioContext")); -export function createAudioWorkletNode(context: AnyAudioContext, name: string, options?: Partial): AudioWorkletNode { - assert(isDefined(stdAudioWorkletNode), "This node only works in a secure context (https or localhost)"); +export function createAudioWorkletNode( + context: AnyAudioContext, + name: string, + options?: Partial +): AudioWorkletNode { + assert( + isDefined(stdAudioWorkletNode), + "This node only works in a secure context (https or localhost)" + ); // @ts-ignore return new stdAudioWorkletNode(context, name, options); } /** - * This promise resolves to a boolean which indicates if the - * functionality is supported within the currently used browse. + * This promise resolves to a boolean which indicates if the + * functionality is supported within the currently used browse. * Taken from [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context#issupported) */ export { isSupported as supported } from "standardized-audio-context"; diff --git a/Tone/core/context/BaseContext.ts b/Tone/core/context/BaseContext.ts index c07af471..fbd1915f 100644 --- a/Tone/core/context/BaseContext.ts +++ b/Tone/core/context/BaseContext.ts @@ -1,11 +1,10 @@ -import { Seconds } from "../type/Units"; -import { Emitter } from "../util/Emitter"; -import { AnyAudioContext } from "./AudioContext"; - -type Draw = import("../util/Draw").DrawClass; -type Destination = import("./Destination").DestinationClass; -type Transport = import("../clock/Transport").TransportClass; -type Listener = import("./Listener").ListenerClass; +import { Seconds } from "../type/Units.js"; +import { Emitter } from "../util/Emitter.js"; +import { AnyAudioContext } from "./AudioContext.js"; +import type { DrawClass as Draw } from "../util/Draw.js"; +import type { DestinationClass as Destination } from "./Destination.js"; +import type { TransportClass as Transport } from "../clock/Transport.js"; +import type { ListenerClass as Listener } from "./Listener.js"; // these are either not used in Tone.js or deprecated and not implemented. export type ExcludedFromBaseAudioContext = @@ -20,15 +19,16 @@ export type ExcludedFromBaseAudioContext = // the subset of the BaseAudioContext which Tone.Context implements. export type BaseAudioContextSubset = Omit< -BaseAudioContext, -ExcludedFromBaseAudioContext + BaseAudioContext, + ExcludedFromBaseAudioContext >; export type ContextLatencyHint = AudioContextLatencyCategory; export abstract class BaseContext extends Emitter<"statechange" | "tick"> - implements BaseAudioContextSubset { + implements BaseAudioContextSubset +{ //--------------------------- // BASE AUDIO CONTEXT METHODS //--------------------------- @@ -104,9 +104,7 @@ export abstract class BaseContext abstract get rawContext(): AnyAudioContext; - abstract addAudioWorkletModule( - _url: string - ): Promise; + abstract addAudioWorkletModule(_url: string): Promise; abstract lookAhead: number; diff --git a/Tone/core/context/Context.test.ts b/Tone/core/context/Context.test.ts index fc39c610..4078a8ee 100644 --- a/Tone/core/context/Context.test.ts +++ b/Tone/core/context/Context.test.ts @@ -1,15 +1,14 @@ import { expect } from "chai"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Offline } from "test/helper/Offline"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { TransportClass } from "../clock/Transport"; -import { getContext } from "../Global"; -import { createAudioContext } from "./AudioContext"; -import { Context } from "./Context"; -import { DestinationClass } from "./Destination"; -import { ListenerClass } from "./Listener"; -import { DrawClass } from "../util/Draw"; -import { connect } from "./ToneAudioNode"; +import { ConstantOutput } from "../../../test/helper/ConstantOutput.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { TransportClass } from "../clock/Transport.js"; +import { getContext } from "../Global.js"; +import { createAudioContext } from "./AudioContext.js"; +import { Context } from "./Context.js"; +import { DestinationClass } from "./Destination.js"; +import { ListenerClass } from "./Listener.js"; +import { DrawClass } from "../util/Draw.js"; +import { connect } from "./ToneAudioNode.js"; describe("Context", () => { it("creates and disposes the classes attached to the context", async () => { @@ -51,16 +50,14 @@ describe("Context", () => { return ctx.close(); }); - if (ONLINE_TESTING) { - it("clock is running", (done) => { - const interval = setInterval(() => { - if (getContext().currentTime > 0.5) { - clearInterval(interval); - done(); - } - }, 20); - }); - } + it("clock is running", (done) => { + const interval = setInterval(() => { + if (getContext().currentTime > 0.5) { + clearInterval(interval); + done(); + } + }, 20); + }); it("has a rawContext", () => { const ctx = new Context(createAudioContext()); @@ -75,7 +72,7 @@ describe("Context", () => { clockSource: "timeout", latencyHint: "playback", lookAhead: 0.2, - updateInterval: 0.1 + updateInterval: 0.1, }); expect(ctx.lookAhead).to.equal(0.2); expect(ctx.updateInterval).to.equal(0.1); @@ -124,97 +121,93 @@ describe("Context", () => { }); }); - if (ONLINE_TESTING) { - context("clockSource", () => { - let ctx; - beforeEach(() => { - ctx = new Context(); - return ctx.resume(); - }); + context("clockSource", () => { + let ctx; + beforeEach(() => { + ctx = new Context(); + return ctx.resume(); + }); - afterEach(() => { - ctx.dispose(); - return ctx.close(); - }); + afterEach(() => { + ctx.dispose(); + return ctx.close(); + }); - it("defaults to 'worker'", () => { - expect(ctx.clockSource).to.equal("worker"); - }); + it("defaults to 'worker'", () => { + expect(ctx.clockSource).to.equal("worker"); + }); - it("provides callback", (done) => { - expect(ctx.clockSource).to.equal("worker"); - ctx.setTimeout(() => { - done(); - }, 0.1); - }); + it("provides callback", (done) => { + expect(ctx.clockSource).to.equal("worker"); + ctx.setTimeout(() => { + done(); + }, 0.1); + }); - it("can be set to 'timeout'", (done) => { - ctx.clockSource = "timeout"; - expect(ctx.clockSource).to.equal("timeout"); - ctx.setTimeout(() => { - done(); - }, 0.1); - }); + it("can be set to 'timeout'", (done) => { + ctx.clockSource = "timeout"; + expect(ctx.clockSource).to.equal("timeout"); + ctx.setTimeout(() => { + done(); + }, 0.1); + }); - it("can be set to 'offline'", (done) => { - ctx.clockSource = "offline"; - expect(ctx.clockSource).to.equal("offline"); - // provides no callback - ctx.setTimeout(() => { - throw new Error("shouldn't be called"); - }, 0.1); - setTimeout(() => { - done(); - }, 200); - }); + it("can be set to 'offline'", (done) => { + ctx.clockSource = "offline"; + expect(ctx.clockSource).to.equal("offline"); + // provides no callback + ctx.setTimeout(() => { + throw new Error("shouldn't be called"); + }, 0.1); + setTimeout(() => { + done(); + }, 200); }); - } + }); context("setTimeout", () => { - if (ONLINE_TESTING) { - let ctx; - beforeEach(() => { - ctx = new Context(); - return ctx.resume(); - }); + let ctx; + beforeEach(() => { + ctx = new Context(); + return ctx.resume(); + }); - afterEach(() => { - ctx.dispose(); - return ctx.close(); - }); + afterEach(() => { + ctx.dispose(); + return ctx.close(); + }); - it("can set a timeout", (done) => { - ctx.setTimeout(() => { - done(); - }, 0.1); - }); + it("can set a timeout", (done) => { + ctx.setTimeout(() => { + done(); + }, 0.1); + }); - it("returns an id", () => { - expect(ctx.setTimeout(() => {}, 0.1)).to.be.a("number"); - // try clearing a random ID, shouldn't cause any errors - ctx.clearTimeout(-2); - }); + it("returns an id", () => { + expect(ctx.setTimeout(() => {}, 0.1)).to.be.a("number"); + // try clearing a random ID, shouldn't cause any errors + ctx.clearTimeout(-2); + }); - it("timeout is not invoked when cancelled", (done) => { - const id = ctx.setTimeout(() => { - throw new Error("shouldn't be invoked"); - }, 0.01); - ctx.clearTimeout(id); - ctx.setTimeout(() => { - done(); - }, 0.02); - }); + it("timeout is not invoked when cancelled", (done) => { + const id = ctx.setTimeout(() => { + throw new Error("shouldn't be invoked"); + }, 0.01); + ctx.clearTimeout(id); + ctx.setTimeout(() => { + done(); + }, 0.02); + }); - it("order is maintained", (done) => { - let wasInvoked = false; - ctx.setTimeout(() => { - expect(wasInvoked).to.equal(true); - done(); - }, 0.02); - ctx.setTimeout(() => { - wasInvoked = true; - }, 0.01); - }); - } + it("order is maintained", (done) => { + let wasInvoked = false; + ctx.setTimeout(() => { + expect(wasInvoked).to.equal(true); + done(); + }, 0.02); + ctx.setTimeout(() => { + wasInvoked = true; + }, 0.01); + }); it("is invoked in the offline context", () => { return Offline((context) => { @@ -227,51 +220,49 @@ describe("Context", () => { }); context("setInterval", () => { - if (ONLINE_TESTING) { - let ctx; - beforeEach(() => { - ctx = new Context(); - return ctx.resume(); - }); + let ctx; + beforeEach(() => { + ctx = new Context(); + return ctx.resume(); + }); - afterEach(() => { - ctx.dispose(); - return ctx.close(); - }); + afterEach(() => { + ctx.dispose(); + return ctx.close(); + }); - it("can set an interval", (done) => { - ctx.setInterval(() => { - done(); - }, 0.1); - }); + it("can set an interval", (done) => { + ctx.setInterval(() => { + done(); + }, 0.1); + }); - it("returns an id", () => { - expect(ctx.setInterval(() => {}, 0.1)).to.be.a("number"); - // try clearing a random ID, shouldn't cause any errors - ctx.clearInterval(-2); - }); + it("returns an id", () => { + expect(ctx.setInterval(() => {}, 0.1)).to.be.a("number"); + // try clearing a random ID, shouldn't cause any errors + ctx.clearInterval(-2); + }); - it("timeout is not invoked when cancelled", (done) => { - const id = ctx.setInterval(() => { - throw new Error("shouldn't be invoked"); - }, 0.01); - ctx.clearInterval(id); - ctx.setInterval(() => { - done(); - }, 0.02); - }); + it("timeout is not invoked when cancelled", (done) => { + const id = ctx.setInterval(() => { + throw new Error("shouldn't be invoked"); + }, 0.01); + ctx.clearInterval(id); + ctx.setInterval(() => { + done(); + }, 0.02); + }); - it("order is maintained", (done) => { - let wasInvoked = false; - ctx.setInterval(() => { - expect(wasInvoked).to.equal(true); - done(); - }, 0.02); - ctx.setInterval(() => { - wasInvoked = true; - }, 0.01); - }); - } + it("order is maintained", (done) => { + let wasInvoked = false; + ctx.setInterval(() => { + expect(wasInvoked).to.equal(true); + done(); + }, 0.02); + ctx.setInterval(() => { + wasInvoked = true; + }, 0.01); + }); it("is invoked in the offline context", () => { let invocationCount = 0; diff --git a/Tone/core/context/Context.ts b/Tone/core/context/Context.ts index b83cbadf..7c30f459 100644 --- a/Tone/core/context/Context.ts +++ b/Tone/core/context/Context.ts @@ -1,22 +1,21 @@ -import { Ticker, TickerClockSource } from "../clock/Ticker"; -import { Seconds } from "../type/Units"; -import { isAudioContext } from "../util/AdvancedTypeCheck"; -import { optionsFromArguments } from "../util/Defaults"; -import { Timeline } from "../util/Timeline"; -import { isDefined } from "../util/TypeCheck"; +import { Ticker, TickerClockSource } from "../clock/Ticker.js"; +import { Seconds } from "../type/Units.js"; +import { isAudioContext } from "../util/AdvancedTypeCheck.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { Timeline } from "../util/Timeline.js"; +import { isDefined } from "../util/TypeCheck.js"; import { AnyAudioContext, createAudioContext, createAudioWorkletNode, -} from "./AudioContext"; -import { closeContext, initializeContext } from "./ContextInitialization"; -import { BaseContext, ContextLatencyHint } from "./BaseContext"; -import { assert } from "../util/Debug"; - -type Transport = import("../clock/Transport").TransportClass; -type Destination = import("./Destination").DestinationClass; -type Listener = import("./Listener").ListenerClass; -type Draw = import("../util/Draw").DrawClass; +} from "./AudioContext.js"; +import { closeContext, initializeContext } from "./ContextInitialization.js"; +import { BaseContext, ContextLatencyHint } from "./BaseContext.js"; +import { assert } from "../util/Debug.js"; +import type { DrawClass as Draw } from "../util/Draw.js"; +import type { DestinationClass as Destination } from "./Destination.js"; +import type { TransportClass as Transport } from "../clock/Transport.js"; +import type { ListenerClass as Listener } from "./Listener.js"; export interface ContextOptions { clockSource: TickerClockSource; @@ -135,9 +134,13 @@ export class Context extends BaseContext { this._context.onstatechange = () => { this.emit("statechange", this.state); }; - + // if no custom updateInterval provided, updateInterval will be derived by lookAhead setter - this[arguments[0]?.hasOwnProperty("updateInterval") ? "_lookAhead" : "lookAhead"] = options.lookAhead; + this[ + arguments[0]?.hasOwnProperty("updateInterval") + ? "_lookAhead" + : "lookAhead" + ] = options.lookAhead; } static getDefaults(): ContextOptions { @@ -377,7 +380,7 @@ export class Context extends BaseContext { * Returns a promise which resolves when all of the worklets have been loaded on this context */ protected async workletsAreReady(): Promise { - await this._workletPromise ? this._workletPromise : Promise.resolve(); + (await this._workletPromise) ? this._workletPromise : Promise.resolve(); } //--------------------------- @@ -421,8 +424,8 @@ export class Context extends BaseContext { set lookAhead(time: Seconds) { this._lookAhead = time; // if lookAhead is 0, default to .01 updateInterval - this.updateInterval = time ? (time / 2) : .01; - } + this.updateInterval = time ? time / 2 : 0.01; + } private _lookAhead!: Seconds; /** @@ -475,7 +478,7 @@ export class Context extends BaseContext { /** * Starts the audio context from a suspended state. This is required - * to initially start the AudioContext. + * to initially start the AudioContext. * @see {@link start} */ resume(): Promise { @@ -491,7 +494,11 @@ export class Context extends BaseContext { * any AudioNodes created from the context will be silent. */ async close(): Promise { - if (isAudioContext(this._context) && (this.state !== "closed") && !this._closeStarted) { + if ( + isAudioContext(this._context) && + this.state !== "closed" && + !this._closeStarted + ) { this._closeStarted = true; await this._context.close(); } diff --git a/Tone/core/context/ContextInitialization.ts b/Tone/core/context/ContextInitialization.ts index 09cf4e25..87e8f326 100644 --- a/Tone/core/context/ContextInitialization.ts +++ b/Tone/core/context/ContextInitialization.ts @@ -1,8 +1,7 @@ //------------------------------------- // INITIALIZING NEW CONTEXT //------------------------------------- - -type Context = import("./Context").Context; +import type { Context } from "./Context.js"; /** * Array of callbacks to invoke when a new context is created @@ -21,7 +20,7 @@ export function onContextInit(cb: (ctx: Context) => void): void { */ export function initializeContext(ctx: Context): void { // add any additional modules - notifyNewContext.forEach(cb => cb(ctx)); + notifyNewContext.forEach((cb) => cb(ctx)); } /** @@ -38,5 +37,5 @@ export function onContextClose(cb: (ctx: Context) => void): void { export function closeContext(ctx: Context): void { // remove any additional modules - notifyCloseContext.forEach(cb => cb(ctx)); + notifyCloseContext.forEach((cb) => cb(ctx)); } diff --git a/Tone/core/context/Delay.test.ts b/Tone/core/context/Delay.test.ts index c7c78e44..7192206d 100644 --- a/Tone/core/context/Delay.test.ts +++ b/Tone/core/context/Delay.test.ts @@ -1,12 +1,11 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { PassAudio } from "test/helper/PassAudio"; -import { connect } from "../context/ToneAudioNode"; -import { Delay } from "./Delay"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { connect } from "../context/ToneAudioNode.js"; +import { Delay } from "./Delay.js"; describe("Delay", () => { - BasicTests(Delay); it("can be created and disposed", () => { @@ -40,7 +39,7 @@ describe("Delay", () => { it("clamps the delayTime range between 0 and maxDelay", () => { const delay = new Delay({ - maxDelay: 1 + maxDelay: 1, }); expect(() => { delay.delayTime.value = 2; @@ -97,7 +96,7 @@ describe("Delay", () => { }); it("passes audio through", () => { - return PassAudio(input => { + return PassAudio((input) => { const delay = new Delay().toDestination(); connect(input, delay); }); diff --git a/Tone/core/context/Delay.ts b/Tone/core/context/Delay.ts index 3d9df1ec..7193728d 100644 --- a/Tone/core/context/Delay.ts +++ b/Tone/core/context/Delay.ts @@ -1,8 +1,8 @@ -import { Param } from "../context/Param"; -import { Seconds, Time } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { readOnly } from "../util/Interface"; -import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode"; +import { Param } from "../context/Param.js"; +import { Seconds, Time } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { readOnly } from "../util/Interface.js"; +import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode.js"; export interface DelayOptions extends ToneAudioNodeOptions { delayTime: Time; @@ -22,7 +22,6 @@ export interface DelayOptions extends ToneAudioNodeOptions { * }, 0.5, 1); */ export class Delay extends ToneAudioNode { - readonly name: string = "Delay"; /** @@ -55,14 +54,28 @@ export class Delay extends ToneAudioNode { constructor(delayTime?: Time, maxDelay?: Time); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Delay.getDefaults(), arguments, ["delayTime", "maxDelay"])); + super( + optionsFromArguments(Delay.getDefaults(), arguments, [ + "delayTime", + "maxDelay", + ]) + ); - const options = optionsFromArguments(Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]); + const options = optionsFromArguments(Delay.getDefaults(), arguments, [ + "delayTime", + "maxDelay", + ]); const maxDelayInSeconds = this.toSeconds(options.maxDelay); - this._maxDelay = Math.max(maxDelayInSeconds, this.toSeconds(options.delayTime)); + this._maxDelay = Math.max( + maxDelayInSeconds, + this.toSeconds(options.delayTime) + ); - this._delayNode = this.input = this.output = this.context.createDelay(maxDelayInSeconds); + this._delayNode = + this.input = + this.output = + this.context.createDelay(maxDelayInSeconds); this.delayTime = new Param({ context: this.context, diff --git a/Tone/core/context/Destination.test.ts b/Tone/core/context/Destination.test.ts index 60320f8c..9786a52b 100644 --- a/Tone/core/context/Destination.test.ts +++ b/Tone/core/context/Destination.test.ts @@ -1,19 +1,18 @@ import { expect } from "chai"; -import { warns } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { getContext } from "../Global"; -import { DestinationClass } from "./Destination"; +import { warns } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Oscillator } from "../../source/oscillator/Oscillator.js"; +import { getContext } from "../Global.js"; +import { DestinationClass } from "./Destination.js"; describe("Destination", () => { - it("creates itself on the context", () => { expect(getContext().destination).instanceOf(DestinationClass); }); it("can be muted and unmuted", () => { - return Offline(context => { + return Offline((context) => { context.destination.mute = false; expect(context.destination.mute).to.equal(false); context.destination.mute = true; @@ -22,7 +21,7 @@ describe("Destination", () => { }); it("passes audio through", () => { - return PassAudio(input => { + return PassAudio((input) => { input.toDestination(); }); }); @@ -31,7 +30,7 @@ describe("Destination", () => { return Offline((context) => { new Oscillator().toDestination().start(0); context.destination.mute = true; - }).then(buffer => { + }).then((buffer) => { expect(buffer.isSilent()).to.equal(true); }); }); @@ -51,23 +50,35 @@ describe("Destination", () => { }); it("can get the maxChannelCount", () => { - return Offline((context) => { - expect(context.destination.maxChannelCount).to.equal(4); - }, 0.1, 4); + return Offline( + (context) => { + expect(context.destination.maxChannelCount).to.equal(4); + }, + 0.1, + 4 + ); }); it("can set the audio channel configuration", () => { - return Offline((context) => { - expect(context.destination.channelCount).to.equal(4); - context.destination.channelCountMode = "explicit"; - context.destination.channelInterpretation = "discrete"; - expect(context.destination.channelCountMode).to.equal("explicit"); - expect(context.destination.channelInterpretation).to.equal("discrete"); - }, 0.1, 4); + return Offline( + (context) => { + expect(context.destination.channelCount).to.equal(4); + context.destination.channelCountMode = "explicit"; + context.destination.channelInterpretation = "discrete"; + expect(context.destination.channelCountMode).to.equal( + "explicit" + ); + expect(context.destination.channelInterpretation).to.equal( + "discrete" + ); + }, + 0.1, + 4 + ); }); it("can pass audio through chained nodes", () => { - return PassAudio(input => { + return PassAudio((input) => { const gain = input.context.createGain(); input.connect(gain); input.context.destination.chain(gain); diff --git a/Tone/core/context/Destination.ts b/Tone/core/context/Destination.ts index 7b3c70e7..d533f4df 100644 --- a/Tone/core/context/Destination.ts +++ b/Tone/core/context/Destination.ts @@ -1,10 +1,14 @@ -import { Volume } from "../../component/channel/Volume"; -import { Decibels } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { onContextClose, onContextInit } from "./ContextInitialization"; -import { Gain } from "./Gain"; -import { Param } from "./Param"; -import { connectSeries, ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode"; +import { Volume } from "../../component/channel/Volume.js"; +import { Decibels } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { onContextClose, onContextInit } from "./ContextInitialization.js"; +import { Gain } from "./Gain.js"; +import { Param } from "./Param.js"; +import { + connectSeries, + ToneAudioNode, + ToneAudioNodeOptions, +} from "./ToneAudioNode.js"; interface DestinationOptions extends ToneAudioNodeOptions { volume: Decibels; @@ -27,14 +31,13 @@ interface DestinationOptions extends ToneAudioNodeOptions { * @category Core */ export class DestinationClass extends ToneAudioNode { - readonly name: string = "Destination"; input: Volume = new Volume({ context: this.context }); output: Gain = new Gain({ context: this.context }); /** - * The volume of the master output in decibels. -Infinity is silent, and 0 is no change. + * The volume of the master output in decibels. -Infinity is silent, and 0 is no change. * @example * const osc = new Tone.Oscillator().toDestination(); * osc.start(); @@ -45,14 +48,24 @@ export class DestinationClass extends ToneAudioNode { constructor(options: Partial); constructor() { - super(optionsFromArguments(DestinationClass.getDefaults(), arguments)); - const options = optionsFromArguments(DestinationClass.getDefaults(), arguments); + const options = optionsFromArguments( + DestinationClass.getDefaults(), + arguments + ); - connectSeries(this.input, this.output, this.context.rawContext.destination); + connectSeries( + this.input, + this.output, + this.context.rawContext.destination + ); this.mute = options.mute; - this._internalChannels = [this.input, this.context.rawContext.destination, this.output]; + this._internalChannels = [ + this.input, + this.context.rawContext.destination, + this.output, + ]; } static getDefaults(): DestinationOptions { @@ -119,10 +132,10 @@ export class DestinationClass extends ToneAudioNode { // INITIALIZATION //------------------------------------- -onContextInit(context => { +onContextInit((context) => { context.destination = new DestinationClass({ context }); }); -onContextClose(context => { +onContextClose((context) => { context.destination.dispose(); }); diff --git a/Tone/core/context/DummyContext.test.ts b/Tone/core/context/DummyContext.test.ts index 75dc8e3c..05335d90 100644 --- a/Tone/core/context/DummyContext.test.ts +++ b/Tone/core/context/DummyContext.test.ts @@ -1,4 +1,4 @@ -import { DummyContext } from "./DummyContext"; +import { DummyContext } from "./DummyContext.js"; describe("DummyContext", () => { it("has all the methods and members", () => { @@ -44,4 +44,3 @@ describe("DummyContext", () => { context.immediate(); }); }); - diff --git a/Tone/core/context/DummyContext.ts b/Tone/core/context/DummyContext.ts index 75f9a382..fe456e84 100644 --- a/Tone/core/context/DummyContext.ts +++ b/Tone/core/context/DummyContext.ts @@ -1,11 +1,10 @@ -import { BaseContext } from "./BaseContext"; -import { Seconds } from "../type/Units"; -import { AnyAudioContext } from "./AudioContext"; - -type Draw = import("../util/Draw").DrawClass; -type Destination = import("./Destination").DestinationClass; -type Transport = import("../clock/Transport").TransportClass; -type Listener = import("./Listener").ListenerClass; +import { BaseContext } from "./BaseContext.js"; +import { Seconds } from "../type/Units.js"; +import { AnyAudioContext } from "./AudioContext.js"; +import type { DrawClass as Draw } from "../util/Draw.js"; +import type { DestinationClass as Destination } from "./Destination.js"; +import type { TransportClass as Transport } from "../clock/Transport.js"; +import type { ListenerClass as Listener } from "./Listener.js"; export class DummyContext extends BaseContext { //--------------------------- diff --git a/Tone/core/context/Gain.test.ts b/Tone/core/context/Gain.test.ts index 5de8b1d7..a58b6d9b 100644 --- a/Tone/core/context/Gain.test.ts +++ b/Tone/core/context/Gain.test.ts @@ -1,11 +1,10 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { PassAudio } from "test/helper/PassAudio"; -import { Gain } from "./Gain"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../../test/helper/Connect.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Gain } from "./Gain.js"; describe("Gain", () => { - BasicTests(Gain); it("can be created and disposed", () => { diff --git a/Tone/core/context/Gain.ts b/Tone/core/context/Gain.ts index 309d2f88..88a59563 100644 --- a/Tone/core/context/Gain.ts +++ b/Tone/core/context/Gain.ts @@ -1,8 +1,8 @@ -import { Param } from "../context/Param"; -import { UnitMap, UnitName } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { readOnly } from "../util/Interface"; -import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode"; +import { Param } from "../context/Param.js"; +import { UnitMap, UnitName } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { readOnly } from "../util/Interface.js"; +import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode.js"; interface GainOptions extends ToneAudioNodeOptions { gain: UnitMap[TypeName]; @@ -25,8 +25,9 @@ interface GainOptions extends ToneAudioNodeOptions { * gainNode.gain.rampTo(0, 0.4, 0.2); * }, 0.7, 1); */ -export class Gain extends ToneAudioNode> { - +export class Gain< + TypeName extends "gain" | "decibels" | "normalRange" = "gain", +> extends ToneAudioNode> { readonly name: string = "Gain"; /** @@ -55,8 +56,16 @@ export class Gain constructor(gain?: UnitMap[TypeName], units?: TypeName); constructor(options?: Partial>); constructor() { - super(optionsFromArguments(Gain.getDefaults(), arguments, ["gain", "units"])); - const options = optionsFromArguments(Gain.getDefaults(), arguments, ["gain", "units"]); + super( + optionsFromArguments(Gain.getDefaults(), arguments, [ + "gain", + "units", + ]) + ); + const options = optionsFromArguments(Gain.getDefaults(), arguments, [ + "gain", + "units", + ]); this.gain = new Param({ context: this.context, diff --git a/Tone/core/context/Listener.test.ts b/Tone/core/context/Listener.test.ts index ac3e03c3..46bca3ed 100644 --- a/Tone/core/context/Listener.test.ts +++ b/Tone/core/context/Listener.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { getContext } from "../Global"; -import { ListenerClass } from "./Listener"; +import { Offline } from "../../../test/helper/Offline.js"; +import { getContext } from "../Global.js"; +import { ListenerClass } from "./Listener.js"; describe("Listener", () => { - it("creates itself on the context", () => { expect(getContext().listener).instanceOf(ListenerClass); }); diff --git a/Tone/core/context/Listener.ts b/Tone/core/context/Listener.ts index 68c0f7f1..4ccc93e0 100644 --- a/Tone/core/context/Listener.ts +++ b/Tone/core/context/Listener.ts @@ -1,8 +1,8 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode"; -import { Param } from "./Param"; -import { onContextClose, onContextInit } from "./ContextInitialization"; +import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode.js"; +import { Param } from "./Param.js"; +import { onContextClose, onContextInit } from "./ContextInitialization.js"; -export interface ListenerOptions extends ToneAudioNodeOptions{ +export interface ListenerOptions extends ToneAudioNodeOptions { positionX: number; positionY: number; positionZ: number; @@ -16,64 +16,63 @@ export interface ListenerOptions extends ToneAudioNodeOptions{ /** * Tone.Listener is a thin wrapper around the AudioListener. Listener combined - * with {@link Panner3D} makes up the Web Audio API's 3D panning system. Panner3D allows you + * with {@link Panner3D} makes up the Web Audio API's 3D panning system. Panner3D allows you * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from - * a first-person perspective. There is only one listener per audio context. + * a first-person perspective. There is only one listener per audio context. */ export class ListenerClass extends ToneAudioNode { - readonly name: string = "Listener"; /** - * The listener has no inputs or outputs. + * The listener has no inputs or outputs. */ - output: undefined; - input: undefined; + output: undefined; + input: undefined; readonly positionX: Param = new Param({ context: this.context, param: this.context.rawContext.listener.positionX, - }) + }); readonly positionY: Param = new Param({ context: this.context, param: this.context.rawContext.listener.positionY, - }) + }); readonly positionZ: Param = new Param({ context: this.context, param: this.context.rawContext.listener.positionZ, - }) + }); readonly forwardX: Param = new Param({ context: this.context, param: this.context.rawContext.listener.forwardX, - }) + }); readonly forwardY: Param = new Param({ context: this.context, param: this.context.rawContext.listener.forwardY, - }) + }); readonly forwardZ: Param = new Param({ context: this.context, param: this.context.rawContext.listener.forwardZ, - }) + }); readonly upX: Param = new Param({ context: this.context, param: this.context.rawContext.listener.upX, - }) + }); readonly upY: Param = new Param({ context: this.context, param: this.context.rawContext.listener.upY, - }) + }); readonly upZ: Param = new Param({ context: this.context, param: this.context.rawContext.listener.upZ, - }) + }); static getDefaults(): ListenerOptions { return Object.assign(ToneAudioNode.getDefaults(), { @@ -108,10 +107,10 @@ export class ListenerClass extends ToneAudioNode { // INITIALIZATION //------------------------------------- -onContextInit(context => { +onContextInit((context) => { context.listener = new ListenerClass({ context }); }); -onContextClose(context => { +onContextClose((context) => { context.listener.dispose(); }); diff --git a/Tone/core/context/Offline.test.ts b/Tone/core/context/Offline.test.ts index 2cc42e31..1c806a14 100644 --- a/Tone/core/context/Offline.test.ts +++ b/Tone/core/context/Offline.test.ts @@ -1,12 +1,11 @@ -import { TestAudioBuffer } from "@tonejs/plot"; +import { TestAudioBuffer } from "../../../test/helper/compare/TestAudioBuffer.js"; import { expect } from "chai"; -import { ToneOscillatorNode } from "Tone/source/oscillator/ToneOscillatorNode"; -import { noOp } from "../util/Interface"; -import { Offline } from "./Offline"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; +import { ToneOscillatorNode } from "../../source/oscillator/ToneOscillatorNode.js"; +import { noOp } from "../util/Interface.js"; +import { Offline } from "./Offline.js"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; describe("Offline", () => { - it("accepts a callback and a duration", () => { return Offline(noOp, 0.01); }); @@ -25,7 +24,7 @@ describe("Offline", () => { it("silent by default", () => { return Offline(noOp, 0.01, 1).then((buffer) => { - const isSilent = buffer.toArray().every(sample => sample === 0); + const isSilent = buffer.toArray().every((sample) => sample === 0); expect(isSilent).to.equal(true); }); }); diff --git a/Tone/core/context/Offline.ts b/Tone/core/context/Offline.ts index f33d6632..dc7ae3f5 100644 --- a/Tone/core/context/Offline.ts +++ b/Tone/core/context/Offline.ts @@ -1,13 +1,15 @@ -import { getContext, setContext } from "../Global"; -import { Seconds } from "../type/Units"; -import { OfflineContext } from "./OfflineContext"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; +import { getContext, setContext } from "../Global.js"; +import { Seconds } from "../type/Units.js"; +import { OfflineContext } from "./OfflineContext.js"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; +import "./Destination.js"; +import "./Listener.js"; /** * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext. * The OfflineAudioContext is capable of rendering much faster than real time in many cases. * The callback function also passes in an offline instance of {@link Context} which can be used - * to schedule events along the Transport. + * to schedule events along the Transport. * @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer. * @param duration the amount of time to record for. * @return The promise which is invoked with the ToneAudioBuffer of the recorded output. @@ -40,7 +42,7 @@ export async function Offline( callback: (context: OfflineContext) => Promise | void, duration: Seconds, channels = 2, - sampleRate: number = getContext().sampleRate, + sampleRate: number = getContext().sampleRate ): Promise { // set the OfflineAudioContext based on the current context const originalContext = getContext(); diff --git a/Tone/core/context/OfflineContext.test.ts b/Tone/core/context/OfflineContext.test.ts index 4afab912..eb32a243 100644 --- a/Tone/core/context/OfflineContext.test.ts +++ b/Tone/core/context/OfflineContext.test.ts @@ -1,8 +1,7 @@ import { expect } from "chai"; -import { OfflineContext } from "./OfflineContext"; +import { OfflineContext } from "./OfflineContext.js"; context("OfflineContext", () => { - it("can be created an disposed", () => { const ctx = new OfflineContext(1, 0.1, 44100); ctx.dispose(); @@ -31,7 +30,7 @@ context("OfflineContext", () => { const osc = ctx.createOscillator(); osc.connect(ctx.rawContext.destination); osc.start(0.1); - return ctx.render().then(buffer => { + return ctx.render().then((buffer) => { expect(buffer).to.have.property("length"); expect(buffer).to.have.property("sampleRate"); const array = buffer.getChannelData(0); @@ -49,7 +48,7 @@ context("OfflineContext", () => { const osc = ctx.createOscillator(); osc.connect(ctx.rawContext.destination); osc.start(0.1); - return ctx.render(false).then(buffer => { + return ctx.render(false).then((buffer) => { expect(buffer).to.have.property("length"); expect(buffer).to.have.property("sampleRate"); const array = buffer.getChannelData(0); diff --git a/Tone/core/context/OfflineContext.ts b/Tone/core/context/OfflineContext.ts index 971d17bb..fe19b11d 100644 --- a/Tone/core/context/OfflineContext.ts +++ b/Tone/core/context/OfflineContext.ts @@ -1,8 +1,8 @@ -import { createOfflineAudioContext } from "../context/AudioContext"; -import { Context } from "../context/Context"; -import { Seconds } from "../type/Units"; -import { isOfflineAudioContext } from "../util/AdvancedTypeCheck"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; +import { createOfflineAudioContext } from "../context/AudioContext.js"; +import { Context } from "../context/Context.js"; +import { Seconds } from "../type/Units.js"; +import { isOfflineAudioContext } from "../util/AdvancedTypeCheck.js"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; /** * Wrapper around the OfflineAudioContext @@ -16,7 +16,6 @@ import { ToneAudioBuffer } from "./ToneAudioBuffer"; * }); */ export class OfflineContext extends Context { - readonly name: string = "OfflineContext"; /** @@ -41,25 +40,27 @@ export class OfflineContext extends Context { * @param duration The duration to render in seconds * @param sampleRate the sample rate to render at */ - constructor( - channels: number, - duration: Seconds, - sampleRate: number, - ); + constructor(channels: number, duration: Seconds, sampleRate: number); constructor(context: OfflineAudioContext); constructor() { - super({ clockSource: "offline", - context: isOfflineAudioContext(arguments[0]) ? - arguments[0] : createOfflineAudioContext(arguments[0], arguments[1] * arguments[2], arguments[2]), + context: isOfflineAudioContext(arguments[0]) + ? arguments[0] + : createOfflineAudioContext( + arguments[0], + arguments[1] * arguments[2], + arguments[2] + ), lookAhead: 0, - updateInterval: isOfflineAudioContext(arguments[0]) ? - 128 / arguments[0].sampleRate : 128 / arguments[2], + updateInterval: isOfflineAudioContext(arguments[0]) + ? 128 / arguments[0].sampleRate + : 128 / arguments[2], }); - this._duration = isOfflineAudioContext(arguments[0]) ? - arguments[0].length / arguments[0].sampleRate : arguments[1]; + this._duration = isOfflineAudioContext(arguments[0]) + ? arguments[0].length / arguments[0].sampleRate + : arguments[1]; } /** @@ -82,7 +83,6 @@ export class OfflineContext extends Context { private async _renderClock(asynchronous: boolean): Promise { let index = 0; while (this._duration - this._currentTime >= 0) { - // invoke all the callbacks on that time this.emit("tick"); @@ -93,7 +93,7 @@ export class OfflineContext extends Context { index++; const yieldEvery = Math.floor(this.sampleRate / 128); if (asynchronous && index % yieldEvery === 0) { - await new Promise(done => setTimeout(done, 1)); + await new Promise((done) => setTimeout(done, 1)); } } } diff --git a/Tone/core/context/Param.test.ts b/Tone/core/context/Param.test.ts index e7477235..e8a721f2 100644 --- a/Tone/core/context/Param.test.ts +++ b/Tone/core/context/Param.test.ts @@ -1,18 +1,25 @@ -import { Compare, Plot } from "@tonejs/plot"; +import { Compare, Plot } from "../../../test/helper/compare/index.js"; import { expect } from "chai"; -import { BasicTests, testAudioContext } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { SCHEDULE_RAMP_AFTER_SET_TARGET } from "test/helper/Supports"; -import { BPM, Decibels, Frequency, Positive, Seconds, Time, Unit, UnitName } from "Tone/core/type/Units"; -import { Signal } from "Tone/signal/Signal"; -import { getContext } from "../Global"; -import { Param } from "./Param"; -import { connect } from "./ToneAudioNode"; +import { BasicTests, testAudioContext } from "../../../test/helper/Basic.js"; +import { atTime, Offline } from "../../../test/helper/Offline.js"; +import { + BPM, + Decibels, + Frequency, + Positive, + Seconds, + Time, + Unit, + UnitName, +} from "../type/Units.js"; +import { Signal } from "../../signal/Signal.js"; +import { getContext } from "../Global.js"; +import { Param } from "./Param.js"; +import { connect } from "./ToneAudioNode.js"; const audioContext = getContext(); describe("Param", () => { - BasicTests(Param, { context: testAudioContext, param: testAudioContext.createOscillator().frequency, @@ -20,7 +27,7 @@ describe("Param", () => { context("constructor", () => { it("can be created and disposed", async () => { - await Offline(context => { + await Offline((context) => { const param = new Param<"time">({ context, param: context.createConstantSource().offset, @@ -32,7 +39,7 @@ describe("Param", () => { }); it("can pass in a value", async () => { - await Offline(context => { + await Offline((context) => { const param = new Param({ context, param: context.createConstantSource().offset, @@ -53,24 +60,24 @@ describe("Param", () => { }); context("Scheduling Curves", () => { - const sampleRate = 11025; function matchesOutputCurve(param, outBuffer): void { outBuffer.toArray()[0].forEach((sample, index) => { try { - expect(param.getValueAtTime(index / sampleRate)).to.be.closeTo(sample, 0.1); + expect( + param.getValueAtTime(index / sampleRate) + ).to.be.closeTo(sample, 0.1); } catch (e) { throw e; } }); } - if (SCHEDULE_RAMP_AFTER_SET_TARGET) { - - it("correctly handles setTargetAtTime followed by a ramp", async () => { - let param; - // this fails on FF - const testBuffer = await Offline(context => { + it("correctly handles setTargetAtTime followed by a ramp", async () => { + let param; + // this fails on FF + const testBuffer = await Offline( + (context) => { const source = context.createConstantSource(); source.connect(context.rawContext.destination); source.start(0); @@ -82,14 +89,19 @@ describe("Param", () => { expect(param.getValueAtTime(0.6)).to.be.closeTo(1.6, 0.1); param.linearRampToValueAtTime(0.5, 0.7); expect(param.getValueAtTime(0.6)).to.be.closeTo(0.75, 0.1); - }, 1.5, 1, sampleRate); - document.body.appendChild(await Plot.signal(testBuffer)); - matchesOutputCurve(param, testBuffer); - }); + }, + 1.5, + 1, + sampleRate + ); + document.body.appendChild(await Plot.signal(testBuffer)); + matchesOutputCurve(param, testBuffer); + }); - it("schedules a value curve", async () => { - let param; - const testBuffer = await Offline(context => { + it("schedules a value curve", async () => { + let param; + const testBuffer = await Offline( + (context) => { const source = context.createConstantSource(); source.connect(context.rawContext.destination); source.start(0); @@ -99,16 +111,29 @@ describe("Param", () => { units: "number", value: 0, }); - param.setValueCurveAtTime([0, 0.5, 0, 1, 1.5], 0.1, 0.8, 0.5); - expect(param.getValueAtTime(0.91)).to.be.closeTo(0.75, 0.01); - }, 1, 1, sampleRate); - document.body.appendChild(await Plot.signal(testBuffer)); - matchesOutputCurve(param, testBuffer); - }); + param.setValueCurveAtTime( + [0, 0.5, 0, 1, 1.5], + 0.1, + 0.8, + 0.5 + ); + expect(param.getValueAtTime(0.91)).to.be.closeTo( + 0.75, + 0.01 + ); + }, + 1, + 1, + sampleRate + ); + // document.body.appendChild(await Plot.signal(testBuffer)); + matchesOutputCurve(param, testBuffer); + }); - it("a mixture of scheduling curves", async () => { - let param; - const testBuffer = await Offline(context => { + it("a mixture of scheduling curves", async () => { + let param; + const testBuffer = await Offline( + (context) => { const source = context.createConstantSource(); source.connect(context.rawContext.destination); source.start(0); @@ -131,14 +156,19 @@ describe("Param", () => { param.setValueAtTime(4, 1.2); param.cancelScheduledValues(1.2); param.linearRampToValueAtTime(1, 1.3); - }, 1.5, 1, sampleRate); - document.body.appendChild(await Plot.signal(testBuffer)); - matchesOutputCurve(param, testBuffer); - }); + }, + 1.5, + 1, + sampleRate + ); + // document.body.appendChild(await Plot.signal(testBuffer)); + matchesOutputCurve(param, testBuffer); + }); - it.skip("can cancel and hold", async () => { - let param; - const testBuffer = await Offline(context => { + it.skip("can cancel and hold", async () => { + let param; + const testBuffer = await Offline( + (context) => { const source = context.createConstantSource(); source.connect(context.rawContext.destination); source.start(0); @@ -155,18 +185,28 @@ describe("Param", () => { expect(param.getValueAtTime(0.2)).to.be.closeTo(0.5, 0.001); param.exponentialRampToValueAtTime(0, 0.4); param.cancelAndHoldAtTime(0.25); - expect(param.getValueAtTime(0.25)).to.be.closeTo(0.033, 0.001); + expect(param.getValueAtTime(0.25)).to.be.closeTo( + 0.033, + 0.001 + ); param.setTargetAtTime(1, 0.3, 0.1); param.cancelAndHoldAtTime(0.4); - expect(param.getValueAtTime(0.4)).to.be.closeTo(0.644, 0.001); + expect(param.getValueAtTime(0.4)).to.be.closeTo( + 0.644, + 0.001 + ); param.setValueAtTime(0, 0.45); param.setValueAtTime(1, 0.48); param.cancelAndHoldAtTime(0.45); expect(param.getValueAtTime(0.45)).to.be.closeTo(0, 0.001); - }, 0.5, 1, sampleRate); - matchesOutputCurve(param, testBuffer); - // document.body.appendChild(await Plot.signal(testBuffer)); - }); + }, + 0.5, + 1, + sampleRate + ); + matchesOutputCurve(param, testBuffer); + // document.body.appendChild(await Plot.signal(testBuffer)); + }); // it ("matches known values", async () => { // await Compare.toFile(context => { @@ -189,12 +229,9 @@ describe("Param", () => { // param.cancelAndHoldAtTime(0.4); // }, "/base/test/audio/param/curve_0.wav", 0.01, 0.5, 1, 11025); // }); - } - }); context("Units", () => { - it("throws an error with invalid values", () => { const osc = audioContext.createOscillator(); const param = new Param<"frequency">({ @@ -249,28 +286,31 @@ describe("Param", () => { }); it("can be forced to not convert", async () => { - const testBuffer = await Offline(context => { - const source = context.createConstantSource(); - source.connect(context.rawContext.destination); - source.start(0); - const param = new Param({ - context, - convert: false, - param: source.offset, - units: "decibels", - }); - param.value = -10; - expect(param.value).to.be.closeTo(-10, 0.01); - }, 0.001, 1); + const testBuffer = await Offline( + (context) => { + const source = context.createConstantSource(); + source.connect(context.rawContext.destination); + source.start(0); + const param = new Param({ + context, + convert: false, + param: source.offset, + units: "decibels", + }); + param.value = -10; + expect(param.value).to.be.closeTo(-10, 0.01); + }, + 0.001, + 1 + ); expect(testBuffer.getValueAtTime(0)).to.be.closeTo(-10, 0.01); }); - }); context("apply", () => { it("can apply a scheduled curve", () => { let sig; - return Offline(context => { + return Offline((context) => { const signal = new Signal(); sig = signal; signal.setValueAtTime(0, 0); @@ -285,17 +325,20 @@ describe("Param", () => { return atTime(0.4, () => { signal.apply(source.offset); }); - }, 2).then(async buffer => { + }, 2).then(async (buffer) => { for (let time = 0.41; time < 2; time += 0.1) { - expect(buffer.getValueAtTime(time)).to.be.closeTo(sig.getValueAtTime(time), 0.01); + expect(buffer.getValueAtTime(time)).to.be.closeTo( + sig.getValueAtTime(time), + 0.01 + ); } - // document.body.appendChild(await Plot.signal(buffer)); + document.body.appendChild(await Plot.signal(buffer)); }); }); it("can apply a scheduled curve that starts with a setTargetAtTime", () => { let sig; - return Offline(context => { + return Offline((context) => { const signal = new Signal(); sig = signal; signal.setTargetAtTime(2, 0, 0.2); @@ -305,9 +348,12 @@ describe("Param", () => { return atTime(0.4, () => { signal.apply(source.offset); }); - }, 2).then(async buffer => { + }, 2).then(async (buffer) => { for (let time = 0.41; time < 2; time += 0.1) { - expect(buffer.getValueAtTime(time)).to.be.closeTo(sig.getValueAtTime(time), 0.05); + expect(buffer.getValueAtTime(time)).to.be.closeTo( + sig.getValueAtTime(time), + 0.05 + ); } // document.body.appendChild(await Plot.signal(buffer)); }); @@ -315,7 +361,7 @@ describe("Param", () => { it("can apply a scheduled curve that starts with a setTargetAtTime and then schedules other things", () => { let sig; - return Offline(context => { + return Offline((context) => { const signal = new Signal(); sig = signal; signal.setTargetAtTime(2, 0, 0.2); @@ -327,16 +373,19 @@ describe("Param", () => { return atTime(0.4, () => { signal.apply(source.offset); }); - }, 2).then(async buffer => { + }, 2).then(async (buffer) => { for (let time = 0.41; time < 2; time += 0.1) { - expect(buffer.getValueAtTime(time)).to.be.closeTo(sig.getValueAtTime(time), 0.05); + expect(buffer.getValueAtTime(time)).to.be.closeTo( + sig.getValueAtTime(time), + 0.05 + ); } // document.body.appendChild(await Plot.signal(buffer)); }); }); it("can set the param if the Param is marked as swappable", () => { - return Offline(context => { + return Offline((context) => { const constSource = context.createConstantSource(); const param = new Param({ swappable: true, @@ -349,7 +398,7 @@ describe("Param", () => { constSource2.start(0); param.setParam(constSource2.offset); connect(constSource2, context.destination); - }, 0.5).then(buffer => { + }, 0.5).then((buffer) => { expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.1, 0.001); expect(buffer.getValueAtTime(0.2)).to.be.closeTo(0.2, 0.001); expect(buffer.getValueAtTime(0.3)).to.be.closeTo(0.3, 0.001); @@ -357,7 +406,7 @@ describe("Param", () => { }); it("throws an error if the param is not set to swappable", () => { - return Offline(context => { + return Offline((context) => { const constSource = context.createConstantSource(); const param = new Param({ param: constSource.offset, @@ -371,21 +420,36 @@ describe("Param", () => { }); context("Unit Conversions", () => { - function testUnitConversion(units: UnitName, inputValue: any, inputVerification: number, outputValue: number): void { + function testUnitConversion( + units: UnitName, + inputValue: any, + inputVerification: number, + outputValue: number + ): void { it(`converts to ${units}`, async () => { - const testBuffer = await Offline(context => { - const source = context.createConstantSource(); - source.connect(context.rawContext.destination); - source.start(0); - const param = new Param({ - context, - param: source.offset, - units, - }); - param.value = inputValue; - expect(param.value).to.be.closeTo(inputVerification, 0.01); - }, 0.001, 1); - expect(testBuffer.getValueAtTime(0)).to.be.closeTo(outputValue, 0.01); + const testBuffer = await Offline( + (context) => { + const source = context.createConstantSource(); + source.connect(context.rawContext.destination); + source.start(0); + const param = new Param({ + context, + param: source.offset, + units, + }); + param.value = inputValue; + expect(param.value).to.be.closeTo( + inputVerification, + 0.01 + ); + }, + 0.001, + 1 + ); + expect(testBuffer.getValueAtTime(0)).to.be.closeTo( + outputValue, + 0.01 + ); }); } @@ -424,7 +488,7 @@ describe("Param", () => { } // number, decibels, normalRange, audioRange, gain // positive, time, frequency, transportTime, ticks, bpm, degrees, samples, hertz - const rangeMax = 3.4028234663852886e+38; + const rangeMax = 3.4028234663852886e38; testMinMaxValue("number", -rangeMax, rangeMax); testMinMaxValue("decibels", -Infinity, rangeMax); testMinMaxValue("normalRange", 0, 1); @@ -480,36 +544,70 @@ describe("Param", () => { // const allSchedulingMethods = ['setValueAtTime', 'linearRampToValueAtTime', 'exponentialRampToValueAtTime'] context("setValueAtTime", () => { - function testSetValueAtTime(units: UnitName, value0, value1, value2): void { + function testSetValueAtTime( + units: UnitName, + value0, + value1, + value2 + ): void { it(`can schedule value with units ${units}`, async () => { - const testBuffer = await Offline(context => { - const source = context.createConstantSource(); - source.connect(context.rawContext.destination); - source.start(0); - const param = new Param({ - context, - param: source.offset, - units, - }); - param.setValueAtTime(value0, 0); - param.setValueAtTime(value1, 0.01); - param.setValueAtTime(value2, 0.02); - - expect(param.getValueAtTime(0)).to.be.closeTo(value0, 0.01); - expect(param.getValueAtTime(0.01)).to.be.closeTo(value1, 0.01); - expect(param.getValueAtTime(0.02)).to.be.closeTo(value2, 0.01); - }, 0.022, 1); + const testBuffer = await Offline( + (context) => { + const source = context.createConstantSource(); + source.connect(context.rawContext.destination); + source.start(0); + const param = new Param({ + context, + param: source.offset, + units, + }); + param.setValueAtTime(value0, 0); + param.setValueAtTime(value1, 0.01); + param.setValueAtTime(value2, 0.02); + + expect(param.getValueAtTime(0)).to.be.closeTo( + value0, + 0.01 + ); + expect(param.getValueAtTime(0.01)).to.be.closeTo( + value1, + 0.01 + ); + expect(param.getValueAtTime(0.02)).to.be.closeTo( + value2, + 0.01 + ); + }, + 0.022, + 1 + ); expect(testBuffer.getValueAtTime(0)).to.be.closeTo(0, 0.01); expect(testBuffer.getValueAtTime(0.011)).to.be.closeTo(1, 0.01); - expect(testBuffer.getValueAtTime(0.021)).to.be.closeTo(0.5, 0.01); + expect(testBuffer.getValueAtTime(0.021)).to.be.closeTo( + 0.5, + 0.01 + ); }); - } - const allUnits: UnitName[] = ["number", "decibels", "normalRange", "audioRange", "gain", - "positive", "time", "frequency", "transportTime", "ticks", "bpm", "degrees", "samples", "hertz"]; - - allUnits.forEach(unit => { + const allUnits: UnitName[] = [ + "number", + "decibels", + "normalRange", + "audioRange", + "gain", + "positive", + "time", + "frequency", + "transportTime", + "ticks", + "bpm", + "degrees", + "samples", + "hertz", + ]; + + allUnits.forEach((unit) => { if (unit === "decibels") { testSetValueAtTime(unit, -100, 0, -6); } else { @@ -518,90 +616,168 @@ describe("Param", () => { }); }); - ["linearRampToValueAtTime", "exponentialRampToValueAtTime"].forEach(method => { + ["linearRampToValueAtTime", "exponentialRampToValueAtTime"].forEach( + (method) => { + context(method, () => { + function testRampToValueAtTime( + units: UnitName, + value0, + value1, + value2 + ): void { + it(`can schedule value with units ${units}`, async () => { + const testBuffer = await Offline( + (context) => { + const source = context.createConstantSource(); + source.connect(context.rawContext.destination); + source.start(0); + const param = new Param({ + context, + param: source.offset, + units, + }); + param.setValueAtTime(value0, 0); + param[method](value1, 0.01); + param[method](value2, 0.02); + + expect(param.getValueAtTime(0)).to.be.closeTo( + value0, + 0.01 + ); + expect( + param.getValueAtTime(0.01) + ).to.be.closeTo(value1, 0.01); + expect( + param.getValueAtTime(0.02) + ).to.be.closeTo(value2, 0.01); + }, + 0.022, + 1 + ); + expect(testBuffer.getValueAtTime(0)).to.be.closeTo( + 1, + 0.01 + ); + expect(testBuffer.getValueAtTime(0.01)).to.be.closeTo( + 0.7, + 0.01 + ); + expect(testBuffer.getValueAtTime(0.02)).to.be.closeTo( + 0, + 0.01 + ); + }); + } - context(method, () => { - function testRampToValueAtTime(units: UnitName, value0, value1, value2): void { - it(`can schedule value with units ${units}`, async () => { - const testBuffer = await Offline(context => { - const source = context.createConstantSource(); - source.connect(context.rawContext.destination); - source.start(0); - const param = new Param({ - context, - param: source.offset, - units, - }); - param.setValueAtTime(value0, 0); - param[method](value1, 0.01); - param[method](value2, 0.02); - - expect(param.getValueAtTime(0)).to.be.closeTo(value0, 0.01); - expect(param.getValueAtTime(0.01)).to.be.closeTo(value1, 0.01); - expect(param.getValueAtTime(0.02)).to.be.closeTo(value2, 0.01); - }, 0.022, 1); - expect(testBuffer.getValueAtTime(0)).to.be.closeTo(1, 0.01); - expect(testBuffer.getValueAtTime(0.01)).to.be.closeTo(0.7, 0.01); - expect(testBuffer.getValueAtTime(0.02)).to.be.closeTo(0, 0.01); + const allUnits: UnitName[] = [ + "number", + "decibels", + "normalRange", + "audioRange", + "gain", + "positive", + "time", + "frequency", + "transportTime", + "ticks", + "bpm", + "degrees", + "samples", + "hertz", + ]; + + allUnits.forEach((unit) => { + if (unit === "decibels") { + testRampToValueAtTime(unit, 0, -3, -100); + } else { + testRampToValueAtTime(unit, 1, 0.7, 0); + } }); - - } - - const allUnits: UnitName[] = ["number", "decibels", "normalRange", "audioRange", "gain", - "positive", "time", "frequency", "transportTime", "ticks", "bpm", "degrees", "samples", "hertz"]; - - allUnits.forEach(unit => { - if (unit === "decibels") { - testRampToValueAtTime(unit, 0, -3, -100); - } else { - testRampToValueAtTime(unit, 1, 0.7, 0); - } }); - }); - }); - - ["linearRampTo", "exponentialRampTo", "rampTo", "targetRampTo"].forEach(method => { + } + ); + + ["linearRampTo", "exponentialRampTo", "rampTo", "targetRampTo"].forEach( + (method) => { + context(method, () => { + function testRampToValueAtTime( + units: UnitName, + value0, + value1, + value2 + ): void { + it(`can schedule value with units ${units}`, async () => { + const testBuffer = await Offline( + (context) => { + const source = context.createConstantSource(); + source.connect(context.rawContext.destination); + source.start(0); + const param = new Param({ + context, + param: source.offset, + units, + value: value0, + }); + param[method](value1, 0.009, 0); + param[method](value2, 0.01, 0.01); + + expect(param.getValueAtTime(0)).to.be.closeTo( + value0, + 0.02 + ); + expect( + param.getValueAtTime(0.01) + ).to.be.closeTo(value1, 0.02); + if (units !== "decibels") { + expect( + param.getValueAtTime(0.025) + ).to.be.closeTo(value2, 0.01); + } + }, + 0.021, + 1 + ); + // document.body.appendChild(await Plot.signal(testBuffer)); + expect(testBuffer.getValueAtTime(0)).to.be.closeTo( + 1, + 0.01 + ); + expect(testBuffer.getValueAtTime(0.01)).to.be.closeTo( + 0.7, + 0.01 + ); + expect(testBuffer.getValueAtTime(0.02)).to.be.closeTo( + 0, + 0.01 + ); + }); + } - context(method, () => { - function testRampToValueAtTime(units: UnitName, value0, value1, value2): void { - it(`can schedule value with units ${units}`, async () => { - const testBuffer = await Offline(context => { - const source = context.createConstantSource(); - source.connect(context.rawContext.destination); - source.start(0); - const param = new Param({ - context, - param: source.offset, - units, - value: value0, - }); - param[method](value1, 0.009, 0); - param[method](value2, 0.01, 0.01); - - expect(param.getValueAtTime(0)).to.be.closeTo(value0, 0.02); - expect(param.getValueAtTime(0.01)).to.be.closeTo(value1, 0.02); - if (units !== "decibels") { - expect(param.getValueAtTime(0.025)).to.be.closeTo(value2, 0.01); - } - }, 0.021, 1); - // document.body.appendChild(await Plot.signal(testBuffer)); - expect(testBuffer.getValueAtTime(0)).to.be.closeTo(1, 0.01); - expect(testBuffer.getValueAtTime(0.01)).to.be.closeTo(0.7, 0.01); - expect(testBuffer.getValueAtTime(0.02)).to.be.closeTo(0, 0.01); + const allUnits: UnitName[] = [ + "number", + "decibels", + "normalRange", + "audioRange", + "gain", + "positive", + "time", + "frequency", + "transportTime", + "ticks", + "bpm", + "degrees", + "samples", + "hertz", + ]; + + allUnits.forEach((unit) => { + if (unit === "decibels") { + testRampToValueAtTime(unit, 0, -3, -100); + } else { + testRampToValueAtTime(unit, 1, 0.7, 0); + } }); - - } - - const allUnits: UnitName[] = ["number", "decibels", "normalRange", "audioRange", "gain", - "positive", "time", "frequency", "transportTime", "ticks", "bpm", "degrees", "samples", "hertz"]; - - allUnits.forEach(unit => { - if (unit === "decibels") { - testRampToValueAtTime(unit, 0, -3, -100); - } else { - testRampToValueAtTime(unit, 1, 0.7, 0); - } }); - }); - }); + } + ); }); diff --git a/Tone/core/context/Param.ts b/Tone/core/context/Param.ts index 9da94e58..f6be71ca 100644 --- a/Tone/core/context/Param.ts +++ b/Tone/core/context/Param.ts @@ -1,15 +1,23 @@ -import { AbstractParam } from "../context/AbstractParam"; -import { dbToGain, gainToDb } from "../type/Conversions"; -import { Decibels, Frequency, Positive, Time, UnitMap, UnitName } from "../type/Units"; -import { isAudioParam } from "../util/AdvancedTypeCheck"; -import { optionsFromArguments } from "../util/Defaults"; -import { Timeline } from "../util/Timeline"; -import { isDefined } from "../util/TypeCheck"; -import { ToneWithContext, ToneWithContextOptions } from "./ToneWithContext"; -import { EQ } from "../util/Math"; -import { assert, assertRange } from "../util/Debug"; - -export interface ParamOptions extends ToneWithContextOptions { +import { AbstractParam } from "../context/AbstractParam.js"; +import { dbToGain, gainToDb } from "../type/Conversions.js"; +import { + Decibels, + Frequency, + Positive, + Time, + UnitMap, + UnitName, +} from "../type/Units.js"; +import { isAudioParam } from "../util/AdvancedTypeCheck.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { Timeline } from "../util/Timeline.js"; +import { isDefined } from "../util/TypeCheck.js"; +import { ToneWithContext, ToneWithContextOptions } from "./ToneWithContext.js"; +import { EQ } from "../util/Math.js"; +import { assert, assertRange } from "../util/Debug.js"; + +export interface ParamOptions + extends ToneWithContextOptions { units: TypeName; value?: UnitMap[TypeName]; param: AudioParam | Param; @@ -22,7 +30,12 @@ export interface ParamOptions extends ToneWithContext /** * the possible automation types */ -type AutomationType = "linearRampToValueAtTime" | "exponentialRampToValueAtTime" | "setValueAtTime" | "setTargetAtTime" | "cancelScheduledValues"; +type AutomationType = + | "linearRampToValueAtTime" + | "exponentialRampToValueAtTime" + | "setValueAtTime" + | "setTargetAtTime" + | "cancelScheduledValues"; interface TargetAutomationEvent { type: "setTargetAtTime"; @@ -50,8 +63,8 @@ export type AutomationEvent = NormalAutomationEvent | TargetAutomationEvent; */ export class Param extends ToneWithContext> - implements AbstractParam { - + implements AbstractParam +{ readonly name: string = "Param"; readonly input: GainNode | AudioParam; @@ -88,7 +101,7 @@ export class Param /** * If the underlying AudioParam can be swapped out - * using the setParam method. + * using the setParam method. */ protected readonly _swappable: boolean; @@ -100,18 +113,33 @@ export class Param constructor(param: AudioParam, units?: TypeName, convert?: boolean); constructor(options: Partial>); constructor() { - super(optionsFromArguments(Param.getDefaults(), arguments, ["param", "units", "convert"])); - - const options = optionsFromArguments(Param.getDefaults(), arguments, ["param", "units", "convert"]); - - assert(isDefined(options.param) && - (isAudioParam(options.param) || options.param instanceof Param), "param must be an AudioParam"); + super( + optionsFromArguments(Param.getDefaults(), arguments, [ + "param", + "units", + "convert", + ]) + ); + + const options = optionsFromArguments(Param.getDefaults(), arguments, [ + "param", + "units", + "convert", + ]); + + assert( + isDefined(options.param) && + (isAudioParam(options.param) || options.param instanceof Param), + "param must be an AudioParam" + ); while (!isAudioParam(options.param)) { options.param = options.param._param; } - this._swappable = isDefined(options.swappable) ? options.swappable : false; + this._swappable = isDefined(options.swappable) + ? options.swappable + : false; if (this._swappable) { this.input = this.context.createGain(); // initialize @@ -128,7 +156,10 @@ export class Param this._maxValue = options.maxValue; // if the value is defined, set it immediately - if (isDefined(options.value) && options.value !== this._toType(this._initialValue)) { + if ( + isDefined(options.value) && + options.value !== this._toType(this._initialValue) + ) { this.setValueAtTime(options.value, 0); } } @@ -153,10 +184,17 @@ export class Param // if it's not the default minValue, return it if (isDefined(this._minValue)) { return this._minValue; - } else if (this.units === "time" || this.units === "frequency" || - this.units === "normalRange" || this.units === "positive" || - this.units === "transportTime" || this.units === "ticks" || - this.units === "bpm" || this.units === "hertz" || this.units === "samples") { + } else if ( + this.units === "time" || + this.units === "frequency" || + this.units === "normalRange" || + this.units === "positive" || + this.units === "transportTime" || + this.units === "ticks" || + this.units === "bpm" || + this.units === "hertz" || + this.units === "samples" + ) { return 0; } else if (this.units === "audioRange") { return -1; @@ -170,8 +208,10 @@ export class Param get maxValue(): number { if (isDefined(this._maxValue)) { return this._maxValue; - } else if (this.units === "normalRange" || - this.units === "audioRange") { + } else if ( + this.units === "normalRange" || + this.units === "audioRange" + ) { return 1; } else { return this._param.maxValue; @@ -190,7 +230,11 @@ export class Param */ private _assertRange(value: number): number { if (isDefined(this.maxValue) && isDefined(this.minValue)) { - assertRange(value, this._fromType(this.minValue), this._fromType(this.maxValue)); + assertRange( + value, + this._fromType(this.minValue), + this._fromType(this.maxValue) + ); } return value; } @@ -237,8 +281,10 @@ export class Param setValueAtTime(value: UnitMap[TypeName], time: Time): this { const computedTime = this.toSeconds(time); const numericValue = this._fromType(value); - assert(isFinite(numericValue) && isFinite(computedTime), - `Invalid argument(s) to setValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(time)}`); + assert( + isFinite(numericValue) && isFinite(computedTime), + `Invalid argument(s) to setValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(time)}` + ); this._assertRange(numericValue); this.log(this.units, "setValueAtTime", value, computedTime); this._events.add({ @@ -258,7 +304,10 @@ export class Param // if it was set by if (before === null) { value = this._initialValue; - } else if (before.type === "setTargetAtTime" && (after === null || after.type === "setValueAtTime")) { + } else if ( + before.type === "setTargetAtTime" && + (after === null || after.type === "setValueAtTime") + ) { const previous = this._events.getBefore(before.time); let previousVal; if (previous === null) { @@ -267,11 +316,20 @@ export class Param previousVal = previous.value; } if (before.type === "setTargetAtTime") { - value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, computedTime); + value = this._exponentialApproach( + before.time, + previousVal, + before.value, + before.constant, + computedTime + ); } } else if (after === null) { value = before.value; - } else if (after.type === "linearRampToValueAtTime" || after.type === "exponentialRampToValueAtTime") { + } else if ( + after.type === "linearRampToValueAtTime" || + after.type === "exponentialRampToValueAtTime" + ) { let beforeValue = before.value; if (before.type === "setTargetAtTime") { const previous = this._events.getBefore(before.time); @@ -282,9 +340,21 @@ export class Param } } if (after.type === "linearRampToValueAtTime") { - value = this._linearInterpolate(before.time, beforeValue, after.time, after.value, computedTime); + value = this._linearInterpolate( + before.time, + beforeValue, + after.time, + after.value, + computedTime + ); } else { - value = this._exponentialInterpolate(before.time, beforeValue, after.time, after.value, computedTime); + value = this._exponentialInterpolate( + before.time, + beforeValue, + after.time, + after.value, + computedTime + ); } } else { value = before.value; @@ -306,8 +376,10 @@ export class Param linearRampToValueAtTime(value: UnitMap[TypeName], endTime: Time): this { const numericValue = this._fromType(value); const computedTime = this.toSeconds(endTime); - assert(isFinite(numericValue) && isFinite(computedTime), - `Invalid argument(s) to linearRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`); + assert( + isFinite(numericValue) && isFinite(computedTime), + `Invalid argument(s) to linearRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}` + ); this._assertRange(numericValue); this._events.add({ time: computedTime, @@ -319,47 +391,79 @@ export class Param return this; } - exponentialRampToValueAtTime(value: UnitMap[TypeName], endTime: Time): this { + exponentialRampToValueAtTime( + value: UnitMap[TypeName], + endTime: Time + ): this { let numericValue = this._fromType(value); // the value can't be 0 numericValue = EQ(numericValue, 0) ? this._minOutput : numericValue; this._assertRange(numericValue); const computedTime = this.toSeconds(endTime); - assert(isFinite(numericValue) && isFinite(computedTime), - `Invalid argument(s) to exponentialRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`); + assert( + isFinite(numericValue) && isFinite(computedTime), + `Invalid argument(s) to exponentialRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}` + ); // store the event this._events.add({ time: computedTime, type: "exponentialRampToValueAtTime", value: numericValue, }); - this.log(this.units, "exponentialRampToValueAtTime", value, computedTime); + this.log( + this.units, + "exponentialRampToValueAtTime", + value, + computedTime + ); this._param.exponentialRampToValueAtTime(numericValue, computedTime); return this; } - exponentialRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + exponentialRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { startTime = this.toSeconds(startTime); this.setRampPoint(startTime); - this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + this.exponentialRampToValueAtTime( + value, + startTime + this.toSeconds(rampTime) + ); return this; } - linearRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + linearRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { startTime = this.toSeconds(startTime); this.setRampPoint(startTime); - this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + this.linearRampToValueAtTime( + value, + startTime + this.toSeconds(rampTime) + ); return this; } - targetRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + targetRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { startTime = this.toSeconds(startTime); this.setRampPoint(startTime); this.exponentialApproachValueAtTime(value, startTime, rampTime); return this; } - exponentialApproachValueAtTime(value: UnitMap[TypeName], time: Time, rampTime: Time): this { + exponentialApproachValueAtTime( + value: UnitMap[TypeName], + time: Time, + rampTime: Time + ): this { time = this.toSeconds(time); rampTime = this.toSeconds(rampTime); const timeConstant = Math.log(rampTime + 1) / Math.log(200); @@ -370,26 +474,46 @@ export class Param return this; } - setTargetAtTime(value: UnitMap[TypeName], startTime: Time, timeConstant: Positive): this { + setTargetAtTime( + value: UnitMap[TypeName], + startTime: Time, + timeConstant: Positive + ): this { const numericValue = this._fromType(value); // The value will never be able to approach without timeConstant > 0. - assert(isFinite(timeConstant) && timeConstant > 0, "timeConstant must be a number greater than 0"); + assert( + isFinite(timeConstant) && timeConstant > 0, + "timeConstant must be a number greater than 0" + ); const computedTime = this.toSeconds(startTime); this._assertRange(numericValue); - assert(isFinite(numericValue) && isFinite(computedTime), - `Invalid argument(s) to setTargetAtTime: ${JSON.stringify(value)}, ${JSON.stringify(startTime)}`); + assert( + isFinite(numericValue) && isFinite(computedTime), + `Invalid argument(s) to setTargetAtTime: ${JSON.stringify(value)}, ${JSON.stringify(startTime)}` + ); this._events.add({ constant: timeConstant, time: computedTime, type: "setTargetAtTime", value: numericValue, }); - this.log(this.units, "setTargetAtTime", value, computedTime, timeConstant); + this.log( + this.units, + "setTargetAtTime", + value, + computedTime, + timeConstant + ); this._param.setTargetAtTime(numericValue, computedTime, timeConstant); return this; } - setValueCurveAtTime(values: UnitMap[TypeName][], startTime: Time, duration: Time, scaling = 1): this { + setValueCurveAtTime( + values: UnitMap[TypeName][], + startTime: Time, + duration: Time, + scaling = 1 + ): this { duration = this.toSeconds(duration); startTime = this.toSeconds(startTime); const startingValue = this._fromType(values[0]) * scaling; @@ -397,14 +521,20 @@ export class Param const segTime = duration / (values.length - 1); for (let i = 1; i < values.length; i++) { const numericValue = this._fromType(values[i]) * scaling; - this.linearRampToValueAtTime(this._toType(numericValue), startTime + i * segTime); + this.linearRampToValueAtTime( + this._toType(numericValue), + startTime + i * segTime + ); } return this; } cancelScheduledValues(time: Time): this { const computedTime = this.toSeconds(time); - assert(isFinite(computedTime), `Invalid argument to cancelScheduledValues: ${JSON.stringify(time)}`); + assert( + isFinite(computedTime), + `Invalid argument to cancelScheduledValues: ${JSON.stringify(time)}` + ); this._events.cancel(computedTime); this._param.cancelScheduledValues(computedTime); this.log(this.units, "cancelScheduledValues", computedTime); @@ -415,10 +545,18 @@ export class Param const computedTime = this.toSeconds(time); const valueAtTime = this._fromType(this.getValueAtTime(computedTime)); // remove the schedule events - assert(isFinite(computedTime), `Invalid argument to cancelAndHoldAtTime: ${JSON.stringify(time)}`); + assert( + isFinite(computedTime), + `Invalid argument to cancelAndHoldAtTime: ${JSON.stringify(time)}` + ); + + this.log( + this.units, + "cancelAndHoldAtTime", + computedTime, + "value=" + valueAtTime + ); - this.log(this.units, "cancelAndHoldAtTime", computedTime, "value=" + valueAtTime); - // if there is an event at the given computedTime // and that even is not a "set" const before = this._events.get(computedTime); @@ -437,9 +575,15 @@ export class Param // cancel the next event(s) this._events.cancel(after.time); if (after.type === "linearRampToValueAtTime") { - this.linearRampToValueAtTime(this._toType(valueAtTime), computedTime); + this.linearRampToValueAtTime( + this._toType(valueAtTime), + computedTime + ); } else if (after.type === "exponentialRampToValueAtTime") { - this.exponentialRampToValueAtTime(this._toType(valueAtTime), computedTime); + this.exponentialRampToValueAtTime( + this._toType(valueAtTime), + computedTime + ); } } @@ -453,8 +597,16 @@ export class Param return this; } - rampTo(value: UnitMap[TypeName], rampTime: Time = 0.1, startTime?: Time): this { - if (this.units === "frequency" || this.units === "bpm" || this.units === "decibels") { + rampTo( + value: UnitMap[TypeName], + rampTime: Time = 0.1, + startTime?: Time + ): this { + if ( + this.units === "frequency" || + this.units === "bpm" || + this.units === "decibels" + ) { this.exponentialRampTo(value, rampTime, startTime); } else { this.linearRampTo(value, rampTime, startTime); @@ -480,10 +632,13 @@ export class Param const endTime = nextEvent ? nextEvent.time : now + 2; const subdivisions = (endTime - now) / 10; for (let i = now; i < endTime; i += subdivisions) { - param.linearRampToValueAtTime(this.getValueAtTime(i) as number, i); + param.linearRampToValueAtTime( + this.getValueAtTime(i) as number, + i + ); } } - this._events.forEachAfter(this.context.currentTime, event => { + this._events.forEachAfter(this.context.currentTime, (event) => { if (event.type === "cancelScheduledValues") { param.cancelScheduledValues(event.time); } else if (event.type === "setTargetAtTime") { @@ -496,11 +651,14 @@ export class Param } /** - * Replace the Param's internal AudioParam. Will apply scheduled curves + * Replace the Param's internal AudioParam. Will apply scheduled curves * onto the parameter and replace the connections. */ setParam(param: AudioParam): this { - assert(this._swappable, "The Param must be assigned as 'swappable' in the constructor"); + assert( + this._swappable, + "The Param must be assigned as 'swappable' in the constructor" + ); const input = this.input as GainNode; input.disconnect(this._param); this.apply(param); @@ -525,17 +683,35 @@ export class Param //------------------------------------- // Calculates the the value along the curve produced by setTargetAtTime - protected _exponentialApproach(t0: number, v0: number, v1: number, timeConstant: number, t: number): number { + protected _exponentialApproach( + t0: number, + v0: number, + v1: number, + timeConstant: number, + t: number + ): number { return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant); } // Calculates the the value along the curve produced by linearRampToValueAtTime - protected _linearInterpolate(t0: number, v0: number, t1: number, v1: number, t: number): number { + protected _linearInterpolate( + t0: number, + v0: number, + t1: number, + v1: number, + t: number + ): number { return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); } // Calculates the the value along the curve produced by exponentialRampToValueAtTime - protected _exponentialInterpolate(t0: number, v0: number, t1: number, v1: number, t: number): number { + protected _exponentialInterpolate( + t0: number, + v0: number, + t1: number, + v1: number, + t: number + ): number { return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); } } diff --git a/Tone/core/context/ToneAudioBuffer.test.ts b/Tone/core/context/ToneAudioBuffer.test.ts index 7868aff3..3258ab32 100644 --- a/Tone/core/context/ToneAudioBuffer.test.ts +++ b/Tone/core/context/ToneAudioBuffer.test.ts @@ -1,20 +1,17 @@ import { expect } from "chai"; -import "test/helper/ToneAudioBuffer"; -import { getContext } from "../Global"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; +import { getContext } from "../Global.js"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; -const testFile = "./audio/sine.wav"; +const testFile = "./test/audio/sine.wav"; describe("ToneAudioBuffer", () => { - context("basic", () => { - it("can be created and disposed", () => { const buff = new ToneAudioBuffer(testFile); buff.dispose(); }); - it("loads a file from a url string", done => { + it("loads a file from a url string", (done) => { const buffer = new ToneAudioBuffer(testFile, (buff) => { expect(buff).to.be.instanceof(ToneAudioBuffer); buffer.dispose(); @@ -22,7 +19,7 @@ describe("ToneAudioBuffer", () => { }); }); - it("has a duration", done => { + it("has a duration", (done) => { const buffer = new ToneAudioBuffer(testFile, () => { expect(buffer.duration).to.be.closeTo(3, 0.01); buffer.dispose(); @@ -38,7 +35,7 @@ describe("ToneAudioBuffer", () => { buffer.dispose(); }); - it("can get the number of channels", done => { + it("can get the number of channels", (done) => { const buffer = new ToneAudioBuffer(testFile, () => { expect(buffer.numberOfChannels).to.be.equal(1); buffer.dispose(); @@ -46,7 +43,7 @@ describe("ToneAudioBuffer", () => { }); }); - it("can get the length of the buffer", done => { + it("can get the length of the buffer", (done) => { const buffer = new ToneAudioBuffer(testFile, () => { expect(buffer.length).to.be.a("number"); expect(buffer.length).to.be.above(130000); @@ -55,7 +52,7 @@ describe("ToneAudioBuffer", () => { }); }); - it("can be constructed with an options object", done => { + it("can be constructed with an options object", (done) => { const buffer = new ToneAudioBuffer({ onload: () => { buffer.dispose(); @@ -89,12 +86,14 @@ describe("ToneAudioBuffer", () => { buffer.dispose(); }); - it("takes an unloaded Tone.ToneAudioBuffer in the constructor method", done => { + it("takes an unloaded Tone.ToneAudioBuffer in the constructor method", (done) => { const unloadedToneAudioBuffer = new ToneAudioBuffer(testFile); const buffer = new ToneAudioBuffer({ onload(): void { const testOne = new ToneAudioBuffer(buffer); - expect(unloadedToneAudioBuffer.get()).to.equal(buffer.get()); + expect(unloadedToneAudioBuffer.get()).to.equal( + buffer.get() + ); unloadedToneAudioBuffer.dispose(); buffer.dispose(); done(); @@ -103,7 +102,7 @@ describe("ToneAudioBuffer", () => { }); }); - it("takes Tone.ToneAudioBuffer in the set method", done => { + it("takes Tone.ToneAudioBuffer in the set method", (done) => { const buffer = new ToneAudioBuffer({ url: testFile, onload(): void { @@ -116,18 +115,20 @@ describe("ToneAudioBuffer", () => { }, }); }); - }); context("loading", () => { - - it("invokes the error callback if there is a problem with the file", done => { - const buffer = new ToneAudioBuffer("nosuchfile.wav", () => { - throw new Error("shouldn't invoke this function"); - }, e => { - buffer.dispose(); - done(); - }); + it("invokes the error callback if there is a problem with the file", (done) => { + const buffer = new ToneAudioBuffer( + "nosuchfile.wav", + () => { + throw new Error("shouldn't invoke this function"); + }, + (e) => { + buffer.dispose(); + done(); + } + ); }); it("invokes the error callback on static .load method", async () => { @@ -141,17 +142,21 @@ describe("ToneAudioBuffer", () => { }); it("can load a file with fallback extensions", async () => { - const buffer = await ToneAudioBuffer.load("./audio/sine.[nope|nada|wav]"); + const buffer = await ToneAudioBuffer.load( + "./test/audio/sine.[nope|nada|wav]" + ); expect(buffer).to.exist; }); it("takes the first supported format when multiple extensions are provided", async () => { - const buffer = await ToneAudioBuffer.load("./audio/sine.[wav|nope]"); + const buffer = await ToneAudioBuffer.load( + "./test/audio/sine.[wav|nope]" + ); expect(buffer).to.exist; }); - it("instance .load method returns Promise", done => { - const promise = (new ToneAudioBuffer()).load(testFile); + it("instance .load method returns Promise", (done) => { + const promise = new ToneAudioBuffer().load(testFile); expect(promise).to.have.property("then"); promise.then((buff) => { expect(buff).to.be.instanceOf(ToneAudioBuffer); @@ -162,34 +167,39 @@ describe("ToneAudioBuffer", () => { }); }); - it("invokes the error callback if the file is corrupt", done => { - const buffer = new ToneAudioBuffer("./audio/corrupt.wav", () => { - throw new Error("shouldn't invoke this function"); - }, e => { - buffer.dispose(); - done(); - }); + it("invokes the error callback if the file is corrupt", (done) => { + const buffer = new ToneAudioBuffer( + "./test/audio/corrupt.wav", + () => { + throw new Error("shouldn't invoke this function"); + }, + (e) => { + buffer.dispose(); + done(); + } + ); }); }); context("buffer manipulation", () => { - it("returns an empty array if there is no channel data", () => { const buffer = new ToneAudioBuffer(); expect(buffer.getChannelData(0).length).to.equal(0); buffer.dispose(); }); - it("can get the channel data as an array", done => { + it("can get the channel data as an array", (done) => { const buffer = new ToneAudioBuffer(testFile, () => { - expect(buffer.getChannelData(0)).to.be.an.instanceOf(Float32Array); + expect(buffer.getChannelData(0)).to.be.an.instanceOf( + Float32Array + ); expect(buffer.getChannelData(0).length).to.be.above(130000); buffer.dispose(); done(); }); }); - it("can reverse a buffer", done => { + it("can reverse a buffer", (done) => { const buffer = new ToneAudioBuffer(testFile, () => { const buffArray = buffer.get() as AudioBuffer; const lastSample = buffArray[buffArray.length - 1]; @@ -230,7 +240,10 @@ describe("ToneAudioBuffer", () => { it("can convert from a multidimentional array", () => { const buffer = new ToneAudioBuffer(); - const arr = [new Float32Array(0.5 * buffer.sampleRate), new Float32Array(0.5 * buffer.sampleRate)]; + const arr = [ + new Float32Array(0.5 * buffer.sampleRate), + new Float32Array(0.5 * buffer.sampleRate), + ]; arr[0][0] = 0.5; buffer.fromArray(arr); expect(buffer.duration).to.equal(0.5); @@ -241,7 +254,10 @@ describe("ToneAudioBuffer", () => { it("can convert to and from an array", () => { const buffer = new ToneAudioBuffer(); - const arr = [new Float32Array(0.5 * buffer.sampleRate), new Float32Array(0.5 * buffer.sampleRate)]; + const arr = [ + new Float32Array(0.5 * buffer.sampleRate), + new Float32Array(0.5 * buffer.sampleRate), + ]; arr[0][0] = 0.5; buffer.fromArray(arr); expect(buffer.toArray(0)[0]).to.equal(0.5); @@ -264,8 +280,11 @@ describe("ToneAudioBuffer", () => { const sliced2 = sliced1.slice(0.5); expect(sliced2.duration).to.be.closeTo(0.5, 0.01); const sliced3 = buffer.slice(2); - expect(sliced3.toArray(0)[Math.floor(0.5 * buffer.sampleRate) + 1]) - .to.equal(buffer.toArray(0)[Math.floor(2.5 * buffer.sampleRate) + 1]); + expect( + sliced3.toArray(0)[Math.floor(0.5 * buffer.sampleRate) + 1] + ).to.equal( + buffer.toArray(0)[Math.floor(2.5 * buffer.sampleRate) + 1] + ); buffer.dispose(); sliced1.dispose(); sliced2.dispose(); @@ -284,7 +303,10 @@ describe("ToneAudioBuffer", () => { it("can convert a buffer to mono", () => { const buffer = new ToneAudioBuffer(); - const arr = [new Float32Array(0.5 * buffer.sampleRate), new Float32Array(0.5 * buffer.sampleRate)]; + const arr = [ + new Float32Array(0.5 * buffer.sampleRate), + new Float32Array(0.5 * buffer.sampleRate), + ]; arr[0][0] = 0.5; buffer.fromArray(arr); expect(buffer.duration).to.equal(0.5); @@ -298,7 +320,10 @@ describe("ToneAudioBuffer", () => { it("can use just the second channel of a buffer when making mono", () => { const buffer = new ToneAudioBuffer(); - const arr = [new Float32Array(0.5 * buffer.sampleRate), new Float32Array(0.5 * buffer.sampleRate)]; + const arr = [ + new Float32Array(0.5 * buffer.sampleRate), + new Float32Array(0.5 * buffer.sampleRate), + ]; arr[0][0] = 0.5; buffer.fromArray(arr); expect(buffer.duration).to.equal(0.5); @@ -312,20 +337,25 @@ describe("ToneAudioBuffer", () => { }); context("static methods", () => { - it("Test if the browser supports the given type", () => { expect(ToneAudioBuffer.supportsType("test.wav")).to.equal(true); expect(ToneAudioBuffer.supportsType("wav")).to.equal(true); - expect(ToneAudioBuffer.supportsType("path/to/test.wav")).to.equal(true); - expect(ToneAudioBuffer.supportsType("path/to/test.nope")).to.equal(false); - }); - - it("can be constructed with ToneAudioBuffer.fromUrl", done => { - ToneAudioBuffer.fromUrl("nosuchfile.wav").then(() => { - throw new Error("shouldn't invoke this function"); - }).catch(() => { - done(); - }); + expect(ToneAudioBuffer.supportsType("path/to/test.wav")).to.equal( + true + ); + expect(ToneAudioBuffer.supportsType("path/to/test.nope")).to.equal( + false + ); + }); + + it("can be constructed with ToneAudioBuffer.fromUrl", (done) => { + ToneAudioBuffer.fromUrl("nosuchfile.wav") + .then(() => { + throw new Error("shouldn't invoke this function"); + }) + .catch(() => { + done(); + }); }); }); diff --git a/Tone/core/context/ToneAudioBuffer.ts b/Tone/core/context/ToneAudioBuffer.ts index a471167c..be983737 100644 --- a/Tone/core/context/ToneAudioBuffer.ts +++ b/Tone/core/context/ToneAudioBuffer.ts @@ -1,10 +1,10 @@ -import { getContext } from "../Global"; -import { Tone } from "../Tone"; -import { Samples, Seconds } from "../type/Units"; -import { optionsFromArguments } from "../util/Defaults"; -import { noOp } from "../util/Interface"; -import { isArray, isNumber, isString } from "../util/TypeCheck"; -import { assert } from "../util/Debug"; +import { getContext } from "../Global.js"; +import { Tone } from "../Tone.js"; +import { Samples, Seconds } from "../type/Units.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { noOp } from "../util/Interface.js"; +import { isArray, isNumber, isString } from "../util/TypeCheck.js"; +import { assert } from "../util/Debug.js"; interface ToneAudioBufferOptions { url?: string | AudioBuffer | ToneAudioBuffer; @@ -397,9 +397,9 @@ export class ToneAudioBuffer extends Tone { const location = document.createElement("a"); location.href = baseUrl + url; location.pathname = (location.pathname + location.hash) - .split("/") - .map(encodeURIComponent) - .join("/"); + .split("/") + .map(encodeURIComponent) + .join("/"); const response = await fetch(location.href); if (!response.ok) { @@ -425,8 +425,8 @@ export class ToneAudioBuffer extends Tone { const extensions = url.split("."); const extension = extensions[extensions.length - 1]; const response = document - .createElement("audio") - .canPlayType("audio/" + extension); + .createElement("audio") + .canPlayType("audio/" + extension); return response !== ""; } diff --git a/Tone/core/context/ToneAudioBuffers.test.ts b/Tone/core/context/ToneAudioBuffers.test.ts index 574d2509..2cbc96e3 100644 --- a/Tone/core/context/ToneAudioBuffers.test.ts +++ b/Tone/core/context/ToneAudioBuffers.test.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; -import "test/helper/ToneAudioBuffer"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; -import { ToneAudioBuffers } from "./ToneAudioBuffers"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; +import { ToneAudioBuffers } from "./ToneAudioBuffers.js"; -const testFile = "./audio/sine.wav"; -const testFile2 = "./audio/hh.wav"; +const testFile = "./test/audio/sine.wav"; +const testFile2 = "./test/audio/hh.wav"; describe("ToneAudioBuffers", () => { it("can be created and disposed", () => { @@ -12,55 +11,67 @@ describe("ToneAudioBuffers", () => { buff.dispose(); }); - it("loads a file from an object string", done => { - const buffer = new ToneAudioBuffers({ - sine: testFile, - }, () => { - expect(buffer).to.be.instanceof(ToneAudioBuffers); - buffer.dispose(); - done(); - }); + it("loads a file from an object string", (done) => { + const buffer = new ToneAudioBuffers( + { + sine: testFile, + }, + () => { + expect(buffer).to.be.instanceof(ToneAudioBuffers); + buffer.dispose(); + done(); + } + ); }); - it("can get a buffer loaded from an object", done => { - const buffer = new ToneAudioBuffers({ - kick: testFile2, - sine: testFile, - }, () => { - expect(buffer.get("kick")).to.be.instanceof(ToneAudioBuffer); - buffer.dispose(); - done(); - }); + it("can get a buffer loaded from an object", (done) => { + const buffer = new ToneAudioBuffers( + { + kick: testFile2, + sine: testFile, + }, + () => { + expect(buffer.get("kick")).to.be.instanceof(ToneAudioBuffer); + buffer.dispose(); + done(); + } + ); }); - it("throws an error when it tries to get an object that doesnt exist", done => { - const buffer = new ToneAudioBuffers({ - sine: testFile, - }, () => { - expect(() => { - buffer.get("nope"); - }).throws(Error); - buffer.dispose(); - done(); - }); + it("throws an error when it tries to get an object that doesnt exist", (done) => { + const buffer = new ToneAudioBuffers( + { + sine: testFile, + }, + () => { + expect(() => { + buffer.get("nope"); + }).throws(Error); + buffer.dispose(); + done(); + } + ); }); - it("tests if it has a buffer", done => { - const buffer = new ToneAudioBuffers({ - kick: testFile2, - sine: testFile, - }, () => { - expect(buffer.has("kick")).to.be.true; - expect(buffer.has("sine")).to.be.true; - expect(buffer.has("nope")).to.be.false; - buffer.dispose(); - done(); - }); + it("tests if it has a buffer", (done) => { + const buffer = new ToneAudioBuffers( + { + kick: testFile2, + sine: testFile, + }, + () => { + expect(buffer.has("kick")).to.be.true; + expect(buffer.has("sine")).to.be.true; + expect(buffer.has("nope")).to.be.false; + buffer.dispose(); + done(); + } + ); }); - it("can pass in buffers as object and options object in second arg", done => { + it("can pass in buffers as object and options object in second arg", (done) => { const buffer = new ToneAudioBuffers({ - baseUrl: "./audio/", + baseUrl: "./test/audio/", onload(): void { expect(buffer.has("sine")).to.be.true; buffer.dispose(); @@ -72,7 +83,7 @@ describe("ToneAudioBuffers", () => { }); }); - it("invokes onerror if it cant load the url", done => { + it("invokes onerror if it cant load the url", (done) => { const buffer = new ToneAudioBuffers({ onerror(): void { buffer.dispose(); @@ -84,29 +95,36 @@ describe("ToneAudioBuffers", () => { }); }); - it("reports itself as loaded", done => { - const buffer = new ToneAudioBuffers({ - kick: testFile2, - sine: testFile, - }, () => { - expect(buffer.loaded).to.be.true; - buffer.dispose(); - done(); - }); + it("reports itself as loaded", (done) => { + const buffer = new ToneAudioBuffers( + { + kick: testFile2, + sine: testFile, + }, + () => { + expect(buffer.loaded).to.be.true; + buffer.dispose(); + done(); + } + ); expect(buffer.loaded).to.be.false; }); - it("can load from a base url", done => { - const buffer = new ToneAudioBuffers({ - hat: "hh.wav", - }, () => { - expect(buffer.get("hat")).to.be.instanceof(ToneAudioBuffer); - buffer.dispose(); - done(); - }, "./audio/"); + it("can load from a base url", (done) => { + const buffer = new ToneAudioBuffers( + { + hat: "hh.wav", + }, + () => { + expect(buffer.get("hat")).to.be.instanceof(ToneAudioBuffer); + buffer.dispose(); + done(); + }, + "./test/audio/" + ); }); - it("can add a buffer", done => { + it("can add a buffer", (done) => { const buffer = new ToneAudioBuffers(); buffer.add("name", testFile, () => { expect(buffer.get("name")).to.be.instanceof(ToneAudioBuffer); @@ -115,7 +133,7 @@ describe("ToneAudioBuffers", () => { }); }); - it("can add a buffer url", done => { + it("can add a buffer url", (done) => { const buffer = new ToneAudioBuffers(); buffer.add("name", testFile, () => { expect(buffer.get("name")).to.be.instanceof(ToneAudioBuffer); @@ -139,7 +157,7 @@ describe("ToneAudioBuffers", () => { expect(buffer.get("name").get()).to.equal(buff.get()); }); - it("can add an AudioBuffer", done => { + it("can add an AudioBuffer", (done) => { ToneAudioBuffer.load(testFile).then((buff) => { const buffer = new ToneAudioBuffers(); buffer.add("name", buff); @@ -155,5 +173,4 @@ describe("ToneAudioBuffers", () => { }); expect(buffer.get("buff").get()).to.equal(buff.get()); }); - }); diff --git a/Tone/core/context/ToneAudioBuffers.ts b/Tone/core/context/ToneAudioBuffers.ts index dd44727e..dc2020a7 100644 --- a/Tone/core/context/ToneAudioBuffers.ts +++ b/Tone/core/context/ToneAudioBuffers.ts @@ -1,9 +1,9 @@ -import { Tone } from "../Tone"; -import { optionsFromArguments } from "../util/Defaults"; -import { noOp } from "../util/Interface"; -import { isString } from "../util/TypeCheck"; -import { ToneAudioBuffer } from "./ToneAudioBuffer"; -import { assert } from "../util/Debug"; +import { Tone } from "../Tone.js"; +import { optionsFromArguments } from "../util/Defaults.js"; +import { noOp } from "../util/Interface.js"; +import { isString } from "../util/TypeCheck.js"; +import { ToneAudioBuffer } from "./ToneAudioBuffer.js"; +import { assert } from "../util/Debug.js"; export interface ToneAudioBuffersUrlMap { [name: string]: string | AudioBuffer | ToneAudioBuffer; @@ -43,7 +43,6 @@ interface ToneAudioBuffersOptions { * @category Core */ export class ToneAudioBuffers extends Tone { - readonly name: string = "ToneAudioBuffers"; /** @@ -69,24 +68,30 @@ export class ToneAudioBuffers extends Tone { constructor( urls?: ToneAudioBuffersUrlMap, onload?: () => void, - baseUrl?: string, + baseUrl?: string ); constructor(options?: Partial); constructor() { - super(); const options = optionsFromArguments( - ToneAudioBuffers.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls", + ToneAudioBuffers.getDefaults(), + arguments, + ["urls", "onload", "baseUrl"], + "urls" ); this.baseUrl = options.baseUrl; // add each one - Object.keys(options.urls).forEach(name => { + Object.keys(options.urls).forEach((name) => { this._loadingCount++; const url = options.urls[name]; - this.add(name, url, this._bufferLoaded.bind(this, options.onload), options.onerror); + this.add( + name, + url, + this._bufferLoaded.bind(this, options.onload), + options.onerror + ); }); - } static getDefaults(): ToneAudioBuffersOptions { @@ -144,23 +149,32 @@ export class ToneAudioBuffers extends Tone { name: string | number, url: string | AudioBuffer | ToneAudioBuffer, callback: () => void = noOp, - onerror: (e: Error) => void = noOp, + onerror: (e: Error) => void = noOp ): this { if (isString(url)) { // don't include the baseUrl if the url is a base64 encoded sound - if (this.baseUrl && url.trim().substring(0, 11).toLowerCase() === "data:audio/") { + if ( + this.baseUrl && + url.trim().substring(0, 11).toLowerCase() === "data:audio/" + ) { this.baseUrl = ""; } - this._buffers.set(name.toString(), new ToneAudioBuffer(this.baseUrl + url, callback, onerror)); + this._buffers.set( + name.toString(), + new ToneAudioBuffer(this.baseUrl + url, callback, onerror) + ); } else { - this._buffers.set(name.toString(), new ToneAudioBuffer(url, callback, onerror)); + this._buffers.set( + name.toString(), + new ToneAudioBuffer(url, callback, onerror) + ); } return this; } dispose(): this { super.dispose(); - this._buffers.forEach(buffer => buffer.dispose()); + this._buffers.forEach((buffer) => buffer.dispose()); this._buffers.clear(); return this; } diff --git a/Tone/core/context/ToneAudioNode.test.ts b/Tone/core/context/ToneAudioNode.test.ts index 95cb6610..cc0dd859 100644 --- a/Tone/core/context/ToneAudioNode.test.ts +++ b/Tone/core/context/ToneAudioNode.test.ts @@ -1,14 +1,13 @@ import { expect } from "chai"; -import { Merge } from "Tone/component"; -import { Split } from "Tone/component/channel/Split"; -import { Oscillator } from "Tone/source"; -import { Gain } from "./Gain"; -import { connect, disconnect, fanIn } from "./ToneAudioNode"; -import { PassAudio } from "test/helper/PassAudio"; -import { Offline } from "test/helper/Offline"; +import { Merge } from "../../component/index.js"; +import { Split } from "../../component/channel/Split.js"; +import { Oscillator } from "../../source/index.js"; +import { Gain } from "./Gain.js"; +import { connect, disconnect, fanIn } from "./ToneAudioNode.js"; +import { PassAudio } from "../../../test/helper/PassAudio.js"; +import { Offline } from "../../../test/helper/Offline.js"; describe("ToneAudioNode", () => { - context("constructor", () => { it("can be created and disposed", () => { const node = new Gain(); @@ -17,7 +16,6 @@ describe("ToneAudioNode", () => { }); context("properties", () => { - it("reports its inputs and outputs", () => { const node = new Gain(); expect(node.numberOfInputs).to.equal(1); @@ -195,16 +193,15 @@ describe("ToneAudioNode", () => { }); context("connect native node", () => { - it("can create a connection", () => { - return PassAudio(input => { + return PassAudio((input) => { const output = input.context.destination; connect(input, output); }); }); it("can disconnect two nodes", () => { - return PassAudio(input => { + return PassAudio((input) => { const output = input.context.destination; connect(input, output); disconnect(input, output); @@ -212,7 +209,7 @@ describe("ToneAudioNode", () => { }); it("can disconnect a node", () => { - PassAudio(input => { + PassAudio((input) => { const output = input.context.destination; connect(input, output); disconnect(input); @@ -220,7 +217,7 @@ describe("ToneAudioNode", () => { }); it("can fan in multiple nodes to a destination", () => { - return PassAudio(input => { + return PassAudio((input) => { const context = input.context; const gain0 = context.createGain(); const gain1 = context.createGain(); @@ -228,9 +225,9 @@ describe("ToneAudioNode", () => { fanIn(gain0, gain1, input, output); }); }); - + it("can connect one channel to another", () => { - return PassAudio(input => { + return PassAudio((input) => { const context = input.context; const output = input.context.destination; const merge = context.createChannelMerger(2); @@ -240,9 +237,9 @@ describe("ToneAudioNode", () => { connect(split, output, 1, 0); }); }); - + it("can disconnect from an explicit channel", () => { - return PassAudio(input => { + return PassAudio((input) => { const context = input.context; const output = input.context.destination; const merge = context.createChannelMerger(2); @@ -253,7 +250,7 @@ describe("ToneAudioNode", () => { disconnect(split, output, 1, 0); }, false); }); - + it("can disconnect from an audio param", () => { return Offline((context) => { const osc = context.createOscillator(); @@ -262,16 +259,16 @@ describe("ToneAudioNode", () => { disconnect(gain, osc.frequency); }); }); - + it("throws an error if things aren't connected", async () => { let threwError = false; - await PassAudio(input => { + await PassAudio((input) => { const output = input.context.destination; disconnect(input, output); - }).catch(() => threwError = true); + }).catch(() => (threwError = true)); expect(threwError).to.equal(true); }); - + it("throws an error if the destination has no input", () => { const source = new Oscillator(); const gain = new Gain(); @@ -281,10 +278,10 @@ describe("ToneAudioNode", () => { gain.dispose(); source.dispose(); }); - + it("throws an error if things aren't connected to a specific channel", async () => { let threwError = false; - await PassAudio(input => { + await PassAudio((input) => { const context = input.context; const output = input.context.destination; const merge = context.createChannelMerger(2); @@ -293,7 +290,7 @@ describe("ToneAudioNode", () => { connect(merge, split, 0, 0); connect(split, output, 1, 0); disconnect(split, output, 0, 0); - }).catch(() => threwError = true); + }).catch(() => (threwError = true)); expect(threwError).to.equal(true); }); }); @@ -341,5 +338,4 @@ describe("ToneAudioNode", () => { }); }); }); - }); diff --git a/Tone/core/context/ToneAudioNode.ts b/Tone/core/context/ToneAudioNode.ts index bebb3d75..19f0ec5f 100644 --- a/Tone/core/context/ToneAudioNode.ts +++ b/Tone/core/context/ToneAudioNode.ts @@ -1,8 +1,8 @@ -import { isAudioNode, isAudioParam } from "../util/AdvancedTypeCheck"; -import { isDefined } from "../util/TypeCheck"; -import { Param } from "./Param"; -import { ToneWithContext, ToneWithContextOptions } from "./ToneWithContext"; -import { assert, warn } from "../util/Debug"; +import { isAudioNode, isAudioParam } from "../util/AdvancedTypeCheck.js"; +import { isDefined } from "../util/TypeCheck.js"; +import { Param } from "./Param.js"; +import { ToneWithContext, ToneWithContextOptions } from "./ToneWithContext.js"; +import { assert, warn } from "../util/Debug.js"; export type InputNode = ToneAudioNode | AudioNode | Param | AudioParam; export type OutputNode = ToneAudioNode | AudioNode; @@ -22,9 +22,9 @@ export type ToneAudioNodeOptions = ToneWithContextOptions; * ToneAudioNode is the base class for classes which process audio. * @category Core */ -export abstract class ToneAudioNode - extends ToneWithContext { - +export abstract class ToneAudioNode< + Options extends ToneAudioNodeOptions = ToneAudioNodeOptions, +> extends ToneWithContext { /** * The name of the class */ @@ -88,7 +88,10 @@ export abstract class ToneAudioNode { + nodeList.forEach((node) => { node.channelCount = options.channelCount; node.channelCountMode = options.channelCountMode; node.channelInterpretation = options.channelInterpretation; @@ -128,7 +131,10 @@ export abstract class ToneAudioNode 0, "ToneAudioNode does not have any internal nodes"); + assert( + nodeList.length > 0, + "ToneAudioNode does not have any internal nodes" + ); // use the first node to get properties // they should all be the same const node = nodeList[0]; @@ -181,7 +187,9 @@ export abstract class ToneAudioNode this.connect(node)); + nodes.forEach((node) => this.connect(node)); return this; } @@ -310,18 +318,28 @@ export function connectSeries(...nodes: InputNode[]): void { * @param outputNumber The output channel of the srcNode * @param inputNumber The input channel of the dstNode */ -export function connect(srcNode: OutputNode, dstNode: InputNode, outputNumber = 0, inputNumber = 0): void { - +export function connect( + srcNode: OutputNode, + dstNode: InputNode, + outputNumber = 0, + inputNumber = 0 +): void { assert(isDefined(srcNode), "Cannot connect from undefined node"); assert(isDefined(dstNode), "Cannot connect to undefined node"); if (dstNode instanceof ToneAudioNode || isAudioNode(dstNode)) { - assert(dstNode.numberOfInputs > 0, "Cannot connect to node with no inputs"); + assert( + dstNode.numberOfInputs > 0, + "Cannot connect to node with no inputs" + ); } - assert(srcNode.numberOfOutputs > 0, "Cannot connect from node with no outputs"); + assert( + srcNode.numberOfOutputs > 0, + "Cannot connect from node with no outputs" + ); // resolve the input of the dstNode - while ((dstNode instanceof ToneAudioNode || dstNode instanceof Param)) { + while (dstNode instanceof ToneAudioNode || dstNode instanceof Param) { if (isDefined(dstNode.input)) { dstNode = dstNode.input; } @@ -352,9 +370,8 @@ export function disconnect( srcNode: OutputNode, dstNode?: InputNode, outputNumber = 0, - inputNumber = 0, + inputNumber = 0 ): void { - // resolve the destination node if (isDefined(dstNode)) { while (dstNode instanceof ToneAudioNode) { @@ -363,7 +380,7 @@ export function disconnect( } // resolve the src node - while (!(isAudioNode(srcNode))) { + while (!isAudioNode(srcNode)) { if (isDefined(srcNode.output)) { srcNode = srcNode.output; } @@ -392,6 +409,6 @@ export function fanIn(...nodes: OutputNode[]): void { const dstNode = nodes.pop(); if (isDefined(dstNode)) { - nodes.forEach(node => connect(node, dstNode)); + nodes.forEach((node) => connect(node, dstNode)); } } diff --git a/Tone/core/context/ToneWithContext.ts b/Tone/core/context/ToneWithContext.ts index 84dfeb1e..22fee153 100644 --- a/Tone/core/context/ToneWithContext.ts +++ b/Tone/core/context/ToneWithContext.ts @@ -1,15 +1,15 @@ -import { getContext } from "../Global"; -import { Tone } from "../Tone"; -import { FrequencyClass } from "../type/Frequency"; -import { TimeClass } from "../type/Time"; -import { TransportTimeClass } from "../type/TransportTime"; -import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units"; -import { assertUsedScheduleTime } from "../util/Debug"; +import { getContext } from "../Global.js"; +import { Tone } from "../Tone.js"; +import { FrequencyClass } from "../type/Frequency.js"; +import { TimeClass } from "../type/Time.js"; +import { TransportTimeClass } from "../type/TransportTime.js"; +import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units.js"; +import { assertUsedScheduleTime } from "../util/Debug.js"; import { getDefaultsFromInstance, optionsFromArguments, -} from "../util/Defaults"; -import { RecursivePartial } from "../util/Interface"; +} from "../util/Defaults.js"; +import { RecursivePartial } from "../util/Interface.js"; import { isArray, isBoolean, @@ -17,9 +17,9 @@ import { isNumber, isString, isUndef, -} from "../util/TypeCheck"; -import { BaseContext } from "./BaseContext"; -import type { TransportClass } from "../clock/Transport"; +} from "../util/TypeCheck.js"; +import { BaseContext } from "./BaseContext.js"; +import type { TransportClass } from "../clock/Transport.js"; /** * A unit which process audio @@ -32,7 +32,7 @@ export interface ToneWithContextOptions { * The Base class for all nodes that have an AudioContext. */ export abstract class ToneWithContext< - Options extends ToneWithContextOptions + Options extends ToneWithContextOptions, > extends Tone { /** * The context belonging to the node. diff --git a/Tone/core/index.ts b/Tone/core/index.ts index 8f98a207..0637deb1 100644 --- a/Tone/core/index.ts +++ b/Tone/core/index.ts @@ -1,39 +1,45 @@ -export * from "./clock/Clock"; +export * from "./clock/Clock.js"; // export * from "./clock/Transport"; -export * from "./context/Context"; -export * from "./context/BaseContext"; -export * from "./context/Delay"; +export * from "./context/Context.js"; +export * from "./context/BaseContext.js"; +export * from "./context/Delay.js"; // export * from "./context/Destination"; -export * from "./context/Gain"; -export * from "./context/Offline"; -export * from "./context/OfflineContext"; -export * from "./context/Param"; -export * from "./context/ToneAudioBuffer"; -export * from "./context/ToneAudioBuffers"; -export * from "./context/ToneAudioNode"; +export * from "./context/Gain.js"; +export * from "./context/Offline.js"; +export * from "./context/OfflineContext.js"; +export * from "./context/Param.js"; +export * from "./context/ToneAudioBuffer.js"; +export * from "./context/ToneAudioBuffers.js"; +export * from "./context/ToneAudioNode.js"; -export * from "./type/Frequency"; -export * from "./type/Midi"; -export * from "./type/Time"; -export * from "./type/Ticks"; -export * from "./type/TransportTime"; +export * from "./type/Frequency.js"; +export * from "./type/Midi.js"; +export * from "./type/Time.js"; +export * from "./type/Ticks.js"; +export * from "./type/TransportTime.js"; -import "./util/Draw"; -export * from "./util/Emitter"; -export * from "./util/IntervalTimeline"; -export * from "./util/StateTimeline"; -export * from "./util/Timeline"; -export * from "./util/TypeCheck"; +import "./util/Draw.js"; +export * from "./util/Emitter.js"; +export * from "./util/IntervalTimeline.js"; +export * from "./util/StateTimeline.js"; +export * from "./util/Timeline.js"; +export * from "./util/TypeCheck.js"; -export { dbToGain, gainToDb, intervalToFrequencyRatio, ftom, mtof } from "./type/Conversions"; -export { optionsFromArguments, defaultArg } from "./util/Defaults"; +export { + dbToGain, + gainToDb, + intervalToFrequencyRatio, + ftom, + mtof, +} from "./type/Conversions.js"; +export { optionsFromArguments, defaultArg } from "./util/Defaults.js"; // get the units and export them under the "Unit" namespace -import * as Unit from "./type/Units"; +import * as Unit from "./type/Units.js"; export { Unit }; // export the debug stuff as Debug -import * as debug from "./util/Debug"; +import * as debug from "./util/Debug.js"; /** @internal */ export { debug }; diff --git a/Tone/core/type/Conversions.test.ts b/Tone/core/type/Conversions.test.ts index eb22b972..f1067a37 100644 --- a/Tone/core/type/Conversions.test.ts +++ b/Tone/core/type/Conversions.test.ts @@ -1,8 +1,12 @@ import { expect } from "chai"; -import { dbToGain, equalPowerScale, gainToDb, intervalToFrequencyRatio } from "./Conversions"; +import { + dbToGain, + equalPowerScale, + gainToDb, + intervalToFrequencyRatio, +} from "./Conversions.js"; describe("Conversions", () => { - it("can convert equalPowerScale", () => { expect(equalPowerScale(0.5)).to.be.closeTo(0.707, 0.001); expect(equalPowerScale(0.75)).to.be.closeTo(0.923, 0.001); diff --git a/Tone/core/type/Conversions.ts b/Tone/core/type/Conversions.ts index a95d7891..80725c07 100644 --- a/Tone/core/type/Conversions.ts +++ b/Tone/core/type/Conversions.ts @@ -1,4 +1,11 @@ -import { Decibels, GainFactor, Hertz, Interval, MidiNote, NormalRange } from "./Units"; +import { + Decibels, + GainFactor, + Hertz, + Interval, + MidiNote, + NormalRange, +} from "./Units.js"; /** * Equal power gain scale. Good for cross-fading. @@ -32,7 +39,7 @@ export function gainToDb(gain: GainFactor): Decibels { * Tone.intervalToFrequencyRatio(-12); // 0.5 */ export function intervalToFrequencyRatio(interval: Interval): number { - return Math.pow(2, (interval / 12)); + return Math.pow(2, interval / 12); } /** diff --git a/Tone/core/type/Frequency.test.ts b/Tone/core/type/Frequency.test.ts index cf37b478..87cb78ef 100644 --- a/Tone/core/type/Frequency.test.ts +++ b/Tone/core/type/Frequency.test.ts @@ -1,20 +1,18 @@ import { expect } from "chai"; -import teoria from "teoria"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { getContext } from "../Global"; -import { Frequency, FrequencyClass } from "./Frequency"; -import { Midi } from "./Midi"; -import { Ticks } from "./Ticks"; -import { Time } from "./Time"; -import { TransportTime } from "./TransportTime"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { getContext } from "../Global.js"; +import { Frequency, FrequencyClass } from "./Frequency.js"; +import { Midi } from "./Midi.js"; +import { Ticks } from "./Ticks.js"; +import { Time } from "./Time.js"; +import { TransportTime } from "./TransportTime.js"; +import { Note, Midi as TonalMidi } from "tonal"; describe("FrequencyClass", () => { - BasicTests(Frequency); context("Constructor", () => { - it("can be made with or without 'new'", () => { const f0 = Frequency(); expect(f0).to.be.instanceOf(FrequencyClass); @@ -73,9 +71,15 @@ describe("FrequencyClass", () => { }); it("can convert from Midi", () => { - expect(Frequency(Midi("C4")).valueOf()).to.equal(Frequency("C4").valueOf()); - expect(Frequency(Midi(60)).valueOf()).to.equal(Frequency("C4").valueOf()); - expect(Frequency(Midi(61)).valueOf()).to.equal(Frequency("C#4").valueOf()); + expect(Frequency(Midi("C4")).valueOf()).to.equal( + Frequency("C4").valueOf() + ); + expect(Frequency(Midi(60)).valueOf()).to.equal( + Frequency("C4").valueOf() + ); + expect(Frequency(Midi(61)).valueOf()).to.equal( + Frequency("C#4").valueOf() + ); }); it("can convert from Ticks", () => { @@ -87,7 +91,6 @@ describe("FrequencyClass", () => { }); context("Eval Types", () => { - it("evaluates numbers as frequency", () => { expect(Frequency("1").valueOf()).to.equal(1); expect(Frequency("123").valueOf()).to.equal(123); @@ -130,8 +133,14 @@ describe("FrequencyClass", () => { }); it("evalutes midi", () => { - expect(Frequency(48, "midi").valueOf()).to.be.closeTo(teoria.Note.fromMIDI(48).fq(), 0.0001); - expect(Frequency(69, "midi").valueOf()).to.be.closeTo(teoria.Note.fromMIDI(69).fq(), 0.0001); + expect(Frequency(48, "midi").valueOf()).to.be.closeTo( + TonalMidi.midiToFreq(48), + 0.0001 + ); + expect(Frequency(69, "midi").valueOf()).to.be.closeTo( + TonalMidi.midiToFreq(69), + 0.0001 + ); }); it("evalutes hz", () => { @@ -140,41 +149,105 @@ describe("FrequencyClass", () => { }); it("can convert notes into frequencies", () => { - expect(Frequency("C4").valueOf()).to.be.closeTo(teoria.note("C4").fq(), 0.0001); - expect(Frequency("D4").valueOf()).to.be.closeTo(teoria.note("D4").fq(), 0.0001); - expect(Frequency("Db4").valueOf()).to.be.closeTo(teoria.note("Db4").fq(), 0.0001); - expect(Frequency("E4").valueOf()).to.be.closeTo(teoria.note("E4").fq(), 0.0001); - expect(Frequency("F2").valueOf()).to.be.closeTo(teoria.note("F2").fq(), 0.0001); - expect(Frequency("Gb-1").valueOf()).to.be.closeTo(teoria.note("Gb-1").fq(), 0.0001); - expect(Frequency("A#10").valueOf()).to.be.closeTo(teoria.note("A#10").fq(), 0.0001); - expect(Frequency("Bb2").valueOf()).to.be.closeTo(teoria.note("Bb2").fq(), 0.0001); + expect(Frequency("C4").valueOf()).to.be.closeTo( + Note.freq("C4") as number, + 0.0001 + ); + expect(Frequency("D4").valueOf()).to.be.closeTo( + Note.freq("D4") as number, + 0.0001 + ); + expect(Frequency("Db4").valueOf()).to.be.closeTo( + Note.freq("Db4") as number, + 0.0001 + ); + expect(Frequency("E4").valueOf()).to.be.closeTo( + Note.freq("E4") as number, + 0.0001 + ); + expect(Frequency("F2").valueOf()).to.be.closeTo( + Note.freq("F2") as number, + 0.0001 + ); + expect(Frequency("Gb-1").valueOf()).to.be.closeTo( + Note.freq("Gb-1") as number, + 0.0001 + ); + expect(Frequency("A#10").valueOf()).to.be.closeTo( + Note.freq("A#10") as number, + 0.0001 + ); + expect(Frequency("Bb2").valueOf()).to.be.closeTo( + Note.freq("Bb2") as number, + 0.0001 + ); }); it("handles double accidentals", () => { - expect(Frequency("Cbb4").valueOf()).to.be.closeTo(teoria.note("Cbb4").fq(), 0.0001); - expect(Frequency("Dx4").valueOf()).to.be.closeTo(teoria.note("Dx4").fq(), 0.0001); - expect(Frequency("Dbb4").valueOf()).to.be.closeTo(teoria.note("Dbb4").fq(), 0.0001); - expect(Frequency("Ex4").valueOf()).to.be.closeTo(teoria.note("Ex4").fq(), 0.0001); - expect(Frequency("Fx2").valueOf()).to.be.closeTo(teoria.note("Fx2").fq(), 0.0001); - expect(Frequency("Gbb-1").valueOf()).to.be.closeTo(teoria.note("Gbb-1").fq(), 0.0001); - expect(Frequency("Ax10").valueOf()).to.be.closeTo(teoria.note("Ax10").fq(), 0.0001); - expect(Frequency("Bbb2").valueOf()).to.be.closeTo(teoria.note("Bbb2").fq(), 0.0001); + expect(Frequency("Cbb4").valueOf()).to.be.closeTo( + Note.freq("Cbb4") as number, + 0.0001 + ); + expect(Frequency("Dx4").valueOf()).to.be.closeTo( + Note.freq("Dx4") as number, + 0.0001 + ); + expect(Frequency("Dbb4").valueOf()).to.be.closeTo( + Note.freq("Dbb4") as number, + 0.0001 + ); + expect(Frequency("Ex4").valueOf()).to.be.closeTo( + Note.freq("Ex4") as number, + 0.0001 + ); + expect(Frequency("Fx2").valueOf()).to.be.closeTo( + Note.freq("Fx2") as number, + 0.0001 + ); + expect(Frequency("Gbb-1").valueOf()).to.be.closeTo( + Note.freq("Gbb-1") as number, + 0.0001 + ); + expect(Frequency("Ax10").valueOf()).to.be.closeTo( + Note.freq("Ax10") as number, + 0.0001 + ); + expect(Frequency("Bbb2").valueOf()).to.be.closeTo( + Note.freq("Bbb2") as number, + 0.0001 + ); }); it("can accomidate different concert tuning", () => { FrequencyClass.A4 = 444; - expect(Frequency("C4").valueOf()).to.be.closeTo(teoria.note("C4").fq(FrequencyClass.A4), 0.0001); - expect(Frequency("D1").valueOf()).to.be.closeTo(teoria.note("D1").fq(FrequencyClass.A4), 0.0001); + expect(Frequency("C4").valueOf()).to.be.closeTo( + TonalMidi.midiToFreq( + TonalMidi.toMidi("C4") as number, + FrequencyClass.A4 + ), + 0.0001 + ); + expect(Frequency("D1").valueOf()).to.be.closeTo( + TonalMidi.midiToFreq( + TonalMidi.toMidi("D1") as number, + FrequencyClass.A4 + ), + 0.0001 + ); FrequencyClass.A4 = 100; - expect(Frequency("C4").valueOf()).to.be.closeTo(teoria.note("C4").fq(FrequencyClass.A4), 0.0001); + expect(Frequency("C4").valueOf()).to.be.closeTo( + TonalMidi.midiToFreq( + TonalMidi.toMidi("C4") as number, + FrequencyClass.A4 + ), + 0.0001 + ); // return it to normal FrequencyClass.A4 = 440; }); - }); context("transpose/harmonize", () => { - it("can transpose a value", () => { expect(Frequency("A4").transpose(3).toMidi()).to.equal(72); expect(Frequency("A4").transpose(-3).toMidi()).to.equal(66); @@ -184,31 +257,48 @@ describe("FrequencyClass", () => { it("can harmonize a value", () => { expect(Frequency("A4").harmonize([0, 3])).to.be.an("array"); expect(Frequency("A4").harmonize([0, 3]).length).to.equal(2); - expect(Frequency("A4").harmonize([0, 3])[0].toNote()).to.equal("A4"); - expect(Frequency("A4").harmonize([0, 3])[1].toNote()).to.equal("C5"); + expect(Frequency("A4").harmonize([0, 3])[0].toNote()).to.equal( + "A4" + ); + expect(Frequency("A4").harmonize([0, 3])[1].toNote()).to.equal( + "C5" + ); expect(Frequency("A4").harmonize([-12, 0, 12])).to.be.an("array"); expect(Frequency("A4").harmonize([-12, 0, 12]).length).to.equal(3); - expect(Frequency("A4").harmonize([-12, 0, 12])[0].toNote()).to.equal("A3"); - expect(Frequency("A4").harmonize([-12, 0, 12])[1].toNote()).to.equal("A4"); - expect(Frequency("A4").harmonize([-12, 0, 12])[2].toNote()).to.equal("A5"); + expect( + Frequency("A4").harmonize([-12, 0, 12])[0].toNote() + ).to.equal("A3"); + expect( + Frequency("A4").harmonize([-12, 0, 12])[1].toNote() + ).to.equal("A4"); + expect( + Frequency("A4").harmonize([-12, 0, 12])[2].toNote() + ).to.equal("A5"); }); }); context("Conversions", () => { - it("can convert frequencies into notes", () => { - expect(Frequency(261.625).toNote()).to.equal(teoria.Note.fromFrequency(261.625).note.scientific()); - expect(Frequency(440).toNote()).to.equal(teoria.Note.fromFrequency(440).note.scientific()); - expect(Frequency(220).toNote()).to.equal(teoria.Note.fromFrequency(220).note.scientific()); - expect(Frequency(13.75).toNote()).to.equal(teoria.Note.fromFrequency(13.75).note.scientific()); + expect(Frequency(261.625).toNote()).to.equal( + Note.fromFreq(261.625) + ); + expect(Frequency(440).toNote()).to.equal(Note.fromFreq(440)); + expect(Frequency(220).toNote()).to.equal(Note.fromFreq(220)); + expect(Frequency(13.75).toNote()).to.equal(Note.fromFreq(13.75)); expect(Frequency(4979).toNote()).to.equal("D#8"); }); it("can convert note to midi values", () => { - expect(Frequency("C4").toMidi()).to.equal(teoria.note("C4").midi()); - expect(Frequency("C#0").toMidi()).to.equal(teoria.note("C#0").midi()); - expect(Frequency("A-4").toMidi()).to.equal(teoria.note("A-4").midi()); + expect(Frequency("C4").toMidi()).to.equal( + TonalMidi.toMidi("C4") as number + ); + expect(Frequency("C#0").toMidi()).to.equal( + TonalMidi.toMidi("C#0") as number + ); + expect(Frequency("A-1").toMidi()).to.equal( + TonalMidi.toMidi("A-1") as number + ); }); it("can convert hertz to seconds", () => { @@ -216,5 +306,4 @@ describe("FrequencyClass", () => { expect(Frequency("2hz").toSeconds()).to.equal(0.5); }); }); - }); diff --git a/Tone/core/type/Frequency.ts b/Tone/core/type/Frequency.ts index 8d0fd85e..aad86bf5 100644 --- a/Tone/core/type/Frequency.ts +++ b/Tone/core/type/Frequency.ts @@ -1,10 +1,18 @@ /* eslint-disable key-spacing */ -import { getContext } from "../Global"; -import { intervalToFrequencyRatio, mtof } from "./Conversions"; -import { ftom, getA4, setA4 } from "./Conversions"; -import { TimeClass } from "./Time"; -import { TimeBaseUnit, TimeExpression, TimeValue } from "./TimeBase"; -import { Frequency, Hertz, Interval, MidiNote, Note, Seconds, Ticks } from "./Units"; +import { getContext } from "../Global.js"; +import { intervalToFrequencyRatio, mtof } from "./Conversions.js"; +import { ftom, getA4, setA4 } from "./Conversions.js"; +import { TimeClass } from "./Time.js"; +import { TimeBaseUnit, TimeExpression, TimeValue } from "./TimeBase.js"; +import { + Frequency, + Hertz, + Interval, + MidiNote, + Note, + Seconds, + Ticks, +} from "./Units.js"; export type FrequencyUnit = TimeBaseUnit | "midi"; @@ -17,8 +25,10 @@ export type FrequencyUnit = TimeBaseUnit | "midi"; * Tone.Frequency("C3").transpose(4); * @category Unit */ -export class FrequencyClass extends TimeClass { - +export class FrequencyClass extends TimeClass< + Type, + FrequencyUnit +> { readonly name: string = "Frequency"; readonly defaultUnits: FrequencyUnit = "hz"; @@ -67,7 +77,9 @@ export class FrequencyClass extends TimeClass extends TimeClass extends TimeClass { + return intervals.map((interval) => { return this.transpose(interval); }); } @@ -135,7 +150,7 @@ export class FrequencyClass extends TimeClass extends TimeClass extends TimeClass { - BasicTests(MidiClass); context("Constructor", () => { - it("can pass in a number in the constructor", () => { const midi = Midi(1); expect(midi).to.be.instanceOf(MidiClass); @@ -93,28 +91,28 @@ describe("MidiClass", () => { }); context("Conversions", () => { - it("can convert frequencies into notes", () => { - expect(Midi(48).toNote()).to.equal(teoria.Note.fromMIDI(48).scientific()); - expect(Midi(90).toNote()).to.equal(teoria.Note.fromMIDI(90).scientific()); + expect(Midi(48).toNote()).to.equal(TonalMidi.midiToNoteName(48)); + expect(Midi(90).toNote()).to.equal( + TonalMidi.midiToNoteName(90, { sharps: true }) + ); expect(Midi("C#4").toNote()).to.equal("C#4"); }); it("can convert note to midi values", () => { - expect(Midi("C4").toMidi()).to.equal(teoria.note("C4").midi()); - expect(Midi("C#0").toMidi()).to.equal(teoria.note("C#0").midi()); - expect(Midi("A-4").toMidi()).to.equal(teoria.note("A-4").midi()); + expect(Midi("C4").toMidi()).to.equal(TonalMidi.toMidi("C4")); + expect(Midi("C#0").toMidi()).to.equal(TonalMidi.toMidi("C#0")); + expect(Midi("A-1").toMidi()).to.equal(TonalMidi.toMidi("A-1")); }); it("can convert midi to frequency", () => { - expect(Midi(60).toFrequency()).to.equal(teoria.Note.fromMIDI(60).fq()); - expect(Midi(25).toFrequency()).to.equal(teoria.Note.fromMIDI(25).fq()); - expect(Midi(108).toFrequency()).to.equal(teoria.Note.fromMIDI(108).fq()); + expect(Midi(60).toFrequency()).to.equal(TonalMidi.midiToFreq(60)); + expect(Midi(25).toFrequency()).to.equal(TonalMidi.midiToFreq(25)); + expect(Midi(108).toFrequency()).to.equal(TonalMidi.midiToFreq(108)); }); }); context("transpose/harmonize", () => { - it("can transpose a value", () => { expect(Midi("A4").transpose(3).toMidi()).to.equal(72); expect(Midi("A4").transpose(-3).toMidi()).to.equal(66); @@ -129,9 +127,15 @@ describe("MidiClass", () => { expect(Midi("A4").harmonize([-12, 0, 12])).to.be.an("array"); expect(Midi("A4").harmonize([-12, 0, 12]).length).to.equal(3); - expect(Midi("A4").harmonize([-12, 0, 12])[0].toNote()).to.equal("A3"); - expect(Midi("A4").harmonize([-12, 0, 12])[1].toNote()).to.equal("A4"); - expect(Midi("A4").harmonize([-12, 0, 12])[2].toNote()).to.equal("A5"); + expect(Midi("A4").harmonize([-12, 0, 12])[0].toNote()).to.equal( + "A3" + ); + expect(Midi("A4").harmonize([-12, 0, 12])[1].toNote()).to.equal( + "A4" + ); + expect(Midi("A4").harmonize([-12, 0, 12])[2].toNote()).to.equal( + "A5" + ); }); }); }); diff --git a/Tone/core/type/Midi.ts b/Tone/core/type/Midi.ts index 50361908..e10e31f6 100644 --- a/Tone/core/type/Midi.ts +++ b/Tone/core/type/Midi.ts @@ -1,8 +1,8 @@ -import { getContext } from "../Global"; -import { ftom, mtof } from "./Conversions"; -import { FrequencyClass, FrequencyUnit } from "./Frequency"; -import { TimeValue } from "./TimeBase"; -import { Hertz, Interval, MidiNote, Seconds, Ticks } from "./Units"; +import { getContext } from "../Global.js"; +import { ftom, mtof } from "./Conversions.js"; +import { FrequencyClass, FrequencyUnit } from "./Frequency.js"; +import { TimeValue } from "./TimeBase.js"; +import { Hertz, Interval, MidiNote, Seconds, Ticks } from "./Units.js"; /** * Midi is a primitive type for encoding Time values. @@ -11,7 +11,6 @@ import { Hertz, Interval, MidiNote, Seconds, Ticks } from "./Units"; * @category Unit */ export class MidiClass extends FrequencyClass { - readonly name: string = "MidiClass"; readonly defaultUnits = "midi"; diff --git a/Tone/core/type/NoteUnits.ts b/Tone/core/type/NoteUnits.ts index c6f4cd46..cb454304 100644 --- a/Tone/core/type/NoteUnits.ts +++ b/Tone/core/type/NoteUnits.ts @@ -2,7 +2,23 @@ type Letter = "C" | "D" | "E" | "F" | "G" | "A" | "B"; type Accidental = "bb" | "b" | "" | "#" | "x"; -type Octave = -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; +type Octave = + | -4 + | -3 + | -2 + | -1 + | 0 + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11; /** * A note in Scientific pitch notation. @@ -12,8 +28,10 @@ type Octave = -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 1 */ export type Note = `${Letter}${Accidental}${Octave}`; -type IntegerRange = - A["length"] extends N ? A[number] : IntegerRange; +type IntegerRange< + N extends number, + A extends any[] = [], +> = A["length"] extends N ? A[number] : IntegerRange; /** * A number representing a midi note. Integers between 0-127 diff --git a/Tone/core/type/Ticks.test.ts b/Tone/core/type/Ticks.test.ts index 44126a08..84da81f9 100644 --- a/Tone/core/type/Ticks.test.ts +++ b/Tone/core/type/Ticks.test.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { getContext } from "../Global"; -import { Frequency } from "./Frequency"; -import { Ticks, TicksClass } from "./Ticks"; -import { Time } from "./Time"; -import { TransportTime } from "./TransportTime"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { atTime, Offline } from "../../../test/helper/Offline.js"; +import { getContext } from "../Global.js"; +import { Frequency } from "./Frequency.js"; +import { Ticks, TicksClass } from "./Ticks.js"; +import { Time } from "./Time.js"; +import { TransportTime } from "./TransportTime.js"; describe("TicksClass", () => { - BasicTests(Ticks); context("Constructor", () => { - it("can be made with or without 'new'", () => { const t0 = Ticks(); expect(t0).to.be.instanceOf(TicksClass); @@ -56,7 +54,9 @@ describe("TicksClass", () => { return Offline((context) => { context.transport.start(); return atTime(0.29, () => { - expect(new TicksClass(context).valueOf()).to.equal(context.transport.ticks); + expect(new TicksClass(context).valueOf()).to.equal( + context.transport.ticks + ); context.transport.stop(); }); }, 0.3); @@ -82,38 +82,54 @@ describe("TicksClass", () => { it("can convert from Frequency", () => { return Offline(({ transport }) => { expect(Ticks(Frequency(2)).valueOf()).to.equal(transport.PPQ); - expect(Ticks(Frequency("4n")).valueOf()).to.equal(transport.PPQ); - expect(Ticks(Frequency(4, "n")).valueOf()).to.equal(transport.PPQ); + expect(Ticks(Frequency("4n")).valueOf()).to.equal( + transport.PPQ + ); + expect(Ticks(Frequency(4, "n")).valueOf()).to.equal( + transport.PPQ + ); }); }); it("can convert from TransportTime", () => { return Offline(({ transport }) => { - expect(Ticks(TransportTime(2)).valueOf()).to.equal(transport.PPQ * 4); - expect(Ticks(TransportTime("4n")).valueOf()).to.equal(transport.PPQ); + expect(Ticks(TransportTime(2)).valueOf()).to.equal( + transport.PPQ * 4 + ); + expect(Ticks(TransportTime("4n")).valueOf()).to.equal( + transport.PPQ + ); }); }); it("can convert from Ticks", () => { return Offline(({ transport }) => { - expect(Ticks(Ticks(transport.PPQ)).valueOf()).to.equal(transport.PPQ); + expect(Ticks(Ticks(transport.PPQ)).valueOf()).to.equal( + transport.PPQ + ); expect(Ticks(Ticks("4n")).valueOf()).to.equal(transport.PPQ); }); }); it("can convert from an Object", () => { return Offline(({ transport }) => { - expect(Ticks({ "4n": 2 }).valueOf()).to.equal(transport.PPQ * 2); - expect(Ticks({ "1n": 1, "8t": 2 }).valueOf()).to.equal(transport.PPQ * 4 + transport.PPQ * (2 / 3)); + expect(Ticks({ "4n": 2 }).valueOf()).to.equal( + transport.PPQ * 2 + ); + expect(Ticks({ "1n": 1, "8t": 2 }).valueOf()).to.equal( + transport.PPQ * 4 + transport.PPQ * (2 / 3) + ); }); }); }); context("Quantizes values", () => { - it("can quantize values", () => { return Offline(({ transport }) => { - expect(Ticks("4t").quantize("4n").valueOf()).to.be.closeTo(transport.PPQ, 0.01); + expect(Ticks("4t").quantize("4n").valueOf()).to.be.closeTo( + transport.PPQ, + 0.01 + ); }); }); @@ -122,32 +138,39 @@ describe("TicksClass", () => { const transport = context.transport; transport.start(); return atTime(0.59, () => { - expect(new TicksClass(context, "@1m").valueOf()).to.be.closeTo(4 * transport.PPQ, 1); - expect(new TicksClass(context, "@4n").valueOf()).to.be.closeTo(transport.PPQ * 2, 1); + expect( + new TicksClass(context, "@1m").valueOf() + ).to.be.closeTo(4 * transport.PPQ, 1); + expect( + new TicksClass(context, "@4n").valueOf() + ).to.be.closeTo(transport.PPQ * 2, 1); }); }, 0.6); }); }); context("Operators", () => { - it("can add the current time", () => { return Offline((context) => { context.transport.start(); return atTime(0.59, () => { const now = context.transport.ticks; - expect(new TicksClass(context, "+4i").valueOf()).to.be.closeTo(4 + now, 0.01); - expect(new TicksClass(context, "+2n").valueOf()).to.be.closeTo(context.transport.PPQ * 2 + now, 0.01); - expect(new TicksClass(context, "+2n").valueOf()).to.be.closeTo(context.transport.PPQ * 2 + now, 0.01); + expect( + new TicksClass(context, "+4i").valueOf() + ).to.be.closeTo(4 + now, 0.01); + expect( + new TicksClass(context, "+2n").valueOf() + ).to.be.closeTo(context.transport.PPQ * 2 + now, 0.01); + expect( + new TicksClass(context, "+2n").valueOf() + ).to.be.closeTo(context.transport.PPQ * 2 + now, 0.01); context.transport.stop(); }); }, 0.6); }); - }); context("Conversions", () => { - it("converts time into notation", () => { return Offline(({ transport }) => { transport.bpm.value = 120; @@ -161,7 +184,9 @@ describe("TicksClass", () => { it("converts time into samples", () => { return Offline(({ transport }) => { - expect(Ticks(transport.PPQ).toSamples()).to.equal(0.5 * getContext().sampleRate); + expect(Ticks(transport.PPQ).toSamples()).to.equal( + 0.5 * getContext().sampleRate + ); }); }); @@ -180,11 +205,13 @@ describe("TicksClass", () => { it("converts time into BarsBeatsSixteenths", () => { return Offline(({ transport }) => { - expect(Ticks("3:1:3").toBarsBeatsSixteenths()).to.equal("3:1:3"); - expect(Ticks(4 * transport.PPQ).toBarsBeatsSixteenths()).to.equal("1:0:0"); + expect(Ticks("3:1:3").toBarsBeatsSixteenths()).to.equal( + "3:1:3" + ); + expect( + Ticks(4 * transport.PPQ).toBarsBeatsSixteenths() + ).to.equal("1:0:0"); }); }); - }); - }); diff --git a/Tone/core/type/Ticks.ts b/Tone/core/type/Ticks.ts index c18bb2aa..8183e34d 100644 --- a/Tone/core/type/Ticks.ts +++ b/Tone/core/type/Ticks.ts @@ -1,7 +1,7 @@ -import { getContext } from "../Global"; -import { TimeBaseUnit, TimeValue } from "./TimeBase"; -import { TransportTimeClass } from "./TransportTime"; -import { Seconds, Ticks } from "./Units"; +import { getContext } from "../Global.js"; +import { TimeBaseUnit, TimeValue } from "./TimeBase.js"; +import { TransportTimeClass } from "./TransportTime.js"; +import { Seconds, Ticks } from "./Units.js"; /** * Ticks is a primitive type for encoding Time values. @@ -12,7 +12,6 @@ import { Seconds, Ticks } from "./Units"; * @category Unit */ export class TicksClass extends TransportTimeClass { - readonly name: string = "Ticks"; readonly defaultUnits: TimeBaseUnit = "i"; @@ -35,7 +34,7 @@ export class TicksClass extends TransportTimeClass { * Returns the value of a second in the current units */ protected _secondsToUnits(seconds: Seconds): Ticks { - return Math.floor(seconds / (60 / this._getBpm()) * this._getPPQ()); + return Math.floor((seconds / (60 / this._getBpm())) * this._getPPQ()); } /** diff --git a/Tone/core/type/Time.test.ts b/Tone/core/type/Time.test.ts index 049aeef3..635d732e 100644 --- a/Tone/core/type/Time.test.ts +++ b/Tone/core/type/Time.test.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { getContext } from "../Global"; -import { Frequency } from "./Frequency"; -import { Ticks } from "./Ticks"; -import { Time, TimeClass } from "./Time"; -import { TransportTime } from "./TransportTime"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { atTime, Offline } from "../../../test/helper/Offline.js"; +import { getContext } from "../Global.js"; +import { Frequency } from "./Frequency.js"; +import { Ticks } from "./Ticks.js"; +import { Time, TimeClass } from "./Time.js"; +import { TransportTime } from "./TransportTime.js"; describe("TimeClass", () => { - BasicTests(TimeClass); context("Constructor", () => { - it("can be used as a function or instantiated", () => { const t0 = Time(); expect(t0).to.be.instanceOf(TimeClass); @@ -77,7 +75,10 @@ describe("TimeClass", () => { it("evalutes objects", () => { return Offline(() => { expect(Time({ "4n": 3 }).valueOf()).to.equal(1.5); - expect(Time({ "8t": 2, "1m": 3 }).valueOf()).to.be.closeTo(6.33, 0.01); + expect(Time({ "8t": 2, "1m": 3 }).valueOf()).to.be.closeTo( + 6.33, + 0.01 + ); expect(Time({ "2n": 1, "8n": 1.5 }).valueOf()).to.equal(1.375); expect(Time({ "2n": 1, "8n": -1 }).valueOf()).to.equal(0.75); }); @@ -85,7 +86,6 @@ describe("TimeClass", () => { }); context("Quantizes values", () => { - it("returns the time quantized to the a subdivision", () => { expect(Time(1.1).quantize(0.5).valueOf()).to.be.closeTo(1, 0.01); expect(Time(2.3).quantize(0.5).valueOf()).to.be.closeTo(2.5, 0.01); @@ -103,16 +103,21 @@ describe("TimeClass", () => { const transport = context.transport; transport.start(0.1); return atTime(0.69, () => { - expect(new TimeClass(context, "@1m").valueOf()).to.be.closeTo(2.1, 0.01); - expect(new TimeClass(context, "@4n").valueOf()).to.be.closeTo(1.1, 0.01); - expect(new TimeClass(context, "@8n").valueOf()).to.be.closeTo(0.85, 0.01); + expect( + new TimeClass(context, "@1m").valueOf() + ).to.be.closeTo(2.1, 0.01); + expect( + new TimeClass(context, "@4n").valueOf() + ).to.be.closeTo(1.1, 0.01); + expect( + new TimeClass(context, "@8n").valueOf() + ).to.be.closeTo(0.85, 0.01); }); }, 0.7); }); }); context("Operators", () => { - it("can add the current time", () => { const now = getContext().now(); expect(Time("+4").valueOf()).to.be.closeTo(4 + now, 0.02); @@ -123,18 +128,20 @@ describe("TimeClass", () => { expect(Time(4).quantize(3)).to.equal(3); expect(Time(5).quantize(3)).to.equal(6); }); - }); context("Conversions", () => { - it("converts time into notation", () => { return Offline(() => { expect(Time("4n").toNotation()).to.equal("4n"); expect(Time(1.5).toNotation()).to.equal("2n."); expect(Time(0).toNotation()).to.equal("0"); expect(Time("1:2:3").toNotation()).to.equal("1m"); - expect(Time(Time("2n").valueOf() + Time("4n").valueOf()).toNotation()).to.equal("2n."); + expect( + Time( + Time("2n").valueOf() + Time("4n").valueOf() + ).toNotation() + ).to.equal("2n."); }); }); @@ -169,13 +176,17 @@ describe("TimeClass", () => { // trailing zero removal test transport.bpm.value = 100; expect(Time("0:1:3").toBarsBeatsSixteenths()).to.equal("0:1:3"); - expect(Time("14:0:0").toBarsBeatsSixteenths()).to.equal("14:0:0"); - expect(Time("15:0:0").toBarsBeatsSixteenths()).to.equal("15:0:0"); + expect(Time("14:0:0").toBarsBeatsSixteenths()).to.equal( + "14:0:0" + ); + expect(Time("15:0:0").toBarsBeatsSixteenths()).to.equal( + "15:0:0" + ); transport.bpm.value = 90; - expect(Time("100:0:0").toBarsBeatsSixteenths()).to.equal("100:0:0"); + expect(Time("100:0:0").toBarsBeatsSixteenths()).to.equal( + "100:0:0" + ); }); }); - }); - }); diff --git a/Tone/core/type/Time.ts b/Tone/core/type/Time.ts index 196e5135..26287510 100644 --- a/Tone/core/type/Time.ts +++ b/Tone/core/type/Time.ts @@ -1,7 +1,19 @@ -import { getContext } from "../Global"; -import { ftom } from "./Conversions"; -import { TimeBaseClass, TimeBaseUnit, TimeExpression, TimeValue } from "./TimeBase"; -import { BarsBeatsSixteenths, MidiNote, Seconds, Subdivision, Ticks, Time } from "./Units"; +import { getContext } from "../Global.js"; +import { ftom } from "./Conversions.js"; +import { + TimeBaseClass, + TimeBaseUnit, + TimeExpression, + TimeValue, +} from "./TimeBase.js"; +import { + BarsBeatsSixteenths, + MidiNote, + Seconds, + Subdivision, + Ticks, + Time, +} from "./Units.js"; /** * TimeClass is a primitive type for encoding and decoding Time values. @@ -12,23 +24,33 @@ import { BarsBeatsSixteenths, MidiNote, Seconds, Subdivision, Ticks, Time } from * const time = Tone.Time("4n"); // a quarter note * @category Unit */ -export class TimeClass - extends TimeBaseClass { - +export class TimeClass< + Type extends Seconds | Ticks = Seconds, + Unit extends string = TimeBaseUnit, +> extends TimeBaseClass { readonly name: string = "TimeClass"; protected _getExpressions(): TimeExpression { return Object.assign(super._getExpressions(), { now: { method: (capture: string): Type => { - return this._now() + new (this.constructor as typeof TimeClass)(this.context, capture).valueOf() as Type; + return (this._now() + + new (this.constructor as typeof TimeClass)( + this.context, + capture + ).valueOf()) as Type; }, regexp: /^\+(.+)/, }, quantize: { method: (capture: string): Type => { - const quantTo = new TimeClass(this.context, capture).valueOf(); - return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo)); + const quantTo = new TimeClass( + this.context, + capture + ).valueOf(); + return this._secondsToUnits( + this.context.transport.nextSubdivision(quantTo) + ); }, regexp: /^@(.+)/, }, @@ -46,12 +68,15 @@ export class TimeClass { - const notationSeconds = new TimeClass(this.context, notation).toSeconds(); - if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) { + let closestSeconds = new TimeClass( + this.context, + testNotations[0] + ).toSeconds(); + testNotations.forEach((notation) => { + const notationSeconds = new TimeClass( + this.context, + notation + ).toSeconds(); + if ( + Math.abs(notationSeconds - time) < + Math.abs(closestSeconds - time) + ) { closest = notation; closestSeconds = notationSeconds; } @@ -136,7 +170,7 @@ export class TimeClass { +export function Time( + value?: TimeValue, + units?: TimeBaseUnit +): TimeClass { return new TimeClass(getContext(), value, units); } diff --git a/Tone/core/type/TimeBase.ts b/Tone/core/type/TimeBase.ts index 7a9663f2..210571c4 100644 --- a/Tone/core/type/TimeBase.ts +++ b/Tone/core/type/TimeBase.ts @@ -1,14 +1,32 @@ -import { BaseContext } from "../context/BaseContext"; -import { Tone } from "../Tone"; -import { isDefined, isObject, isString, isUndef } from "../util/TypeCheck"; -import { BPM, Hertz, MidiNote, Milliseconds, Samples, Seconds, Ticks, Time } from "./Units"; +import { BaseContext } from "../context/BaseContext.js"; +import { Tone } from "../Tone.js"; +import { isDefined, isObject, isString, isUndef } from "../util/TypeCheck.js"; +import { + BPM, + Hertz, + MidiNote, + Milliseconds, + Samples, + Seconds, + Ticks, + Time, +} from "./Units.js"; export type TimeValue = Time | TimeBaseClass; /** * The units that the TimeBase can accept. extended by other classes */ -export type TimeBaseUnit = "s" | "n" | "t" | "m" | "i" | "hz" | "tr" | "samples" | "number"; +export type TimeBaseUnit = + | "s" + | "n" + | "t" + | "m" + | "i" + | "hz" + | "tr" + | "samples" + | "number"; export interface TypeFunction { regexp: RegExp; @@ -25,8 +43,10 @@ export interface TimeExpression { /** * TimeBase is a flexible encoding of time which can be evaluated to and from a string. */ -export abstract class TimeBaseClass extends Tone { - +export abstract class TimeBaseClass< + Type extends number, + Unit extends string, +> extends Tone { readonly context: BaseContext; /** @@ -83,7 +103,9 @@ export abstract class TimeBaseClass ex }, m: { method: (value) => { - return this._beatsToUnits(parseInt(value, 10) * this._getTimeSignature()); + return this._beatsToUnits( + parseInt(value, 10) * this._getTimeSignature() + ); }, regexp: /^(\d+)m$/i, }, @@ -92,16 +114,21 @@ export abstract class TimeBaseClass ex const numericValue = parseInt(value, 10); const scalar = dot === "." ? 1.5 : 1; if (numericValue === 1) { - return this._beatsToUnits(this._getTimeSignature()) * scalar as Type; + return (this._beatsToUnits(this._getTimeSignature()) * + scalar) as Type; } else { - return this._beatsToUnits(4 / numericValue) * scalar as Type; + return (this._beatsToUnits(4 / numericValue) * + scalar) as Type; } }, regexp: /^(\d+)n(\.?)$/i, }, number: { method: (value) => { - return this._expressions[this.defaultUnits].method.call(this, value); + return this._expressions[this.defaultUnits].method.call( + this, + value + ); }, regexp: /^(\d+(?:\.\d+)?)$/, }, @@ -113,14 +140,17 @@ export abstract class TimeBaseClass ex }, samples: { method: (value) => { - return parseInt(value, 10) / this.context.sampleRate as Type; + return (parseInt(value, 10) / + this.context.sampleRate) as Type; }, regexp: /^(\d+)samples$/, }, t: { method: (value) => { const numericValue = parseInt(value, 10); - return this._beatsToUnits(8 / (Math.floor(numericValue) * 3)); + return this._beatsToUnits( + 8 / (Math.floor(numericValue) * 3) + ); }, regexp: /^(\d+)t$/i, }, @@ -128,7 +158,9 @@ export abstract class TimeBaseClass ex method: (m, q, s) => { let total = 0; if (m && m !== "0") { - total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m)); + total += this._beatsToUnits( + this._getTimeSignature() * parseFloat(m) + ); } if (q && q !== "0") { total += this._beatsToUnits(parseFloat(q)); @@ -168,8 +200,10 @@ export abstract class TimeBaseClass ex for (const typeName in this._val) { if (isDefined(this._val[typeName])) { const quantity = this._val[typeName]; - // @ts-ignore - const time = (new this.constructor(this.context, typeName)).valueOf() * quantity; + const time = + // @ts-ignore + new this.constructor(this.context, typeName).valueOf() * + quantity; total += time; } } @@ -198,14 +232,14 @@ export abstract class TimeBaseClass ex * Returns the value of a frequency in the current units */ protected _frequencyToUnits(freq: Hertz): Type { - return 1 / freq as Type; + return (1 / freq) as Type; } /** * Return the value of the beats in the current units */ protected _beatsToUnits(beats: number): Type { - return (60 / this._getBpm()) * beats as Type; + return ((60 / this._getBpm()) * beats) as Type; } /** @@ -219,7 +253,7 @@ export abstract class TimeBaseClass ex * Returns the value of a tick in the current time units */ protected _ticksToUnits(ticks: Ticks): Type { - return (ticks * (this._beatsToUnits(1)) / this._getPPQ()) as Type; + return ((ticks * this._beatsToUnits(1)) / this._getPPQ()) as Type; } /** diff --git a/Tone/core/type/TransportTime.test.ts b/Tone/core/type/TransportTime.test.ts index 1d041e95..95672e84 100644 --- a/Tone/core/type/TransportTime.test.ts +++ b/Tone/core/type/TransportTime.test.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { getContext } from "../Global"; -import { Frequency } from "./Frequency"; -import { Ticks } from "./Ticks"; -import { Time } from "./Time"; -import { TransportTime, TransportTimeClass } from "./TransportTime"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { atTime, Offline } from "../../../test/helper/Offline.js"; +import { getContext } from "../Global.js"; +import { Frequency } from "./Frequency.js"; +import { Ticks } from "./Ticks.js"; +import { Time } from "./Time.js"; +import { TransportTime, TransportTimeClass } from "./TransportTime.js"; describe("TransportTimeClass", () => { - BasicTests(TransportTime); context("Constructor", () => { - it("can be made with or without 'new'", () => { const t0 = TransportTime(); expect(t0).to.be.instanceOf(TransportTimeClass); @@ -57,7 +55,9 @@ describe("TransportTimeClass", () => { const transport = context.transport; transport.start(); return atTime(0.29, () => { - expect(new TransportTimeClass(context).valueOf()).to.equal(transport.seconds); + expect(new TransportTimeClass(context).valueOf()).to.equal( + transport.seconds + ); transport.stop(); }); }, 0.3); @@ -90,7 +90,9 @@ describe("TransportTimeClass", () => { it("can convert from Ticks", () => { return Offline((context) => { const transport = context.transport; - expect(TransportTime(Ticks(transport.PPQ)).valueOf()).to.equal(0.5); + expect(TransportTime(Ticks(transport.PPQ)).valueOf()).to.equal( + 0.5 + ); expect(TransportTime(Ticks("4n")).valueOf()).to.equal(0.5); }); }); @@ -98,16 +100,19 @@ describe("TransportTimeClass", () => { it("can convert from an Object", () => { return Offline(() => { expect(TransportTime({ "4n": 2 }).valueOf()).to.equal(1); - expect(TransportTime({ "1n": 1, "8t": 2 }).valueOf()).to.be.closeTo(2.333, 0.01); + expect( + TransportTime({ "1n": 1, "8t": 2 }).valueOf() + ).to.be.closeTo(2.333, 0.01); }); }); }); context("Quantizes values", () => { - it("can quantize values", () => { return Offline((context) => { - expect(TransportTime("4t").quantize("4n").valueOf()).to.be.closeTo(0.5, 0.01); + expect( + TransportTime("4t").quantize("4n").valueOf() + ).to.be.closeTo(0.5, 0.01); }); }); @@ -116,15 +121,18 @@ describe("TransportTimeClass", () => { const transport = context.transport; transport.start(); return atTime(0.59, () => { - expect(new TransportTimeClass(context, "@1m").valueOf()).to.be.closeTo(2, 0.01); - expect(new TransportTimeClass(context, "@4n").valueOf()).to.be.closeTo(1, 0.01); + expect( + new TransportTimeClass(context, "@1m").valueOf() + ).to.be.closeTo(2, 0.01); + expect( + new TransportTimeClass(context, "@4n").valueOf() + ).to.be.closeTo(1, 0.01); }); }, 0.6); }); }); context("Operators", () => { - it("can add the current time", () => { return Offline((context) => { const transport = context.transport; @@ -132,17 +140,19 @@ describe("TransportTimeClass", () => { return atTime(0.59, () => { const now = transport.seconds; const quarterNote = 60 / transport.bpm.value; - expect(new TransportTimeClass(context, "+4i").valueOf()).to.be.closeTo(4 / transport.PPQ + now, 0.1); - expect(new TransportTimeClass(context, "+2n").valueOf()).to.be.closeTo(quarterNote * 2 + now, 0.1); + expect( + new TransportTimeClass(context, "+4i").valueOf() + ).to.be.closeTo(4 / transport.PPQ + now, 0.1); + expect( + new TransportTimeClass(context, "+2n").valueOf() + ).to.be.closeTo(quarterNote * 2 + now, 0.1); transport.stop(); }); }, 0.6); }); - }); context("Conversions", () => { - it("converts time into notation", () => { return Offline((context) => { const transport = context.transport; @@ -157,7 +167,9 @@ describe("TransportTimeClass", () => { it("converts time into samples", () => { return Offline((context) => { - expect(TransportTime(2).toSamples()).to.equal(2 * context.sampleRate); + expect(TransportTime(2).toSamples()).to.equal( + 2 * context.sampleRate + ); }); }); @@ -175,10 +187,13 @@ describe("TransportTimeClass", () => { it("converts time into BarsBeatsSixteenths", () => { return Offline(() => { - expect(TransportTime("3:1:3").toBarsBeatsSixteenths()).to.equal("3:1:3"); - expect(TransportTime(2).toBarsBeatsSixteenths()).to.equal("1:0:0"); + expect(TransportTime("3:1:3").toBarsBeatsSixteenths()).to.equal( + "3:1:3" + ); + expect(TransportTime(2).toBarsBeatsSixteenths()).to.equal( + "1:0:0" + ); }); }); - }); }); diff --git a/Tone/core/type/TransportTime.ts b/Tone/core/type/TransportTime.ts index 412a59b2..9cf4f8a6 100644 --- a/Tone/core/type/TransportTime.ts +++ b/Tone/core/type/TransportTime.ts @@ -1,7 +1,7 @@ -import { getContext } from "../Global"; -import { Seconds, Ticks } from "../type/Units"; -import { TimeClass } from "./Time"; -import { TimeBaseUnit, TimeValue } from "./TimeBase"; +import { getContext } from "../Global.js"; +import { Seconds, Ticks } from "../type/Units.js"; +import { TimeClass } from "./Time.js"; +import { TimeBaseUnit, TimeValue } from "./TimeBase.js"; /** * TransportTime is a time along the Transport's @@ -10,8 +10,9 @@ import { TimeBaseUnit, TimeValue } from "./TimeBase"; * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime). * @category Unit */ -export class TransportTimeClass extends TimeClass { - +export class TransportTimeClass< + Type extends Seconds | Ticks = Seconds, +> extends TimeClass { readonly name: string = "TransportTime"; /** @@ -29,6 +30,9 @@ export class TransportTimeClass extends * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime). * @category Unit */ -export function TransportTime(value?: TimeValue, units?: TimeBaseUnit): TransportTimeClass { +export function TransportTime( + value?: TimeValue, + units?: TimeBaseUnit +): TransportTimeClass { return new TransportTimeClass(getContext(), value, units); } diff --git a/Tone/core/type/Units.ts b/Tone/core/type/Units.ts index 5d4f87e4..8da3e343 100644 --- a/Tone/core/type/Units.ts +++ b/Tone/core/type/Units.ts @@ -1,6 +1,6 @@ -export * from "./NoteUnits"; +export * from "./NoteUnits.js"; -import { Note } from "./NoteUnits"; +import { Note } from "./NoteUnits.js"; /** * A number representing a time in seconds @@ -50,7 +50,12 @@ export type Positive = number; * e.g. "4n" is a quarter note, "4t" is a quarter note triplet, and "4n." is a dotted quarter note. * @category Unit */ -export type Subdivision = "1m" | "1n" | "1n." | `${2 | 4 | 8 | 16 | 32 | 64 | 128 | 256}${"n" | "n." | "t"}` | "0"; +export type Subdivision = + | "1m" + | "1n" + | "1n." + | `${2 | 4 | 8 | 16 | 32 | 64 | 128 | 256}${"n" | "n." | "t"}` + | "0"; /** * A time object has a subdivision as the keys and a number as the values. * @example diff --git a/Tone/core/util/AdvancedTypeCheck.ts b/Tone/core/util/AdvancedTypeCheck.ts index 7f056e06..98c9723d 100644 --- a/Tone/core/util/AdvancedTypeCheck.ts +++ b/Tone/core/util/AdvancedTypeCheck.ts @@ -1,7 +1,9 @@ import { - AudioBuffer, isAnyAudioContext, - isAnyAudioNode, isAnyAudioParam, - isAnyOfflineAudioContext + AudioBuffer, + isAnyAudioContext, + isAnyAudioNode, + isAnyAudioParam, + isAnyOfflineAudioContext, } from "standardized-audio-context"; /** diff --git a/Tone/core/util/Debug.test.ts b/Tone/core/util/Debug.test.ts index a58b5746..49edfd5a 100644 --- a/Tone/core/util/Debug.test.ts +++ b/Tone/core/util/Debug.test.ts @@ -1,20 +1,19 @@ import { expect } from "chai"; -import { ToneOscillatorNode } from "../../source/oscillator/ToneOscillatorNode"; -import { assertRange, setLogger } from "./Debug"; -import { theWindow } from "../context/AudioContext"; -import { Oscillator } from "Tone/source"; -import { Context } from "../context/Context"; +import { ToneOscillatorNode } from "../../source/oscillator/ToneOscillatorNode.js"; +import { assertRange, setLogger } from "./Debug.js"; +import { theWindow } from "../context/AudioContext.js"; +import { Oscillator } from "../../source/index.js"; +import { Context } from "../context/Context.js"; describe("Debug", () => { - it("can log a class when that class is set to 'debug'", () => { const osc = new ToneOscillatorNode(); osc.debug = true; let loggerInvoked = false; let warnInvoked = false; setLogger({ - log: () => loggerInvoked = true, - warn: () => warnInvoked = true + log: () => (loggerInvoked = true), + warn: () => (warnInvoked = true), }); osc.start(); expect(loggerInvoked).to.be.true; @@ -30,8 +29,8 @@ describe("Debug", () => { let loggerInvoked = false; let warnInvoked = false; setLogger({ - log: () => loggerInvoked = true, - warn: () => warnInvoked = true + log: () => (loggerInvoked = true), + warn: () => (warnInvoked = true), }); osc.start(); expect(loggerInvoked).to.be.true; @@ -50,7 +49,7 @@ describe("Debug", () => { expect(() => { assertRange(2, 0, 1); }).to.throw(RangeError); - + expect(() => { assertRange(0, 0); }).to.not.throw(RangeError); @@ -63,7 +62,7 @@ describe("Debug", () => { let warnInvoked = false; setLogger({ log: () => {}, - warn: () => warnInvoked = true + warn: () => (warnInvoked = true), }); osc.start(); expect(warnInvoked).to.be.true; diff --git a/Tone/core/util/Debug.ts b/Tone/core/util/Debug.ts index 31a37a0e..a1fcc8f1 100644 --- a/Tone/core/util/Debug.ts +++ b/Tone/core/util/Debug.ts @@ -1,4 +1,6 @@ -import { isUndef } from "./TypeCheck"; +import { isUndef } from "./TypeCheck.js"; +import type { BaseContext } from "../context/BaseContext.js"; +import type { Time } from "../type/Units.js"; /** * Assert that the statement is true, otherwise invoke the error. @@ -25,13 +27,11 @@ export function assertRange(value: number, gte: number, lte = Infinity): void { /** * Warn if the context is not running. */ -export function assertContextRunning( - context: import("../context/BaseContext").BaseContext -): void { +export function assertContextRunning(context: BaseContext): void { // add a warning if the context is not started if (!context.isOffline && context.state !== "running") { warn( - "The AudioContext is \"suspended\". Invoke Tone.start() from a user action to start the audio." + 'The AudioContext is "suspended". Invoke Tone.start() from a user action to start the audio.' ); } } @@ -52,12 +52,16 @@ export function enterScheduledCallback(insideCallback: boolean): void { /** * Make sure that a time was passed into */ -export function assertUsedScheduleTime( - time?: import("../type/Units").Time -): void { - if (isUndef(time) && isInsideScheduledCallback && !printedScheduledWarning) { +export function assertUsedScheduleTime(time?: Time): void { + if ( + isUndef(time) && + isInsideScheduledCallback && + !printedScheduledWarning + ) { printedScheduledWarning = true; - warn("Events scheduled inside of scheduled callbacks should use the passed in scheduling time. See https://github.com/Tonejs/Tone.js/wiki/Accurate-Timing"); + warn( + "Events scheduled inside of scheduled callbacks should use the passed in scheduling time. See https://github.com/Tonejs/Tone.js/wiki/Accurate-Timing" + ); } } diff --git a/Tone/core/util/Decorator.ts b/Tone/core/util/Decorator.ts index f1e78533..09374c61 100644 --- a/Tone/core/util/Decorator.ts +++ b/Tone/core/util/Decorator.ts @@ -1,27 +1,23 @@ -import { assertRange } from "./Debug"; -import { Time } from "../type/Units"; +import { assertRange } from "./Debug.js"; +import { Time } from "../type/Units.js"; /** * Assert that the number is in the given range. */ export function range(min: number, max = Infinity) { const valueMap: WeakMap = new WeakMap(); - return function(target: any, propertyKey: string | symbol) { - Reflect.defineProperty( - target, - propertyKey, - { - configurable: true, - enumerable: true, - get: function() { - return valueMap.get(this); - }, - set: function(newValue: number) { - assertRange(newValue, min, max); - valueMap.set(this, newValue); - } + return function (target: any, propertyKey: string | symbol) { + Reflect.defineProperty(target, propertyKey, { + configurable: true, + enumerable: true, + get: function () { + return valueMap.get(this); }, - ); + set: function (newValue: number) { + assertRange(newValue, min, max); + valueMap.set(this, newValue); + }, + }); }; } @@ -31,21 +27,17 @@ export function range(min: number, max = Infinity) { */ export function timeRange(min: number, max = Infinity) { const valueMap: WeakMap = new WeakMap(); - return function(target: any, propertyKey: string) { - Reflect.defineProperty( - target, - propertyKey, - { - configurable: true, - enumerable: true, - get: function() { - return valueMap.get(this); - }, - set: function(newValue: Time) { - assertRange(this.toSeconds(newValue), min, max); - valueMap.set(this, newValue); - } + return function (target: any, propertyKey: string) { + Reflect.defineProperty(target, propertyKey, { + configurable: true, + enumerable: true, + get: function () { + return valueMap.get(this); + }, + set: function (newValue: Time) { + assertRange(this.toSeconds(newValue), min, max); + valueMap.set(this, newValue); }, - ); + }); }; } diff --git a/Tone/core/util/Defaults.ts b/Tone/core/util/Defaults.ts index 8da7d56b..0c422fe4 100644 --- a/Tone/core/util/Defaults.ts +++ b/Tone/core/util/Defaults.ts @@ -1,27 +1,44 @@ -import { isAudioBuffer, isAudioNode, isAudioParam } from "./AdvancedTypeCheck"; -import { isDefined, isObject, isUndef } from "./TypeCheck"; - -type BaseToneOptions = import("../Tone").BaseToneOptions; +import { + isAudioBuffer, + isAudioNode, + isAudioParam, +} from "./AdvancedTypeCheck.js"; +import { isDefined, isObject, isUndef } from "./TypeCheck.js"; +import type { BaseToneOptions } from "../Tone.js"; /** * Some objects should not be merged */ function noCopy(key: string, arg: any): boolean { - return key === "value" || isAudioParam(arg) || isAudioNode(arg) || isAudioBuffer(arg); + return ( + key === "value" || + isAudioParam(arg) || + isAudioNode(arg) || + isAudioBuffer(arg) + ); } +export function deepMerge(target: T): T; +export function deepMerge(target: T, source1: U): T & U; +export function deepMerge( + target: T, + source1: U, + source2: V +): T & U & V; +export function deepMerge( + target: T, + source1: U, + source2: V, + source3: W +): T & U & V & W; /** * Recursively merge an object * @param target the object to merge into * @param sources the source objects to merge */ -export function deepMerge(target: T): T; -export function deepMerge(target: T, source1: U): T & U; -export function deepMerge(target: T, source1: U, source2: V): T & U & V; -export function deepMerge(target: T, source1: U, source2: V, source3: W): T & U & V & W; export function deepMerge(target: any, ...sources: any[]): any { if (!sources.length) { - return target; + return target; } const source = sources.shift(); @@ -31,7 +48,7 @@ export function deepMerge(target: any, ...sources: any[]): any { target[key] = source[key]; } else if (isObject(source[key])) { if (!target[key]) { - Object.assign(target, { [key]: {} }); + Object.assign(target, { [key]: {} }); } deepMerge(target[key], source[key] as any); } else { @@ -47,7 +64,10 @@ export function deepMerge(target: any, ...sources: any[]): any { * Returns true if the two arrays have the same value for each of the elements */ export function deepEquals(arrayA: T[], arrayB: T[]): boolean { - return arrayA.length === arrayB.length && arrayA.every((element, index) => arrayB[index] === element); + return ( + arrayA.length === arrayB.length && + arrayA.every((element, index) => arrayB[index] === element) + ); } /** @@ -58,14 +78,16 @@ export function optionsFromArguments( defaults: T, argsArray: IArguments, keys: Array = [], - objKey?: keyof T, + objKey?: keyof T ): T { const opts: Partial = {}; const args = Array.from(argsArray); // if the first argument is an object and has an object key if (isObject(args[0]) && objKey && !Reflect.has(args[0], objKey)) { // if it's not part of the defaults - const partOfDefaults = Object.keys(args[0]).some(key => Reflect.has(defaults, key)); + const partOfDefaults = Object.keys(args[0]).some((key) => + Reflect.has(defaults, key) + ); if (!partOfDefaults) { // merge that key deepMerge(opts, { [objKey]: args[0] }); @@ -115,8 +137,11 @@ export function defaultArg(given: T, fallback: T): T { /** * Remove all of the properties belonging to omit from obj. */ -export function omitFromObject(obj: T, omit: O): Omit { - omit.forEach(prop => { +export function omitFromObject( + obj: T, + omit: O +): Omit { + omit.forEach((prop) => { if (Reflect.has(obj, prop)) { delete obj[prop]; } diff --git a/Tone/core/util/Draw.test.ts b/Tone/core/util/Draw.test.ts index 5cc66a5f..82f06a46 100644 --- a/Tone/core/util/Draw.test.ts +++ b/Tone/core/util/Draw.test.ts @@ -1,72 +1,66 @@ import { expect } from "chai"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { DrawClass } from "./Draw"; +import { DrawClass } from "./Draw.js"; describe("Draw", () => { + const draw = new DrawClass(); - if (ONLINE_TESTING) { + after(() => { + draw.dispose(); + }); - const draw = new DrawClass(); + it("can schedule a callback at a AudioContext time", (done) => { + const scheduledTime = draw.now() + 0.2; + draw.schedule(() => { + expect(draw.context.currentTime).to.be.closeTo(scheduledTime, 0.05); + done(); + }, scheduledTime); + }); - after(() => { - draw.dispose(); - }); + it("can schedule multiple callbacks", (done) => { + let callbackCount = 0; + const firstEvent = draw.now() + 0.1; + draw.schedule(() => { + callbackCount++; + expect(draw.context.currentTime).to.be.closeTo(firstEvent, 0.05); + }, firstEvent); - it("can schedule a callback at a AudioContext time", (done) => { - const scheduledTime = draw.now() + 0.2; - draw.schedule(() => { - expect(draw.context.currentTime).to.be.closeTo(scheduledTime, 0.05); - done(); - }, scheduledTime); - }); + const thirdEvent = draw.now() + 0.3; + draw.schedule(() => { + callbackCount++; + expect(draw.context.currentTime).to.be.closeTo(thirdEvent, 0.05); + expect(callbackCount).to.equal(3); + done(); + }, thirdEvent); - it("can schedule multiple callbacks", (done) => { - let callbackCount = 0; - const firstEvent = draw.now() + 0.1; - draw.schedule(() => { - callbackCount++; - expect(draw.context.currentTime).to.be.closeTo(firstEvent, 0.05); - }, firstEvent); + const secondEvent = draw.now() + 0.2; + draw.schedule(() => { + callbackCount++; + expect(draw.context.currentTime).to.be.closeTo(secondEvent, 0.05); + }, secondEvent); + }); - const thirdEvent = draw.now() + 0.3; - draw.schedule(() => { - callbackCount++; - expect(draw.context.currentTime).to.be.closeTo(thirdEvent, 0.05); - expect(callbackCount).to.equal(3); - done(); - }, thirdEvent); + it("can cancel scheduled events", (done) => { + let callbackCount = 0; + draw.schedule(() => { + callbackCount++; + }, draw.now() + 0.1); - const secondEvent = draw.now() + 0.2; - draw.schedule(() => { - callbackCount++; - expect(draw.context.currentTime).to.be.closeTo(secondEvent, 0.05); - }, secondEvent); - }); + draw.schedule(() => { + throw new Error("should not call this method"); + }, draw.now() + 0.2); - it("can cancel scheduled events", (done) => { - let callbackCount = 0; - draw.schedule(() => { - callbackCount++; - }, draw.now() + 0.1); + draw.schedule(() => { + throw new Error("should not call this method"); + }, draw.now() + 0.25); - draw.schedule(() => { - throw new Error("should not call this method"); - }, draw.now() + 0.2); + // cancel the second and third events + draw.cancel(draw.now() + 0.15); - draw.schedule(() => { - throw new Error("should not call this method"); - }, draw.now() + 0.25); - - // cancel the second and third events - draw.cancel(draw.now() + 0.15); - - // schedule another one after - draw.schedule(() => { - callbackCount++; - expect(callbackCount).to.equal(2); - done(); - }, draw.now() + 0.3); - - }); - } + // schedule another one after + draw.schedule(() => { + callbackCount++; + expect(callbackCount).to.equal(2); + done(); + }, draw.now() + 0.3); + }); }); diff --git a/Tone/core/util/Draw.ts b/Tone/core/util/Draw.ts index 0cc3061d..03ca1981 100644 --- a/Tone/core/util/Draw.ts +++ b/Tone/core/util/Draw.ts @@ -1,7 +1,13 @@ -import { ToneWithContext, ToneWithContextOptions } from "../context/ToneWithContext"; -import { Seconds, Time } from "../type/Units"; -import { Timeline, TimelineEvent } from "./Timeline"; -import { onContextClose, onContextInit } from "../context/ContextInitialization"; +import { + ToneWithContext, + ToneWithContextOptions, +} from "../context/ToneWithContext.js"; +import { Seconds, Time } from "../type/Units.js"; +import { Timeline, TimelineEvent } from "./Timeline.js"; +import { + onContextClose, + onContextInit, +} from "../context/ContextInitialization.js"; interface DrawEvent extends TimelineEvent { callback: () => void; @@ -26,7 +32,6 @@ interface DrawEvent extends TimelineEvent { * @category Core */ export class DrawClass extends ToneWithContext { - readonly name: string = "Draw"; /** @@ -93,7 +98,10 @@ export class DrawClass extends ToneWithContext { */ private _drawLoop(): void { const now = this.context.currentTime; - while (this._events.length && (this._events.peek() as DrawEvent).time - this.anticipation <= now) { + while ( + this._events.length && + (this._events.peek() as DrawEvent).time - this.anticipation <= now + ) { const event = this._events.shift(); if (event && now - event.time <= this.expiration) { event.callback(); @@ -116,10 +124,10 @@ export class DrawClass extends ToneWithContext { // INITIALIZATION //------------------------------------- -onContextInit(context => { +onContextInit((context) => { context.draw = new DrawClass({ context }); }); -onContextClose(context => { +onContextClose((context) => { context.draw.dispose(); }); diff --git a/Tone/core/util/Emitter.test.ts b/Tone/core/util/Emitter.test.ts index 3f7ffa9a..d765d90e 100644 --- a/Tone/core/util/Emitter.test.ts +++ b/Tone/core/util/Emitter.test.ts @@ -1,14 +1,13 @@ import { expect } from "chai"; -import { Emitter } from "./Emitter"; +import { Emitter } from "./Emitter.js"; describe("Emitter", () => { - it("can be created and disposed", () => { const emitter = new Emitter(); emitter.dispose(); }); - it("can bind events", done => { + it("can bind events", (done) => { const emitter = new Emitter(); emitter.on("something", () => { done(); @@ -66,7 +65,7 @@ describe("Emitter", () => { emitter.dispose(); }); - it("can remove an event while emitting", done => { + it("can remove an event while emitting", (done) => { const emitter = new Emitter(); emitter.on("something", () => { emitter.off("something"); @@ -81,7 +80,7 @@ describe("Emitter", () => { it("can invoke an event once", () => { const emitter = new Emitter(); - emitter.once("something", val => { + emitter.once("something", (val) => { expect(val).to.equal(1); }); emitter.emit("something", 1); @@ -89,7 +88,7 @@ describe("Emitter", () => { emitter.dispose(); }); - it("can pass arguments to the callback", done => { + it("can pass arguments to the callback", (done) => { const emitter = new Emitter(); emitter.on("something", (arg0, arg1) => { expect(arg0).to.equal("A"); diff --git a/Tone/core/util/Emitter.ts b/Tone/core/util/Emitter.ts index 69f089a7..e1a198b5 100644 --- a/Tone/core/util/Emitter.ts +++ b/Tone/core/util/Emitter.ts @@ -1,5 +1,5 @@ -import { Tone } from "../Tone"; -import { isUndef } from "./TypeCheck"; +import { Tone } from "../Tone.js"; +import { isUndef } from "./TypeCheck.js"; export interface EmitterEventObject { [event: string]: Array<(...args: any[]) => void>; @@ -13,7 +13,6 @@ export interface EmitterEventObject { * @category Core */ export class Emitter extends Tone { - readonly name: string = "Emitter"; /** @@ -29,7 +28,7 @@ export class Emitter extends Tone { on(event: EventType, callback: (...args: any[]) => void): this { // split the event const events = event.split(/\W+/); - events.forEach(eventName => { + events.forEach((eventName) => { if (isUndef(this._events)) { this._events = {}; } @@ -65,7 +64,7 @@ export class Emitter extends Tone { */ off(event: EventType, callback?: (...args: any[]) => void): this { const events = event.split(/\W+/); - events.forEach(eventName => { + events.forEach((eventName) => { if (isUndef(this._events)) { this._events = {}; } @@ -91,7 +90,7 @@ export class Emitter extends Tone { * @param event The name of the event. * @param args The arguments to pass to the functions listening. */ - emit(event, ...args: any[]): this { + emit(event: EventType, ...args: any[]): this { if (this._events) { if (this._events.hasOwnProperty(event)) { const eventList = this._events[event].slice(0); @@ -108,8 +107,11 @@ export class Emitter extends Tone { */ static mixin(constr: any): void { // instance._events = {}; - ["on", "once", "off", "emit"].forEach(name => { - const property = Object.getOwnPropertyDescriptor(Emitter.prototype, name) as PropertyDescriptor; + ["on", "once", "off", "emit"].forEach((name) => { + const property = Object.getOwnPropertyDescriptor( + Emitter.prototype, + name + ) as PropertyDescriptor; Object.defineProperty(constr.prototype, name, property); }); } diff --git a/Tone/core/util/Interface.ts b/Tone/core/util/Interface.ts index b0bc9e8f..254b417b 100644 --- a/Tone/core/util/Interface.ts +++ b/Tone/core/util/Interface.ts @@ -1,4 +1,4 @@ -import { isArray } from "./TypeCheck"; +import { isArray } from "./TypeCheck.js"; // return an interface which excludes certain keys export type Omit = Pick>; @@ -8,7 +8,7 @@ export type Omit = Pick>; */ export function readOnly(target: object, property: string | string[]): void { if (isArray(property)) { - property.forEach(str => readOnly(target, str)); + property.forEach((str) => readOnly(target, str)); } else { Object.defineProperty(target, property, { enumerable: true, @@ -22,7 +22,7 @@ export function readOnly(target: object, property: string | string[]): void { */ export function writable(target: object, property: string | string[]): void { if (isArray(property)) { - property.forEach(str => writable(target, str)); + property.forEach((str) => writable(target, str)); } else { Object.defineProperty(target, property, { writable: true, @@ -38,8 +38,9 @@ export const noOp: (...args: any[]) => any = () => { * Recursive Partial taken from here: https://stackoverflow.com/a/51365037 */ export type RecursivePartial = { - [P in keyof T]?: - T[P] extends Array ? Array> : - T[P] extends object ? RecursivePartial : - T[P]; + [P in keyof T]?: T[P] extends Array + ? Array> + : T[P] extends object + ? RecursivePartial + : T[P]; }; diff --git a/Tone/core/util/IntervalTimeline.test.ts b/Tone/core/util/IntervalTimeline.test.ts index f55a1c9b..a5258307 100644 --- a/Tone/core/util/IntervalTimeline.test.ts +++ b/Tone/core/util/IntervalTimeline.test.ts @@ -1,13 +1,11 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { IntervalTimeline, IntervalTimelineEvent } from "./IntervalTimeline"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { IntervalTimeline, IntervalTimelineEvent } from "./IntervalTimeline.js"; describe("IntervalTimeline", () => { - BasicTests(IntervalTimeline); context("inserting/deleting events", () => { - it("accepts events into the timeline", () => { const sched = new IntervalTimeline(); sched.add({ @@ -129,11 +127,9 @@ describe("IntervalTimeline", () => { }).to.throw(Error); sched.dispose(); }); - }); context("getting events", () => { - it("returns null when no events are in the timeline", () => { const sched = new IntervalTimeline(); expect(sched.get(3)).to.equal(null); @@ -157,8 +153,7 @@ describe("IntervalTimeline", () => { state: "C", time: 2, }); - // @ts-ignore - expect(sched.get(0.2).state).to.equal("A"); + expect(sched.get(0.2)?.state).to.equal("A"); sched.dispose(); }); @@ -169,8 +164,7 @@ describe("IntervalTimeline", () => { state: "A", time: 0, }); - // @ts-ignore - expect(sched.get(0.99).state).to.equal("A"); + expect(sched.get(0.99)?.state).to.equal("A"); expect(sched.get(1)).to.equal(null); sched.dispose(); }); @@ -205,8 +199,7 @@ describe("IntervalTimeline", () => { state: "C", time: 2, }); - // @ts-ignore - expect(sched.get(0.2).state).to.equal("B"); + expect(sched.get(0.2)?.state).to.equal("B"); sched.dispose(); }); @@ -232,10 +225,8 @@ describe("IntervalTimeline", () => { sched.add(ev2); sched.remove(ev0); sched.remove(ev1); - // @ts-ignore expect(sched.get(0.2)).to.not.equal(null); - // @ts-ignore - expect(sched.get(0.2).state).to.equal("C"); + expect(sched.get(0.2)?.state).to.equal("C"); sched.dispose(); }); @@ -269,11 +260,9 @@ describe("IntervalTimeline", () => { } sched.dispose(); }); - }); context("cancelling", () => { - it("can cancel items after the given time", () => { const sched = new IntervalTimeline(); for (let i = 5; i < 100; i++) { @@ -304,7 +293,6 @@ describe("IntervalTimeline", () => { }); context("Iterators", () => { - it("iterates over all items and returns and item", () => { const sched = new IntervalTimeline(); sched.add({ time: 0, duration: 5 }); diff --git a/Tone/core/util/IntervalTimeline.ts b/Tone/core/util/IntervalTimeline.ts index 395bfa3a..f808467b 100644 --- a/Tone/core/util/IntervalTimeline.ts +++ b/Tone/core/util/IntervalTimeline.ts @@ -1,6 +1,6 @@ -import { Tone } from "../Tone"; -import { isDefined } from "./TypeCheck"; -import { assert } from "./Debug"; +import { Tone } from "../Tone.js"; +import { isDefined } from "./TypeCheck.js"; +import { assert } from "./Debug.js"; /** * An IntervalTimeline event must have a time and duration @@ -23,7 +23,6 @@ type IteratorCallback = (event: IntervalTimelineEvent) => void; * @internal */ export class IntervalTimeline extends Tone { - readonly name: string = "IntervalTimeline"; /** @@ -43,10 +42,17 @@ export class IntervalTimeline extends Tone { */ add(event: IntervalTimelineEvent): this { assert(isDefined(event.time), "Events must have a time property"); - assert(isDefined(event.duration), "Events must have a duration parameter"); + assert( + isDefined(event.duration), + "Events must have a duration parameter" + ); event.time = event.time.valueOf(); - let node: IntervalNode | null = new IntervalNode(event.time, event.time + event.duration, event); + let node: IntervalNode | null = new IntervalNode( + event.time, + event.time + event.duration, + event + ); if (this._root === null) { this._root = node; } else { @@ -95,7 +101,7 @@ export class IntervalTimeline extends Tone { * @param after The time to query. */ cancel(after: number): this { - this.forEachFrom(after, event => this.remove(event)); + this.forEachFrom(after, (event) => this.remove(event)); return this; } @@ -113,7 +119,10 @@ export class IntervalTimeline extends Tone { * Replace the references to the node in the node's parent * with the replacement node. */ - private _replaceNodeInParent(node: IntervalNode, replacement: IntervalNode | null): void { + private _replaceNodeInParent( + node: IntervalNode, + replacement: IntervalNode | null + ): void { if (node.parent !== null) { if (node.isLeftChild()) { node.parent.left = replacement; @@ -289,8 +298,8 @@ export class IntervalTimeline extends Tone { forEach(callback: IteratorCallback): this { if (this._root !== null) { const allNodes: IntervalNode[] = []; - this._root.traverse(node => allNodes.push(node)); - allNodes.forEach(node => { + this._root.traverse((node) => allNodes.push(node)); + allNodes.forEach((node) => { if (node.event) { callback(node.event); } @@ -309,7 +318,7 @@ export class IntervalTimeline extends Tone { if (this._root !== null) { const results: IntervalNode[] = []; this._root.search(time, results); - results.forEach(node => { + results.forEach((node) => { if (node.event) { callback(node.event); } @@ -328,7 +337,7 @@ export class IntervalTimeline extends Tone { if (this._root !== null) { const results: IntervalNode[] = []; this._root.searchAfter(time, results); - results.forEach(node => { + results.forEach((node) => { if (node.event) { callback(node.event); } @@ -343,7 +352,7 @@ export class IntervalTimeline extends Tone { dispose(): this { super.dispose(); if (this._root !== null) { - this._root.traverse(node => node.dispose()); + this._root.traverse((node) => node.dispose()); } this._root = null; return this; @@ -365,7 +374,6 @@ export class IntervalTimeline extends Tone { * @param high */ class IntervalNode { - // the event container event: IntervalTimelineEvent | null; // the low value diff --git a/Tone/core/util/Math.ts b/Tone/core/util/Math.ts index e91757dd..c6427a78 100644 --- a/Tone/core/util/Math.ts +++ b/Tone/core/util/Math.ts @@ -1,5 +1,5 @@ /** - * The threshold for correctness for operators. Less than one sample even + * The threshold for correctness for operators. Less than one sample even * at very high sampling rates (e.g. `1e-6 < 1 / 192000`). */ const EPSILON = 1e-6; diff --git a/Tone/core/util/StateTimeline.test.ts b/Tone/core/util/StateTimeline.test.ts index 909d04a7..1ba5284c 100644 --- a/Tone/core/util/StateTimeline.test.ts +++ b/Tone/core/util/StateTimeline.test.ts @@ -1,8 +1,7 @@ import { expect } from "chai"; -import { StateTimeline } from "./StateTimeline"; +import { StateTimeline } from "./StateTimeline.js"; describe("StateTimeline", () => { - it("can be created and disposed", () => { const sched = new StateTimeline(); sched.dispose(); @@ -59,20 +58,13 @@ describe("StateTimeline", () => { sched.setStateAtTime("started", 2); sched.setStateAtTime("stopped", 3); expect(sched.getLastState("stopped", 1)).to.exist; - // @ts-ignore - expect(sched.getLastState("stopped", 1).state).is.equal("stopped"); - // @ts-ignore + expect(sched.getLastState("stopped", 1)?.state).is.equal("stopped"); expect(sched.getLastState("stopped", 2)).to.exist; - // @ts-ignore - expect(sched.getLastState("stopped", 2).state).is.equal("stopped"); - // @ts-ignore - expect(sched.getLastState("stopped", 2).time).is.equal(1); - // @ts-ignore - expect(sched.getLastState("stopped", 0.9).time).to.equal(0); - // @ts-ignore - expect(sched.getLastState("stopped", 4).state).is.equal("stopped"); - // @ts-ignore - expect(sched.getLastState("stopped", 4).time).is.equal(3); + expect(sched.getLastState("stopped", 2)?.state).is.equal("stopped"); + expect(sched.getLastState("stopped", 2)?.time).is.equal(1); + expect(sched.getLastState("stopped", 0.9)?.time).to.equal(0); + expect(sched.getLastState("stopped", 4)?.state).is.equal("stopped"); + expect(sched.getLastState("stopped", 4)?.time).is.equal(3); sched.dispose(); }); @@ -82,22 +74,14 @@ describe("StateTimeline", () => { sched.setStateAtTime("stopped", 1); sched.setStateAtTime("started", 2); sched.setStateAtTime("stopped", 3); - // @ts-ignore expect(sched.getNextState("stopped", 1)).to.exist; - // @ts-ignore - expect(sched.getNextState("stopped", 1).state).is.equal("stopped"); - // @ts-ignore + expect(sched.getNextState("stopped", 1)?.state).is.equal("stopped"); expect(sched.getNextState("stopped", 2)).to.exist; - // @ts-ignore - expect(sched.getNextState("stopped", 2).state).is.equal("stopped"); - // @ts-ignore - expect(sched.getNextState("stopped", 2).time).is.equal(3); - // @ts-ignore + expect(sched.getNextState("stopped", 2)?.state).is.equal("stopped"); + expect(sched.getNextState("stopped", 2)?.time).is.equal(3); expect(sched.getNextState("stopped", 0.9)).to.exist; - // @ts-ignore - expect(sched.getNextState("stopped", 0.9).state).is.equal("stopped"); - // @ts-ignore - expect(sched.getNextState("stopped", 0.9).time).is.equal(1); + expect(sched.getNextState("stopped", 0.9)?.state).is.equal("stopped"); + expect(sched.getNextState("stopped", 0.9)?.time).is.equal(1); sched.dispose(); }); }); diff --git a/Tone/core/util/StateTimeline.ts b/Tone/core/util/StateTimeline.ts index 79074538..b806869b 100644 --- a/Tone/core/util/StateTimeline.ts +++ b/Tone/core/util/StateTimeline.ts @@ -1,6 +1,6 @@ -import { Seconds } from "../type/Units"; -import { Timeline, TimelineEvent } from "./Timeline"; -import { assertRange } from "./Debug"; +import { Seconds } from "../type/Units.js"; +import { Timeline, TimelineEvent } from "./Timeline.js"; +import { assertRange } from "./Debug.js"; export type BasicPlaybackState = "started" | "stopped"; export type PlaybackState = BasicPlaybackState | "paused"; @@ -14,8 +14,9 @@ export interface StateTimelineEvent extends TimelineEvent { * @param initial The initial state of the StateTimeline. Defaults to `undefined` * @internal */ -export class StateTimeline = Record> extends Timeline { - +export class StateTimeline< + AdditionalOptions extends Record = Record, +> extends Timeline { readonly name: string = "StateTimeline"; /** @@ -50,12 +51,18 @@ export class StateTimeline = Recor * @param time The time to query. * @param options Any additional options that are needed in the timeline. */ - setStateAtTime(state: PlaybackState, time: Seconds, options?: AdditionalOptions): this { + setStateAtTime( + state: PlaybackState, + time: Seconds, + options?: AdditionalOptions + ): this { assertRange(time, 0); - this.add(Object.assign({}, options, { - state, - time, - })); + this.add( + Object.assign({}, options, { + state, + time, + }) + ); return this; } @@ -65,7 +72,10 @@ export class StateTimeline = Recor * @param time When to check before * @return The event with the given state before the time */ - getLastState(state: PlaybackState, time: number): StateTimelineEvent & AdditionalOptions | undefined { + getLastState( + state: PlaybackState, + time: number + ): (StateTimelineEvent & AdditionalOptions) | undefined { // time = this.toSeconds(time); const index = this._search(time); for (let i = index; i >= 0; i--) { @@ -82,7 +92,10 @@ export class StateTimeline = Recor * @param time When to check from * @return The event with the given state after the time */ - getNextState(state: PlaybackState, time: number): StateTimelineEvent & AdditionalOptions | undefined { + getNextState( + state: PlaybackState, + time: number + ): (StateTimelineEvent & AdditionalOptions) | undefined { // time = this.toSeconds(time); const index = this._search(time); if (index !== -1) { diff --git a/Tone/core/util/Timeline.test.ts b/Tone/core/util/Timeline.test.ts index 4f4bca1d..ccdbee11 100644 --- a/Tone/core/util/Timeline.test.ts +++ b/Tone/core/util/Timeline.test.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { Timeline } from "./Timeline"; +import { Timeline } from "./Timeline.js"; interface StateTimelineEvent { state: string; @@ -17,14 +17,12 @@ interface TimelineValueEvent { } describe("Timeline", () => { - it("can be created and disposed", () => { const sched = new Timeline(); sched.dispose(); }); it("accepts events into the timeline", () => { - const sched = new Timeline(); sched.add({ state: "A", @@ -384,7 +382,6 @@ describe("Timeline", () => { }); context("Iterators", () => { - it("iterates over all items and returns and item", () => { const sched = new Timeline(); sched.add({ time: 0 }); diff --git a/Tone/core/util/Timeline.ts b/Tone/core/util/Timeline.ts index de65d93e..b8e7a0f6 100644 --- a/Tone/core/util/Timeline.ts +++ b/Tone/core/util/Timeline.ts @@ -1,8 +1,8 @@ -import { Tone } from "../Tone"; -import { Seconds } from "../type/Units"; -import { optionsFromArguments } from "./Defaults"; -import { assert } from "./Debug"; -import { EQ, GT, GTE, LT } from "./Math"; +import { Tone } from "../Tone.js"; +import { Seconds } from "../type/Units.js"; +import { optionsFromArguments } from "./Defaults.js"; +import { assert } from "./Debug.js"; +import { EQ, GT, GTE, LT } from "./Math.js"; type TimelineSearchParam = "ticks" | "time"; @@ -29,7 +29,6 @@ export interface TimelineEvent { * @internal */ export class Timeline extends Tone { - readonly name: string = "Timeline"; /** @@ -44,8 +43,8 @@ export class Timeline extends Tone { protected _timeline: GenericEvent[] = []; /** - * If the time value must always be greater than or equal to the last - * element on the list. + * If the time value must always be greater than or equal to the last + * element on the list. */ increasing: boolean; @@ -56,7 +55,11 @@ export class Timeline extends Tone { constructor(options?: Partial); constructor() { super(); - const options = optionsFromArguments(Timeline.getDefaults(), arguments, ["memory"]); + const options = optionsFromArguments( + Timeline.getDefaults(), + arguments, + ["memory"] + ); this.memory = options.memory; this.increasing = options.increasing; @@ -82,11 +85,17 @@ export class Timeline extends Tone { */ add(event: GenericEvent): this { // the event needs to have a time attribute - assert(Reflect.has(event, "time"), "Timeline: events must have a time attribute"); + assert( + Reflect.has(event, "time"), + "Timeline: events must have a time attribute" + ); event.time = event.time.valueOf(); if (this.increasing && this.length) { const lastValue = this._timeline[this.length - 1] as GenericEvent; - assert(GTE(event.time, lastValue.time), "The time must be greater than or equal to the last scheduled time"); + assert( + GTE(event.time, lastValue.time), + "The time must be greater than or equal to the last scheduled time" + ); this._timeline.push(event); } else { const index = this._search(event.time); @@ -117,7 +126,10 @@ export class Timeline extends Tone { * Get the nearest event whose time is less than or equal to the given time. * @param time The time to query. */ - get(time: number, param: TimelineSearchParam = "time"): GenericEvent | null { + get( + time: number, + param: TimelineSearchParam = "time" + ): GenericEvent | null { const index = this._search(time, param); if (index !== -1) { return this._timeline[index]; @@ -145,7 +157,10 @@ export class Timeline extends Tone { * Get the event which is scheduled after the given time. * @param time The time to query. */ - getAfter(time: number, param: TimelineSearchParam = "time"): GenericEvent | null { + getAfter( + time: number, + param: TimelineSearchParam = "time" + ): GenericEvent | null { const index = this._search(time, param); if (index + 1 < this._timeline.length) { return this._timeline[index + 1]; @@ -237,7 +252,10 @@ export class Timeline extends Tone { * If a time is searched before the first index in the timeline, -1 is returned. * If the time is after the end, the index of the last item is returned. */ - protected _search(time: number, param: TimelineSearchParam = "time"): number { + protected _search( + time: number, + param: TimelineSearchParam = "time" + ): number { if (this._timeline.length === 0) { return -1; } @@ -282,7 +300,8 @@ export class Timeline extends Tone { */ private _iterate( callback: (event: GenericEvent) => void, - lowerBound = 0, upperBound = this._timeline.length - 1, + lowerBound = 0, + upperBound = this._timeline.length - 1 ): void { this._timeline.slice(lowerBound, upperBound + 1).forEach(callback); } @@ -301,7 +320,10 @@ export class Timeline extends Tone { * @param time The time to check if items are before * @param callback The callback to invoke with every item */ - forEachBefore(time: Seconds, callback: (event: GenericEvent) => void): this { + forEachBefore( + time: Seconds, + callback: (event: GenericEvent) => void + ): this { // iterate over the items in reverse so that removing an item doesn't break things const upperBound = this._search(time); if (upperBound !== -1) { @@ -330,7 +352,11 @@ export class Timeline extends Tone { * @param endTime The end of the test interval. * @param callback The callback to invoke with every item */ - forEachBetween(startTime: number, endTime: number, callback: (event: GenericEvent) => void): this { + forEachBetween( + startTime: number, + endTime: number, + callback: (event: GenericEvent) => void + ): this { let lowerBound = this._search(startTime); let upperBound = this._search(endTime); if (lowerBound !== -1 && upperBound !== -1) { @@ -382,9 +408,13 @@ export class Timeline extends Tone { break; } } - this._iterate(event => { - callback(event); - }, lowerBound, upperBound); + this._iterate( + (event) => { + callback(event); + }, + lowerBound, + upperBound + ); } return this; } diff --git a/Tone/core/util/TimelineValue.test.ts b/Tone/core/util/TimelineValue.test.ts index 6b0d8ebe..14a119d5 100644 --- a/Tone/core/util/TimelineValue.test.ts +++ b/Tone/core/util/TimelineValue.test.ts @@ -1,8 +1,7 @@ import { expect } from "chai"; -import { TimelineValue } from "./TimelineValue"; +import { TimelineValue } from "./TimelineValue.js"; describe("TimelineValue", () => { - it("can be created and disposed", () => { const sched = new TimelineValue(0); sched.dispose(); @@ -10,8 +9,8 @@ describe("TimelineValue", () => { it("can add events to the timeline", () => { const sched = new TimelineValue(10); - sched.set(11, 1); - sched.set(1, 12); + sched.set(11, 1); + sched.set(1, 12); sched.set(3, 4); expect(sched.get(0)).to.equal(10); expect(sched.get(1)).to.equal(11); diff --git a/Tone/core/util/TimelineValue.ts b/Tone/core/util/TimelineValue.ts index dba66df1..456b4edb 100644 --- a/Tone/core/util/TimelineValue.ts +++ b/Tone/core/util/TimelineValue.ts @@ -1,6 +1,6 @@ -import { Timeline, TimelineEvent } from "./Timeline"; -import { Tone } from "../Tone"; -import { Seconds } from "../type/Units"; +import { Timeline, TimelineEvent } from "./Timeline.js"; +import { Tone } from "../Tone.js"; +import { Seconds } from "../type/Units.js"; interface TimelineValueEvent extends TimelineEvent { value: T; @@ -10,13 +10,14 @@ interface TimelineValueEvent extends TimelineEvent { * Represents a single value which is gettable and settable in a timed way */ export class TimelineValue extends Tone { - readonly name: string = "TimelineValue"; /** * The timeline which stores the values */ - private _timeline: Timeline> = new Timeline({ memory: 10 }) + private _timeline: Timeline> = new Timeline({ + memory: 10, + }); /** * Hold the value to return if there is no scheduled values @@ -27,7 +28,6 @@ export class TimelineValue extends Tone { * @param initialValue The value to return if there is no scheduled values */ constructor(initialValue: Type) { - super(); this._initialValue = initialValue; } @@ -37,11 +37,12 @@ export class TimelineValue extends Tone { */ set(value: Type, time: Seconds): this { this._timeline.add({ - value, time + value, + time, }); return this; } - + /** * Get the value at the given time */ diff --git a/Tone/core/util/TypeCheck.ts b/Tone/core/util/TypeCheck.ts index f0e76a7a..f34bbf6d 100644 --- a/Tone/core/util/TypeCheck.ts +++ b/Tone/core/util/TypeCheck.ts @@ -1,4 +1,4 @@ -import { Note } from "../type/Units"; +import { Note } from "../type/Units.js"; /** * Test if the arg is undefined diff --git a/Tone/core/util/global.d.ts b/Tone/core/util/global.d.ts index 6467bd32..94138370 100644 --- a/Tone/core/util/global.d.ts +++ b/Tone/core/util/global.d.ts @@ -3,5 +3,12 @@ * that the AudioParamMap extends Map */ interface AudioParamMap extends Map { - forEach(callbackfn: (value: AudioParam, key: string, parent: AudioParamMap) => void, thisArg?: any): void; + forEach( + callbackfn: ( + value: AudioParam, + key: string, + parent: AudioParamMap + ) => void, + thisArg?: any + ): void; } diff --git a/Tone/core/worklet/DelayLine.worklet.ts b/Tone/core/worklet/DelayLine.worklet.ts index 09aa2c40..afb2a617 100644 --- a/Tone/core/worklet/DelayLine.worklet.ts +++ b/Tone/core/worklet/DelayLine.worklet.ts @@ -1,4 +1,4 @@ -import { addToWorklet } from "./WorkletGlobalScope"; +import { addToWorklet } from "./WorkletGlobalScope.js"; const delayLine = /* javascript */ ` /** diff --git a/Tone/core/worklet/SingleIOProcessor.worklet.ts b/Tone/core/worklet/SingleIOProcessor.worklet.ts index a5418631..21789a7e 100644 --- a/Tone/core/worklet/SingleIOProcessor.worklet.ts +++ b/Tone/core/worklet/SingleIOProcessor.worklet.ts @@ -1,5 +1,5 @@ -import "./ToneAudioWorkletProcessor.worklet"; -import { addToWorklet } from "./WorkletGlobalScope"; +import "./ToneAudioWorkletProcessor.worklet.js"; +import { addToWorklet } from "./WorkletGlobalScope.js"; export const singleIOProcess = /* javascript */ ` /** diff --git a/Tone/core/worklet/ToneAudioWorklet.ts b/Tone/core/worklet/ToneAudioWorklet.ts index 8e68f4ac..90cf5fac 100644 --- a/Tone/core/worklet/ToneAudioWorklet.ts +++ b/Tone/core/worklet/ToneAudioWorklet.ts @@ -1,11 +1,15 @@ -import { ToneAudioNode, ToneAudioNodeOptions } from "../context/ToneAudioNode"; -import { noOp } from "../util/Interface"; -import { getWorkletGlobalScope } from "./WorkletGlobalScope"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../context/ToneAudioNode.js"; +import { noOp } from "../util/Interface.js"; +import { getWorkletGlobalScope } from "./WorkletGlobalScope.js"; export type ToneAudioWorkletOptions = ToneAudioNodeOptions; -export abstract class ToneAudioWorklet extends ToneAudioNode { - +export abstract class ToneAudioWorklet< + Options extends ToneAudioWorkletOptions, +> extends ToneAudioNode { readonly name: string = "ToneAudioWorklet"; /** @@ -46,7 +50,9 @@ export abstract class ToneAudioWorklet constructor(options: Options) { super(options); - const blobUrl = URL.createObjectURL(new Blob([getWorkletGlobalScope()], { type: "text/javascript" })); + const blobUrl = URL.createObjectURL( + new Blob([getWorkletGlobalScope()], { type: "text/javascript" }) + ); const name = this._audioWorkletName(); this._dummyGain = this.context.createGain(); @@ -56,8 +62,12 @@ export abstract class ToneAudioWorklet this.context.addAudioWorkletModule(blobUrl).then(() => { // create the worklet when it's read if (!this.disposed) { - this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions); - this._worklet.onprocessorerror = this.onprocessorerror.bind(this); + this._worklet = this.context.createAudioWorkletNode( + name, + this.workletOptions + ); + this._worklet.onprocessorerror = + this.onprocessorerror.bind(this); this.onReady(this._worklet); } }); @@ -72,5 +82,4 @@ export abstract class ToneAudioWorklet } return this; } - } diff --git a/Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts b/Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts index 92fe5b07..92467d9b 100644 --- a/Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts +++ b/Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts @@ -1,4 +1,4 @@ -import { addToWorklet } from "./WorkletGlobalScope"; +import { addToWorklet } from "./WorkletGlobalScope.js"; const toneAudioWorkletProcessor = /* javascript */ ` /** diff --git a/Tone/core/worklet/WorkletGlobalScope.ts b/Tone/core/worklet/WorkletGlobalScope.ts index b19b9ea2..a63f7908 100644 --- a/Tone/core/worklet/WorkletGlobalScope.ts +++ b/Tone/core/worklet/WorkletGlobalScope.ts @@ -14,7 +14,7 @@ export function addToWorklet(classOrFunction: string) { * Register a processor in the AudioWorkletGlobalScope with the given name */ export function registerProcessor(name: string, classDesc: string) { - const processor = /* javascript */`registerProcessor("${name}", ${classDesc})`; + const processor = /* javascript */ `registerProcessor("${name}", ${classDesc})`; workletContext.add(processor); } diff --git a/Tone/effect/AutoFilter.test.ts b/Tone/effect/AutoFilter.test.ts index c9007ce4..2dbcb462 100644 --- a/Tone/effect/AutoFilter.test.ts +++ b/Tone/effect/AutoFilter.test.ts @@ -1,37 +1,39 @@ -import { AutoFilter } from "./AutoFilter"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; -import teoria from "teoria"; -import { Offline } from "test/helper/Offline"; +import { AutoFilter } from "./AutoFilter.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Note } from "tonal"; +import { Offline } from "../../test/helper/Offline.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Noise } from "Tone/source"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Noise } from "../source/index.js"; describe("AutoFilter", () => { - BasicTests(AutoFilter); EffectTests(AutoFilter); it("matches a file", () => { - return CompareToFile(() => { - const autoFilter = new AutoFilter({ - baseFrequency: 200, - octaves: 4, - frequency: 4, - type: "sine" - }).toDestination(); - new Noise().connect(autoFilter).start(); - autoFilter.start(0.2); - }, "autoFilter.wav", 0.1); + return CompareToFile( + () => { + const autoFilter = new AutoFilter({ + baseFrequency: 200, + octaves: 4, + frequency: 4, + type: "sine", + }).toDestination(); + new Noise().connect(autoFilter).start(); + autoFilter.start(0.2); + }, + "autoFilter.wav", + 0.1 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const autoFilter = new AutoFilter({ baseFrequency: 2000, octaves: 2, - type: "sawtooth" + type: "sawtooth", }); expect(autoFilter.baseFrequency).to.be.closeTo(2000, 0.1); expect(autoFilter.octaves).to.equal(2); @@ -50,7 +52,7 @@ describe("AutoFilter", () => { autoFilter.set({ baseFrequency: 1200, frequency: 2.4, - type: "triangle" + type: "triangle", }); expect(autoFilter.get().baseFrequency).to.be.closeTo(1200, 0.01); expect(autoFilter.get().frequency).to.be.closeTo(2.4, 0.01); @@ -76,13 +78,15 @@ describe("AutoFilter", () => { it("accepts baseFrequency and octaves as frequency values", () => { const autoFilter = new AutoFilter("2n", "C2", 4); - expect(autoFilter.baseFrequency).to.be.closeTo(teoria.note("C2").fq(), 0.01); + expect(autoFilter.baseFrequency).to.be.closeTo( + Note.freq("C2") as number, + 0.01 + ); expect(autoFilter.octaves).to.equal(4); autoFilter.dispose(); }); it("can sync the frequency to the transport", () => { - return Offline(({ transport }) => { const autoFilter = new AutoFilter(2); autoFilter.sync(); @@ -96,7 +100,6 @@ describe("AutoFilter", () => { }); it("can unsync the frequency to the transport", () => { - return Offline(({ transport }) => { const autoFilter = new AutoFilter(2); autoFilter.sync(); @@ -110,4 +113,3 @@ describe("AutoFilter", () => { }); }); }); - diff --git a/Tone/effect/AutoFilter.ts b/Tone/effect/AutoFilter.ts index 63765f75..b67f3758 100644 --- a/Tone/effect/AutoFilter.ts +++ b/Tone/effect/AutoFilter.ts @@ -1,18 +1,21 @@ -import { Frequency, Positive } from "../core/type/Units"; -import { Filter, FilterOptions } from "../component/filter/Filter"; -import { SourceOptions } from "../source/Source"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFOEffect, LFOEffectOptions } from "./LFOEffect"; +import { Frequency, Positive } from "../core/type/Units.js"; +import { Filter, FilterOptions } from "../component/filter/Filter.js"; +import { SourceOptions } from "../source/Source.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFOEffect, LFOEffectOptions } from "./LFOEffect.js"; export interface AutoFilterOptions extends LFOEffectOptions { baseFrequency: Frequency; octaves: Positive; - filter: Omit; + filter: Omit< + FilterOptions, + keyof SourceOptions | "frequency" | "detune" | "gain" + >; } /** * AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency. - * Setting the LFO rate and depth allows for control over the filter modulation rate + * Setting the LFO rate and depth allows for control over the filter modulation rate * and depth. * * @example @@ -23,7 +26,6 @@ export interface AutoFilterOptions extends LFOEffectOptions { * @category Effect */ export class AutoFilter extends LFOEffect { - readonly name: string = "AutoFilter"; /** @@ -41,16 +43,31 @@ export class AutoFilter extends LFOEffect { * @param baseFrequency The lower value of the LFOs oscillation * @param octaves The number of octaves above the baseFrequency */ - constructor(frequency?: Frequency, baseFrequency?: Frequency, octaves?: Positive); + constructor( + frequency?: Frequency, + baseFrequency?: Frequency, + octaves?: Positive + ); constructor(options?: Partial); constructor() { + super( + optionsFromArguments(AutoFilter.getDefaults(), arguments, [ + "frequency", + "baseFrequency", + "octaves", + ]) + ); + const options = optionsFromArguments( + AutoFilter.getDefaults(), + arguments, + ["frequency", "baseFrequency", "octaves"] + ); - super(optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"])); - const options = optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]); - - this.filter = new Filter(Object.assign(options.filter, { - context: this.context, - })); + this.filter = new Filter( + Object.assign(options.filter, { + context: this.context, + }) + ); // connections this.connectEffect(this.filter); @@ -67,7 +84,7 @@ export class AutoFilter extends LFOEffect { type: "lowpass" as const, rolloff: -12 as -12, Q: 1, - } + }, }); } @@ -84,7 +101,7 @@ export class AutoFilter extends LFOEffect { } /** - * The maximum value of the filter's cutoff frequency. + * The maximum value of the filter's cutoff frequency. */ get octaves(): Positive { return this._octaves; diff --git a/Tone/effect/AutoPanner.test.ts b/Tone/effect/AutoPanner.test.ts index d80ccc04..ed7a29ba 100644 --- a/Tone/effect/AutoPanner.test.ts +++ b/Tone/effect/AutoPanner.test.ts @@ -1,32 +1,35 @@ -import { AutoPanner } from "./AutoPanner"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; -import { Offline } from "test/helper/Offline"; +import { AutoPanner } from "./AutoPanner.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Offline } from "../../test/helper/Offline.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; describe("AutoPanner", () => { BasicTests(AutoPanner); EffectTests(AutoPanner); it("matches a file", () => { - return CompareToFile(() => { - const autoFilter = new AutoPanner({ - type: "sine", - frequency: 3, - }).toDestination(); - new Oscillator().connect(autoFilter).start(); - autoFilter.start(0.2); - }, "autoPanner.wav", 0.01); + return CompareToFile( + () => { + const autoFilter = new AutoPanner({ + type: "sine", + frequency: 3, + }).toDestination(); + new Oscillator().connect(autoFilter).start(); + autoFilter.start(0.2); + }, + "autoPanner.wav", + 0.01 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const autoPanner = new AutoPanner({ type: "sawtooth", - depth: 0.2 + depth: 0.2, }); expect(autoPanner.depth.value).to.be.closeTo(0.2, 0.01); expect(autoPanner.type).to.equal("sawtooth"); @@ -43,7 +46,7 @@ describe("AutoPanner", () => { const autoPanner = new AutoPanner(); autoPanner.set({ frequency: 2.4, - type: "triangle" + type: "triangle", }); expect(autoPanner.get().frequency).to.be.closeTo(2.4, 0.01); expect(autoPanner.get().type).to.equal("triangle"); @@ -87,4 +90,3 @@ describe("AutoPanner", () => { }); }); }); - diff --git a/Tone/effect/AutoPanner.ts b/Tone/effect/AutoPanner.ts index 22088dbf..34aa82d4 100644 --- a/Tone/effect/AutoPanner.ts +++ b/Tone/effect/AutoPanner.ts @@ -1,14 +1,14 @@ -import { Panner } from "../component/channel/Panner"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFOEffect, LFOEffectOptions } from "./LFOEffect"; -import { Frequency } from "../core/type/Units"; +import { Panner } from "../component/channel/Panner.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFOEffect, LFOEffectOptions } from "./LFOEffect.js"; +import { Frequency } from "../core/type/Units.js"; export interface AutoPannerOptions extends LFOEffectOptions { channelCount: number; } /** - * AutoPanner is a {@link Panner} with an {@link LFO} connected to the pan amount. + * AutoPanner is a {@link Panner} with an {@link LFO} connected to the pan amount. * [Related Reading](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/). * * @example @@ -19,7 +19,6 @@ export interface AutoPannerOptions extends LFOEffectOptions { * @category Effect */ export class AutoPanner extends LFOEffect { - readonly name: string = "AutoPanner"; /** @@ -28,18 +27,25 @@ export class AutoPanner extends LFOEffect { readonly _panner: Panner; /** - * @param frequency Rate of left-right oscillation. + * @param frequency Rate of left-right oscillation. */ constructor(frequency?: Frequency); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"])); - const options = optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]); + super( + optionsFromArguments(AutoPanner.getDefaults(), arguments, [ + "frequency", + ]) + ); + const options = optionsFromArguments( + AutoPanner.getDefaults(), + arguments, + ["frequency"] + ); this._panner = new Panner({ context: this.context, - channelCount: options.channelCount + channelCount: options.channelCount, }); // connections this.connectEffect(this._panner); @@ -50,7 +56,7 @@ export class AutoPanner extends LFOEffect { static getDefaults(): AutoPannerOptions { return Object.assign(LFOEffect.getDefaults(), { - channelCount: 1 + channelCount: 1, }); } @@ -60,4 +66,3 @@ export class AutoPanner extends LFOEffect { return this; } } - diff --git a/Tone/effect/AutoWah.test.ts b/Tone/effect/AutoWah.test.ts index d0b50e16..56873cc3 100644 --- a/Tone/effect/AutoWah.test.ts +++ b/Tone/effect/AutoWah.test.ts @@ -1,31 +1,33 @@ -import { AutoWah } from "./AutoWah"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { AutoWah } from "./AutoWah.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Synth } from "Tone/instrument/Synth"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Synth } from "../instrument/Synth.js"; describe("AutoWah", () => { - BasicTests(AutoWah); EffectTests(AutoWah); it("matches a file", () => { - return CompareToFile(() => { - const wah = new AutoWah().toDestination(); - wah.follower = 0.4; - const synth = new Synth().connect(wah); - synth.triggerAttackRelease("C4", 0.5); - }, "autoWah.wav", 0.01); + return CompareToFile( + () => { + const wah = new AutoWah().toDestination(); + wah.follower = 0.4; + const synth = new Synth().connect(wah); + synth.triggerAttackRelease("C4", 0.5); + }, + "autoWah.wav", + 0.01 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const autoWah = new AutoWah({ baseFrequency: 150, octaves: 3, - sensitivity: -10 + sensitivity: -10, }); expect(autoWah.baseFrequency).to.be.closeTo(150, 0.01); autoWah.baseFrequency = 250; @@ -58,4 +60,3 @@ describe("AutoWah", () => { }); }); }); - diff --git a/Tone/effect/AutoWah.ts b/Tone/effect/AutoWah.ts index 9c978adb..ece8b670 100644 --- a/Tone/effect/AutoWah.ts +++ b/Tone/effect/AutoWah.ts @@ -1,13 +1,20 @@ -import { Effect, EffectOptions } from "./Effect"; -import { Filter } from "../component/filter/Filter"; -import { Follower } from "../component/analysis/Follower"; -import { Decibels, Frequency, GainFactor, Hertz, Positive, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Gain } from "../core/context/Gain"; -import { dbToGain, gainToDb } from "../core/type/Conversions"; -import { ScaleExp } from "../signal/ScaleExp"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; +import { Effect, EffectOptions } from "./Effect.js"; +import { Filter } from "../component/filter/Filter.js"; +import { Follower } from "../component/analysis/Follower.js"; +import { + Decibels, + Frequency, + GainFactor, + Hertz, + Positive, + Time, +} from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Gain } from "../core/context/Gain.js"; +import { dbToGain, gainToDb } from "../core/type/Conversions.js"; +import { ScaleExp } from "../signal/ScaleExp.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; export interface AutoWahOptions extends EffectOptions { baseFrequency: Frequency; @@ -19,10 +26,10 @@ export interface AutoWahOptions extends EffectOptions { } /** - * AutoWah connects a {@link Follower} to a {@link Filter}. - * The frequency of the filter, follows the input amplitude curve. + * AutoWah connects a {@link Follower} to a {@link Filter}. + * The frequency of the filter, follows the input amplitude curve. * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna). - * + * * @example * const autoWah = new Tone.AutoWah(50, 6, -30).toDestination(); * // initialize the synth and connect to autowah @@ -34,7 +41,6 @@ export interface AutoWahOptions extends EffectOptions { * @category Effect */ export class AutoWah extends Effect { - readonly name: string = "AutoWah"; /** @@ -85,15 +91,28 @@ export class AutoWah extends Effect { /** * @param baseFrequency The frequency the filter is set to at the low point of the wah - * @param octaves The number of octaves above the baseFrequency the filter will sweep to when fully open. + * @param octaves The number of octaves above the baseFrequency the filter will sweep to when fully open. * @param sensitivity The decibel threshold sensitivity for the incoming signal. Normal range of -40 to 0. */ - constructor(baseFrequency?: Frequency, octaves?: Positive, sensitivity?: Decibels); + constructor( + baseFrequency?: Frequency, + octaves?: Positive, + sensitivity?: Decibels + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"])); - const options = optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]); + super( + optionsFromArguments(AutoWah.getDefaults(), arguments, [ + "baseFrequency", + "octaves", + "sensitivity", + ]) + ); + const options = optionsFromArguments(AutoWah.getDefaults(), arguments, [ + "baseFrequency", + "octaves", + "sensitivity", + ]); this._follower = new Follower({ context: this.context, @@ -116,14 +135,18 @@ export class AutoWah extends Effect { }); this._peaking = new Filter({ context: this.context, - type: "peaking" + type: "peaking", }); this._peaking.gain.value = options.gain; this.gain = this._peaking.gain; this.Q = this._bandpass.Q; // the control signal path - this.effectSend.chain(this._inputBoost, this._follower, this._sweepRange); + this.effectSend.chain( + this._inputBoost, + this._follower, + this._sweepRange + ); this._sweepRange.connect(this._bandpass.frequency); this._sweepRange.connect(this._peaking.frequency); // the filtered path @@ -193,7 +216,10 @@ export class AutoWah extends Effect { */ private _setSweepRange() { this._sweepRange.min = this._baseFrequency; - this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2); + this._sweepRange.max = Math.min( + this._baseFrequency * Math.pow(2, this._octaves), + this.context.sampleRate / 2 + ); } dispose(): this { diff --git a/Tone/effect/BitCrusher.test.ts b/Tone/effect/BitCrusher.test.ts index 6e68b505..2d3132b0 100644 --- a/Tone/effect/BitCrusher.test.ts +++ b/Tone/effect/BitCrusher.test.ts @@ -1,24 +1,26 @@ -import { BitCrusher } from "./BitCrusher"; -import { FeedbackCombFilter } from "Tone/component/filter/FeedbackCombFilter"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { BitCrusher } from "./BitCrusher.js"; +import { FeedbackCombFilter } from "../component/filter/FeedbackCombFilter.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; import { expect } from "chai"; describe("BitCrusher", () => { - BasicTests(BitCrusher); EffectTests(BitCrusher); context("API", () => { - it("matches a file", () => { - return CompareToFile(() => { - const crusher = new BitCrusher({ bits: 4 }).toDestination(); - const osc = new Oscillator(110).connect(crusher); - osc.start(0); - }, "bitCrusher.wav", 0.01); + return CompareToFile( + () => { + const crusher = new BitCrusher({ bits: 4 }).toDestination(); + const osc = new Oscillator(110).connect(crusher); + osc.start(0); + }, + "bitCrusher.wav", + 0.01 + ); }); it("can pass in options in the constructor", () => { @@ -55,4 +57,3 @@ describe("BitCrusher", () => { }; }); }); - diff --git a/Tone/effect/BitCrusher.ts b/Tone/effect/BitCrusher.ts index a1fd87f8..aa86fd46 100644 --- a/Tone/effect/BitCrusher.ts +++ b/Tone/effect/BitCrusher.ts @@ -1,11 +1,14 @@ -import { ToneAudioWorklet, ToneAudioWorkletOptions } from "../core/worklet/ToneAudioWorklet"; -import { Effect, EffectOptions } from "./Effect"; -import { Positive } from "../core/type/Units"; -import { Gain } from "../core/context/Gain"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { connectSeries } from "../core/context/ToneAudioNode"; -import { Param } from "../core/context/Param"; -import { workletName } from "./BitCrusher.worklet"; +import { + ToneAudioWorklet, + ToneAudioWorkletOptions, +} from "../core/worklet/ToneAudioWorklet.js"; +import { Effect, EffectOptions } from "./Effect.js"; +import { Positive } from "../core/type/Units.js"; +import { Gain } from "../core/context/Gain.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { connectSeries } from "../core/context/ToneAudioNode.js"; +import { Param } from "../core/context/Param.js"; +import { workletName } from "./BitCrusher.worklet.js"; export interface BitCrusherOptions extends EffectOptions { bits: Positive; @@ -20,11 +23,10 @@ export interface BitCrusherOptions extends EffectOptions { * const crusher = new Tone.BitCrusher(4).toDestination(); * const synth = new Tone.Synth().connect(crusher); * synth.triggerAttackRelease("C2", 2); - * + * * @category Effect */ export class BitCrusher extends Effect { - readonly name: string = "BitCrusher"; /** @@ -42,8 +44,14 @@ export class BitCrusher extends Effect { constructor(bits?: Positive); constructor(options?: Partial); constructor() { - super(optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"])); - const options = optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]); + super( + optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]) + ); + const options = optionsFromArguments( + BitCrusher.getDefaults(), + arguments, + ["bits"] + ); this._bitCrusherWorklet = new BitCrusherWorklet({ context: this.context, @@ -76,7 +84,6 @@ interface BitCrusherWorkletOptions extends ToneAudioWorkletOptions { * Internal class which creates an AudioWorklet to do the bit crushing */ class BitCrusherWorklet extends ToneAudioWorklet { - readonly name: string = "BitCrusherWorklet"; readonly input: Gain; @@ -87,7 +94,10 @@ class BitCrusherWorklet extends ToneAudioWorklet { constructor(options?: Partial); constructor() { super(optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments)); - const options = optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments); + const options = optionsFromArguments( + BitCrusherWorklet.getDefaults(), + arguments + ); this.input = new Gain({ context: this.context }); this.output = new Gain({ context: this.context }); diff --git a/Tone/effect/BitCrusher.worklet.ts b/Tone/effect/BitCrusher.worklet.ts index e56b6aeb..8b99a2af 100644 --- a/Tone/effect/BitCrusher.worklet.ts +++ b/Tone/effect/BitCrusher.worklet.ts @@ -1,9 +1,9 @@ -import "../core/worklet/SingleIOProcessor.worklet"; -import { registerProcessor } from "../core/worklet/WorkletGlobalScope"; +import "../core/worklet/SingleIOProcessor.worklet.js"; +import { registerProcessor } from "../core/worklet/WorkletGlobalScope.js"; export const workletName = "bit-crusher"; -export const bitCrusherWorklet = /* javascript */` +export const bitCrusherWorklet = /* javascript */ ` class BitCrusherWorklet extends SingleIOProcessor { static get parameterDescriptors() { diff --git a/Tone/effect/Chebyshev.test.ts b/Tone/effect/Chebyshev.test.ts index f3b1e7e4..53b57617 100644 --- a/Tone/effect/Chebyshev.test.ts +++ b/Tone/effect/Chebyshev.test.ts @@ -1,25 +1,27 @@ -import { Chebyshev } from "./Chebyshev"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { Chebyshev } from "./Chebyshev.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Synth } from "Tone/instrument"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Synth } from "../instrument/index.js"; describe("Chebyshev", () => { - BasicTests(Chebyshev); EffectTests(Chebyshev, 51); it("matches a file", () => { - return CompareToFile(() => { - const cheby = new Chebyshev(100).toDestination(); - const synth = new Synth().connect(cheby); - synth.triggerAttackRelease("C2", 0.2); - }, "chebyshev.wav", 0.01); + return CompareToFile( + () => { + const cheby = new Chebyshev(100).toDestination(); + const synth = new Synth().connect(cheby); + synth.triggerAttackRelease("C2", 0.2); + }, + "chebyshev.wav", + 0.01 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const cheby = new Chebyshev({ order: 2, @@ -46,4 +48,3 @@ describe("Chebyshev", () => { }); }); }); - diff --git a/Tone/effect/Chebyshev.ts b/Tone/effect/Chebyshev.ts index 74b9a7f8..f2f0ac05 100644 --- a/Tone/effect/Chebyshev.ts +++ b/Tone/effect/Chebyshev.ts @@ -1,8 +1,8 @@ -import { Effect, EffectOptions } from "./Effect"; -import { Positive } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { WaveShaper } from "../signal/WaveShaper"; -import { assert } from "../core/util/Debug"; +import { Effect, EffectOptions } from "./Effect.js"; +import { Positive } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { WaveShaper } from "../signal/WaveShaper.js"; +import { assert } from "../core/util/Debug.js"; export interface ChebyshevOptions extends EffectOptions { order: Positive; @@ -10,10 +10,10 @@ export interface ChebyshevOptions extends EffectOptions { } /** - * Chebyshev is a waveshaper which is good + * Chebyshev is a waveshaper which is good * for making different types of distortion sounds. - * Note that odd orders sound very different from even ones, - * and order = 1 is no change. + * Note that odd orders sound very different from even ones, + * and order = 1 is no change. * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php). * @example * // create a new cheby @@ -24,7 +24,6 @@ export interface ChebyshevOptions extends EffectOptions { * @category Effect */ export class Chebyshev extends Effect { - readonly name: string = "Chebyshev"; /** @@ -38,18 +37,23 @@ export class Chebyshev extends Effect { private _order: number; /** - * @param order The order of the chebyshev polynomial. Normal range between 1-100. + * @param order The order of the chebyshev polynomial. Normal range between 1-100. */ constructor(order?: Positive); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"])); - const options = optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]); + super( + optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]) + ); + const options = optionsFromArguments( + Chebyshev.getDefaults(), + arguments, + ["order"] + ); this._shaper = new WaveShaper({ context: this.context, - length: 4096 + length: 4096, }); this._order = options.order; @@ -61,17 +65,21 @@ export class Chebyshev extends Effect { static getDefaults(): ChebyshevOptions { return Object.assign(Effect.getDefaults(), { order: 1, - oversample: "none" as const + oversample: "none" as const, }); } /** * get the coefficient for that degree * @param x the x value - * @param degree - * @param memo memoize the computed value. this speeds up computation greatly. + * @param degree + * @param memo memoize the computed value. this speeds up computation greatly. */ - private _getCoefficient(x: number, degree: number, memo: Map): number { + private _getCoefficient( + x: number, + degree: number, + memo: Map + ): number { if (memo.has(degree)) { return memo.get(degree) as number; } else if (degree === 0) { @@ -79,17 +87,21 @@ export class Chebyshev extends Effect { } else if (degree === 1) { memo.set(degree, x); } else { - memo.set(degree, 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo)); + memo.set( + degree, + 2 * x * this._getCoefficient(x, degree - 1, memo) - + this._getCoefficient(x, degree - 2, memo) + ); } return memo.get(degree) as number; } /** - * The order of the Chebyshev polynomial which creates the equation which is applied to the incoming + * The order of the Chebyshev polynomial which creates the equation which is applied to the incoming * signal through a Tone.WaveShaper. Must be an integer. The equations are in the form: * ``` * order 2: 2x^2 + 1 - * order 3: 4x^3 + 3x + * order 3: 4x^3 + 3x * ``` * @min 1 * @max 100 @@ -100,9 +112,9 @@ export class Chebyshev extends Effect { set order(order) { assert(Number.isInteger(order), "'order' must be an integer"); this._order = order; - this._shaper.setMap((x => { + this._shaper.setMap((x) => { return this._getCoefficient(x, order, new Map()); - })); + }); } /** diff --git a/Tone/effect/Chorus.test.ts b/Tone/effect/Chorus.test.ts index dc3d649a..f34d78d1 100644 --- a/Tone/effect/Chorus.test.ts +++ b/Tone/effect/Chorus.test.ts @@ -1,10 +1,10 @@ -import { Chorus } from "./Chorus"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { Chorus } from "./Chorus.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source"; -import { Offline } from "test/helper/Offline"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/index.js"; +import { Offline } from "../../test/helper/Offline.js"; describe("Chorus", () => { BasicTests(Chorus); @@ -15,8 +15,8 @@ describe("Chorus", () => { () => { const chorus = new Chorus().toDestination().start(); const osc = new Oscillator(220, "sawtooth") - .connect(chorus) - .start(); + .connect(chorus) + .start(); }, "chorus.wav", 0.25 diff --git a/Tone/effect/Chorus.ts b/Tone/effect/Chorus.ts index 32aacd75..aa6a18dc 100644 --- a/Tone/effect/Chorus.ts +++ b/Tone/effect/Chorus.ts @@ -1,11 +1,21 @@ -import { StereoFeedbackEffect, StereoFeedbackEffectOptions } from "../effect/StereoFeedbackEffect"; -import { Degrees, Frequency, Milliseconds, NormalRange, Seconds, Time } from "../core/type/Units"; -import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFO } from "../source/oscillator/LFO"; -import { Delay } from "../core/context/Delay"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; +import { + StereoFeedbackEffect, + StereoFeedbackEffectOptions, +} from "../effect/StereoFeedbackEffect.js"; +import { + Degrees, + Frequency, + Milliseconds, + NormalRange, + Seconds, + Time, +} from "../core/type/Units.js"; +import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Delay } from "../core/context/Delay.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; export interface ChorusOptions extends StereoFeedbackEffectOptions { frequency: Frequency; @@ -29,7 +39,6 @@ export interface ChorusOptions extends StereoFeedbackEffectOptions { * @category Effect */ export class Chorus extends StereoFeedbackEffect { - readonly name: string = "Chorus"; /** @@ -45,12 +54,12 @@ export class Chorus extends StereoFeedbackEffect { /** * the lfo which controls the delayTime */ - private _lfoL: LFO + private _lfoL: LFO; /** * another LFO for the right side with a 180 degree phase diff */ - private _lfoR: LFO + private _lfoR: LFO; /** * delay for left @@ -65,19 +74,32 @@ export class Chorus extends StereoFeedbackEffect { /** * The frequency of the LFO which modulates the delayTime. */ - readonly frequency: Signal<"frequency"> + readonly frequency: Signal<"frequency">; /** * @param frequency The frequency of the LFO. * @param delayTime The delay of the chorus effect in ms. * @param depth The depth of the chorus. */ - constructor(frequency?: Frequency, delayTime?: Milliseconds, depth?: NormalRange); + constructor( + frequency?: Frequency, + delayTime?: Milliseconds, + depth?: NormalRange + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"])); - const options = optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]); + super( + optionsFromArguments(Chorus.getDefaults(), arguments, [ + "frequency", + "delayTime", + "depth", + ]) + ); + const options = optionsFromArguments(Chorus.getDefaults(), arguments, [ + "frequency", + "delayTime", + "depth", + ]); this._depth = options.depth; this._delayTime = options.delayTime / 1000; @@ -92,7 +114,7 @@ export class Chorus extends StereoFeedbackEffect { frequency: options.frequency, min: 0, max: 1, - phase: 180 + phase: 180, }); this._delayNodeL = new Delay({ context: this.context }); this._delayNodeR = new Delay({ context: this.context }); @@ -173,8 +195,8 @@ export class Chorus extends StereoFeedbackEffect { return this._lfoR.phase - this._lfoL.phase; } set spread(spread) { - this._lfoL.phase = 90 - (spread / 2); - this._lfoR.phase = (spread / 2) + 90; + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; } /** @@ -196,7 +218,7 @@ export class Chorus extends StereoFeedbackEffect { } /** - * Sync the filter to the transport. + * Sync the filter to the transport. * @see {@link LFO.sync} */ sync(): this { diff --git a/Tone/effect/Distortion.test.ts b/Tone/effect/Distortion.test.ts index 423169ee..4d0977d2 100644 --- a/Tone/effect/Distortion.test.ts +++ b/Tone/effect/Distortion.test.ts @@ -1,26 +1,28 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { EffectTests } from "test/helper/EffectTests"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { Distortion } from "./Distortion"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { Distortion } from "./Distortion.js"; describe("Distortion", () => { - BasicTests(Distortion); EffectTests(Distortion); it("matches a file", () => { - return CompareToFile(() => { - const dist = new Distortion(0.8).toDestination(); - const osc = new Oscillator().connect(dist); - osc.type = "square"; - osc.start(0).stop(0.4); - }, "distortion.wav", 0.02); + return CompareToFile( + () => { + const dist = new Distortion(0.8).toDestination(); + const osc = new Oscillator().connect(dist); + osc.type = "square"; + osc.start(0).stop(0.4); + }, + "distortion.wav", + 0.02 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const dist = new Distortion({ distortion: 0.2, diff --git a/Tone/effect/Distortion.ts b/Tone/effect/Distortion.ts index 3753fbf4..b07af346 100644 --- a/Tone/effect/Distortion.ts +++ b/Tone/effect/Distortion.ts @@ -1,6 +1,6 @@ -import { optionsFromArguments } from "../core/util/Defaults"; -import { WaveShaper } from "../signal/WaveShaper"; -import { Effect, EffectOptions } from "./Effect"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { WaveShaper } from "../signal/WaveShaper.js"; +import { Effect, EffectOptions } from "./Effect.js"; export interface DistortionOptions extends EffectOptions { distortion: number; @@ -18,7 +18,6 @@ export interface DistortionOptions extends EffectOptions { * @category Effect */ export class Distortion extends Effect { - readonly name: string = "Distortion"; /** @@ -37,9 +36,16 @@ export class Distortion extends Effect { constructor(distortion?: number); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"])); - const options = optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]); + super( + optionsFromArguments(Distortion.getDefaults(), arguments, [ + "distortion", + ]) + ); + const options = optionsFromArguments( + Distortion.getDefaults(), + arguments, + ["distortion"] + ); this._shaper = new WaveShaper({ context: this.context, @@ -75,7 +81,7 @@ export class Distortion extends Effect { // should output 0 when input is 0 return 0; } else { - return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x)); + return ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x)); } }); } diff --git a/Tone/effect/Effect.ts b/Tone/effect/Effect.ts index 9a2205ff..88e2e18d 100644 --- a/Tone/effect/Effect.ts +++ b/Tone/effect/Effect.ts @@ -1,9 +1,12 @@ -import { CrossFade } from "../component/channel/CrossFade"; -import { Gain } from "../core/context/Gain"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { NormalRange } from "../core/type/Units"; -import { readOnly } from "../core/util/Interface"; -import { Signal } from "../signal/Signal"; +import { CrossFade } from "../component/channel/CrossFade.js"; +import { Gain } from "../core/context/Gain.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { NormalRange } from "../core/type/Units.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Signal } from "../signal/Signal.js"; export interface EffectOptions extends ToneAudioNodeOptions { wet: NormalRange; @@ -13,9 +16,9 @@ export interface EffectOptions extends ToneAudioNodeOptions { * the effectSend and effectReturn GainNodes, then control the amount of * effect which goes to the output using the wet control. */ -export abstract class Effect - extends ToneAudioNode { - +export abstract class Effect< + Options extends EffectOptions, +> extends ToneAudioNode { readonly name: string = "Effect"; /** diff --git a/Tone/effect/FeedbackDelay.test.ts b/Tone/effect/FeedbackDelay.test.ts index cafcf4b0..e58d7140 100644 --- a/Tone/effect/FeedbackDelay.test.ts +++ b/Tone/effect/FeedbackDelay.test.ts @@ -1,27 +1,29 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { EffectTests } from "test/helper/EffectTests"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { FeedbackDelay } from "./FeedbackDelay"; -import { FeedbackEffect } from "./FeedbackEffect"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { FeedbackDelay } from "./FeedbackDelay.js"; +import { FeedbackEffect } from "./FeedbackEffect.js"; describe("FeedbackDelay", () => { - BasicTests(FeedbackDelay); EffectTests(FeedbackDelay, 0.01); it("matches a file", () => { - return CompareToFile(() => { - const delay = new FeedbackDelay(0.1, 0.6).toDestination(); - const osc = new Oscillator().connect(delay); - osc.type = "square"; - osc.start(0).stop(0.01); - }, "feedbackDelay.wav", 0.05); + return CompareToFile( + () => { + const delay = new FeedbackDelay(0.1, 0.6).toDestination(); + const osc = new Oscillator().connect(delay); + osc.type = "square"; + osc.start(0).stop(0.01); + }, + "feedbackDelay.wav", + 0.05 + ); }); context("API", () => { - it("extends FeedbackEffect", () => { const feedbackDelay = new FeedbackDelay(0.2, 0.3); expect(feedbackDelay).to.be.instanceOf(FeedbackEffect); diff --git a/Tone/effect/FeedbackDelay.ts b/Tone/effect/FeedbackDelay.ts index 3ba8239b..65b9c8a2 100644 --- a/Tone/effect/FeedbackDelay.ts +++ b/Tone/effect/FeedbackDelay.ts @@ -1,9 +1,9 @@ -import { Delay } from "../core/context/Delay"; -import { Param } from "../core/context/Param"; -import { NormalRange, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; -import { FeedbackEffect, FeedbackEffectOptions } from "./FeedbackEffect"; +import { Delay } from "../core/context/Delay.js"; +import { Param } from "../core/context/Param.js"; +import { NormalRange, Time } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; +import { FeedbackEffect, FeedbackEffectOptions } from "./FeedbackEffect.js"; interface FeedbackDelayOptions extends FeedbackEffectOptions { delayTime: Time; @@ -25,7 +25,6 @@ interface FeedbackDelayOptions extends FeedbackEffectOptions { * @category Effect */ export class FeedbackDelay extends FeedbackEffect { - readonly name: string = "FeedbackDelay"; /** @@ -41,9 +40,17 @@ export class FeedbackDelay extends FeedbackEffect { constructor(delayTime?: Time, feedback?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"])); - const options = optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]); + super( + optionsFromArguments(FeedbackDelay.getDefaults(), arguments, [ + "delayTime", + "feedback", + ]) + ); + const options = optionsFromArguments( + FeedbackDelay.getDefaults(), + arguments, + ["delayTime", "feedback"] + ); this._delayNode = new Delay({ context: this.context, diff --git a/Tone/effect/FeedbackEffect.ts b/Tone/effect/FeedbackEffect.ts index 1206c09e..4c10e96f 100644 --- a/Tone/effect/FeedbackEffect.ts +++ b/Tone/effect/FeedbackEffect.ts @@ -1,8 +1,8 @@ -import { Gain } from "../core/context/Gain"; -import { Param } from "../core/context/Param"; -import { NormalRange } from "../core/type/Units"; -import { readOnly } from "../core/util/Interface"; -import { Effect, EffectOptions } from "./Effect"; +import { Gain } from "../core/context/Gain.js"; +import { Param } from "../core/context/Param.js"; +import { NormalRange } from "../core/type/Units.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Effect, EffectOptions } from "./Effect.js"; export interface FeedbackEffectOptions extends EffectOptions { /** @@ -22,8 +22,9 @@ export interface FeedbackEffectOptions extends EffectOptions { * FeedbackEffect provides a loop between an audio source and its own output. * This is a base-class for feedback effects. */ -export abstract class FeedbackEffect extends Effect { - +export abstract class FeedbackEffect< + Options extends FeedbackEffectOptions, +> extends Effect { readonly name: string = "FeedbackEffect"; /** @@ -37,7 +38,6 @@ export abstract class FeedbackEffect exte feedback: Param<"normalRange">; constructor(options: FeedbackEffectOptions) { - super(options); this._feedbackGain = new Gain({ diff --git a/Tone/effect/Freeverb.test.ts b/Tone/effect/Freeverb.test.ts index 5450e799..c2e3661b 100644 --- a/Tone/effect/Freeverb.test.ts +++ b/Tone/effect/Freeverb.test.ts @@ -1,26 +1,28 @@ -import { Freeverb } from "./Freeverb"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { Freeverb } from "./Freeverb.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; import { expect } from "chai"; describe("Freeverb", () => { - BasicTests(Freeverb); EffectTests(Freeverb); it("matches a file basic", () => { - return CompareToFile(() => { - const reverb = new Freeverb(0.9).toDestination(); - reverb.dampening = 7000; - const osc = new Oscillator().connect(reverb); - osc.start(0).stop(0.01); - }, "freeverb.wav", 0.3); + return CompareToFile( + () => { + const reverb = new Freeverb(0.9).toDestination(); + reverb.dampening = 7000; + const osc = new Oscillator().connect(reverb); + osc.start(0).stop(0.01); + }, + "freeverb.wav", + 0.3 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const reverb = new Freeverb({ dampening: 2000, @@ -42,4 +44,3 @@ describe("Freeverb", () => { }); }); }); - diff --git a/Tone/effect/Freeverb.ts b/Tone/effect/Freeverb.ts index d2044acc..277e2c14 100644 --- a/Tone/effect/Freeverb.ts +++ b/Tone/effect/Freeverb.ts @@ -1,9 +1,9 @@ -import { StereoEffect, StereoEffectOptions } from "./StereoEffect"; -import { Frequency, NormalRange } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; -import { Signal } from "../signal/Signal"; -import { LowpassCombFilter } from "../component/filter/LowpassCombFilter"; +import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js"; +import { Frequency, NormalRange } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Signal } from "../signal/Signal.js"; +import { LowpassCombFilter } from "../component/filter/LowpassCombFilter.js"; export interface FreeverbOptions extends StereoEffectOptions { dampening: Frequency; @@ -13,7 +13,16 @@ export interface FreeverbOptions extends StereoEffectOptions { /** * An array of comb filter delay values from Freeverb implementation */ -const combFilterTunings = [1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100]; +const combFilterTunings = [ + 1557 / 44100, + 1617 / 44100, + 1491 / 44100, + 1422 / 44100, + 1277 / 44100, + 1356 / 44100, + 1188 / 44100, + 1116 / 44100, +]; /** * An array of allpass filter frequency values from Freeverb implementation @@ -33,7 +42,6 @@ const allpassFilterFrequencies = [225, 556, 441, 341]; * @category Effect */ export class Freeverb extends StereoEffect { - readonly name: string = "Freeverb"; /** @@ -63,9 +71,17 @@ export class Freeverb extends StereoEffect { constructor(roomSize?: NormalRange, dampening?: Frequency); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"])); - const options = optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]); + super( + optionsFromArguments(Freeverb.getDefaults(), arguments, [ + "roomSize", + "dampening", + ]) + ); + const options = optionsFromArguments( + Freeverb.getDefaults(), + arguments, + ["roomSize", "dampening"] + ); this.roomSize = new Signal({ context: this.context, @@ -74,7 +90,7 @@ export class Freeverb extends StereoEffect { }); // make the allpass filters on the right - this._allpassFiltersL = allpassFilterFrequencies.map(freq => { + this._allpassFiltersL = allpassFilterFrequencies.map((freq) => { const allpassL = this.context.createBiquadFilter(); allpassL.type = "allpass"; allpassL.frequency.value = freq; @@ -82,7 +98,7 @@ export class Freeverb extends StereoEffect { }); // make the allpass filters on the left - this._allpassFiltersR = allpassFilterFrequencies.map(freq => { + this._allpassFiltersR = allpassFilterFrequencies.map((freq) => { const allpassR = this.context.createBiquadFilter(); allpassR.type = "allpass"; allpassR.frequency.value = freq; @@ -111,7 +127,7 @@ export class Freeverb extends StereoEffect { static getDefaults(): FreeverbOptions { return Object.assign(StereoEffect.getDefaults(), { roomSize: 0.7, - dampening: 3000 + dampening: 3000, }); } @@ -123,14 +139,14 @@ export class Freeverb extends StereoEffect { return this._combFilters[0].dampening; } set dampening(d) { - this._combFilters.forEach(c => c.dampening = d); + this._combFilters.forEach((c) => (c.dampening = d)); } dispose(): this { super.dispose(); - this._allpassFiltersL.forEach(al => al.disconnect()); - this._allpassFiltersR.forEach(ar => ar.disconnect()); - this._combFilters.forEach(cf => cf.dispose()); + this._allpassFiltersL.forEach((al) => al.disconnect()); + this._allpassFiltersR.forEach((ar) => ar.disconnect()); + this._combFilters.forEach((cf) => cf.dispose()); this.roomSize.dispose(); return this; } diff --git a/Tone/effect/FrequencyShifter.test.ts b/Tone/effect/FrequencyShifter.test.ts index 40c61901..7bf75542 100644 --- a/Tone/effect/FrequencyShifter.test.ts +++ b/Tone/effect/FrequencyShifter.test.ts @@ -1,27 +1,29 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { EffectTests } from "test/helper/EffectTests"; -import { Offline } from "test/helper/Offline"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { FrequencyShifter } from "./FrequencyShifter"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { FrequencyShifter } from "./FrequencyShifter.js"; describe("FrequencyShifter", () => { - BasicTests(FrequencyShifter); EffectTests(FrequencyShifter); it("matches a file", () => { - return CompareToFile(() => { - const shifter = new FrequencyShifter().toDestination(); - shifter.frequency.value = -60; - const osc = new Oscillator().connect(shifter); - osc.start(0); - }, "frequencyShifter.wav", 0.1); + return CompareToFile( + () => { + const shifter = new FrequencyShifter().toDestination(); + shifter.frequency.value = -60; + const osc = new Oscillator().connect(shifter); + osc.start(0); + }, + "frequencyShifter.wav", + 0.1 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const shifter = new FrequencyShifter({ frequency: -20, diff --git a/Tone/effect/FrequencyShifter.ts b/Tone/effect/FrequencyShifter.ts index 66a910e2..4836c0ac 100644 --- a/Tone/effect/FrequencyShifter.ts +++ b/Tone/effect/FrequencyShifter.ts @@ -1,13 +1,13 @@ -import { PhaseShiftAllpass } from "../component/filter/PhaseShiftAllpass"; -import { Frequency } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Effect, EffectOptions } from "../effect/Effect"; -import { Add } from "../signal/Add"; -import { Multiply } from "../signal/Multiply"; -import { Negate } from "../signal/Negate"; -import { Signal } from "../signal/Signal"; -import { Oscillator } from "../source/oscillator/Oscillator"; -import { ToneOscillatorNode } from "../source/oscillator/ToneOscillatorNode"; +import { PhaseShiftAllpass } from "../component/filter/PhaseShiftAllpass.js"; +import { Frequency } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Effect, EffectOptions } from "../effect/Effect.js"; +import { Add } from "../signal/Add.js"; +import { Multiply } from "../signal/Multiply.js"; +import { Negate } from "../signal/Negate.js"; +import { Signal } from "../signal/Signal.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { ToneOscillatorNode } from "../source/oscillator/ToneOscillatorNode.js"; interface FrequencyShifterOptions extends EffectOptions { frequency: Frequency; @@ -32,7 +32,6 @@ interface FrequencyShifterOptions extends EffectOptions { * @category Effect */ export class FrequencyShifter extends Effect { - readonly name: string = "FrequencyShifter"; /** @@ -82,9 +81,16 @@ export class FrequencyShifter extends Effect { constructor(frequency?: Frequency); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"])); - const options = optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]); + super( + optionsFromArguments(FrequencyShifter.getDefaults(), arguments, [ + "frequency", + ]) + ); + const options = optionsFromArguments( + FrequencyShifter.getDefaults(), + arguments, + ["frequency"] + ); this.frequency = new Signal({ context: this.context, diff --git a/Tone/effect/JCReverb.test.ts b/Tone/effect/JCReverb.test.ts index c3799be0..48e21cd4 100644 --- a/Tone/effect/JCReverb.test.ts +++ b/Tone/effect/JCReverb.test.ts @@ -1,25 +1,27 @@ -import { JCReverb } from "./JCReverb"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { JCReverb } from "./JCReverb.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Noise } from "Tone/source/Noise"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Noise } from "../source/Noise.js"; describe("JCReverb", () => { - BasicTests(JCReverb); EffectTests(JCReverb); it("matches a file", () => { - return CompareToFile(() => { - const reverb = new JCReverb().toDestination(); - const noise = new Noise().connect(reverb); - noise.start(0).stop(0.1); - }, "jcReverb.wav", 0.2); + return CompareToFile( + () => { + const reverb = new JCReverb().toDestination(); + const noise = new Noise().connect(reverb); + noise.start(0).stop(0.1); + }, + "jcReverb.wav", + 0.2 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const reverb = new JCReverb({ roomSize: 0.2, @@ -38,4 +40,3 @@ describe("JCReverb", () => { }); }); }); - diff --git a/Tone/effect/JCReverb.ts b/Tone/effect/JCReverb.ts index 0aeb4ca1..cffb0273 100644 --- a/Tone/effect/JCReverb.ts +++ b/Tone/effect/JCReverb.ts @@ -1,10 +1,10 @@ -import { NormalRange } from "../core/type/Units"; -import { StereoEffect, StereoEffectOptions } from "./StereoEffect"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Scale } from "../signal/Scale"; -import { Signal } from "../signal/Signal"; -import { FeedbackCombFilter } from "../component/filter/FeedbackCombFilter"; -import { readOnly } from "../core/util/Interface"; +import { NormalRange } from "../core/type/Units.js"; +import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Scale } from "../signal/Scale.js"; +import { Signal } from "../signal/Signal.js"; +import { FeedbackCombFilter } from "../component/filter/FeedbackCombFilter.js"; +import { readOnly } from "../core/util/Interface.js"; export interface JCReverbOptions extends StereoEffectOptions { roomSize: NormalRange; @@ -13,7 +13,12 @@ export interface JCReverbOptions extends StereoEffectOptions { /** * an array of the comb filter delay time values */ -const combFilterDelayTimes = [1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000]; +const combFilterDelayTimes = [ + 1687 / 25000, + 1601 / 25000, + 2053 / 25000, + 2251 / 25000, +]; /** * the resonances of each of the comb filters @@ -36,17 +41,16 @@ const allpassFilterFreqs = [347, 113, 37]; * // connecting the synth to reverb through delay * const synth = new Tone.DuoSynth().chain(delay, reverb); * synth.triggerAttackRelease("A4", "8n"); - * + * * @category Effect */ export class JCReverb extends StereoEffect { - readonly name: string = "JCReverb"; /** - * Room size control values. + * Room size control values. */ - readonly roomSize: Signal<"normalRange"> + readonly roomSize: Signal<"normalRange">; /** * Scale the room size @@ -69,9 +73,16 @@ export class JCReverb extends StereoEffect { constructor(roomSize?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"])); - const options = optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]); + super( + optionsFromArguments(JCReverb.getDefaults(), arguments, [ + "roomSize", + ]) + ); + const options = optionsFromArguments( + JCReverb.getDefaults(), + arguments, + ["roomSize"] + ); this.roomSize = new Signal({ context: this.context, @@ -85,7 +96,7 @@ export class JCReverb extends StereoEffect { }); // make the allpass filters - this._allpassFilters = allpassFilterFreqs.map(freq => { + this._allpassFilters = allpassFilterFreqs.map((freq) => { const allpass = this.context.createBiquadFilter(); allpass.type = "allpass"; allpass.frequency.value = freq; @@ -93,20 +104,22 @@ export class JCReverb extends StereoEffect { }); // and the comb filters - this._feedbackCombFilters = combFilterDelayTimes.map((delayTime, index) => { - const fbcf = new FeedbackCombFilter({ - context: this.context, - delayTime, - }); - this._scaleRoomSize.connect(fbcf.resonance); - fbcf.resonance.value = combFilterResonances[index]; - if (index < combFilterDelayTimes.length / 2) { - this.connectEffectLeft(...this._allpassFilters, fbcf); - } else { - this.connectEffectRight(...this._allpassFilters, fbcf); + this._feedbackCombFilters = combFilterDelayTimes.map( + (delayTime, index) => { + const fbcf = new FeedbackCombFilter({ + context: this.context, + delayTime, + }); + this._scaleRoomSize.connect(fbcf.resonance); + fbcf.resonance.value = combFilterResonances[index]; + if (index < combFilterDelayTimes.length / 2) { + this.connectEffectLeft(...this._allpassFilters, fbcf); + } else { + this.connectEffectRight(...this._allpassFilters, fbcf); + } + return fbcf; } - return fbcf; - }); + ); // chain the allpass filters together this.roomSize.connect(this._scaleRoomSize); @@ -121,8 +134,8 @@ export class JCReverb extends StereoEffect { dispose(): this { super.dispose(); - this._allpassFilters.forEach(apf => apf.disconnect()); - this._feedbackCombFilters.forEach(fbcf => fbcf.dispose()); + this._allpassFilters.forEach((apf) => apf.disconnect()); + this._feedbackCombFilters.forEach((fbcf) => fbcf.dispose()); this.roomSize.dispose(); this._scaleRoomSize.dispose(); return this; diff --git a/Tone/effect/LFOEffect.ts b/Tone/effect/LFOEffect.ts index 7439f1aa..ced17bd7 100644 --- a/Tone/effect/LFOEffect.ts +++ b/Tone/effect/LFOEffect.ts @@ -1,10 +1,10 @@ -import { Effect, EffectOptions } from "../effect/Effect"; -import { Frequency, NormalRange, Time } from "../core/type/Units"; -import { LFO } from "../source/oscillator/LFO"; -import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; -import { Param } from "../core/context/Param"; +import { Effect, EffectOptions } from "../effect/Effect.js"; +import { Frequency, NormalRange, Time } from "../core/type/Units.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Param } from "../core/context/Param.js"; export interface LFOEffectOptions extends EffectOptions { frequency: Frequency; @@ -15,8 +15,9 @@ export interface LFOEffectOptions extends EffectOptions { /** * Base class for LFO-based effects. */ -export abstract class LFOEffect extends Effect { - +export abstract class LFOEffect< + Options extends LFOEffectOptions, +> extends Effect { readonly name: string = "LFOEffect"; /** @@ -25,18 +26,17 @@ export abstract class LFOEffect extends Effect protected _lfo: LFO; /** - * The range of the filter modulating between the min and max frequency. + * The range of the filter modulating between the min and max frequency. * 0 = no modulation. 1 = full modulation. */ readonly depth: Param<"normalRange">; /** - * How fast the filter modulates between min and max. + * How fast the filter modulates between min and max. */ readonly frequency: Signal<"frequency">; constructor(options: LFOEffectOptions) { - super(options); this._lfo = new LFO({ @@ -76,7 +76,7 @@ export abstract class LFOEffect extends Effect } /** - * Sync the filter to the transport. + * Sync the filter to the transport. * @see {@link LFO.sync} */ sync(): this { @@ -93,7 +93,7 @@ export abstract class LFOEffect extends Effect } /** - * The type of the LFO's oscillator. + * The type of the LFO's oscillator. * @see {@link Oscillator.type} * @example * const autoFilter = new Tone.AutoFilter().start().toDestination(); diff --git a/Tone/effect/MidSideEffect.ts b/Tone/effect/MidSideEffect.ts index 77693363..f31d1622 100644 --- a/Tone/effect/MidSideEffect.ts +++ b/Tone/effect/MidSideEffect.ts @@ -1,7 +1,7 @@ -import { Effect, EffectOptions } from "./Effect"; -import { MidSideSplit } from "../component/channel/MidSideSplit"; -import { MidSideMerge } from "../component/channel/MidSideMerge"; -import { OutputNode, ToneAudioNode } from "../core/context/ToneAudioNode"; +import { Effect, EffectOptions } from "./Effect.js"; +import { MidSideSplit } from "../component/channel/MidSideSplit.js"; +import { MidSideMerge } from "../component/channel/MidSideMerge.js"; +import { OutputNode, ToneAudioNode } from "../core/context/ToneAudioNode.js"; export type MidSideEffectOptions = EffectOptions; @@ -15,42 +15,42 @@ export type MidSideEffectOptions = EffectOptions; * This is a base-class for Mid/Side Effects. * @category Effect */ -export abstract class MidSideEffect extends Effect { - +export abstract class MidSideEffect< + Options extends MidSideEffectOptions, +> extends Effect { readonly name: string = "MidSideEffect"; /** * The mid/side split */ private _midSideSplit: MidSideSplit; - + /** * The mid/side merge */ private _midSideMerge: MidSideMerge; - + /** * The mid send. Connect to mid processing */ protected _midSend: ToneAudioNode; - + /** * The side send. Connect to side processing */ protected _sideSend: ToneAudioNode; - + /** * The mid return connection */ protected _midReturn: ToneAudioNode; - + /** * The side return connection */ protected _sideReturn: ToneAudioNode; constructor(options: MidSideEffectOptions) { - super(options); this._midSideMerge = new MidSideMerge({ context: this.context }); @@ -71,7 +71,7 @@ export abstract class MidSideEffect extend protected connectEffectMid(...nodes: OutputNode[]): void { this._midSend.chain(...nodes, this._midReturn); } - + /** * Connect the side chain of the effect */ @@ -90,4 +90,3 @@ export abstract class MidSideEffect extend return this; } } - diff --git a/Tone/effect/Phaser.test.ts b/Tone/effect/Phaser.test.ts index 1c024c90..109e0346 100644 --- a/Tone/effect/Phaser.test.ts +++ b/Tone/effect/Phaser.test.ts @@ -1,26 +1,28 @@ -import { Phaser } from "./Phaser"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { Phaser } from "./Phaser.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { ToneAudioBuffer } from "Tone/core"; -import { Player } from "Tone/source/buffer/Player"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { ToneAudioBuffer } from "../core/index.js"; +import { Player } from "../source/buffer/Player.js"; describe("Phaser", () => { - BasicTests(Phaser); EffectTests(Phaser); it("matches a file basic", async () => { - const buffer = await ToneAudioBuffer.fromUrl("./audio/FWDL.wav"); - return CompareToFile(() => { - const phaser = new Phaser(2, 6, 200).toDestination(); - const player = new Player(buffer).connect(phaser).start(); - }, "phaser.wav", 0.1); + const buffer = await ToneAudioBuffer.fromUrl("./test/audio/FWDL.wav"); + return CompareToFile( + () => { + const phaser = new Phaser(2, 6, 200).toDestination(); + const player = new Player(buffer).connect(phaser).start(); + }, + "phaser.wav", + 0.1 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const phaser = new Phaser({ frequency: 0.2, @@ -41,4 +43,3 @@ describe("Phaser", () => { }); }); }); - diff --git a/Tone/effect/Phaser.ts b/Tone/effect/Phaser.ts index af9abbf6..ad37e22a 100644 --- a/Tone/effect/Phaser.ts +++ b/Tone/effect/Phaser.ts @@ -1,9 +1,9 @@ -import { StereoEffect, StereoEffectOptions } from "./StereoEffect"; -import { Frequency, Hertz, Positive } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFO } from "../source/oscillator/LFO"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; +import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js"; +import { Frequency, Hertz, Positive } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; export interface PhaserOptions extends StereoEffectOptions { frequency: Frequency; @@ -29,7 +29,6 @@ export interface PhaserOptions extends StereoEffectOptions { * @category Effect */ export class Phaser extends StereoEffect { - readonly name: string = "Phaser"; /** @@ -77,18 +76,31 @@ export class Phaser extends StereoEffect { * @param octaves The octaves of the effect. * @param baseFrequency The base frequency of the filters. */ - constructor(frequency?: Frequency, octaves?: Positive, baseFrequency?: Frequency); + constructor( + frequency?: Frequency, + octaves?: Positive, + baseFrequency?: Frequency + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"])); - const options = optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]); + super( + optionsFromArguments(Phaser.getDefaults(), arguments, [ + "frequency", + "octaves", + "baseFrequency", + ]) + ); + const options = optionsFromArguments(Phaser.getDefaults(), arguments, [ + "frequency", + "octaves", + "baseFrequency", + ]); this._lfoL = new LFO({ context: this.context, frequency: options.frequency, min: 0, - max: 1 + max: 1, }); this._lfoR = new LFO({ context: this.context, @@ -134,7 +146,10 @@ export class Phaser extends StereoEffect { }); } - private _makeFilters(stages: number, connectToFreq: LFO): BiquadFilterNode[] { + private _makeFilters( + stages: number, + connectToFreq: LFO + ): BiquadFilterNode[] { const filters: BiquadFilterNode[] = []; // make all the filters for (let i = 0; i < stages; i++) { @@ -178,10 +193,9 @@ export class Phaser extends StereoEffect { this.Q.dispose(); this._lfoL.dispose(); this._lfoR.dispose(); - this._filtersL.forEach(f => f.disconnect()); - this._filtersR.forEach(f => f.disconnect()); + this._filtersL.forEach((f) => f.disconnect()); + this._filtersR.forEach((f) => f.disconnect()); this.frequency.dispose(); return this; } } - diff --git a/Tone/effect/PingPongDelay.test.ts b/Tone/effect/PingPongDelay.test.ts index 34219e4a..ed1c4c2e 100644 --- a/Tone/effect/PingPongDelay.test.ts +++ b/Tone/effect/PingPongDelay.test.ts @@ -1,25 +1,27 @@ -import { PingPongDelay } from "./PingPongDelay"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { PingPongDelay } from "./PingPongDelay.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; describe("PingPongDelay", () => { - BasicTests(PingPongDelay); EffectTests(PingPongDelay, 0.01); it("matches a file", () => { - return CompareToFile(() => { - const delay = new PingPongDelay(0.2, 0.8).toDestination(); - const pulse = new Oscillator().connect(delay); - pulse.start(0).stop(0.1); - }, "pingPongDelay.wav", 0.2); + return CompareToFile( + () => { + const delay = new PingPongDelay(0.2, 0.8).toDestination(); + const pulse = new Oscillator().connect(delay); + pulse.start(0).stop(0.1); + }, + "pingPongDelay.wav", + 0.2 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const pingPong = new PingPongDelay({ delayTime: 0.2, @@ -38,4 +40,3 @@ describe("PingPongDelay", () => { }); }); }); - diff --git a/Tone/effect/PingPongDelay.ts b/Tone/effect/PingPongDelay.ts index 917d1a79..69504ab6 100644 --- a/Tone/effect/PingPongDelay.ts +++ b/Tone/effect/PingPongDelay.ts @@ -1,9 +1,12 @@ -import { StereoXFeedbackEffect, StereoXFeedbackEffectOptions } from "./StereoXFeedbackEffect"; -import { NormalRange, Seconds, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Delay } from "../core/context/Delay"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; +import { + StereoXFeedbackEffect, + StereoXFeedbackEffectOptions, +} from "./StereoXFeedbackEffect.js"; +import { NormalRange, Seconds, Time } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Delay } from "../core/context/Delay.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; export interface PingPongDelayOptions extends StereoXFeedbackEffectOptions { delayTime: Time; @@ -25,7 +28,6 @@ export interface PingPongDelayOptions extends StereoXFeedbackEffectOptions { * @category Effect */ export class PingPongDelay extends StereoXFeedbackEffect { - readonly name: string = "PingPongDelay"; /** @@ -55,9 +57,17 @@ export class PingPongDelay extends StereoXFeedbackEffect { constructor(delayTime?: Time, feedback?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"])); - const options = optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]); + super( + optionsFromArguments(PingPongDelay.getDefaults(), arguments, [ + "delayTime", + "feedback", + ]) + ); + const options = optionsFromArguments( + PingPongDelay.getDefaults(), + arguments, + ["delayTime", "feedback"] + ); this._leftDelay = new Delay({ context: this.context, @@ -65,11 +75,11 @@ export class PingPongDelay extends StereoXFeedbackEffect { }); this._rightDelay = new Delay({ context: this.context, - maxDelay: options.maxDelay + maxDelay: options.maxDelay, }); this._rightPreDelay = new Delay({ context: this.context, - maxDelay: options.maxDelay + maxDelay: options.maxDelay, }); this.delayTime = new Signal({ context: this.context, @@ -80,7 +90,11 @@ export class PingPongDelay extends StereoXFeedbackEffect { // connect it up this.connectEffectLeft(this._leftDelay); this.connectEffectRight(this._rightPreDelay, this._rightDelay); - this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime); + this.delayTime.fan( + this._leftDelay.delayTime, + this._rightDelay.delayTime, + this._rightPreDelay.delayTime + ); // rearranged the feedback to be after the rightPreDelay this._feedbackL.disconnect(); this._feedbackL.connect(this._rightDelay); @@ -90,7 +104,7 @@ export class PingPongDelay extends StereoXFeedbackEffect { static getDefaults(): PingPongDelayOptions { return Object.assign(StereoXFeedbackEffect.getDefaults(), { delayTime: 0.25, - maxDelay: 1 + maxDelay: 1, }); } diff --git a/Tone/effect/PitchShift.test.ts b/Tone/effect/PitchShift.test.ts index 893922f0..73d6692a 100644 --- a/Tone/effect/PitchShift.test.ts +++ b/Tone/effect/PitchShift.test.ts @@ -1,29 +1,33 @@ -import { PitchShift } from "./PitchShift"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { PitchShift } from "./PitchShift.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; describe("PitchShift", () => { - BasicTests(PitchShift); EffectTests(PitchShift); it("matches a file", () => { - return CompareToFile(() => { - const pitchShift = new PitchShift(4).toDestination(); - const osc = new Oscillator().toDestination().connect(pitchShift); - osc.start(0); - }, "pitchShift.wav", 0.3); + return CompareToFile( + () => { + const pitchShift = new PitchShift(4).toDestination(); + const osc = new Oscillator() + .toDestination() + .connect(pitchShift); + osc.start(0); + }, + "pitchShift.wav", + 0.3 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const pitchShift = new PitchShift({ windowSize: 0.2, - pitch: 2 + pitch: 2, }); expect(pitchShift.windowSize).to.be.closeTo(0.2, 0.01); expect(pitchShift.pitch).to.be.closeTo(2, 0.01); @@ -53,9 +57,12 @@ describe("PitchShift", () => { it("can set set the feedback and delay times", () => { const pitchShift = new PitchShift({ delayTime: "4n", - feedback: 0.3 + feedback: 0.3, }); - expect(pitchShift.delayTime.value).to.be.closeTo(pitchShift.toSeconds("4n"), 0.01); + expect(pitchShift.delayTime.value).to.be.closeTo( + pitchShift.toSeconds("4n"), + 0.01 + ); expect(pitchShift.feedback.value).to.be.closeTo(0.3, 0.01); pitchShift.delayTime.value = 0.2; expect(pitchShift.delayTime.value).to.be.closeTo(0.2, 0.01); @@ -63,4 +70,3 @@ describe("PitchShift", () => { }); }); }); - diff --git a/Tone/effect/PitchShift.ts b/Tone/effect/PitchShift.ts index 6ae73960..a62e01b3 100644 --- a/Tone/effect/PitchShift.ts +++ b/Tone/effect/PitchShift.ts @@ -1,13 +1,13 @@ -import { Interval, Seconds, Time } from "../core/type/Units"; -import { FeedbackEffect, FeedbackEffectOptions } from "./FeedbackEffect"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFO } from "../source/oscillator/LFO"; -import { Delay } from "../core/context/Delay"; -import { CrossFade } from "../component/channel/CrossFade"; -import { Signal } from "../signal/Signal"; -import { readOnly } from "../core/util/Interface"; -import { Param } from "../core/context/Param"; -import { intervalToFrequencyRatio } from "../core/type/Conversions"; +import { Interval, Seconds, Time } from "../core/type/Units.js"; +import { FeedbackEffect, FeedbackEffectOptions } from "./FeedbackEffect.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Delay } from "../core/context/Delay.js"; +import { CrossFade } from "../component/channel/CrossFade.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Param } from "../core/context/Param.js"; +import { intervalToFrequencyRatio } from "../core/type/Conversions.js"; export interface PitchShiftOptions extends FeedbackEffectOptions { pitch: Interval; @@ -24,7 +24,6 @@ export interface PitchShiftOptions extends FeedbackEffectOptions { * @category Effect */ export class PitchShift extends FeedbackEffect { - readonly name: string = "PitchShift"; /** @@ -89,31 +88,36 @@ export class PitchShift extends FeedbackEffect { constructor(pitch?: Interval); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"])); - const options = optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]); + super( + optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]) + ); + const options = optionsFromArguments( + PitchShift.getDefaults(), + arguments, + ["pitch"] + ); this._frequency = new Signal({ context: this.context }); this._delayA = new Delay({ maxDelay: 1, - context: this.context + context: this.context, }); this._lfoA = new LFO({ context: this.context, min: 0, max: 0.1, - type: "sawtooth" + type: "sawtooth", }).connect(this._delayA.delayTime); this._delayB = new Delay({ maxDelay: 1, - context: this.context + context: this.context, }); this._lfoB = new LFO({ context: this.context, min: 0, max: 0.1, type: "sawtooth", - phase: 180 + phase: 180, }).connect(this._delayB.delayTime); this._crossFade = new CrossFade({ context: this.context }); this._crossFadeLFO = new LFO({ @@ -121,7 +125,7 @@ export class PitchShift extends FeedbackEffect { min: 0, max: 1, type: "triangle", - phase: 90 + phase: 90, }).connect(this._crossFade.fade); this._feedbackDelay = new Delay({ delayTime: options.delayTime, @@ -137,7 +141,11 @@ export class PitchShift extends FeedbackEffect { this._delayA.connect(this._crossFade.a); this._delayB.connect(this._crossFade.b); // connect the frequency - this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency); + this._frequency.fan( + this._lfoA.frequency, + this._lfoB.frequency, + this._crossFadeLFO.frequency + ); // route the input this.effectSend.fan(this._delayA, this._delayB); this._crossFade.chain(this._feedbackDelay, this.effectReturn); @@ -155,7 +163,7 @@ export class PitchShift extends FeedbackEffect { pitch: 0, windowSize: 0.1, delayTime: 0, - feedback: 0 + feedback: 0, }); } diff --git a/Tone/effect/Reverb.test.ts b/Tone/effect/Reverb.test.ts index aa45b232..556c24c4 100644 --- a/Tone/effect/Reverb.test.ts +++ b/Tone/effect/Reverb.test.ts @@ -1,15 +1,13 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; -import { Reverb } from "./Reverb"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { Reverb } from "./Reverb.js"; describe("Reverb", () => { - BasicTests(Reverb); context("API", () => { - it("can pass in options in the constructor", () => { const reverb = new Reverb({ decay: 2, diff --git a/Tone/effect/Reverb.ts b/Tone/effect/Reverb.ts index e135f5d8..4a49fc9a 100644 --- a/Tone/effect/Reverb.ts +++ b/Tone/effect/Reverb.ts @@ -1,12 +1,12 @@ -import { Merge } from "../component/channel/Merge"; -import { Gain } from "../core/context/Gain"; -import { Seconds, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Noise } from "../source/Noise"; -import { Effect, EffectOptions } from "./Effect"; -import { OfflineContext } from "../core/context/OfflineContext"; -import { noOp } from "../core/util/Interface"; -import { assertRange } from "../core/util/Debug"; +import { Merge } from "../component/channel/Merge.js"; +import { Gain } from "../core/context/Gain.js"; +import { Seconds, Time } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Noise } from "../source/Noise.js"; +import { Effect, EffectOptions } from "./Effect.js"; +import { OfflineContext } from "../core/context/OfflineContext.js"; +import { noOp } from "../core/util/Interface.js"; +import { assertRange } from "../core/util/Debug.js"; interface ReverbOptions extends EffectOptions { decay: Seconds; @@ -18,15 +18,14 @@ interface ReverbOptions extends EffectOptions { * Generates an Impulse Response Buffer * with Tone.Offline then feeds the IR into ConvolverNode. * The impulse response generation is async, so you have - * to wait until {@link ready} resolves before it will make a sound. + * to wait until {@link ready} resolves before it will make a sound. * * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen). * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License. - * + * * @category Effect */ export class Reverb extends Effect { - readonly name: string = "Reverb"; /** @@ -38,7 +37,7 @@ export class Reverb extends Effect { * The duration of the reverb. */ private _decay: Seconds; - + /** * The amount of time before the reverb is fully ramped in. */ @@ -47,7 +46,7 @@ export class Reverb extends Effect { /** * Resolves when the reverb buffer is generated. Whenever either {@link decay} * or {@link preDelay} are set, you have to wait until {@link ready} resolves - * before the IR is generated with the latest values. + * before the IR is generated with the latest values. */ ready: Promise = Promise.resolve(); @@ -57,9 +56,10 @@ export class Reverb extends Effect { constructor(decay?: Seconds); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"])); - const options = optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]); + const options = optionsFromArguments(Reverb.getDefaults(), arguments, [ + "decay", + ]); this._decay = options.decay; this._preDelay = options.preDelay; @@ -109,7 +109,11 @@ export class Reverb extends Effect { const previousReady = this.ready; // create a noise burst which decays over the duration in each channel - const context = new OfflineContext(2, this._decay + this._preDelay, this.context.sampleRate); + const context = new OfflineContext( + 2, + this._decay + this._preDelay, + this.context.sampleRate + ); const noiseL = new Noise({ context }); const noiseR = new Noise({ context }); const merge = new Merge({ context }); @@ -123,12 +127,16 @@ export class Reverb extends Effect { gainNode.gain.setValueAtTime(0, 0); gainNode.gain.setValueAtTime(1, this._preDelay); // decay - gainNode.gain.exponentialApproachValueAtTime(0, this._preDelay, this.decay); - + gainNode.gain.exponentialApproachValueAtTime( + 0, + this._preDelay, + this.decay + ); + // render the buffer const renderPromise = context.render(); this.ready = renderPromise.then(noOp); - + // wait for the previous `ready` to resolve await previousReady; // set the buffer diff --git a/Tone/effect/StereoEffect.ts b/Tone/effect/StereoEffect.ts index 91492246..750cfb8b 100644 --- a/Tone/effect/StereoEffect.ts +++ b/Tone/effect/StereoEffect.ts @@ -1,19 +1,25 @@ -import { EffectOptions } from "./Effect"; -import { connect, connectSeries, OutputNode, ToneAudioNode } from "../core/context/ToneAudioNode"; -import { CrossFade } from "../component/channel/CrossFade"; -import { Signal } from "../signal/Signal"; -import { Split } from "../component/channel/Split"; -import { Gain } from "../core/context/Gain"; -import { Merge } from "../component/channel/Merge"; -import { readOnly } from "../core/util/Interface"; +import { EffectOptions } from "./Effect.js"; +import { + connect, + connectSeries, + OutputNode, + ToneAudioNode, +} from "../core/context/ToneAudioNode.js"; +import { CrossFade } from "../component/channel/CrossFade.js"; +import { Signal } from "../signal/Signal.js"; +import { Split } from "../component/channel/Split.js"; +import { Gain } from "../core/context/Gain.js"; +import { Merge } from "../component/channel/Merge.js"; +import { readOnly } from "../core/util/Interface.js"; export type StereoEffectOptions = EffectOptions; /** * Base class for Stereo effects. */ -export class StereoEffect extends ToneAudioNode { - +export class StereoEffect< + Options extends StereoEffectOptions, +> extends ToneAudioNode { readonly name: string = "StereoEffect"; readonly input: Gain; @@ -23,25 +29,24 @@ export class StereoEffect extends ToneAudio * the drywet knob to control the amount of effect */ private _dryWet: CrossFade; - + /** * The wet control, i.e. how much of the effected * will pass through to the output. */ readonly wet: Signal<"normalRange">; - + /** * Split it */ protected _split: Split; - + /** * the stereo effect merger */ protected _merge: Merge; constructor(options: StereoEffectOptions) { - super(options); this.input = new Gain({ context: this.context }); @@ -51,7 +56,7 @@ export class StereoEffect extends ToneAudio this._dryWet = this.output = new CrossFade({ context: this.context, - fade: options.wet + fade: options.wet, }); this.wet = this._dryWet.fade; this._split = new Split({ context: this.context, channels: 2 }); @@ -64,23 +69,23 @@ export class StereoEffect extends ToneAudio this._merge.connect(this._dryWet.b); readOnly(this, ["wet"]); } - + /** * Connect the left part of the effect */ protected connectEffectLeft(...nodes: OutputNode[]): void { this._split.connect(nodes[0], 0, 0); connectSeries(...nodes); - connect(nodes[nodes.length-1], this._merge, 0, 0); + connect(nodes[nodes.length - 1], this._merge, 0, 0); } - + /** * Connect the right part of the effect */ protected connectEffectRight(...nodes: OutputNode[]): void { this._split.connect(nodes[0], 1, 0); connectSeries(...nodes); - connect(nodes[nodes.length-1], this._merge, 0, 1); + connect(nodes[nodes.length - 1], this._merge, 0, 1); } static getDefaults(): StereoEffectOptions { diff --git a/Tone/effect/StereoFeedbackEffect.ts b/Tone/effect/StereoFeedbackEffect.ts index 2d77b70a..a9d3dfdc 100644 --- a/Tone/effect/StereoFeedbackEffect.ts +++ b/Tone/effect/StereoFeedbackEffect.ts @@ -1,10 +1,10 @@ -import { StereoEffect, StereoEffectOptions } from "./StereoEffect"; -import { NormalRange } from "../core/type/Units"; -import { Signal } from "../signal/Signal"; -import { Gain } from "../core/context/Gain"; -import { readOnly } from "../core/util/Interface"; -import { Split } from "../component/channel/Split"; -import { Merge } from "../component/channel/Merge"; +import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js"; +import { NormalRange } from "../core/type/Units.js"; +import { Signal } from "../signal/Signal.js"; +import { Gain } from "../core/context/Gain.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Split } from "../component/channel/Split.js"; +import { Merge } from "../component/channel/Merge.js"; export interface StereoFeedbackEffectOptions extends StereoEffectOptions { feedback: NormalRange; @@ -13,8 +13,9 @@ export interface StereoFeedbackEffectOptions extends StereoEffectOptions { /** * Base class for stereo feedback effects where the effectReturn is fed back into the same channel. */ -export class StereoFeedbackEffect extends StereoEffect { - +export class StereoFeedbackEffect< + Options extends StereoFeedbackEffectOptions, +> extends StereoEffect { /** * The amount of feedback from the output * back into the input of the effect (routed @@ -43,13 +44,12 @@ export class StereoFeedbackEffect e protected _feedbackMerge: Merge; constructor(options: StereoFeedbackEffectOptions) { - super(options); this.feedback = new Signal({ context: this.context, - value: options.feedback, - units: "normalRange" + value: options.feedback, + units: "normalRange", }); this._feedbackL = new Gain({ context: this.context }); this._feedbackR = new Gain({ context: this.context }); @@ -59,7 +59,7 @@ export class StereoFeedbackEffect e this._merge.connect(this._feedbackSplit); this._feedbackMerge.connect(this._split); - + // the left output connected to the left input this._feedbackSplit.connect(this._feedbackL, 0, 0); this._feedbackL.connect(this._feedbackMerge, 0, 0); @@ -67,7 +67,7 @@ export class StereoFeedbackEffect e // the right output connected to the right input this._feedbackSplit.connect(this._feedbackR, 1, 0); this._feedbackR.connect(this._feedbackMerge, 0, 1); - + // the feedback control this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain); readOnly(this, ["feedback"]); diff --git a/Tone/effect/StereoWidener.test.ts b/Tone/effect/StereoWidener.test.ts index 21ea6653..aa1da11c 100644 --- a/Tone/effect/StereoWidener.test.ts +++ b/Tone/effect/StereoWidener.test.ts @@ -1,27 +1,28 @@ -import { StereoWidener } from "./StereoWidener"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { StereoWidener } from "./StereoWidener.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { Player } from "Tone/source/buffer/Player"; -import "test/helper/ToneAudioBuffer"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js"; +import { Player } from "../source/buffer/Player.js"; describe("StereoWidener", () => { - BasicTests(StereoWidener); EffectTests(StereoWidener, 0); it("matches a file basic", async () => { - const buffer = await ToneAudioBuffer.fromUrl("./audio/FWDL.wav"); - return CompareToFile(() => { - const phaser = new StereoWidener(0.1).toDestination(); - const player = new Player(buffer).connect(phaser).start(); - }, "stereoWidener.wav", 0.3); + const buffer = await ToneAudioBuffer.fromUrl("./test/audio/FWDL.wav"); + return CompareToFile( + () => { + const phaser = new StereoWidener(0.1).toDestination(); + const player = new Player(buffer).connect(phaser).start(); + }, + "stereoWidener.wav", + 0.3 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const widener = new StereoWidener(0.2); expect(widener.width.value).to.be.closeTo(0.2, 0.001); @@ -38,4 +39,3 @@ describe("StereoWidener", () => { }); }); }); - diff --git a/Tone/effect/StereoWidener.ts b/Tone/effect/StereoWidener.ts index c3f55afd..af4b3f6a 100644 --- a/Tone/effect/StereoWidener.ts +++ b/Tone/effect/StereoWidener.ts @@ -1,11 +1,14 @@ -import { MidSideEffect, MidSideEffectOptions } from "../effect/MidSideEffect"; -import { Signal } from "../signal/Signal"; -import { Multiply } from "../signal/Multiply"; -import { Subtract } from "../signal/Subtract"; -import { NormalRange } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; -import { connect } from "../core/context/ToneAudioNode"; +import { + MidSideEffect, + MidSideEffectOptions, +} from "../effect/MidSideEffect.js"; +import { Signal } from "../signal/Signal.js"; +import { Multiply } from "../signal/Multiply.js"; +import { Subtract } from "../signal/Subtract.js"; +import { NormalRange } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; +import { connect } from "../core/context/ToneAudioNode.js"; export interface StereoWidenerOptions extends MidSideEffectOptions { width: NormalRange; @@ -22,34 +25,33 @@ export interface StereoWidenerOptions extends MidSideEffectOptions { * @category Effect */ export class StereoWidener extends MidSideEffect { - readonly name: string = "StereoWidener"; /** * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change. */ readonly width: Signal<"normalRange">; - + /** * Two times the (1-width) for the mid channel */ private _twoTimesWidthMid: Multiply; - + /** * Two times the width for the side channel */ private _twoTimesWidthSide: Multiply; - + /** * Mid multiplier */ private _midMult: Multiply; - + /** * 1 - width */ private _oneMinusWidth: Subtract; - + /** * Side multiplier */ @@ -61,9 +63,16 @@ export class StereoWidener extends MidSideEffect { constructor(width?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"])); - const options = optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]); + super( + optionsFromArguments(StereoWidener.getDefaults(), arguments, [ + "width", + ]) + ); + const options = optionsFromArguments( + StereoWidener.getDefaults(), + arguments, + ["width"] + ); this.width = new Signal({ context: this.context, value: options.width, diff --git a/Tone/effect/StereoXFeedbackEffect.ts b/Tone/effect/StereoXFeedbackEffect.ts index 0e463a1b..113645c0 100644 --- a/Tone/effect/StereoXFeedbackEffect.ts +++ b/Tone/effect/StereoXFeedbackEffect.ts @@ -1,8 +1,12 @@ -import { StereoFeedbackEffect, StereoFeedbackEffectOptions } from "./StereoFeedbackEffect"; -import { NormalRange } from "../core/type/Units"; -import { readOnly } from "../core/util/Interface"; +import { + StereoFeedbackEffect, + StereoFeedbackEffectOptions, +} from "./StereoFeedbackEffect.js"; +import { NormalRange } from "../core/type/Units.js"; +import { readOnly } from "../core/util/Interface.js"; -export interface StereoXFeedbackEffectOptions extends StereoFeedbackEffectOptions { +export interface StereoXFeedbackEffectOptions + extends StereoFeedbackEffectOptions { feedback: NormalRange; } @@ -19,10 +23,10 @@ export interface StereoXFeedbackEffectOptions extends StereoFeedbackEffectOption * +--------------------------------+ feedbackR <-------------------------------------+ * ``` */ -export class StereoXFeedbackEffect extends StereoFeedbackEffect { - +export class StereoXFeedbackEffect< + Options extends StereoXFeedbackEffectOptions, +> extends StereoFeedbackEffect { constructor(options: StereoXFeedbackEffectOptions) { - super(options); // the left output connected to the right input this._feedbackL.disconnect(); @@ -31,7 +35,7 @@ export class StereoXFeedbackEffect // the left output connected to the right input this._feedbackR.disconnect(); this._feedbackR.connect(this._feedbackMerge, 0, 0); - + readOnly(this, ["feedback"]); } } diff --git a/Tone/effect/Tremolo.test.ts b/Tone/effect/Tremolo.test.ts index ab434324..838cd152 100644 --- a/Tone/effect/Tremolo.test.ts +++ b/Tone/effect/Tremolo.test.ts @@ -1,24 +1,27 @@ -import { Tremolo } from "./Tremolo"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; -import { Offline } from "test/helper/Offline"; +import { Tremolo } from "./Tremolo.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; +import { Offline } from "../../test/helper/Offline.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/index.js"; describe("Tremolo", () => { BasicTests(Tremolo); EffectTests(Tremolo); it("matches a file", () => { - return CompareToFile(() => { - const tremolo = new Tremolo().toDestination().start(0.2); - const osc = new Oscillator().connect(tremolo).start(); - }, "tremolo.wav", 0.05); + return CompareToFile( + () => { + const tremolo = new Tremolo().toDestination().start(0.2); + const osc = new Oscillator().connect(tremolo).start(); + }, + "tremolo.wav", + 0.05 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const tremolo = new Tremolo({ depth: 0.2, @@ -41,7 +44,7 @@ describe("Tremolo", () => { const tremolo = new Tremolo(); tremolo.set({ frequency: 2.4, - type: "triangle" + type: "triangle", }); expect(tremolo.get().frequency).to.be.closeTo(2.4, 0.01); expect(tremolo.get().type).to.equal("triangle"); @@ -58,7 +61,6 @@ describe("Tremolo", () => { }); it("can sync the frequency to the transport", () => { - return Offline(({ transport }) => { const tremolo = new Tremolo(2); tremolo.sync(); @@ -71,7 +73,6 @@ describe("Tremolo", () => { }); it("can unsync the frequency to the transport", () => { - return Offline(({ transport }) => { const tremolo = new Tremolo(2); tremolo.sync(); @@ -85,4 +86,3 @@ describe("Tremolo", () => { }); }); }); - diff --git a/Tone/effect/Tremolo.ts b/Tone/effect/Tremolo.ts index fec39dcc..38cd15eb 100644 --- a/Tone/effect/Tremolo.ts +++ b/Tone/effect/Tremolo.ts @@ -1,11 +1,11 @@ -import { StereoEffect, StereoEffectOptions } from "./StereoEffect"; -import { LFO } from "../source/oscillator/LFO"; -import { Gain } from "../core/context/Gain"; -import { Signal } from "../signal/Signal"; -import { Degrees, Frequency, NormalRange, Time } from "../core/type/Units"; -import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; +import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Gain } from "../core/context/Gain.js"; +import { Signal } from "../signal/Signal.js"; +import { Degrees, Frequency, NormalRange, Time } from "../core/type/Units.js"; +import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; export interface TremoloOptions extends StereoEffectOptions { frequency: Frequency; @@ -23,11 +23,10 @@ export interface TremoloOptions extends StereoEffectOptions { * const tremolo = new Tone.Tremolo(9, 0.75).toDestination().start(); * // route an oscillator through the tremolo and start it * const oscillator = new Tone.Oscillator().connect(tremolo).start(); - * + * * @category Effect */ export class Tremolo extends StereoEffect { - readonly name: string = "Tremolo"; /** @@ -69,9 +68,16 @@ export class Tremolo extends StereoEffect { constructor(frequency?: Frequency, depth?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"])); - const options = optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]); + super( + optionsFromArguments(Tremolo.getDefaults(), arguments, [ + "frequency", + "depth", + ]) + ); + const options = optionsFromArguments(Tremolo.getDefaults(), arguments, [ + "frequency", + "depth", + ]); this._lfoL = new LFO({ context: this.context, @@ -174,8 +180,8 @@ export class Tremolo extends StereoEffect { return this._lfoR.phase - this._lfoL.phase; // 180 } set spread(spread) { - this._lfoL.phase = 90 - (spread / 2); - this._lfoR.phase = (spread / 2) + 90; + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; } dispose(): this { diff --git a/Tone/effect/Vibrato.test.ts b/Tone/effect/Vibrato.test.ts index 7fb056d2..86758a4f 100644 --- a/Tone/effect/Vibrato.test.ts +++ b/Tone/effect/Vibrato.test.ts @@ -1,39 +1,42 @@ -import { Vibrato } from "./Vibrato"; -import { BasicTests } from "test/helper/Basic"; -import { EffectTests } from "test/helper/EffectTests"; +import { Vibrato } from "./Vibrato.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { EffectTests } from "../../test/helper/EffectTests.js"; import { expect } from "chai"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Oscillator } from "Tone/source/oscillator/Oscillator"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; describe("Vibrato", () => { BasicTests(Vibrato); EffectTests(Vibrato); it("matches a file", () => { - return CompareToFile(() => { - const vibrato = new Vibrato(4, 1).toDestination(); - const osc = new Oscillator().connect(vibrato).start(); - }, "vibrato.wav", 0.02); + return CompareToFile( + () => { + const vibrato = new Vibrato(4, 1).toDestination(); + const osc = new Oscillator().connect(vibrato).start(); + }, + "vibrato.wav", + 0.02 + ); }); context("API", () => { - it("can pass in options in the constructor", () => { const vibrato = new Vibrato({ maxDelay: 0.02, depth: 0.25, - type: "sawtooth" + type: "sawtooth", }); expect(vibrato.depth.value).to.be.closeTo(0.25, 0.001); expect(vibrato.type).to.equal("sawtooth"); vibrato.dispose(); }); - + it("can get/set the options", () => { const vibrato = new Vibrato(); vibrato.set({ frequency: 2.4, - type: "triangle" + type: "triangle", }); expect(vibrato.get().frequency).to.be.closeTo(2.4, 0.01); expect(vibrato.get().type).to.equal("triangle"); diff --git a/Tone/effect/Vibrato.ts b/Tone/effect/Vibrato.ts index 2cb35bfc..34d354c9 100644 --- a/Tone/effect/Vibrato.ts +++ b/Tone/effect/Vibrato.ts @@ -1,12 +1,12 @@ -import { Effect, EffectOptions } from "./Effect"; -import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface"; -import { Frequency, NormalRange, Seconds } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { LFO } from "../source/oscillator/LFO"; -import { Delay } from "../core/context/Delay"; -import { Signal } from "../signal/Signal"; -import { Param } from "../core/context/Param"; -import { readOnly } from "../core/util/Interface"; +import { Effect, EffectOptions } from "./Effect.js"; +import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface.js"; +import { Frequency, NormalRange, Seconds } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Delay } from "../core/context/Delay.js"; +import { Signal } from "../signal/Signal.js"; +import { Param } from "../core/context/Param.js"; +import { readOnly } from "../core/util/Interface.js"; export interface VibratoOptions extends EffectOptions { maxDelay: Seconds; @@ -16,29 +16,28 @@ export interface VibratoOptions extends EffectOptions { } /** * A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO - * modulates the delayTime of the delay, causing the pitch to rise and fall. + * modulates the delayTime of the delay, causing the pitch to rise and fall. * @category Effect */ export class Vibrato extends Effect { - readonly name: string = "Vibrato"; /** * The delay node used for the vibrato effect */ private _delayNode: Delay; - + /** * The LFO used to control the vibrato */ private _lfo: LFO; - + /** * The frequency of the vibrato */ readonly frequency: Signal<"frequency">; - + /** - * The depth of the vibrato. + * The depth of the vibrato. */ readonly depth: Param<"normalRange">; @@ -49,9 +48,16 @@ export class Vibrato extends Effect { constructor(frequency?: Frequency, depth?: NormalRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"])); - const options = optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]); + super( + optionsFromArguments(Vibrato.getDefaults(), arguments, [ + "frequency", + "depth", + ]) + ); + const options = optionsFromArguments(Vibrato.getDefaults(), arguments, [ + "frequency", + "depth", + ]); this._delayNode = new Delay({ context: this.context, @@ -62,10 +68,12 @@ export class Vibrato extends Effect { context: this.context, type: options.type, min: 0, - max: options.maxDelay, + max: options.maxDelay, frequency: options.frequency, - phase: -90 // offse the phase so the resting position is in the center - }).start().connect(this._delayNode.delayTime); + phase: -90, // offse the phase so the resting position is in the center + }) + .start() + .connect(this._delayNode.delayTime); this.frequency = this._lfo.frequency; this.depth = this._lfo.amplitude; @@ -79,7 +87,7 @@ export class Vibrato extends Effect { maxDelay: 0.005, frequency: 5, depth: 0.1, - type: "sine" as const + type: "sine" as const, }); } @@ -92,7 +100,7 @@ export class Vibrato extends Effect { set type(type) { this._lfo.type = type; } - + dispose(): this { super.dispose(); this._delayNode.dispose(); diff --git a/Tone/effect/index.ts b/Tone/effect/index.ts index 5c6772ea..f575897d 100644 --- a/Tone/effect/index.ts +++ b/Tone/effect/index.ts @@ -1,18 +1,18 @@ -export * from "./AutoFilter"; -export * from "./AutoPanner"; -export * from "./AutoWah"; -export * from "./BitCrusher"; -export * from "./Chebyshev"; -export * from "./Chorus"; -export * from "./Distortion"; -export * from "./FeedbackDelay"; -export * from "./FrequencyShifter"; -export * from "./Freeverb"; -export * from "./JCReverb"; -export * from "./PingPongDelay"; -export * from "./PitchShift"; -export * from "./Phaser"; -export * from "./Reverb"; -export * from "./StereoWidener"; -export * from "./Tremolo"; -export * from "./Vibrato"; +export * from "./AutoFilter.js"; +export * from "./AutoPanner.js"; +export * from "./AutoWah.js"; +export * from "./BitCrusher.js"; +export * from "./Chebyshev.js"; +export * from "./Chorus.js"; +export * from "./Distortion.js"; +export * from "./FeedbackDelay.js"; +export * from "./FrequencyShifter.js"; +export * from "./Freeverb.js"; +export * from "./JCReverb.js"; +export * from "./PingPongDelay.js"; +export * from "./PitchShift.js"; +export * from "./Phaser.js"; +export * from "./Reverb.js"; +export * from "./StereoWidener.js"; +export * from "./Tremolo.js"; +export * from "./Vibrato.js"; diff --git a/Tone/event/Loop.test.ts b/Tone/event/Loop.test.ts index 525d5687..0dc722c1 100644 --- a/Tone/event/Loop.test.ts +++ b/Tone/event/Loop.test.ts @@ -1,16 +1,14 @@ -import { BasicTests } from "test/helper/Basic"; -import { Loop } from "Tone/event/Loop"; -import { Offline, whenBetween } from "test/helper/Offline"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Loop } from "./Loop.js"; +import { Offline, whenBetween } from "../../test/helper/Offline.js"; import { expect } from "chai"; -import { noOp } from "Tone/core/util/Interface"; -import { Time } from "Tone/core/type/Time"; +import { noOp } from "../core/util/Interface.js"; +import { Time } from "../core/type/Time.js"; describe("Loop", () => { - BasicTests(Loop); context("Constructor", () => { - it("takes a callback and an interval", () => { return Offline(() => { const callback = noOp; @@ -36,7 +34,7 @@ describe("Loop", () => { callback: callback, iterations: 4, probability: 0.3, - interval: "8t" + interval: "8t", }); expect(loop.callback).to.equal(callback); expect(loop.interval.valueOf()).to.equal(Time("8t").valueOf()); @@ -48,14 +46,13 @@ describe("Loop", () => { }); context("Get/Set", () => { - it("can set values with object", () => { return Offline(() => { const callback = noOp; const loop = new Loop(); loop.set({ callback: callback, - iterations: 8 + iterations: 8, }); expect(loop.callback).to.equal(callback); expect(loop.iterations).to.equal(8); @@ -80,7 +77,7 @@ describe("Loop", () => { const loop = new Loop({ callback: callback, iterations: 4, - probability: 0.3 + probability: 0.3, }); const values = loop.get(); expect(values.iterations).to.equal(4); @@ -91,7 +88,6 @@ describe("Loop", () => { }); context("Callback", () => { - it("does not invoke get invoked until started", () => { return Offline(({ transport }) => { new Loop(() => { @@ -155,7 +151,6 @@ describe("Loop", () => { }); context("Scheduling", () => { - it("can be started and stopped multiple times", () => { return Offline(({ transport }) => { const loop = new Loop().start().stop(0.2).start(0.4); @@ -220,11 +215,9 @@ describe("Loop", () => { }; }, 0.5); }); - }); context("Looping", () => { - it("loops", () => { let callCount = 0; return Offline(({ transport }) => { @@ -232,7 +225,7 @@ describe("Loop", () => { interval: 0.1, callback: () => { callCount++; - } + }, }).start(0); transport.start(); }, 0.81).then(() => { @@ -252,7 +245,7 @@ describe("Loop", () => { expect(time - lastCall).to.be.closeTo(0.25, 0.01); } lastCall = time; - } + }, }).start(0); transport.start(); }, 1).then(() => { @@ -268,7 +261,7 @@ describe("Loop", () => { iterations: 2, callback: () => { callCount++; - } + }, }).start(0); transport.start(); }, 0.4).then(() => { @@ -290,7 +283,6 @@ describe("Loop", () => { }); context("playbackRate", () => { - it("can adjust the playbackRate", () => { let invoked = false; return Offline(({ transport }) => { @@ -304,14 +296,13 @@ describe("Loop", () => { expect(time - lastCall).to.be.closeTo(0.25, 0.01); } lastCall = time; - } + }, }).start(0); expect(loop.playbackRate).to.equal(2); transport.start(); }, 0.7).then(() => { expect(invoked).to.be.true; }); - }); it("can playback at a faster rate", () => { @@ -321,7 +312,7 @@ describe("Loop", () => { interval: 0.1, callback: () => { callCount++; - } + }, }).start(0); loop.playbackRate = 1.5; expect(loop.playbackRate).to.equal(1.5); diff --git a/Tone/event/Loop.ts b/Tone/event/Loop.ts index fb18d69c..f629afa9 100644 --- a/Tone/event/Loop.ts +++ b/Tone/event/Loop.ts @@ -1,9 +1,18 @@ -import { ToneEvent } from "./ToneEvent"; -import { NormalRange, Positive, Seconds, Time, TransportTime } from "../core/type/Units"; -import { ToneWithContext, ToneWithContextOptions } from "../core/context/ToneWithContext"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { noOp } from "../core/util/Interface"; -import { BasicPlaybackState } from "../core/util/StateTimeline"; +import { ToneEvent } from "./ToneEvent.js"; +import { + NormalRange, + Positive, + Seconds, + Time, + TransportTime, +} from "../core/type/Units.js"; +import { + ToneWithContext, + ToneWithContextOptions, +} from "../core/context/ToneWithContext.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { noOp } from "../core/util/Interface.js"; +import { BasicPlaybackState } from "../core/util/StateTimeline.js"; export interface LoopOptions extends ToneWithContextOptions { callback: (time: Seconds) => void; @@ -16,20 +25,21 @@ export interface LoopOptions extends ToneWithContextOptions { } /** - * Loop creates a looped callback at the - * specified interval. The callback can be + * Loop creates a looped callback at the + * specified interval. The callback can be * started, stopped and scheduled along - * the Transport's timeline. + * the Transport's timeline. * @example * const loop = new Tone.Loop((time) => { - * // triggered every eighth note. + * // triggered every eighth note. * console.log(time); * }, "8n").start(0); * Tone.Transport.start(); * @category Event */ -export class Loop extends ToneWithContext { - +export class Loop< + Options extends LoopOptions = LoopOptions, +> extends ToneWithContext { readonly name: string = "Loop"; /** @@ -40,17 +50,25 @@ export class Loop extends ToneWithCon /** * The callback to invoke with the next event in the pattern */ - callback: (time: Seconds) => void + callback: (time: Seconds) => void; /** * @param callback The callback to invoke at the time. - * @param interval The time between successive callback calls. + * @param interval The time between successive callback calls. */ constructor(callback?: (time: Seconds) => void, interval?: Time); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Loop.getDefaults(), arguments, ["callback", "interval"])); - const options = optionsFromArguments(Loop.getDefaults(), arguments, ["callback", "interval"]); + super( + optionsFromArguments(Loop.getDefaults(), arguments, [ + "callback", + "interval", + ]) + ); + const options = optionsFromArguments(Loop.getDefaults(), arguments, [ + "callback", + "interval", + ]); this._event = new ToneEvent({ context: this.context, @@ -75,7 +93,7 @@ export class Loop extends ToneWithCon iterations: Infinity, probability: 1, mute: false, - humanize: false + humanize: false, }); } @@ -122,14 +140,14 @@ export class Loop extends ToneWithCon } /** - * The progress of the loop as a value between 0-1. 0, when the loop is stopped or done iterating. + * The progress of the loop as a value between 0-1. 0, when the loop is stopped or done iterating. */ get progress(): NormalRange { return this._event.progress; } /** - * The time between successive callbacks. + * The time between successive callbacks. * @example * const loop = new Tone.Loop(); * loop.interval = "8n"; // loop every 8n @@ -142,8 +160,8 @@ export class Loop extends ToneWithCon } /** - * The playback rate of the loop. The normal playback rate is 1 (no change). - * A `playbackRate` of 2 would be twice as fast. + * The playback rate of the loop. The normal playback rate is 1 (no change). + * A `playbackRate` of 2 would be twice as fast. */ get playbackRate(): Positive { return this._event.playbackRate; @@ -153,7 +171,7 @@ export class Loop extends ToneWithCon } /** - * Random variation +/-0.01s to the scheduled time. + * Random variation +/-0.01s to the scheduled time. * Or give it a time value which it will randomize by. */ get humanize(): boolean | Time { diff --git a/Tone/event/Part.test.ts b/Tone/event/Part.test.ts index de0fd601..c2a07daf 100644 --- a/Tone/event/Part.test.ts +++ b/Tone/event/Part.test.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { Time } from "Tone/core/type/Time"; -import { noOp } from "Tone/core/util/Interface"; -import { Part } from "./Part"; -import { Sequence } from "./Sequence"; -import { ToneEvent } from "./ToneEvent"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { atTime, Offline } from "../../test/helper/Offline.js"; +import { Time } from "../core/type/Time.js"; +import { noOp } from "../core/util/Interface.js"; +import { Part } from "./Part.js"; +import { Sequence } from "./Sequence.js"; +import { ToneEvent } from "./ToneEvent.js"; describe("Part", () => { - BasicTests(Part); context("Constructor", () => { - it("takes a callback and an array of values", () => { return Offline(() => { const callback = noOp; @@ -54,7 +52,6 @@ describe("Part", () => { }); context("Adding / Removing / Getting Events", () => { - it("can take events in the constructor as an array of times", () => { return Offline(() => { const part = new Part(noOp, ["0", "8n", "4n"]); @@ -65,7 +62,11 @@ describe("Part", () => { it("can take events in the constructor as an array of times and values", () => { return Offline(() => { - const part = new Part(noOp, [["0", "C4"], ["8n", "D3"], ["4n", "E4"]]); + const part = new Part(noOp, [ + ["0", "C4"], + ["8n", "D3"], + ["4n", "E4"], + ]); expect(part.length).to.equal(3); part.dispose(); }); @@ -73,7 +74,11 @@ describe("Part", () => { it("can retrieve an event using 'at'", () => { return Offline(() => { - const part = new Part(noOp, [["0", 0], ["8n", "C2"], ["4n", 2]]); + const part = new Part(noOp, [ + ["0", 0], + ["8n", "C2"], + ["4n", 2], + ]); expect(part.length).to.equal(3); expect(part.at(0)).to.be.instanceof(ToneEvent); expect((part.at(0) as ToneEvent).value).to.equal(0); @@ -99,14 +104,16 @@ describe("Part", () => { it("can take events in the constructor as an array of objects", () => { return Offline(() => { - const part = new Part(noOp, [{ - note: "C3", - time: 0.3, - }, - { - note: "D3", - time: 1, - }]); + const part = new Part(noOp, [ + { + note: "C3", + time: 0.3, + }, + { + note: "D3", + time: 1, + }, + ]); expect(part.length).to.equal(2); expect((part.at(0.3) as ToneEvent).value).to.be.an("object"); expect((part.at(0.3) as ToneEvent).value.note).to.equal("C3"); @@ -117,16 +124,23 @@ describe("Part", () => { it("can cancel event changes", () => { let count = 0; return Offline(({ transport }) => { - const part = new Part((time) => { - count++; - }, [{ - note: "C3", - time: 0, - }, - { - note: "D3", - time: 0.2, - }]).start(0).stop(0.1); + const part = new Part( + (time) => { + count++; + }, + [ + { + note: "C3", + time: 0, + }, + { + note: "D3", + time: 0.2, + }, + ] + ) + .start(0) + .stop(0.1); part.cancel(0.1); transport.start(0); }, 0.3).then(() => { @@ -156,8 +170,12 @@ describe("Part", () => { }); expect(part.length).to.equal(1); expect((part.at(0.5) as ToneEvent).value).to.be.an("object"); - expect((part.at(0.5) as ToneEvent).value.duration).to.deep.equal("8n"); - expect((part.at(0.5) as ToneEvent).value.note).to.deep.equal("D4"); + expect( + (part.at(0.5) as ToneEvent).value.duration + ).to.deep.equal("8n"); + expect((part.at(0.5) as ToneEvent).value.note).to.deep.equal( + "D4" + ); part.dispose(); }); }); @@ -193,7 +211,10 @@ describe("Part", () => { it("can remove an event by time", () => { return Offline(() => { const part = new Part({ - events: [[0.2, "C3"], [0.2, "C4"]], + events: [ + [0.2, "C3"], + [0.2, "C4"], + ], }); expect(part.length).to.equal(2); part.remove(0.2); @@ -223,7 +244,10 @@ describe("Part", () => { it("added events have the same settings as the parent", () => { return Offline(() => { const part = new Part({ - events: [[0.2, "C3"], [0.3, "C4"]], + events: [ + [0.2, "C3"], + [0.3, "C4"], + ], loopEnd: "1m", loopStart: "4n", probability: 0.2, @@ -265,11 +289,9 @@ describe("Part", () => { part.dispose(); }); }); - }); context("Part callback", () => { - it("does not invoke get invoked until started", () => { return Offline(({ transport }) => { const part = new Part(() => { @@ -295,11 +317,14 @@ describe("Part", () => { let invoked = false; return Offline(({ transport }) => { const startTime = 0.1; - const part = new Part((time) => { - expect(time).to.be.a("number"); - expect(time - startTime).to.be.closeTo(0.5, 0.01); - invoked = true; - }, [0.3]); + const part = new Part( + (time) => { + expect(time).to.be.a("number"); + expect(time - startTime).to.be.closeTo(0.5, 0.01); + invoked = true; + }, + [0.3] + ); part.start(0.2); transport.start(startTime); }, 0.62).then(() => { @@ -310,12 +335,15 @@ describe("Part", () => { it("passes in the value to the callback", () => { let invoked = false; return Offline(({ transport }) => { - const part = new Part((time, thing) => { - expect(time).to.be.a("number"); - expect(thing).to.equal("thing"); - part.dispose(); - invoked = true; - }, [[0, "thing"]]).start(); + const part = new Part( + (time, thing) => { + expect(time).to.be.a("number"); + expect(thing).to.equal("thing"); + part.dispose(); + invoked = true; + }, + [[0, "thing"]] + ).start(); transport.start(); }, 0.6).then(() => { expect(invoked).to.be.true; @@ -360,10 +388,17 @@ describe("Part", () => { let count = 0; return Offline(({ transport }) => { const now = transport.now() + 0.1; - new Part((time, value) => { - count++; - expect(time - now).to.be.closeTo(value, 0.01); - }, [[0, 0], [0.1, 0.1], [0.2, 0.2]]).start(); + new Part( + (time, value) => { + count++; + expect(time - now).to.be.closeTo(value, 0.01); + }, + [ + [0, 0], + [0.1, 0.1], + [0.2, 0.2], + ] + ).start(); transport.start(now); }, 0.4).then(() => { expect(count).to.equal(3); @@ -397,7 +432,10 @@ describe("Part", () => { return Offline(({ transport }) => { const startTime = 0.1; const subPart = new Part({ - events: [[0, 1], [0.3, 2]], + events: [ + [0, 1], + [0.3, 2], + ], }); const part = new Part((time, value) => { invokations++; @@ -409,7 +447,10 @@ describe("Part", () => { expect(time - startTime).to.be.closeTo(0.5, 0.01); part.dispose(); } - }).add(0.2, subPart).add(0, 0).start(0); + }) + .add(0.2, subPart) + .add(0, 0) + .start(0); transport.start(startTime); }, 0.7).then(() => { expect(invokations).to.equal(3); @@ -420,26 +461,33 @@ describe("Part", () => { let invoked = false; return Offline(({ transport }) => { const startTime = 0.1; - const part = new Part((time, number) => { - expect(time - startTime).to.be.closeTo(0.1, 0.01); - expect(number).to.equal(1); - invoked = true; - }, [[0, 0], [1, 1]]).start(0, 0.9); + const part = new Part( + (time, number) => { + expect(time - startTime).to.be.closeTo(0.1, 0.01); + expect(number).to.equal(1); + invoked = true; + }, + [ + [0, 0], + [1, 1], + ] + ).start(0, 0.9); transport.start(startTime); }, 0.3).then(() => { expect(invoked).to.be.true; }); }); - }); context("Looping", () => { - it("can be set using a boolean as an argument when created", () => { let callCount = 0; return Offline(({ transport }) => { new Part({ - events: [[0, 1], [0.1, 2]], + events: [ + [0, 1], + [0.1, 2], + ], loop: true, loopEnd: 0.2, callback(): void { @@ -456,7 +504,10 @@ describe("Part", () => { let callCount = 0; return Offline(({ transport }) => { const part = new Part({ - events: [[0, 1], [0.1, 2]], + events: [ + [0, 1], + [0.1, 2], + ], loop: true, loopEnd: 0.2, callback(): void { @@ -474,7 +525,10 @@ describe("Part", () => { let callCount = 0; return Offline(({ transport }) => { const part = new Part({ - events: [[0, 1], [0.1, 2]], + events: [ + [0, 1], + [0.1, 2], + ], loop: false, loopEnd: 0.2, callback(): void { @@ -515,7 +569,10 @@ describe("Part", () => { return Offline(({ transport }) => { let switched = false; const part = new Part({ - events: [[0, 0], [0.25, 1]], + events: [ + [0, 0], + [0.25, 1], + ], loop: true, loopEnd: 0.5, callback(time, value): void { @@ -539,7 +596,10 @@ describe("Part", () => { return Offline(({ transport }) => { let switched = false; const part = new Part({ - events: [[0, 0], [0.25, 1]], + events: [ + [0, 0], + [0.25, 1], + ], loop: true, loopEnd: 0.5, callback(time, value): void { @@ -649,7 +709,12 @@ describe("Part", () => { let invoked = false; return Offline(({ transport }) => { new Part({ - events: [[0, 0], ["8n", 1], ["8n + 16n", 2], ["4n", 3]], + events: [ + [0, 0], + ["8n", 1], + ["8n + 16n", 2], + ["4n", 3], + ], loop: true, loopEnd: "4n", loopStart: "8n", @@ -668,19 +733,37 @@ describe("Part", () => { it("can be started and stopped multiple times", () => { let eventTimeIndex = 0; return Offline(({ transport }) => { - const eventTimes = [[0.5, 0], [0.6, 1], [1.1, 0], [1.2, 1], [1.3, 2], [1.4, 0], [1.5, 1], [1.6, 2]]; + const eventTimes = [ + [0.5, 0], + [0.6, 1], + [1.1, 0], + [1.2, 1], + [1.3, 2], + [1.4, 0], + [1.5, 1], + [1.6, 2], + ]; new Part({ - events: [[0, 0], [0.1, 1], [0.2, 2]], + events: [ + [0, 0], + [0.1, 1], + [0.2, 2], + ], loop: true, loopEnd: 0.3, loopStart: 0, callback(time, value): void { expect(eventTimes.length).to.be.gt(eventTimeIndex); - expect(eventTimes[eventTimeIndex][0]).to.be.closeTo(time, 0.05); + expect(eventTimes[eventTimeIndex][0]).to.be.closeTo( + time, + 0.05 + ); expect(eventTimes[eventTimeIndex][1]).to.equal(value); eventTimeIndex++; }, - }).start(0.3).stop(0.81); + }) + .start(0.3) + .stop(0.81); transport.start(0.2).stop(0.61).start(0.8); }, 2).then(() => { expect(eventTimeIndex).to.equal(8); @@ -690,19 +773,37 @@ describe("Part", () => { it("can adjust the loopEnd times", () => { let eventTimeIndex = 0; return Offline(({ transport }) => { - const eventTimes = [[0.5, 0], [0.6, 1], [1.1, 0], [1.2, 1], [1.3, 2], [1.4, 0], [1.5, 1], [1.6, 2]]; + const eventTimes = [ + [0.5, 0], + [0.6, 1], + [1.1, 0], + [1.2, 1], + [1.3, 2], + [1.4, 0], + [1.5, 1], + [1.6, 2], + ]; const part = new Part({ - events: [[0, 0], [0.1, 1], [0.2, 2]], + events: [ + [0, 0], + [0.1, 1], + [0.2, 2], + ], loop: true, loopEnd: 0.2, loopStart: 0, callback(time, value): void { expect(eventTimes.length).to.be.gt(eventTimeIndex); - expect(eventTimes[eventTimeIndex][0]).to.be.closeTo(time, 0.05); + expect(eventTimes[eventTimeIndex][0]).to.be.closeTo( + time, + 0.05 + ); expect(eventTimes[eventTimeIndex][1]).to.equal(value); eventTimeIndex++; }, - }).start(0.3).stop(0.81); + }) + .start(0.3) + .stop(0.81); part.loopEnd = 0.4; part.loopEnd = 0.3; transport.start(0.2).stop(0.61).start(0.8); @@ -736,15 +837,21 @@ describe("Part", () => { let iteration = 0; return Offline(({ transport }) => { const now = transport.now(); - const part = new Part((time, number) => { - if (iteration === 0) { - expect(number).to.equal(1); - expect(time - now).to.be.closeTo(0.2, 0.05); - } else if (iteration === 1) { - expect(number).to.equal(0); - } - iteration++; - }, [[0, 0], [0.25, 1]]); + const part = new Part( + (time, number) => { + if (iteration === 0) { + expect(number).to.equal(1); + expect(time - now).to.be.closeTo(0.2, 0.05); + } else if (iteration === 1) { + expect(number).to.equal(0); + } + iteration++; + }, + [ + [0, 0], + [0.25, 1], + ] + ); part.loop = true; part.loopEnd = 0.5; part.start(0, 1.05); @@ -757,20 +864,27 @@ describe("Part", () => { it("can start a loop with an offset before loop start", () => { let iteration = 0; return Offline(({ transport }) => { - const part = new Part((time, number) => { - if (iteration === 0) { - expect(number).to.equal(0); - } else if (iteration === 1) { - expect(number).to.equal(1); - } else if (iteration === 2) { - expect(number).to.equal(2); - } else if (iteration === 3) { - expect(number).to.equal(1); - } else if (iteration === 4) { - expect(number).to.equal(2); - } - iteration++; - }, [[0, 0], [0.25, 1], [0.30, 2]]); + const part = new Part( + (time, number) => { + if (iteration === 0) { + expect(number).to.equal(0); + } else if (iteration === 1) { + expect(number).to.equal(1); + } else if (iteration === 2) { + expect(number).to.equal(2); + } else if (iteration === 3) { + expect(number).to.equal(1); + } else if (iteration === 4) { + expect(number).to.equal(2); + } + iteration++; + }, + [ + [0, 0], + [0.25, 1], + [0.3, 2], + ] + ); part.loop = true; part.loopStart = 0.25; part.loopEnd = 0.5; @@ -780,11 +894,9 @@ describe("Part", () => { expect(iteration).to.equal(5); }); }); - }); context("playbackRate", () => { - it("can adjust the playbackRate", () => { let invoked = false; return Offline(({ transport }) => { @@ -835,7 +947,6 @@ describe("Part", () => { }); context("scheduling", () => { - it("throws an error if events are scheduling in the wrong order", () => { const part = new Part(); part.start(1); diff --git a/Tone/event/Part.ts b/Tone/event/Part.ts index 693a31c9..b849815e 100644 --- a/Tone/event/Part.ts +++ b/Tone/event/Part.ts @@ -1,20 +1,36 @@ -import { TicksClass } from "../core/type/Ticks"; -import { TransportTimeClass } from "../core/type/TransportTime"; -import { NormalRange, Positive, Seconds, Ticks, Time, TransportTime } from "../core/type/Units"; -import { defaultArg, optionsFromArguments } from "../core/util/Defaults"; -import { StateTimeline } from "../core/util/StateTimeline"; -import { isArray, isDefined, isObject, isUndef } from "../core/util/TypeCheck"; -import { ToneEvent, ToneEventCallback, ToneEventOptions } from "./ToneEvent"; - -type CallbackType = - T extends { - time: Time; - [key: string]: any; - } ? T : - T extends ArrayLike ? T[1] : - T extends Time ? null : never; - -interface PartOptions extends Omit>, "value"> { +import { TicksClass } from "../core/type/Ticks.js"; +import { TransportTimeClass } from "../core/type/TransportTime.js"; +import { + NormalRange, + Positive, + Seconds, + Ticks, + Time, + TransportTime, +} from "../core/type/Units.js"; +import { defaultArg, optionsFromArguments } from "../core/util/Defaults.js"; +import { StateTimeline } from "../core/util/StateTimeline.js"; +import { + isArray, + isDefined, + isObject, + isUndef, +} from "../core/util/TypeCheck.js"; +import { ToneEvent, ToneEventCallback, ToneEventOptions } from "./ToneEvent.js"; + +type CallbackType = T extends { + time: Time; + [key: string]: any; +} + ? T + : T extends ArrayLike + ? T[1] + : T extends Time + ? null + : never; + +interface PartOptions + extends Omit>, "value"> { events: T[]; } @@ -42,7 +58,6 @@ interface PartOptions extends Omit>, "value" * @category Event */ export class Part extends ToneEvent { - readonly name: string = "Part"; /** @@ -62,18 +77,28 @@ export class Part extends ToneEvent { * @param callback The callback to invoke on each event * @param value the array of events */ - constructor(callback?: ToneEventCallback>, value?: ValueType[]); + constructor( + callback?: ToneEventCallback>, + value?: ValueType[] + ); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(Part.getDefaults(), arguments, ["callback", "events"])); - const options = optionsFromArguments(Part.getDefaults(), arguments, ["callback", "events"]); + super( + optionsFromArguments(Part.getDefaults(), arguments, [ + "callback", + "events", + ]) + ); + const options = optionsFromArguments(Part.getDefaults(), arguments, [ + "callback", + "events", + ]); // make sure things are assigned in the right order this._state.increasing = true; // add the events - options.events.forEach(event => { + options.events.forEach((event) => { if (isArray(event)) { this.add(event[0], event[1]); } else { @@ -109,7 +134,7 @@ export class Part extends ToneEvent { state: "started", time: ticks, }); - this._forEach(event => { + this._forEach((event) => { this._startNote(event, ticks, computedOffset); }); } @@ -126,13 +151,19 @@ export class Part extends ToneEvent { private _startNote(event: ToneEvent, ticks: Ticks, offset: Ticks): void { ticks -= offset; if (this._loop) { - if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) { + if ( + event.startOffset >= this._loopStart && + event.startOffset < this._loopEnd + ) { if (event.startOffset < offset) { // start it on the next loop ticks += this._getLoopDuration(); } event.start(new TicksClass(this.context, ticks)); - } else if (event.startOffset < this._loopStart && event.startOffset >= offset) { + } else if ( + event.startOffset < this._loopStart && + event.startOffset >= offset + ) { event.loop = false; event.start(new TicksClass(this.context, ticks)); } @@ -146,7 +177,7 @@ export class Part extends ToneEvent { } set startOffset(offset) { this._startOffset = offset; - this._forEach(event => { + this._forEach((event) => { event.startOffset += this._startOffset; }); } @@ -159,7 +190,7 @@ export class Part extends ToneEvent { const ticks = this.toTicks(time); this._state.cancel(ticks); this._state.setStateAtTime("stopped", ticks); - this._forEach(event => { + this._forEach((event) => { event.stop(time); }); return this; @@ -180,7 +211,10 @@ export class Part extends ToneEvent { * @param value If a value is passed in, the value of the event at the given time will be set to it. */ at(time: Time, value?: any): ToneEvent | null { - const timeInTicks = new TransportTimeClass(this.context, time).toTicks(); + const timeInTicks = new TransportTimeClass( + this.context, + time + ).toTicks(); const tickTime = new TicksClass(this.context, 1).toSeconds(); const iterator = this._events.values(); @@ -214,10 +248,7 @@ export class Part extends ToneEvent { * const part = new Tone.Part(); * part.add("1m", "C#+11"); */ - add(obj: { - time: Time; - [key: string]: any; - }): this; + add(obj: { time: Time; [key: string]: any }): this; add(time: Time, value?: any): this; add(time: Time | object, value?: any): this { // extract the parameters @@ -277,10 +308,7 @@ export class Part extends ToneEvent { * @param time The time of the event * @param value Optionally select only a specific event value */ - remove(obj: { - time: Time; - [key: string]: any; - }): this; + remove(obj: { time: Time; [key: string]: any }): this; remove(time: Time, value?: any): this; remove(time: Time | object, value?: any): this { // extract the parameters @@ -289,9 +317,12 @@ export class Part extends ToneEvent { time = value.time; } time = this.toTicks(time); - this._events.forEach(event => { + this._events.forEach((event) => { if (event.startOffset === time) { - if (isUndef(value) || (isDefined(value) && event.value === value)) { + if ( + isUndef(value) || + (isDefined(value) && event.value === value) + ) { this._events.delete(event); event.dispose(); } @@ -304,7 +335,7 @@ export class Part extends ToneEvent { * Remove all of the notes from the group. */ clear(): this { - this._forEach(event => event.dispose()); + this._forEach((event) => event.dispose()); this._events.clear(); return this; } @@ -314,7 +345,7 @@ export class Part extends ToneEvent { * @param after The time after which to cancel the scheduled events. */ cancel(after?: TransportTime | TransportTimeClass): this { - this._forEach(event => event.cancel(after)); + this._forEach((event) => event.cancel(after)); this._state.cancel(this.toTicks(after)); return this; } @@ -324,7 +355,7 @@ export class Part extends ToneEvent { */ private _forEach(callback: (event: ToneEvent) => void): this { if (this._events) { - this._events.forEach(event => { + this._events.forEach((event) => { if (event instanceof Part) { event._forEach(callback); } else { @@ -341,7 +372,7 @@ export class Part extends ToneEvent { * @param value The value to set it to */ private _setAll(attr: string, value: any): void { - this._forEach(event => { + this._forEach((event) => { event[attr] = value; }); } @@ -362,7 +393,11 @@ export class Part extends ToneEvent { * @param event The event to test */ private _testLoopBoundries(event: ToneEvent): void { - if (this._loop && (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd)) { + if ( + this._loop && + (event.startOffset < this._loopStart || + event.startOffset >= this._loopEnd) + ) { event.cancel(0); } else if (event.state === "stopped") { // reschedule it if it's stopped @@ -405,7 +440,7 @@ export class Part extends ToneEvent { } set loop(loop) { this._loop = loop; - this._forEach(event => { + this._forEach((event) => { event.loopStart = this.loopStart; event.loopEnd = this.loopEnd; event.loop = loop; @@ -423,7 +458,7 @@ export class Part extends ToneEvent { set loopEnd(loopEnd) { this._loopEnd = this.toTicks(loopEnd); if (this._loop) { - this._forEach(event => { + this._forEach((event) => { event.loopEnd = loopEnd; this._testLoopBoundries(event); }); @@ -440,7 +475,7 @@ export class Part extends ToneEvent { set loopStart(loopStart) { this._loopStart = this.toTicks(loopStart); if (this._loop) { - this._forEach(event => { + this._forEach((event) => { event.loopStart = this.loopStart; this._testLoopBoundries(event); }); diff --git a/Tone/event/Pattern.test.ts b/Tone/event/Pattern.test.ts index 9375fa26..7262b5bd 100644 --- a/Tone/event/Pattern.test.ts +++ b/Tone/event/Pattern.test.ts @@ -1,18 +1,16 @@ -import { BasicTests } from "test/helper/Basic"; -import { Pattern } from "./Pattern"; -import { Offline } from "test/helper/Offline"; -import { Time } from "Tone/core/type/Time"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Pattern } from "./Pattern.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Time } from "../core/type/Time.js"; import { expect } from "chai"; describe("Pattern", () => { - BasicTests(Pattern); context("Constructor", () => { - it("takes a callback, an array of values and a pattern name", () => { return Offline(() => { - const callback = function() {}; + const callback = function () {}; const pattern = new Pattern(callback, [0, 1, 2, 3], "down"); expect(pattern.callback).to.equal(callback); expect(pattern.values).to.deep.equal([0, 1, 2, 3]); @@ -30,17 +28,19 @@ describe("Pattern", () => { it("can pass in arguments in options object", () => { return Offline(() => { - const callback = function() {}; + const callback = function () {}; const pattern = new Pattern({ callback: callback, iterations: 4, probability: 0.3, interval: "8t", values: [1, 2, 3], - pattern: "upDown" + pattern: "upDown", }); expect(pattern.callback).to.equal(callback); - expect(pattern.interval.valueOf()).to.equal(Time("8t").valueOf()); + expect(pattern.interval.valueOf()).to.equal( + Time("8t").valueOf() + ); expect(pattern.iterations).to.equal(4); expect(pattern.values).to.deep.equal([1, 2, 3]); expect(pattern.probability).to.equal(0.3); @@ -51,10 +51,9 @@ describe("Pattern", () => { }); context("Get/Set", () => { - it("can set values with object", () => { return Offline(() => { - const callback = function() {}; + const callback = function () {}; const pattern = new Pattern(); pattern.set({ callback: callback, @@ -68,7 +67,7 @@ describe("Pattern", () => { it("can set get a the values as an object", () => { return Offline(() => { - const callback = function() {}; + const callback = function () {}; const pattern = new Pattern({ callback: callback, pattern: "random", @@ -85,18 +84,17 @@ describe("Pattern", () => { }); context("Callback", () => { - it("is invoked after it's started", () => { let invoked = false; return Offline(({ transport }) => { const values = ["a", "b", "c"]; let index = 0; - const pattern = new Pattern((() => { + const pattern = new Pattern(() => { invoked = true; expect(pattern.value).to.equal(values[index]); expect(pattern.index).to.equal(index); index++; - }), values).start(0); + }, values).start(0); transport.start(); }, 0.2).then(() => { expect(invoked).to.be.true; @@ -107,14 +105,18 @@ describe("Pattern", () => { let invoked = false; return Offline(({ transport }) => { const startTime = 0.05; - const pattern = new Pattern(((time, note) => { - expect(time).to.be.a("number"); - expect(time - startTime).to.be.closeTo(0.3, 0.01); - expect(note).to.be.equal("a"); - expect(pattern.value).to.equal("a"); - expect(pattern.index).to.be.equal(0); - invoked = true; - }), ["a"], "up"); + const pattern = new Pattern( + (time, note) => { + expect(time).to.be.a("number"); + expect(time - startTime).to.be.closeTo(0.3, 0.01); + expect(note).to.be.equal("a"); + expect(pattern.value).to.equal("a"); + expect(pattern.index).to.be.equal(0); + invoked = true; + }, + ["a"], + "up" + ); transport.start(startTime); pattern.start(0.3); }, 0.4).then(() => { @@ -126,12 +128,16 @@ describe("Pattern", () => { let counter = 0; return Offline(({ transport }) => { const values = ["a", "b", "c"]; - const pattern = new Pattern(((time, note) => { - expect(note).to.equal(values[counter % 3]); - expect(pattern.value).to.equal(values[counter % 3]); - expect(pattern.index).to.be.equal(counter % 3); - counter++; - }), values, "up").start(0); + const pattern = new Pattern( + (time, note) => { + expect(note).to.equal(values[counter % 3]); + expect(pattern.value).to.equal(values[counter % 3]); + expect(pattern.index).to.be.equal(counter % 3); + counter++; + }, + values, + "up" + ).start(0); pattern.interval = "16n"; transport.start(0); }, 0.7).then(() => { @@ -143,12 +149,16 @@ describe("Pattern", () => { let counter = 0; return Offline(({ transport }) => { const values = ["a", "b", "c"]; - const pattern = new Pattern(((time, note) => { - expect(note).to.equal(values[counter % 3]); - expect(pattern.value).to.equal(values[counter % 3]); - expect(pattern.index).to.be.equal(counter % 3); - counter++; - }), ["a"], "down").start(0); + const pattern = new Pattern( + (time, note) => { + expect(note).to.equal(values[counter % 3]); + expect(pattern.value).to.equal(values[counter % 3]); + expect(pattern.index).to.be.equal(counter % 3); + counter++; + }, + ["a"], + "down" + ).start(0); pattern.interval = "16n"; pattern.pattern = "up"; pattern.values = values; @@ -158,6 +168,4 @@ describe("Pattern", () => { }); }); }); - }); - diff --git a/Tone/event/Pattern.ts b/Tone/event/Pattern.ts index ab79d5a7..99a68976 100644 --- a/Tone/event/Pattern.ts +++ b/Tone/event/Pattern.ts @@ -1,9 +1,9 @@ -import { Loop, LoopOptions } from "./Loop"; -import { PatternGenerator, PatternName } from "./PatternGenerator"; -import { ToneEventCallback } from "./ToneEvent"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Seconds } from "../core/type/Units"; -import { noOp } from "../core/util/Interface"; +import { Loop, LoopOptions } from "./Loop.js"; +import { PatternGenerator, PatternName } from "./PatternGenerator.js"; +import { ToneEventCallback } from "./ToneEvent.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Seconds } from "../core/type/Units.js"; +import { noOp } from "../core/util/Interface.js"; export interface PatternOptions extends LoopOptions { pattern: PatternName; @@ -13,7 +13,7 @@ export interface PatternOptions extends LoopOptions { /** * Pattern arpeggiates between the given notes - * in a number of patterns. + * in a number of patterns. * @example * const pattern = new Tone.Pattern((time, note) => { * // the order of the notes passed in depends on the pattern @@ -21,7 +21,6 @@ export interface PatternOptions extends LoopOptions { * @category Event */ export class Pattern extends Loop> { - readonly name: string = "Pattern"; /** @@ -32,12 +31,12 @@ export class Pattern extends Loop> { /** * The current index */ - private _index?: number; + private _index?: number; /** * The current value */ - private _value?: ValueType; + private _value?: ValueType; /** * Hold the pattern type @@ -62,17 +61,29 @@ export class Pattern extends Loop> { constructor( callback?: ToneEventCallback, values?: ValueType[], - pattern?: PatternName, + pattern?: PatternName ); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"])); - const options = optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]); + super( + optionsFromArguments(Pattern.getDefaults(), arguments, [ + "callback", + "values", + "pattern", + ]) + ); + const options = optionsFromArguments(Pattern.getDefaults(), arguments, [ + "callback", + "values", + "pattern", + ]); this.callback = options.callback; this._values = options.values; - this._pattern = PatternGenerator(options.values.length, options.pattern); + this._pattern = PatternGenerator( + options.values.length, + options.pattern + ); this._type = options.pattern; } @@ -116,12 +127,12 @@ export class Pattern extends Loop> { /** * The current index of the pattern. */ - get index(): number | undefined { + get index(): number | undefined { return this._index; } /** - * The pattern type. + * The pattern type. */ get pattern(): PatternName { return this._type; @@ -131,4 +142,3 @@ export class Pattern extends Loop> { this._pattern = PatternGenerator(this._values.length, this._type); } } - diff --git a/Tone/event/PatternGenerator.test.ts b/Tone/event/PatternGenerator.test.ts index 81b2acf1..918a0e10 100644 --- a/Tone/event/PatternGenerator.test.ts +++ b/Tone/event/PatternGenerator.test.ts @@ -1,8 +1,7 @@ import { expect } from "chai"; -import { PatternGenerator } from "./PatternGenerator"; +import { PatternGenerator } from "./PatternGenerator.js"; describe("PatternGenerator", () => { - function getArrayValues(gen: Iterator, length: number): any[] { const ret: any[] = []; for (let i = 0; i < length; i++) { @@ -12,10 +11,11 @@ describe("PatternGenerator", () => { } context("API", () => { - it("can be constructed with an number and type", () => { const pattern = PatternGenerator(4, "down"); - expect(getArrayValues(pattern, 10)).to.deep.equal([3, 2, 1, 0, 3, 2, 1, 0, 3, 2]); + expect(getArrayValues(pattern, 10)).to.deep.equal([ + 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, + ]); }); it("throws an error with a number less than 1", () => { @@ -27,50 +27,65 @@ describe("PatternGenerator", () => { }); context("Patterns", () => { - it("does the up pattern", () => { const pattern = PatternGenerator(4, "up"); - expect(getArrayValues(pattern, 6)).to.deep.equal([0, 1, 2, 3, 0, 1]); + expect(getArrayValues(pattern, 6)).to.deep.equal([ + 0, 1, 2, 3, 0, 1, + ]); }); it("does the down pattern", () => { const pattern = PatternGenerator(4, "down"); - expect(getArrayValues(pattern, 6)).to.deep.equal([3, 2, 1, 0, 3, 2]); + expect(getArrayValues(pattern, 6)).to.deep.equal([ + 3, 2, 1, 0, 3, 2, + ]); }); it("does the upDown pattern", () => { const pattern = PatternGenerator(4, "upDown"); - expect(getArrayValues(pattern, 10)).to.deep.equal([0, 1, 2, 3, 2, 1, 0, 1, 2, 3]); + expect(getArrayValues(pattern, 10)).to.deep.equal([ + 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, + ]); }); it("does the downUp pattern", () => { const pattern = PatternGenerator(4, "downUp"); - expect(getArrayValues(pattern, 10)).to.deep.equal([3, 2, 1, 0, 1, 2, 3, 2, 1, 0]); + expect(getArrayValues(pattern, 10)).to.deep.equal([ + 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, + ]); }); it("does the alternateUp pattern", () => { const pattern = PatternGenerator(5, "alternateUp"); - expect(getArrayValues(pattern, 10)).to.deep.equal([0, 2, 1, 3, 2, 4, 3, 0, 2, 1]); + expect(getArrayValues(pattern, 10)).to.deep.equal([ + 0, 2, 1, 3, 2, 4, 3, 0, 2, 1, + ]); }); it("does the alternateDown pattern", () => { const pattern = PatternGenerator(5, "alternateDown"); - expect(getArrayValues(pattern, 10)).to.deep.equal([4, 2, 3, 1, 2, 0, 1, 4, 2, 3]); + expect(getArrayValues(pattern, 10)).to.deep.equal([ + 4, 2, 3, 1, 2, 0, 1, 4, 2, 3, + ]); }); it("outputs random elements from the values", () => { const numValues = 5; const pattern = PatternGenerator(numValues, "random"); for (let i = 0; i < 10; i++) { - expect(pattern.next().value).to.be.at.least(0).and.at.most(numValues - 1); + expect(pattern.next().value) + .to.be.at.least(0) + .and.at.most(numValues - 1); } }); it("does randomOnce pattern", () => { const pattern = PatternGenerator(5, "randomOnce"); - expect(getArrayValues(pattern, 10).sort()).to.deep.equal([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); + expect(getArrayValues(pattern, 10).sort()).to.deep.equal([ + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + ]); }); - + it("randomly walks up or down 1 step without repeating", () => { const values = [0, 1, 2, 3, 4]; const pattern = PatternGenerator(5, "randomWalk"); diff --git a/Tone/event/PatternGenerator.ts b/Tone/event/PatternGenerator.ts index 9aecb92c..5b1f99cc 100644 --- a/Tone/event/PatternGenerator.ts +++ b/Tone/event/PatternGenerator.ts @@ -1,10 +1,19 @@ -import { assert } from "../core/util/Debug"; -import { clamp } from "../core/util/Math"; +import { assert } from "../core/util/Debug.js"; +import { clamp } from "../core/util/Math.js"; /** * The name of the patterns */ -export type PatternName = "up" | "down" | "upDown" | "downUp" | "alternateUp" | "alternateDown" | "random" | "randomOnce" | "randomWalk"; +export type PatternName = + | "up" + | "down" + | "upDown" + | "downUp" + | "alternateUp" + | "alternateDown" + | "random" + | "randomOnce" + | "randomWalk"; /** * Start at the first value and go up to the last @@ -33,7 +42,10 @@ function* downPatternGen(numValues: number): IterableIterator { /** * Infinitely yield the generator */ -function* infiniteGen(numValues: number, gen: typeof upPatternGen): IterableIterator { +function* infiniteGen( + numValues: number, + gen: typeof upPatternGen +): IterableIterator { while (true) { yield* gen(numValues); } @@ -42,7 +54,10 @@ function* infiniteGen(numValues: number, gen: typeof upPatternGen): IterableI /** * Alternate between two generators */ -function* alternatingGenerator(numValues: number, directionUp: boolean): IterableIterator { +function* alternatingGenerator( + numValues: number, + directionUp: boolean +): IterableIterator { let index = directionUp ? 0 : numValues - 1; while (true) { index = clamp(index, 0, numValues - 1); @@ -71,7 +86,7 @@ function* jumpUp(numValues: number): IterableIterator { index = clamp(index, 0, numValues - 1); yield index; stepIndex++; - index += (stepIndex % 2 ? 2 : -1); + index += stepIndex % 2 ? 2 : -1; } } @@ -85,7 +100,7 @@ function* jumpDown(numValues: number): IterableIterator { index = clamp(index, 0, numValues - 1); yield index; stepIndex++; - index += (stepIndex % 2 ? -2 : 1); + index += stepIndex % 2 ? -2 : 1; } } @@ -127,7 +142,8 @@ function* randomWalk(numValues: number): IterableIterator { index++; // at bottom, so force upward step } else if (index === numValues - 1) { index--; // at top, so force downward step - } else if (Math.random() < 0.5) { // else choose random downward or upward step + } else if (Math.random() < 0.5) { + // else choose random downward or upward step index--; } else { index++; @@ -143,17 +159,21 @@ function* randomWalk(numValues: number): IterableIterator { * @param pattern The name of the pattern use when iterating over * @param index Where to start in the offset of the values array */ -export function* PatternGenerator(numValues: number, pattern: PatternName = "up", index = 0): Iterator { +export function* PatternGenerator( + numValues: number, + pattern: PatternName = "up", + index = 0 +): Iterator { // safeguards assert(numValues >= 1, "The number of values must be at least one"); switch (pattern) { - case "up" : + case "up": yield* infiniteGen(numValues, upPatternGen); - case "down" : + case "down": yield* infiniteGen(numValues, downPatternGen); - case "upDown" : + case "upDown": yield* alternatingGenerator(numValues, true); - case "downUp" : + case "downUp": yield* alternatingGenerator(numValues, false); case "alternateUp": yield* infiniteGen(numValues, jumpUp); diff --git a/Tone/event/Sequence.test.ts b/Tone/event/Sequence.test.ts index 21d8e070..04c50b55 100644 --- a/Tone/event/Sequence.test.ts +++ b/Tone/event/Sequence.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { atTime, Offline } from "test/helper/Offline"; -import { Time } from "Tone/core/type/Time"; -import { noOp } from "Tone/core/util/Interface"; -import { Sequence } from "./Sequence"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { atTime, Offline } from "../../test/helper/Offline.js"; +import { Time } from "../core/type/Time.js"; +import { noOp } from "../core/util/Interface.js"; +import { Sequence } from "./Sequence.js"; describe("Sequence", () => { - BasicTests(Sequence); context("Constructor", () => { - it("takes a callback and a sequence of values", () => { return Offline(() => { const callback = noOp; @@ -73,7 +71,6 @@ describe("Sequence", () => { }); context("Adding / Removing / Getting Events", () => { - it("can add an event using the index", () => { return Offline(() => { const seq = new Sequence(); @@ -154,10 +151,8 @@ describe("Sequence", () => { seq.dispose(); }); }); - }); context("Sequence callback", () => { - it("invokes the callback after it's started", () => { let invoked = false; return Offline(({ transport }) => { @@ -174,9 +169,15 @@ describe("Sequence", () => { it("can be scheduled to stop", () => { let invoked = 0; return Offline(({ transport }) => { - const seq = new Sequence(() => { - invoked++; - }, [0, 1], 0.1).start(0).stop(0.5); + const seq = new Sequence( + () => { + invoked++; + }, + [0, 1], + 0.1 + ) + .start(0) + .stop(0.5); transport.start(); }, 1).then(() => { expect(invoked).to.equal(6); @@ -187,12 +188,15 @@ describe("Sequence", () => { let invoked = false; return Offline(({ transport }) => { const now = 0.1; - const seq = new Sequence((time) => { - expect(time).to.be.a("number"); - expect(time - now).to.be.closeTo(0.3, 0.01); - seq.dispose(); - invoked = true; - }, [0.5]); + const seq = new Sequence( + (time) => { + expect(time).to.be.a("number"); + expect(time - now).to.be.closeTo(0.3, 0.01); + seq.dispose(); + invoked = true; + }, + [0.5] + ); seq.start(0.3); transport.start(now); }, 0.5).then(() => { @@ -203,12 +207,15 @@ describe("Sequence", () => { it("passes in the value to the callback", () => { let invoked = false; return Offline(({ transport }) => { - const seq = new Sequence((time, thing) => { - expect(time).to.be.a("number"); - expect(thing).to.equal("thing"); - seq.dispose(); - invoked = true; - }, ["thing"]).start(); + const seq = new Sequence( + (time, thing) => { + expect(time).to.be.a("number"); + expect(thing).to.equal("thing"); + seq.dispose(); + invoked = true; + }, + ["thing"] + ).start(); transport.start(); }, 0.1).then(() => { expect(invoked).to.be.true; @@ -218,10 +225,14 @@ describe("Sequence", () => { it("invokes the scheduled events in the right order", () => { let count = 0; return Offline(({ transport }) => { - const seq = new Sequence((time, value) => { - expect(value).to.equal(count); - count++; - }, [0, [1, 2], [3, 4]], "16n").start(); + const seq = new Sequence( + (time, value) => { + expect(value).to.equal(count); + count++; + }, + [0, [1, 2], [3, 4]], + "16n" + ).start(); seq.loop = false; transport.start(0); }, 0.5).then(() => { @@ -233,11 +244,22 @@ describe("Sequence", () => { let count = 0; return Offline(({ transport }) => { const eighth = transport.toSeconds("8n"); - const times = [0, eighth, eighth * 1.5, eighth * 2, eighth * (2 + 1 / 3), eighth * (2 + 2 / 3)]; - const seq = new Sequence((time) => { - expect(time).to.be.closeTo(times[count], 0.01); - count++; - }, [0, [1, 2], [3, 4, 5]], "8n").start(0); + const times = [ + 0, + eighth, + eighth * 1.5, + eighth * 2, + eighth * (2 + 1 / 3), + eighth * (2 + 2 / 3), + ]; + const seq = new Sequence( + (time) => { + expect(time).to.be.closeTo(times[count], 0.01); + count++; + }, + [0, [1, 2], [3, 4, 5]], + "8n" + ).start(0); seq.loop = false; transport.start(0); }, 0.8).then(() => { @@ -250,10 +272,14 @@ describe("Sequence", () => { return Offline(({ transport }) => { const eighth = transport.toSeconds("8n"); const times = [0, eighth * 2.5]; - const seq = new Sequence((time, value) => { - expect(time).to.be.closeTo(times[count], 0.01); - count++; - }, [0, null, [null, 1]], "8n").start(0); + const seq = new Sequence( + (time, value) => { + expect(time).to.be.closeTo(times[count], 0.01); + count++; + }, + [0, null, [null, 1]], + "8n" + ).start(0); seq.loop = false; transport.start(0); }, 0.8).then(() => { @@ -266,10 +292,14 @@ describe("Sequence", () => { return Offline(({ transport }) => { const eighth = transport.toSeconds("8n"); const times = [0, eighth, eighth * 1.5, eighth * 1.75]; - const seq = new Sequence((time) => { - expect(time).to.be.closeTo(times[count], 0.01); - count++; - }, [0, [1, [2, 3]]], "8n").start(0); + const seq = new Sequence( + (time) => { + expect(time).to.be.closeTo(times[count], 0.01); + count++; + }, + [0, [1, [2, 3]]], + "8n" + ).start(0); seq.loop = false; transport.start(0); }, 0.7).then(() => { @@ -309,11 +339,9 @@ describe("Sequence", () => { transport.start(); }, 0.5); }); - }); context("Looping", () => { - it("can be set to loop", () => { let callCount = 0; return Offline(({ transport }) => { @@ -381,7 +409,6 @@ describe("Sequence", () => { }); context("playbackRate", () => { - it("can adjust the playbackRate", () => { let invoked = false; return Offline(({ transport }) => { @@ -409,7 +436,10 @@ describe("Sequence", () => { return Offline(({ transport }) => { let lastCall; new Sequence({ - events: [[0, 1], [2, 3]], + events: [ + [0, 1], + [2, 3], + ], playbackRate: 0.5, subdivision: "8n", callback(time): void { diff --git a/Tone/event/Sequence.ts b/Tone/event/Sequence.ts index 1c6ded00..7fe71339 100644 --- a/Tone/event/Sequence.ts +++ b/Tone/event/Sequence.ts @@ -1,9 +1,16 @@ -import { TicksClass } from "../core/type/Ticks"; -import { NormalRange, Positive, Seconds, Ticks, Time, TransportTime } from "../core/type/Units"; -import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { isArray, isString } from "../core/util/TypeCheck"; -import { Part } from "./Part"; -import { ToneEvent, ToneEventCallback, ToneEventOptions } from "./ToneEvent"; +import { TicksClass } from "../core/type/Ticks.js"; +import { + NormalRange, + Positive, + Seconds, + Ticks, + Time, + TransportTime, +} from "../core/type/Units.js"; +import { omitFromObject, optionsFromArguments } from "../core/util/Defaults.js"; +import { isArray, isString } from "../core/util/TypeCheck.js"; +import { Part } from "./Part.js"; +import { ToneEvent, ToneEventCallback, ToneEventOptions } from "./ToneEvent.js"; type SequenceEventDescription = Array>; @@ -31,7 +38,6 @@ interface SequenceOptions extends Omit, "value"> { * @category Event */ export class Sequence extends ToneEvent { - readonly name: string = "Sequence"; /** @@ -65,13 +71,22 @@ export class Sequence extends ToneEvent { constructor( callback?: ToneEventCallback, events?: SequenceEventDescription, - subdivision?: Time, + subdivision?: Time ); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"])); - const options = optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]); + super( + optionsFromArguments(Sequence.getDefaults(), arguments, [ + "callback", + "events", + "subdivision", + ]) + ); + const options = optionsFromArguments( + Sequence.getDefaults(), + arguments, + ["callback", "events", "subdivision"] + ); this._subdivision = this.toTicks(options.subdivision); @@ -89,13 +104,16 @@ export class Sequence extends ToneEvent { } static getDefaults(): SequenceOptions { - return Object.assign(omitFromObject(ToneEvent.getDefaults(), ["value"]), { - events: [], - loop: true, - loopEnd: 0, - loopStart: 0, - subdivision: "8n", - }); + return Object.assign( + omitFromObject(ToneEvent.getDefaults(), ["value"]), + { + events: [], + loop: true, + loopEnd: 0, + loopStart: 0, + subdivision: "8n", + } + ); } /** @@ -157,7 +175,11 @@ export class Sequence extends ToneEvent { // property is index in this case return target[property]; }, - set: (target: any[], property: PropertyKey, value: any): boolean => { + set: ( + target: any[], + property: PropertyKey, + value: any + ): boolean => { if (isString(property) && isFinite(parseInt(property, 10))) { if (isArray(value)) { target[property] = this._createSequence(value); @@ -179,7 +201,11 @@ export class Sequence extends ToneEvent { */ private _eventsUpdated(): void { this._part.clear(); - this._rescheduleSequence(this._eventsArray, this._subdivision, this.startOffset); + this._rescheduleSequence( + this._eventsArray, + this._subdivision, + this.startOffset + ); // update the loopEnd this.loopEnd = this.loopEnd; } @@ -187,13 +213,25 @@ export class Sequence extends ToneEvent { /** * reschedule all of the events that need to be rescheduled */ - private _rescheduleSequence(sequence: any[], subdivision: Ticks, startOffset: Ticks): void { + private _rescheduleSequence( + sequence: any[], + subdivision: Ticks, + startOffset: Ticks + ): void { sequence.forEach((value, index) => { - const eventOffset = index * (subdivision) + startOffset; + const eventOffset = index * subdivision + startOffset; if (isArray(value)) { - this._rescheduleSequence(value, subdivision / value.length, eventOffset); + this._rescheduleSequence( + value, + subdivision / value.length, + eventOffset + ); } else { - const startTime = new TicksClass(this.context, eventOffset, "i").toSeconds(); + const startTime = new TicksClass( + this.context, + eventOffset, + "i" + ).toSeconds(); this._part.add(startTime, value); } }); @@ -205,7 +243,10 @@ export class Sequence extends ToneEvent { * @return The time of that index */ private _indexTime(index: number): Seconds { - return new TicksClass(this.context, index * (this._subdivision) + this.startOffset).toSeconds(); + return new TicksClass( + this.context, + index * this._subdivision + this.startOffset + ).toSeconds(); } /** diff --git a/Tone/event/ToneEvent.test.ts b/Tone/event/ToneEvent.test.ts index 573f9fd6..1b6e3be3 100644 --- a/Tone/event/ToneEvent.test.ts +++ b/Tone/event/ToneEvent.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline, whenBetween } from "test/helper/Offline"; -import { Time } from "Tone/core/type/Time"; -import { noOp } from "Tone/core/util/Interface"; -import { ToneEvent } from "./ToneEvent"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Offline, whenBetween } from "../../test/helper/Offline.js"; +import { Time } from "../core/type/Time.js"; +import { noOp } from "../core/util/Interface.js"; +import { ToneEvent } from "./ToneEvent.js"; describe("ToneEvent", () => { - BasicTests(ToneEvent); context("Constructor", () => { - it("takes a callback and a value", () => { return Offline(() => { const callback = noOp; @@ -51,7 +49,6 @@ describe("ToneEvent", () => { }); context("Get/Set", () => { - it("can set values with object", () => { return Offline(() => { const callback = noOp; @@ -85,7 +82,6 @@ describe("ToneEvent", () => { }); context("ToneEvent callback", () => { - it("does not invoke get invoked until started", () => { return Offline(({ transport }) => { const event = new ToneEvent(() => { @@ -152,7 +148,6 @@ describe("ToneEvent", () => { }); it("can trigger with some probability", () => { - return Offline(({ transport }) => { const note = new ToneEvent(() => { throw new Error("shouldn't call this callback"); @@ -165,7 +160,6 @@ describe("ToneEvent", () => { }); context("Scheduling", () => { - it("can be started and stopped multiple times", () => { return Offline(({ transport }) => { const note = new ToneEvent().start(0).stop(0.2).start(0.4); @@ -185,7 +179,6 @@ describe("ToneEvent", () => { }); it("restarts when transport is restarted", () => { - return Offline(({ transport }) => { const note = new ToneEvent().start(0).stop(0.4); transport.start(0).stop(0.5).start(0.55); @@ -231,11 +224,9 @@ describe("ToneEvent", () => { }; }, 0.5); }); - }); context("Looping", () => { - it("can be set to loop", () => { let callCount = 0; return Offline(({ transport }) => { @@ -250,7 +241,6 @@ describe("ToneEvent", () => { }, 0.8).then(() => { expect(callCount).to.equal(4); }); - }); it("can be set to loop at a specific interval", () => { @@ -355,17 +345,27 @@ describe("ToneEvent", () => { it("can be started and stopped multiple times", () => { return Offline(({ transport }) => { - const eventTimes = [0.3, 0.39, 0.9, 0.99, 1.3, 1.39, 1.48, 1.57, 1.66, 1.75, 1.84]; + const eventTimes = [ + 0.3, 0.39, 0.9, 0.99, 1.3, 1.39, 1.48, 1.57, 1.66, 1.75, + 1.84, + ]; let eventTimeIndex = 0; new ToneEvent({ loop: true, loopEnd: 0.09, callback(time): void { expect(eventTimes.length).to.be.gt(eventTimeIndex); - expect(eventTimes[eventTimeIndex]).to.be.closeTo(time, 0.05); + expect(eventTimes[eventTimeIndex]).to.be.closeTo( + time, + 0.05 + ); eventTimeIndex++; }, - }).start(0.1).stop(0.2).start(0.5).stop(1.1); + }) + .start(0.1) + .stop(0.2) + .start(0.5) + .stop(1.1); transport.start(0.2).stop(0.5).start(0.8); }, 2); }); @@ -423,7 +423,6 @@ describe("ToneEvent", () => { }); context("playbackRate and humanize", () => { - it("can adjust the playbackRate", () => { return Offline(({ transport }) => { let lastCall; @@ -460,7 +459,6 @@ describe("ToneEvent", () => { }).start(0); transport.start(); }, 1.2); - }); it("can humanize the callback by some amount", () => { @@ -480,6 +478,5 @@ describe("ToneEvent", () => { transport.start(); }, 0.6); }); - }); }); diff --git a/Tone/event/ToneEvent.ts b/Tone/event/ToneEvent.ts index 4c299c0e..de698d2c 100644 --- a/Tone/event/ToneEvent.ts +++ b/Tone/event/ToneEvent.ts @@ -1,12 +1,25 @@ -import "../core/clock/Transport"; -import { ToneWithContext, ToneWithContextOptions } from "../core/context/ToneWithContext"; -import { TicksClass } from "../core/type/Ticks"; -import { TransportTimeClass } from "../core/type/TransportTime"; -import { NormalRange, Positive, Seconds, Ticks, Time, TransportTime } from "../core/type/Units"; -import { defaultArg, optionsFromArguments } from "../core/util/Defaults"; -import { noOp } from "../core/util/Interface"; -import { BasicPlaybackState, StateTimeline } from "../core/util/StateTimeline"; -import { isBoolean, isNumber } from "../core/util/TypeCheck"; +import "../core/clock/Transport.js"; +import { + ToneWithContext, + ToneWithContextOptions, +} from "../core/context/ToneWithContext.js"; +import { TicksClass } from "../core/type/Ticks.js"; +import { TransportTimeClass } from "../core/type/TransportTime.js"; +import { + NormalRange, + Positive, + Seconds, + Ticks, + Time, + TransportTime, +} from "../core/type/Units.js"; +import { defaultArg, optionsFromArguments } from "../core/util/Defaults.js"; +import { noOp } from "../core/util/Interface.js"; +import { + BasicPlaybackState, + StateTimeline, +} from "../core/util/StateTimeline.js"; +import { isBoolean, isNumber } from "../core/util/TypeCheck.js"; export type ToneEventCallback = (time: Seconds, value: T) => void; @@ -40,8 +53,9 @@ export interface ToneEventOptions extends ToneWithContextOptions { * chordEvent.loopEnd = "1m"; * @category Event */ -export class ToneEvent extends ToneWithContext> { - +export class ToneEvent extends ToneWithContext< + ToneEventOptions +> { readonly name: string = "ToneEvent"; /** @@ -110,9 +124,17 @@ export class ToneEvent extends ToneWithContext, value?: ValueType); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(ToneEvent.getDefaults(), arguments, ["callback", "value"])); - const options = optionsFromArguments(ToneEvent.getDefaults(), arguments, ["callback", "value"]); + super( + optionsFromArguments(ToneEvent.getDefaults(), arguments, [ + "callback", + "value", + ]) + ); + const options = optionsFromArguments( + ToneEvent.getDefaults(), + arguments, + ["callback", "value"] + ); this._loop = options.loop; this.callback = options.callback; @@ -150,30 +172,48 @@ export class ToneEvent extends ToneWithContext { + this._state.forEachFrom(after, (event) => { let duration; if (event.state === "started") { if (event.id !== -1) { this.context.transport.clear(event.id); } - const startTick = event.time + Math.round(this.startOffset / this._playbackRate); - if (this._loop === true || isNumber(this._loop) && this._loop > 1) { + const startTick = + event.time + + Math.round(this.startOffset / this._playbackRate); + if ( + this._loop === true || + (isNumber(this._loop) && this._loop > 1) + ) { duration = Infinity; if (isNumber(this._loop)) { - duration = (this._loop) * this._getLoopDuration(); + duration = this._loop * this._getLoopDuration(); } const nextEvent = this._state.getAfter(startTick); if (nextEvent !== null) { - duration = Math.min(duration, nextEvent.time - startTick); + duration = Math.min( + duration, + nextEvent.time - startTick + ); } if (duration !== Infinity) { duration = new TicksClass(this.context, duration); } - const interval = new TicksClass(this.context, this._getLoopDuration()); + const interval = new TicksClass( + this.context, + this._getLoopDuration() + ); event.id = this.context.transport.scheduleRepeat( - this._tick.bind(this), interval, new TicksClass(this.context, startTick), duration); + this._tick.bind(this), + interval, + new TicksClass(this.context, startTick), + duration + ); } else { - event.id = this.context.transport.schedule(this._tick.bind(this), new TicksClass(this.context, startTick)); + event.id = this.context.transport.schedule( + this._tick.bind(this), + new TicksClass(this.context, startTick) + ); } } }); @@ -183,7 +223,9 @@ export class ToneEvent extends ToneWithContext extends ToneWithContext { + this._state.forEachFrom(ticks, (event) => { this.context.transport.clear(event.id); }); this._state.cancel(ticks); diff --git a/Tone/event/index.ts b/Tone/event/index.ts index ba87ca2d..940ad7e5 100644 --- a/Tone/event/index.ts +++ b/Tone/event/index.ts @@ -1,5 +1,5 @@ -export * from "./Loop"; -export * from "./Part"; -export * from "./Pattern"; -export * from "./Sequence"; -export * from "./ToneEvent"; +export * from "./Loop.js"; +export * from "./Part.js"; +export * from "./Pattern.js"; +export * from "./Sequence.js"; +export * from "./ToneEvent.js"; diff --git a/Tone/fromContext.test.ts b/Tone/fromContext.test.ts index 6f29b98b..82871e83 100644 --- a/Tone/fromContext.test.ts +++ b/Tone/fromContext.test.ts @@ -1,9 +1,8 @@ import { expect } from "chai"; -import { OfflineContext } from "./core/context/OfflineContext"; -import { fromContext } from "./fromContext"; +import { OfflineContext } from "./core/context/OfflineContext.js"; +import { fromContext } from "./fromContext.js"; describe("fromContext", () => { - let context: OfflineContext; before(() => { @@ -25,5 +24,4 @@ describe("fromContext", () => { const tone = fromContext(context); expect(tone.Time("+0.5").valueOf()).to.equal(0.5); }); - }); diff --git a/Tone/fromContext.ts b/Tone/fromContext.ts index afc7d852..bce5272f 100644 --- a/Tone/fromContext.ts +++ b/Tone/fromContext.ts @@ -1,18 +1,21 @@ -import * as Classes from "./classes"; -import { TransportClass } from "./core/clock/Transport"; -import { Context } from "./core/context/Context"; -import { ListenerClass } from "./core/context/Listener"; -import { DestinationClass } from "./core/context/Destination"; -import { FrequencyClass } from "./core/type/Frequency"; -import { MidiClass } from "./core/type/Midi"; -import { TicksClass } from "./core/type/Ticks"; -import { TimeClass } from "./core/type/Time"; -import { TransportTimeClass } from "./core/type/TransportTime"; -import { isDefined, isFunction } from "./core/util/TypeCheck"; -import { omitFromObject } from "./core/util/Defaults"; -import { DrawClass } from "./core/util/Draw"; +import * as Classes from "./classes.js"; +import { TransportClass } from "./core/clock/Transport.js"; +import { Context } from "./core/context/Context.js"; +import { ListenerClass } from "./core/context/Listener.js"; +import { DestinationClass } from "./core/context/Destination.js"; +import { FrequencyClass } from "./core/type/Frequency.js"; +import { MidiClass } from "./core/type/Midi.js"; +import { TicksClass } from "./core/type/Ticks.js"; +import { TimeClass } from "./core/type/Time.js"; +import { TransportTimeClass } from "./core/type/TransportTime.js"; +import { isDefined, isFunction } from "./core/util/TypeCheck.js"; +import { omitFromObject } from "./core/util/Defaults.js"; +import { DrawClass } from "./core/util/Draw.js"; -type ClassesWithoutSingletons = Omit; +type ClassesWithoutSingletons = Omit< + typeof Classes, + "Transport" | "Destination" | "Draw" +>; /** * The exported Tone object. Contains all of the classes that default @@ -40,9 +43,10 @@ function bindTypeClass(context: Context, type) { * @param context The context to bind all of the nodes to */ export function fromContext(context: Context): ToneObject { - const classesWithContext: Partial = {}; - Object.keys(omitFromObject(Classes, ["Transport", "Destination", "Draw"])).map(key => { + Object.keys( + omitFromObject(Classes, ["Transport", "Destination", "Draw"]) + ).map((key) => { const cls = Classes[key]; if (isDefined(cls) && isFunction(cls.getDefaults)) { classesWithContext[key] = class ToneFromContextNode extends cls { diff --git a/Tone/index.test.ts b/Tone/index.test.ts index 16bcb6fc..aac83b57 100644 --- a/Tone/index.test.ts +++ b/Tone/index.test.ts @@ -1,12 +1,11 @@ -import * as Tone from "./index"; +import * as Tone from "./index.js"; import { expect } from "chai"; -import { DestinationClass } from "./core/context/Destination"; -import { Context } from "./core/context/Context"; -import { TransportClass } from "./core/clock/Transport"; -import { DrawClass } from "./core/util/Draw"; +import { DestinationClass } from "./core/context/Destination.js"; +import { Context } from "./core/context/Context.js"; +import { TransportClass } from "./core/clock/Transport.js"; +import { DrawClass } from "./core/util/Draw.js"; describe("Tone", () => { - it("has 'now' and 'immediate' methods", () => { expect(Tone.now).to.be.a("function"); expect(Tone.now()).to.be.a("number"); @@ -43,7 +42,7 @@ describe("Tone", () => { await ctx.close(); Tone.setContext(origContext); }); - + it("can set the global context from a raw offline context", async () => { const ctx = new OfflineAudioContext(2, 44100, 44100); const origContext = Tone.getContext(); diff --git a/Tone/index.ts b/Tone/index.ts index d95430de..ea59c99e 100644 --- a/Tone/index.ts +++ b/Tone/index.ts @@ -1,16 +1,16 @@ -export { getContext, setContext } from "./core/Global"; -import { Context } from "./core/context/Context"; -export * from "./classes"; -export * from "./version"; -import { getContext } from "./core/Global"; -import { ToneAudioBuffer } from "./core/context/ToneAudioBuffer"; -export { start } from "./core/Global"; -import { Seconds } from "./core/type/Units"; -export { supported } from "./core/context/AudioContext"; -import type { TransportClass } from "./core/clock/Transport"; -import type { DestinationClass } from "./core/context/Destination"; -import type { DrawClass } from "./core/util/Draw"; -import type { ListenerClass } from "./core/context/Listener"; +export { getContext, setContext } from "./core/Global.js"; +import { Context } from "./core/context/Context.js"; +export * from "./classes.js"; +export * from "./version.js"; +import { getContext } from "./core/Global.js"; +import { ToneAudioBuffer } from "./core/context/ToneAudioBuffer.js"; +export { start } from "./core/Global.js"; +import { Seconds } from "./core/type/Units.js"; +export { supported } from "./core/context/AudioContext.js"; +import type { TransportClass } from "./core/clock/Transport.js"; +import type { DestinationClass } from "./core/context/Destination.js"; +import type { DrawClass } from "./core/util/Draw.js"; +import type { ListenerClass } from "./core/context/Listener.js"; /** * The current audio context time of the global {@link BaseContext}. @@ -119,8 +119,8 @@ export function loaded() { } // this fills in name changes from 13.x to 14.x -import { ToneAudioBuffers } from "./core/context/ToneAudioBuffers"; -import { ToneBufferSource } from "./source/buffer/ToneBufferSource"; +import { ToneAudioBuffers } from "./core/context/ToneAudioBuffers.js"; +import { ToneBufferSource } from "./source/buffer/ToneBufferSource.js"; /** @deprecated Use {@link ToneAudioBuffer} */ export const Buffer: typeof ToneAudioBuffer = ToneAudioBuffer; /** @deprecated Use {@link ToneAudioBuffers} */ diff --git a/Tone/instrument/AMSynth.test.ts b/Tone/instrument/AMSynth.test.ts index 1c4cef6b..6e75ef7a 100644 --- a/Tone/instrument/AMSynth.test.ts +++ b/Tone/instrument/AMSynth.test.ts @@ -1,28 +1,30 @@ -import { AMSynth } from "./AMSynth"; -import { BasicTests } from "test/helper/Basic"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { AMSynth } from "./AMSynth.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; +import { Offline } from "../../test/helper/Offline.js"; describe("AMSynth", () => { - BasicTests(AMSynth); InstrumentTest(AMSynth, "C4"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new AMSynth().toDestination(); - synth.triggerAttackRelease("C5", 0.1, 0.1); - }, "amSynth.wav", 0.15); + return CompareToFile( + () => { + const synth = new AMSynth().toDestination(); + synth.triggerAttackRelease("C5", 0.1, 0.1); + }, + "amSynth.wav", + 0.15 + ); }); context("API", () => { - it("invokes the onsilence callback", (done) => { Offline(() => { const amSynth = new AMSynth({ - onsilence: () => done() + onsilence: () => done(), }); amSynth.triggerAttackRelease("C3", 0.2, 0); }, 2); @@ -52,11 +54,11 @@ describe("AMSynth", () => { it("can be constructed with an options object", () => { const amSynth = new AMSynth({ oscillator: { - type: "square" + type: "square", }, modulationEnvelope: { - attack: 0.3 - } + attack: 0.3, + }, }); expect(amSynth.modulationEnvelope.attack).to.equal(0.3); expect(amSynth.oscillator.type).to.equal("square"); @@ -67,13 +69,11 @@ describe("AMSynth", () => { const amSynth = new AMSynth(); amSynth.set({ harmonicity: 1.5, - detune: 1200 + detune: 1200, }); expect(amSynth.get().harmonicity).to.equal(1.5); expect(amSynth.get().detune).to.be.closeTo(1200, 1); amSynth.dispose(); }); - }); }); - diff --git a/Tone/instrument/AMSynth.ts b/Tone/instrument/AMSynth.ts index 22dffe1f..3ce61be0 100644 --- a/Tone/instrument/AMSynth.ts +++ b/Tone/instrument/AMSynth.ts @@ -1,7 +1,7 @@ -import { AudioToGain } from "../signal/AudioToGain"; -import { RecursivePartial } from "../core/util/Interface"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { ModulationSynth, ModulationSynthOptions } from "./ModulationSynth"; +import { AudioToGain } from "../signal/AudioToGain.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { ModulationSynth, ModulationSynthOptions } from "./ModulationSynth.js"; export type AMSynthOptions = ModulationSynthOptions; @@ -15,11 +15,10 @@ export type AMSynthOptions = ModulationSynthOptions; * @example * const synth = new Tone.AMSynth().toDestination(); * synth.triggerAttackRelease("C4", "4n"); - * + * * @category Instrument */ export class AMSynth extends ModulationSynth { - readonly name: string = "AMSynth"; /** diff --git a/Tone/instrument/DuoSynth.test.ts b/Tone/instrument/DuoSynth.test.ts index 8de040de..aad34171 100644 --- a/Tone/instrument/DuoSynth.test.ts +++ b/Tone/instrument/DuoSynth.test.ts @@ -1,46 +1,48 @@ -import { BasicTests } from "test/helper/Basic"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { DuoSynth } from "./DuoSynth"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { DuoSynth } from "./DuoSynth.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; import { expect } from "chai"; -import { MonophonicTest } from "test/helper/MonophonicTests"; +import { MonophonicTest } from "../../test/helper/MonophonicTests.js"; describe("DuoSynth", () => { - BasicTests(DuoSynth); MonophonicTest(DuoSynth, "C4"); InstrumentTest(DuoSynth, "C4", { voice0: { oscillator: { - type: "square" + type: "square", }, envelope: { decay: 0.1, sustain: 0.5, - release: 0.2 - } + release: 0.2, + }, }, voice1: { oscillator: { - type: "square" + type: "square", }, envelope: { decay: 0.1, sustain: 0.5, - release: 0.3 - } - } + release: 0.3, + }, + }, }); it("matches a file", () => { - return CompareToFile(() => { - const synth = new DuoSynth().toDestination(); - synth.triggerAttackRelease("C5", 0.1, 0.1); - }, "duoSynth.wav", 0.05); + return CompareToFile( + () => { + const synth = new DuoSynth().toDestination(); + synth.triggerAttackRelease("C5", 0.1, 0.1); + }, + "duoSynth.wav", + 0.07 + ); }); context("API", () => { - it("can get and set voice0 attributes", () => { const duoSynth = new DuoSynth(); duoSynth.voice0.oscillator.type = "triangle"; @@ -73,9 +75,9 @@ describe("DuoSynth", () => { const duoSynth = new DuoSynth({ voice0: { filter: { - rolloff: -24 - } - } + rolloff: -24, + }, + }, }); expect(duoSynth.voice0.filter.rolloff).to.equal(-24); duoSynth.dispose(); @@ -84,12 +86,10 @@ describe("DuoSynth", () => { it("can get/set attributes", () => { const duoSynth = new DuoSynth(); duoSynth.set({ - harmonicity: 1.5 + harmonicity: 1.5, }); expect(duoSynth.get().harmonicity).to.equal(1.5); duoSynth.dispose(); }); - }); }); - diff --git a/Tone/instrument/DuoSynth.ts b/Tone/instrument/DuoSynth.ts index 8e8f616f..22d52c37 100644 --- a/Tone/instrument/DuoSynth.ts +++ b/Tone/instrument/DuoSynth.ts @@ -1,13 +1,23 @@ -import { Monophonic, MonophonicOptions } from "./Monophonic"; -import { MonoSynth, MonoSynthOptions } from "./MonoSynth"; -import { Signal } from "../signal/Signal"; -import { readOnly, RecursivePartial } from "../core/util/Interface"; -import { LFO } from "../source/oscillator/LFO"; -import { Gain, } from "../core/context/Gain"; -import { Multiply } from "../signal/Multiply"; -import { Frequency, NormalRange, Positive, Seconds, Time } from "../core/type/Units"; -import { deepMerge, omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { Param } from "../core/context/Param"; +import { Monophonic, MonophonicOptions } from "./Monophonic.js"; +import { MonoSynth, MonoSynthOptions } from "./MonoSynth.js"; +import { Signal } from "../signal/Signal.js"; +import { readOnly, RecursivePartial } from "../core/util/Interface.js"; +import { LFO } from "../source/oscillator/LFO.js"; +import { Gain } from "../core/context/Gain.js"; +import { Multiply } from "../signal/Multiply.js"; +import { + Frequency, + NormalRange, + Positive, + Seconds, + Time, +} from "../core/type/Units.js"; +import { + deepMerge, + omitFromObject, + optionsFromArguments, +} from "../core/util/Defaults.js"; +import { Param } from "../core/context/Param.js"; export interface DuoSynthOptions extends MonophonicOptions { voice0: Omit; @@ -26,7 +36,6 @@ export interface DuoSynthOptions extends MonophonicOptions { * @category Instrument */ export class DuoSynth extends Monophonic { - readonly name: string = "DuoSynth"; readonly frequency: Signal<"frequency">; @@ -78,13 +87,17 @@ export class DuoSynth extends Monophonic { super(optionsFromArguments(DuoSynth.getDefaults(), arguments)); const options = optionsFromArguments(DuoSynth.getDefaults(), arguments); - this.voice0 = new MonoSynth(Object.assign(options.voice0, { - context: this.context, - onsilence: () => this.onsilence(this) - })); - this.voice1 = new MonoSynth(Object.assign(options.voice1, { - context: this.context, - })); + this.voice0 = new MonoSynth( + Object.assign(options.voice0, { + context: this.context, + onsilence: () => this.onsilence(this), + }) + ); + this.voice1 = new MonoSynth( + Object.assign(options.voice1, { + context: this.context, + }) + ); this.harmonicity = new Multiply({ context: this.context, @@ -96,7 +109,7 @@ export class DuoSynth extends Monophonic { frequency: options.vibratoRate, context: this.context, min: -50, - max: 50 + max: 50, }); // start the vibrato immediately this._vibrato.start(); @@ -104,19 +117,19 @@ export class DuoSynth extends Monophonic { this._vibratoGain = new Gain({ context: this.context, units: "normalRange", - gain: options.vibratoAmount + gain: options.vibratoAmount, }); this.vibratoAmount = this._vibratoGain.gain; this.frequency = new Signal({ context: this.context, units: "frequency", - value: 440 + value: 440, }); this.detune = new Signal({ context: this.context, units: "cents", - value: options.detune + value: options.detune, }); // control the two voices frequency @@ -131,12 +144,21 @@ export class DuoSynth extends Monophonic { this.voice0.connect(this.output); this.voice1.connect(this.output); - readOnly(this, ["voice0", "voice1", "frequency", "vibratoAmount", "vibratoRate"]); + readOnly(this, [ + "voice0", + "voice1", + "frequency", + "vibratoAmount", + "vibratoRate", + ]); } getLevelAtTime(time: Time): NormalRange { time = this.toSeconds(time); - return this.voice0.envelope.getValueAtTime(time) + this.voice1.envelope.getValueAtTime(time); + return ( + this.voice0.envelope.getValueAtTime(time) + + this.voice1.envelope.getValueAtTime(time) + ); } static getDefaults(): DuoSynthOptions { @@ -145,38 +167,45 @@ export class DuoSynth extends Monophonic { vibratoRate: 5, harmonicity: 1.5, voice0: deepMerge( - omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), + omitFromObject( + MonoSynth.getDefaults(), + Object.keys(Monophonic.getDefaults()) + ), { filterEnvelope: { attack: 0.01, decay: 0.0, sustain: 1, - release: 0.5 + release: 0.5, }, envelope: { attack: 0.01, decay: 0.0, sustain: 1, - release: 0.5 - } - }), + release: 0.5, + }, + } + ), voice1: deepMerge( - omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), + omitFromObject( + MonoSynth.getDefaults(), + Object.keys(Monophonic.getDefaults()) + ), { - filterEnvelope: { attack: 0.01, decay: 0.0, sustain: 1, - release: 0.5 + release: 0.5, }, envelope: { attack: 0.01, decay: 0.0, sustain: 1, - release: 0.5 - } - }), + release: 0.5, + }, + } + ), }) as unknown as DuoSynthOptions; } /** @@ -213,4 +242,3 @@ export class DuoSynth extends Monophonic { return this; } } - diff --git a/Tone/instrument/FMSynth.test.ts b/Tone/instrument/FMSynth.test.ts index 40c32dd5..c73f473d 100644 --- a/Tone/instrument/FMSynth.test.ts +++ b/Tone/instrument/FMSynth.test.ts @@ -1,20 +1,23 @@ import { expect } from "chai"; -import { FMSynth } from "./FMSynth"; -import { BasicTests } from "test/helper/Basic"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Offline } from "test/helper/Offline"; +import { FMSynth } from "./FMSynth.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { Offline } from "../../test/helper/Offline.js"; describe("FMSynth", () => { - BasicTests(FMSynth); InstrumentTest(FMSynth, "C4"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new FMSynth().toDestination(); - synth.triggerAttackRelease("G4", 0.1, 0.05); - }, "fmSynth.wav", 0.06); + return CompareToFile( + () => { + const synth = new FMSynth().toDestination(); + synth.triggerAttackRelease("G4", 0.1, 0.05); + }, + "fmSynth.wav", + 0.08 + ); }); context("API", () => { @@ -28,7 +31,7 @@ describe("FMSynth", () => { it("invokes the onsilence callback", (done) => { Offline(() => { const synth = new FMSynth({ - onsilence: () => done() + onsilence: () => done(), }); synth.triggerAttackRelease("C3", 0.2, 0); }, 2); @@ -51,8 +54,8 @@ describe("FMSynth", () => { it("can be constructed with an options object", () => { const fmSynth = new FMSynth({ envelope: { - release: 0.3 - } + release: 0.3, + }, }); expect(fmSynth.envelope.release).to.equal(0.3); fmSynth.dispose(); @@ -62,7 +65,7 @@ describe("FMSynth", () => { const fmSynth = new FMSynth(); fmSynth.set({ harmonicity: 1.5, - detune: 1200 + detune: 1200, }); expect(fmSynth.get().harmonicity).to.equal(1.5); expect(fmSynth.get().detune).to.be.closeTo(1200, 1); diff --git a/Tone/instrument/FMSynth.ts b/Tone/instrument/FMSynth.ts index ed1f481b..15642519 100644 --- a/Tone/instrument/FMSynth.ts +++ b/Tone/instrument/FMSynth.ts @@ -1,8 +1,8 @@ -import { Positive } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { RecursivePartial } from "../core/util/Interface"; -import { Multiply } from "../signal/Multiply"; -import { ModulationSynth, ModulationSynthOptions } from "./ModulationSynth"; +import { Positive } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { Multiply } from "../signal/Multiply.js"; +import { ModulationSynth, ModulationSynthOptions } from "./ModulationSynth.js"; export interface FMSynthOptions extends ModulationSynthOptions { modulationIndex: Positive; @@ -17,7 +17,7 @@ export interface FMSynthOptions extends ModulationSynthOptions { * @example * const fmSynth = new Tone.FMSynth().toDestination(); * fmSynth.triggerAttackRelease("C5", "4n"); - * + * * @category Instrument */ diff --git a/Tone/instrument/Instrument.ts b/Tone/instrument/Instrument.ts index 24564f92..dd96760c 100644 --- a/Tone/instrument/Instrument.ts +++ b/Tone/instrument/Instrument.ts @@ -1,9 +1,13 @@ -import { Volume } from "../component/channel/Volume"; -import { Param } from "../core/context/Param"; -import { OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { Decibels, Frequency, NormalRange, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; +import { Volume } from "../component/channel/Volume.js"; +import { Param } from "../core/context/Param.js"; +import { + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { Decibels, Frequency, NormalRange, Time } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; export interface InstrumentOptions extends ToneAudioNodeOptions { volume: Decibels; @@ -12,8 +16,9 @@ export interface InstrumentOptions extends ToneAudioNodeOptions { /** * Base-class for all instruments */ -export abstract class Instrument extends ToneAudioNode { - +export abstract class Instrument< + Options extends InstrumentOptions, +> extends ToneAudioNode { /** * The output and volume triming node */ @@ -47,9 +52,11 @@ export abstract class Instrument extends Tone constructor(options?: Partial); constructor() { - super(optionsFromArguments(Instrument.getDefaults(), arguments)); - const options = optionsFromArguments(Instrument.getDefaults(), arguments); + const options = optionsFromArguments( + Instrument.getDefaults(), + arguments + ); this._volume = this.output = new Volume({ context: this.context, @@ -109,7 +116,7 @@ export abstract class Instrument extends Tone * @param timePosition What position the time argument appears in */ protected _syncMethod(method: string, timePosition: number): void { - const originalMethod = this["_original_" + method] = this[method]; + const originalMethod = (this["_original_" + method] = this[method]); this[method] = (...args: any[]) => { const time = args[timePosition]; const id = this.context.transport.schedule((t) => { @@ -124,7 +131,7 @@ export abstract class Instrument extends Tone * Unsync the instrument from the Transport */ unsync(): this { - this._scheduledEvents.forEach(id => this.context.transport.clear(id)); + this._scheduledEvents.forEach((id) => this.context.transport.clear(id)); this._scheduledEvents = []; if (this._synced) { this._synced = false; @@ -150,7 +157,12 @@ export abstract class Instrument extends Tone * // trigger "C4" for the duration of an 8th note * synth.triggerAttackRelease("C4", "8n"); */ - triggerAttackRelease(note: Frequency, duration: Time, time?: Time, velocity?: NormalRange): this { + triggerAttackRelease( + note: Frequency, + duration: Time, + time?: Time, + velocity?: NormalRange + ): this { const computedTime = this.toSeconds(time); const computedDuration = this.toSeconds(duration); this.triggerAttack(note, computedTime, velocity); @@ -164,7 +176,11 @@ export abstract class Instrument extends Tone * @param time the time to trigger the note * @param velocity the velocity to trigger the note (between 0-1) */ - abstract triggerAttack(note: Frequency, time?: Time, velocity?: NormalRange): this; + abstract triggerAttack( + note: Frequency, + time?: Time, + velocity?: NormalRange + ): this; private _original_triggerAttack = this.triggerAttack; /** @@ -175,9 +191,10 @@ export abstract class Instrument extends Tone private _original_triggerRelease = this.triggerRelease; /** - * The release which is scheduled to the timeline. + * The release which is scheduled to the timeline. */ - protected _syncedRelease = (time: number) => this._original_triggerRelease(time); + protected _syncedRelease = (time: number) => + this._original_triggerRelease(time); /** * clean up diff --git a/Tone/instrument/MembraneSynth.test.ts b/Tone/instrument/MembraneSynth.test.ts index 7687de22..2b73a3d4 100644 --- a/Tone/instrument/MembraneSynth.test.ts +++ b/Tone/instrument/MembraneSynth.test.ts @@ -1,34 +1,40 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { MembraneSynth } from "./MembraneSynth"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { MembraneSynth } from "./MembraneSynth.js"; describe("MembraneSynth", () => { - BasicTests(MembraneSynth); InstrumentTest(MembraneSynth, "C2"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new MembraneSynth().toDestination(); - synth.triggerAttackRelease("F#2", 0.1, 0.05); - }, "membraneSynth.wav", 0.5); + return CompareToFile( + () => { + const synth = new MembraneSynth().toDestination(); + synth.triggerAttackRelease("F#2", 0.1, 0.05); + }, + "membraneSynth.wav", + 0.5 + ); }); it("matches another file", () => { - return CompareToFile(() => { - const synth = new MembraneSynth({ - envelope: { - sustain: 0, - }, - }).toDestination(); - synth.triggerAttackRelease("C2", 0.1); - }, "membraneSynth2.wav", 0.5); + return CompareToFile( + () => { + const synth = new MembraneSynth({ + envelope: { + sustain: 0, + }, + }).toDestination(); + synth.triggerAttackRelease("C2", 0.1); + }, + "membraneSynth2.wav", + 0.5 + ); }); context("API", () => { - it("can get and set oscillator attributes", () => { const drumSynth = new MembraneSynth(); drumSynth.oscillator.type = "triangle"; diff --git a/Tone/instrument/MembraneSynth.ts b/Tone/instrument/MembraneSynth.ts index b4a979a0..23ad8523 100644 --- a/Tone/instrument/MembraneSynth.ts +++ b/Tone/instrument/MembraneSynth.ts @@ -1,10 +1,10 @@ -import { FrequencyClass } from "../core/type/Frequency"; -import { Frequency, Positive, Time } from "../core/type/Units"; -import { deepMerge, optionsFromArguments } from "../core/util/Defaults"; -import { readOnly, RecursivePartial } from "../core/util/Interface"; -import { Monophonic } from "./Monophonic"; -import { Synth, SynthOptions } from "./Synth"; -import { range, timeRange } from "../core/util/Decorator"; +import { FrequencyClass } from "../core/type/Frequency.js"; +import { Frequency, Positive, Time } from "../core/type/Units.js"; +import { deepMerge, optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly, RecursivePartial } from "../core/util/Interface.js"; +import { Monophonic } from "./Monophonic.js"; +import { Synth, SynthOptions } from "./Synth.js"; +import { range, timeRange } from "../core/util/Decorator.js"; export interface MembraneSynthOptions extends SynthOptions { pitchDecay: Time; @@ -25,7 +25,6 @@ export interface MembraneSynthOptions extends SynthOptions { * @category Instrument */ export class MembraneSynth extends Synth { - readonly name: string = "MembraneSynth"; /** @@ -52,11 +51,13 @@ export class MembraneSynth extends Synth { /** * @param options the options available for the synth see defaults */ - constructor(options?: RecursivePartial) + constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(MembraneSynth.getDefaults(), arguments)); - const options = optionsFromArguments(MembraneSynth.getDefaults(), arguments); + const options = optionsFromArguments( + MembraneSynth.getDefaults(), + arguments + ); this.pitchDecay = options.pitchDecay; this.octaves = options.octaves; @@ -82,10 +83,15 @@ export class MembraneSynth extends Synth { setNote(note: Frequency | FrequencyClass, time?: Time): this { const seconds = this.toSeconds(time); - const hertz = this.toFrequency(note instanceof FrequencyClass ? note.toFrequency() : note); + const hertz = this.toFrequency( + note instanceof FrequencyClass ? note.toFrequency() : note + ); const maxNote = hertz * this.octaves; this.oscillator.frequency.setValueAtTime(maxNote, seconds); - this.oscillator.frequency.exponentialRampToValueAtTime(hertz, seconds + this.toSeconds(this.pitchDecay)); + this.oscillator.frequency.exponentialRampToValueAtTime( + hertz, + seconds + this.toSeconds(this.pitchDecay) + ); return this; } diff --git a/Tone/instrument/MetalSynth.test.ts b/Tone/instrument/MetalSynth.test.ts index c3b93299..10f49f74 100644 --- a/Tone/instrument/MetalSynth.test.ts +++ b/Tone/instrument/MetalSynth.test.ts @@ -1,26 +1,28 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { MonophonicTest } from "test/helper/MonophonicTests"; -import { MetalSynth } from "./MetalSynth"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { MonophonicTest } from "../../test/helper/MonophonicTests.js"; +import { MetalSynth } from "./MetalSynth.js"; describe("MetalSynth", () => { - BasicTests(MetalSynth); InstrumentTest(MetalSynth, "C2"); MonophonicTest(MetalSynth, "C4"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new MetalSynth().toDestination(); - synth.triggerAttackRelease(200, 0.1, 0.05); - }, "metalSynth.wav", 2); + return CompareToFile( + () => { + const synth = new MetalSynth().toDestination(); + synth.triggerAttackRelease(200, 0.1, 0.05); + }, + "metalSynth.wav", + 2 + ); }); context("API", () => { - it("can be constructed with octave and harmonicity values", () => { const cymbal = new MetalSynth({ harmonicity: 3.1, @@ -61,6 +63,5 @@ describe("MetalSynth", () => { expect(cymbal.resonance).to.be.closeTo(2222, 1); cymbal.dispose(); }); - }); }); diff --git a/Tone/instrument/MetalSynth.ts b/Tone/instrument/MetalSynth.ts index b5f346a2..71f745f6 100644 --- a/Tone/instrument/MetalSynth.ts +++ b/Tone/instrument/MetalSynth.ts @@ -1,28 +1,28 @@ -import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; -import { Filter } from "../component/filter/Filter"; -import { Gain } from "../core/context/Gain"; +import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope.js"; +import { Filter } from "../component/filter/Filter.js"; +import { Gain } from "../core/context/Gain.js"; import { ToneAudioNode, ToneAudioNodeOptions, -} from "../core/context/ToneAudioNode"; +} from "../core/context/ToneAudioNode.js"; import { Frequency, NormalRange, Positive, Seconds, Time, -} from "../core/type/Units"; +} from "../core/type/Units.js"; import { deepMerge, omitFromObject, optionsFromArguments, -} from "../core/util/Defaults"; -import { noOp, RecursivePartial } from "../core/util/Interface"; -import { Multiply } from "../signal/Multiply"; -import { Scale } from "../signal/Scale"; -import { Signal } from "../signal/Signal"; -import { FMOscillator } from "../source/oscillator/FMOscillator"; -import { Monophonic, MonophonicOptions } from "./Monophonic"; +} from "../core/util/Defaults.js"; +import { noOp, RecursivePartial } from "../core/util/Interface.js"; +import { Multiply } from "../signal/Multiply.js"; +import { Scale } from "../signal/Scale.js"; +import { Signal } from "../signal/Signal.js"; +import { FMOscillator } from "../source/oscillator/FMOscillator.js"; +import { Monophonic, MonophonicOptions } from "./Monophonic.js"; export interface MetalSynthOptions extends MonophonicOptions { harmonicity: Positive; diff --git a/Tone/instrument/ModulationSynth.ts b/Tone/instrument/ModulationSynth.ts index b67dd834..af743ff0 100644 --- a/Tone/instrument/ModulationSynth.ts +++ b/Tone/instrument/ModulationSynth.ts @@ -1,17 +1,20 @@ -import { Signal } from "../signal/Signal"; -import { Multiply } from "../signal/Multiply"; -import { Gain } from "../core/context/Gain"; -import { NormalRange, Positive, Seconds, Time } from "../core/type/Units"; -import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { Monophonic } from "./Monophonic"; -import { OmniOscillator } from "../source/oscillator/OmniOscillator"; -import { OmniOscillatorSynthOptions } from "../source/oscillator/OscillatorInterface"; -import { Source } from "../source/Source"; -import { Synth, SynthOptions } from "./Synth"; -import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; -import { readOnly, RecursivePartial } from "../core/util/Interface"; -import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; +import { Signal } from "../signal/Signal.js"; +import { Multiply } from "../signal/Multiply.js"; +import { Gain } from "../core/context/Gain.js"; +import { NormalRange, Positive, Seconds, Time } from "../core/type/Units.js"; +import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { Monophonic } from "./Monophonic.js"; +import { OmniOscillator } from "../source/oscillator/OmniOscillator.js"; +import { OmniOscillatorSynthOptions } from "../source/oscillator/OscillatorInterface.js"; +import { Source } from "../source/Source.js"; +import { Synth, SynthOptions } from "./Synth.js"; +import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope.js"; +import { readOnly, RecursivePartial } from "../core/util/Interface.js"; +import { omitFromObject, optionsFromArguments } from "../core/util/Defaults.js"; export interface ModulationSynthOptions extends SynthOptions { harmonicity: Positive; @@ -21,8 +24,9 @@ export interface ModulationSynthOptions extends SynthOptions { /** * Base class for both AM and FM synths */ -export abstract class ModulationSynth extends Monophonic { - +export abstract class ModulationSynth< + Options extends ModulationSynthOptions, +> extends Monophonic { readonly name: string = "ModulationSynth"; /** @@ -85,7 +89,10 @@ export abstract class ModulationSynth ex constructor(options?: RecursivePartial); constructor() { super(optionsFromArguments(ModulationSynth.getDefaults(), arguments)); - const options = optionsFromArguments(ModulationSynth.getDefaults(), arguments); + const options = optionsFromArguments( + ModulationSynth.getDefaults(), + arguments + ); this._carrier = new Synth({ context: this.context, @@ -113,7 +120,7 @@ export abstract class ModulationSynth ex this.detune = new Signal({ context: this.context, value: options.detune, - units: "cents" + units: "cents", }); this.harmonicity = new Multiply({ context: this.context, @@ -125,7 +132,15 @@ export abstract class ModulationSynth ex gain: 0, }); - readOnly(this, ["frequency", "harmonicity", "oscillator", "envelope", "modulation", "modulationEnvelope", "detune"]); + readOnly(this, [ + "frequency", + "harmonicity", + "oscillator", + "envelope", + "modulation", + "modulationEnvelope", + "detune", + ]); } static getDefaults(): ModulationSynthOptions { @@ -135,10 +150,10 @@ export abstract class ModulationSynth ex omitFromObject(OmniOscillator.getDefaults(), [ ...Object.keys(Source.getDefaults()), "frequency", - "detune" + "detune", ]), { - type: "sine" + type: "sine", } ) as OmniOscillatorSynthOptions, envelope: Object.assign( @@ -150,17 +165,17 @@ export abstract class ModulationSynth ex attack: 0.01, decay: 0.01, sustain: 1, - release: 0.5 + release: 0.5, } ), modulation: Object.assign( omitFromObject(OmniOscillator.getDefaults(), [ ...Object.keys(Source.getDefaults()), "frequency", - "detune" + "detune", ]), { - type: "square" + type: "square", } ) as OmniOscillatorSynthOptions, modulationEnvelope: Object.assign( @@ -172,9 +187,9 @@ export abstract class ModulationSynth ex attack: 0.5, decay: 0.0, sustain: 1, - release: 0.5 + release: 0.5, } - ) + ), }); } diff --git a/Tone/instrument/MonoSynth.test.ts b/Tone/instrument/MonoSynth.test.ts index f8d1c295..8565ea41 100644 --- a/Tone/instrument/MonoSynth.test.ts +++ b/Tone/instrument/MonoSynth.test.ts @@ -1,24 +1,26 @@ -import { BasicTests } from "test/helper/Basic"; -import { MonoSynth } from "./MonoSynth"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { MonoSynth } from "./MonoSynth.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; +import { Offline } from "../../test/helper/Offline.js"; describe("MonoSynth", () => { - BasicTests(MonoSynth); InstrumentTest(MonoSynth, "C4"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new MonoSynth().toDestination(); - synth.triggerAttackRelease("C4", 0.1, 0.05); - }, "monoSynth.wav", 0.01); + return CompareToFile( + () => { + const synth = new MonoSynth().toDestination(); + synth.triggerAttackRelease("C4", 0.1, 0.05); + }, + "monoSynth.wav", + 0.01 + ); }); context("API", () => { - it("can get and set oscillator attributes", () => { const monoSynth = new MonoSynth(); monoSynth.oscillator.type = "triangle"; @@ -50,8 +52,8 @@ describe("MonoSynth", () => { it("can be constructed with an options object", () => { const monoSynth = new MonoSynth({ envelope: { - sustain: 0.3 - } + sustain: 0.3, + }, }); expect(monoSynth.envelope.sustain).to.equal(0.3); monoSynth.dispose(); @@ -61,8 +63,8 @@ describe("MonoSynth", () => { const monoSynth = new MonoSynth(); monoSynth.set({ envelope: { - decay: 0.24 - } + decay: 0.24, + }, }); expect(monoSynth.get().envelope.decay).to.equal(0.24); monoSynth.dispose(); @@ -75,14 +77,12 @@ describe("MonoSynth", () => { attack: 0.1, decay: 0.1, sustain: 0, - } + }, }).toDestination(); synth.triggerAttack("C4", 0); }, 0.5).then((buffer) => { expect(buffer.getTimeOfLastSound()).to.be.closeTo(0.2, 0.01); }); }); - }); }); - diff --git a/Tone/instrument/MonoSynth.ts b/Tone/instrument/MonoSynth.ts index a9efe911..0f3fc0a5 100644 --- a/Tone/instrument/MonoSynth.ts +++ b/Tone/instrument/MonoSynth.ts @@ -1,16 +1,22 @@ -import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; -import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; -import { Filter, FilterOptions } from "../component/filter/Filter"; -import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { readOnly, RecursivePartial } from "../core/util/Interface"; -import { Monophonic, MonophonicOptions } from "../instrument/Monophonic"; -import { OmniOscillator } from "../source/oscillator/OmniOscillator"; -import { Source } from "../source/Source"; -import { FrequencyEnvelope, FrequencyEnvelopeOptions } from "../component/envelope/FrequencyEnvelope"; -import { NormalRange, Seconds, Time } from "../core/type/Units"; -import { Signal } from "../signal/Signal"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { OmniOscillatorSynthOptions } from "../source/oscillator/OscillatorInterface"; +import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope.js"; +import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope.js"; +import { Filter, FilterOptions } from "../component/filter/Filter.js"; +import { omitFromObject, optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly, RecursivePartial } from "../core/util/Interface.js"; +import { Monophonic, MonophonicOptions } from "../instrument/Monophonic.js"; +import { OmniOscillator } from "../source/oscillator/OmniOscillator.js"; +import { Source } from "../source/Source.js"; +import { + FrequencyEnvelope, + FrequencyEnvelopeOptions, +} from "../component/envelope/FrequencyEnvelope.js"; +import { NormalRange, Seconds, Time } from "../core/type/Units.js"; +import { Signal } from "../signal/Signal.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { OmniOscillatorSynthOptions } from "../source/oscillator/OscillatorInterface.js"; export interface MonoSynthOptions extends MonophonicOptions { oscillator: OmniOscillatorSynthOptions; @@ -37,7 +43,6 @@ export interface MonoSynthOptions extends MonophonicOptions { * @category Instrument */ export class MonoSynth extends Monophonic { - readonly name = "MonoSynth"; /** @@ -73,18 +78,29 @@ export class MonoSynth extends Monophonic { constructor(options?: RecursivePartial); constructor() { super(optionsFromArguments(MonoSynth.getDefaults(), arguments)); - const options = optionsFromArguments(MonoSynth.getDefaults(), arguments); - - this.oscillator = new OmniOscillator(Object.assign(options.oscillator, { - context: this.context, - detune: options.detune, - onstop: () => this.onsilence(this), - })); + const options = optionsFromArguments( + MonoSynth.getDefaults(), + arguments + ); + + this.oscillator = new OmniOscillator( + Object.assign(options.oscillator, { + context: this.context, + detune: options.detune, + onstop: () => this.onsilence(this), + }) + ); this.frequency = this.oscillator.frequency; this.detune = this.oscillator.detune; - this.filter = new Filter(Object.assign(options.filter, { context: this.context })); - this.filterEnvelope = new FrequencyEnvelope(Object.assign(options.filterEnvelope, { context: this.context })); - this.envelope = new AmplitudeEnvelope(Object.assign(options.envelope, { context: this.context })); + this.filter = new Filter( + Object.assign(options.filter, { context: this.context }) + ); + this.filterEnvelope = new FrequencyEnvelope( + Object.assign(options.filterEnvelope, { context: this.context }) + ); + this.envelope = new AmplitudeEnvelope( + Object.assign(options.envelope, { context: this.context }) + ); // connect the oscillators to the output this.oscillator.chain(this.filter, this.envelope, this.output); @@ -92,30 +108,46 @@ export class MonoSynth extends Monophonic { // connect the filter envelope this.filterEnvelope.connect(this.filter.frequency); - readOnly(this, ["oscillator", "frequency", "detune", "filter", "filterEnvelope", "envelope"]); + readOnly(this, [ + "oscillator", + "frequency", + "detune", + "filter", + "filterEnvelope", + "envelope", + ]); } static getDefaults(): MonoSynthOptions { return Object.assign(Monophonic.getDefaults(), { envelope: Object.assign( - omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), + omitFromObject( + Envelope.getDefaults(), + Object.keys(ToneAudioNode.getDefaults()) + ), { attack: 0.005, decay: 0.1, release: 1, sustain: 0.9, - }, + } ), filter: Object.assign( - omitFromObject(Filter.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), + omitFromObject( + Filter.getDefaults(), + Object.keys(ToneAudioNode.getDefaults()) + ), { Q: 1, rolloff: -12, type: "lowpass", - }, + } ), filterEnvelope: Object.assign( - omitFromObject(FrequencyEnvelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), + omitFromObject( + FrequencyEnvelope.getDefaults(), + Object.keys(ToneAudioNode.getDefaults()) + ), { attack: 0.6, baseFrequency: 200, @@ -127,10 +159,13 @@ export class MonoSynth extends Monophonic { } ), oscillator: Object.assign( - omitFromObject(OmniOscillator.getDefaults(), Object.keys(Source.getDefaults())), + omitFromObject( + OmniOscillator.getDefaults(), + Object.keys(Source.getDefaults()) + ), { type: "sawtooth", - }, + } ) as OmniOscillatorSynthOptions, }); } diff --git a/Tone/instrument/Monophonic.ts b/Tone/instrument/Monophonic.ts index 9ac57409..27508042 100644 --- a/Tone/instrument/Monophonic.ts +++ b/Tone/instrument/Monophonic.ts @@ -1,10 +1,16 @@ -import { FrequencyClass } from "../core/type/Frequency"; -import { Cents, Frequency, NormalRange, Seconds, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { noOp } from "../core/util/Interface"; -import { Instrument, InstrumentOptions } from "../instrument/Instrument"; -import { Signal } from "../signal/Signal"; -import { timeRange } from "../core/util/Decorator"; +import { FrequencyClass } from "../core/type/Frequency.js"; +import { + Cents, + Frequency, + NormalRange, + Seconds, + Time, +} from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { noOp } from "../core/util/Interface.js"; +import { Instrument, InstrumentOptions } from "../instrument/Instrument.js"; +import { Signal } from "../signal/Signal.js"; +import { timeRange } from "../core/util/Decorator.js"; type onSilenceCallback = (instrument: Monophonic) => void; @@ -17,8 +23,9 @@ export interface MonophonicOptions extends InstrumentOptions { /** * Abstract base class for other monophonic instruments to extend. */ -export abstract class Monophonic extends Instrument { - +export abstract class Monophonic< + Options extends MonophonicOptions, +> extends Instrument { /** * The glide time between notes. */ @@ -42,9 +49,11 @@ export abstract class Monophonic extends Inst constructor(options?: Partial); constructor() { - super(optionsFromArguments(Monophonic.getDefaults(), arguments)); - const options = optionsFromArguments(Monophonic.getDefaults(), arguments); + const options = optionsFromArguments( + Monophonic.getDefaults(), + arguments + ); this.portamento = options.portamento; this.onsilence = options.onsilence; @@ -68,7 +77,11 @@ export abstract class Monophonic extends Inst * // trigger the note a half second from now at half velocity * synth.triggerAttack("C4", "+0.5", 0.5); */ - triggerAttack(note: Frequency | FrequencyClass, time?: Time, velocity: NormalRange = 1): this { + triggerAttack( + note: Frequency | FrequencyClass, + time?: Time, + velocity: NormalRange = 1 + ): this { this.log("triggerAttack", note, time, velocity); const seconds = this.toSeconds(time); this._triggerEnvelopeAttack(seconds, velocity); @@ -95,7 +108,10 @@ export abstract class Monophonic extends Inst /** * Internal method which starts the envelope attack */ - protected abstract _triggerEnvelopeAttack(time: Seconds, velocity: NormalRange): void; + protected abstract _triggerEnvelopeAttack( + time: Seconds, + velocity: NormalRange + ): void; /** * Internal method which starts the envelope release @@ -123,10 +139,15 @@ export abstract class Monophonic extends Inst */ setNote(note: Frequency | FrequencyClass, time?: Time): this { const computedTime = this.toSeconds(time); - const computedFrequency = note instanceof FrequencyClass ? note.toFrequency() : note; + const computedFrequency = + note instanceof FrequencyClass ? note.toFrequency() : note; if (this.portamento > 0 && this.getLevelAtTime(computedTime) > 0.05) { const portTime = this.toSeconds(this.portamento); - this.frequency.exponentialRampTo(computedFrequency, portTime, computedTime); + this.frequency.exponentialRampTo( + computedFrequency, + portTime, + computedTime + ); } else { this.frequency.setValueAtTime(computedFrequency, computedTime); } diff --git a/Tone/instrument/NoiseSynth.test.ts b/Tone/instrument/NoiseSynth.test.ts index b997a9c3..150aadd9 100644 --- a/Tone/instrument/NoiseSynth.test.ts +++ b/Tone/instrument/NoiseSynth.test.ts @@ -1,11 +1,10 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { NoiseSynth } from "./NoiseSynth"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { NoiseSynth } from "./NoiseSynth.js"; describe("NoiseSynth", () => { - BasicTests(NoiseSynth); InstrumentTest(NoiseSynth, undefined, { @@ -17,32 +16,39 @@ describe("NoiseSynth", () => { }); it("matches a file", () => { - return CompareToFile(() => { - const synth = new NoiseSynth({ - envelope: { - attack: 0.01, - decay: 0.4, - }, - }).toDestination(); - synth.triggerAttack(0); - synth.triggerAttack(0.3); - }, "noiseSynth.wav", 4); + return CompareToFile( + () => { + const synth = new NoiseSynth({ + envelope: { + attack: 0.01, + decay: 0.4, + }, + }).toDestination(); + synth.triggerAttack(0); + synth.triggerAttack(0.3); + }, + "noiseSynth.wav", + 4 + ); }); it("matches another file", () => { - return CompareToFile(() => { - const synth = new NoiseSynth({ - envelope: { - attack: 0.01, - decay: 0.4, - }, - }).toDestination(); - synth.triggerAttackRelease(0.1, 0); - }, "noiseSynthRelease.wav", 4); + return CompareToFile( + () => { + const synth = new NoiseSynth({ + envelope: { + attack: 0.01, + decay: 0.4, + }, + }).toDestination(); + synth.triggerAttackRelease(0.1, 0); + }, + "noiseSynthRelease.wav", + 4 + ); }); context("API", () => { - it("can get and set noise type", () => { const noiseSynth = new NoiseSynth(); noiseSynth.noise.type = "pink"; @@ -77,6 +83,5 @@ describe("NoiseSynth", () => { expect(noiseSynth.get().envelope.decay).to.equal(0.24); noiseSynth.dispose(); }); - }); }); diff --git a/Tone/instrument/NoiseSynth.ts b/Tone/instrument/NoiseSynth.ts index 45373f67..c465f141 100644 --- a/Tone/instrument/NoiseSynth.ts +++ b/Tone/instrument/NoiseSynth.ts @@ -1,15 +1,15 @@ -import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; -import { NormalRange, Time } from "../core/type/Units"; -import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { RecursivePartial } from "../core/util/Interface"; -import { Noise, NoiseOptions } from "../source/Noise"; -import { Instrument, InstrumentOptions } from "./Instrument"; +import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope.js"; +import { NormalRange, Time } from "../core/type/Units.js"; +import { omitFromObject, optionsFromArguments } from "../core/util/Defaults.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { Noise, NoiseOptions } from "../source/Noise.js"; +import { Instrument, InstrumentOptions } from "./Instrument.js"; import { ToneAudioNode, ToneAudioNodeOptions, -} from "../core/context/ToneAudioNode"; -import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; -import { Source } from "../source/Source"; +} from "../core/context/ToneAudioNode.js"; +import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope.js"; +import { Source } from "../source/Source.js"; export interface NoiseSynthOptions extends InstrumentOptions { envelope: Omit; diff --git a/Tone/instrument/PluckSynth.test.ts b/Tone/instrument/PluckSynth.test.ts index 979b2e6d..fa4d5dd3 100644 --- a/Tone/instrument/PluckSynth.test.ts +++ b/Tone/instrument/PluckSynth.test.ts @@ -1,33 +1,39 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { PluckSynth } from "./PluckSynth"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { PluckSynth } from "./PluckSynth.js"; describe("PluckSynth", () => { - BasicTests(PluckSynth); InstrumentTest(PluckSynth, "C3"); it("matches a file", () => { - return CompareToFile(() => { - const synth = new PluckSynth().toDestination(); - synth.triggerAttack("C4"); - }, "pluckSynth.wav", 0.02); + return CompareToFile( + () => { + const synth = new PluckSynth().toDestination(); + synth.triggerAttack("C4"); + }, + "pluckSynth.wav", + 0.02 + ); }); it("matches a file with release", () => { - return CompareToFile(() => { - const synth = new PluckSynth({ - resonance: 0.97, - release: 0.2 - }).toDestination(); - synth.triggerAttackRelease("C4", 0.6); - }, "pluckSynth2.wav", 0.06); + return CompareToFile( + () => { + const synth = new PluckSynth({ + resonance: 0.97, + release: 0.2, + }).toDestination(); + synth.triggerAttackRelease("C4", 0.6); + }, + "pluckSynth2.wav", + 0.06 + ); }); - - context("API", () => { + context("API", () => { it("can get and set resonance", () => { const pluck = new PluckSynth(); pluck.resonance = 0.4; diff --git a/Tone/instrument/PluckSynth.ts b/Tone/instrument/PluckSynth.ts index 27bb53ea..ac9e404e 100644 --- a/Tone/instrument/PluckSynth.ts +++ b/Tone/instrument/PluckSynth.ts @@ -1,10 +1,10 @@ -import { Frequency, NormalRange, Time } from "../core/type/Units"; -import { LowpassCombFilter } from "../component/filter/LowpassCombFilter"; -import { deepMerge } from "../core/util/Defaults"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { RecursivePartial } from "../core/util/Interface"; -import { Noise } from "../source/Noise"; -import { Instrument, InstrumentOptions } from "./Instrument"; +import { Frequency, NormalRange, Time } from "../core/type/Units.js"; +import { LowpassCombFilter } from "../component/filter/LowpassCombFilter.js"; +import { deepMerge } from "../core/util/Defaults.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { Noise } from "../source/Noise.js"; +import { Instrument, InstrumentOptions } from "./Instrument.js"; export interface PluckSynthOptions extends InstrumentOptions { attackNoise: number; @@ -24,7 +24,6 @@ export interface PluckSynthOptions extends InstrumentOptions { * @category Instrument */ export class PluckSynth extends Instrument { - readonly name = "PluckSynth"; /** @@ -51,15 +50,17 @@ export class PluckSynth extends Instrument { */ release: Time; - constructor(options?: RecursivePartial) + constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(PluckSynth.getDefaults(), arguments)); - const options = optionsFromArguments(PluckSynth.getDefaults(), arguments); + const options = optionsFromArguments( + PluckSynth.getDefaults(), + arguments + ); this._noise = new Noise({ context: this.context, - type: "pink" + type: "pink", }); this.attackNoise = options.attackNoise; diff --git a/Tone/instrument/PolySynth.test.ts b/Tone/instrument/PolySynth.test.ts index d3d022ec..9e6d98e1 100644 --- a/Tone/instrument/PolySynth.test.ts +++ b/Tone/instrument/PolySynth.test.ts @@ -1,48 +1,59 @@ import { expect } from "chai"; -import { BasicTests, warns } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { atTime, Offline } from "test/helper/Offline"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { PolySynth } from "./PolySynth"; -import { Synth } from "./Synth"; -import { FMSynth } from "./FMSynth"; -import { PluckSynth } from "./PluckSynth"; -import { MetalSynth } from "./MetalSynth"; -import { MembraneSynth } from "./MembraneSynth"; +import { BasicTests, warns } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { atTime, Offline } from "../../test/helper/Offline.js"; +import { OutputAudio } from "../../test/helper/OutputAudio.js"; +import { PolySynth } from "./PolySynth.js"; +import { Synth } from "./Synth.js"; +import { FMSynth } from "./FMSynth.js"; +import { PluckSynth } from "./PluckSynth.js"; +import { MetalSynth } from "./MetalSynth.js"; +import { MembraneSynth } from "./MembraneSynth.js"; describe("PolySynth", () => { - BasicTests(PolySynth); it("matches a file", () => { - return CompareToFile(() => { - const synth = new PolySynth().toDestination(); - synth.triggerAttackRelease("C4", 0.2, 0); - synth.triggerAttackRelease("C4", 0.1, 0.1); - synth.triggerAttackRelease("E4", 0.1, 0.2); - synth.triggerAttackRelease("E4", 0.1, 0.3); - synth.triggerAttackRelease("G4", 0.1, 0.4); - synth.triggerAttackRelease("B4", 0.1, 0.4); - synth.triggerAttackRelease("C4", 0.2, 0.5); - }, "polySynth.wav", 0.6); + return CompareToFile( + () => { + const synth = new PolySynth().toDestination(); + synth.triggerAttackRelease("C4", 0.2, 0); + synth.triggerAttackRelease("C4", 0.1, 0.1); + synth.triggerAttackRelease("E4", 0.1, 0.2); + synth.triggerAttackRelease("E4", 0.1, 0.3); + synth.triggerAttackRelease("G4", 0.1, 0.4); + synth.triggerAttackRelease("B4", 0.1, 0.4); + synth.triggerAttackRelease("C4", 0.2, 0.5); + }, + "polySynth.wav", + 0.6 + ); }); it("matches another file", () => { - return CompareToFile(() => { - const synth = new PolySynth().toDestination(); - synth.triggerAttackRelease(["C4", "E4", "G4", "B4"], 0.2, 0); - synth.triggerAttackRelease(["C4", "E4", "G4", "B4"], 0.2, 0.3); - }, "polySynth2.wav", 0.6); + return CompareToFile( + () => { + const synth = new PolySynth().toDestination(); + synth.triggerAttackRelease(["C4", "E4", "G4", "B4"], 0.2, 0); + synth.triggerAttackRelease(["C4", "E4", "G4", "B4"], 0.2, 0.3); + }, + "polySynth2.wav", + 0.6 + ); }); it("matches a file and chooses the right voice", () => { - return CompareToFile(() => { - const synth = new PolySynth().toDestination(); - synth.triggerAttackRelease(["C4", "E4"], 1, 0); - synth.triggerAttackRelease("G4", 0.1, 0.2); - synth.triggerAttackRelease("B4", 0.1, 0.4); - synth.triggerAttackRelease("G4", 0.1, 0.6); - }, "polySynth3.wav", 0.5); + return CompareToFile( + () => { + const synth = new PolySynth().toDestination(); + synth.triggerAttackRelease(["C4", "E4"], 1, 0); + synth.triggerAttackRelease("G4", 0.1, 0.2); + synth.triggerAttackRelease("B4", 0.1, 0.4); + synth.triggerAttackRelease("G4", 0.1, 0.6); + }, + "polySynth3.wav", + 0.5 + ); }); it("can be constructed with monophonic synths", () => { @@ -65,7 +76,6 @@ describe("PolySynth", () => { }); context("Playing Notes", () => { - it("triggerAttackRelease can take an array of durations", () => { return OutputAudio(() => { const polySynth = new PolySynth(); @@ -81,7 +91,7 @@ describe("PolySynth", () => { polySynth.toDestination(); polySynth.triggerAttack("C4", 0); polySynth.triggerRelease("C4", 0.1); - }, 0.3).then(buffer => { + }, 0.3).then((buffer) => { expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0, 0.01); expect(buffer.getValueAtTime(0.2)).to.be.closeTo(0, 0.01); }); @@ -143,7 +153,11 @@ describe("PolySynth", () => { }, }); polySynth.toDestination(); - polySynth.triggerAttackRelease(["C4", "E4", "G4", "B4", "D5"], 0.1, 0); + polySynth.triggerAttackRelease( + ["C4", "E4", "G4", "B4", "D5"], + 0.1, + 0 + ); return [ atTime(0, () => { expect(polySynth.activeVoices).to.equal(5); @@ -246,7 +260,6 @@ describe("PolySynth", () => { expect(buffer.getTimeOfLastSound()).to.be.closeTo(0.4, 0.01); }); }); - }); context("Transport sync", () => { @@ -281,9 +294,11 @@ describe("PolySynth", () => { return Offline(({ transport }) => { const synth = new PolySynth(Synth, { envelope: { - release: 0 - } - }).sync().toDestination(); + release: 0, + }, + }) + .sync() + .toDestination(); synth.triggerAttackRelease("C4", 0.5); transport.start(0.5).stop(1); }, 1.5).then((buffer) => { @@ -295,9 +310,11 @@ describe("PolySynth", () => { return Offline(({ transport }) => { const synth = new PolySynth(Synth, { envelope: { - release: 0 - } - }).sync().toDestination(); + release: 0, + }, + }) + .sync() + .toDestination(); synth.triggerAttackRelease("C4", 0.8, 0.5); transport.loopEnd = 1; transport.loop = true; @@ -315,9 +332,12 @@ describe("PolySynth", () => { const synth = new PolySynth(Synth, { envelope: { sustain: 1, - release: 0 - } - }).sync().toDestination().unsync(); + release: 0, + }, + }) + .sync() + .toDestination() + .unsync(); synth.triggerAttackRelease("C4", 1, 0.5); transport.start().stop(1); }, 2).then((buffer) => { @@ -330,7 +350,6 @@ describe("PolySynth", () => { }); context("API", () => { - it("can be constructed with an options object", () => { const polySynth = new PolySynth(Synth, { envelope: { diff --git a/Tone/instrument/PolySynth.ts b/Tone/instrument/PolySynth.ts index 07cdfa58..f40825c1 100644 --- a/Tone/instrument/PolySynth.ts +++ b/Tone/instrument/PolySynth.ts @@ -1,17 +1,27 @@ -import { MidiClass } from "../core/type/Midi"; -import { Frequency, MidiNote, NormalRange, Seconds, Time } from "../core/type/Units"; -import { deepMerge, omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { RecursivePartial } from "../core/util/Interface"; -import { isArray, isNumber } from "../core/util/TypeCheck"; -import { Instrument, InstrumentOptions } from "./Instrument"; -import { MembraneSynth, MembraneSynthOptions } from "./MembraneSynth"; -import { FMSynth, FMSynthOptions } from "./FMSynth"; -import { AMSynth, AMSynthOptions } from "./AMSynth"; -import { MonoSynth, MonoSynthOptions } from "./MonoSynth"; -import { MetalSynth, MetalSynthOptions } from "./MetalSynth"; -import { Monophonic } from "./Monophonic"; -import { Synth, SynthOptions } from "./Synth"; -import { assert, warn } from "../core/util/Debug"; +import { MidiClass } from "../core/type/Midi.js"; +import { + Frequency, + MidiNote, + NormalRange, + Seconds, + Time, +} from "../core/type/Units.js"; +import { + deepMerge, + omitFromObject, + optionsFromArguments, +} from "../core/util/Defaults.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { isArray, isNumber } from "../core/util/TypeCheck.js"; +import { Instrument, InstrumentOptions } from "./Instrument.js"; +import { MembraneSynth, MembraneSynthOptions } from "./MembraneSynth.js"; +import { FMSynth, FMSynthOptions } from "./FMSynth.js"; +import { AMSynth, AMSynthOptions } from "./AMSynth.js"; +import { MonoSynth, MonoSynthOptions } from "./MonoSynth.js"; +import { MetalSynth, MetalSynthOptions } from "./MetalSynth.js"; +import { Monophonic } from "./Monophonic.js"; +import { Synth, SynthOptions } from "./Synth.js"; +import { assert, warn } from "../core/util/Debug.js"; type VoiceConstructor = { getDefaults: () => VoiceOptions; @@ -19,20 +29,28 @@ type VoiceConstructor = { type OmitMonophonicOptions = Omit; -type VoiceOptions = - T extends MembraneSynth ? MembraneSynthOptions : - T extends MetalSynth ? MetalSynthOptions : - T extends FMSynth ? FMSynthOptions : - T extends MonoSynth ? MonoSynthOptions : - T extends AMSynth ? AMSynthOptions : - T extends Synth ? SynthOptions : - T extends Monophonic ? U : - never; +type VoiceOptions = T extends MembraneSynth + ? MembraneSynthOptions + : T extends MetalSynth + ? MetalSynthOptions + : T extends FMSynth + ? FMSynthOptions + : T extends MonoSynth + ? MonoSynthOptions + : T extends AMSynth + ? AMSynthOptions + : T extends Synth + ? SynthOptions + : T extends Monophonic + ? U + : never; /** * The settable synth options. excludes monophonic options. */ -type PartialVoiceOptions = RecursivePartial>>; +type PartialVoiceOptions = RecursivePartial< + OmitMonophonicOptions> +>; export interface PolySynthOptions extends InstrumentOptions { maxPolyphony: number; @@ -55,8 +73,9 @@ export interface PolySynthOptions extends InstrumentOptions { * synth.triggerAttackRelease(["C4", "E4", "A4"], 1); * @category Instrument */ -export class PolySynth = Synth> extends Instrument> { - +export class PolySynth< + Voice extends Monophonic = Synth, +> extends Instrument> { readonly name: string = "PolySynth"; /** @@ -67,7 +86,11 @@ export class PolySynth = Synth> extends Instrument /** * The currently active voices */ - private _activeVoices: Array<{ midi: MidiNote; voice: Voice; released: boolean }> = []; + private _activeVoices: Array<{ + midi: MidiNote; + voice: Voice; + released: boolean; + }> = []; /** * All of the allocated voices for this synth. @@ -110,19 +133,33 @@ export class PolySynth = Synth> extends Instrument */ constructor( voice?: VoiceConstructor, - options?: PartialVoiceOptions, + options?: PartialVoiceOptions ); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"])); - const options = optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]); + super( + optionsFromArguments(PolySynth.getDefaults(), arguments, [ + "voice", + "options", + ]) + ); + const options = optionsFromArguments( + PolySynth.getDefaults(), + arguments, + ["voice", "options"] + ); // check against the old API (pre 14.3.0) - assert(!isNumber(options.voice), "DEPRECATED: The polyphony count is no longer the first argument."); + assert( + !isNumber(options.voice), + "DEPRECATED: The polyphony count is no longer the first argument." + ); const defaults = options.voice.getDefaults(); - this.options = Object.assign(defaults, options.options) as VoiceOptions; + this.options = Object.assign( + defaults, + options.options + ) as VoiceOptions; this.voice = options.voice as unknown as VoiceConstructor; this.maxPolyphony = options.maxPolyphony; @@ -132,7 +169,10 @@ export class PolySynth = Synth> extends Instrument const index = this._voices.indexOf(this._dummyVoice); this._voices.splice(index, 1); // kick off the GC interval - this._gcTimeout = this.context.setInterval(this._collectGarbage.bind(this), 1); + this._gcTimeout = this.context.setInterval( + this._collectGarbage.bind(this), + 1 + ); } static getDefaults(): PolySynthOptions { @@ -157,7 +197,9 @@ export class PolySynth = Synth> extends Instrument private _makeVoiceAvailable(voice: Voice): void { this._availableVoices.push(voice); // remove the midi note from 'active voices' - const activeVoiceIndex = this._activeVoices.findIndex((e) => e.voice === voice); + const activeVoiceIndex = this._activeVoices.findIndex( + (e) => e.voice === voice + ); this._activeVoices.splice(activeVoiceIndex, 1); } @@ -172,11 +214,16 @@ export class PolySynth = Synth> extends Instrument return this._availableVoices.shift(); } else if (this._voices.length < this.maxPolyphony) { // otherwise if there is still more maxPolyphony, make a new voice - const voice = new this.voice(Object.assign(this.options, { - context: this.context, - onsilence: this._makeVoiceAvailable.bind(this), - })); - assert(voice instanceof Monophonic, "Voice must extend Monophonic class"); + const voice = new this.voice( + Object.assign(this.options, { + context: this.context, + onsilence: this._makeVoiceAvailable.bind(this), + }) + ); + assert( + voice instanceof Monophonic, + "Voice must extend Monophonic class" + ); voice.connect(this.output); this._voices.push(voice); return voice; @@ -189,8 +236,14 @@ export class PolySynth = Synth> extends Instrument * Occasionally check if there are any allocated voices which can be cleaned up. */ private _collectGarbage(): void { - this._averageActiveVoices = Math.max(this._averageActiveVoices * 0.95, this.activeVoices); - if (this._availableVoices.length && this._voices.length > Math.ceil(this._averageActiveVoices + 1)) { + this._averageActiveVoices = Math.max( + this._averageActiveVoices * 0.95, + this.activeVoices + ); + if ( + this._availableVoices.length && + this._voices.length > Math.ceil(this._averageActiveVoices + 1) + ) { // take off an available note const firstAvail = this._availableVoices.shift() as Voice; const index = this._voices.indexOf(firstAvail); @@ -204,14 +257,20 @@ export class PolySynth = Synth> extends Instrument /** * Internal method which triggers the attack */ - private _triggerAttack(notes: Frequency[], time: Seconds, velocity?: NormalRange): void { - notes.forEach(note => { + private _triggerAttack( + notes: Frequency[], + time: Seconds, + velocity?: NormalRange + ): void { + notes.forEach((note) => { const midiNote = new MidiClass(this.context, note).toMidi(); const voice = this._getNextAvailableVoice(); if (voice) { voice.triggerAttack(note, time, velocity); this._activeVoices.push({ - midi: midiNote, voice, released: false, + midi: midiNote, + voice, + released: false, }); this.log("triggerAttack", note, time); } @@ -222,9 +281,11 @@ export class PolySynth = Synth> extends Instrument * Internal method which triggers the release */ private _triggerRelease(notes: Frequency[], time: Seconds): void { - notes.forEach(note => { + notes.forEach((note) => { const midiNote = new MidiClass(this.context, note).toMidi(); - const event = this._activeVoices.find(({ midi, released }) => midi === midiNote && !released); + const event = this._activeVoices.find( + ({ midi, released }) => midi === midiNote && !released + ); if (event) { // trigger release on that note event.voice.triggerRelease(time); @@ -239,7 +300,12 @@ export class PolySynth = Synth> extends Instrument * Schedule the attack/release events. If the time is in the future, then it should set a timeout * to wait for just-in-time scheduling */ - private _scheduleEvent(type: "attack" | "release", notes: Frequency[], time: Seconds, velocity?: NormalRange): void { + private _scheduleEvent( + type: "attack" | "release", + notes: Frequency[], + time: Seconds, + velocity?: NormalRange + ): void { assert(!this.disposed, "Synth was already disposed"); // if the notes are greater than this amount of time in the future, they should be scheduled with setTimeout if (time <= this.now()) { @@ -269,8 +335,11 @@ export class PolySynth = Synth> extends Instrument * // trigger a chord immediately with a velocity of 0.2 * synth.triggerAttack(["Ab3", "C4", "F5"], Tone.now(), 0.2); */ - triggerAttack(notes: Frequency | Frequency[], time?: Time, velocity?: NormalRange): this { - + triggerAttack( + notes: Frequency | Frequency[], + time?: Time, + velocity?: NormalRange + ): this { if (!Array.isArray(notes)) { notes = [notes]; } @@ -315,17 +384,23 @@ export class PolySynth = Synth> extends Instrument notes: Frequency | Frequency[], duration: Time | Time[], time?: Time, - velocity?: NormalRange, + velocity?: NormalRange ): this { const computedTime = this.toSeconds(time); this.triggerAttack(notes, computedTime, velocity); if (isArray(duration)) { - assert(isArray(notes), "If the duration is an array, the notes must also be an array"); + assert( + isArray(notes), + "If the duration is an array, the notes must also be an array" + ); notes = notes as Frequency[]; for (let i = 0; i < notes.length; i++) { const d = duration[Math.min(i, duration.length - 1)]; const durationSeconds = this.toSeconds(d); - assert(durationSeconds > 0, "The duration must be greater than 0"); + assert( + durationSeconds > 0, + "The duration must be greater than 0" + ); this.triggerRelease(notes[i], computedTime + durationSeconds); } } else { @@ -350,9 +425,9 @@ export class PolySynth = Synth> extends Instrument } /** - * The release which is scheduled to the timeline. + * The release which is scheduled to the timeline. */ - protected _syncedRelease = (time: number) => this.releaseAll(time); + protected _syncedRelease = (time: number) => this.releaseAll(time); /** * Set a member/attribute of the voices @@ -368,10 +443,13 @@ export class PolySynth = Synth> extends Instrument */ set(options: RecursivePartial>): this { // remove options which are controlled by the PolySynth - const sanitizedOptions = omitFromObject(options, ["onsilence", "context"]); + const sanitizedOptions = omitFromObject(options, [ + "onsilence", + "context", + ]); // store all of the options this.options = deepMerge(this.options, sanitizedOptions); - this._voices.forEach(voice => voice.set(sanitizedOptions)); + this._voices.forEach((voice) => voice.set(sanitizedOptions)); this._dummyVoice.set(sanitizedOptions); return this; } @@ -391,11 +469,11 @@ export class PolySynth = Synth> extends Instrument }); return this; } - + dispose(): this { super.dispose(); this._dummyVoice.dispose(); - this._voices.forEach(v => v.dispose()); + this._voices.forEach((v) => v.dispose()); this._activeVoices = []; this._availableVoices = []; this.context.clearInterval(this._gcTimeout); diff --git a/Tone/instrument/Sampler.test.ts b/Tone/instrument/Sampler.test.ts index 99b2a9dc..3224dc92 100644 --- a/Tone/instrument/Sampler.test.ts +++ b/Tone/instrument/Sampler.test.ts @@ -1,49 +1,62 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { atTime, Offline } from "test/helper/Offline"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { Sampler } from "Tone/instrument/Sampler"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { atTime, Offline } from "../../test/helper/Offline.js"; +import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js"; +import { Sampler } from "./Sampler.js"; describe("Sampler", () => { - const A4_buffer = new ToneAudioBuffer(); beforeEach(() => { - return A4_buffer.load("./audio/sine.wav"); + return A4_buffer.load("./test/audio/sine.wav"); }); BasicTests(Sampler); - InstrumentTest(Sampler, "A4", { - 69: A4_buffer, - }, 1); + InstrumentTest( + Sampler, + "A4", + { + 69: A4_buffer, + }, + 1 + ); it("matches a file", () => { - return CompareToFile(() => { - const sampler = new Sampler({ - 69: A4_buffer, - }, { - release: 0.4, - }).toDestination(); - sampler.triggerAttackRelease("C4", 0.1, 0, 0.2); - sampler.triggerAttackRelease("E4", 0.1, 0.2, 0.4); - sampler.triggerAttackRelease("G4", 0.1, 0.4, 0.6); - sampler.triggerAttackRelease("B4", 0.1, 0.6, 0.8); - sampler.triggerAttackRelease("C4", 0.1, 0.8); - }, "sampler.wav", 0.01); + return CompareToFile( + () => { + const sampler = new Sampler( + { + 69: A4_buffer, + }, + { + release: 0.4, + } + ).toDestination(); + sampler.triggerAttackRelease("C4", 0.1, 0, 0.2); + sampler.triggerAttackRelease("E4", 0.1, 0.2, 0.4); + sampler.triggerAttackRelease("G4", 0.1, 0.4, 0.6); + sampler.triggerAttackRelease("B4", 0.1, 0.6, 0.8); + sampler.triggerAttackRelease("C4", 0.1, 0.8); + }, + "sampler.wav", + 0.01 + ); }); context("Constructor", () => { - it("can be constructed with an options object", () => { - const sampler = new Sampler({ - 69: A4_buffer, - }, { - attack: 0.2, - release: 0.3, - }); + const sampler = new Sampler( + { + 69: A4_buffer, + }, + { + attack: 0.2, + release: 0.3, + } + ); expect(sampler.attack).to.equal(0.2); expect(sampler.release).to.equal(0.3); sampler.dispose(); @@ -90,7 +103,7 @@ describe("Sampler", () => { }).throws(Error); }); - it("invokes onerror if the ", done => { + it("invokes onerror if the ", (done) => { const sampler = new Sampler({ urls: { 40: "./nosuchfile.wav", @@ -99,7 +112,7 @@ describe("Sampler", () => { expect(e).to.be.instanceOf(Error); sampler.dispose(); done(); - } + }, }); }); @@ -113,40 +126,48 @@ describe("Sampler", () => { }); it("invokes the callback when loaded", (done) => { - const sampler = new Sampler({ - A4: "./audio/sine.wav", - }, () => { - expect(sampler.loaded).to.be.true; - done(); - }); + const sampler = new Sampler( + { + A4: "./test/audio/sine.wav", + }, + () => { + expect(sampler.loaded).to.be.true; + done(); + } + ); }); it("can pass in a callback and baseUrl", (done) => { - const sampler = new Sampler({ - A4: A4_buffer, - }, () => { - expect(sampler.loaded).to.be.true; - done(); - }, "./baseUrl"); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + () => { + expect(sampler.loaded).to.be.true; + done(); + }, + "./baseUrl" + ); }); it("can dispose while playing sounds", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttack("A4", 0); sampler.triggerRelease("A4", 0.2); sampler.dispose(); }, 0.3); }); - }); context("Makes sound", () => { - it("repitches the note", () => { return Offline(() => { const sampler = new Sampler({ @@ -160,11 +181,14 @@ describe("Sampler", () => { it("is silent after the release", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttack("A4", 0); sampler.triggerRelease("A4", 0.2); }, 0.3).then((buffer) => { @@ -174,27 +198,36 @@ describe("Sampler", () => { it("can triggerRelease after the buffer has already stopped", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttack("A4", 0); return atTime(A4_buffer.duration + 0.01, () => { sampler.triggerRelease("A4"); }); }, A4_buffer.duration + 0.1).then((buffer) => { - expect(buffer.getTimeOfLastSound()).to.be.closeTo(A4_buffer.duration, 0.01); + expect(buffer.getTimeOfLastSound()).to.be.closeTo( + A4_buffer.duration, + 0.01 + ); }); }); it("can release multiple notes", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttack("A4", 0); sampler.triggerAttack("C4", 0); sampler.triggerAttack("A4", 0.1); @@ -207,11 +240,14 @@ describe("Sampler", () => { it("can trigger the attack and release", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttackRelease("A4", 0.2, 0.1); }, 0.4).then((buffer) => { expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.1, 0.01); @@ -221,11 +257,14 @@ describe("Sampler", () => { it("can trigger polyphonic attack release", () => { return Offline(() => { - const sampler = new Sampler({ - A4: A4_buffer, - }, { - release: 0, - }).toDestination(); + const sampler = new Sampler( + { + A4: A4_buffer, + }, + { + release: 0, + } + ).toDestination(); sampler.triggerAttackRelease(["A4", "C4"], [0.2, 0.3], 0.1); }, 0.5).then((buffer) => { expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.1, 0.01); @@ -235,7 +274,6 @@ describe("Sampler", () => { }); context("add samples", () => { - it("can add a note with it's midi value", () => { return Offline(() => { const sampler = new Sampler().toDestination(); @@ -258,7 +296,7 @@ describe("Sampler", () => { it("can pass in a url and invokes the callback", (done) => { const sampler = new Sampler(); - sampler.add("A4", "./audio/sine.wav", () => { + sampler.add("A4", "./test/audio/sine.wav", () => { done(); }); }); diff --git a/Tone/instrument/Sampler.ts b/Tone/instrument/Sampler.ts index fc00c9d0..da7ff263 100644 --- a/Tone/instrument/Sampler.ts +++ b/Tone/instrument/Sampler.ts @@ -1,15 +1,25 @@ -import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer"; -import { ToneAudioBuffers } from "../core/context/ToneAudioBuffers"; -import { ftomf, intervalToFrequencyRatio } from "../core/type/Conversions"; -import { FrequencyClass } from "../core/type/Frequency"; -import { Frequency, Interval, MidiNote, NormalRange, Note, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { noOp } from "../core/util/Interface"; -import { isArray, isNote, isNumber } from "../core/util/TypeCheck"; -import { Instrument, InstrumentOptions } from "../instrument/Instrument"; -import { ToneBufferSource, ToneBufferSourceCurve } from "../source/buffer/ToneBufferSource"; -import { timeRange } from "../core/util/Decorator"; -import { assert } from "../core/util/Debug"; +import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js"; +import { ToneAudioBuffers } from "../core/context/ToneAudioBuffers.js"; +import { ftomf, intervalToFrequencyRatio } from "../core/type/Conversions.js"; +import { FrequencyClass } from "../core/type/Frequency.js"; +import { + Frequency, + Interval, + MidiNote, + NormalRange, + Note, + Time, +} from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { noOp } from "../core/util/Interface.js"; +import { isArray, isNote, isNumber } from "../core/util/TypeCheck.js"; +import { Instrument, InstrumentOptions } from "../instrument/Instrument.js"; +import { + ToneBufferSource, + ToneBufferSourceCurve, +} from "../source/buffer/ToneBufferSource.js"; +import { timeRange } from "../core/util/Decorator.js"; +import { assert } from "../core/util/Debug.js"; interface SamplesMap { [note: string]: ToneAudioBuffer | AudioBuffer | string; @@ -48,7 +58,6 @@ export interface SamplerOptions extends InstrumentOptions { * @category Instrument */ export class Sampler extends Instrument { - readonly name: string = "Sampler"; /** @@ -95,18 +104,34 @@ export class Sampler extends Instrument { * Scientific Pitch Notation to the url of that sample. * @param options The remaining options associated with the sampler */ - constructor(samples?: SamplesMap, options?: Partial>); + constructor( + samples?: SamplesMap, + options?: Partial> + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls")); - const options = optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls"); + super( + optionsFromArguments( + Sampler.getDefaults(), + arguments, + ["urls", "onload", "baseUrl"], + "urls" + ) + ); + const options = optionsFromArguments( + Sampler.getDefaults(), + arguments, + ["urls", "onload", "baseUrl"], + "urls" + ); const urlMap = {}; Object.keys(options.urls).forEach((note) => { const noteNumber = parseInt(note, 10); - assert(isNote(note) - || (isNumber(noteNumber) && isFinite(noteNumber)), `url key is neither a note or midi pitch: ${note}`); + assert( + isNote(note) || (isNumber(noteNumber) && isFinite(noteNumber)), + `url key is neither a note or midi pitch: ${note}` + ); if (isNote(note)) { // convert the note name to MIDI const mid = new FrequencyClass(this.context, note).toMidi(); @@ -170,20 +195,28 @@ export class Sampler extends Instrument { * @param time When to play the note * @param velocity The velocity to play the sample back. */ - triggerAttack(notes: Frequency | Frequency[], time?: Time, velocity: NormalRange = 1): this { + triggerAttack( + notes: Frequency | Frequency[], + time?: Time, + velocity: NormalRange = 1 + ): this { this.log("triggerAttack", notes, time, velocity); if (!Array.isArray(notes)) { notes = [notes]; } - notes.forEach(note => { - const midiFloat = ftomf(new FrequencyClass(this.context, note).toFrequency()); + notes.forEach((note) => { + const midiFloat = ftomf( + new FrequencyClass(this.context, note).toFrequency() + ); const midi = Math.round(midiFloat) as MidiNote; const remainder = midiFloat - midi; // find the closest note pitch const difference = this._findClosest(midi); const closestNote = midi - difference; const buffer = this._buffers.get(closestNote); - const playbackRate = intervalToFrequencyRatio(difference + remainder); + const playbackRate = intervalToFrequencyRatio( + difference + remainder + ); // play that note const source = new ToneBufferSource({ url: buffer, @@ -203,7 +236,9 @@ export class Sampler extends Instrument { // remove it when it's done source.onended = () => { if (this._activeSources && this._activeSources.has(midi)) { - const sources = this._activeSources.get(midi) as ToneBufferSource[]; + const sources = this._activeSources.get( + midi + ) as ToneBufferSource[]; const index = sources.indexOf(source); if (index !== -1) { sources.splice(index, 1); @@ -223,13 +258,18 @@ export class Sampler extends Instrument { if (!Array.isArray(notes)) { notes = [notes]; } - notes.forEach(note => { + notes.forEach((note) => { const midi = new FrequencyClass(this.context, note).toMidi(); // find the note - if (this._activeSources.has(midi) && (this._activeSources.get(midi) as ToneBufferSource[]).length) { - const sources = this._activeSources.get(midi) as ToneBufferSource[]; + if ( + this._activeSources.has(midi) && + (this._activeSources.get(midi) as ToneBufferSource[]).length + ) { + const sources = this._activeSources.get( + midi + ) as ToneBufferSource[]; time = this.toSeconds(time); - sources.forEach(source => { + sources.forEach((source) => { source.stop(time); }); this._activeSources.set(midi, []); @@ -244,7 +284,7 @@ export class Sampler extends Instrument { */ releaseAll(time?: Time): this { const computedTime = this.toSeconds(time); - this._activeSources.forEach(sources => { + this._activeSources.forEach((sources) => { while (sources.length) { const source = sources.shift() as ToneBufferSource; source.stop(computedTime); @@ -272,12 +312,15 @@ export class Sampler extends Instrument { notes: Frequency[] | Frequency, duration: Time | Time[], time?: Time, - velocity: NormalRange = 1, + velocity: NormalRange = 1 ): this { const computedTime = this.toSeconds(time); this.triggerAttack(notes, computedTime, velocity); if (isArray(duration)) { - assert(isArray(notes), "notes must be an array when duration is array"); + assert( + isArray(notes), + "notes must be an array when duration is array" + ); (notes as Frequency[]).forEach((note, index) => { const d = duration[Math.min(index, duration.length - 1)]; this.triggerRelease(note, computedTime + this.toSeconds(d)); @@ -294,8 +337,15 @@ export class Sampler extends Instrument { * @param url Either the url of the buffer, or a buffer which will be added with the given name. * @param callback The callback to invoke when the url is loaded. */ - add(note: Note | MidiNote, url: string | ToneAudioBuffer | AudioBuffer, callback?: () => void): this { - assert(isNote(note) || isFinite(note), `note must be a pitch or midi: ${note}`); + add( + note: Note | MidiNote, + url: string | ToneAudioBuffer | AudioBuffer, + callback?: () => void + ): this { + assert( + isNote(note) || isFinite(note), + `note must be a pitch or midi: ${note}` + ); if (isNote(note)) { // convert the note name to MIDI const mid = new FrequencyClass(this.context, note).toMidi(); @@ -320,8 +370,8 @@ export class Sampler extends Instrument { dispose(): this { super.dispose(); this._buffers.dispose(); - this._activeSources.forEach(sources => { - sources.forEach(source => source.dispose()); + this._activeSources.forEach((sources) => { + sources.forEach((source) => source.dispose()); }); this._activeSources.clear(); return this; diff --git a/Tone/instrument/Synth.test.ts b/Tone/instrument/Synth.test.ts index 43610711..27727ba4 100644 --- a/Tone/instrument/Synth.test.ts +++ b/Tone/instrument/Synth.test.ts @@ -1,37 +1,43 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { InstrumentTest } from "test/helper/InstrumentTests"; -import { MonophonicTest } from "test/helper/MonophonicTests"; -import { Offline } from "test/helper/Offline"; -import { Frequency } from "Tone/core/type/Frequency"; -import { Synth } from "./Synth"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { InstrumentTest } from "../../test/helper/InstrumentTests.js"; +import { MonophonicTest } from "../../test/helper/MonophonicTests.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Frequency } from "../core/type/Frequency.js"; +import { Synth } from "./Synth.js"; describe("Synth", () => { - BasicTests(Synth); InstrumentTest(Synth, "C4"); MonophonicTest(Synth, "C4"); it("matches a file basic", () => { - return CompareToFile(() => { - const synth = new Synth().toDestination(); - synth.triggerAttackRelease("C4", 0.1, 0.05); - }, "synth_basic.wav", 0.3); + return CompareToFile( + () => { + const synth = new Synth().toDestination(); + synth.triggerAttackRelease("C4", 0.1, 0.05); + }, + "synth_basic.wav", + 0.3 + ); }); it("matches a file melody", () => { - return CompareToFile(() => { - const synth = new Synth().toDestination(); - synth.triggerAttack("C4", 0); - synth.triggerAttack("E4", 0.1, 0.5); - synth.triggerAttackRelease("G4", 0.5, 0.3); - synth.triggerAttackRelease("B4", 0.5, 0.5, 0.2); - }, "synth_melody.wav", 0.3); + return CompareToFile( + () => { + const synth = new Synth().toDestination(); + synth.triggerAttack("C4", 0); + synth.triggerAttack("E4", 0.1, 0.5); + synth.triggerAttackRelease("G4", 0.5, 0.3); + synth.triggerAttackRelease("B4", 0.5, 0.5, 0.2); + }, + "synth_melody.wav", + 0.3 + ); }); context("API", () => { - it("can get and set oscillator attributes", () => { const simple = new Synth(); simple.oscillator.type = "triangle"; @@ -121,9 +127,11 @@ describe("Synth", () => { return Offline(({ transport }) => { const synth = new Synth({ envelope: { - release: 0 - } - }).sync().toDestination(); + release: 0, + }, + }) + .sync() + .toDestination(); synth.triggerAttackRelease("C4", 0.5); transport.start(0.5).stop(1); }, 1.5).then((buffer) => { @@ -135,9 +143,11 @@ describe("Synth", () => { return Offline(({ transport }) => { const synth = new Synth({ envelope: { - release: 0 - } - }).sync().toDestination(); + release: 0, + }, + }) + .sync() + .toDestination(); synth.triggerAttackRelease("C4", 0.8, 0.5); transport.loopEnd = 1; transport.loop = true; @@ -155,9 +165,12 @@ describe("Synth", () => { const synth = new Synth({ envelope: { sustain: 1, - release: 0 - } - }).sync().toDestination().unsync(); + release: 0, + }, + }) + .sync() + .toDestination() + .unsync(); synth.triggerAttackRelease("C4", 1, 0.5); transport.start().stop(1); }, 2).then((buffer) => { diff --git a/Tone/instrument/Synth.ts b/Tone/instrument/Synth.ts index 2c4bf66d..ed47f675 100644 --- a/Tone/instrument/Synth.ts +++ b/Tone/instrument/Synth.ts @@ -1,15 +1,21 @@ -import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; -import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; -import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { NormalRange, Seconds, Time } from "../core/type/Units"; -import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; -import { readOnly } from "../core/util/Interface"; -import { RecursivePartial } from "../core/util/Interface"; -import { Signal } from "../signal/Signal"; -import { OmniOscillator } from "../source/oscillator/OmniOscillator"; -import { OmniOscillatorOptions, OmniOscillatorSynthOptions } from "../source/oscillator/OscillatorInterface"; -import { Source } from "../source/Source"; -import { Monophonic, MonophonicOptions } from "./Monophonic"; +import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope.js"; +import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope.js"; +import { + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { NormalRange, Seconds, Time } from "../core/type/Units.js"; +import { omitFromObject, optionsFromArguments } from "../core/util/Defaults.js"; +import { readOnly } from "../core/util/Interface.js"; +import { RecursivePartial } from "../core/util/Interface.js"; +import { Signal } from "../signal/Signal.js"; +import { OmniOscillator } from "../source/oscillator/OmniOscillator.js"; +import { + OmniOscillatorOptions, + OmniOscillatorSynthOptions, +} from "../source/oscillator/OscillatorInterface.js"; +import { Source } from "../source/Source.js"; +import { Monophonic, MonophonicOptions } from "./Monophonic.js"; export interface SynthOptions extends MonophonicOptions { oscillator: OmniOscillatorSynthOptions; @@ -28,8 +34,9 @@ export interface SynthOptions extends MonophonicOptions { * synth.triggerAttackRelease("C4", "8n"); * @category Instrument */ -export class Synth extends Monophonic { - +export class Synth< + Options extends SynthOptions = SynthOptions, +> extends Monophonic { readonly name: string = "Synth"; /** @@ -60,18 +67,28 @@ export class Synth extends Monophon super(optionsFromArguments(Synth.getDefaults(), arguments)); const options = optionsFromArguments(Synth.getDefaults(), arguments); - this.oscillator = new OmniOscillator(Object.assign({ - context: this.context, - detune: options.detune, - onstop: () => this.onsilence(this), - }, options.oscillator)); + this.oscillator = new OmniOscillator( + Object.assign( + { + context: this.context, + detune: options.detune, + onstop: () => this.onsilence(this), + }, + options.oscillator + ) + ); this.frequency = this.oscillator.frequency; this.detune = this.oscillator.detune; - this.envelope = new AmplitudeEnvelope(Object.assign({ - context: this.context, - }, options.envelope)); + this.envelope = new AmplitudeEnvelope( + Object.assign( + { + context: this.context, + }, + options.envelope + ) + ); // connect the oscillators to the output this.oscillator.chain(this.envelope, this.output); @@ -81,19 +98,26 @@ export class Synth extends Monophon static getDefaults(): SynthOptions { return Object.assign(Monophonic.getDefaults(), { envelope: Object.assign( - omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), + omitFromObject( + Envelope.getDefaults(), + Object.keys(ToneAudioNode.getDefaults()) + ), { attack: 0.005, decay: 0.1, release: 1, sustain: 0.3, - }, + } ), oscillator: Object.assign( - omitFromObject(OmniOscillator.getDefaults(), [...Object.keys(Source.getDefaults()), "frequency", "detune"]), + omitFromObject(OmniOscillator.getDefaults(), [ + ...Object.keys(Source.getDefaults()), + "frequency", + "detune", + ]), { type: "triangle", - }, + } ) as OmniOscillatorOptions, }); } diff --git a/Tone/instrument/index.ts b/Tone/instrument/index.ts index e5fdf169..c6282800 100644 --- a/Tone/instrument/index.ts +++ b/Tone/instrument/index.ts @@ -1,11 +1,11 @@ -export * from "./AMSynth"; -export * from "./DuoSynth"; -export * from "./FMSynth"; -export * from "./MetalSynth"; -export * from "./MembraneSynth"; -export * from "./MonoSynth"; -export * from "./NoiseSynth"; -export * from "./PluckSynth"; -export * from "./PolySynth"; -export * from "./Sampler"; -export * from "./Synth"; +export * from "./AMSynth.js"; +export * from "./DuoSynth.js"; +export * from "./FMSynth.js"; +export * from "./MetalSynth.js"; +export * from "./MembraneSynth.js"; +export * from "./MonoSynth.js"; +export * from "./NoiseSynth.js"; +export * from "./PluckSynth.js"; +export * from "./PolySynth.js"; +export * from "./Sampler.js"; +export * from "./Synth.js"; diff --git a/Tone/signal/Abs.test.ts b/Tone/signal/Abs.test.ts index 8499c10a..160a2610 100644 --- a/Tone/signal/Abs.test.ts +++ b/Tone/signal/Abs.test.ts @@ -1,15 +1,13 @@ -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Abs } from "./Abs"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Abs } from "./Abs.js"; +import { Signal } from "./Signal.js"; describe("Abs", () => { - BasicTests(Abs); context("Absolute Value", () => { - it("outputs the same value for positive values", () => { return ConstantOutput(() => { const signal = new Signal(0.4); @@ -36,7 +34,5 @@ describe("Abs", () => { abs.toDestination(); }, 0.3); }); - }); - }); diff --git a/Tone/signal/Abs.ts b/Tone/signal/Abs.ts index 16ab121f..1a1562b9 100644 --- a/Tone/signal/Abs.ts +++ b/Tone/signal/Abs.ts @@ -1,6 +1,6 @@ -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { SignalOperator } from "./SignalOperator"; -import { WaveShaper } from "./WaveShaper"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; +import { SignalOperator } from "./SignalOperator.js"; +import { WaveShaper } from "./WaveShaper.js"; /** * Return the absolute value of an incoming signal. @@ -15,7 +15,6 @@ import { WaveShaper } from "./WaveShaper"; * @category Signal */ export class Abs extends SignalOperator { - readonly name: string = "Abs"; /** @@ -23,7 +22,7 @@ export class Abs extends SignalOperator { */ private _abs = new WaveShaper({ context: this.context, - mapping: val => { + mapping: (val) => { if (Math.abs(val) < 0.001) { return 0; } else { diff --git a/Tone/signal/Add.test.ts b/Tone/signal/Add.test.ts index 406f824e..dab11b49 100644 --- a/Tone/signal/Add.test.ts +++ b/Tone/signal/Add.test.ts @@ -1,15 +1,13 @@ -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Add } from "./Add"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Add } from "./Add.js"; +import { Signal } from "./Signal.js"; describe("Add", () => { - BasicTests(Add); context("Addition", () => { - it("handles input and output connections", () => { const add = new Add(); connectFrom().connect(add); diff --git a/Tone/signal/Add.ts b/Tone/signal/Add.ts index 4f12cd4d..903bdd67 100644 --- a/Tone/signal/Add.ts +++ b/Tone/signal/Add.ts @@ -1,8 +1,8 @@ -import { connectSeries } from "../core/context/ToneAudioNode"; -import { Gain } from "../core/context/Gain"; -import { Param } from "../core/context/Param"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Signal, SignalOptions } from "./Signal"; +import { connectSeries } from "../core/context/ToneAudioNode.js"; +import { Gain } from "../core/context/Gain.js"; +import { Param } from "../core/context/Param.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Signal, SignalOptions } from "./Signal.js"; /** * Add a signal and a number or two signals. When no value is @@ -21,7 +21,6 @@ import { Signal, SignalOptions } from "./Signal"; * @category Signal */ export class Add extends Signal { - override = false; readonly name: string = "Add"; @@ -44,7 +43,11 @@ export class Add extends Signal { constructor(value?: number); constructor(options?: Partial>); constructor() { - super(Object.assign(optionsFromArguments(Add.getDefaults(), arguments, ["value"]))); + super( + Object.assign( + optionsFromArguments(Add.getDefaults(), arguments, ["value"]) + ) + ); connectSeries(this._constantSource, this._sum); } diff --git a/Tone/signal/AudioToGain.test.ts b/Tone/signal/AudioToGain.test.ts index 3c641e02..d124fcc8 100644 --- a/Tone/signal/AudioToGain.test.ts +++ b/Tone/signal/AudioToGain.test.ts @@ -1,15 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Offline } from "test/helper/Offline"; -import { Oscillator } from "../source/oscillator/Oscillator"; -import { AudioToGain } from "./AudioToGain"; -import { Signal } from "./Signal"; -import { Zero } from "./Zero"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Oscillator } from "../source/oscillator/Oscillator.js"; +import { AudioToGain } from "./AudioToGain.js"; +import { Signal } from "./Signal.js"; +import { Zero } from "./Zero.js"; describe("AudioToGain", () => { - BasicTests(AudioToGain); it("normalizes an oscillator to 0,1", () => { @@ -18,7 +17,7 @@ describe("AudioToGain", () => { const a2g = new AudioToGain(); osc.connect(a2g); a2g.toDestination(); - }).then(buffer => { + }).then((buffer) => { expect(buffer.min()).to.be.closeTo(0, 0.01); expect(buffer.max()).to.be.closeTo(1, 0.01); }); diff --git a/Tone/signal/AudioToGain.ts b/Tone/signal/AudioToGain.ts index 743ea600..a024e14e 100644 --- a/Tone/signal/AudioToGain.ts +++ b/Tone/signal/AudioToGain.ts @@ -1,6 +1,6 @@ -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { SignalOperator } from "./SignalOperator"; -import { WaveShaper } from "./WaveShaper"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; +import { SignalOperator } from "./SignalOperator.js"; +import { WaveShaper } from "./WaveShaper.js"; /** * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. @@ -8,7 +8,6 @@ import { WaveShaper } from "./WaveShaper"; * @category Signal */ export class AudioToGain extends SignalOperator { - readonly name: string = "AudioToGain"; /** @@ -16,7 +15,7 @@ export class AudioToGain extends SignalOperator { */ private _norm = new WaveShaper({ context: this.context, - mapping: x => (x + 1) / 2, + mapping: (x) => (x + 1) / 2, }); /** diff --git a/Tone/signal/GainToAudio.test.ts b/Tone/signal/GainToAudio.test.ts index ad6eea30..ae09ca52 100644 --- a/Tone/signal/GainToAudio.test.ts +++ b/Tone/signal/GainToAudio.test.ts @@ -1,16 +1,14 @@ -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Zero } from "Tone/signal/Zero"; -import { GainToAudio } from "./GainToAudio"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Zero } from "./Zero.js"; +import { GainToAudio } from "./GainToAudio.js"; +import { Signal } from "./Signal.js"; describe("GainToAudio", () => { - BasicTests(GainToAudio); context("Gain To Audio", () => { - it("outputs 0 for an input value of 0.5", () => { return ConstantOutput(() => { const sig = new Signal(0.5); diff --git a/Tone/signal/GainToAudio.ts b/Tone/signal/GainToAudio.ts index 6948217f..132ed0d2 100644 --- a/Tone/signal/GainToAudio.ts +++ b/Tone/signal/GainToAudio.ts @@ -1,6 +1,6 @@ -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { SignalOperator } from "./SignalOperator"; -import { WaveShaper } from "./WaveShaper"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; +import { SignalOperator } from "./SignalOperator.js"; +import { WaveShaper } from "./WaveShaper.js"; /** * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1]. @@ -8,7 +8,6 @@ import { WaveShaper } from "./WaveShaper"; * @category Signal */ export class GainToAudio extends SignalOperator { - readonly name: string = "GainToAudio"; /** @@ -16,7 +15,7 @@ export class GainToAudio extends SignalOperator { */ private _norm = new WaveShaper({ context: this.context, - mapping: x => Math.abs(x) * 2 - 1, + mapping: (x) => Math.abs(x) * 2 - 1, }); /** diff --git a/Tone/signal/GreaterThan.test.ts b/Tone/signal/GreaterThan.test.ts index 971de401..b86f39c1 100644 --- a/Tone/signal/GreaterThan.test.ts +++ b/Tone/signal/GreaterThan.test.ts @@ -1,14 +1,12 @@ -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { BasicTests } from "test/helper/Basic"; -import { GreaterThan } from "./GreaterThan"; -import { Signal } from "./Signal"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { GreaterThan } from "./GreaterThan.js"; +import { Signal } from "./Signal.js"; describe("GreaterThan", () => { - BasicTests(GreaterThan); context("Comparison", () => { - it("outputs 0 when signal is less than value", () => { return ConstantOutput(() => { const signal = new Signal(1); @@ -78,4 +76,3 @@ describe("GreaterThan", () => { }); }); }); - diff --git a/Tone/signal/GreaterThan.ts b/Tone/signal/GreaterThan.ts index 530a1d5a..9e2b88d4 100644 --- a/Tone/signal/GreaterThan.ts +++ b/Tone/signal/GreaterThan.ts @@ -1,17 +1,17 @@ -import { ToneAudioNode } from "../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Subtract } from "./Subtract"; -import { Signal, SignalOptions } from "./Signal"; -import { GreaterThanZero } from "./GreaterThanZero"; -import { readOnly } from "../core/util/Interface"; -import { Param } from "../core/context/Param"; +import { ToneAudioNode } from "../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Subtract } from "./Subtract.js"; +import { Signal, SignalOptions } from "./Signal.js"; +import { GreaterThanZero } from "./GreaterThanZero.js"; +import { readOnly } from "../core/util/Interface.js"; +import { Param } from "../core/context/Param.js"; export type GreaterThanOptions = SignalOptions<"number">; /** * Output 1 if the signal is greater than the value, otherwise outputs 0. * can compare two signals or a signal and a number. - * + * * @example * return Tone.Offline(() => { * const gt = new Tone.GreaterThan(2).toDestination(); @@ -20,8 +20,7 @@ export type GreaterThanOptions = SignalOptions<"number">; * @category Signal */ export class GreaterThan extends Signal<"number"> { - - readonly name: string = "GreaterThan" + readonly name: string = "GreaterThan"; readonly override: boolean = false; @@ -48,7 +47,7 @@ export class GreaterThan extends Signal<"number"> { * gt.comparator.setValueAtTime(0.5, 0.1); * }, 0.5, 1); */ - readonly comparator: Param<"number"> + readonly comparator: Param<"number">; /** * @param value The value to compare to @@ -56,14 +55,26 @@ export class GreaterThan extends Signal<"number"> { constructor(value?: number); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(GreaterThan.getDefaults(), arguments, ["value"]))); - const options = optionsFromArguments(GreaterThan.getDefaults(), arguments, ["value"]); + super( + Object.assign( + optionsFromArguments(GreaterThan.getDefaults(), arguments, [ + "value", + ]) + ) + ); + const options = optionsFromArguments( + GreaterThan.getDefaults(), + arguments, + ["value"] + ); this._subtract = this.input = new Subtract({ context: this.context, - value: options.value + value: options.value, + }); + this._gtz = this.output = new GreaterThanZero({ + context: this.context, }); - this._gtz = this.output = new GreaterThanZero({ context: this.context }); this.comparator = this._param = this._subtract.subtrahend; readOnly(this, "comparator"); diff --git a/Tone/signal/GreaterThanZero.test.ts b/Tone/signal/GreaterThanZero.test.ts index 05ebdb89..a1a98b28 100644 --- a/Tone/signal/GreaterThanZero.test.ts +++ b/Tone/signal/GreaterThanZero.test.ts @@ -1,14 +1,12 @@ -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { BasicTests } from "test/helper/Basic"; -import { GreaterThanZero } from "./GreaterThanZero"; -import { Signal } from "Tone/signal/Signal"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { GreaterThanZero } from "./GreaterThanZero.js"; +import { Signal } from "./Signal.js"; describe("GreaterThanZero", () => { - BasicTests(GreaterThanZero); describe("Comparison", () => { - it("Outputs 0 when the value is less than 0", () => { return ConstantOutput(() => { const signal = new Signal(-1); @@ -46,4 +44,3 @@ describe("GreaterThanZero", () => { }); }); }); - diff --git a/Tone/signal/GreaterThanZero.ts b/Tone/signal/GreaterThanZero.ts index bab08cbe..0c7855e5 100644 --- a/Tone/signal/GreaterThanZero.ts +++ b/Tone/signal/GreaterThanZero.ts @@ -1,10 +1,10 @@ -import { SignalOperator, SignalOperatorOptions } from "./SignalOperator"; -import { Multiply } from "./Multiply"; -import { ToneAudioNode } from "../core/context/ToneAudioNode"; -import { WaveShaper } from "./WaveShaper"; -import { optionsFromArguments } from "../core/util/Defaults"; +import { SignalOperator, SignalOperatorOptions } from "./SignalOperator.js"; +import { Multiply } from "./Multiply.js"; +import { ToneAudioNode } from "../core/context/ToneAudioNode.js"; +import { WaveShaper } from "./WaveShaper.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; -export type GreaterThanZeroOptions = SignalOperatorOptions +export type GreaterThanZeroOptions = SignalOperatorOptions; /** * GreaterThanZero outputs 1 when the input is strictly greater than zero @@ -17,7 +17,6 @@ export type GreaterThanZeroOptions = SignalOperatorOptions * @category Signal */ export class GreaterThanZero extends SignalOperator { - readonly name: string = "GreaterThanZero"; /** @@ -36,7 +35,11 @@ export class GreaterThanZero extends SignalOperator { constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(GreaterThanZero.getDefaults(), arguments))); + super( + Object.assign( + optionsFromArguments(GreaterThanZero.getDefaults(), arguments) + ) + ); this._thresh = this.output = new WaveShaper({ context: this.context, @@ -51,7 +54,7 @@ export class GreaterThanZero extends SignalOperator { }); this._scale = this.input = new Multiply({ context: this.context, - value: 10000 + value: 10000, }); // connections diff --git a/Tone/signal/Multiply.test.ts b/Tone/signal/Multiply.test.ts index f928e67a..1ed4f882 100644 --- a/Tone/signal/Multiply.test.ts +++ b/Tone/signal/Multiply.test.ts @@ -1,19 +1,17 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -// import Test from "test/helper/Test"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Multiply } from "./Multiply"; -// import Multiply from "Tone/signal/Multiply"; -import { Signal } from "./Signal"; -// import Oscillator from "Tone/source/Oscillator"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +// import Test from "../../test/helper/Test"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Multiply } from "./Multiply.js"; +// import Multiply from "Multiply"; +import { Signal } from "./Signal.js"; +// import Oscillator from "../source/Oscillator"; describe("Multiply", () => { - BasicTests(Multiply); describe("Multiplication", () => { - it("handles input and output connections", () => { const mult = new Multiply(); connectFrom().connect(mult, 0); diff --git a/Tone/signal/Multiply.ts b/Tone/signal/Multiply.ts index 9b22b423..7df6ce02 100644 --- a/Tone/signal/Multiply.ts +++ b/Tone/signal/Multiply.ts @@ -1,8 +1,8 @@ -import { Gain } from "../core/context/Gain"; -import { Param } from "../core/context/Param"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Signal, SignalOptions } from "./Signal"; -import { InputNode, OutputNode } from "../core/context/ToneAudioNode"; +import { Gain } from "../core/context/Gain.js"; +import { Param } from "../core/context/Param.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Signal, SignalOptions } from "./Signal.js"; +import { InputNode, OutputNode } from "../core/context/ToneAudioNode.js"; /** * Multiply two incoming signals. Or, if a number is given in the constructor, @@ -23,8 +23,9 @@ import { InputNode, OutputNode } from "../core/context/ToneAudioNode"; * // the output of mult is 20. * @category Signal */ -export class Multiply extends Signal { - +export class Multiply< + TypeName extends "number" | "positive" = "number", +> extends Signal { readonly name: string = "Multiply"; /** @@ -58,16 +59,30 @@ export class Multiply extends constructor(value?: number); constructor(options?: Partial>); constructor() { - super(Object.assign(optionsFromArguments(Multiply.getDefaults(), arguments, ["value"]))); - const options = optionsFromArguments(Multiply.getDefaults(), arguments, ["value"]); + super( + Object.assign( + optionsFromArguments(Multiply.getDefaults(), arguments, [ + "value", + ]) + ) + ); + const options = optionsFromArguments( + Multiply.getDefaults(), + arguments, + ["value"] + ); - this._mult = this.input = this.output = new Gain({ - context: this.context, - minValue: options.minValue, - maxValue: options.maxValue, - }); + this._mult = + this.input = + this.output = + new Gain({ + context: this.context, + minValue: options.minValue, + maxValue: options.maxValue, + }); - this.factor = this._param = this._mult.gain as unknown as Param; + this.factor = this._param = this._mult + .gain as unknown as Param; this.factor.setValueAtTime(options.value, 0); } diff --git a/Tone/signal/Negate.test.ts b/Tone/signal/Negate.test.ts index 49d46283..f56ed58e 100644 --- a/Tone/signal/Negate.test.ts +++ b/Tone/signal/Negate.test.ts @@ -1,14 +1,12 @@ -import { BasicTests } from "test/helper/Basic"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Negate } from "./Negate"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Negate } from "./Negate.js"; +import { Signal } from "./Signal.js"; describe("Negate", () => { - BasicTests(Negate); context("Negating", () => { - it("negateates a positive value", () => { return ConstantOutput(() => { const signal = new Signal(1); diff --git a/Tone/signal/Negate.ts b/Tone/signal/Negate.ts index de21c071..e4135cc9 100644 --- a/Tone/signal/Negate.ts +++ b/Tone/signal/Negate.ts @@ -1,6 +1,6 @@ -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { Multiply } from "./Multiply"; -import { SignalOperator } from "./SignalOperator"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; +import { Multiply } from "./Multiply.js"; +import { SignalOperator } from "./SignalOperator.js"; /** * Negate the incoming signal. i.e. an input signal of 10 will output -10 @@ -12,7 +12,6 @@ import { SignalOperator } from "./SignalOperator"; * @category Signal */ export class Negate extends SignalOperator { - readonly name: string = "Negate"; /** diff --git a/Tone/signal/Pow.test.ts b/Tone/signal/Pow.test.ts index 732b1631..48f3e5ca 100644 --- a/Tone/signal/Pow.test.ts +++ b/Tone/signal/Pow.test.ts @@ -1,21 +1,19 @@ -import { BasicTests } from "test/helper/Basic"; -import { Pow } from "./Pow"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Pow } from "./Pow.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Signal } from "./Signal.js"; describe("Pow", () => { - BasicTests(Pow); context("Exponential Scaling", () => { - it("can do powers of 2", () => { return ConstantOutput(() => { const signal = new Signal(0.3); const pow = new Pow(2); signal.connect(pow); pow.toDestination(); - }, 0.09); + }, 0.09); }); it("can compute negative values and powers less than 1", () => { @@ -24,7 +22,7 @@ describe("Pow", () => { const pow = new Pow(0.5); signal.connect(pow); pow.toDestination(); - }, 0.7); + }, 0.7); }); it("can set a new exponent", () => { @@ -34,7 +32,7 @@ describe("Pow", () => { pow.value = 3; signal.connect(pow); pow.toDestination(); - }, 0.125); + }, 0.125); }); }); }); diff --git a/Tone/signal/Pow.ts b/Tone/signal/Pow.ts index dced525d..ce2c366d 100644 --- a/Tone/signal/Pow.ts +++ b/Tone/signal/Pow.ts @@ -1,7 +1,7 @@ -import { WaveShaper, WaveShaperMappingFn } from "./WaveShaper"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { SignalOperator } from "./SignalOperator"; -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; +import { WaveShaper, WaveShaperMappingFn } from "./WaveShaper.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { SignalOperator } from "./SignalOperator.js"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; export interface PowOptions extends ToneAudioNodeOptions { value: number; @@ -13,11 +13,10 @@ export interface PowOptions extends ToneAudioNodeOptions { * @example * const pow = new Tone.Pow(2); * const sig = new Tone.Signal(0.5).connect(pow); - * // output of pow is 0.25. + * // output of pow is 0.25. * @category Signal */ export class Pow extends SignalOperator { - readonly name: string = "Pow"; private _exponent: number; @@ -34,14 +33,23 @@ export class Pow extends SignalOperator { constructor(value?: number); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(Pow.getDefaults(), arguments, ["value"]))); - const options = optionsFromArguments(Pow.getDefaults(), arguments, ["value"]); + super( + Object.assign( + optionsFromArguments(Pow.getDefaults(), arguments, ["value"]) + ) + ); + const options = optionsFromArguments(Pow.getDefaults(), arguments, [ + "value", + ]); - this._exponentScaler = this.input = this.output = new WaveShaper({ - context: this.context, - mapping: this._expFunc(options.value), - length: 8192, - }); + this._exponentScaler = + this.input = + this.output = + new WaveShaper({ + context: this.context, + mapping: this._expFunc(options.value), + length: 8192, + }); this._exponent = options.value; } diff --git a/Tone/signal/Scale.test.ts b/Tone/signal/Scale.test.ts index 1fdc5f8d..abad2fe3 100644 --- a/Tone/signal/Scale.test.ts +++ b/Tone/signal/Scale.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Scale } from "./Scale"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Scale } from "./Scale.js"; +import { Signal } from "./Signal.js"; describe("Scale", () => { - BasicTests(Scale); context("Scaling", () => { - it("handles input and output connections", () => { const scale = new Scale({ min: 0, max: 100 }); connectFrom().connect(scale); diff --git a/Tone/signal/Scale.ts b/Tone/signal/Scale.ts index ba56aaad..cd020197 100644 --- a/Tone/signal/Scale.ts +++ b/Tone/signal/Scale.ts @@ -1,8 +1,12 @@ -import { InputNode, OutputNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Add } from "./Add"; -import { Multiply } from "./Multiply"; -import { SignalOperator } from "./SignalOperator"; +import { + InputNode, + OutputNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Add } from "./Add.js"; +import { Multiply } from "./Multiply.js"; +import { SignalOperator } from "./SignalOperator.js"; export interface ScaleOptions extends ToneAudioNodeOptions { min: number; @@ -20,8 +24,9 @@ export interface ScaleOptions extends ToneAudioNodeOptions { * // the output of scale equals 75 * @category Signal */ -export class Scale extends SignalOperator { - +export class Scale< + Options extends ScaleOptions = ScaleOptions, +> extends SignalOperator { readonly name: string = "Scale"; input: InputNode; @@ -54,8 +59,18 @@ export class Scale extends SignalOp constructor(min?: number, max?: number); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(Scale.getDefaults(), arguments, ["min", "max"]))); - const options = optionsFromArguments(Scale.getDefaults(), arguments, ["min", "max"]); + super( + Object.assign( + optionsFromArguments(Scale.getDefaults(), arguments, [ + "min", + "max", + ]) + ) + ); + const options = optionsFromArguments(Scale.getDefaults(), arguments, [ + "min", + "max", + ]); this._mult = this.input = new Multiply({ context: this.context, diff --git a/Tone/signal/ScaleExp.test.ts b/Tone/signal/ScaleExp.test.ts index 04c2d5ba..acb6ecf9 100644 --- a/Tone/signal/ScaleExp.test.ts +++ b/Tone/signal/ScaleExp.test.ts @@ -1,15 +1,13 @@ -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { ScaleExp } from "./ScaleExp"; -import { BasicTests } from "test/helper/Basic"; -import { Signal } from "Tone/signal/Signal"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { ScaleExp } from "./ScaleExp.js"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { Signal } from "./Signal.js"; import { expect } from "chai"; describe("ScaleExp", () => { - BasicTests(ScaleExp); context("Scaling", () => { - it("can set the min and max values", () => { const scale = new ScaleExp(-20, 10, 2); scale.min = -0.01; @@ -33,7 +31,7 @@ describe("ScaleExp", () => { const scale = new ScaleExp(0, 1, 3); signal.connect(scale); scale.toDestination(); - }, 0.125); + }, 0.125); }); it("scale a signal between 1 and 3 exponentially", () => { @@ -42,8 +40,7 @@ describe("ScaleExp", () => { const scale = new ScaleExp(1, 3, 2); signal.connect(scale); scale.toDestination(); - }, 1.5); + }, 1.5); }); }); }); - diff --git a/Tone/signal/ScaleExp.ts b/Tone/signal/ScaleExp.ts index a66b75e1..9aa8f837 100644 --- a/Tone/signal/ScaleExp.ts +++ b/Tone/signal/ScaleExp.ts @@ -1,7 +1,7 @@ -import { Scale, ScaleOptions } from "./Scale"; -import { Positive } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Pow } from "./Pow"; +import { Scale, ScaleOptions } from "./Scale.js"; +import { Positive } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Pow } from "./Pow.js"; export interface ScaleExpOptions extends ScaleOptions { exponent: Positive; @@ -17,7 +17,6 @@ export interface ScaleExpOptions extends ScaleOptions { * @category Signal */ export class ScaleExp extends Scale { - readonly name: string = "ScaleExp"; /** @@ -33,8 +32,20 @@ export class ScaleExp extends Scale { constructor(min?: number, max?: number, exponent?: number); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"]))); - const options = optionsFromArguments(ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"]); + super( + Object.assign( + optionsFromArguments(ScaleExp.getDefaults(), arguments, [ + "min", + "max", + "exponent", + ]) + ) + ); + const options = optionsFromArguments( + ScaleExp.getDefaults(), + arguments, + ["min", "max", "exponent"] + ); this.input = this._exp = new Pow({ context: this.context, diff --git a/Tone/signal/Signal.test.ts b/Tone/signal/Signal.test.ts index cb134537..95f1ff3f 100644 --- a/Tone/signal/Signal.test.ts +++ b/Tone/signal/Signal.test.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Offline } from "test/helper/Offline"; -import { Decibels, Frequency, Time } from "Tone/core/type/Units"; -import { Gain } from "../core/context/Gain"; -import { Signal } from "./Signal"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Decibels, Frequency, Time } from "../core/type/Units.js"; +import { Gain } from "../core/context/Gain.js"; +import { Signal } from "./Signal.js"; describe("Signal", () => { - BasicTests(Signal); context("Signal Rate Value", () => { - it("has 1 input and 1 output", () => { const signal = new Signal(); expect(signal.numberOfInputs).to.equal(1); @@ -77,8 +75,7 @@ describe("Signal", () => { }); context("Scheduling", () => { - - afterEach(done => { + afterEach((done) => { setTimeout(() => done(), 100); }); @@ -94,7 +91,7 @@ describe("Signal", () => { }); it("can linear ramp from the current value to another value in the future", async () => { - const buffer = await Offline(context => { + const buffer = await Offline((context) => { const sig = new Signal(0).toDestination(); sig.setValueAtTime(0, 0); sig.linearRampToValueAtTime(1, 0.1); @@ -105,7 +102,7 @@ describe("Signal", () => { }); it("can set a ramp point and then ramp from there", async () => { - const buffer = await Offline(context => { + const buffer = await Offline((context) => { const sig = new Signal(0).toDestination(); sig.setRampPoint(0); sig.linearRampToValueAtTime(1, 1); @@ -118,7 +115,7 @@ describe("Signal", () => { }); it("can schedule multiple automations", async () => { - const buffer = await Offline(context => { + const buffer = await Offline((context) => { const sig = new Signal(0).toDestination(); sig.setValueAtTime(0, 0); sig.linearRampToValueAtTime(0.5, 0.5); @@ -212,7 +209,7 @@ describe("Signal", () => { const sig = new Signal(1).toDestination(); sig.exponentialRampTo(2, 1); sig.cancelAndHoldAtTime(0.5); - }, 1).then(buffer => { + }, 1).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(1, 0.1); expect(buffer.getValueAtTime(0.25)).to.be.closeTo(1.2, 0.1); expect(buffer.getValueAtTime(0.5)).to.be.closeTo(1.4, 0.1); @@ -334,7 +331,10 @@ describe("Signal", () => { sig.setValueCurveAtTime([0, 1, 0.5, 0.2], 0, 1); }, 1).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.01); - expect(buffer.getValueAtTime(0.33 / 2)).to.be.closeTo(0.5, 0.01); + expect(buffer.getValueAtTime(0.33 / 2)).to.be.closeTo( + 0.5, + 0.01 + ); expect(buffer.getValueAtTime(0.33)).to.be.closeTo(1, 0.02); expect(buffer.getValueAtTime(0.66)).to.be.closeTo(0.5, 0.02); expect(buffer.getValueAtTime(0.99)).to.be.closeTo(0.2, 0.02); @@ -347,10 +347,22 @@ describe("Signal", () => { sig.setValueCurveAtTime([0, 1, 0.5, 0.2], 0.5, 1); }, 1.5).then((buffer) => { expect(buffer.getValueAtTime(0 + 0.5)).to.be.closeTo(0, 0.01); - expect(buffer.getValueAtTime(0.33 / 2 + 0.5)).to.be.closeTo(0.5, 0.01); - expect(buffer.getValueAtTime(0.33 + 0.5)).to.be.closeTo(1, 0.02); - expect(buffer.getValueAtTime(0.66 + 0.5)).to.be.closeTo(0.5, 0.02); - expect(buffer.getValueAtTime(0.99 + 0.5)).to.be.closeTo(0.2, 0.02); + expect(buffer.getValueAtTime(0.33 / 2 + 0.5)).to.be.closeTo( + 0.5, + 0.01 + ); + expect(buffer.getValueAtTime(0.33 + 0.5)).to.be.closeTo( + 1, + 0.02 + ); + expect(buffer.getValueAtTime(0.66 + 0.5)).to.be.closeTo( + 0.5, + 0.02 + ); + expect(buffer.getValueAtTime(0.99 + 0.5)).to.be.closeTo( + 0.2, + 0.02 + ); }); }); @@ -378,7 +390,6 @@ describe("Signal", () => { }); context("Units", () => { - it("can be created with specific units", () => { const signal = new Signal(0, "bpm"); expect(signal.units).to.equal("bpm"); @@ -441,7 +452,7 @@ describe("Signal", () => { expect(signal.value).to.be.closeTo(1, 0.01); signal.dispose(); }); - + it("converts AudioRange units", () => { expect(() => { new Signal(-2, "audioRange"); @@ -450,7 +461,7 @@ describe("Signal", () => { expect(signal.value).to.be.closeTo(-1, 0.01); signal.dispose(); }); - + it("converts Positive units", () => { expect(() => { new Signal(-2, "positive"); @@ -459,11 +470,9 @@ describe("Signal", () => { expect(signal.value).to.be.closeTo(100, 0.01); signal.dispose(); }); - }); context("Transport Syncing", () => { - it("maintains its original value after being synced to the transport", () => { return ConstantOutput(({ transport }) => { const sig = new Signal(3).toDestination(); diff --git a/Tone/signal/Signal.ts b/Tone/signal/Signal.ts index bc667ac6..f1e52074 100644 --- a/Tone/signal/Signal.ts +++ b/Tone/signal/Signal.ts @@ -1,13 +1,19 @@ -import { AbstractParam } from "../core/context/AbstractParam"; -import { Param } from "../core/context/Param"; -import { InputNode, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { connect } from "../core/context/ToneAudioNode"; -import { Time, UnitMap, UnitName } from "../core/type/Units"; -import { isAudioParam } from "../core/util/AdvancedTypeCheck"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { ToneConstantSource } from "./ToneConstantSource"; - -export interface SignalOptions extends ToneAudioNodeOptions { +import { AbstractParam } from "../core/context/AbstractParam.js"; +import { Param } from "../core/context/Param.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { connect } from "../core/context/ToneAudioNode.js"; +import { Time, UnitMap, UnitName } from "../core/type/Units.js"; +import { isAudioParam } from "../core/util/AdvancedTypeCheck.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { ToneConstantSource } from "./ToneConstantSource.js"; + +export interface SignalOptions + extends ToneAudioNodeOptions { value: UnitMap[TypeName]; units: TypeName; convert: boolean; @@ -34,9 +40,10 @@ export interface SignalOptions extends ToneAudioNodeO * signal.rampTo("C2", 4, "+0.5"); * @category Signal */ -export class Signal extends ToneAudioNode> - implements AbstractParam { - +export class Signal + extends ToneAudioNode> + implements AbstractParam +{ readonly name: string = "Signal"; /** @@ -59,10 +66,17 @@ export class Signal extends ToneAudioNode< constructor(value?: UnitMap[TypeName], units?: TypeName); constructor(options?: Partial>); constructor() { + super( + optionsFromArguments(Signal.getDefaults(), arguments, [ + "value", + "units", + ]) + ); - super(optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"])); - - const options = optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]) as SignalOptions; + const options = optionsFromArguments(Signal.getDefaults(), arguments, [ + "value", + "units", + ]) as SignalOptions; this.output = this._constantSource = new ToneConstantSource({ context: this.context, @@ -122,27 +136,52 @@ export class Signal extends ToneAudioNode< this._param.exponentialRampToValueAtTime(value, time); return this; } - exponentialRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + exponentialRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { this._param.exponentialRampTo(value, rampTime, startTime); return this; } - linearRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + linearRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { this._param.linearRampTo(value, rampTime, startTime); return this; } - targetRampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this { + targetRampTo( + value: UnitMap[TypeName], + rampTime: Time, + startTime?: Time + ): this { this._param.targetRampTo(value, rampTime, startTime); return this; } - exponentialApproachValueAtTime(value: UnitMap[TypeName], time: Time, rampTime: Time): this { + exponentialApproachValueAtTime( + value: UnitMap[TypeName], + time: Time, + rampTime: Time + ): this { this._param.exponentialApproachValueAtTime(value, time, rampTime); return this; } - setTargetAtTime(value: UnitMap[TypeName], startTime: Time, timeConstant: number): this { + setTargetAtTime( + value: UnitMap[TypeName], + startTime: Time, + timeConstant: number + ): this { this._param.setTargetAtTime(value, startTime, timeConstant); return this; } - setValueCurveAtTime(values: UnitMap[TypeName][], startTime: Time, duration: Time, scaling?: number): this { + setValueCurveAtTime( + values: UnitMap[TypeName][], + startTime: Time, + duration: Time, + scaling?: number + ): this { this._param.setValueCurveAtTime(values, startTime, duration, scaling); return this; } @@ -210,9 +249,17 @@ export class Signal extends ToneAudioNode< * @param outputNum the optional output number * @param inputNum the input number */ -export function connectSignal(signal: OutputNode, destination: InputNode, outputNum?: number, inputNum?: number): void { - if (destination instanceof Param || isAudioParam(destination) || - (destination instanceof Signal && destination.override)) { +export function connectSignal( + signal: OutputNode, + destination: InputNode, + outputNum?: number, + inputNum?: number +): void { + if ( + destination instanceof Param || + isAudioParam(destination) || + (destination instanceof Signal && destination.override) + ) { // cancel changes destination.cancelScheduledValues(0); // reset the value diff --git a/Tone/signal/SignalOperator.ts b/Tone/signal/SignalOperator.ts index 14202d70..e920db8d 100644 --- a/Tone/signal/SignalOperator.ts +++ b/Tone/signal/SignalOperator.ts @@ -1,17 +1,28 @@ -import { optionsFromArguments } from "../core/util/Defaults"; -import { InputNode, ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { connectSignal } from "./Signal"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { + InputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { connectSignal } from "./Signal.js"; export type SignalOperatorOptions = ToneAudioNodeOptions; /** * A signal operator has an input and output and modifies the signal. */ -export abstract class SignalOperator extends ToneAudioNode { - +export abstract class SignalOperator< + Options extends SignalOperatorOptions, +> extends ToneAudioNode { constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(SignalOperator.getDefaults(), arguments, ["context"]))); + super( + Object.assign( + optionsFromArguments(SignalOperator.getDefaults(), arguments, [ + "context", + ]) + ) + ); } connect(destination: InputNode, outputNum = 0, inputNum = 0): this { diff --git a/Tone/signal/Subtract.test.ts b/Tone/signal/Subtract.test.ts index 8aed888e..613e3c00 100644 --- a/Tone/signal/Subtract.test.ts +++ b/Tone/signal/Subtract.test.ts @@ -1,15 +1,13 @@ -import { BasicTests } from "test/helper/Basic"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Signal } from "./Signal"; -import { Subtract } from "./Subtract"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { connectFrom, connectTo } from "../../test/helper/Connect.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Signal } from "./Signal.js"; +import { Subtract } from "./Subtract.js"; describe("Subtract", () => { - BasicTests(Subtract); context("Subtraction", () => { - it("handles input and output connections", () => { const subtract = new Subtract(); connectFrom().connect(subtract); diff --git a/Tone/signal/Subtract.ts b/Tone/signal/Subtract.ts index 3c20b7a7..c350ac0f 100644 --- a/Tone/signal/Subtract.ts +++ b/Tone/signal/Subtract.ts @@ -1,9 +1,9 @@ -import { connectSeries } from "../core/context/ToneAudioNode"; -import { Gain } from "../core/context/Gain"; -import { Param } from "../core/context/Param"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { Negate } from "../signal/Negate"; -import { Signal, SignalOptions } from "../signal/Signal"; +import { connectSeries } from "../core/context/ToneAudioNode.js"; +import { Gain } from "../core/context/Gain.js"; +import { Param } from "../core/context/Param.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { Negate } from "../signal/Negate.js"; +import { Signal, SignalOptions } from "../signal/Signal.js"; /** * Subtract the signal connected to the input is subtracted from the signal connected @@ -25,7 +25,6 @@ import { Signal, SignalOptions } from "../signal/Signal"; * @category Signal */ export class Subtract extends Signal { - override = false; readonly name: string = "Subtract"; @@ -54,7 +53,13 @@ export class Subtract extends Signal { constructor(value?: number); constructor(options?: Partial>); constructor() { - super(Object.assign(optionsFromArguments(Subtract.getDefaults(), arguments, ["value"]))); + super( + Object.assign( + optionsFromArguments(Subtract.getDefaults(), arguments, [ + "value", + ]) + ) + ); connectSeries(this._constantSource, this._neg, this._sum); } diff --git a/Tone/signal/SyncedSignal.test.ts b/Tone/signal/SyncedSignal.test.ts index 38eb55bf..3d12475c 100644 --- a/Tone/signal/SyncedSignal.test.ts +++ b/Tone/signal/SyncedSignal.test.ts @@ -1,44 +1,50 @@ -import { SyncedSignal } from "./SyncedSignal"; -import { Offline } from "test/helper/Offline"; +import { SyncedSignal } from "./SyncedSignal.js"; +import { Offline } from "../../test/helper/Offline.js"; import { expect } from "chai"; -import { dbToGain } from "Tone/core/type/Conversions"; -import "../core/clock/Transport"; -import "../core/context/Destination"; -import { BasicTests } from "test/helper/Basic"; +import { dbToGain } from "../core/type/Conversions.js"; +import "../core/clock/Transport.js"; +import "../core/context/Destination.js"; +import { BasicTests } from "../../test/helper/Basic.js"; describe("SyncedSignal", () => { - BasicTests(SyncedSignal); context("Scheduling Events", () => { - it("can schedule a change in the future", () => { const sched = new SyncedSignal(1); sched.setValueAtTime(2, 0.2); sched.dispose(); }); - + it("can schedule setValueAtTime relative to the Transport", () => { - return Offline(({ transport }) => { - const sched = new SyncedSignal(1).toDestination(); - sched.setValueAtTime(2, 0.1); - sched.setValueAtTime(3, 0.2); - transport.start(0.1); - }, 0.4, 1).then((buffer) => { + return Offline( + ({ transport }) => { + const sched = new SyncedSignal(1).toDestination(); + sched.setValueAtTime(2, 0.1); + sched.setValueAtTime(3, 0.2); + transport.start(0.1); + }, + 0.4, + 1 + ).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.1)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.201)).to.be.closeTo(2, 0.07); expect(buffer.getValueAtTime(0.301)).to.be.closeTo(3, 0.07); }); }); - + it("can schedule linearRampToValueAtTime relative to the Transport", () => { - return Offline(({ transport }) => { - const sched = new SyncedSignal(1).toDestination(); - sched.setValueAtTime(1, 0.1); - sched.linearRampToValueAtTime(2, 0.2); - transport.start(0.1); - }, 0.4, 1).then((buffer) => { + return Offline( + ({ transport }) => { + const sched = new SyncedSignal(1).toDestination(); + sched.setValueAtTime(1, 0.1); + sched.linearRampToValueAtTime(2, 0.2); + transport.start(0.1); + }, + 0.4, + 1 + ).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.1)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.2)).to.be.closeTo(1, 0.07); @@ -46,14 +52,18 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(0.301)).to.be.closeTo(2, 0.07); }); }); - + it("can schedule exponentialRampToValueAtTime relative to the Transport", () => { - return Offline(({ transport }) => { - const sched = new SyncedSignal(1).toDestination(); - sched.setValueAtTime(1, 0.1); - sched.exponentialRampToValueAtTime(2, 0.2); - transport.start(0.1); - }, 0.4, 1).then((buffer) => { + return Offline( + ({ transport }) => { + const sched = new SyncedSignal(1).toDestination(); + sched.setValueAtTime(1, 0.1); + sched.exponentialRampToValueAtTime(2, 0.2); + transport.start(0.1); + }, + 0.4, + 1 + ).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.1)).to.be.closeTo(1, 0.07); expect(buffer.getValueAtTime(0.2)).to.be.closeTo(1, 0.07); @@ -61,7 +71,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(0.301)).to.be.closeTo(2, 0.07); }); }); - + it("can get exponential ramp value in the future", () => { let sched; return Offline(({ transport }) => { @@ -72,11 +82,14 @@ describe("SyncedSignal", () => { transport.start(0.1); }, 0.6).then((buffer) => { buffer.forEach((sample, time) => { - expect(sample).to.be.closeTo(sched.getValueAtTime(time - 0.1), 0.07); + expect(sample).to.be.closeTo( + sched.getValueAtTime(time - 0.1), + 0.07 + ); }); }); }); - + it("can get exponential approach in the future", () => { let sched; return Offline(({ transport }) => { @@ -86,11 +99,14 @@ describe("SyncedSignal", () => { transport.start(0.1); }, 0.6).then((buffer) => { buffer.forEach((sample, time) => { - expect(sample).to.be.closeTo(sched.getValueAtTime(time - 0.1), 0.07); + expect(sample).to.be.closeTo( + sched.getValueAtTime(time - 0.1), + 0.07 + ); }); }); }); - + it("can loop the signal when the Transport loops", () => { let sched; return Offline(({ transport }) => { @@ -107,7 +123,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(1.5)).to.be.closeTo(2, 0.01); }); }); - + it("can get set a curve in the future", () => { let sched; return Offline(({ transport }) => { @@ -116,11 +132,14 @@ describe("SyncedSignal", () => { transport.start(0.2); }, 1).then((buffer) => { buffer.forEach((sample, time) => { - expect(sample).to.be.closeTo(sched.getValueAtTime(time - 0.2), 0.07); + expect(sample).to.be.closeTo( + sched.getValueAtTime(time - 0.2), + 0.07 + ); }); }); }); - + it("can scale a curve value", () => { let sched; return Offline(({ transport }) => { @@ -133,7 +152,7 @@ describe("SyncedSignal", () => { }); }); }); - + it("can schedule a linear ramp between two times", () => { let sched; return Offline(({ transport }) => { @@ -148,7 +167,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(2)).to.closeTo(1, 0.1); }); }); - + it("can get exponential ramp value between two times", () => { let sched; return Offline(({ transport }) => { @@ -163,7 +182,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(2)).to.closeTo(3, 0.1); }); }); - + it("can cancel and hold a scheduled value", () => { let sched; return Offline(({ transport }) => { @@ -179,7 +198,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(0.75)).to.be.closeTo(0.5, 0.1); }); }); - + it("can cancel a scheduled value", () => { let sched; return Offline(({ transport }) => { @@ -196,7 +215,7 @@ describe("SyncedSignal", () => { expect(buffer.getValueAtTime(0.75)).to.be.closeTo(1, 0.1); }); }); - + it("can automate values with different units", () => { let sched; return Offline(({ transport }) => { @@ -208,7 +227,10 @@ describe("SyncedSignal", () => { }, 1.2).then((buffer) => { buffer.forEach((sample, time) => { if (time < 0.5) { - expect(sample).to.be.within(dbToGain(-12.01), dbToGain(-4.99)); + expect(sample).to.be.within( + dbToGain(-12.01), + dbToGain(-4.99) + ); } else if (time < 1) { expect(sample).to.be.closeTo(dbToGain(-12), 0.1); } else if (time > 1.1) { @@ -244,4 +266,3 @@ describe("SyncedSignal", () => { }); }); }); - diff --git a/Tone/signal/SyncedSignal.ts b/Tone/signal/SyncedSignal.ts index fbdd3029..be373f80 100644 --- a/Tone/signal/SyncedSignal.ts +++ b/Tone/signal/SyncedSignal.ts @@ -1,19 +1,27 @@ -import { Signal, SignalOptions } from "./Signal"; -import { NormalRange, Seconds, Time, TransportTime, UnitMap, UnitName } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { TransportTimeClass } from "../core/type/TransportTime"; -import { ToneConstantSource } from "./ToneConstantSource"; -import { OutputNode } from "../core/context/ToneAudioNode"; -import type { TransportClass } from "../core/clock/Transport"; +import { Signal, SignalOptions } from "./Signal.js"; +import { + NormalRange, + Seconds, + Time, + TransportTime, + UnitMap, + UnitName, +} from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { TransportTimeClass } from "../core/type/TransportTime.js"; +import { ToneConstantSource } from "./ToneConstantSource.js"; +import { OutputNode } from "../core/context/ToneAudioNode.js"; +import type { TransportClass } from "../core/clock/Transport.js"; /** * Adds the ability to synchronize the signal to the {@link TransportClass} * @category Signal */ -export class SyncedSignal extends Signal { - +export class SyncedSignal< + TypeName extends UnitName = "number", +> extends Signal { readonly name: string = "SyncedSignal"; - + /** * Don't override when something is connected to the input */ @@ -43,12 +51,22 @@ export class SyncedSignal extends Signal>); constructor() { - - super(optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"])); - const options = optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]) as SignalOptions; + super( + optionsFromArguments(Signal.getDefaults(), arguments, [ + "value", + "units", + ]) + ); + const options = optionsFromArguments(Signal.getDefaults(), arguments, [ + "value", + "units", + ]) as SignalOptions; this._lastVal = options.value; - this._synced = this.context.transport.scheduleRepeat(this._onTick.bind(this), "1i"); + this._synced = this.context.transport.scheduleRepeat( + this._onTick.bind(this), + "1i" + ); this._syncedCallback = this._anchorValue.bind(this); this.context.transport.on("start", this._syncedCallback); @@ -60,7 +78,7 @@ export class SyncedSignal extends Signal({ + this._constantSource = this.output = new ToneConstantSource({ context: this.context, offset: options.value, units: options.units, @@ -91,73 +109,133 @@ export class SyncedSignal extends Signal { - BasicTests(ToneConstantSource); context("Constructor", () => { - it("can be constructed with an offset", () => { const source = new ToneConstantSource(330); expect(source.offset.value).to.equal(330); @@ -30,39 +27,34 @@ describe("ToneConstantSource", () => { expect(source.offset.value).to.be.closeTo(2, 0.01); source.dispose(); }); - }); context("onended", () => { + it("invokes the onended callback in the online context", (done) => { + const source = new ToneConstantSource(); + source.start(); + source.stop("+0.3"); + const now = source.now(); + source.onended = () => { + expect(source.now() - now).to.be.within(0.25, 0.5); + source.dispose(); + done(); + }; + }); - if (ONLINE_TESTING) { - - it("invokes the onended callback in the online context", (done) => { - const source = new ToneConstantSource(); - source.start(); - source.stop("+0.3"); - const now = source.now(); - source.onended = () => { - expect(source.now() - now).to.be.within(0.25, 0.5); - source.dispose(); - done(); - }; - }); - - it("invokes the onended callback only once in the online context", (done) => { - const source = new ToneConstantSource(); - source.start(); - source.stop("+0.1"); - source.stop("+0.2"); - source.stop("+0.3"); - const now = source.now(); - source.onended = () => { - expect(source.now() - now).to.be.within(0.25, 0.5); - source.dispose(); - done(); - }; - }); - } + it("invokes the onended callback only once in the online context", (done) => { + const source = new ToneConstantSource(); + source.start(); + source.stop("+0.1"); + source.stop("+0.2"); + source.stop("+0.3"); + const now = source.now(); + source.onended = () => { + expect(source.now() - now).to.be.within(0.25, 0.5); + source.dispose(); + done(); + }; + }); it("invokes the onended callback in the offline context", () => { let wasInvoked = false; @@ -101,7 +93,6 @@ describe("ToneConstantSource", () => { }); context("Scheduling", () => { - it("throw an error if start is called multiple time", () => { const source = new ToneConstantSource(); source.start(); @@ -115,7 +106,7 @@ describe("ToneConstantSource", () => { return Offline(() => { const source = new ToneConstantSource().toDestination(); source.start(0).stop(0.1); - }, 0.4).then(buffer => { + }, 0.4).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.above(0); expect(buffer.getValueAtTime(0.09)).to.be.above(0); expect(buffer.getValueAtTime(0.1)).to.equal(0); @@ -134,38 +125,35 @@ describe("ToneConstantSource", () => { }); }); - if (ONLINE_TESTING) { + it("clamps start time to the currentTime", () => { + const source = new ToneConstantSource(); + source.start(0); + const currentTime = source.context.currentTime; + expect(source.getStateAtTime(0)).to.equal("stopped"); + expect(source.getStateAtTime(currentTime)).to.equal("started"); + source.dispose(); + }); - it("clamps start time to the currentTime", () => { - const source = new ToneConstantSource(); - source.start(0); - const currentTime = source.context.currentTime; - expect(source.getStateAtTime(0)).to.equal("stopped"); - expect(source.getStateAtTime(currentTime)).to.equal("started"); + it("clamps stop time to the currentTime", (done) => { + const source = new ToneConstantSource(); + source.start(0); + let currentTime = source.context.currentTime; + expect(source.getStateAtTime(0)).to.equal("stopped"); + expect(source.getStateAtTime(currentTime)).to.equal("started"); + setTimeout(() => { + currentTime = source.now(); + source.stop(0); + expect(source.getStateAtTime(currentTime + 0.01)).to.equal( + "stopped" + ); source.dispose(); - }); - - it("clamps stop time to the currentTime", (done) => { - const source = new ToneConstantSource(); - source.start(0); - let currentTime = source.context.currentTime; - expect(source.getStateAtTime(0)).to.equal("stopped"); - expect(source.getStateAtTime(currentTime)).to.equal("started"); - setTimeout(() => { - currentTime = source.now(); - source.stop(0); - expect(source.getStateAtTime(currentTime + 0.01)).to.equal("stopped"); - source.dispose(); - done(); - }, 100); - }); - } + done(); + }, 100); + }); }); context("State", () => { - it("reports the right state", () => { - return Offline(() => { const source = new ToneConstantSource(); source.start(0); @@ -182,7 +170,6 @@ describe("ToneConstantSource", () => { }); it("can call stop multiple times, takes the last value", () => { - return Offline(() => { const source = new ToneConstantSource(); source.start(0); diff --git a/Tone/signal/ToneConstantSource.ts b/Tone/signal/ToneConstantSource.ts index 294d7715..a012059d 100644 --- a/Tone/signal/ToneConstantSource.ts +++ b/Tone/signal/ToneConstantSource.ts @@ -1,10 +1,14 @@ -import { connect } from "../core/context/ToneAudioNode"; -import { Param } from "../core/context/Param"; -import { Seconds, Time, UnitMap, UnitName } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { OneShotSource, OneShotSourceOptions } from "../source/OneShotSource"; +import { connect } from "../core/context/ToneAudioNode.js"; +import { Param } from "../core/context/Param.js"; +import { Seconds, Time, UnitMap, UnitName } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { + OneShotSource, + OneShotSourceOptions, +} from "../source/OneShotSource.js"; -export interface ToneConstantSourceOptions extends OneShotSourceOptions { +export interface ToneConstantSourceOptions + extends OneShotSourceOptions { convert: boolean; offset: UnitMap[TypeName]; units: TypeName; @@ -17,8 +21,9 @@ export interface ToneConstantSourceOptions extends On * Adds the ability to reschedule the stop method. * @category Signal */ -export class ToneConstantSource extends OneShotSource> { - +export class ToneConstantSource< + TypeName extends UnitName = "number", +> extends OneShotSource> { readonly name: string = "ToneConstantSource"; /** @@ -37,9 +42,16 @@ export class ToneConstantSource extends On constructor(offset: UnitMap[TypeName]); constructor(options?: Partial>); constructor() { - - super(optionsFromArguments(ToneConstantSource.getDefaults(), arguments, ["offset"])); - const options = optionsFromArguments(ToneConstantSource.getDefaults(), arguments, ["offset"]); + super( + optionsFromArguments(ToneConstantSource.getDefaults(), arguments, [ + "offset", + ]) + ); + const options = optionsFromArguments( + ToneConstantSource.getDefaults(), + arguments, + ["offset"] + ); connect(this._source, this._gainNode); diff --git a/Tone/signal/WaveShaper.test.ts b/Tone/signal/WaveShaper.test.ts index 1e51e695..4b40331e 100644 --- a/Tone/signal/WaveShaper.test.ts +++ b/Tone/signal/WaveShaper.test.ts @@ -1,16 +1,14 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Offline } from "test/helper/Offline"; -import { Signal } from "./Signal"; -import { WaveShaper } from "./WaveShaper"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Offline } from "../../test/helper/Offline.js"; +import { Signal } from "./Signal.js"; +import { WaveShaper } from "./WaveShaper.js"; describe("WaveShaper", () => { - BasicTests(WaveShaper); describe("Construction Options", () => { - it("can be constructed with an array", () => { const waveshaper = new WaveShaper([1, 2, 3, 4, 5, 6]); expect(waveshaper.curve && waveshaper.curve[0]).to.equal(1); @@ -42,11 +40,9 @@ describe("WaveShaper", () => { waveshaper.oversample = "3x"; }).to.throw(Error); }); - }); describe("Logic", () => { - it("shapes the output of the incoming signal", () => { return ConstantOutput(() => { const signal = new Signal(1); @@ -86,10 +82,9 @@ describe("WaveShaper", () => { signal.linearRampToValueAtTime(1, 1); }, 1).then((buffer) => { buffer.forEach((sample, time) => { - expect(sample).to.be.closeTo(2 * ((time * 2) - 1), 0.005); + expect(sample).to.be.closeTo(2 * (time * 2 - 1), 0.005); }); }); }); - }); }); diff --git a/Tone/signal/WaveShaper.ts b/Tone/signal/WaveShaper.ts index b46463d6..5f59274d 100644 --- a/Tone/signal/WaveShaper.ts +++ b/Tone/signal/WaveShaper.ts @@ -1,9 +1,9 @@ -import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { isArray, isFunction } from "../core/util/TypeCheck"; -import { assert } from "../core/util/Debug"; -import { Signal } from "./Signal"; -import { SignalOperator } from "./SignalOperator"; +import { ToneAudioNodeOptions } from "../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { isArray, isFunction } from "../core/util/TypeCheck.js"; +import { assert } from "../core/util/Debug.js"; +import { Signal } from "./Signal.js"; +import { SignalOperator } from "./SignalOperator.js"; export type WaveShaperMappingFn = (value: number, index?: number) => number; @@ -27,7 +27,6 @@ interface WaveShaperOptions extends ToneAudioNodeOptions { * @category Signal */ export class WaveShaper extends SignalOperator { - readonly name: string = "WaveShaper"; /** @@ -60,10 +59,24 @@ export class WaveShaper extends SignalOperator { constructor(mapping?: WaveShaperMapping, length?: number); constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(WaveShaper.getDefaults(), arguments, ["mapping", "length"]))); - const options = optionsFromArguments(WaveShaper.getDefaults(), arguments, ["mapping", "length"]); - - if (isArray(options.mapping) || options.mapping instanceof Float32Array) { + super( + Object.assign( + optionsFromArguments(WaveShaper.getDefaults(), arguments, [ + "mapping", + "length", + ]) + ) + ); + const options = optionsFromArguments( + WaveShaper.getDefaults(), + arguments, + ["mapping", "length"] + ); + + if ( + isArray(options.mapping) || + options.mapping instanceof Float32Array + ) { this.curve = Float32Array.from(options.mapping); } else if (isFunction(options.mapping)) { this.setMap(options.mapping, options.length); @@ -120,8 +133,13 @@ export class WaveShaper extends SignalOperator { } set oversample(oversampling: OverSampleType) { - const isOverSampleType = ["none", "2x", "4x"].some(str => str.includes(oversampling)); - assert(isOverSampleType, "oversampling must be either 'none', '2x', or '4x'"); + const isOverSampleType = ["none", "2x", "4x"].some((str) => + str.includes(oversampling) + ); + assert( + isOverSampleType, + "oversampling must be either 'none', '2x', or '4x'" + ); this._shaper.oversample = oversampling; } diff --git a/Tone/signal/Zero.test.ts b/Tone/signal/Zero.test.ts index 8c2d6b67..065d617a 100644 --- a/Tone/signal/Zero.test.ts +++ b/Tone/signal/Zero.test.ts @@ -1,14 +1,12 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { ConstantOutput } from "test/helper/ConstantOutput"; -import { Zero } from "./Zero"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { ConstantOutput } from "../../test/helper/ConstantOutput.js"; +import { Zero } from "./Zero.js"; describe("Zero", () => { - BasicTests(Zero); context("Zero", () => { - it("has 0 inputs and 1 output", () => { const zero = new Zero(); expect(zero.numberOfInputs).to.equal(0); @@ -17,9 +15,13 @@ describe("Zero", () => { }); it("always outputs 0", () => { - return ConstantOutput(() => { - new Zero().toDestination(); - }, 0, 0); + return ConstantOutput( + () => { + new Zero().toDestination(); + }, + 0, + 0 + ); }); }); }); diff --git a/Tone/signal/Zero.ts b/Tone/signal/Zero.ts index 7d8a9cc0..93717787 100644 --- a/Tone/signal/Zero.ts +++ b/Tone/signal/Zero.ts @@ -1,7 +1,11 @@ -import { Gain } from "../core/context/Gain"; -import { connect, disconnect, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { SignalOperator } from "./SignalOperator"; +import { Gain } from "../core/context/Gain.js"; +import { + connect, + disconnect, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { SignalOperator } from "./SignalOperator.js"; /** * Tone.Zero outputs 0's at audio-rate. The reason this has to be @@ -10,7 +14,6 @@ import { SignalOperator } from "./SignalOperator"; * @category Signal */ export class Zero extends SignalOperator { - readonly name: string = "Zero"; /** @@ -30,7 +33,9 @@ export class Zero extends SignalOperator { constructor(options?: Partial); constructor() { - super(Object.assign(optionsFromArguments(Zero.getDefaults(), arguments))); + super( + Object.assign(optionsFromArguments(Zero.getDefaults(), arguments)) + ); connect(this.context.getConstant(0), this._gain); } diff --git a/Tone/signal/index.ts b/Tone/signal/index.ts index 410a8c4f..16ac8b28 100644 --- a/Tone/signal/index.ts +++ b/Tone/signal/index.ts @@ -1,16 +1,16 @@ -export * from "./Add"; -export * from "./Abs"; -export * from "./AudioToGain"; -export * from "./GainToAudio"; -export * from "./GreaterThan"; -export * from "./GreaterThanZero"; -export * from "./Multiply"; -export * from "./Negate"; -export * from "./Pow"; -export * from "./Signal"; -export * from "./Scale"; -export * from "./ScaleExp"; -export * from "./Subtract"; -export * from "./SyncedSignal"; -export * from "./WaveShaper"; -export * from "./Zero"; +export * from "./Add.js"; +export * from "./Abs.js"; +export * from "./AudioToGain.js"; +export * from "./GainToAudio.js"; +export * from "./GreaterThan.js"; +export * from "./GreaterThanZero.js"; +export * from "./Multiply.js"; +export * from "./Negate.js"; +export * from "./Pow.js"; +export * from "./Signal.js"; +export * from "./Scale.js"; +export * from "./ScaleExp.js"; +export * from "./Subtract.js"; +export * from "./SyncedSignal.js"; +export * from "./WaveShaper.js"; +export * from "./Zero.js"; diff --git a/Tone/source/Noise.test.ts b/Tone/source/Noise.test.ts index c3e16bab..a880ae02 100644 --- a/Tone/source/Noise.test.ts +++ b/Tone/source/Noise.test.ts @@ -1,25 +1,27 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { SourceTests } from "test/helper/SourceTests"; -import { Noise } from "./Noise"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { CompareToFile } from "../../test/helper/CompareToFile.js"; +import { OutputAudio } from "../../test/helper/OutputAudio.js"; +import { SourceTests } from "../../test/helper/SourceTests.js"; +import { Noise } from "./Noise.js"; describe("Noise", () => { - // run the common tests BasicTests(Noise); SourceTests(Noise); it("matches a file", () => { - return CompareToFile(() => { - const noise = new Noise().toDestination(); - noise.start(0.1).stop(0.2); - }, "noise.wav", 9); + return CompareToFile( + () => { + const noise = new Noise().toDestination(); + noise.start(0.1).stop(0.2); + }, + "noise.wav", + 9 + ); }); context("Get/Set", () => { - it("can be constructed with an options object", () => { const noise = new Noise({ type: "brown", @@ -44,7 +46,6 @@ describe("Noise", () => { expect(noise.playbackRate).to.equal(3); }); }); - }); context("Fades", () => { @@ -64,11 +65,10 @@ describe("Noise", () => { }); context("Type", () => { - it("can be set to 3 noise types", () => { const noise = new Noise(); const types = ["white", "brown", "pink"]; - types.forEach(type => { + types.forEach((type) => { // @ts-ignore noise.type = type; expect(noise.type).to.equal(type); diff --git a/Tone/source/Noise.ts b/Tone/source/Noise.ts index 6d9c8f32..62a32e5d 100644 --- a/Tone/source/Noise.ts +++ b/Tone/source/Noise.ts @@ -1,9 +1,9 @@ -import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer"; -import { Positive, Time } from "../core/type/Units"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { assert } from "../core/util/Debug"; -import { Source, SourceOptions } from "../source/Source"; -import { ToneBufferSource } from "./buffer/ToneBufferSource"; +import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js"; +import { Positive, Time } from "../core/type/Units.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { assert } from "../core/util/Debug.js"; +import { Source, SourceOptions } from "../source/Source.js"; +import { ToneBufferSource } from "./buffer/ToneBufferSource.js"; export type NoiseType = "white" | "brown" | "pink"; @@ -35,7 +35,6 @@ export interface NoiseOptions extends SourceOptions { * @category Source */ export class Noise extends Source { - readonly name: string = "Noise"; /** @@ -71,7 +70,9 @@ export class Noise extends Source { constructor(options?: Partial); constructor() { super(optionsFromArguments(Noise.getDefaults(), arguments, ["type"])); - const options = optionsFromArguments(Noise.getDefaults(), arguments, ["type"]); + const options = optionsFromArguments(Noise.getDefaults(), arguments, [ + "type", + ]); this._playbackRate = options.playbackRate; this.type = options.type; @@ -138,7 +139,10 @@ export class Noise extends Source { onended: () => this.onstop(this), playbackRate: this._playbackRate, }).connect(this.output); - this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001)); + this._source.start( + this.toSeconds(time), + Math.random() * (buffer.duration - 0.001) + ); } /** @@ -234,7 +238,7 @@ const _noiseBuffers = { let lastOut = 0.0; for (let i = 0; i < BUFFER_LENGTH; i++) { const white = Math.random() * 2 - 1; - channel[i] = (lastOut + (0.02 * white)) / 1.02; + channel[i] = (lastOut + 0.02 * white) / 1.02; lastOut = channel[i]; channel[i] *= 3.5; // (roughly) compensate for gain } @@ -256,11 +260,12 @@ const _noiseBuffers = { const white = Math.random() * 2 - 1; b0 = 0.99886 * b0 + white * 0.0555179; b1 = 0.99332 * b1 + white * 0.0750759; - b2 = 0.96900 * b2 + white * 0.1538520; - b3 = 0.86650 * b3 + white * 0.3104856; - b4 = 0.55000 * b4 + white * 0.5329522; - b5 = -0.7616 * b5 - white * 0.0168980; - channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; + channel[i] = + b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; channel[i] *= 0.11; // (roughly) compensate for gain b6 = white * 0.115926; } diff --git a/Tone/source/OneShotSource.ts b/Tone/source/OneShotSource.ts index c87590d3..0e7bb95a 100644 --- a/Tone/source/OneShotSource.ts +++ b/Tone/source/OneShotSource.ts @@ -1,12 +1,12 @@ -import { Gain } from "../core/context/Gain"; +import { Gain } from "../core/context/Gain.js"; import { ToneAudioNode, ToneAudioNodeOptions, -} from "../core/context/ToneAudioNode"; -import { GainFactor, Seconds, Time } from "../core/type/Units"; -import { noOp } from "../core/util/Interface"; -import { assert } from "../core/util/Debug"; -import { BasicPlaybackState } from "../core/util/StateTimeline"; +} from "../core/context/ToneAudioNode.js"; +import { GainFactor, Seconds, Time } from "../core/type/Units.js"; +import { noOp } from "../core/util/Interface.js"; +import { assert } from "../core/util/Debug.js"; +import { BasicPlaybackState } from "../core/util/StateTimeline.js"; export type OneShotSourceCurve = "linear" | "exponential"; @@ -23,7 +23,7 @@ export interface OneShotSourceOptions extends ToneAudioNodeOptions { * Base class for fire-and-forget nodes */ export abstract class OneShotSource< - Options extends ToneAudioNodeOptions + Options extends ToneAudioNodeOptions, > extends ToneAudioNode { /** * The callback to invoke after the @@ -217,7 +217,7 @@ export abstract class OneShotSource< /** * Get the playback state at the given time */ - getStateAtTime = function(time: Time): BasicPlaybackState { + getStateAtTime = function (time: Time): BasicPlaybackState { const computedTime = this.toSeconds(time); if ( this._startTime !== -1 && diff --git a/Tone/source/Source.test.ts b/Tone/source/Source.test.ts index 10df2675..8a1d9543 100644 --- a/Tone/source/Source.test.ts +++ b/Tone/source/Source.test.ts @@ -1,13 +1,11 @@ import { expect } from "chai"; -import { atTime, Offline } from "test/helper/Offline"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { ToneAudioBuffer } from "Tone/core"; -import { getContext } from "Tone/core/Global"; -import { Player } from "./buffer/Player"; -import { Oscillator } from "./oscillator/Oscillator"; +import { atTime, Offline } from "../../test/helper/Offline.js"; +import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js"; +import { getContext } from "../core/Global.js"; +import { Player } from "./buffer/Player.js"; +import { Oscillator } from "./oscillator/Oscillator.js"; describe("Source", () => { - it("can be started and stopped", () => { const source = new Oscillator(); source.start(0); @@ -99,34 +97,31 @@ describe("Source", () => { }, 2); }); - if (ONLINE_TESTING) { + it("clamps start time to the currentTime", (done) => { + const source = new Oscillator(); + expect(source.state).to.equal("stopped"); + source.start(0); + setTimeout(() => { + expect(source.state).to.equal("started"); + source.dispose(); + done(); + }, 10); + }); - it("clamps start time to the currentTime", (done) => { - const source = new Oscillator(); - expect(source.state).to.equal("stopped"); - source.start(0); + it("clamps stop time to the currentTime", (done) => { + const source = new Oscillator(); + expect(source.state).to.equal("stopped"); + source.start(0); + setTimeout(() => { + expect(source.state).to.equal("started"); + source.stop(0); setTimeout(() => { - expect(source.state).to.equal("started"); + expect(source.state).to.equal("stopped"); source.dispose(); done(); }, 10); - }); - - it("clamps stop time to the currentTime", (done) => { - const source = new Oscillator(); - expect(source.state).to.equal("stopped"); - source.start(0); - setTimeout(() => { - expect(source.state).to.equal("started"); - source.stop(0); - setTimeout(() => { - expect(source.state).to.equal("stopped"); - source.dispose(); - done(); - }, 10); - }, 10); - }); - } + }, 10); + }); it("correctly returns the scheduled play state", () => { return Offline(() => { @@ -156,7 +151,6 @@ describe("Source", () => { }); context("sync", () => { - const ramp = new Float32Array(getContext().sampleRate); ramp.forEach((val, index) => { ramp[index] = index / getContext().sampleRate; @@ -246,7 +240,9 @@ describe("Source", () => { it.skip("can sync schedule multiple starts", () => { return Offline(({ transport }) => { - const buff = ToneAudioBuffer.fromArray(new Float32Array(1024).map(v => 1)); + const buff = ToneAudioBuffer.fromArray( + new Float32Array(1024).map((v) => 1) + ); const source = new Player(buff); source.sync().start(0.1).start(0.3); transport.start(0); @@ -270,7 +266,7 @@ describe("Source", () => { transport.start(0, 0.1); expect(source.state).to.equal("stopped"); - return time => { + return (time) => { if (time > 0.21 && time < 0.29) { expect(source.state).to.equal("started"); } else if (time > 0.31) { @@ -327,7 +323,7 @@ describe("Source", () => { const source = new Player(rampBuffer).toDestination(); source.sync().start(0.2, 0.1).stop(0.3); transport.start(0.2); - }, 0.7).then(output => { + }, 0.7).then((output) => { expect(output.getValueAtTime(0.41)).to.be.closeTo(0.1, 0.01); expect(output.getValueAtTime(0.45)).to.be.closeTo(0.15, 0.001); expect(output.getValueAtTime(0.5)).to.be.equal(0); @@ -339,7 +335,7 @@ describe("Source", () => { const source = new Player(rampBuffer).toDestination(); source.sync().start(0.2, 0.1).stop(0.4); transport.start(0.2, 0.1); - }, 0.7).then(output => { + }, 0.7).then((output) => { expect(output.getValueAtTime(0.21)).to.be.closeTo(0.0, 0.01); expect(output.getValueAtTime(0.31)).to.be.closeTo(0.1, 0.01); expect(output.getValueAtTime(0.41)).to.be.closeTo(0.2, 0.01); @@ -353,7 +349,7 @@ describe("Source", () => { const source = new Player(rampBuffer).toDestination(); source.sync().start(0.2, 0.1).stop(0.4); transport.start(0, 0.3); - }, 0.7).then(output => { + }, 0.7).then((output) => { expect(output.getValueAtTime(0.01)).to.be.closeTo(0.2, 0.01); expect(output.getValueAtTime(0.05)).to.be.closeTo(0.25, 0.01); expect(output.getValueAtTime(0.11)).to.be.equal(0); @@ -365,7 +361,7 @@ describe("Source", () => { const source = new Player(rampBuffer).toDestination(); source.sync().start(0.2, 0.1, 0.3); transport.start(0, 0.3); - }, 0.7).then(output => { + }, 0.7).then((output) => { expect(output.getValueAtTime(0.01)).to.be.closeTo(0.2, 0.01); expect(output.getValueAtTime(0.1)).to.be.closeTo(0.3, 0.01); expect(output.getValueAtTime(0.199)).to.be.closeTo(0.4, 0.01); @@ -378,7 +374,7 @@ describe("Source", () => { const source = new Player(rampBuffer).toDestination(); source.sync().start(0.2).stop(0.4); transport.start(0).stop(0.3); - }, 0.7).then(output => { + }, 0.7).then((output) => { expect(output.getValueAtTime(0.2)).to.be.closeTo(0.0, 0.01); expect(output.getValueAtTime(0.25)).to.be.closeTo(0.05, 0.01); expect(output.getValueAtTime(0.31)).to.be.equal(0); diff --git a/Tone/source/Source.ts b/Tone/source/Source.ts index 72c838e4..8c2e1e47 100644 --- a/Tone/source/Source.ts +++ b/Tone/source/Source.ts @@ -1,23 +1,23 @@ -import { Volume } from "../component/channel/Volume"; -import "../core/context/Destination"; -import "../core/clock/Transport"; -import { Param } from "../core/context/Param"; +import { Volume } from "../component/channel/Volume.js"; +import "../core/context/Destination.js"; +import "../core/clock/Transport.js"; +import { Param } from "../core/context/Param.js"; import { OutputNode, ToneAudioNode, ToneAudioNodeOptions, -} from "../core/context/ToneAudioNode"; -import { Decibels, Seconds, Time } from "../core/type/Units"; -import { defaultArg } from "../core/util/Defaults"; -import { noOp, readOnly } from "../core/util/Interface"; +} from "../core/context/ToneAudioNode.js"; +import { Decibels, Seconds, Time } from "../core/type/Units.js"; +import { defaultArg } from "../core/util/Defaults.js"; +import { noOp, readOnly } from "../core/util/Interface.js"; import { BasicPlaybackState, StateTimeline, StateTimelineEvent, -} from "../core/util/StateTimeline"; -import { isDefined, isUndef } from "../core/util/TypeCheck"; -import { assert, assertContextRunning } from "../core/util/Debug"; -import { GT } from "../core/util/Math"; +} from "../core/util/StateTimeline.js"; +import { isDefined, isUndef } from "../core/util/TypeCheck.js"; +import { assert, assertContextRunning } from "../core/util/Debug.js"; +import { GT } from "../core/util/Math.js"; type onStopCallback = (source: Source) => void; @@ -45,7 +45,7 @@ export interface SourceOptions extends ToneAudioNodeOptions { * ``` */ export abstract class Source< - Options extends SourceOptions + Options extends SourceOptions, > extends ToneAudioNode { /** * The output volume node @@ -362,7 +362,7 @@ export abstract class Source< } /** - * Unsync the source to the Transport. + * Unsync the source to the Transport. * @see {@link sync} */ unsync(): this { diff --git a/Tone/source/UserMedia.test.ts b/Tone/source/UserMedia.test.ts index 8c535204..3610dcb7 100644 --- a/Tone/source/UserMedia.test.ts +++ b/Tone/source/UserMedia.test.ts @@ -1,16 +1,13 @@ -import { BasicTests } from "test/helper/Basic"; -import { UserMedia } from "./UserMedia"; -import { GET_USER_MEDIA } from "test/helper/Supports"; +import { BasicTests } from "../../test/helper/Basic.js"; +import { UserMedia } from "./UserMedia.js"; import { expect } from "chai"; -import { OfflineContext } from "Tone/core"; +import { OfflineContext } from "../core/index.js"; describe("UserMedia", () => { - // run the common tests BasicTests(UserMedia); context("Source Tests", () => { - it("can be constructed with the input number", () => { const extIn = new UserMedia(); extIn.dispose(); @@ -19,7 +16,7 @@ describe("UserMedia", () => { it("can be constructed with an options object", () => { const extIn = new UserMedia({ volume: -10, - mute: false + mute: false, }); expect(extIn.volume.value).to.be.closeTo(-10, 0.1); expect(extIn.mute).to.be.false; @@ -37,141 +34,143 @@ describe("UserMedia", () => { it("indicates if the browser has UserMedia support", () => { expect(UserMedia.supported).to.be.a("boolean"); }); - }); - // if it is a manual test (i.e. there is a person to 'allow' the microphone) - if (GET_USER_MEDIA && UserMedia.supported) { - - context("Opening and closing", function() { + context("Opening and closing", function () { + // long timeout to give testers time to allow the microphone + this.timeout(100000); - // long timeout to give testers time to allow the microphone - this.timeout(100000); + let HAS_USER_MEDIA_INPUTS = false; - let HAS_USER_MEDIA_INPUTS = false; - - before(() => { - return UserMedia.enumerateDevices().then((devices) => { - HAS_USER_MEDIA_INPUTS = devices.length > 0; - }); + before(() => { + return UserMedia.enumerateDevices().then((devices) => { + HAS_USER_MEDIA_INPUTS = devices.length > 0; }); + }); - it("open returns a promise", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - const promise = extIn.open(); - expect(promise).to.have.property("then"); - return promise.then(() => { - extIn.dispose(); - }); - } - }); + it("open returns a promise", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + const promise = extIn.open(); + expect(promise).to.have.property("then"); + return promise.then(() => { + extIn.dispose(); + }); + } + }); - it("can open an input", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open().then(() => { - extIn.dispose(); - }); - } - }); + it("can open an input", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn.open().then(() => { + extIn.dispose(); + }); + } + }); - it("can open an input by name", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - let name: string; - return UserMedia.enumerateDevices().then((devices) => { + it("can open an input by name", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + let name: string; + return UserMedia.enumerateDevices() + .then((devices) => { name = devices[0].deviceId; return extIn.open(name); - }).then(() => { + }) + .then(() => { expect(extIn.deviceId).to.equal(name); extIn.dispose(); }); - } - }); + } + }); - it("can open an input by index", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open(0).then(() => { - extIn.dispose(); - }); - } - }); + it("can open an input by index", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn.open(0).then(() => { + extIn.dispose(); + }); + } + }); - it("throws an error if it cant find the device name", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open("doesn't exist").then(() => { + it("throws an error if it cant find the device name", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn + .open("doesn't exist") + .then(() => { // shouldn't call 'then' throw new Error("shouldnt call 'then'"); - }).catch(() => { + }) + .catch(() => { extIn.dispose(); }); - } - }); + } + }); - it("is 'started' after media is open and 'stopped' otherwise", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - expect(extIn.state).to.equal("stopped"); - return extIn.open().then(() => { - expect(extIn.state).to.equal("started"); - extIn.dispose(); - }); - } - }); + it("is 'started' after media is open and 'stopped' otherwise", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + expect(extIn.state).to.equal("stopped"); + return extIn.open().then(() => { + expect(extIn.state).to.equal("started"); + extIn.dispose(); + }); + } + }); - it("has a label, group and device id when open", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open().then(() => { - expect(extIn.deviceId).to.be.a("string"); - expect(extIn.groupId).to.be.a("string"); - expect(extIn.label).to.be.a("string"); - extIn.dispose(); - }); - } - }); + it("has a label, group and device id when open", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn.open().then(() => { + expect(extIn.deviceId).to.be.a("string"); + expect(extIn.groupId).to.be.a("string"); + expect(extIn.label).to.be.a("string"); + extIn.dispose(); + }); + } + }); - it("can reopen an input", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open().then(() => { + it("can reopen an input", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn + .open() + .then(() => { return extIn.open(); - }).then(() => { - extIn.dispose(); - }); - } - }); - - it("can close an input", () => { - if (HAS_USER_MEDIA_INPUTS) { - const extIn = new UserMedia(); - return extIn.open().then(() => { - extIn.close(); + }) + .then(() => { extIn.dispose(); }); - } - }); + } + }); - it("can enumerate devices", () => { - return UserMedia.enumerateDevices().then((devices) => { - expect(devices).to.be.instanceOf(Array); + it("can close an input", () => { + if (HAS_USER_MEDIA_INPUTS) { + const extIn = new UserMedia(); + return extIn.open().then(() => { + extIn.close(); + extIn.dispose(); }); + } + }); + + it("can enumerate devices", () => { + return UserMedia.enumerateDevices().then((devices) => { + expect(devices).to.be.instanceOf(Array); }); + }); - it("doesn't work in OfflineContext", done => { - if (HAS_USER_MEDIA_INPUTS) { - const context = new OfflineContext(2, 2, 44100); - const extIn = new UserMedia({ context }); - extIn.open().catch(() => { - done(); - }); - } else { + it("doesn't work in OfflineContext", (done) => { + if (HAS_USER_MEDIA_INPUTS) { + const context = new OfflineContext(2, 2, 44100); + const extIn = new UserMedia({ context }); + extIn.open().catch(() => { done(); - } - }); + }); + } else { + done(); + } }); - } + }); }); diff --git a/Tone/source/UserMedia.ts b/Tone/source/UserMedia.ts index b48f5f79..be7bf84f 100644 --- a/Tone/source/UserMedia.ts +++ b/Tone/source/UserMedia.ts @@ -1,18 +1,23 @@ -import { connect, OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; -import { Decibels } from "../core/type/Units"; -import { Volume } from "../component/channel/Volume"; -import { optionsFromArguments } from "../core/util/Defaults"; -import { assert } from "../core/util/Debug"; -import { Param } from "../core/context/Param"; -import { readOnly } from "../core/util/Interface"; -import { isDefined, isNumber } from "../core/util/TypeCheck"; +import { + connect, + OutputNode, + ToneAudioNode, + ToneAudioNodeOptions, +} from "../core/context/ToneAudioNode.js"; +import { Decibels } from "../core/type/Units.js"; +import { Volume } from "../component/channel/Volume.js"; +import { optionsFromArguments } from "../core/util/Defaults.js"; +import { assert } from "../core/util/Debug.js"; +import { Param } from "../core/context/Param.js"; +import { readOnly } from "../core/util/Interface.js"; +import { isDefined, isNumber } from "../core/util/TypeCheck.js"; export interface UserMediaOptions extends ToneAudioNodeOptions { volume: Decibels; mute: boolean; } /** - * UserMedia uses MediaDevices.getUserMedia to open up and external microphone or audio input. + * UserMedia uses MediaDevices.getUserMedia to open up and external microphone or audio input. * Check [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) * to see which browsers are supported. Access to an external input * is limited to secure (HTTPS) connections. @@ -32,7 +37,6 @@ export interface UserMediaOptions extends ToneAudioNodeOptions { */ export class UserMedia extends ToneAudioNode { - readonly name: string = "UserMedia"; readonly input: undefined; @@ -69,9 +73,14 @@ export class UserMedia extends ToneAudioNode { constructor(volume?: Decibels); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"])); - const options = optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]); + super( + optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]) + ); + const options = optionsFromArguments( + UserMedia.getDefaults(), + arguments, + ["volume"] + ); this._volume = this.output = new Volume({ context: this.context, @@ -85,7 +94,7 @@ export class UserMedia extends ToneAudioNode { static getDefaults(): UserMediaOptions { return Object.assign(ToneAudioNode.getDefaults(), { mute: false, - volume: 0 + volume: 0, }); } @@ -108,7 +117,9 @@ export class UserMedia extends ToneAudioNode { this._device = devices[labelOrId]; } else { this._device = devices.find((device) => { - return device.label === labelOrId || device.deviceId === labelOrId; + return ( + device.label === labelOrId || device.deviceId === labelOrId + ); }); // didn't find a matching device if (!this._device && devices.length > 0) { @@ -123,7 +134,7 @@ export class UserMedia extends ToneAudioNode { sampleRate: this.context.sampleRate, noiseSuppression: false, mozNoiseSuppression: false, - } + }, }; if (this._device) { // @ts-ignore @@ -134,7 +145,8 @@ export class UserMedia extends ToneAudioNode { if (!this._stream) { this._stream = stream; // Wrap a MediaStreamSourceNode around the live input stream. - const mediaStreamNode = this.context.createMediaStreamSource(stream); + const mediaStreamNode = + this.context.createMediaStreamSource(stream); // Connect the MediaStreamSourceNode to a gate gain node connect(mediaStreamNode, this.output); this._mediaStream = mediaStreamNode; @@ -170,7 +182,7 @@ export class UserMedia extends ToneAudioNode { */ static async enumerateDevices(): Promise { const allDevices = await navigator.mediaDevices.enumerateDevices(); - return allDevices.filter(device => { + return allDevices.filter((device) => { return device.kind === "audioinput"; }); } @@ -254,7 +266,9 @@ export class UserMedia extends ToneAudioNode { * If getUserMedia is supported by the browser. */ static get supported(): boolean { - return isDefined(navigator.mediaDevices) && - isDefined(navigator.mediaDevices.getUserMedia); + return ( + isDefined(navigator.mediaDevices) && + isDefined(navigator.mediaDevices.getUserMedia) + ); } } diff --git a/Tone/source/buffer/GrainPlayer.test.ts b/Tone/source/buffer/GrainPlayer.test.ts index ac640fa9..d855ee1f 100644 --- a/Tone/source/buffer/GrainPlayer.test.ts +++ b/Tone/source/buffer/GrainPlayer.test.ts @@ -1,17 +1,16 @@ -import { BasicTests } from "test/helper/Basic"; -import { GrainPlayer } from "./GrainPlayer"; -import { Offline, whenBetween } from "test/helper/Offline"; -import { SourceTests } from "test/helper/SourceTests"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { CompareToFile } from "test/helper/CompareToFile"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { GrainPlayer } from "./GrainPlayer.js"; +import { Offline, whenBetween } from "../../../test/helper/Offline.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; import { expect } from "chai"; describe("GrainPlayer", () => { - const buffer = new ToneAudioBuffer(); beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); // run the common tests @@ -19,28 +18,33 @@ describe("GrainPlayer", () => { SourceTests(GrainPlayer, buffer); it("matches a file", () => { - return CompareToFile(() => { - const player = new GrainPlayer(buffer).toDestination(); - player.start(0.1).stop(0.2); - player.detune = -100, - player.playbackRate = 2; - }, "grainPlayer.wav", 0.16); + return CompareToFile( + () => { + const player = new GrainPlayer(buffer).toDestination(); + player.start(0.1).stop(0.2); + (player.detune = -100), (player.playbackRate = 2); + }, + "grainPlayer.wav", + 0.16 + ); }); it("matches another file", () => { - return CompareToFile(() => { - const player = new GrainPlayer(buffer).toDestination(); - player.start(0.1, 0.2); - player.loop = true; - player.overlap = 0.005; - player.grainSize = 0.05; - player.detune = 1200, - player.playbackRate = 0.5; - }, "grainPlayer2.wav", 0.2); + return CompareToFile( + () => { + const player = new GrainPlayer(buffer).toDestination(); + player.start(0.1, 0.2); + player.loop = true; + player.overlap = 0.005; + player.grainSize = 0.05; + (player.detune = 1200), (player.playbackRate = 0.5); + }, + "grainPlayer2.wav", + 0.2 + ); }); context("Constructor", () => { - it("can be constructed with a Tone.Buffer", (done) => { const player = new GrainPlayer(buffer); expect(player.buffer.get()).to.equal(buffer.get()); @@ -66,43 +70,40 @@ describe("GrainPlayer", () => { }); context("Loading", () => { - it("loads a url which was passed in", (done) => { - const player = new GrainPlayer("./audio/sine.wav", (() => { + const player = new GrainPlayer("./test/audio/sine.wav", () => { expect(player.loaded).to.be.true; player.dispose(); done(); - })); + }); }); it("can be created with an options object", (done) => { const player = new GrainPlayer({ - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", loop: true, - onload: function() { + onload: function () { expect(player.loop).to.be.true; player.dispose(); done(); - } + }, }); }); it("invokes onerror if no url", (done) => { const source = new GrainPlayer({ - url: "./nosuchfile.wav", + url: "./nosuchfile.wav", onerror() { source.dispose(); done(); - } + }, }); }); - }); context("Looping", () => { - beforeEach(() => { - buffer.load("./audio/short_sine.wav"); + buffer.load("./test/audio/short_sine.wav"); }); it("can be set to loop", () => { @@ -111,13 +112,11 @@ describe("GrainPlayer", () => { expect(player.loop).to.be.true; player.dispose(); }); - }); context("start/stop", () => { - beforeEach(() => { - buffer.load("./audio/short_sine.wav"); + buffer.load("./test/audio/short_sine.wav"); }); it("can be play for a specific duration", () => { @@ -125,7 +124,7 @@ describe("GrainPlayer", () => { const player = new GrainPlayer(buffer); player.toDestination(); player.start(0).stop(0.1); - return function(time) { + return function (time) { whenBetween(time, 0.1, Infinity, () => { expect(player.state).to.equal("stopped"); }); @@ -143,7 +142,7 @@ describe("GrainPlayer", () => { const player = new GrainPlayer(buffer); player.toDestination(); player.start(0, 0, 0.1); - return function(time) { + return function (time) { whenBetween(time, 0.1, Infinity, () => { expect(player.state).to.equal("stopped"); }); @@ -176,7 +175,10 @@ describe("GrainPlayer", () => { player.grainSize = 0.1; player.start(0); }, bufferDuration * 1.2).then((output) => { - expect(output.getTimeOfLastSound()).to.be.closeTo(bufferDuration, 0.1); + expect(output.getTimeOfLastSound()).to.be.closeTo( + bufferDuration, + 0.1 + ); }); }); @@ -187,20 +189,21 @@ describe("GrainPlayer", () => { player.playbackRate = 2; player.start(0); }, bufferDuration).then((output) => { - expect(output.getTimeOfLastSound()).to.be.closeTo(bufferDuration * 0.5, 0.1); + expect(output.getTimeOfLastSound()).to.be.closeTo( + bufferDuration * 0.5, + 0.1 + ); }); }); - }); context("Get/Set", () => { - it("can be set with an options object", () => { const player = new GrainPlayer(); expect(player.loop).to.be.false; player.set({ loop: true, - loopStart: 0.4 + loopStart: 0.4, }); expect(player.loop).to.be.true; expect(player.loopStart).to.equal(0.4); @@ -209,11 +212,11 @@ describe("GrainPlayer", () => { it("can get an options object", () => { const player = new GrainPlayer({ - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", loopStart: 0.2, loopEnd: 0.3, loop: true, - reverse: true + reverse: true, }); expect(player.get().loopStart).to.equal(0.2); expect(player.get().loopEnd).to.equal(0.3); @@ -228,8 +231,5 @@ describe("GrainPlayer", () => { expect(player.playbackRate).to.equal(0.5); player.dispose(); }); - }); - }); - diff --git a/Tone/source/buffer/GrainPlayer.ts b/Tone/source/buffer/GrainPlayer.ts index b7a9056f..8723c63d 100644 --- a/Tone/source/buffer/GrainPlayer.ts +++ b/Tone/source/buffer/GrainPlayer.ts @@ -1,12 +1,12 @@ -import { Source, SourceOptions } from "../Source"; -import { noOp } from "../../core/util/Interface"; -import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer"; -import { defaultArg, optionsFromArguments } from "../../core/util/Defaults"; -import { Clock } from "../../core/clock/Clock"; -import { Cents, Positive, Seconds, Time } from "../../core/type/Units"; -import { ToneBufferSource } from "./ToneBufferSource"; -import { intervalToFrequencyRatio } from "../../core/type/Conversions"; -import { assertRange } from "../../core/util/Debug"; +import { Source, SourceOptions } from "../Source.js"; +import { noOp } from "../../core/util/Interface.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { defaultArg, optionsFromArguments } from "../../core/util/Defaults.js"; +import { Clock } from "../../core/clock/Clock.js"; +import { Cents, Positive, Seconds, Time } from "../../core/type/Units.js"; +import { ToneBufferSource } from "./ToneBufferSource.js"; +import { intervalToFrequencyRatio } from "../../core/type/Conversions.js"; +import { assertRange } from "../../core/util/Debug.js"; interface GrainPlayerOptions extends SourceOptions { onload: () => void; @@ -30,7 +30,6 @@ interface GrainPlayerOptions extends SourceOptions { * @category Source */ export class GrainPlayer extends Source { - readonly name: string = "GrainPlayer"; /** @@ -87,12 +86,23 @@ export class GrainPlayer extends Source { * @param url Either the AudioBuffer or the url from which to load the AudioBuffer * @param onload The function to invoke when the buffer is loaded. */ - constructor(url?: string | AudioBuffer | ToneAudioBuffer, onload?: () => void); + constructor( + url?: string | AudioBuffer | ToneAudioBuffer, + onload?: () => void + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"])); - const options = optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]); + super( + optionsFromArguments(GrainPlayer.getDefaults(), arguments, [ + "url", + "onload", + ]) + ); + const options = optionsFromArguments( + GrainPlayer.getDefaults(), + arguments, + ["url", "onload"] + ); this.buffer = new ToneAudioBuffer({ onload: options.onload, @@ -103,7 +113,7 @@ export class GrainPlayer extends Source { this._clock = new Clock({ context: this.context, callback: this._tick.bind(this), - frequency: 1 / options.grainSize + frequency: 1 / options.grainSize, }); this._playbackRate = options.playbackRate; this._grainSize = options.grainSize; @@ -132,7 +142,7 @@ export class GrainPlayer extends Source { loop: false, loopStart: 0, loopEnd: 0, - reverse: false + reverse: false, }); } @@ -156,7 +166,7 @@ export class GrainPlayer extends Source { * Stop and then restart the player from the beginning (or offset) * @param time When the player should start. * @param offset The offset from the beginning of the sample to start at. - * @param duration How long the sample should play. If no duration is given, + * @param duration How long the sample should play. If no duration is given, * it will default to the full length of the sample (minus any offset) */ restart(time?: Seconds, offset?: Time, duration?: Time): this { @@ -215,7 +225,7 @@ export class GrainPlayer extends Source { loopStart: this._loopStart, loopEnd: this._loopEnd, // compute the playbackRate based on the detune - playbackRate: intervalToFrequencyRatio(this.detune / 100) + playbackRate: intervalToFrequencyRatio(this.detune / 100), }).connect(this.output); source.start(time, this._grainSize * ticks); @@ -290,7 +300,10 @@ export class GrainPlayer extends Source { } set grainSize(size) { this._grainSize = this.toSeconds(size); - this._clock.frequency.setValueAtTime(this._playbackRate / this._grainSize, this.now()); + this._clock.frequency.setValueAtTime( + this._playbackRate / this._grainSize, + this.now() + ); } /** diff --git a/Tone/source/buffer/Player.test.ts b/Tone/source/buffer/Player.test.ts index ee167cde..2b46b4f3 100644 --- a/Tone/source/buffer/Player.test.ts +++ b/Tone/source/buffer/Player.test.ts @@ -1,17 +1,17 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { atTime, Offline, whenBetween } from "test/helper/Offline"; -import { SourceTests } from "test/helper/SourceTests"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { getContext } from "Tone/core/Global"; -import { Player } from "./Player"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { atTime, Offline, whenBetween } from "../../../test/helper/Offline.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { getContext } from "../../core/Global.js"; +import { Player } from "./Player.js"; describe("Player", () => { const buffer = new ToneAudioBuffer(); beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); // run the common tests @@ -44,7 +44,7 @@ describe("Player", () => { }); it("can be constructed with an unloaded Tone.Buffer", (done) => { - const playerBuffer = new ToneAudioBuffer("./audio/sine.wav"); + const playerBuffer = new ToneAudioBuffer("./test/audio/sine.wav"); const player = new Player(playerBuffer, () => { expect(player.buffer.get()).to.equal(playerBuffer.get()); player.dispose(); @@ -107,7 +107,7 @@ describe("Player", () => { context("Loading", () => { it("loads a url which was passed in", (done) => { - const player = new Player("./audio/sine.wav", () => { + const player = new Player("./test/audio/sine.wav", () => { expect(player.loaded).to.be.true; player.dispose(); done(); @@ -116,7 +116,7 @@ describe("Player", () => { it("loads a url using the load method", () => { const player = new Player(); - return player.load("./audio/sine.wav").then(() => { + return player.load("./test/audio/sine.wav").then(() => { expect(player.buffer).to.be.instanceof(ToneAudioBuffer); }); }); @@ -124,7 +124,7 @@ describe("Player", () => { it("can be created with an options object", () => { const player = new Player({ loop: true, - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", }); player.dispose(); }); @@ -149,7 +149,7 @@ describe("Player", () => { done(); }, 10); }, - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", }); }); }); @@ -184,7 +184,7 @@ describe("Player", () => { context("Looping", () => { beforeEach(() => { - return buffer.load("./audio/short_sine.wav"); + return buffer.load("./test/audio/short_sine.wav"); }); it("can be set to loop", () => { @@ -383,7 +383,7 @@ describe("Player", () => { loopEnd: 0.3, loopStart: 0.2, reverse: true, - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", }); expect(player.get().loopStart).to.equal(0.2); expect(player.get().loopEnd).to.equal(0.3); @@ -502,9 +502,9 @@ describe("Player", () => { const player = new Player(buffer); player.toDestination(); player - .start(0, 0, 0.05) - .start(0.1, 0, 0.05) - .start(0.2, 0, 0.05); + .start(0, 0, 0.05) + .start(0.1, 0, 0.05) + .start(0.2, 0, 0.05); player.stop(0.1); }, 0.3).then((buff) => { expect(buff.getTimeOfLastSound()).to.be.closeTo(0.1, 0.02); @@ -559,9 +559,9 @@ describe("Player", () => { it("plays synced to the Transport", () => { return Offline(({ transport }) => { const player = new Player(buffer) - .sync() - .start(0) - .toDestination(); + .sync() + .start(0) + .toDestination(); transport.start(0); }, 0.05).then((buff) => { expect(buff.isSilent()).to.be.false; @@ -587,13 +587,13 @@ describe("Player", () => { it("offsets correctly when started by the Transport", () => { const testSample = buffer.toArray(0)[ - Math.floor(0.13125 * getContext().sampleRate) + Math.floor(0.13125 * getContext().sampleRate) ]; return Offline(({ transport }) => { const player = new Player(buffer) - .sync() - .start(0, 0.1) - .toDestination(); + .sync() + .start(0, 0.1) + .toDestination(); transport.start(0, 0.03125); }, 0.05).then((buff) => { expect(buff.toArray()[0][0]).to.equal(testSample); @@ -699,29 +699,40 @@ describe("Player", () => { it("stops only last activeSource when restarting at intervals < latencyHint", (done) => { const originalLookAhead = getContext().lookAhead; - getContext().lookAhead = .3; + getContext().lookAhead = 0.3; const player = new Player({ onload(): void { player.start(undefined, undefined, 1); - setTimeout(() => player.restart(undefined, undefined, 1), 50); - setTimeout(() => player.restart(undefined, undefined, 1), 100); - setTimeout(() => player.restart(undefined, undefined, 1), 150); + setTimeout( + () => player.restart(undefined, undefined, 1), + 50 + ); + setTimeout( + () => player.restart(undefined, undefined, 1), + 100 + ); + setTimeout( + () => player.restart(undefined, undefined, 1), + 150 + ); setTimeout(() => { player.restart(undefined, undefined, 1); const checkStopTimes = new Set(); // @ts-ignore - player._activeSources.forEach(source => { + player._activeSources.forEach((source) => { // @ts-ignore checkStopTimes.add(source._stopTime); }); getContext().lookAhead = originalLookAhead; // ensure each source has a different stopTime - // @ts-ignore - expect(checkStopTimes.size).to.equal(player._activeSources.size); + expect(checkStopTimes.size).to.equal( + // @ts-ignore + player._activeSources.size + ); done(); }, 250); }, - url: "./audio/sine.wav", + url: "./test/audio/sine.wav", }); }); }); diff --git a/Tone/source/buffer/Player.ts b/Tone/source/buffer/Player.ts index 1d36c03e..2b81adc0 100644 --- a/Tone/source/buffer/Player.ts +++ b/Tone/source/buffer/Player.ts @@ -1,12 +1,12 @@ -import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer"; -import { Positive, Seconds, Time } from "../../core/type/Units"; -import { defaultArg, optionsFromArguments } from "../../core/util/Defaults"; -import { noOp } from "../../core/util/Interface"; -import { isUndef } from "../../core/util/TypeCheck"; -import { Source, SourceOptions } from "../Source"; -import { ToneBufferSource } from "./ToneBufferSource"; -import { assertRange } from "../../core/util/Debug"; -import { timeRange } from "../../core/util/Decorator"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { Positive, Seconds, Time } from "../../core/type/Units.js"; +import { defaultArg, optionsFromArguments } from "../../core/util/Defaults.js"; +import { noOp } from "../../core/util/Interface.js"; +import { isUndef } from "../../core/util/TypeCheck.js"; +import { Source, SourceOptions } from "../Source.js"; +import { ToneBufferSource } from "./ToneBufferSource.js"; +import { assertRange } from "../../core/util/Debug.js"; +import { timeRange } from "../../core/util/Decorator.js"; export interface PlayerOptions extends SourceOptions { onload: () => void; diff --git a/Tone/source/buffer/Players.test.ts b/Tone/source/buffer/Players.test.ts index 51116cef..c5442971 100644 --- a/Tone/source/buffer/Players.test.ts +++ b/Tone/source/buffer/Players.test.ts @@ -1,25 +1,22 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { OutputAudio } from "test/helper/OutputAudio"; -import "test/helper/ToneAudioBuffer"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { getContext } from "Tone/core/Global"; -import { Player } from "./Player"; -import { Players } from "./Players"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { OutputAudio } from "../../../test/helper/OutputAudio.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { getContext } from "../../core/Global.js"; +import { Player } from "./Player.js"; +import { Players } from "./Players.js"; describe("Players", () => { - const buffer = new ToneAudioBuffer(); beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); BasicTests(Players, { test: buffer }); context("Constructor", () => { - it("can be constructed with an object containing a ToneAudioBuffer", () => { const players = new Players({ test: buffer, @@ -37,53 +34,62 @@ describe("Players", () => { }); it("can be constructed with a url", (done) => { - const players = new Players({ - test0: "./audio/sine.wav", - test1: "./audio/sine.wav", - }, () => { - expect(players.player("test0")).to.be.instanceOf(Player); - expect(players.player("test0").buffer.loaded).to.be.true; - expect(players.player("test1")).to.be.instanceOf(Player); - expect(players.player("test1").buffer.loaded).to.be.true; - expect(players.loaded).to.be.true; - players.dispose(); - done(); - }); + const players = new Players( + { + test0: "./test/audio/sine.wav", + test1: "./test/audio/sine.wav", + }, + () => { + expect(players.player("test0")).to.be.instanceOf(Player); + expect(players.player("test0").buffer.loaded).to.be.true; + expect(players.player("test1")).to.be.instanceOf(Player); + expect(players.player("test1").buffer.loaded).to.be.true; + expect(players.loaded).to.be.true; + players.dispose(); + done(); + } + ); }); it("can pass in additional args in the second parameters", (done) => { - const players = new Players({ - test: "./audio/sine.wav", - }, { - onload: () => { - expect(players.player("test").buffer.loaded).to.be.true; - expect(players.volume.value).to.be.closeTo(-12, 0.1); - players.dispose(); - done(); + const players = new Players( + { + test: "./test/audio/sine.wav", }, - volume: -12, - }); + { + onload: () => { + expect(players.player("test").buffer.loaded).to.be.true; + expect(players.volume.value).to.be.closeTo(-12, 0.1); + players.dispose(); + done(); + }, + volume: -12, + } + ); }); it("invokes onerror if no url", (done) => { const source = new Players({ urls: { - test: "./nosuchfile.wav" - }, + test: "./nosuchfile.wav", + }, onerror() { source.dispose(); done(); - } + }, }); }); it("can get and set fadeIn/Out", () => { - const players = new Players({ - test: "./audio/sine.wav", - }, { - fadeIn: 0.1, - fadeOut: 0.2, - }); + const players = new Players( + { + test: "./test/audio/sine.wav", + }, + { + fadeIn: 0.1, + fadeOut: 0.2, + } + ); expect(players.fadeIn).to.equal(0.1); expect(players.fadeOut).to.equal(0.2); expect(players.player("test").fadeIn).to.equal(0.1); @@ -97,7 +103,6 @@ describe("Players", () => { }); context("get/has/add buffers", () => { - it("says it 'has' a sample", () => { const players = new Players({ test: buffer, @@ -136,7 +141,7 @@ describe("Players", () => { it("can add a player with a url", (done) => { const players = new Players(); expect(players.has("test")).to.be.false; - players.add("test", "./audio/sine.wav", () => { + players.add("test", "./test/audio/sine.wav", () => { expect(players.has("test")).to.be.true; players.dispose(); done(); @@ -145,7 +150,7 @@ describe("Players", () => { it("can add a player with an unloaded ToneAudioBuffer", (done) => { const players = new Players(); - const buffer2 = new ToneAudioBuffer("./audio/sine.wav"); + const buffer2 = new ToneAudioBuffer("./test/audio/sine.wav"); players.add("test", buffer2, () => { expect(players.has("test")).to.be.true; expect(players.player("test").loaded).to.be.true; @@ -156,7 +161,6 @@ describe("Players", () => { }); context("start/stop players", () => { - it("makes a sound", () => { return OutputAudio(() => { const players = new Players({ @@ -258,17 +262,22 @@ describe("Players", () => { it("fades in and out correctly", () => { return Offline(() => { - const onesArray = new Float32Array(getContext().sampleRate * 0.5); + const onesArray = new Float32Array( + getContext().sampleRate * 0.5 + ); onesArray.forEach((sample, index) => { onesArray[index] = 1; }); const onesBuffer = ToneAudioBuffer.fromArray(onesArray); - const players = new Players({ - test: onesBuffer, - }, { - fadeIn: 0.1, - fadeOut: 0.1, - }).toDestination(); + const players = new Players( + { + test: onesBuffer, + }, + { + fadeIn: 0.1, + fadeOut: 0.1, + } + ).toDestination(); players.player("test").start(0); }, 0.6).then((buffer2) => { buffer2.forEach((sample, time) => { diff --git a/Tone/source/buffer/Players.ts b/Tone/source/buffer/Players.ts index 056b308b..cafaf7dc 100644 --- a/Tone/source/buffer/Players.ts +++ b/Tone/source/buffer/Players.ts @@ -1,15 +1,18 @@ -import { Volume } from "../../component/channel/Volume"; -import { Param } from "../../core/context/Param"; -import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer"; -import { ToneAudioBuffers, ToneAudioBuffersUrlMap } from "../../core/context/ToneAudioBuffers"; -import { OutputNode, ToneAudioNode } from "../../core/context/ToneAudioNode"; -import { Decibels, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { assert } from "../../core/util/Debug"; -import { noOp, readOnly } from "../../core/util/Interface"; -import { BasicPlaybackState } from "../../core/util/StateTimeline"; -import { Source, SourceOptions } from "../Source"; -import { Player } from "./Player"; +import { Volume } from "../../component/channel/Volume.js"; +import { Param } from "../../core/context/Param.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { + ToneAudioBuffers, + ToneAudioBuffersUrlMap, +} from "../../core/context/ToneAudioBuffers.js"; +import { OutputNode, ToneAudioNode } from "../../core/context/ToneAudioNode.js"; +import { Decibels, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { assert } from "../../core/util/Debug.js"; +import { noOp, readOnly } from "../../core/util/Interface.js"; +import { BasicPlaybackState } from "../../core/util/StateTimeline.js"; +import { Source, SourceOptions } from "../Source.js"; +import { Player } from "./Player.js"; export interface PlayersOptions extends SourceOptions { urls: ToneAudioBuffersUrlMap; @@ -27,7 +30,6 @@ export interface PlayersOptions extends SourceOptions { * @category Source */ export class Players extends ToneAudioNode { - readonly name: string = "Players"; /** @@ -79,11 +81,26 @@ export class Players extends ToneAudioNode { * @param urls An object mapping a name to a url. * @param options The remaining options associated with the players */ - constructor(urls?: ToneAudioBuffersUrlMap, options?: Partial>); + constructor( + urls?: ToneAudioBuffersUrlMap, + options?: Partial> + ); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls")); - const options = optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls"); + super( + optionsFromArguments( + Players.getDefaults(), + arguments, + ["urls", "onload"], + "urls" + ) + ); + const options = optionsFromArguments( + Players.getDefaults(), + arguments, + ["urls", "onload"], + "urls" + ); /** * The output volume node @@ -96,10 +113,10 @@ export class Players extends ToneAudioNode { this.volume = this._volume.volume; readOnly(this, "volume"); this._buffers = new ToneAudioBuffers({ - urls: options.urls, - onload: options.onload, + urls: options.urls, + onload: options.onload, baseUrl: options.baseUrl, - onerror: options.onerror + onerror: options.onerror, }); // mute initially this.mute = options.mute; @@ -138,7 +155,7 @@ export class Players extends ToneAudioNode { } set fadeIn(fadeIn) { this._fadeIn = fadeIn; - this._players.forEach(player => { + this._players.forEach((player) => { player.fadeIn = fadeIn; }); } @@ -151,7 +168,7 @@ export class Players extends ToneAudioNode { } set fadeOut(fadeOut) { this._fadeOut = fadeOut; - this._players.forEach(player => { + this._players.forEach((player) => { player.fadeOut = fadeOut; }); } @@ -160,7 +177,9 @@ export class Players extends ToneAudioNode { * The state of the players object. Returns "started" if any of the players are playing. */ get state(): BasicPlaybackState { - const playing = Array.from(this._players).some(([_, player]) => player.state === "started"); + const playing = Array.from(this._players).some( + ([_, player]) => player.state === "started" + ); return playing ? "started" : "stopped"; } @@ -177,7 +196,10 @@ export class Players extends ToneAudioNode { * @param name The players name as defined in the constructor object or `add` method. */ player(name: string): Player { - assert(this.has(name), `No Player with the name ${name} exists on this object`); + assert( + this.has(name), + `No Player with the name ${name} exists on this object` + ); if (!this._players.has(name)) { const player = new Player({ context: this.context, @@ -209,8 +231,15 @@ export class Players extends ToneAudioNode { * players.player("gong").start(); * }); */ - add(name: string, url: string | ToneAudioBuffer | AudioBuffer, callback?: () => void): this { - assert(!this._buffers.has(name), "A buffer with that name already exists on this object"); + add( + name: string, + url: string | ToneAudioBuffer | AudioBuffer, + callback?: () => void + ): this { + assert( + !this._buffers.has(name), + "A buffer with that name already exists on this object" + ); this._buffers.add(name, url, callback); return this; } @@ -220,7 +249,7 @@ export class Players extends ToneAudioNode { * @param time The time to stop all of the players. */ stopAll(time?: Time): this { - this._players.forEach(player => player.stop(time)); + this._players.forEach((player) => player.stop(time)); return this; } @@ -228,7 +257,7 @@ export class Players extends ToneAudioNode { super.dispose(); this._volume.dispose(); this.volume.dispose(); - this._players.forEach(player => player.dispose()); + this._players.forEach((player) => player.dispose()); this._buffers.dispose(); return this; } diff --git a/Tone/source/buffer/ToneBufferSource.test.ts b/Tone/source/buffer/ToneBufferSource.test.ts index 6fc73518..63ffe4b9 100644 --- a/Tone/source/buffer/ToneBufferSource.test.ts +++ b/Tone/source/buffer/ToneBufferSource.test.ts @@ -1,24 +1,22 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Offline } from "test/helper/Offline"; -import { OFFLINE_BUFFERSOURCE_ONENDED, ONLINE_TESTING } from "test/helper/Supports"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { getContext } from "Tone/core/Global"; -import { ToneBufferSource } from "./ToneBufferSource"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { getContext } from "../../core/Global.js"; +import { ToneBufferSource } from "./ToneBufferSource.js"; const sampleRate = getContext().sampleRate; describe("ToneBufferSource", () => { - const buffer = new ToneAudioBuffer(); const ones = new Float32Array(sampleRate * 0.5); - ones.forEach((sample, index) => ones[index] = 1); + ones.forEach((sample, index) => (ones[index] = 1)); const onesBuffer = ToneAudioBuffer.fromArray(ones); beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); // run the common tests @@ -32,7 +30,6 @@ describe("ToneBufferSource", () => { }); context("Constructor", () => { - it("can be constructed with a Tone.Buffer", () => { const source = new ToneBufferSource(buffer); expect(source.buffer.get()).to.equal(buffer.get()); @@ -74,11 +71,14 @@ describe("ToneBufferSource", () => { }); it("can be constructed with a url and onload", (done) => { - const source = new ToneBufferSource("./audio/short_sine.wav", () => { - expect(source.buffer.loaded).is.equal(true); - source.dispose(); - done(); - }); + const source = new ToneBufferSource( + "./test/audio/short_sine.wav", + () => { + expect(source.buffer.loaded).is.equal(true); + source.dispose(); + done(); + } + ); }); it("invokes onerror if no url", (done) => { @@ -87,7 +87,7 @@ describe("ToneBufferSource", () => { onerror() { source.dispose(); done(); - } + }, }); }); @@ -104,9 +104,8 @@ describe("ToneBufferSource", () => { }); context("Looping", () => { - beforeEach(() => { - return buffer.load("./audio/short_sine.wav"); + return buffer.load("./test/audio/short_sine.wav"); }); it("can be set to loop", () => { @@ -154,8 +153,14 @@ describe("ToneBufferSource", () => { }, buffer.duration * 2).then((buff) => { expect(buff.getRmsAtTime(0)).to.be.above(0); expect(buff.getRmsAtTime(buffer.duration * 0.5)).to.be.above(0); - expect(buff.getRmsAtTime(buffer.duration)).to.be.closeTo(0, 0.001); - expect(buff.getRmsAtTime(buffer.duration * 1.5)).to.be.closeTo(0, 0.001); + expect(buff.getRmsAtTime(buffer.duration)).to.be.closeTo( + 0, + 0.001 + ); + expect(buff.getRmsAtTime(buffer.duration * 1.5)).to.be.closeTo( + 0, + 0.001 + ); }); }); @@ -176,34 +181,35 @@ describe("ToneBufferSource", () => { it("starts at the loop start offset if looping", () => { const offsetTime = 0.05; - const offsetSample = buffer.toArray()[Math.floor(offsetTime * sampleRate)]; + const offsetSample = + buffer.toArray()[Math.floor(offsetTime * sampleRate)]; return Offline(() => { const player = new ToneBufferSource(buffer).toDestination(); player.loop = true; player.loopStart = offsetTime; player.start(0); - }, 0.1).then(buff => { + }, 0.1).then((buff) => { expect(buff.getValueAtTime(0)).to.equal(offsetSample); }); }); it("the offset is modulo the loopDuration", () => { - const testSample = buffer.toArray()[Math.floor(0.051 * sampleRate)] as number; + const testSample = buffer.toArray()[ + Math.floor(0.051 * sampleRate) + ] as number; return Offline(() => { const player = new ToneBufferSource(buffer).toDestination(); player.loop = true; player.loopStart = 0; player.loopEnd = 0.1; player.start(0, 0.351); - }, 0.1).then(buff => { + }, 0.1).then((buff) => { expect(buff.getValueAtTime(0)).to.be.closeTo(testSample, 1e-4); }); }); - }); context("Get/Set", () => { - it("can be set with an options object", () => { const player = new ToneBufferSource(); expect(player.loop).is.equal(false); @@ -224,33 +230,29 @@ describe("ToneBufferSource", () => { expect(player.playbackRate.value).to.equal(0.5); player.dispose(); }); - }); context("onended", () => { - beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); - if (ONLINE_TESTING) { - it.skip("schedules the onended callback in online context", (done) => { - const player = new ToneBufferSource(buffer); - player.start().stop("+0.1"); - player.onended = () => { - expect(player.state).to.equal("stopped"); - player.dispose(); - done(); - }; - }); - } + it.skip("schedules the onended callback in online context", (done) => { + const player = new ToneBufferSource(buffer); + player.start().stop("+0.1"); + player.onended = () => { + expect(player.state).to.equal("stopped"); + player.dispose(); + done(); + }; + }); it("schedules the onended callback when offline", () => { let wasInvoked = false; return Offline(() => { const player = new ToneBufferSource(buffer).toDestination(); player.start(0.2).stop(0.4); - player.onended = () => wasInvoked = true; + player.onended = () => (wasInvoked = true); }, 0.5).then(() => { expect(wasInvoked).to.equal(true); }); @@ -270,28 +272,23 @@ describe("ToneBufferSource", () => { }); }); - if (OFFLINE_BUFFERSOURCE_ONENDED) { - it("schedules the onended callback when the buffer is done without scheduling stop", () => { - - let wasInvoked = false; - return Offline(() => { - const player = new ToneBufferSource(buffer).toDestination(); - player.start(0); - player.onended = () => { - wasInvoked = true; - }; - }, buffer.duration * 1.1).then(() => { - expect(wasInvoked).to.equal(true); - }); + it("schedules the onended callback when the buffer is done without scheduling stop", () => { + let wasInvoked = false; + return Offline(() => { + const player = new ToneBufferSource(buffer).toDestination(); + player.start(0); + player.onended = () => { + wasInvoked = true; + }; + }, buffer.duration * 1.1).then(() => { + expect(wasInvoked).to.equal(true); }); - } - + }); }); context("state", () => { - beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); it("reports the right state when scheduled to stop", () => { @@ -326,9 +323,8 @@ describe("ToneBufferSource", () => { }); context("Start/Stop Scheduling", () => { - beforeEach(() => { - return buffer.load("./audio/sine.wav"); + return buffer.load("./test/audio/sine.wav"); }); it("can play for a specific duration", () => { @@ -336,7 +332,7 @@ describe("ToneBufferSource", () => { const player = new ToneBufferSource(buffer).toDestination(); player.start(0).stop(0.1); - return time => { + return (time) => { if (time > 0.1) { expect(player.state).to.equal("stopped"); } @@ -382,8 +378,14 @@ describe("ToneBufferSource", () => { }, buffer.duration).then((rms) => { expect(rms.getRmsAtTime(0.03)).to.be.gt(0); expect(rms.getRmsAtTime(buffer.duration * 0.45)).to.be.gt(0); - expect(rms.getRmsAtTime(buffer.duration * 0.5)).to.closeTo(0, 0.01); - expect(rms.getRmsAtTime(buffer.duration * 0.7)).to.closeTo(0, 0.01); + expect(rms.getRmsAtTime(buffer.duration * 0.5)).to.closeTo( + 0, + 0.01 + ); + expect(rms.getRmsAtTime(buffer.duration * 0.7)).to.closeTo( + 0, + 0.01 + ); }); }); @@ -408,7 +410,8 @@ describe("ToneBufferSource", () => { it("can start at an offset", () => { const offsetTime = 0.1; - const offsetSample = buffer.toArray()[Math.floor(offsetTime * sampleRate)]; + const offsetSample = + buffer.toArray()[Math.floor(offsetTime * sampleRate)]; return Offline(() => { const player = new ToneBufferSource(buffer).toDestination(); player.start(0, offsetTime); @@ -477,7 +480,7 @@ describe("ToneBufferSource", () => { const player = new ToneBufferSource(onesBuffer).toDestination(); player.fadeOut = 0.1; player.start(0).stop(0.2); - }, 0.32).then(buff => { + }, 0.32).then((buff) => { expect(buff.getValueAtTime(0)).to.equal(1); expect(buff.getValueAtTime(0.1)).to.equal(1); expect(buff.getValueAtTime(0.2)).to.equal(1); @@ -502,7 +505,7 @@ describe("ToneBufferSource", () => { player.fadeIn = 0.1; player.fadeOut = 0.1; player.start(0).stop(0.4); - }, 0.51).then(buff => { + }, 0.51).then((buff) => { expect(buff.getValueAtTime(0)).to.equal(0); expect(buff.getValueAtTime(0.05)).to.be.closeTo(0.93, 0.01); expect(buff.getValueAtTime(0.1)).to.be.closeTo(1, 0.01); @@ -573,6 +576,5 @@ describe("ToneBufferSource", () => { expect(buff.getTimeOfLastSound()).to.be.closeTo(0.2, 0.02); }); }); - }); }); diff --git a/Tone/source/buffer/ToneBufferSource.ts b/Tone/source/buffer/ToneBufferSource.ts index 54016465..b15d8c59 100644 --- a/Tone/source/buffer/ToneBufferSource.ts +++ b/Tone/source/buffer/ToneBufferSource.ts @@ -1,13 +1,17 @@ -import { connect } from "../../core/context/ToneAudioNode"; -import { Param } from "../../core/context/Param"; -import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer"; -import { GainFactor, Positive, Seconds, Time } from "../../core/type/Units"; -import { defaultArg, optionsFromArguments } from "../../core/util/Defaults"; -import { noOp } from "../../core/util/Interface"; -import { isDefined } from "../../core/util/TypeCheck"; -import { assert } from "../../core/util/Debug"; -import { OneShotSource, OneShotSourceCurve, OneShotSourceOptions } from "../OneShotSource"; -import { EQ, GTE, LT } from "../../core/util/Math"; +import { connect } from "../../core/context/ToneAudioNode.js"; +import { Param } from "../../core/context/Param.js"; +import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js"; +import { GainFactor, Positive, Seconds, Time } from "../../core/type/Units.js"; +import { defaultArg, optionsFromArguments } from "../../core/util/Defaults.js"; +import { noOp } from "../../core/util/Interface.js"; +import { isDefined } from "../../core/util/TypeCheck.js"; +import { assert } from "../../core/util/Debug.js"; +import { + OneShotSource, + OneShotSourceCurve, + OneShotSourceOptions, +} from "../OneShotSource.js"; +import { EQ, GTE, LT } from "../../core/util/Math.js"; export type ToneBufferSourceCurve = OneShotSourceCurve; @@ -29,7 +33,6 @@ export interface ToneBufferSourceOptions extends OneShotSourceOptions { * @category Source */ export class ToneBufferSource extends OneShotSource { - readonly name: string = "ToneBufferSource"; /** @@ -58,12 +61,23 @@ export class ToneBufferSource extends OneShotSource { * @param url The buffer to play or url to load * @param onload The callback to invoke when the buffer is done playing. */ - constructor(url?: ToneAudioBuffer | AudioBuffer | string, onload?: () => void); + constructor( + url?: ToneAudioBuffer | AudioBuffer | string, + onload?: () => void + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(ToneBufferSource.getDefaults(), arguments, ["url", "onload"])); - const options = optionsFromArguments(ToneBufferSource.getDefaults(), arguments, ["url", "onload"]); + super( + optionsFromArguments(ToneBufferSource.getDefaults(), arguments, [ + "url", + "onload", + ]) + ); + const options = optionsFromArguments( + ToneBufferSource.getDefaults(), + arguments, + ["url", "onload"] + ); connect(this._source, this._gainNode); this._source.onended = () => this._stopSource(); @@ -82,7 +96,11 @@ export class ToneBufferSource extends OneShotSource { this.loop = options.loop; this.loopStart = options.loopStart; this.loopEnd = options.loopEnd; - this._buffer = new ToneAudioBuffer(options.url, options.onload, options.onerror); + this._buffer = new ToneAudioBuffer( + options.url, + options.onload, + options.onerror + ); this._internalChannels.push(this._source); } @@ -136,7 +154,12 @@ export class ToneBufferSource extends OneShotSource { * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset) * @param gain The gain to play the buffer back at. */ - start(time?: Time, offset?: Time, duration?: Time, gain: GainFactor = 1): this { + start( + time?: Time, + offset?: Time, + duration?: Time, + gain: GainFactor = 1 + ): this { assert(this.buffer.loaded, "buffer is either not set or not loaded"); const computedTime = this.toSeconds(time); @@ -156,22 +179,25 @@ export class ToneBufferSource extends OneShotSource { // start the buffer source if (this.loop) { // modify the offset if it's greater than the loop time - const loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration; + const loopEnd = + this.toSeconds(this.loopEnd) || this.buffer.duration; const loopStart = this.toSeconds(this.loopStart); const loopDuration = loopEnd - loopStart; // move the offset back if (GTE(computedOffset, loopEnd)) { - computedOffset = ((computedOffset - loopStart) % loopDuration) + loopStart; + computedOffset = + ((computedOffset - loopStart) % loopDuration) + loopStart; } // when the offset is very close to the duration, set it to 0 if (EQ(computedOffset, this.buffer.duration)) { computedOffset = 0; } } - + // this.buffer.loaded would have return false if the AudioBuffer was undefined this._source.buffer = this.buffer.get() as AudioBuffer; - this._source.loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration; + this._source.loopEnd = + this.toSeconds(this.loopEnd) || this.buffer.duration; if (LT(computedOffset, this.buffer.duration)) { this._sourceStarted = true; this._source.start(computedTime, computedOffset); diff --git a/Tone/source/index.ts b/Tone/source/index.ts index 81b38793..4d12e3ba 100644 --- a/Tone/source/index.ts +++ b/Tone/source/index.ts @@ -1,15 +1,15 @@ -export * from "./Noise"; -export * from "./UserMedia"; -export * from "./oscillator/Oscillator"; -export * from "./oscillator/AMOscillator"; -export * from "./oscillator/FMOscillator"; -export * from "./oscillator/PulseOscillator"; -export * from "./oscillator/FatOscillator"; -export * from "./oscillator/PWMOscillator"; -export * from "./oscillator/OmniOscillator"; -export * from "./oscillator/ToneOscillatorNode"; -export * from "./oscillator/LFO"; -export * from "./buffer/ToneBufferSource"; -export * from "./buffer/Player"; -export * from "./buffer/Players"; -export * from "./buffer/GrainPlayer"; +export * from "./Noise.js"; +export * from "./UserMedia.js"; +export * from "./oscillator/Oscillator.js"; +export * from "./oscillator/AMOscillator.js"; +export * from "./oscillator/FMOscillator.js"; +export * from "./oscillator/PulseOscillator.js"; +export * from "./oscillator/FatOscillator.js"; +export * from "./oscillator/PWMOscillator.js"; +export * from "./oscillator/OmniOscillator.js"; +export * from "./oscillator/ToneOscillatorNode.js"; +export * from "./oscillator/LFO.js"; +export * from "./buffer/ToneBufferSource.js"; +export * from "./buffer/Player.js"; +export * from "./buffer/Players.js"; +export * from "./buffer/GrainPlayer.js"; diff --git a/Tone/source/oscillator/AMOscillator.test.ts b/Tone/source/oscillator/AMOscillator.test.ts index b6e4d0fe..da78e0c9 100644 --- a/Tone/source/oscillator/AMOscillator.test.ts +++ b/Tone/source/oscillator/AMOscillator.test.ts @@ -1,26 +1,28 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { SourceTests } from "test/helper/SourceTests"; -import { AMOscillator } from "./AMOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { AMOscillator } from "./AMOscillator.js"; describe("AMOscillator", () => { - // run the common tests BasicTests(AMOscillator); SourceTests(AMOscillator); OscillatorTests(AMOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new AMOscillator().toDestination(); - osc.start(0.1).stop(0.4); - }, "amOscillator.wav", 0.03); + return CompareToFile( + () => { + const osc = new AMOscillator().toDestination(); + osc.start(0.1).stop(0.4); + }, + "amOscillator.wav", + 0.03 + ); }); context("Amplitude Modulation", () => { - it("can pass in parameters in the constructor", () => { const amOsc = new AMOscillator({ harmonicity: 3, diff --git a/Tone/source/oscillator/AMOscillator.ts b/Tone/source/oscillator/AMOscillator.ts index 161e74c1..e5e007ed 100644 --- a/Tone/source/oscillator/AMOscillator.ts +++ b/Tone/source/oscillator/AMOscillator.ts @@ -1,20 +1,22 @@ -import { Gain } from "../../core/context/Gain"; -import { Degrees, Frequency, Seconds } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { AudioToGain } from "../../signal/AudioToGain"; -import { Multiply } from "../../signal/Multiply"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; -import { Oscillator } from "./Oscillator"; +import { Gain } from "../../core/context/Gain.js"; +import { Degrees, Frequency, Seconds } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { AudioToGain } from "../../signal/AudioToGain.js"; +import { Multiply } from "../../signal/Multiply.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { Oscillator } from "./Oscillator.js"; import { - AMConstructorOptions, AMOscillatorOptions, - generateWaveform, NonCustomOscillatorType, + AMConstructorOptions, + AMOscillatorOptions, + generateWaveform, + NonCustomOscillatorType, ToneOscillatorInterface, - ToneOscillatorType -} from "./OscillatorInterface"; + ToneOscillatorType, +} from "./OscillatorInterface.js"; -export { AMOscillatorOptions } from "./OscillatorInterface"; +export { AMOscillatorOptions } from "./OscillatorInterface.js"; /** * An amplitude modulated oscillator node. It is implemented with @@ -35,8 +37,10 @@ export { AMOscillatorOptions } from "./OscillatorInterface"; * }, 0.2, 1); * @category Source */ -export class AMOscillator extends Source implements ToneOscillatorInterface { - +export class AMOscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "AMOscillator"; /** @@ -86,12 +90,25 @@ export class AMOscillator extends Source implements ToneOsc * @param type The type of the carrier oscillator. * @param modulationType The type of the modulator oscillator. */ - constructor(frequency?: Frequency, type?: ToneOscillatorType, modulationType?: ToneOscillatorType); + constructor( + frequency?: Frequency, + type?: ToneOscillatorType, + modulationType?: ToneOscillatorType + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); - const options = optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); + super( + optionsFromArguments(AMOscillator.getDefaults(), arguments, [ + "frequency", + "type", + "modulationType", + ]) + ); + const options = optionsFromArguments( + AMOscillator.getDefaults(), + arguments, + ["frequency", "type", "modulationType"] + ); this._carrier = new Oscillator({ context: this.context, @@ -101,8 +118,8 @@ export class AMOscillator extends Source implements ToneOsc phase: options.phase, type: options.type, } as OscillatorOptions); - this.frequency = this._carrier.frequency, - this.detune = this._carrier.detune; + (this.frequency = this._carrier.frequency), + (this.detune = this._carrier.detune); this._modulator = new Oscillator({ context: this.context, diff --git a/Tone/source/oscillator/FMOscillator.test.ts b/Tone/source/oscillator/FMOscillator.test.ts index 0f191238..423bc0e5 100644 --- a/Tone/source/oscillator/FMOscillator.test.ts +++ b/Tone/source/oscillator/FMOscillator.test.ts @@ -1,27 +1,29 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { connectFrom } from "test/helper/Connect"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { SourceTests } from "test/helper/SourceTests"; -import { FMOscillator } from "./FMOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { connectFrom } from "../../../test/helper/Connect.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { FMOscillator } from "./FMOscillator.js"; describe("FMOscillator", () => { - // run the common tests BasicTests(FMOscillator); SourceTests(FMOscillator); OscillatorTests(FMOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new FMOscillator().toDestination(); - osc.start(0); - }, "fmOscillator.wav", 0.01); + return CompareToFile( + () => { + const osc = new FMOscillator().toDestination(); + osc.start(0); + }, + "fmOscillator.wav", + 0.01 + ); }); context("Frequency Modulation", () => { - it("can pass in parameters in the constructor", () => { const fmOsc = new FMOscillator({ harmonicity: 3, diff --git a/Tone/source/oscillator/FMOscillator.ts b/Tone/source/oscillator/FMOscillator.ts index 1956aaf8..ee5ff080 100644 --- a/Tone/source/oscillator/FMOscillator.ts +++ b/Tone/source/oscillator/FMOscillator.ts @@ -1,17 +1,21 @@ -import { Gain } from "../../core/context/Gain"; -import { Degrees, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { Multiply } from "../../signal/Multiply"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; -import { Oscillator } from "./Oscillator"; +import { Gain } from "../../core/context/Gain.js"; +import { Degrees, Frequency, Seconds, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { Multiply } from "../../signal/Multiply.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { Oscillator } from "./Oscillator.js"; import { - FMConstructorOptions, FMOscillatorOptions, - generateWaveform, NonCustomOscillatorType, ToneOscillatorInterface, ToneOscillatorType -} from "./OscillatorInterface"; + FMConstructorOptions, + FMOscillatorOptions, + generateWaveform, + NonCustomOscillatorType, + ToneOscillatorInterface, + ToneOscillatorType, +} from "./OscillatorInterface.js"; -export { FMOscillatorOptions } from "./OscillatorInterface"; +export { FMOscillatorOptions } from "./OscillatorInterface.js"; /** * FMOscillator implements a frequency modulation synthesis * ``` @@ -38,8 +42,10 @@ export { FMOscillatorOptions } from "./OscillatorInterface"; * }, 0.1, 1); * @category Source */ -export class FMOscillator extends Source implements ToneOscillatorInterface { - +export class FMOscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "FMOscillator"; /** @@ -86,12 +92,25 @@ export class FMOscillator extends Source implements ToneOsc * @param type The type of the carrier oscillator. * @param modulationType The type of the modulator oscillator. */ - constructor(frequency?: Frequency, type?: ToneOscillatorType, modulationType?: ToneOscillatorType); + constructor( + frequency?: Frequency, + type?: ToneOscillatorType, + modulationType?: ToneOscillatorType + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); - const options = optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); + super( + optionsFromArguments(FMOscillator.getDefaults(), arguments, [ + "frequency", + "type", + "modulationType", + ]) + ); + const options = optionsFromArguments( + FMOscillator.getDefaults(), + arguments, + ["frequency", "type", "modulationType"] + ); this._carrier = new Oscillator({ context: this.context, @@ -137,7 +156,12 @@ export class FMOscillator extends Source implements ToneOsc this._carrier.connect(this.output); this.detune.connect(this._modulator.detune); - readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]); + readOnly(this, [ + "modulationIndex", + "frequency", + "detune", + "harmonicity", + ]); } static getDefaults(): FMOscillatorOptions { diff --git a/Tone/source/oscillator/FatOscillator.test.ts b/Tone/source/oscillator/FatOscillator.test.ts index db7dc1d7..fd176f80 100644 --- a/Tone/source/oscillator/FatOscillator.test.ts +++ b/Tone/source/oscillator/FatOscillator.test.ts @@ -1,26 +1,28 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { SourceTests } from "test/helper/SourceTests"; -import { FatOscillator } from "./FatOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { FatOscillator } from "./FatOscillator.js"; describe("FatOscillator", () => { - // run the common tests BasicTests(FatOscillator); SourceTests(FatOscillator); OscillatorTests(FatOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new FatOscillator().toDestination(); - osc.start(0); - }, "fatOscillator.wav", 0.2); + return CompareToFile( + () => { + const osc = new FatOscillator().toDestination(); + osc.start(0); + }, + "fatOscillator.wav", + 0.2 + ); }); context("Detuned Oscillators", () => { - it("can pass in parameters in the constructor", () => { const fatOsc = new FatOscillator({ count: 4, @@ -86,6 +88,5 @@ describe("FatOscillator", () => { expect(osc.type).to.equal("square"); osc.dispose(); }); - }); }); diff --git a/Tone/source/oscillator/FatOscillator.ts b/Tone/source/oscillator/FatOscillator.ts index 5f220aac..f1dcc8d2 100644 --- a/Tone/source/oscillator/FatOscillator.ts +++ b/Tone/source/oscillator/FatOscillator.ts @@ -1,16 +1,26 @@ -import { Cents, Degrees, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { noOp, readOnly } from "../../core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; -import { Oscillator } from "./Oscillator"; import { - FatConstructorOptions, FatOscillatorOptions, - generateWaveform, NonCustomOscillatorType, ToneOscillatorInterface, ToneOscillatorType -} from "./OscillatorInterface"; -import { assertRange } from "../../core/util/Debug"; + Cents, + Degrees, + Frequency, + Seconds, + Time, +} from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { noOp, readOnly } from "../../core/util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { Oscillator } from "./Oscillator.js"; +import { + FatConstructorOptions, + FatOscillatorOptions, + generateWaveform, + NonCustomOscillatorType, + ToneOscillatorInterface, + ToneOscillatorType, +} from "./OscillatorInterface.js"; +import { assertRange } from "../../core/util/Debug.js"; -export { FatOscillatorOptions } from "./OscillatorInterface"; +export { FatOscillatorOptions } from "./OscillatorInterface.js"; /** * FatOscillator is an array of oscillators with detune spread between the oscillators @@ -18,8 +28,10 @@ export { FatOscillatorOptions } from "./OscillatorInterface"; * const fatOsc = new Tone.FatOscillator("Ab3", "sawtooth", 40).toDestination().start(); * @category Source */ -export class FatOscillator extends Source implements ToneOscillatorInterface { - +export class FatOscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "FatOscillator"; readonly frequency: Signal<"frequency">; @@ -60,12 +72,25 @@ export class FatOscillator extends Source implements ToneO * @param type The type of the oscillator. * @param spread The detune spread between the oscillators. */ - constructor(frequency?: Frequency, type?: ToneOscillatorType, spread?: Cents); + constructor( + frequency?: Frequency, + type?: ToneOscillatorType, + spread?: Cents + ); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"])); - const options = optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]); + super( + optionsFromArguments(FatOscillator.getDefaults(), arguments, [ + "frequency", + "type", + "spread", + ]) + ); + const options = optionsFromArguments( + FatOscillator.getDefaults(), + arguments, + ["frequency", "type", "spread"] + ); this.frequency = new Signal({ context: this.context, @@ -103,7 +128,7 @@ export class FatOscillator extends Source implements ToneO */ protected _start(time: Time): void { time = this.toSeconds(time); - this._forEach(osc => osc.start(time)); + this._forEach((osc) => osc.start(time)); } /** @@ -111,11 +136,11 @@ export class FatOscillator extends Source implements ToneO */ protected _stop(time: Time): void { time = this.toSeconds(time); - this._forEach(osc => osc.stop(time)); + this._forEach((osc) => osc.stop(time)); } protected _restart(time: Seconds): void { - this._forEach(osc => osc.restart(time)); + this._forEach((osc) => osc.restart(time)); } /** @@ -135,7 +160,7 @@ export class FatOscillator extends Source implements ToneO } set type(type: ToneOscillatorType) { this._type = type; - this._forEach(osc => osc.type = type); + this._forEach((osc) => (osc.type = type)); } /** @@ -155,7 +180,7 @@ export class FatOscillator extends Source implements ToneO if (this._oscillators.length > 1) { const start = -spread / 2; const step = spread / (this._oscillators.length - 1); - this._forEach((osc, i) => osc.detune.value = start + step * i); + this._forEach((osc, i) => (osc.detune.value = start + step * i)); } } @@ -173,7 +198,7 @@ export class FatOscillator extends Source implements ToneO assertRange(count, 1); if (this._oscillators.length !== count) { // dispose the previous oscillators - this._forEach(osc => osc.dispose()); + this._forEach((osc) => osc.dispose()); this._oscillators = []; for (let i = 0; i < count; i++) { const osc = new Oscillator({ @@ -196,7 +221,7 @@ export class FatOscillator extends Source implements ToneO // set the spread this.spread = this._spread; if (this.state === "started") { - this._forEach(osc => osc.start()); + this._forEach((osc) => osc.start()); } } } @@ -206,14 +231,16 @@ export class FatOscillator extends Source implements ToneO } set phase(phase: Degrees) { this._phase = phase; - this._forEach((osc, i) => osc.phase = this._phase + (i / this.count) * 360); + this._forEach( + (osc, i) => (osc.phase = this._phase + (i / this.count) * 360) + ); } get baseType(): OscillatorType { return this._oscillators[0].baseType; } set baseType(baseType: OscillatorType) { - this._forEach(osc => osc.baseType = baseType); + this._forEach((osc) => (osc.baseType = baseType)); this._type = this._oscillators[0].type; } @@ -225,7 +252,7 @@ export class FatOscillator extends Source implements ToneO this._partialCount = this._partials.length; if (partials.length) { this._type = "custom"; - this._forEach(osc => osc.partials = partials); + this._forEach((osc) => (osc.partials = partials)); } } @@ -234,7 +261,7 @@ export class FatOscillator extends Source implements ToneO } set partialCount(partialCount: number) { this._partialCount = partialCount; - this._forEach(osc => osc.partialCount = partialCount); + this._forEach((osc) => (osc.partialCount = partialCount)); this._type = this._oscillators[0].type; } @@ -249,7 +276,7 @@ export class FatOscillator extends Source implements ToneO super.dispose(); this.frequency.dispose(); this.detune.dispose(); - this._forEach(osc => osc.dispose()); + this._forEach((osc) => osc.dispose()); return this; } } diff --git a/Tone/source/oscillator/LFO.test.ts b/Tone/source/oscillator/LFO.test.ts index b8434d80..31fe5e48 100644 --- a/Tone/source/oscillator/LFO.test.ts +++ b/Tone/source/oscillator/LFO.test.ts @@ -1,12 +1,11 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { Offline } from "test/helper/Offline"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { Signal } from "Tone/signal/Signal"; -import { LFO, LFOOptions } from "./LFO"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { OutputAudio } from "../../../test/helper/OutputAudio.js"; +import { Signal } from "../../signal/Signal.js"; +import { LFO, LFOOptions } from "./LFO.js"; describe("LFO", () => { - BasicTests(LFO); context("API", () => { @@ -20,7 +19,6 @@ describe("LFO", () => { }); context("Low Oscillations", () => { - it("can be started and stopped", () => { const lfo = new LFO(); lfo.start(); @@ -198,7 +196,7 @@ describe("LFO", () => { }); it("can adjust the amplitude", () => { - return Offline(({ transport }) => { + return Offline(() => { const lfo = new LFO(10, -10, 10); lfo.amplitude.value = 0.5; lfo.toDestination(); @@ -210,7 +208,7 @@ describe("LFO", () => { }); it("can adjust the amplitude not centered at 0", () => { - return Offline(({ transport }) => { + return Offline(() => { const lfo = new LFO(10, 400, 4000); lfo.amplitude.value = 0.5; lfo.toDestination(); @@ -224,7 +222,7 @@ describe("LFO", () => { it("can pass in partials to the constructor", () => { const lfo = new LFO({ type: "custom", - partials: [0, 2, 3] + partials: [0, 2, 3], }); expect(lfo.partials).to.deep.equal([0, 2, 3]); lfo.partials = [1, 2, 3]; diff --git a/Tone/source/oscillator/LFO.ts b/Tone/source/oscillator/LFO.ts index 5d1e13c4..bc8d1f7b 100644 --- a/Tone/source/oscillator/LFO.ts +++ b/Tone/source/oscillator/LFO.ts @@ -1,16 +1,29 @@ -import { Gain } from "../../core/context/Gain"; -import { Param } from "../../core/context/Param"; -import { InputNode, OutputNode, ToneAudioNode } from "../../core/context/ToneAudioNode"; -import { Degrees, Frequency, NormalRange, Time, UnitName } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { BasicPlaybackState } from "../../core/util/StateTimeline"; -import { AudioToGain } from "../../signal/AudioToGain"; -import { Scale } from "../../signal/Scale"; -import { connectSignal, Signal } from "../../signal/Signal"; -import { Zero } from "../../signal/Zero"; -import { Oscillator, ToneOscillatorType } from "./Oscillator"; -import { ToneOscillatorConstructorOptions, ToneOscillatorOptions } from "./OscillatorInterface"; +import { Gain } from "../../core/context/Gain.js"; +import { Param } from "../../core/context/Param.js"; +import { + InputNode, + OutputNode, + ToneAudioNode, +} from "../../core/context/ToneAudioNode.js"; +import { + Degrees, + Frequency, + NormalRange, + Time, + UnitName, +} from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { BasicPlaybackState } from "../../core/util/StateTimeline.js"; +import { AudioToGain } from "../../signal/AudioToGain.js"; +import { Scale } from "../../signal/Scale.js"; +import { connectSignal, Signal } from "../../signal/Signal.js"; +import { Zero } from "../../signal/Zero.js"; +import { Oscillator, ToneOscillatorType } from "./Oscillator.js"; +import { + ToneOscillatorConstructorOptions, + ToneOscillatorOptions, +} from "./OscillatorInterface.js"; export type LFOOptions = { min: number; @@ -31,7 +44,6 @@ export type LFOOptions = { * @category Source */ export class LFO extends ToneAudioNode { - readonly name: string = "LFO"; /** @@ -112,11 +124,22 @@ export class LFO extends ToneAudioNode { constructor(frequency?: Frequency, min?: number, max?: number); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(LFO.getDefaults(), arguments, ["frequency", "min", "max"])); - const options = optionsFromArguments(LFO.getDefaults(), arguments, ["frequency", "min", "max"]); - - this._oscillator = new Oscillator(options as ToneOscillatorConstructorOptions); + super( + optionsFromArguments(LFO.getDefaults(), arguments, [ + "frequency", + "min", + "max", + ]) + ); + const options = optionsFromArguments(LFO.getDefaults(), arguments, [ + "frequency", + "min", + "max", + ]); + + this._oscillator = new Oscillator( + options as ToneOscillatorConstructorOptions + ); this.frequency = this._oscillator.frequency; @@ -250,7 +273,7 @@ export class LFO extends ToneAudioNode { } /** - * The oscillator's partials array. + * The oscillator's partials array. * @see {@link Oscillator.partials} */ get partials(): number[] { diff --git a/Tone/source/oscillator/OmniOscillator.test.ts b/Tone/source/oscillator/OmniOscillator.test.ts index e900e607..a0afdf56 100644 --- a/Tone/source/oscillator/OmniOscillator.test.ts +++ b/Tone/source/oscillator/OmniOscillator.test.ts @@ -1,31 +1,33 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { SourceTests } from "test/helper/SourceTests"; -import { FMOscillator } from "./FMOscillator"; -import { OmniOscillator } from "./OmniOscillator"; -import { OmniOscillatorType } from "./OscillatorInterface"; -import { PulseOscillator } from "./PulseOscillator"; -import { PWMOscillator } from "./PWMOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { OutputAudio } from "../../../test/helper/OutputAudio.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { FMOscillator } from "./FMOscillator.js"; +import { OmniOscillator } from "./OmniOscillator.js"; +import { OmniOscillatorType } from "./OscillatorInterface.js"; +import { PulseOscillator } from "./PulseOscillator.js"; +import { PWMOscillator } from "./PWMOscillator.js"; describe("OmniOscillator", () => { - // run the common tests BasicTests(OmniOscillator); SourceTests(OmniOscillator); OscillatorTests(OmniOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new OmniOscillator(220, "fmsquare").toDestination(); - osc.start(0.1).stop(0.2); - }, "omniOscillator.wav", 1.6); + return CompareToFile( + () => { + const osc = new OmniOscillator(220, "fmsquare").toDestination(); + osc.start(0.1).stop(0.2); + }, + "omniOscillator.wav", + 1.6 + ); }); context("Sound", () => { - it("makes a sound", () => { return OutputAudio(() => { const osc = new OmniOscillator(); @@ -90,11 +92,9 @@ describe("OmniOscillator", () => { osc.type = "fmsine"; }); }); - }); context("Type", () => { - it("can get and set the type", () => { const osc = new OmniOscillator({ type: "sawtooth", @@ -105,8 +105,16 @@ describe("OmniOscillator", () => { it("handles various types", () => { const osc = new OmniOscillator(); - const types: OmniOscillatorType[] = ["triangle3", "sine", "pulse", "pwm", "amsine4", "fatsquare2", "fmsawtooth"]; - types.forEach(type => { + const types: OmniOscillatorType[] = [ + "triangle3", + "sine", + "pulse", + "pwm", + "amsine4", + "fatsquare2", + "fmsawtooth", + ]; + types.forEach((type) => { osc.type = type; expect(osc.type).to.equal(type); }); diff --git a/Tone/source/oscillator/OmniOscillator.ts b/Tone/source/oscillator/OmniOscillator.ts index b17ca69e..9c1d16b2 100644 --- a/Tone/source/oscillator/OmniOscillator.ts +++ b/Tone/source/oscillator/OmniOscillator.ts @@ -1,38 +1,52 @@ -import { Cents, Degrees, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { isNumber, isString } from "../../core/util/TypeCheck"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; -import { AMOscillator } from "./AMOscillator"; -import { FatOscillator } from "./FatOscillator"; -import { FMOscillator } from "./FMOscillator"; -import { Oscillator } from "./Oscillator"; +import { + Cents, + Degrees, + Frequency, + Seconds, + Time, +} from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { isNumber, isString } from "../../core/util/TypeCheck.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { AMOscillator } from "./AMOscillator.js"; +import { FatOscillator } from "./FatOscillator.js"; +import { FMOscillator } from "./FMOscillator.js"; +import { Oscillator } from "./Oscillator.js"; import { generateWaveform, - OmniOscillatorOptions, - OmniOscillatorType, ToneOscillatorInterface, ToneOscillatorType -} from "./OscillatorInterface"; -import { PulseOscillator } from "./PulseOscillator"; -import { PWMOscillator } from "./PWMOscillator"; + OmniOscillatorOptions, + OmniOscillatorType, + ToneOscillatorInterface, + ToneOscillatorType, +} from "./OscillatorInterface.js"; +import { PulseOscillator } from "./PulseOscillator.js"; +import { PWMOscillator } from "./PWMOscillator.js"; -export { OmniOscillatorOptions } from "./OscillatorInterface"; +export { OmniOscillatorOptions } from "./OscillatorInterface.js"; /** * All of the oscillator types that OmniOscillator can take on */ -type AnyOscillator = Oscillator | PWMOscillator | PulseOscillator | FatOscillator | AMOscillator | FMOscillator; +type AnyOscillator = + | Oscillator + | PWMOscillator + | PulseOscillator + | FatOscillator + | AMOscillator + | FMOscillator; /** * All of the Oscillator constructor types mapped to their name. */ interface OmniOscillatorSource { - "fm": FMOscillator; - "am": AMOscillator; - "pwm": PWMOscillator; - "pulse": PulseOscillator; - "oscillator": Oscillator; - "fat": FatOscillator; + fm: FMOscillator; + am: AMOscillator; + pwm: PWMOscillator; + pulse: PulseOscillator; + oscillator: Oscillator; + fat: FatOscillator; } /** @@ -41,16 +55,22 @@ interface OmniOscillatorSource { export type OmniOscSourceType = keyof OmniOscillatorSource; // Conditional Types -type IsAmOrFmOscillator = Osc extends AMOscillator ? Ret : Osc extends FMOscillator ? Ret : undefined; +type IsAmOrFmOscillator = Osc extends AMOscillator + ? Ret + : Osc extends FMOscillator + ? Ret + : undefined; type IsFatOscillator = Osc extends FatOscillator ? Ret : undefined; type IsPWMOscillator = Osc extends PWMOscillator ? Ret : undefined; -type IsPulseOscillator = Osc extends PulseOscillator ? Ret : undefined; +type IsPulseOscillator = Osc extends PulseOscillator + ? Ret + : undefined; type IsFMOscillator = Osc extends FMOscillator ? Ret : undefined; type AnyOscillatorConstructor = new (...args: any[]) => AnyOscillator; const OmniOscillatorSourceMap: { - [key in OmniOscSourceType]: AnyOscillatorConstructor + [key in OmniOscSourceType]: AnyOscillatorConstructor; } = { am: AMOscillator, fat: FatOscillator, @@ -61,7 +81,7 @@ const OmniOscillatorSourceMap: { }; /** - * OmniOscillator aggregates all of the oscillator types into one. + * OmniOscillator aggregates all of the oscillator types into one. * @example * return Tone.Offline(() => { * const omniOsc = new Tone.OmniOscillator("C#4", "pwm").toDestination().start(); @@ -70,8 +90,8 @@ const OmniOscillatorSourceMap: { */ export class OmniOscillator extends Source - implements Omit { - + implements Omit +{ readonly name: string = "OmniOscillator"; readonly frequency: Signal<"frequency">; @@ -94,9 +114,17 @@ export class OmniOscillator constructor(frequency?: Frequency, type?: OmniOscillatorType); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"])); - const options = optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"]); + super( + optionsFromArguments(OmniOscillator.getDefaults(), arguments, [ + "frequency", + "type", + ]) + ); + const options = optionsFromArguments( + OmniOscillator.getDefaults(), + arguments, + ["frequency", "type"] + ); this.frequency = new Signal({ context: this.context, @@ -121,7 +149,7 @@ export class OmniOscillator AMOscillator.getDefaults(), FatOscillator.getDefaults(), PulseOscillator.getDefaults(), - PWMOscillator.getDefaults(), + PWMOscillator.getDefaults() ); } @@ -149,7 +177,7 @@ export class OmniOscillator * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the * oscillator's class are accessible when the oscillator is set to that type, but throws an error - * when it's not. + * when it's not. * @example * const omniOsc = new Tone.OmniOscillator().toDestination().start(); * omniOsc.type = "pwm"; @@ -159,10 +187,10 @@ export class OmniOscillator */ get type(): OmniOscillatorType { let prefix = ""; - if (["am", "fm", "fat"].some(p => this._sourceType === p)) { + if (["am", "fm", "fat"].some((p) => this._sourceType === p)) { prefix = this._sourceType; } - return prefix + this._oscillator.type as OmniOscillatorType; + return (prefix + this._oscillator.type) as OmniOscillatorType; } set type(type) { if (type.substr(0, 2) === "fm") { @@ -185,7 +213,7 @@ export class OmniOscillator } else { this._createNewOscillator("oscillator"); this._oscillator = this._oscillator as Oscillator; - this._oscillator.type = (type as ToneOscillatorType); + this._oscillator.type = type as ToneOscillatorType; } } @@ -198,7 +226,10 @@ export class OmniOscillator return this._oscillator.partials; } set partials(partials) { - if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) { + if ( + !this._getOscType(this._oscillator, "pulse") && + !this._getOscType(this._oscillator, "pwm") + ) { this._oscillator.partials = partials; } } @@ -207,7 +238,10 @@ export class OmniOscillator return this._oscillator.partialCount; } set partialCount(partialCount) { - if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) { + if ( + !this._getOscType(this._oscillator, "pulse") && + !this._getOscType(this._oscillator, "pwm") + ) { this._oscillator.partialCount = partialCount; } } @@ -269,17 +303,20 @@ export class OmniOscillator set sourceType(sType) { // the basetype defaults to sine let baseType = "sine"; - if (this._oscillator.type !== "pwm" && this._oscillator.type !== "pulse") { + if ( + this._oscillator.type !== "pwm" && + this._oscillator.type !== "pulse" + ) { baseType = this._oscillator.type; } // set the type if (sType === "fm") { - this.type = "fm" + baseType as OmniOscillatorType; + this.type = ("fm" + baseType) as OmniOscillatorType; } else if (sType === "am") { - this.type = "am" + baseType as OmniOscillatorType; + this.type = ("am" + baseType) as OmniOscillatorType; } else if (sType === "fat") { - this.type = "fat" + baseType as OmniOscillatorType; + this.type = ("fat" + baseType) as OmniOscillatorType; } else if (sType === "oscillator") { this.type = baseType as OmniOscillatorType; } else if (sType === "pulse") { @@ -291,13 +328,13 @@ export class OmniOscillator private _getOscType( osc: AnyOscillator, - sourceType: SourceType, + sourceType: SourceType ): osc is OmniOscillatorSource[SourceType] { return osc instanceof OmniOscillatorSourceMap[sourceType]; } /** - * The base type of the oscillator. + * The base type of the oscillator. * @see {@link Oscillator.baseType} * @example * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4"); @@ -307,9 +344,12 @@ export class OmniOscillator return this._oscillator.baseType; } set baseType(baseType) { - if (!this._getOscType(this._oscillator, "pulse") && + if ( + !this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm") && - baseType !== "pulse" && baseType !== "pwm") { + baseType !== "pulse" && + baseType !== "pwm" + ) { this._oscillator.baseType = baseType; } } @@ -320,9 +360,15 @@ export class OmniOscillator */ get width(): IsPulseOscillator> { if (this._getOscType(this._oscillator, "pulse")) { - return this._oscillator.width as IsPulseOscillator>; + return this._oscillator.width as IsPulseOscillator< + OscType, + Signal<"audioRange"> + >; } else { - return undefined as IsPulseOscillator>; + return undefined as IsPulseOscillator< + OscType, + Signal<"audioRange"> + >; } } @@ -361,18 +407,28 @@ export class OmniOscillator } /** - * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types. + * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types. * @see {@link AMOscillator} or {@link FMOscillator} */ get modulationType(): IsAmOrFmOscillator { - if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { - return this._oscillator.modulationType as IsAmOrFmOscillator; + if ( + this._getOscType(this._oscillator, "fm") || + this._getOscType(this._oscillator, "am") + ) { + return this._oscillator.modulationType as IsAmOrFmOscillator< + OscType, + ToneOscillatorType + >; } else { return undefined as IsAmOrFmOscillator; } } set modulationType(mType) { - if ((this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) && isString(mType)) { + if ( + (this._getOscType(this._oscillator, "fm") || + this._getOscType(this._oscillator, "am")) && + isString(mType) + ) { this._oscillator.modulationType = mType; } } @@ -383,7 +439,10 @@ export class OmniOscillator */ get modulationIndex(): IsFMOscillator> { if (this._getOscType(this._oscillator, "fm")) { - return this._oscillator.modulationIndex as IsFMOscillator>; + return this._oscillator.modulationIndex as IsFMOscillator< + OscType, + Signal<"positive"> + >; } else { return undefined as IsFMOscillator>; } @@ -394,8 +453,14 @@ export class OmniOscillator * @see {@link AMOscillator} or {@link FMOscillator} */ get harmonicity(): IsAmOrFmOscillator> { - if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) { - return this._oscillator.harmonicity as IsAmOrFmOscillator>; + if ( + this._getOscType(this._oscillator, "fm") || + this._getOscType(this._oscillator, "am") + ) { + return this._oscillator.harmonicity as IsAmOrFmOscillator< + OscType, + Signal<"positive"> + >; } else { return undefined as IsAmOrFmOscillator>; } @@ -409,7 +474,10 @@ export class OmniOscillator */ get modulationFrequency(): IsPWMOscillator> { if (this._getOscType(this._oscillator, "pwm")) { - return this._oscillator.modulationFrequency as IsPWMOscillator>; + return this._oscillator.modulationFrequency as IsPWMOscillator< + OscType, + Signal<"frequency"> + >; } else { return undefined as IsPWMOscillator>; } diff --git a/Tone/source/oscillator/Oscillator.test.ts b/Tone/source/oscillator/Oscillator.test.ts index 044a81b5..ab4f295b 100644 --- a/Tone/source/oscillator/Oscillator.test.ts +++ b/Tone/source/oscillator/Oscillator.test.ts @@ -1,30 +1,32 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Offline } from "test/helper/Offline"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { SourceTests } from "test/helper/SourceTests"; -import { Oscillator } from "./Oscillator"; -import { ToneOscillatorType } from "./OscillatorInterface"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { OutputAudio } from "../../../test/helper/OutputAudio.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { Oscillator } from "./Oscillator.js"; +import { ToneOscillatorType } from "./OscillatorInterface.js"; describe("Oscillator", () => { - // run the common tests BasicTests(Oscillator); SourceTests(Oscillator); OscillatorTests(Oscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new Oscillator().toDestination(); - osc.type = "square"; - osc.start(0).stop(0.2); - }, "oscillator.wav", 0.1); + return CompareToFile( + () => { + const osc = new Oscillator().toDestination(); + osc.type = "square"; + osc.start(0).stop(0.2); + }, + "oscillator.wav", + 0.1 + ); }); context("Get/Set", () => { - it("can be set with an options object", () => { const osc = new Oscillator(); osc.set({ @@ -92,11 +94,9 @@ describe("Oscillator", () => { } osc.dispose(); }); - }); context("Type", () => { - it("can get and set the type", () => { const osc = new Oscillator({ type: "sawtooth", @@ -115,7 +115,12 @@ describe("Oscillator", () => { it("handles 4 basic types", () => { const osc = new Oscillator(); - const types: ToneOscillatorType[] = ["triangle", "sawtooth", "sine", "square"]; + const types: ToneOscillatorType[] = [ + "triangle", + "sawtooth", + "sine", + "square", + ]; for (const type of types) { osc.type = type; expect(osc.type).to.equal(type); @@ -161,7 +166,6 @@ describe("Oscillator", () => { }); context("Partials", () => { - it("can pass partials in the constructor", () => { const osc = new Oscillator({ partials: [1, 0.3, 0.3], @@ -218,7 +222,6 @@ describe("Oscillator", () => { expect(osc.type).to.equal("sine4"); osc.dispose(); }); - }); context("Synchronization", () => { @@ -274,5 +277,4 @@ describe("Oscillator", () => { osc.dispose(); }); }); - }); diff --git a/Tone/source/oscillator/Oscillator.ts b/Tone/source/oscillator/Oscillator.ts index 89d256f1..e661b2ba 100644 --- a/Tone/source/oscillator/Oscillator.ts +++ b/Tone/source/oscillator/Oscillator.ts @@ -1,17 +1,29 @@ -import { AudioRange, Degrees, Frequency, Radians, Time } from "../../core/type/Units"; -import { deepEquals, optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { isDefined } from "../../core/util/TypeCheck"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; import { - generateWaveform, ToneOscillatorConstructorOptions, ToneOscillatorInterface, - ToneOscillatorOptions, ToneOscillatorType -} from "./OscillatorInterface"; -import { ToneOscillatorNode } from "./ToneOscillatorNode"; -import { assertRange } from "../../core/util/Debug"; -import { clamp } from "../../core/util/Math"; -export { ToneOscillatorOptions, ToneOscillatorType } from "./OscillatorInterface"; + AudioRange, + Degrees, + Frequency, + Radians, + Time, +} from "../../core/type/Units.js"; +import { deepEquals, optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { isDefined } from "../../core/util/TypeCheck.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { + generateWaveform, + ToneOscillatorConstructorOptions, + ToneOscillatorInterface, + ToneOscillatorOptions, + ToneOscillatorType, +} from "./OscillatorInterface.js"; +import { ToneOscillatorNode } from "./ToneOscillatorNode.js"; +import { assertRange } from "../../core/util/Debug.js"; +import { clamp } from "../../core/util/Math.js"; +export { + ToneOscillatorOptions, + ToneOscillatorType, +} from "./OscillatorInterface.js"; /** * Oscillator supports a number of features including * phase rotation, multiple oscillator types (see Oscillator.type), @@ -22,8 +34,10 @@ export { ToneOscillatorOptions, ToneOscillatorType } from "./OscillatorInterface * const osc = new Tone.Oscillator(440, "sine").toDestination().start(); * @category Source */ -export class Oscillator extends Source implements ToneOscillatorInterface { - +export class Oscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "Oscillator"; /** @@ -71,11 +85,19 @@ export class Oscillator extends Source implements ToneOsc * @param type The oscillator type. Read more about type below. */ constructor(frequency?: Frequency, type?: ToneOscillatorType); - constructor(options?: Partial) + constructor(options?: Partial); constructor() { - - super(optionsFromArguments(Oscillator.getDefaults(), arguments, ["frequency", "type"])); - const options = optionsFromArguments(Oscillator.getDefaults(), arguments, ["frequency", "type"]); + super( + optionsFromArguments(Oscillator.getDefaults(), arguments, [ + "frequency", + "type", + ]) + ); + const options = optionsFromArguments( + Oscillator.getDefaults(), + arguments, + ["frequency", "type"] + ); this.frequency = new Signal<"frequency">({ context: this.context, @@ -96,7 +118,8 @@ export class Oscillator extends Source implements ToneOsc this._type = options.type; if (options.partialCount && options.type !== "custom") { - this._type = this.baseType + options.partialCount.toString() as ToneOscillatorType; + this._type = (this.baseType + + options.partialCount.toString()) as ToneOscillatorType; } this.phase = options.phase; } @@ -205,19 +228,36 @@ export class Oscillator extends Source implements ToneOsc * the oscillator values when they have already been computed * with the same values. */ - private _getCachedPeriodicWave(): { real: Float32Array; imag: Float32Array; partials: number[]; wave: PeriodicWave } | undefined { + private _getCachedPeriodicWave(): + | { + real: Float32Array; + imag: Float32Array; + partials: number[]; + wave: PeriodicWave; + } + | undefined { if (this._type === "custom") { - const oscProps = Oscillator._periodicWaveCache.find(description => { - return description.phase === this._phase && - deepEquals(description.partials, this._partials); - }); + const oscProps = Oscillator._periodicWaveCache.find( + (description) => { + return ( + description.phase === this._phase && + deepEquals(description.partials, this._partials) + ); + } + ); return oscProps; } else { - const oscProps = Oscillator._periodicWaveCache.find(description => { - return description.type === this._type && - description.phase === this._phase; - }); - this._partialCount = oscProps ? oscProps.partialCount : this._partialCount; + const oscProps = Oscillator._periodicWaveCache.find( + (description) => { + return ( + description.type === this._type && + description.phase === this._phase + ); + } + ); + this._partialCount = oscProps + ? oscProps.partialCount + : this._partialCount; return oscProps; } } @@ -227,7 +267,8 @@ export class Oscillator extends Source implements ToneOsc } set type(type) { this._type = type; - const isBasicType = ["sine", "square", "sawtooth", "triangle"].indexOf(type) !== -1; + const isBasicType = + ["sine", "square", "sawtooth", "triangle"].indexOf(type) !== -1; if (this._phase === 0 && isBasicType) { this._wave = undefined; this._partialCount = 0; @@ -248,7 +289,10 @@ export class Oscillator extends Source implements ToneOsc } } else { const [real, imag] = this._getRealImaginary(type, this._phase); - const periodicWave = this.context.createPeriodicWave(real, imag); + const periodicWave = this.context.createPeriodicWave( + real, + imag + ); this._wave = periodicWave; if (this._oscillator !== null) { this._oscillator.setPeriodicWave(this._wave); @@ -271,11 +315,18 @@ export class Oscillator extends Source implements ToneOsc } get baseType(): OscillatorType { - return (this._type as string).replace(this.partialCount.toString(), "") as OscillatorType; + return (this._type as string).replace( + this.partialCount.toString(), + "" + ) as OscillatorType; } set baseType(baseType) { - if (this.partialCount && this._type !== "custom" && baseType !== "custom") { - this.type = baseType + this.partialCount as ToneOscillatorType; + if ( + this.partialCount && + this._type !== "custom" && + baseType !== "custom" + ) { + this.type = (baseType + this.partialCount) as ToneOscillatorType; } else { this.type = baseType; } @@ -287,7 +338,9 @@ export class Oscillator extends Source implements ToneOsc set partialCount(p) { assertRange(p, 0); let type = this._type; - const partial = /^(sine|triangle|square|sawtooth)(\d+)$/.exec(this._type); + const partial = /^(sine|triangle|square|sawtooth)(\d+)$/.exec( + this._type + ); if (partial) { type = partial[1] as OscillatorType; } @@ -295,13 +348,13 @@ export class Oscillator extends Source implements ToneOsc if (p === 0) { this.type = type; } else { - this.type = type + p.toString() as ToneOscillatorType; + this.type = (type + p.toString()) as ToneOscillatorType; } } else { // extend or shorten the partials array const fullPartials = new Float32Array(p); // copy over the partials array - this._partials.forEach((v, i) => fullPartials[i] = v); + this._partials.forEach((v, i) => (fullPartials[i] = v)); this._partials = Array.from(fullPartials); this.type = this._type; } @@ -312,7 +365,10 @@ export class Oscillator extends Source implements ToneOsc * on the oscillator type. * @returns [real: Float32Array, imaginary: Float32Array] */ - private _getRealImaginary(type: ToneOscillatorType, phase: Radians): Float32Array[] { + private _getRealImaginary( + type: ToneOscillatorType, + phase: Radians + ): Float32Array[] { const fftSize = 4096; let periodicWaveSize = fftSize / 2; @@ -347,20 +403,23 @@ export class Oscillator extends Source implements ToneOsc let b; switch (type) { case "sine": - b = (n <= partialCount) ? 1 : 0; + b = n <= partialCount ? 1 : 0; this._partials[n - 1] = b; break; case "square": - b = (n & 1) ? 2 * piFactor : 0; + b = n & 1 ? 2 * piFactor : 0; this._partials[n - 1] = b; break; case "sawtooth": - b = piFactor * ((n & 1) ? 1 : -1); + b = piFactor * (n & 1 ? 1 : -1); this._partials[n - 1] = b; break; case "triangle": if (n & 1) { - b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1); + b = + 2 * + (piFactor * piFactor) * + (((n - 1) >> 1) & 1 ? -1 : 1); } else { b = 0; } @@ -386,11 +445,16 @@ export class Oscillator extends Source implements ToneOsc /** * Compute the inverse FFT for a given phase. */ - private _inverseFFT(real: Float32Array, imag: Float32Array, phase: Radians): number { + private _inverseFFT( + real: Float32Array, + imag: Float32Array, + phase: Radians + ): number { let sum = 0; const len = real.length; for (let i = 0; i < len; i++) { - sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase); + sum += + real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase); } return sum; } @@ -406,9 +470,16 @@ export class Oscillator extends Source implements ToneOsc const testPositions = 32; // check for peaks in 16 places for (let i = 0; i < testPositions; i++) { - maxValue = Math.max(this._inverseFFT(real, imag, (i / testPositions) * twoPi), maxValue); + maxValue = Math.max( + this._inverseFFT(real, imag, (i / testPositions) * twoPi), + maxValue + ); } - return clamp(-this._inverseFFT(real, imag, this._phase) / maxValue, -1, 1); + return clamp( + -this._inverseFFT(real, imag, this._phase) / maxValue, + -1, + 1 + ); } get partials(): number[] { @@ -426,7 +497,7 @@ export class Oscillator extends Source implements ToneOsc return this._phase * (180 / Math.PI); } set phase(phase) { - this._phase = phase * Math.PI / 180; + this._phase = (phase * Math.PI) / 180; // reset the type this.type = this._type; } diff --git a/Tone/source/oscillator/OscillatorInterface.ts b/Tone/source/oscillator/OscillatorInterface.ts index acb7734e..b62a5abb 100644 --- a/Tone/source/oscillator/OscillatorInterface.ts +++ b/Tone/source/oscillator/OscillatorInterface.ts @@ -4,11 +4,11 @@ import { Degrees, Frequency, Positive, -} from "../../core/type/Units"; -import { Omit } from "../../core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { SourceOptions } from "../Source"; -import { OfflineContext } from "../../core/context/OfflineContext"; +} from "../../core/type/Units.js"; +import { Omit } from "../../core/util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { SourceOptions } from "../Source.js"; +import { OfflineContext } from "../../core/context/OfflineContext.js"; /** * The common interface of all Oscillators @@ -489,7 +489,10 @@ export type OmniOscillatorOptions = | OmniAMPartialsOscillatorOptions | ToneOscillatorConstructorOptions; -type OmitSourceOptions = Omit; +type OmitSourceOptions = Omit< + T, + "frequency" | "detune" | "context" +>; /** * The settable options for the omni oscillator inside of the source which excludes certain attributes that are defined by the parent class diff --git a/Tone/source/oscillator/PWMOscillator.test.ts b/Tone/source/oscillator/PWMOscillator.test.ts index da8bfaab..bfca4bdb 100644 --- a/Tone/source/oscillator/PWMOscillator.test.ts +++ b/Tone/source/oscillator/PWMOscillator.test.ts @@ -1,27 +1,29 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { connectFrom } from "test/helper/Connect"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { SourceTests } from "test/helper/SourceTests"; -import { PWMOscillator } from "./PWMOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { connectFrom } from "../../../test/helper/Connect.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { PWMOscillator } from "./PWMOscillator.js"; describe("PWMOscillator", () => { - // run the common tests BasicTests(PWMOscillator); SourceTests(PWMOscillator); OscillatorTests(PWMOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new PWMOscillator().toDestination(); - osc.start(0.1); - }, "pwmOscillator.wav", 0.01); + return CompareToFile( + () => { + const osc = new PWMOscillator().toDestination(); + osc.start(0.1); + }, + "pwmOscillator.wav", + 0.01 + ); }); context("Modulation Frequency", () => { - it("can set the modulation frequency", () => { const pwm = new PWMOscillator(); pwm.modulationFrequency.value = 0.2; @@ -34,7 +36,6 @@ describe("PWMOscillator", () => { connectFrom().connect(pwm.modulationFrequency); pwm.dispose(); }); - }); context("Types", () => { diff --git a/Tone/source/oscillator/PWMOscillator.ts b/Tone/source/oscillator/PWMOscillator.ts index 09905121..7a5ffa7f 100644 --- a/Tone/source/oscillator/PWMOscillator.ts +++ b/Tone/source/oscillator/PWMOscillator.ts @@ -1,14 +1,18 @@ -import { Degrees, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { Multiply } from "../../signal/Multiply"; -import { Signal } from "../../signal/Signal"; -import { Source } from "../Source"; -import { Oscillator } from "./Oscillator"; -import { generateWaveform, PWMOscillatorOptions, ToneOscillatorInterface } from "./OscillatorInterface"; -import { PulseOscillator } from "./PulseOscillator"; - -export { PWMOscillatorOptions } from "./OscillatorInterface"; +import { Degrees, Frequency, Seconds, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { Multiply } from "../../signal/Multiply.js"; +import { Signal } from "../../signal/Signal.js"; +import { Source } from "../Source.js"; +import { Oscillator } from "./Oscillator.js"; +import { + generateWaveform, + PWMOscillatorOptions, + ToneOscillatorInterface, +} from "./OscillatorInterface.js"; +import { PulseOscillator } from "./PulseOscillator.js"; + +export { PWMOscillatorOptions } from "./OscillatorInterface.js"; /** * PWMOscillator modulates the width of a Tone.PulseOscillator @@ -21,8 +25,10 @@ export { PWMOscillatorOptions } from "./OscillatorInterface"; * }, 0.1, 1); * @category Source */ -export class PWMOscillator extends Source implements ToneOscillatorInterface { - +export class PWMOscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "PWMOscillator"; readonly sourceType = "pwm"; @@ -71,8 +77,17 @@ export class PWMOscillator extends Source implements ToneO constructor(frequency?: Frequency, modulationFrequency?: Frequency); constructor(options?: Partial); constructor() { - super(optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"])); - const options = optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]); + super( + optionsFromArguments(PWMOscillator.getDefaults(), arguments, [ + "frequency", + "modulationFrequency", + ]) + ); + const options = optionsFromArguments( + PWMOscillator.getDefaults(), + arguments, + ["frequency", "modulationFrequency"] + ); this._pulse = new PulseOscillator({ context: this.context, diff --git a/Tone/source/oscillator/PulseOscillator.test.ts b/Tone/source/oscillator/PulseOscillator.test.ts index 90215dbd..dd280f47 100644 --- a/Tone/source/oscillator/PulseOscillator.test.ts +++ b/Tone/source/oscillator/PulseOscillator.test.ts @@ -1,25 +1,28 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Offline } from "test/helper/Offline"; -import { OscillatorTests } from "test/helper/OscillatorTests"; -import { SourceTests } from "test/helper/SourceTests"; -import { PulseOscillator } from "./PulseOscillator"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { Offline } from "../../../test/helper/Offline.js"; +import { OscillatorTests } from "../../../test/helper/OscillatorTests.js"; +import { SourceTests } from "../../../test/helper/SourceTests.js"; +import { PulseOscillator } from "./PulseOscillator.js"; describe("PulseOscillator", () => { - // run the common tests BasicTests(PulseOscillator); SourceTests(PulseOscillator); OscillatorTests(PulseOscillator); it("matches a file", () => { - return CompareToFile(() => { - const osc = new PulseOscillator({ - width: 0.2, - }).toDestination(); - osc.start(0); - }, "pulseOscillator.wav", 0.03); + return CompareToFile( + () => { + const osc = new PulseOscillator({ + width: 0.2, + }).toDestination(); + osc.start(0); + }, + "pulseOscillator.wav", + 0.03 + ); }); context("Phase Rotation", () => { @@ -62,11 +65,9 @@ describe("PulseOscillator", () => { }); }); }); - }); context("Width", () => { - it("can set the width", () => { const osc = new PulseOscillator({ width: 0.2, diff --git a/Tone/source/oscillator/PulseOscillator.ts b/Tone/source/oscillator/PulseOscillator.ts index 14209dcb..f4c10c2e 100644 --- a/Tone/source/oscillator/PulseOscillator.ts +++ b/Tone/source/oscillator/PulseOscillator.ts @@ -1,14 +1,24 @@ -import { Gain } from "../../core/context/Gain"; -import { AudioRange, Degrees, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { readOnly } from "../../core/util/Interface"; -import { Signal } from "../../signal/Signal"; -import { WaveShaper } from "../../signal/WaveShaper"; -import { Source } from "../Source"; -import { Oscillator } from "./Oscillator"; -import { generateWaveform, PulseOscillatorOptions, ToneOscillatorInterface } from "./OscillatorInterface"; - -export { PulseOscillatorOptions } from "./OscillatorInterface"; +import { Gain } from "../../core/context/Gain.js"; +import { + AudioRange, + Degrees, + Frequency, + Seconds, + Time, +} from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { readOnly } from "../../core/util/Interface.js"; +import { Signal } from "../../signal/Signal.js"; +import { WaveShaper } from "../../signal/WaveShaper.js"; +import { Source } from "../Source.js"; +import { Oscillator } from "./Oscillator.js"; +import { + generateWaveform, + PulseOscillatorOptions, + ToneOscillatorInterface, +} from "./OscillatorInterface.js"; + +export { PulseOscillatorOptions } from "./OscillatorInterface.js"; /** * PulseOscillator is an oscillator with control over pulse width, @@ -45,8 +55,10 @@ export { PulseOscillatorOptions } from "./OscillatorInterface"; * }, 0.1, 1); * @category Source */ -export class PulseOscillator extends Source implements ToneOscillatorInterface { - +export class PulseOscillator + extends Source + implements ToneOscillatorInterface +{ readonly name: string = "PulseOscillator"; /** @@ -86,7 +98,7 @@ export class PulseOscillator extends Source implements T */ private _thresh = new WaveShaper({ context: this.context, - mapping: val => val <= 0 ? -1 : 1, + mapping: (val) => (val <= 0 ? -1 : 1), }); /** @@ -96,9 +108,17 @@ export class PulseOscillator extends Source implements T constructor(frequency?: Frequency, width?: AudioRange); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"])); - const options = optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]); + super( + optionsFromArguments(PulseOscillator.getDefaults(), arguments, [ + "frequency", + "width", + ]) + ); + const options = optionsFromArguments( + PulseOscillator.getDefaults(), + arguments, + ["frequency", "width"] + ); this.width = new Signal({ context: this.context, @@ -199,9 +219,9 @@ export class PulseOscillator extends Source implements T } /** - * *Internal use* The carrier oscillator type is fed through the + * *Internal use* The carrier oscillator type is fed through the * waveshaper node to create the pulse. Using different carrier oscillators - * changes oscillator's behavior. + * changes oscillator's behavior. */ set carrierType(type: "triangle" | "sine") { this._triangle.type = type; diff --git a/Tone/source/oscillator/ToneOscillatorNode.test.ts b/Tone/source/oscillator/ToneOscillatorNode.test.ts index 79f27351..1559a6a3 100644 --- a/Tone/source/oscillator/ToneOscillatorNode.test.ts +++ b/Tone/source/oscillator/ToneOscillatorNode.test.ts @@ -1,13 +1,11 @@ import { expect } from "chai"; -import { BasicTests } from "test/helper/Basic"; -import { CompareToFile } from "test/helper/CompareToFile"; -import { Offline, whenBetween } from "test/helper/Offline"; -import { ONLINE_TESTING } from "test/helper/Supports"; -import { Frequency } from "Tone/core/type/Frequency"; -import { ToneOscillatorNode } from "./ToneOscillatorNode"; +import { BasicTests } from "../../../test/helper/Basic.js"; +import { CompareToFile } from "../../../test/helper/CompareToFile.js"; +import { Offline, whenBetween } from "../../../test/helper/Offline.js"; +import { Frequency } from "../../core/type/Frequency.js"; +import { ToneOscillatorNode } from "./ToneOscillatorNode.js"; describe("ToneOscillatorNode", () => { - BasicTests(ToneOscillatorNode); it("matches a file", () => { @@ -18,12 +16,14 @@ describe("ToneOscillatorNode", () => { }); context("Constructor", () => { - it("can be constructed with a frequency and type", () => { const osc0 = new ToneOscillatorNode(330, "square"); expect(osc0.frequency.value).to.equal(330); osc0.dispose(); - const osc1 = new ToneOscillatorNode(Frequency(550).valueOf(), "sawtooth"); + const osc1 = new ToneOscillatorNode( + Frequency(550).valueOf(), + "sawtooth" + ); expect(osc1.frequency.value).to.equal(550); osc1.dispose(); const osc2 = new ToneOscillatorNode("A3", "triangle"); @@ -50,11 +50,9 @@ describe("ToneOscillatorNode", () => { expect(osc.type).to.equal("square"); osc.dispose(); }); - }); context("Type", () => { - it("can get and set the type", () => { const osc = new ToneOscillatorNode(); osc.type = "triangle"; @@ -64,44 +62,42 @@ describe("ToneOscillatorNode", () => { it("can set a periodic wave", () => { const osc = new ToneOscillatorNode(); - const periodicWave = osc.context.createPeriodicWave(Float32Array.from([1, 0]), Float32Array.from([1, 0])); + const periodicWave = osc.context.createPeriodicWave( + Float32Array.from([1, 0]), + Float32Array.from([1, 0]) + ); osc.setPeriodicWave(periodicWave); expect(osc.type).to.equal("custom"); osc.dispose(); }); - }); context("onended", () => { + it("invokes the onended callback in the online context", (done) => { + const osc = new ToneOscillatorNode(); + osc.start(); + osc.stop("+0.3"); + const now = osc.now(); + osc.onended = () => { + expect(osc.now() - now).to.be.within(0.25, 0.5); + osc.dispose(); + done(); + }; + }); - if (ONLINE_TESTING) { - - it("invokes the onended callback in the online context", (done) => { - const osc = new ToneOscillatorNode(); - osc.start(); - osc.stop("+0.3"); - const now = osc.now(); - osc.onended = () => { - expect(osc.now() - now).to.be.within(0.25, 0.5); - osc.dispose(); - done(); - }; - }); - - it("invokes the onended callback only once in the online context", (done) => { - const osc = new ToneOscillatorNode(); - osc.start(); - osc.stop("+0.1"); - osc.stop("+0.2"); - osc.stop("+0.3"); - const now = osc.now(); - osc.onended = () => { - expect(osc.now() - now).to.be.within(0.25, 0.5); - osc.dispose(); - done(); - }; - }); - } + it("invokes the onended callback only once in the online context", (done) => { + const osc = new ToneOscillatorNode(); + osc.start(); + osc.stop("+0.1"); + osc.stop("+0.2"); + osc.stop("+0.3"); + const now = osc.now(); + osc.onended = () => { + expect(osc.now() - now).to.be.within(0.25, 0.5); + osc.dispose(); + done(); + }; + }); it("invokes the onended callback in the offline context", () => { let wasInvoked = false; @@ -140,7 +136,6 @@ describe("ToneOscillatorNode", () => { }); context("Scheduling", () => { - it("throw an error if start is called multiple time", () => { const osc = new ToneOscillatorNode(); osc.start(); @@ -154,7 +149,7 @@ describe("ToneOscillatorNode", () => { return Offline(() => { const osc = new ToneOscillatorNode().toDestination(); osc.start(0).stop(0.1); - }, 0.4).then(buffer => { + }, 0.4).then((buffer) => { expect(buffer.getRmsAtTime(0)).to.be.above(0); expect(buffer.getRmsAtTime(0.09)).to.be.above(0); expect(buffer.getRmsAtTime(0.1)).to.equal(0); @@ -173,38 +168,35 @@ describe("ToneOscillatorNode", () => { }); }); - if (ONLINE_TESTING) { + it("clamps start time to the currentTime", () => { + const osc = new ToneOscillatorNode(); + osc.start(0); + const currentTime = osc.context.currentTime; + expect(osc.getStateAtTime(0)).to.equal("stopped"); + expect(osc.getStateAtTime(currentTime)).to.equal("started"); + osc.dispose(); + }); - it("clamps start time to the currentTime", () => { - const osc = new ToneOscillatorNode(); - osc.start(0); - const currentTime = osc.context.currentTime; - expect(osc.getStateAtTime(0)).to.equal("stopped"); - expect(osc.getStateAtTime(currentTime)).to.equal("started"); + it("clamps stop time to the currentTime", (done) => { + const osc = new ToneOscillatorNode(); + osc.start(0); + let currentTime = osc.context.currentTime; + expect(osc.getStateAtTime(0)).to.equal("stopped"); + expect(osc.getStateAtTime(currentTime)).to.equal("started"); + setTimeout(() => { + currentTime = osc.now(); + osc.stop(0); + expect(osc.getStateAtTime(currentTime + 0.01)).to.equal( + "stopped" + ); osc.dispose(); - }); - - it("clamps stop time to the currentTime", (done) => { - const osc = new ToneOscillatorNode(); - osc.start(0); - let currentTime = osc.context.currentTime; - expect(osc.getStateAtTime(0)).to.equal("stopped"); - expect(osc.getStateAtTime(currentTime)).to.equal("started"); - setTimeout(() => { - currentTime = osc.now(); - osc.stop(0); - expect(osc.getStateAtTime(currentTime + 0.01)).to.equal("stopped"); - osc.dispose(); - done(); - }, 100); - }); - } + done(); + }, 100); + }); }); context("State", () => { - it("reports the right state", () => { - return Offline(() => { const osc = new ToneOscillatorNode(); osc.start(0); @@ -221,7 +213,6 @@ describe("ToneOscillatorNode", () => { }); it("can call stop multiple times, takes the last value", () => { - return Offline(() => { const osc = new ToneOscillatorNode(); osc.start(0); diff --git a/Tone/source/oscillator/ToneOscillatorNode.ts b/Tone/source/oscillator/ToneOscillatorNode.ts index 5766085c..c0058f1a 100644 --- a/Tone/source/oscillator/ToneOscillatorNode.ts +++ b/Tone/source/oscillator/ToneOscillatorNode.ts @@ -1,9 +1,9 @@ -import { connect } from "../../core/context/ToneAudioNode"; -import { Param } from "../../core/context/Param"; -import { Cents, Frequency, Seconds, Time } from "../../core/type/Units"; -import { optionsFromArguments } from "../../core/util/Defaults"; -import { OneShotSource, OneShotSourceOptions } from "../OneShotSource"; -import { readOnly } from "../../core/util/Interface"; +import { connect } from "../../core/context/ToneAudioNode.js"; +import { Param } from "../../core/context/Param.js"; +import { Cents, Frequency, Seconds, Time } from "../../core/type/Units.js"; +import { optionsFromArguments } from "../../core/util/Defaults.js"; +import { OneShotSource, OneShotSourceOptions } from "../OneShotSource.js"; +import { readOnly } from "../../core/util/Interface.js"; export interface ToneOscillatorNodeOptions extends OneShotSourceOptions { frequency: Frequency; @@ -18,7 +18,6 @@ export interface ToneOscillatorNodeOptions extends OneShotSourceOptions { * @category Source */ export class ToneOscillatorNode extends OneShotSource { - readonly name: string = "ToneOscillatorNode"; /** @@ -41,15 +40,20 @@ export class ToneOscillatorNode extends OneShotSource * @param frequency The frequency value * @param type The basic oscillator type */ - constructor( - frequency: Frequency, - type: OscillatorType, - ); + constructor(frequency: Frequency, type: OscillatorType); constructor(options?: Partial); constructor() { - - super(optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"])); - const options = optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]); + super( + optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, [ + "frequency", + "type", + ]) + ); + const options = optionsFromArguments( + ToneOscillatorNode.getDefaults(), + arguments, + ["frequency", "type"] + ); connect(this._oscillator, this._gainNode); diff --git a/package-lock.json b/package-lock.json index 0b537903..7a52ded5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,71 +1,83 @@ { "name": "tone", - "version": "14.9.0", + "version": "15.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tone", - "version": "14.9.0", + "version": "15.0.0", "license": "MIT", "dependencies": { "standardized-audio-context": "^25.3.70", "tslib": "^2.3.1" }, "devDependencies": { - "@tonejs/plot": "0.0.35", + "@rollup/plugin-commonjs": "^25.0.7", "@types/chai": "^4.3.0", "@types/mocha": "^5.2.6", "@types/ua-parser-js": "^0.7.36", - "@typescript-eslint/eslint-plugin": "^5.6.0", - "@typescript-eslint/parser": "^5.6.0", - "async": "^3.2.2", - "chai": "^4.3.4", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "@web/dev-server-esbuild": "^1.0.2", + "@web/dev-server-rollup": "^0.6.1", + "@web/test-runner": "^0.18.1", + "@web/test-runner-puppeteer": "^0.16.0", + "array2d": "^0.0.5", + "audiobuffer-to-wav": "^1.0.0", + "chai": "^5.1.0", "codecov": "^3.8.3", - "cross-var": "^1.1.0", - "eslint": "^7.32.0", - "eslint-plugin-html": "^6.2.0", - "eslint-plugin-jsdoc": "^36.1.1", + "concurrently": "^8.2.2", + "eslint": "^8.56.0", + "eslint-plugin-file-extension-in-import-ts": "^2.1.0", + "eslint-plugin-html": "^8.1.1", + "eslint-plugin-jsdoc": "^48.2.3", + "fft-windowing": "^0.1.4", + "fourier-transform": "^1.1.2", "fs-extra": "^8.1.0", - "glob": "^7.2.0", + "glob": "^10.3.12", "html-webpack-plugin": "^5.5.0", "http-server": "^13.0.2", "jsdom": "^16.7.0", - "karma": "^6.3.9", - "karma-chrome-launcher": "^2.2.0", - "karma-coverage": "^2.1.0", - "karma-firefox-launcher": "^1.3.0", - "karma-mocha": "^2.0.1", - "karma-safari-launcher": "^1.0.0", - "karma-sourcemap-loader": "^0.3.8", - "karma-spec-reporter": "0.0.32", - "karma-typescript": "^5.5.2", "mocha": "^9.1.3", + "plotly.js-dist": "^2.32.0", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", "semver": "^5.7.1", - "showdown": "^2.0.0-alpha", + "showdown": "^2.1.0", "teoria": "^2.5.0", "tmp-promise": "^2.1.1", - "ts-loader": "^7.0.5", - "ts-node": "^8.10.2", + "tonal": "^6.0.1", + "ts-loader": "^9.5.1", "typedoc": "^0.25.13", - "typescript": "^4.4.4", + "typescript": "^5.4.5", "ua-parser-js": "^0.7.31", - "webpack": "^5.65.0", - "webpack-cli": "^4.10.0", - "yargs": "^17.3.0" + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4", + "yargs": "^17.3.0", + "zx": "^8.0.2" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "node_modules/@75lb/deep-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", + "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "lodash.assignwith": "^4.2.0", + "typical": "^7.1.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=12.17" + } + }, + "node_modules/@75lb/deep-merge/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "dev": true, + "engines": { + "node": ">=12.17" } }, "node_modules/@babel/code-frame": { @@ -77,243 +89,6 @@ "@babel/highlight": "^7.10.4" } }, - "node_modules/@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", - "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.13", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.13", - "@babel/types": "^7.18.13", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.13", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/generator/node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", @@ -323,29 +98,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", @@ -404,18 +156,6 @@ "node": ">=4" } }, - "node_modules/@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/runtime": { "version": "7.24.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", @@ -432,162 +172,454 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, "engines": { - "node": ">=6.9.0" + "node": ">=10.0.0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "node_modules/@es-joy/jsdoccomment": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", + "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=16" } }, - "node_modules/@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", - "to-fast-properties": "^2.0.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/types/node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.1.90" + "node": ">=12" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10.0.0" + "node": ">=12" } }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.10.8", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", - "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "comment-parser": "1.2.4", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "1.1.1" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12 || ^14 || ^16" + "node": ">=12" } }, - "node_modules/@es-joy/jsdoccomment/node_modules/jsdoc-type-pratt-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.1.1.tgz", - "integrity": "sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g==", + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.0.0" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -599,52 +631,165 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { - "node": ">=8" + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -660,54 +805,46 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mdn/browser-compat-data": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.2.1.tgz", + "integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -743,157 +880,42 @@ "node": ">= 8" } }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", - "dev": true - }, - "node_modules/@tonejs/plot": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@tonejs/plot/-/plot-0.0.35.tgz", - "integrity": "sha512-g0g6lQzMEVPbazExSWSF+nKErEr0IiQu+Bj4x5BRcLHY5jiDimMQSXzjDLMOVx3IDfYsbmSClZ3OyEO+9C0kOA==", - "dev": true, - "dependencies": { - "array2d": "0.0.5", - "audiobuffer-to-wav": "^1.0.0", - "dsp.js": "^1.0.1", - "fft-windowing": "^0.1.4", - "plotly.js-dist": "^1.45.3" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "optional": true, "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/chai": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", - "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", - "dev": true - }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true - }, - "node_modules/@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "node": ">=14" } }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.7.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.15.tgz", - "integrity": "sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ==", - "dev": true - }, - "node_modules/@types/ua-parser-js": { - "version": "0.7.36", - "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", - "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "node_modules/@puppeteer/browsers": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", + "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" + "bin": { + "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -905,1532 +927,2194 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "node_modules/@rollup/plugin-commonjs": { + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", - "debug": "^4.3.4" + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=14.0.0" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { - "typescript": { + "rollup": { "optional": true } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "balanced-match": "^1.0.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "node_modules/@rollup/plugin-commonjs/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "dependencies": { + "brace-expansion": "^2.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "engines": { + "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=14.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { - "typescript": { + "rollup": { "optional": true } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" + "node": ">=14.0.0" }, - "bin": { - "semver": "bin/semver.js" + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, - "engines": { - "node": ">=10" + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.36.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tonaljs/abc-notation": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/abc-notation/-/abc-notation-4.8.3.tgz", + "integrity": "sha512-ZN+wrlDdiFOLgbGcXiCcCd/ek8P42t7EMgjTA5yVTU8+WwtMSDPmZyNMvfETEVZoWvCOAOW9UVXemP9oFV9OxA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-note": "6.0.0" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "node_modules/@tonaljs/array": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/array/-/array-4.8.3.tgz", + "integrity": "sha512-TeX5vqk61EhlRAIo70d0hKt3a0FEcROsu9ETtTclXl+qaQ1QtEEs0M+B46IZ+sQo5T3s8vtz5z1yCiK26HPr5A==", "dev": true, "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "@tonaljs/pitch-note": "6.0.0" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "node_modules/@tonaljs/chord": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/chord/-/chord-6.0.0.tgz", + "integrity": "sha512-lWTSynCzPO5rV6CQUoM7b5DqmO0VYq3hEwSwo5d+tEdocYwUvfDbPl1JHq2un9f+5nEnNRkb8AfRsbi9wyVsIg==", "dev": true, "dependencies": { - "@xtuc/long": "4.2.2" + "@tonaljs/chord-detect": "4.8.5", + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/interval": "^5.0.0", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-note": "6.0.0", + "@tonaljs/scale-type": "4.8.5" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "node_modules/@tonaljs/chord-detect": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/@tonaljs/chord-detect/-/chord-detect-4.8.5.tgz", + "integrity": "sha512-sH4WBP9wk70YcFAcb02vd6C5odRXj+aoIgf6WaHHFmp/8AH5aK+Vr3uLVavw7u/1mf0B4XK5hGdGEUuQynGTrw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "node_modules/@tonaljs/chord-type": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@tonaljs/chord-type/-/chord-type-5.0.5.tgz", + "integrity": "sha512-Rne/7YwXgPAQSt8DM6/yb61Hfp8stQR4SrhbePjzB/oVwVIzUL+uxH29uwd/KxDkIEITaHXS3v5ntRcVXCQYnA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "node_modules/@tonaljs/collection": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/collection/-/collection-4.8.1.tgz", + "integrity": "sha512-2TaiK9QEjOCkV7jW2B9uo5FPetNoiS9//nNPWXOWjB/E9KGd2SV1THEuxLx1Ew3uXUQpezup5adNljbZtOHbrA==", + "dev": true + }, + "node_modules/@tonaljs/core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/core/-/core-5.0.0.tgz", + "integrity": "sha512-vifjXX+xKidK+q1xGgcfGX79HtIMydXp1NrdGG5VshYHC3TRpVNti4HJDb/6qOjokQp9as/iOCyaAmcWIq0ZUA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@tonaljs/pitch": "5.0.2", + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-interval": "6.0.0", + "@tonaljs/pitch-note": "6.0.0" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "node_modules/@tonaljs/duration-value": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/duration-value/-/duration-value-4.8.1.tgz", + "integrity": "sha512-/jP8Q+z2h+2+IBeTsyF9KWedqu8Jffhvp17/H6pxUJ7b1U+HNdn5G7KfXbblEqhykYSKTSKK/m+86M7j4RnAgw==", + "dev": true + }, + "node_modules/@tonaljs/interval": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/interval/-/interval-5.0.0.tgz", + "integrity": "sha512-WXmi0TdijggCzREc2B0RN3ZtgUQhu8E7DXVqL/lVLAZA8zaVfsFAv4k1NdXr7bkmcCM4yzhXeGzBo8L2QJR1SA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@tonaljs/pitch": "^5.0.2", + "@tonaljs/pitch-distance": "^5.0.3", + "@tonaljs/pitch-interval": "^6.0.0" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "node_modules/@tonaljs/key": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@tonaljs/key/-/key-4.9.4.tgz", + "integrity": "sha512-oq+C8AAmHJdkWs2Txq3ZR5koIeKYSNwQwR3G+Y1Bd+XbXvd/d9d7xJmzxUWY8fnFnvOve8FNShCvoWfnF62HtQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" + "@tonaljs/core": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/roman-numeral": "4.8.3" } }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "node_modules/@tonaljs/midi": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@tonaljs/midi/-/midi-4.9.3.tgz", + "integrity": "sha512-sz6XrX6qoYSW3yDpR0K5JhYpsvlzrIJYFfRiOdf4kmnTPAewYyg7f8nLRMl502lBNCt80Bktx4mDHXaL6tWVKw==", "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "dependencies": { + "@tonaljs/core": "5.0.0" } }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "node_modules/@tonaljs/mode": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/mode/-/mode-4.8.4.tgz", + "integrity": "sha512-6416B8YgWj6hgWgHPsSvizCMoyWg66C/TlviSexQNnYjQHAlp0rAOcLTL3IskVrFNTgNMlNP1vcj+s1kt18LuQ==", "dev": true, "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/interval": "5.0.0", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/scale-type": "4.8.5" } }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "node_modules/@tonaljs/note": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/@tonaljs/note/-/note-4.10.3.tgz", + "integrity": "sha512-GvNILH91kkBV9ISAHK75gFkI8Jr0mvKRkO/wU1OhUAapnOrNzFS+EqxusKGc2Lz2MLIbVFRIBqWdyhxIwgpSCg==", "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } + "dependencies": { + "@tonaljs/core": "5.0.0", + "@tonaljs/midi": "4.9.3" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@tonaljs/pcset": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/@tonaljs/pcset/-/pcset-4.9.2.tgz", + "integrity": "sha512-s8enXa/nsFkJkz96VjcFu+fapEr69ENhr3yoHykPsU+0MlZ9aMWXilE97Ek3eHAX9gT55+mElEU7qGWkwdaU9w==", "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0" } }, - "node_modules/accidental-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/accidental-value/-/accidental-value-1.0.0.tgz", - "integrity": "sha512-Dug400VXZ95UwXqoSjYa3kUvKSDfOtPQAOerbKY5Tk/9Kf3DW3+sYKJK5qv4//TIwIaG2r5xxRN55OwMxCsN7A==", + "node_modules/@tonaljs/pitch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch/-/pitch-5.0.2.tgz", + "integrity": "sha512-mxaXJPPe+LIJdjzpZEl8I8Wx3dEvlzkBbsr2Ltwc2dTAdnErAZ5R0TxVq2egF27lMvQN2QPQPWI9iDPPdVUmrg==", "dev": true }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@tonaljs/pitch-distance": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-distance/-/pitch-distance-5.0.3.tgz", + "integrity": "sha512-3sgU93gfNsMX1wAYXraYJyIJMIViXZRE1Fh/OXwbUi6lEX/iLRmFVSz37ObnaRaOz0pVm+uUhvW2iKy8QtOWpw==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@tonaljs/pitch": "5.0.2", + "@tonaljs/pitch-interval": "6.0.0", + "@tonaljs/pitch-note": "6.0.0" } }, - "node_modules/acorn-globals": { + "node_modules/@tonaljs/pitch-interval": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-interval/-/pitch-interval-6.0.0.tgz", + "integrity": "sha512-0iaFWbgshYWjfmdxzF8jNmTqsNK2krwn+FqDRZb8vEsfaSNC8Jek0f5wYcE2to+7f0P5jJlJnj8CUGvlfKIT5A==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@tonaljs/pitch": "5.0.2" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/@tonaljs/pitch-note": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-note/-/pitch-note-6.0.0.tgz", + "integrity": "sha512-m4Ei7zwSsKwotVfnodA7m1SR7zD5NNIea+V7Mo35EcK32ZJBg+SvxdwgfNNdLO8bkDbVrZIgVYqeP3R3Jq7VFQ==", "dev": true, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@tonaljs/pitch": "5.0.2" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@tonaljs/progression": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/progression/-/progression-4.8.4.tgz", + "integrity": "sha512-cybCQ3szoozZW5v8jydRxdmDCGiZ2sE8qEnqbNz7+RY7WtZCXbK8MAFjPq2M5NGxIwnw94sbM7RV7d6f5W7+nA==", "dev": true, "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" + "@tonaljs/chord": "6.0.0", + "@tonaljs/core": "5.0.0", + "@tonaljs/roman-numeral": "4.8.3" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@tonaljs/range": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/range/-/range-4.8.4.tgz", + "integrity": "sha512-ASB+i34Z5cXnBntaZOlmgZTfiLdKpMjSCL0ohE4ebZBTbTkuZWMKUucMxe2xpNKNBByPKVmeocv/Wpr8GNzU1Q==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@tonaljs/collection": "4.8.1", + "@tonaljs/midi": "4.9.3" } }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/@tonaljs/roman-numeral": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/roman-numeral/-/roman-numeral-4.8.3.tgz", + "integrity": "sha512-U3LnDSVSngWiHEECPAWCvOlqZC0vt8IL/IoXSKXpt9YfW9NYRUlejoQack1NM9M80P8fCBnJQ7Uz3x8mC1eRow==", "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" + "dependencies": { + "@tonaljs/core": "5.0.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "node_modules/@tonaljs/scale": { + "version": "4.12.6", + "resolved": "https://registry.npmjs.org/@tonaljs/scale/-/scale-4.12.6.tgz", + "integrity": "sha512-nWDGNfx+rJuF+FFXbvWvtv7vApHpAlLkpke8C7TTM4lEw+fQXdi0cQaNQDS0QmIReeGSThe9CMxRL8+niabFKQ==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/scale-type": "4.8.5" } }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/@tonaljs/scale-type": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/@tonaljs/scale-type/-/scale-type-4.8.5.tgz", + "integrity": "sha512-3DCo/r3QEalIDG7dSBgRFD90Tm22qXSHuz5pyDUMNZpQuodzxz1BvsXSkC3CMGchX4eoaSjtArfKIrz0oEJUhw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" } }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "node_modules/@tonaljs/time-signature": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/time-signature/-/time-signature-4.8.1.tgz", + "integrity": "sha512-P3h2S1M006LpmPkwuAVS/pP02Hns6pSzKP2ghyit4Lszj4ppwNwcyJ1hgT/TVkiwMbUVbNltTKDraonG+2Xe/g==", "dev": true }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "node_modules/@tonaljs/voice-leading": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voice-leading/-/voice-leading-5.0.3.tgz", + "integrity": "sha512-SFG0YPnuTyyW2tb5bKe2+InJGDb7SGGsfjIxIiIm+B3lhCuQKL9ugOUUgD47uUO3ppidGkbbLZhDABKbLmkvWg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@tonaljs/note": "4.10.3" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@tonaljs/voicing": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voicing/-/voicing-5.0.3.tgz", + "integrity": "sha512-bPE7A086gYlw/Bbbf+XblBtK5pt9bZ3k1sAABZwdaumi7a+8oifHMouaZl2AP3PEYuMkF/80SXDeyC2MvawMKA==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "@tonaljs/chord": "6.0.0", + "@tonaljs/interval": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/range": "4.8.4", + "@tonaljs/voice-leading": "5.0.3", + "@tonaljs/voicing-dictionary": "5.0.3" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@tonaljs/voicing-dictionary": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voicing-dictionary/-/voicing-dictionary-5.0.3.tgz", + "integrity": "sha512-mXg1+9fbMxv/3SZLUss5FIPyAnV5aRognE/suV2FXb3cf+20PjyNGGlRN60w5SBbNZfzj+GPf8DeIwob+RbV8w==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "@tonaljs/chord": "6.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/voice-leading": "5.0.3" } }, - "node_modules/argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==", + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, "engines": { - "node": ">=0.6.10" + "node": ">= 6" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, + "node_modules/@types/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/node": "*" } }, - "node_modules/array2d": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/array2d/-/array2d-0.0.5.tgz", - "integrity": "sha512-j/gCL/6qZX7gjyKC5oYoP1n8Lf+uAVlYtfXCL1uTkcR+NiRdsuvJHgvqdXHmxRvLqparN3EV3cdibDMZTyz54Q==", + "node_modules/@types/babel__code-frame": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.6.tgz", + "integrity": "sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==", "dev": true }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/asn1.js/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/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "node_modules/@types/co-body": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/co-body/-/co-body-6.1.3.tgz", + "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==", "dev": true, "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" + "@types/node": "*", + "@types/qs": "*" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "node_modules/@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "engines": { - "node": "*" + "dependencies": { + "@types/node": "*" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/@types/content-disposition": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", + "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", + "dev": true + }, + "node_modules/@types/convert-source-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-2.0.3.tgz", + "integrity": "sha512-ag0BfJLZf6CQz8VIuRIEYQ5Ggwk/82uvTQf27RcpyDNbY0Vw49LIPqAxk5tqYfrCs9xDaIMvl4aj7ZopnYL8bA==", + "dev": true + }, + "node_modules/@types/cookies": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", + "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" } }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "node_modules/@types/debounce": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", + "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", "dev": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "node_modules/audiobuffer-to-wav": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz", - "integrity": "sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w==", + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "optional": true, + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "dev": true }, - "node_modules/automation-events": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.0.4.tgz", - "integrity": "sha512-uM5VFyhksP/GzzOuGi/ygeI16ked+IA5enGLH9b+BvxUSDnfAWC54RZnnem/iprEKtuWV29FX5gvYcesPAgPAw==", + "node_modules/@types/http-assert": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", + "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.4", - "tslib": "^2.6.2" + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/keygrip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", + "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==", + "dev": true + }, + "node_modules/@types/koa": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", + "dev": true, + "dependencies": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "node_modules/@types/koa-compose": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", + "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", + "dev": true, + "dependencies": { + "@types/koa": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.12.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", + "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/ua-parser-js": { + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=18.2.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4" + }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", "dev": true, "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "semver": "^7.6.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.8.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@web/browser-logs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", + "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", + "dev": true, + "dependencies": { + "errorstacks": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/config-loader": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.1.tgz", + "integrity": "sha512-IYjHXUgSGGNpO3YJQ9foLcazbJlAWDdJGRe9be7aOhon0Nd6Na5JIOJAej7jsMu76fKHr4b4w2LfIdNQ4fJ8pA==", + "dev": true, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.4.tgz", + "integrity": "sha512-Gye0DhDbst/KVNRCFzRd+4V9LJmuuQYJBsf6UXeEbCYuBSKeshEW4AA1esLsfy1gONsD6NIGiru5509l35P9Ug==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/command-line-args": "^5.0.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server-core": "^0.7.1", + "@web/dev-server-rollup": "^0.6.1", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "debounce": "^1.2.0", + "deepmerge": "^4.2.2", + "ip": "^2.0.1", + "nanocolors": "^0.2.1", + "open": "^8.0.2", + "portfinder": "^1.0.32" + }, + "bin": { + "wds": "dist/bin.js", + "web-dev-server": "dist/bin.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.1.tgz", + "integrity": "sha512-alHd2j0f4e1ekqYDR8lWScrzR7D5gfsUZq3BP3De9bkFWM3AELINCmqqlVKmCtlkAdEc9VyQvNiEqrxraOdc2A==", + "dev": true, + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@web/dev-server-core/node_modules/isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "dev": true, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@web/dev-server-core/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "dev": true, + "engines": { + "node": ">=16.14" + } + }, + "node_modules/@web/dev-server-esbuild": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-1.0.2.tgz", + "integrity": "sha512-ak5mKt7L0H/Fa470Ku7p9A1eI32DNyFGM83jDkJviBO8r3lM00O5hVFW1K+UIYNC5EyanLyPxTqgtIuQEyMYcQ==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^4.0.0", + "@web/dev-server-core": "^0.7.0", + "esbuild": "^0.19.11", + "get-tsconfig": "^4.7.2", + "parse5": "^6.0.1", + "ua-parser-js": "^1.0.33" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-esbuild/node_modules/ua-parser-js": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" } }, - "node_modules/babel-core/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@web/dev-server-rollup": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.1.tgz", + "integrity": "sha512-vhtsQ8qu1pBHailOBOYJwZnYDc1Lmx6ZAd2j+y5PD2ck0R1LmVsZ7dZK8hDCpkvpvlu2ndURjL9tbzdcsBRJmg==", "dev": true, "dependencies": { - "ms": "2.0.0" + "@rollup/plugin-node-resolve": "^15.0.1", + "@web/dev-server-core": "^0.7.0", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^4.4.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-core/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "node_modules/@web/dev-server-rollup/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", "dev": true, "dependencies": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" } }, - "node_modules/babel-helper-bindify-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", - "integrity": "sha512-TYX2QQATKA6Wssp6j7jqlw4QLmABDN1olRdEHndYvBXdaXM5dcx6j5rN0+nd+aVL+Th40fAEYvvw/Xxd/LETuQ==", + "node_modules/@web/dev-server-rollup/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "engines": { + "node": ">=12" } }, - "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", + "node_modules/@web/dev-server-rollup/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "dev": true, "dependencies": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", + "node_modules/@web/parse5-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", + "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", "dev": true, "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", + "node_modules/@web/test-runner": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.18.1.tgz", + "integrity": "sha512-jB/9vrpGVtcLY6/7sPpKpSheQ3wWY9P5aQcz2SK2gMHTq3gNpa51NAyec0Al7EFpHvJ1wKYTGRLB2gPyEoJeDg==", "dev": true, "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@web/browser-logs": "^0.4.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server": "^0.4.0", + "@web/test-runner-chrome": "^0.16.0", + "@web/test-runner-commands": "^0.9.0", + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-mocha": "^0.9.0", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "convert-source-map": "^2.0.0", + "diff": "^5.0.0", + "globby": "^11.0.1", + "nanocolors": "^0.2.1", + "portfinder": "^1.0.32", + "source-map": "^0.7.3" + }, + "bin": { + "web-test-runner": "dist/bin.js", + "wtr": "dist/bin.js" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", + "node_modules/@web/test-runner-chrome": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.16.0.tgz", + "integrity": "sha512-Edc6Y49aVB6k18S5IOj9OCX3rEf8F3jptIu0p95+imqxmcutFEh1GNmlAk2bQGnXS0U6uVY7Xbf61fiaXUQqhg==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", + "async-mutex": "0.4.0", + "chrome-launcher": "^0.15.0", + "puppeteer-core": "^22.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-explode-class": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", - "integrity": "sha512-SFbWewr0/0U4AiRzsHqwsbOQeLXVa9T1ELdqEa2efcQB5KopTnunAqoj07TuHlN2lfTQNPGO/rJR4FMln5fVcA==", + "node_modules/@web/test-runner-commands": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", + "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", "dev": true, "dependencies": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@web/test-runner-core": "^0.13.0", + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", + "node_modules/@web/test-runner-commands/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", - "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "node_modules/@web/test-runner-core": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.1.tgz", + "integrity": "sha512-2hESALx/UFsAzK+ApWXAkFp2eCmwcs2yj1v4YjwV8F38sQumJ40P3px3BMjFwkOYDORtQOicW0RUeSw1g3BMLA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.0", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^2.0.1", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", + "node_modules/@web/test-runner-core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@web/test-runner-core/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">= 8" } }, - "node_modules/babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", + "node_modules/@web/test-runner-coverage-v8": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", + "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@web/test-runner-core": "^0.13.0", + "istanbul-lib-coverage": "^3.0.0", + "lru-cache": "^8.0.4", + "picomatch": "^2.2.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", + "node_modules/@web/test-runner-coverage-v8/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "engines": { + "node": ">=16.14" } }, - "node_modules/babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", + "node_modules/@web/test-runner-mocha": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz", + "integrity": "sha512-ZL9F6FXd0DBQvo/h/+mSfzFTSRVxzV9st/AHhpgABtUtV/AIpVE9to6+xdkpu6827kwjezdpuadPfg+PlrBWqQ==", "dev": true, "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@web/test-runner-core": "^0.13.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", + "node_modules/@web/test-runner-puppeteer": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-puppeteer/-/test-runner-puppeteer-0.16.0.tgz", + "integrity": "sha512-/p8zG+FX3LZjJttjQBqEigfGpnoUyEeNXrYReQWT4Uqj16Zm5F7I0UVecmBCRjnplUoXXlNcZNMsXb0jXBucTw==", "dev": true, "dependencies": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@web/test-runner-chrome": "^0.16.0", + "@web/test-runner-core": "^0.13.0", + "puppeteer": "^22.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", + "node_modules/@web/test-runner/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@web/test-runner/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "engines": { + "node": ">=0.3.1" } }, - "node_modules/babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "node_modules/@web/test-runner/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">= 8" } }, - "node_modules/babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", - "dev": true - }, - "node_modules/babel-plugin-syntax-async-generators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha512-EbciFN5Jb9iqU9bqaLmmFLx2G8pAUsvpWJ6OzOWBNrSY9qTohXj+7YfZx6Ug1Qqh7tCb1EA7Jvn9bMC1HBiucg==", - "dev": true - }, - "node_modules/babel-plugin-syntax-class-constructor-call": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", - "integrity": "sha512-EEuBcXz/wZ81Jaac0LnMHtD4Mfz9XWn2oH2Xj+CHwz2SZWUqqdtR2BgWPSdTGMmxN/5KLSh4PImt9+9ZedDarA==", - "dev": true - }, - "node_modules/babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", - "dev": true - }, - "node_modules/babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", - "dev": true - }, - "node_modules/babel-plugin-syntax-do-expressions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", - "integrity": "sha512-HD/5qJB9oSXzl0caxM+aRD7ENICXqcc3Up/8toDQk7zNIDE7TzsqtxC5f4t9Rwhu2Ya8l9l4j6b3vOsy+a6qxg==", - "dev": true - }, - "node_modules/babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==", - "dev": true - }, - "node_modules/babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, - "node_modules/babel-plugin-syntax-export-extensions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha512-Eo0rcRaIDMld/W6mVhePiudIuLW+Cr/8eveW3mBREfZORScZgx4rh6BAPyvzdEc/JZvQ+LkC80t0VGFs6FX+lg==", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, - "node_modules/babel-plugin-syntax-function-bind": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", - "integrity": "sha512-m8yMoh9LIiNyeLdQs5I9G+3YXo4nqVsKQkk7YplrG4qAFbNi9hkZlow8HDHxhH9QOVFPHmy8+03NzRCdyChIKw==", + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, - "node_modules/babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", - "dev": true + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } }, - "node_modules/babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, - "node_modules/babel-plugin-transform-async-generator-functions": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", - "integrity": "sha512-uT7eovUxtXe8Q2ufcjRuJIOL0hg6VAUJhiWJBLxH/evYAw+aqoJLcYTR8hqx13iOx/FfbCMHgBmXWZjukbkyPg==", + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, - "node_modules/babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/babel-plugin-transform-class-constructor-call": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", - "integrity": "sha512-RvYukT1Nh7njz8P8326ztpQUGCKwmjgu6aRIx1lkvylWITYcskg29vy1Kp8WXIq7FvhXsz0Crf2kS94bjB690A==", + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { - "babel-plugin-syntax-class-constructor-call": "^6.18.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@xtuc/long": "4.2.2" } }, - "node_modules/babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, - "node_modules/babel-plugin-transform-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", - "integrity": "sha512-skQ2CImwDkCHu0mkWvCOlBCpBIHW4/49IZWVwV4A/EnWjL9bB6UBvLyMNe3Td5XDStSZNhe69j4bfEW8dvUbew==", + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/babel-plugin-transform-do-expressions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", - "integrity": "sha512-yQwYqYg+Tnj1InA8W1rsItsZVhkv1Euc4KVua9ledtPz5PDWYz7LVyy6rDBpVYUWFZj5k6GUm3YZpCbIm8Tqew==", + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "babel-plugin-syntax-do-expressions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, - "node_modules/babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" } }, - "node_modules/babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, - "node_modules/babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, - "dependencies": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, - "node_modules/babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", + "node_modules/accidental-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/accidental-value/-/accidental-value-1.0.0.tgz", + "integrity": "sha512-Dug400VXZ95UwXqoSjYa3kUvKSDfOtPQAOerbKY5Tk/9Kf3DW3+sYKJK5qv4//TIwIaG2r5xxRN55OwMxCsN7A==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "node_modules/babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, - "node_modules/babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "peerDependencies": { + "ajv": "^6.9.1" } }, - "node_modules/babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "dependencies": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", - "dev": true, - "dependencies": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true }, - "node_modules/babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", + "node_modules/ansi-styles/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", - "dev": true, - "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "node_modules/ansi-styles/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=14" } }, - "node_modules/babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", + "node_modules/argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", + "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==", "dev": true, - "dependencies": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=0.6.10" } }, - "node_modules/babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha512-mtzELzINaYqdVglyZrDDVwkcFRuE7s6QUFWXxwffKAHB/NkfbJ2NJSytugB43ytIC8UVt30Ereyx+7gNyTkDLg==", + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, - "dependencies": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=6" } }, - "node_modules/babel-plugin-transform-function-bind": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", - "integrity": "sha512-9Ec4KYf1GurT39mlUjDSlN7HWSlB3u3mWRMogQbb+Y88lO0ZM3rJ0ADhPnQwWK9TbO6e/4E+Et1rrfGY9mFimA==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "babel-plugin-syntax-function-bind": "^6.8.0", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=8" } }, - "node_modules/babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", - "dev": true, - "dependencies": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } + "node_modules/array2d": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/array2d/-/array2d-0.0.5.tgz", + "integrity": "sha512-j/gCL/6qZX7gjyKC5oYoP1n8Lf+uAVlYtfXCL1uTkcR+NiRdsuvJHgvqdXHmxRvLqparN3EV3cdibDMZTyz54Q==", + "dev": true }, - "node_modules/babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "dependencies": { - "regenerator-transform": "^0.10.0" + "engines": { + "node": ">=12" } }, - "node_modules/babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" } }, - "node_modules/babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha512-XfwUqG1Ry6R43m4Wfob+vHbIVBIqTg/TJY4Snku1iIzeH7mUnwHA8Vagmv+ZQbPwhS8HgsdQvy28Py3k5zpoFQ==", - "deprecated": "🙌 Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!", + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "dependencies": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "engines": { + "node": ">=8" } }, - "node_modules/babel-preset-stage-0": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", - "integrity": "sha512-MJD+xBbpsApbKlzAX0sOBF+VeFaUmv5s8FSOO7SSZpes1QgphCjq/UIGRFWSmQ/0i5bqQjLGCTXGGXqcLQ9JDA==", + "node_modules/async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", "dev": true, "dependencies": { - "babel-plugin-transform-do-expressions": "^6.22.0", - "babel-plugin-transform-function-bind": "^6.22.0", - "babel-preset-stage-1": "^6.24.1" + "tslib": "^2.4.0" } }, - "node_modules/babel-preset-stage-1": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", - "integrity": "sha512-rn+UOcd7BHDniq1SVxv2/AVVSVI1NK+hfS0I/iR6m6KbOi/aeBRcqBilqO73pd9VUpRXF2HFtlDuC9F2BEQqmg==", - "dev": true, - "dependencies": { - "babel-plugin-transform-class-constructor-call": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-preset-stage-2": "^6.24.1" - } + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, - "node_modules/babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha512-9F+nquz+37PrlTSBdpeQBKnQfAMNBnryXw+m4qBh35FNbJPfzZz+sjN2G5Uf1CRedU9PH7fJkTbYijxmkLX8Og==", - "dev": true, - "dependencies": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" - } + "node_modules/audiobuffer-to-wav": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz", + "integrity": "sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w==", + "dev": true }, - "node_modules/babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha512-eCbEOF8uN0KypFXJmZXn2sTk7bPV9uM5xov7G/7BM08TbQEObsVs0cEWfy6NQySlfk7JBi/t+XJP1JkruYfthA==", - "dev": true, + "node_modules/automation-events": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.0.4.tgz", + "integrity": "sha512-uM5VFyhksP/GzzOuGi/ygeI16ked+IA5enGLH9b+BvxUSDnfAWC54RZnnem/iprEKtuWV29FX5gvYcesPAgPAw==", "dependencies": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" + "@babel/runtime": "^7.24.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.2.0" } }, - "node_modules/babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", - "dev": true, - "dependencies": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, - "node_modules/babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", + "node_modules/bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } + "optional": true }, - "node_modules/babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "node_modules/bare-fs": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.0.tgz", + "integrity": "sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw==", "dev": true, + "optional": true, "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^1.0.0" } }, - "node_modules/babel-traverse/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/babel-traverse/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "optional": true }, - "node_modules/babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "node_modules/bare-path": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.2.tgz", + "integrity": "sha512-o7KSt4prEphWUHa3QUwCxUI00R86VdjiuxmJK0iNVDHYPGo+HsDaVCnqCmPbf/MiW1ok8F4p3m8RTHlWk8K2ig==", "dev": true, + "optional": true, "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "bare-os": "^2.1.0" } }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "node_modules/bare-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-1.0.0.tgz", + "integrity": "sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ==", "dev": true, - "bin": { - "babylon": "bin/babylon.js" + "optional": true, + "dependencies": { + "streamx": "^2.16.1" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2451,15 +3135,6 @@ } ] }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true, - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, "node_modules/basic-auth": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", @@ -2469,13 +3144,13 @@ "node": ">= 0.6" } }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, "engines": { - "node": "*" + "node": ">=10.0.0" } }, "node_modules/binary-extensions": { @@ -2487,203 +3162,50 @@ "node": ">=8" } }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } + "dev": true }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -2693,13 +3215,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -2732,23 +3258,32 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/bytes": { "version": "3.1.2", @@ -2759,14 +3294,33 @@ "node": ">= 0.8" } }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2804,9 +3358,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001390", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001390.tgz", - "integrity": "sha512-sS4CaUM+/+vqQUlCvCJ2WtDlV81aWtHhqeEVkLokVJJa3ViN4zDxAGfq9R8i1m90uGHxo99cy10Od+lvn3hf0g==", + "version": "1.0.30001615", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001615.tgz", + "integrity": "sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ==", "dev": true, "funding": [ { @@ -2816,50 +3370,67 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.0.tgz", + "integrity": "sha512-kDZ7MZyM6Q1DhR9jy7dalKohXQ2yrlXkk59CR52aRKxJrobmlBNqnFQxX9xOX8w+4mz8SYlKJa/7D7ddltFXCw==", "dev": true, "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "assertion-error": "^2.0.1", + "check-error": "^2.0.0", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz", + "integrity": "sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog==", "dev": true, "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/chokidar": { @@ -2889,6 +3460,36 @@ "fsevents": "~2.3.2" } }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chrome-launcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -2898,20 +3499,24 @@ "node": ">=6.0" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "node_modules/chromium-bidi": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.19.tgz", + "integrity": "sha512-UA6zL77b7RYCjJkZBsZ0wlvCTD+jTjllZ8f6wdO4buevXgTZYjV+XLB9CiEa2OuuTGGTLnI7eN9I60YxuALGQg==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" + }, + "peerDependencies": { + "devtools-protocol": "*" } }, "node_modules/clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "dev": true, "dependencies": { "source-map": "~0.6.0" @@ -2920,13 +3525,16 @@ "node": ">= 10.0" } }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/cliui": { @@ -2940,36 +3548,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -2984,6 +3562,28 @@ "node": ">=6" } }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/co-body": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz", + "integrity": "sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==", + "dev": true, + "dependencies": { + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + } + }, "node_modules/codecov": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.3.tgz", @@ -3020,48 +3620,69 @@ "dev": true }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, "engines": { - "node": ">=0.1.90" + "node": ">= 0.8" } }, - "node_modules/combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", "dev": true, "dependencies": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "node_modules/combine-source-map/node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/command-line-usage": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", + "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^3.0.0", + "typical": "^7.1.1" }, "engines": { - "node": ">= 0.8" + "node": ">=12.20.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "dev": true, + "engines": { + "node": ">=12.17" } }, "node_modules/commander": { @@ -3074,114 +3695,129 @@ } }, "node_modules/comment-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, "engines": { "node": ">= 12.0.0" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "node_modules/concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", "dev": true, "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" }, "engines": { - "node": ">= 0.10.0" + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, "engines": { "node": ">= 0.6" } }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true, "engines": { "node": ">= 0.6" } }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", "dev": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "depd": "~2.0.0", + "keygrip": "~1.1.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, "node_modules/corser": { @@ -3193,96 +3829,62 @@ "node": ">= 0.4.0" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/create-ecdh/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/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/cross-var": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cross-var/-/cross-var-1.1.0.tgz", - "integrity": "sha512-wIcFax9RNm5ayuORUeJ5MLxPbfh8XdZhhUpKutIszU46Fs9UIhEdPJ7+YguM+7FxEj+68hSQVyathVsIu84SiA==", + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "babel-preset-es2015": "^6.18.0", - "babel-preset-stage-0": "^6.16.0", - "babel-register": "^6.18.0", - "cross-spawn": "^5.0.1", - "exit": "^0.1.2" + "argparse": "^2.0.1" }, "bin": { - "cross-var": "index.js" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": "*" + "node": ">= 8" } }, "node_modules/css-select": { @@ -3337,18 +3939,21 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "node_modules/daccord": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/daccord/-/daccord-1.1.0.tgz", "integrity": "sha512-LMIBv6VNgcZqD5zQEPps5xT+EyrClJwCzJR9qWGhZ4SoWylPucqtiwIWm9Z7Yla90A017+408HXh6RS4o2qkgw==", "dev": true }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -3363,15 +3968,28 @@ "node": ">=10" } }, - "node_modules/date-format": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.13.tgz", - "integrity": "sha512-bnYCwf8Emc3pTD8pXnre+wfnjGtfi5ncMDKy7+cWZXbmRAsdWkOQHrfC1yz/KiwP5thDp2kCHWYWKBX4HP1hoQ==", + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, "engines": { - "node": ">=4.0" + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3408,40 +4026,44 @@ "dev": true }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.1.tgz", + "integrity": "sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw==", "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "dependencies": { - "clone": "^1.0.2" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3450,6 +4072,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3459,6 +4104,12 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3468,14 +4119,13 @@ "node": ">= 0.8" } }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "engines": { + "node": ">= 0.6.0" } }, "node_modules/destroy": { @@ -3488,48 +4138,10 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", - "dev": true, - "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/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/devtools-protocol": { + "version": "0.0.1273771", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1273771.tgz", + "integrity": "sha512-QDbb27xcTVReQQW/GHJsdQqGKwYBE7re7gxehj467kKP2DKuYBUj6i2k5LRiAC66J1yZG/9gsxooz/s9pcm0Og==", "dev": true }, "node_modules/dir-glob": { @@ -3565,18 +4177,6 @@ "utila": "~0.4" } }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -3600,18 +4200,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -3684,10 +4272,10 @@ "tslib": "^2.0.3" } }, - "node_modules/dsp.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dsp.js/-/dsp.js-1.0.1.tgz", - "integrity": "sha512-5ols1j2i2tdbtd38DMR6xGSmE8dE/qFWgqrNN1ZNnIZnOEAFjzoVq5hM57nbQS9u0VmxqCUw8YccgsS9+zhtNg==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, "node_modules/ee-first": { @@ -3697,30 +4285,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.241", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.241.tgz", - "integrity": "sha512-e7Wsh4ilaioBZ5bMm6+F4V5c11dh56/5Jwz7Hl5Tu1J7cnB+Pqx5qIF2iC7HPpfyQMqGSvvLP5bBAIDd2gAtGw==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/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==", + "version": "1.4.754", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.754.tgz", + "integrity": "sha512-7Kr5jUdns5rL/M9wFFmMZAgFDuL2YOnanFH4OI4iFzUqyh3XOL7nAGbSlSMZdzKMIyyTpNSbqZsWG9odwLeKvA==", "dev": true }, "node_modules/emoji-regex": { @@ -3729,15 +4296,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -3747,102 +4305,32 @@ "node": ">= 0.8" } }, - "node_modules/engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "once": "^1.4.0" } }, "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/enhanced-resolve/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=8.6" + "node": ">=10.13.0" } }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "engines": { "node": ">=0.12" @@ -3851,10 +4339,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -3863,88 +4360,90 @@ "node": ">=4" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" + "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "node_modules/errorstacks": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/errorstacks/-/errorstacks-2.4.1.tgz", + "integrity": "sha512-jE4i0SMYevwu/xxAuzhly/KTwtj0xDhbzB6m1xPImxTkw8wcCbgarOQPfCVMi5JKVyW7in29pNJCCJrry3Ynnw==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", + "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==", "dev": true }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -3966,15 +4465,14 @@ } }, "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", @@ -3996,172 +4494,122 @@ "node": ">=4.0" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-plugin-file-extension-in-import-ts": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-file-extension-in-import-ts/-/eslint-plugin-file-extension-in-import-ts-2.1.0.tgz", + "integrity": "sha512-zK8HbxkWlMI+t8hmMRg8pgQB8e1WVglnpcAQ2YkEIMyUh0jb5bgU++Bjwh60qVbJUh820x7DzwJDR72r3tLbUA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.1", + "resolve": "^1.22.8" + } + }, "node_modules/eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-8.1.1.tgz", + "integrity": "sha512-6qmlJsc40D2m3Dn9oEH+0PAOkJhxVu0f5sVItqpCE0YWgYnyP4xCjBc3UWTHaJcY9ARkWOLIIuXLq0ndRnQOHw==", "dev": true, "dependencies": { - "htmlparser2": "^7.1.2" + "htmlparser2": "^9.1.0" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/eslint-plugin-jsdoc": { - "version": "36.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.1.1.tgz", - "integrity": "sha512-nuLDvH1EJaKx0PCa9oeQIxH6pACIhZd1gkalTUxZbaxxwokjs7TplqY0Q8Ew3CoZaf5aowm0g/Z3JGHCatt+gQ==", + "version": "48.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.3.tgz", + "integrity": "sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "0.10.8", - "comment-parser": "1.2.4", - "debug": "^4.3.2", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^1.1.1", - "lodash": "^4.17.21", - "regextras": "^0.8.0", - "semver": "^7.3.5", - "spdx-expression-parse": "^3.0.1" + "@es-joy/jsdoccomment": "~0.42.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": "^12 || ^14 || ^16" + "node": ">=18" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4173,12 +4621,6 @@ "node": ">=10" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -4192,114 +4634,24 @@ "node": ">=8.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/color-convert": { + "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -4312,186 +4664,97 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=8" + "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "argparse": "^2.0.1" }, "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/espree/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, "node_modules/esprima": { @@ -4508,9 +4771,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4558,6 +4821,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4567,6 +4836,15 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -4582,37 +4860,53 @@ "node": ">=0.8.x" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -4674,6 +4968,15 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fft-windowing": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/fft-windowing/-/fft-windowing-0.1.4.tgz", @@ -4704,49 +5007,16 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "dependencies": { - "ee-first": "1.1.1" + "array-back": "^3.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">=4.0.0" } }, "node_modules/find-up": { @@ -4775,28 +5045,64 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -4813,13 +5119,32 @@ } } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { @@ -4836,16 +5161,19 @@ "node": ">= 6" } }, - "node_modules/fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha512-05cXDIwNbFaoFWaz5gNHlUTbH5whiss/hr/ibzPd4MH3cR4w0ZKeIPiVdbyJurg3O5r/Bjpvn9KOb1/rPMf3nA==", + "node_modules/fourier-transform": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fourier-transform/-/fourier-transform-1.1.2.tgz", + "integrity": "sha512-TjdHddt7Wul3RXvm3O5euI64aAzUPhE1rqzuAFsIu7Puyny6CNLgL8bbKtYoIK71HSF90o+9WjUmRsXmYGYD0Q==", + "dev": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "dependencies": { - "null-check": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, "node_modules/fs-extra": { @@ -4883,53 +5211,14 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4940,59 +5229,124 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=14.14" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/get-uri/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/get-uri/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5016,13 +5370,28 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/globby": { @@ -5054,10 +5423,28 @@ "node": ">=8" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/growl": { @@ -5069,55 +5456,34 @@ "node": ">=4.x" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, "engines": { - "node": ">= 0.4.0" + "node": ">=4" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "es-define-property": "^1.0.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5136,12 +5502,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -5150,48 +5516,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "node": ">= 0.4" } }, "node_modules/he": { @@ -5213,30 +5547,6 @@ "notecoord": "^1.0.1" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", - "dev": true, - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -5277,9 +5587,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -5296,13 +5606,22 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -5312,10 +5631,91 @@ } ], "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" } }, "node_modules/http-errors": { @@ -5397,82 +5797,6 @@ "node": ">=6" } }, - "node_modules/http-server/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/http-server/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/http-server/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/http-server/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/http-server/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/http-server/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -5519,9 +5843,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -5580,6 +5904,15 @@ "node": ">=0.8.19" } }, + "node_modules/inflation": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", + "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5596,27 +5929,13 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", - "dev": true, - "dependencies": { - "source-map": "~0.5.3" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, "engines": { - "node": ">= 0.4" + "node": ">=10.13.0" } }, "node_modules/interval-coords": { @@ -5625,42 +5944,36 @@ "integrity": "sha512-s7tB4gLonSlNpJ1bIzQUtdehpX7BjdCQnlBfKl6wXNo93/KIrum/DQdKOzbObjTrfYY4IwlRfJI7NZdFoRo0Qw==", "dev": true }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "dependencies": { - "loose-envify": "^1.0.0" - } + "node_modules/ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", + "dev": true }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 12" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -5674,56 +5987,28 @@ "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "builtin-modules": "^3.3.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5753,18 +6038,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5801,33 +6074,11 @@ "node": ">=0.10.0" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true }, "node_modules/is-number": { "version": "7.0.0", @@ -5838,19 +6089,13 @@ "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/is-plain-obj": { @@ -5880,81 +6125,25 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "*" } }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-unicode-supported": { @@ -5969,18 +6158,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5993,24 +6170,6 @@ "node": ">=8" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6035,89 +6194,20 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, "engines": { "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", @@ -6131,6 +6221,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -6169,12 +6277,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true - }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -6188,10 +6290,16 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "node_modules/jsdoc-type-pratt-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.2.0.tgz", - "integrity": "sha512-4STjeF14jp4bqha44nKMY1OUI6d2/g6uclHWUCZ7B4DoLzaB5bmpTkQrpqU+vSVzMD0LsKAOskcnI3I3VfIpmg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" @@ -6255,14 +6363,11 @@ "node": ">=0.4.0" } }, - "node_modules/jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -6278,24 +6383,9 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - } + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/jsonc-parser": { "version": "3.2.1", @@ -6312,274 +6402,182 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/karma": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.0.tgz", - "integrity": "sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==", + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", "dev": true, "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" + "tsscmp": "1.0.6" }, "engines": { - "node": ">= 10" + "node": ">= 0.6" } }, - "node_modules/karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { - "fs-access": "^1.0.0", - "which": "^1.2.1" + "json-buffer": "3.0.1" } }, - "node_modules/karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" - }, "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/karma-firefox-launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz", - "integrity": "sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ==", - "dev": true, - "dependencies": { - "is-wsl": "^2.1.0" + "node": ">=0.10.0" } }, - "node_modules/karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", "dev": true, "dependencies": { - "minimist": "^1.2.3" + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" } }, - "node_modules/karma-safari-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz", - "integrity": "sha512-qmypLWd6F2qrDJfAETvXDfxHvKDk+nyIjpH9xIeI3/hENr0U3nuqkxaftq73PfXZ4aOuOChA6SnLW4m4AxfRjQ==", - "dev": true, - "peerDependencies": { - "karma": ">=0.9" - } + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true }, - "node_modules/karma-sourcemap-loader": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz", - "integrity": "sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g==", + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.2" + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" } }, - "node_modules/karma-spec-reporter": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz", - "integrity": "sha512-ZXsYERZJMTNRR2F3QN11OWF5kgnT/K2dzhM+oY3CDyMrDI3TjIWqYGG7c15rR9wjmy9lvdC+CCshqn3YZqnNrA==", + "node_modules/koa-etag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", + "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", "dev": true, "dependencies": { - "colors": "^1.1.2" - }, - "peerDependencies": { - "karma": ">=0.9" - } - }, - "node_modules/karma-typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/karma-typescript/-/karma-typescript-5.5.3.tgz", - "integrity": "sha512-l1FHurolXEBIzRa9ExpNtjzysAhsi/vLpTazpwLHWWK86mknvVpqor6pRZ5Nid7jvOPrTBqAq0JRuLgiCdRkFw==", - "dev": true, - "dependencies": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2", - "assert": "^2.0.0", - "async": "^3.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.4.3", - "combine-source-map": "^0.8.0", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "convert-source-map": "^1.7.0", - "crypto-browserify": "^3.12.0", - "diff": "^4.0.1", - "domain-browser": "^4.16.0", - "events": "^3.2.0", - "glob": "^7.1.6", - "https-browserify": "^1.0.0", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.19", - "log4js": "^6.3.0", - "minimatch": "^3.0.4", - "os-browserify": "^0.3.0", - "pad": "^3.2.0", - "path-browserify": "^1.0.0", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.1.1", - "source-map": "^0.7.3", - "stream-browserify": "^3.0.0", - "stream-http": "^3.1.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.11", - "tmp": "^0.2.1", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.1", - "vm-browserify": "^1.1.2" - }, - "peerDependencies": { - "karma": "1 || 2 || 3 || 4 || 5 || 6", - "typescript": "1 || 2 || 3 || 4" + "etag": "^1.8.1" } }, - "node_modules/karma-typescript/node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "node_modules/koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" }, "engines": { - "node": ">=0.4.0" + "node": ">= 8" } }, - "node_modules/karma-typescript/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "node_modules/koa-send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">= 0.6" } }, - "node_modules/karma-typescript/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "node_modules/koa-send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/karma-typescript/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/karma-typescript/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" + "node": ">= 0.6" } }, - "node_modules/karma/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "node_modules/koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", "dev": true, - "bin": { - "mime": "cli.js" + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">= 7.6.0" } }, - "node_modules/karma/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 0.6" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, "node_modules/levn": { @@ -6595,39 +6593,44 @@ "node": ">= 0.8.0" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, - "engines": { - "node": ">=6.11.5" + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" } }, - "node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" + "ms": "2.0.0" } }, - "node_modules/loader-utils/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" + "engines": { + "node": ">=6.11.5" } }, "node_modules/locate-path": { @@ -6651,10 +6654,16 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "node_modules/lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, "node_modules/lodash.merge": { @@ -6663,12 +6672,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -6685,111 +6688,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/log4js": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.6.1.tgz", - "integrity": "sha512-J8VYFH2UQq/xucdNu71io4Fo+purYYudyErgBbswWKO0MC6QVOERRomt5su/z6d3RJSmLyTGmXl3Q/XjKCf+/A==", - "dev": true, - "dependencies": { - "date-format": "^4.0.13", - "debug": "^4.3.4", - "flatted": "^3.2.6", - "rfdc": "^1.3.0", - "streamroller": "^3.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.0.tgz", + "integrity": "sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lower-case": { @@ -6802,13 +6739,15 @@ } }, "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/lunr": { @@ -6817,36 +6756,45 @@ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -6859,16 +6807,11 @@ "node": ">= 12" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } + "node_modules/marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "dev": true }, "node_modules/media-typer": { "version": "0.3.0", @@ -6879,43 +6822,6 @@ "node": ">= 0.6" } }, - "node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/memory-fs/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/memory-fs/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -6944,25 +6850,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/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==", - "dev": true - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -6996,17 +6883,14 @@ "node": ">= 0.6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } }, "node_modules/minimatch": { "version": "3.1.2", @@ -7026,6 +6910,21 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -7226,21 +7125,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/mocha/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -7265,6 +7149,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanocolors": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", + "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", + "dev": true + }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -7298,6 +7188,15 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -7351,9 +7250,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-path": { @@ -7383,101 +7282,78 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha512-j8ZNHg19TyIQOWCGeeQJBuu6xZYIEurf8M1Qsfd8mFrGEfIZytbw18YjKWg+LcO25NowXGZXZpKAx+Ui3TFfDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nwsapi": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "ee-first": "1.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "engines": { - "node": ">= 0.4" + "dependencies": { + "wrappy": "1" } }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { - "ee-first": "1.1.1" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/opener": { @@ -7490,9 +7366,9 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", @@ -7500,36 +7376,12 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7569,23 +7421,75 @@ "node": ">=6" } }, - "node_modules/pad": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/pad/-/pad-3.2.0.tgz", - "integrity": "sha512-2u0TrjcGbOjBTJpyewEl4hBO3OeX5wWue7eIFPzQTg6wFSvoaHcBTTUY5m+n0hd04gmTCPuY0kCpVIVuw5etwg==", + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", "dev": true, "dependencies": { - "wcwidth": "^1.0.1" + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" }, "engines": { - "node": ">= 4.0.0" + "node": ">= 14" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } }, "node_modules/param-case": { "version": "3.0.4", @@ -7609,17 +7513,22 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse5": { @@ -7647,12 +7556,6 @@ "tslib": "^2.0.3" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7686,6 +7589,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -7696,29 +7624,19 @@ } }, "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, "engines": { - "node": "*" + "node": ">= 14.16" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true }, "node_modules/picocolors": { "version": "1.0.0", @@ -7809,9 +7727,9 @@ } }, "node_modules/plotly.js-dist": { - "version": "1.58.5", - "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-1.58.5.tgz", - "integrity": "sha512-gy4cm5gYeem1eoXeryrSfftDm/CacQUE+W6xPRGiC5PnB/WHDPaex+HVeAGdKEek57ok1j2IkDw3lnXoB0Bfiw==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-2.32.0.tgz", + "integrity": "sha512-+RnvqNTJADe3ctmCMT2YOhXu4ZwYuBi7eD4FF0oyaJ8jWj65Ru6lZVnetr7T3ZvnU5BgQWbbId+tYgf0PBFkeQ==", "dev": true }, "node_modules/portfinder": { @@ -7855,59 +7773,110 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "dev": true, "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, "engines": { - "node": ">= 0.6" + "node": ">= 14" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, "engines": { - "node": ">= 0.6.0" + "node": ">= 14" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, "node_modules/psl": { @@ -7916,26 +7885,16 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/public-encrypt/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==", - "dev": true - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -7945,13 +7904,60 @@ "node": ">=6" } }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "node_modules/puppeteer": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.7.1.tgz", + "integrity": "sha512-JBCBCwQ9+dyPp5haqeecgv0N0vgWFx44woUeKJaPeJT8CU3RXrd8F/tqJQbuAmcWlbMhYJSlTJkIFrwVAs6BNA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.2.3", + "cosmiconfig": "9.0.0", + "devtools-protocol": "0.0.1273771", + "puppeteer-core": "22.7.1" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.7.1.tgz", + "integrity": "sha512-jD7T7yN7PWGuJmNT0TAEboA26s0VVnvbgCxqgQIF+eNQW2u71ENaV2JwzSJiCHO+e72H4Ue6AgKD9USQ8xAcOQ==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "2.2.3", + "chromium-bidi": "0.5.19", + "debug": "4.3.4", + "devtools-protocol": "0.0.1273771", + "ws": "8.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "engines": { - "node": ">=0.9" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/qs": { @@ -7969,25 +7975,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -8014,6 +8001,12 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -8023,25 +8016,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -8057,20 +8031,6 @@ "node": ">= 0.8" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -8083,103 +8043,16 @@ "node": ">=8.10.0" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "dependencies": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "node_modules/regextras": { + "node_modules/rechoir": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true, - "engines": { - "node": ">=0.1.14" - } - }, - "node_modules/regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "dependencies": { - "jsesc": "~0.5.0" + "resolve": "^1.20.0" }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "engines": { + "node": ">= 10.13.0" } }, "node_modules/relateurl": { @@ -8204,15 +8077,6 @@ "strip-ansi": "^6.0.1" } }, - "node_modules/renderkid/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/renderkid/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -8241,30 +8105,6 @@ "entities": "^2.0.0" } }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", - "dev": true, - "dependencies": { - "is-finite": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8274,15 +8114,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -8290,12 +8121,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -8336,6 +8167,77 @@ "node": ">=4" } }, + "node_modules/resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "dev": true, + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8346,35 +8248,57 @@ "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "node_modules/rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", "dev": true, "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -8400,6 +8324,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8425,9 +8358,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -8459,9 +8392,9 @@ "dev": true }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -8476,31 +8409,29 @@ "randombytes": "^2.1.0" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" }, - "bin": { - "sha.js": "bin.js" + "engines": { + "node": ">= 0.4" } }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -8514,24 +8445,33 @@ } }, "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shiki": { @@ -8563,9 +8503,9 @@ } }, "node_modules/showdown/node_modules/commander": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", - "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "engines": { "node": "^12.20.0 || >=14" @@ -8585,14 +8525,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/slice-ansi": { "version": "4.0.0", @@ -8611,103 +8548,91 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/socket.io": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", - "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "node_modules/socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", "dev": true, "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" }, "engines": { - "node": ">=10.0.0" + "node": ">= 14" } }, - "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true - }, - "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" + "debug": "^4.3.4" }, "engines": { - "node": ">=10.0.0" + "node": ">= 14" } }, "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { - "source-map": "^0.5.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", @@ -8715,9 +8640,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "node_modules/sprintf-js": { @@ -8745,16 +8670,6 @@ "node": ">= 0.6" } }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, "node_modules/stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -8764,61 +8679,28 @@ "stubs": "^3.0.0" } }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/streamroller": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.2.tgz", - "integrity": "sha512-wZswqzbgGGsXYIrBYhOE0yP+nQ6XRk7xDcYwuQAGTYXdyAUmvgVFE0YU1g5pvQT0m7GBaQfYcSnlHbapuK0H0A==", + "node_modules/stream-read-all": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", + "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", "dev": true, - "dependencies": { - "date-format": "^4.0.13", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, "engines": { - "node": ">=8.0" + "node": ">=10" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", "dev": true, "dependencies": { - "safe-buffer": "~5.2.0" + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -8833,16 +8715,22 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -8854,44 +8742,17 @@ "node": ">=8" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -8913,12 +8774,24 @@ "dev": true }, "node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=8" + } + }, + "node_modules/supports-color/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -8939,63 +8812,43 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "node_modules/table-layout": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", + "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", "dev": true, "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "@75lb/deep-merge": "^1.1.1", + "array-back": "^6.2.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.0", + "stream-read-all": "^3.0.1", + "typical": "^7.1.1", + "wordwrapjs": "^5.1.0" }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "bin": { + "table-layout": "bin/cli.js" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=12.17" } }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/table-layout/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.17" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/table-layout/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12.17" } }, "node_modules/tapable": { @@ -9007,6 +8860,31 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dev": true, + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/teeny-request": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz", @@ -9037,13 +8915,13 @@ } }, "node_modules/terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -9055,16 +8933,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -9088,10 +8966,19 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/terser/node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -9106,54 +8993,17 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, "node_modules/tmp-promise": { "version": "2.1.1", @@ -9164,6 +9014,26 @@ "tmp": "0.1.0" } }, + "node_modules/tmp-promise/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/tmp-promise/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -9188,15 +9058,6 @@ "node": ">=6" } }, - "node_modules/to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9218,10 +9079,40 @@ "node": ">=0.6" } }, + "node_modules/tonal": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tonal/-/tonal-6.0.1.tgz", + "integrity": "sha512-L0bxiINjnQ03+XqNWppQYYQwDXK/zd+WaschlG7OogtGiFWyp6oPkfgi9G2LJT++CflSM9W3X9qJAGVwHNHVsg==", + "dev": true, + "dependencies": { + "@tonaljs/abc-notation": "4.8.3", + "@tonaljs/array": "4.8.3", + "@tonaljs/chord": "6.0.0", + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/duration-value": "4.8.1", + "@tonaljs/interval": "5.0.0", + "@tonaljs/key": "4.9.4", + "@tonaljs/midi": "4.9.3", + "@tonaljs/mode": "4.8.4", + "@tonaljs/note": "4.10.3", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/progression": "4.8.4", + "@tonaljs/range": "4.8.4", + "@tonaljs/roman-numeral": "4.8.3", + "@tonaljs/scale": "4.12.6", + "@tonaljs/scale-type": "4.8.5", + "@tonaljs/time-signature": "4.8.1", + "@tonaljs/voice-leading": "5.0.3", + "@tonaljs/voicing": "5.0.3", + "@tonaljs/voicing-dictionary": "5.0.3" + } + }, "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, "dependencies": { "psl": "^1.1.33", @@ -9254,123 +9145,69 @@ "node": ">=8" } }, - "node_modules/trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, - "engines": { - "node": ">=0.10.0" + "bin": { + "tree-kill": "cli.js" } }, - "node_modules/ts-loader": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", - "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "dependencies": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^4.0.0", - "semver": "^6.0.0" - }, "engines": { - "node": ">=10.0.0" + "node": ">=16" }, "peerDependencies": { - "typescript": "*" + "typescript": ">=4.2.0" } }, - "node_modules/ts-loader/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "engines": { - "node": ">=4" - } - }, - "node_modules/ts-loader/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" } }, "node_modules/ts-loader/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/ts-loader/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" + "lru-cache": "^6.0.0" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "semver": "bin/semver.js" }, "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "typescript": ">=2.7" + "node": ">=10" } }, - "node_modules/ts-node/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ts-node/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "node": ">= 8" } }, "node_modules/tslib": { @@ -9378,33 +9215,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "node": ">=0.6.x" } }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9417,15 +9236,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -9497,16 +9307,25 @@ } }, "node_modules/typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/ua-parser-js": { @@ -9528,21 +9347,22 @@ "node": "*" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "buffer": "^5.2.1", + "through": "^2.3.8" } }, + "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==", + "dev": true + }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -9574,9 +9394,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz", + "integrity": "sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==", "dev": true, "funding": [ { @@ -9586,14 +9406,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "escalade": "^3.1.1", + "escalade": "^3.1.2", "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -9608,16 +9432,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, "node_modules/url-join": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", @@ -9634,12 +9448,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, "node_modules/urlgrey": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-1.0.0.tgz", @@ -9649,24 +9457,10 @@ "fast-url-parser": "^1.1.3" } }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true }, "node_modules/utila": { @@ -9675,15 +9469,6 @@ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", "dev": true }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -9693,10 +9478,24 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/vary": { @@ -9708,21 +9507,6 @@ "node": ">= 0.8" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -9757,9 +9541,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -9769,15 +9553,6 @@ "node": ">=10.13.0" } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -9788,34 +9563,34 @@ } }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.16.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -9835,44 +9610,42 @@ } }, "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "webpack": "5.x.x" }, "peerDependenciesMeta": { "@webpack-cli/generators": { "optional": true }, - "@webpack-cli/migrate": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -9882,92 +9655,22 @@ } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-cli/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-cli/node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/webpack-cli/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-cli/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-cli/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, "engines": { - "node": ">= 8" + "node": ">=14" } }, "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", + "flat": "^5.0.2", "wildcard": "^2.0.0" }, "engines": { @@ -9984,9 +9687,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -9995,28 +9698,15 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, + "node_modules/webpack/node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -10047,68 +9737,44 @@ } }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "node-which": "bin/node-which" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 8" } }, "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, "node_modules/workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", @@ -10132,58 +9798,22 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrappy": { @@ -10225,15 +9855,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10244,24 +9865,24 @@ } }, "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" @@ -10291,6 +9912,20 @@ "node": ">=10" } }, + "node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -10300,13 +9935,23 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 4.0.0" } }, "node_modules/yocto-queue": { @@ -10320,227 +9965,67 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" + "funding": { + "url": "https://github.com/sponsors/colinhacks" } }, - "@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", - "dev": true - }, - "@babel/core": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", - "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", + "node_modules/zx": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/zx/-/zx-8.0.2.tgz", + "integrity": "sha512-3g+ePtPYmyrjRuASlJiUhkje1je4a47woML/fzTKBb9PA5BzRQbSswwyJ8nlFWJjA1ORRi6TMyAdhuz/jK+Gaw==", "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.13", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.13", - "@babel/types": "^7.18.13", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "bin": { + "zx": "build/cli.js" }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", - "dev": true, - "requires": { - "@babel/types": "^7.18.13", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" + "engines": { + "node": ">= 16.0.0" }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - } + "optionalDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/node": ">=20.12.5" } - }, - "@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + } + }, + "dependencies": { + "@75lb/deep-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", + "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", - "semver": "^6.3.0" + "lodash.assignwith": "^4.2.0", + "typical": "^7.1.1" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true } } }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", - "dev": true, - "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/highlight": "^7.10.4" } }, - "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", - "dev": true - }, "@babel/helper-validator-identifier": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", - "dev": true, - "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, "@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", @@ -10589,199 +10074,360 @@ } } }, - "@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", - "dev": true + "@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "requires": { + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@es-joy/jsdoccomment": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", + "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "dev": true, + "requires": { + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + } + }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "dev": true, + "optional": true }, - "@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", - "requires": { - "regenerator-runtime": "^0.14.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - } - } + "@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "dev": true, + "optional": true }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - } - } + "optional": true }, - "@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } + "optional": true }, - "@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", - "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - } - } + "optional": true }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true + "@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "dev": true, + "optional": true }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true + "@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "dev": true, + "optional": true }, - "@es-joy/jsdoccomment": { - "version": "0.10.8", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", - "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", + "@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "dev": true, + "optional": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "requires": { - "comment-parser": "1.2.4", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "1.1.1" - }, - "dependencies": { - "jsdoc-type-pratt-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.1.1.tgz", - "integrity": "sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g==", - "dev": true - } + "eslint-visitor-keys": "^3.3.0" } }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" } }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { @@ -10791,50 +10437,43 @@ "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@mdn/browser-compat-data": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.2.1.tgz", + "integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -10861,1543 +10500,1813 @@ "fastq": "^1.6.0" } }, - "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", - "dev": true - }, - "@tonejs/plot": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@tonejs/plot/-/plot-0.0.35.tgz", - "integrity": "sha512-g0g6lQzMEVPbazExSWSF+nKErEr0IiQu+Bj4x5BRcLHY5jiDimMQSXzjDLMOVx3IDfYsbmSClZ3OyEO+9C0kOA==", - "dev": true, - "requires": { - "array2d": "0.0.5", - "audiobuffer-to-wav": "^1.0.0", - "dsp.js": "^1.0.1", - "fft-windowing": "^0.1.4", - "plotly.js-dist": "^1.45.3" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/chai": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", - "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", - "dev": true - }, - "@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true - }, - "@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "@types/node": { - "version": "18.7.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.15.tgz", - "integrity": "sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ==", - "dev": true - }, - "@types/ua-parser-js": { - "version": "0.7.36", - "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", - "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", - "dev": true + "optional": true }, - "@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "@puppeteer/browsers": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", + "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "requires": { + "lru-cache": "^6.0.0" + } + } } }, - "@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "@rollup/plugin-commonjs": { + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "yallist": "^4.0.0" + "balanced-match": "^1.0.0" } }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } } } }, - "@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" } }, - "@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "eslint-visitor-keys": "^3.3.0" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true + "@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "dev": true, + "optional": true }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } + "optional": true }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true + "@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "dev": true, + "optional": true }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true + "@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "dev": true, + "optional": true }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "dev": true, + "optional": true }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "dev": true, + "optional": true + }, + "@tonaljs/abc-notation": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/abc-notation/-/abc-notation-4.8.3.tgz", + "integrity": "sha512-ZN+wrlDdiFOLgbGcXiCcCd/ek8P42t7EMgjTA5yVTU8+WwtMSDPmZyNMvfETEVZoWvCOAOW9UVXemP9oFV9OxA==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-note": "6.0.0" } }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true + "@tonaljs/array": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/array/-/array-4.8.3.tgz", + "integrity": "sha512-TeX5vqk61EhlRAIo70d0hKt3a0FEcROsu9ETtTclXl+qaQ1QtEEs0M+B46IZ+sQo5T3s8vtz5z1yCiK26HPr5A==", + "dev": true, + "requires": { + "@tonaljs/pitch-note": "6.0.0" + } }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "@tonaljs/chord": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/chord/-/chord-6.0.0.tgz", + "integrity": "sha512-lWTSynCzPO5rV6CQUoM7b5DqmO0VYq3hEwSwo5d+tEdocYwUvfDbPl1JHq2un9f+5nEnNRkb8AfRsbi9wyVsIg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@tonaljs/chord-detect": "4.8.5", + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/interval": "^5.0.0", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-note": "6.0.0", + "@tonaljs/scale-type": "4.8.5" } }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "@tonaljs/chord-detect": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/@tonaljs/chord-detect/-/chord-detect-4.8.5.tgz", + "integrity": "sha512-sH4WBP9wk70YcFAcb02vd6C5odRXj+aoIgf6WaHHFmp/8AH5aK+Vr3uLVavw7u/1mf0B4XK5hGdGEUuQynGTrw==", "dev": true, "requires": { - "@xtuc/ieee754": "^1.2.0" + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" } }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "@tonaljs/chord-type": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@tonaljs/chord-type/-/chord-type-5.0.5.tgz", + "integrity": "sha512-Rne/7YwXgPAQSt8DM6/yb61Hfp8stQR4SrhbePjzB/oVwVIzUL+uxH29uwd/KxDkIEITaHXS3v5ntRcVXCQYnA==", "dev": true, "requires": { - "@xtuc/long": "4.2.2" + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" } }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "@tonaljs/collection": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/collection/-/collection-4.8.1.tgz", + "integrity": "sha512-2TaiK9QEjOCkV7jW2B9uo5FPetNoiS9//nNPWXOWjB/E9KGd2SV1THEuxLx1Ew3uXUQpezup5adNljbZtOHbrA==", "dev": true }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "@tonaljs/core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/core/-/core-5.0.0.tgz", + "integrity": "sha512-vifjXX+xKidK+q1xGgcfGX79HtIMydXp1NrdGG5VshYHC3TRpVNti4HJDb/6qOjokQp9as/iOCyaAmcWIq0ZUA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@tonaljs/pitch": "5.0.2", + "@tonaljs/pitch-distance": "5.0.3", + "@tonaljs/pitch-interval": "6.0.0", + "@tonaljs/pitch-note": "6.0.0" } }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "@tonaljs/duration-value": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/duration-value/-/duration-value-4.8.1.tgz", + "integrity": "sha512-/jP8Q+z2h+2+IBeTsyF9KWedqu8Jffhvp17/H6pxUJ7b1U+HNdn5G7KfXbblEqhykYSKTSKK/m+86M7j4RnAgw==", + "dev": true + }, + "@tonaljs/interval": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/interval/-/interval-5.0.0.tgz", + "integrity": "sha512-WXmi0TdijggCzREc2B0RN3ZtgUQhu8E7DXVqL/lVLAZA8zaVfsFAv4k1NdXr7bkmcCM4yzhXeGzBo8L2QJR1SA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@tonaljs/pitch": "^5.0.2", + "@tonaljs/pitch-distance": "^5.0.3", + "@tonaljs/pitch-interval": "^6.0.0" } }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "@tonaljs/key": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@tonaljs/key/-/key-4.9.4.tgz", + "integrity": "sha512-oq+C8AAmHJdkWs2Txq3ZR5koIeKYSNwQwR3G+Y1Bd+XbXvd/d9d7xJmzxUWY8fnFnvOve8FNShCvoWfnF62HtQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@tonaljs/core": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/roman-numeral": "4.8.3" } }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "@tonaljs/midi": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@tonaljs/midi/-/midi-4.9.3.tgz", + "integrity": "sha512-sz6XrX6qoYSW3yDpR0K5JhYpsvlzrIJYFfRiOdf4kmnTPAewYyg7f8nLRMl502lBNCt80Bktx4mDHXaL6tWVKw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@tonaljs/core": "5.0.0" } }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "@tonaljs/mode": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/mode/-/mode-4.8.4.tgz", + "integrity": "sha512-6416B8YgWj6hgWgHPsSvizCMoyWg66C/TlviSexQNnYjQHAlp0rAOcLTL3IskVrFNTgNMlNP1vcj+s1kt18LuQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/interval": "5.0.0", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/scale-type": "4.8.5" } }, - "@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "@tonaljs/note": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/@tonaljs/note/-/note-4.10.3.tgz", + "integrity": "sha512-GvNILH91kkBV9ISAHK75gFkI8Jr0mvKRkO/wU1OhUAapnOrNzFS+EqxusKGc2Lz2MLIbVFRIBqWdyhxIwgpSCg==", "dev": true, "requires": { - "envinfo": "^7.7.3" + "@tonaljs/core": "5.0.0", + "@tonaljs/midi": "4.9.3" } }, - "@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "@tonaljs/pcset": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/@tonaljs/pcset/-/pcset-4.9.2.tgz", + "integrity": "sha512-s8enXa/nsFkJkz96VjcFu+fapEr69ENhr3yoHykPsU+0MlZ9aMWXilE97Ek3eHAX9gT55+mElEU7qGWkwdaU9w==", "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "requires": { + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0" + } }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "@tonaljs/pitch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch/-/pitch-5.0.2.tgz", + "integrity": "sha512-mxaXJPPe+LIJdjzpZEl8I8Wx3dEvlzkBbsr2Ltwc2dTAdnErAZ5R0TxVq2egF27lMvQN2QPQPWI9iDPPdVUmrg==", "dev": true }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "@tonaljs/pitch-distance": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-distance/-/pitch-distance-5.0.3.tgz", + "integrity": "sha512-3sgU93gfNsMX1wAYXraYJyIJMIViXZRE1Fh/OXwbUi6lEX/iLRmFVSz37ObnaRaOz0pVm+uUhvW2iKy8QtOWpw==", "dev": true, "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "@tonaljs/pitch": "5.0.2", + "@tonaljs/pitch-interval": "6.0.0", + "@tonaljs/pitch-note": "6.0.0" } }, - "accidental-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/accidental-value/-/accidental-value-1.0.0.tgz", - "integrity": "sha512-Dug400VXZ95UwXqoSjYa3kUvKSDfOtPQAOerbKY5Tk/9Kf3DW3+sYKJK5qv4//TIwIaG2r5xxRN55OwMxCsN7A==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { + "@tonaljs/pitch-interval": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-interval/-/pitch-interval-6.0.0.tgz", + "integrity": "sha512-0iaFWbgshYWjfmdxzF8jNmTqsNK2krwn+FqDRZb8vEsfaSNC8Jek0f5wYcE2to+7f0P5jJlJnj8CUGvlfKIT5A==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "@tonaljs/pitch": "5.0.2" } }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "@tonaljs/pitch-note": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@tonaljs/pitch-note/-/pitch-note-6.0.0.tgz", + "integrity": "sha512-m4Ei7zwSsKwotVfnodA7m1SR7zD5NNIea+V7Mo35EcK32ZJBg+SvxdwgfNNdLO8bkDbVrZIgVYqeP3R3Jq7VFQ==", "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true + "requires": { + "@tonaljs/pitch": "5.0.2" + } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "@tonaljs/progression": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/progression/-/progression-4.8.4.tgz", + "integrity": "sha512-cybCQ3szoozZW5v8jydRxdmDCGiZ2sE8qEnqbNz7+RY7WtZCXbK8MAFjPq2M5NGxIwnw94sbM7RV7d6f5W7+nA==", "dev": true, "requires": { - "debug": "4" + "@tonaljs/chord": "6.0.0", + "@tonaljs/core": "5.0.0", + "@tonaljs/roman-numeral": "4.8.3" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "@tonaljs/range": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tonaljs/range/-/range-4.8.4.tgz", + "integrity": "sha512-ASB+i34Z5cXnBntaZOlmgZTfiLdKpMjSCL0ohE4ebZBTbTkuZWMKUucMxe2xpNKNBByPKVmeocv/Wpr8GNzU1Q==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@tonaljs/collection": "4.8.1", + "@tonaljs/midi": "4.9.3" } }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "@tonaljs/roman-numeral": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@tonaljs/roman-numeral/-/roman-numeral-4.8.3.tgz", + "integrity": "sha512-U3LnDSVSngWiHEECPAWCvOlqZC0vt8IL/IoXSKXpt9YfW9NYRUlejoQack1NM9M80P8fCBnJQ7Uz3x8mC1eRow==", "dev": true, - "requires": {} - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true + "requires": { + "@tonaljs/core": "5.0.0" + } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true + "@tonaljs/scale": { + "version": "4.12.6", + "resolved": "https://registry.npmjs.org/@tonaljs/scale/-/scale-4.12.6.tgz", + "integrity": "sha512-nWDGNfx+rJuF+FFXbvWvtv7vApHpAlLkpke8C7TTM4lEw+fQXdi0cQaNQDS0QmIReeGSThe9CMxRL8+niabFKQ==", + "dev": true, + "requires": { + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/scale-type": "4.8.5" + } }, - "ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", - "dev": true + "@tonaljs/scale-type": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/@tonaljs/scale-type/-/scale-type-4.8.5.tgz", + "integrity": "sha512-3DCo/r3QEalIDG7dSBgRFD90Tm22qXSHuz5pyDUMNZpQuodzxz1BvsXSkC3CMGchX4eoaSjtArfKIrz0oEJUhw==", + "dev": true, + "requires": { + "@tonaljs/core": "5.0.0", + "@tonaljs/pcset": "4.9.2" + } }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "@tonaljs/time-signature": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tonaljs/time-signature/-/time-signature-4.8.1.tgz", + "integrity": "sha512-P3h2S1M006LpmPkwuAVS/pP02Hns6pSzKP2ghyit4Lszj4ppwNwcyJ1hgT/TVkiwMbUVbNltTKDraonG+2Xe/g==", "dev": true }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "@tonaljs/voice-leading": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voice-leading/-/voice-leading-5.0.3.tgz", + "integrity": "sha512-SFG0YPnuTyyW2tb5bKe2+InJGDb7SGGsfjIxIiIm+B3lhCuQKL9ugOUUgD47uUO3ppidGkbbLZhDABKbLmkvWg==", "dev": true, "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@tonaljs/note": "4.10.3" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "@tonaljs/voicing": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voicing/-/voicing-5.0.3.tgz", + "integrity": "sha512-bPE7A086gYlw/Bbbf+XblBtK5pt9bZ3k1sAABZwdaumi7a+8oifHMouaZl2AP3PEYuMkF/80SXDeyC2MvawMKA==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "@tonaljs/chord": "6.0.0", + "@tonaljs/interval": "5.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/range": "4.8.4", + "@tonaljs/voice-leading": "5.0.3", + "@tonaljs/voicing-dictionary": "5.0.3" } }, - "argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==", - "dev": true + "@tonaljs/voicing-dictionary": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@tonaljs/voicing-dictionary/-/voicing-dictionary-5.0.3.tgz", + "integrity": "sha512-mXg1+9fbMxv/3SZLUss5FIPyAnV5aRognE/suV2FXb3cf+20PjyNGGlRN60w5SBbNZfzj+GPf8DeIwob+RbV8w==", + "dev": true, + "requires": { + "@tonaljs/chord": "6.0.0", + "@tonaljs/note": "4.10.3", + "@tonaljs/voice-leading": "5.0.3" + } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, - "array2d": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/array2d/-/array2d-0.0.5.tgz", - "integrity": "sha512-j/gCL/6qZX7gjyKC5oYoP1n8Lf+uAVlYtfXCL1uTkcR+NiRdsuvJHgvqdXHmxRvLqparN3EV3cdibDMZTyz54Q==", + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "dev": true }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "@types/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "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==", - "dev": true - } + "@types/node": "*" } }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "@types/babel__code-frame": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.6.tgz", + "integrity": "sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" + "@types/connect": "*", + "@types/node": "*" } }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true + "@types/co-body": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/co-body/-/co-body-6.1.3.tgz", + "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*" + } }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/content-disposition": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", + "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", "dev": true }, - "audiobuffer-to-wav": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz", - "integrity": "sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w==", + "@types/convert-source-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-2.0.3.tgz", + "integrity": "sha512-ag0BfJLZf6CQz8VIuRIEYQ5Ggwk/82uvTQf27RcpyDNbY0Vw49LIPqAxk5tqYfrCs9xDaIMvl4aj7ZopnYL8bA==", "dev": true }, - "automation-events": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.0.4.tgz", - "integrity": "sha512-uM5VFyhksP/GzzOuGi/ygeI16ked+IA5enGLH9b+BvxUSDnfAWC54RZnnem/iprEKtuWV29FX5gvYcesPAgPAw==", + "@types/cookies": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", + "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "dev": true, "requires": { - "@babel/runtime": "^7.24.4", - "tslib": "^2.6.2" + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" } }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "@types/debounce": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", + "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "@types/estree": "*", + "@types/json-schema": "*" } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "@types/eslint": "*", + "@types/estree": "*" } }, - "babel-helper-bindify-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", - "integrity": "sha512-TYX2QQATKA6Wssp6j7jqlw4QLmABDN1olRdEHndYvBXdaXM5dcx6j5rN0+nd+aVL+Th40fAEYvvw/Xxd/LETuQ==", + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", + "@types/express-serve-static-core": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", + "@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", "dev": true, + "optional": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/jsonfile": "*", + "@types/node": "*" } }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "@types/http-assert": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", + "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", + "dev": true + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@types/istanbul-lib-coverage": "*" } }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", + "@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/istanbul-lib-report": "*" } }, - "babel-helper-explode-class": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", - "integrity": "sha512-SFbWewr0/0U4AiRzsHqwsbOQeLXVa9T1ELdqEa2efcQB5KopTnunAqoj07TuHlN2lfTQNPGO/rJR4FMln5fVcA==", + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, + "optional": true, "requires": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/node": "*" } }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", + "@types/keygrip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", + "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==", + "dev": true + }, + "@types/koa": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" } }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", + "@types/koa-compose": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", + "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@types/koa": "*" } }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "dev": true + }, + "@types/node": { + "version": "20.12.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", + "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "undici-types": "~5.26.4" } }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", + "@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true + }, + "@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@types/mime": "^1", + "@types/node": "*" } }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", + "@types/ua-parser-js": { + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "dev": true + }, + "@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/node": "*" } }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", + "@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, + "optional": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@types/node": "*" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", + "@typescript-eslint/eslint-plugin": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "@typescript-eslint/parser": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4" } }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", + "@typescript-eslint/scope-manager": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" } }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", - "dev": true - }, - "babel-plugin-syntax-async-generators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha512-EbciFN5Jb9iqU9bqaLmmFLx2G8pAUsvpWJ6OzOWBNrSY9qTohXj+7YfZx6Ug1Qqh7tCb1EA7Jvn9bMC1HBiucg==", - "dev": true - }, - "babel-plugin-syntax-class-constructor-call": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", - "integrity": "sha512-EEuBcXz/wZ81Jaac0LnMHtD4Mfz9XWn2oH2Xj+CHwz2SZWUqqdtR2BgWPSdTGMmxN/5KLSh4PImt9+9ZedDarA==", - "dev": true - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", - "dev": true + "@typescript-eslint/type-utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + } }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", + "@typescript-eslint/types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", "dev": true }, - "babel-plugin-syntax-do-expressions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", - "integrity": "sha512-HD/5qJB9oSXzl0caxM+aRD7ENICXqcc3Up/8toDQk7zNIDE7TzsqtxC5f4t9Rwhu2Ya8l9l4j6b3vOsy+a6qxg==", - "dev": true + "@typescript-eslint/typescript-estree": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } }, - "babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==", - "dev": true + "@typescript-eslint/utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "semver": "^7.6.0" + }, + "dependencies": { + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", - "dev": true + "@typescript-eslint/visitor-keys": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.8.0", + "eslint-visitor-keys": "^3.4.3" + } }, - "babel-plugin-syntax-export-extensions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha512-Eo0rcRaIDMld/W6mVhePiudIuLW+Cr/8eveW3mBREfZORScZgx4rh6BAPyvzdEc/JZvQ+LkC80t0VGFs6FX+lg==", + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "babel-plugin-syntax-function-bind": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", - "integrity": "sha512-m8yMoh9LIiNyeLdQs5I9G+3YXo4nqVsKQkk7YplrG4qAFbNi9hkZlow8HDHxhH9QOVFPHmy8+03NzRCdyChIKw==", + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", - "dev": true + "@web/browser-logs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", + "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", + "dev": true, + "requires": { + "errorstacks": "^2.2.0" + } }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", + "@web/config-loader": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.1.tgz", + "integrity": "sha512-IYjHXUgSGGNpO3YJQ9foLcazbJlAWDdJGRe9be7aOhon0Nd6Na5JIOJAej7jsMu76fKHr4b4w2LfIdNQ4fJ8pA==", "dev": true }, - "babel-plugin-transform-async-generator-functions": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", - "integrity": "sha512-uT7eovUxtXe8Q2ufcjRuJIOL0hg6VAUJhiWJBLxH/evYAw+aqoJLcYTR8hqx13iOx/FfbCMHgBmXWZjukbkyPg==", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" + "@web/dev-server": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.4.tgz", + "integrity": "sha512-Gye0DhDbst/KVNRCFzRd+4V9LJmuuQYJBsf6UXeEbCYuBSKeshEW4AA1esLsfy1gONsD6NIGiru5509l35P9Ug==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@types/command-line-args": "^5.0.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server-core": "^0.7.1", + "@web/dev-server-rollup": "^0.6.1", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "debounce": "^1.2.0", + "deepmerge": "^4.2.2", + "ip": "^2.0.1", + "nanocolors": "^0.2.1", + "open": "^8.0.2", + "portfinder": "^1.0.32" + } + }, + "@web/dev-server-core": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.1.tgz", + "integrity": "sha512-alHd2j0f4e1ekqYDR8lWScrzR7D5gfsUZq3BP3De9bkFWM3AELINCmqqlVKmCtlkAdEc9VyQvNiEqrxraOdc2A==", + "dev": true, + "requires": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true + }, + "isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "dev": true + }, + "lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "dev": true + } } }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", + "@web/dev-server-esbuild": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-1.0.2.tgz", + "integrity": "sha512-ak5mKt7L0H/Fa470Ku7p9A1eI32DNyFGM83jDkJviBO8r3lM00O5hVFW1K+UIYNC5EyanLyPxTqgtIuQEyMYcQ==", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@mdn/browser-compat-data": "^4.0.0", + "@web/dev-server-core": "^0.7.0", + "esbuild": "^0.19.11", + "get-tsconfig": "^4.7.2", + "parse5": "^6.0.1", + "ua-parser-js": "^1.0.33" + }, + "dependencies": { + "ua-parser-js": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "dev": true + } } }, - "babel-plugin-transform-class-constructor-call": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", - "integrity": "sha512-RvYukT1Nh7njz8P8326ztpQUGCKwmjgu6aRIx1lkvylWITYcskg29vy1Kp8WXIq7FvhXsz0Crf2kS94bjB690A==", + "@web/dev-server-rollup": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.1.tgz", + "integrity": "sha512-vhtsQ8qu1pBHailOBOYJwZnYDc1Lmx6ZAd2j+y5PD2ck0R1LmVsZ7dZK8hDCpkvpvlu2ndURjL9tbzdcsBRJmg==", "dev": true, "requires": { - "babel-plugin-syntax-class-constructor-call": "^6.18.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@rollup/plugin-node-resolve": "^15.0.1", + "@web/dev-server-core": "^0.7.0", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^4.4.0", + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } } }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", + "@web/parse5-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", + "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" } }, - "babel-plugin-transform-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", - "integrity": "sha512-skQ2CImwDkCHu0mkWvCOlBCpBIHW4/49IZWVwV4A/EnWjL9bB6UBvLyMNe3Td5XDStSZNhe69j4bfEW8dvUbew==", + "@web/test-runner": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.18.1.tgz", + "integrity": "sha512-jB/9vrpGVtcLY6/7sPpKpSheQ3wWY9P5aQcz2SK2gMHTq3gNpa51NAyec0Al7EFpHvJ1wKYTGRLB2gPyEoJeDg==", "dev": true, "requires": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "@web/browser-logs": "^0.4.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server": "^0.4.0", + "@web/test-runner-chrome": "^0.16.0", + "@web/test-runner-commands": "^0.9.0", + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-mocha": "^0.9.0", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "convert-source-map": "^2.0.0", + "diff": "^5.0.0", + "globby": "^11.0.1", + "nanocolors": "^0.2.1", + "portfinder": "^1.0.32", + "source-map": "^0.7.3" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + } } }, - "babel-plugin-transform-do-expressions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", - "integrity": "sha512-yQwYqYg+Tnj1InA8W1rsItsZVhkv1Euc4KVua9ledtPz5PDWYz7LVyy6rDBpVYUWFZj5k6GUm3YZpCbIm8Tqew==", + "@web/test-runner-chrome": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.16.0.tgz", + "integrity": "sha512-Edc6Y49aVB6k18S5IOj9OCX3rEf8F3jptIu0p95+imqxmcutFEh1GNmlAk2bQGnXS0U6uVY7Xbf61fiaXUQqhg==", "dev": true, "requires": { - "babel-plugin-syntax-do-expressions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", + "async-mutex": "0.4.0", + "chrome-launcher": "^0.15.0", + "puppeteer-core": "^22.0.0" } }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", + "@web/test-runner-commands": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", + "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@web/test-runner-core": "^0.13.0", + "mkdirp": "^1.0.4" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } } }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "@web/test-runner-core": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.1.tgz", + "integrity": "sha512-2hESALx/UFsAzK+ApWXAkFp2eCmwcs2yj1v4YjwV8F38sQumJ40P3px3BMjFwkOYDORtQOicW0RUeSw1g3BMLA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.0", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^2.0.1", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + } } }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", + "@web/test-runner-coverage-v8": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", + "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@web/test-runner-core": "^0.13.0", + "istanbul-lib-coverage": "^3.0.0", + "lru-cache": "^8.0.4", + "picomatch": "^2.2.2", + "v8-to-istanbul": "^9.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "dev": true + } } }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", + "@web/test-runner-mocha": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz", + "integrity": "sha512-ZL9F6FXd0DBQvo/h/+mSfzFTSRVxzV9st/AHhpgABtUtV/AIpVE9to6+xdkpu6827kwjezdpuadPfg+PlrBWqQ==", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@web/test-runner-core": "^0.13.0" } }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", + "@web/test-runner-puppeteer": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-puppeteer/-/test-runner-puppeteer-0.16.0.tgz", + "integrity": "sha512-/p8zG+FX3LZjJttjQBqEigfGpnoUyEeNXrYReQWT4Uqj16Zm5F7I0UVecmBCRjnplUoXXlNcZNMsXb0jXBucTw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@web/test-runner-chrome": "^0.16.0", + "@web/test-runner-core": "^0.13.0", + "puppeteer": "^22.0.0" } }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", + "@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@xtuc/ieee754": "^1.2.0" } }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@xtuc/long": "4.2.2" } }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", + "@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", + "@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", + "@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", + "@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "requires": {} }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", + "@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "requires": {} }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", + "@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", + "accidental-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/accidental-value/-/accidental-value-1.0.0.tgz", + "integrity": "sha512-Dug400VXZ95UwXqoSjYa3kUvKSDfOtPQAOerbKY5Tk/9Kf3DW3+sYKJK5qv4//TIwIaG2r5xxRN55OwMxCsN7A==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "debug": "4" } }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha512-mtzELzINaYqdVglyZrDDVwkcFRuE7s6QUFWXxwffKAHB/NkfbJ2NJSytugB43ytIC8UVt30Ereyx+7gNyTkDLg==", + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "requires": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" - } + "requires": {} }, - "babel-plugin-transform-function-bind": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", - "integrity": "sha512-9Ec4KYf1GurT39mlUjDSlN7HWSlB3u3mWRMogQbb+Y88lO0ZM3rJ0ADhPnQwWK9TbO6e/4E+Et1rrfGY9mFimA==", + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "babel-plugin-syntax-function-bind": "^6.8.0", - "babel-runtime": "^6.22.0" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" + "color-convert": "^2.0.1" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } } }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", + "are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "sprintf-js": "~1.0.2" } }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha512-XfwUqG1Ry6R43m4Wfob+vHbIVBIqTg/TJY4Snku1iIzeH7mUnwHA8Vagmv+ZQbPwhS8HgsdQvy28Py3k5zpoFQ==", + "argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", + "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==", + "dev": true + }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array2d": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/array2d/-/array2d-0.0.5.tgz", + "integrity": "sha512-j/gCL/6qZX7gjyKC5oYoP1n8Lf+uAVlYtfXCL1uTkcR+NiRdsuvJHgvqdXHmxRvLqparN3EV3cdibDMZTyz54Q==", + "dev": true + }, + "assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "tslib": "^2.0.1" } }, - "babel-preset-stage-0": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", - "integrity": "sha512-MJD+xBbpsApbKlzAX0sOBF+VeFaUmv5s8FSOO7SSZpes1QgphCjq/UIGRFWSmQ/0i5bqQjLGCTXGGXqcLQ9JDA==", + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", "dev": true, "requires": { - "babel-plugin-transform-do-expressions": "^6.22.0", - "babel-plugin-transform-function-bind": "^6.22.0", - "babel-preset-stage-1": "^6.24.1" + "tslib": "^2.4.0" } }, - "babel-preset-stage-1": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", - "integrity": "sha512-rn+UOcd7BHDniq1SVxv2/AVVSVI1NK+hfS0I/iR6m6KbOi/aeBRcqBilqO73pd9VUpRXF2HFtlDuC9F2BEQqmg==", - "dev": true, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "audiobuffer-to-wav": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz", + "integrity": "sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w==", + "dev": true + }, + "automation-events": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.0.4.tgz", + "integrity": "sha512-uM5VFyhksP/GzzOuGi/ygeI16ked+IA5enGLH9b+BvxUSDnfAWC54RZnnem/iprEKtuWV29FX5gvYcesPAgPAw==", "requires": { - "babel-plugin-transform-class-constructor-call": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-preset-stage-2": "^6.24.1" + "@babel/runtime": "^7.24.4", + "tslib": "^2.6.2" } }, - "babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha512-9F+nquz+37PrlTSBdpeQBKnQfAMNBnryXw+m4qBh35FNbJPfzZz+sjN2G5Uf1CRedU9PH7fJkTbYijxmkLX8Og==", - "dev": true, - "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" - } + "b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true }, - "babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha512-eCbEOF8uN0KypFXJmZXn2sTk7bPV9uM5xov7G/7BM08TbQEObsVs0cEWfy6NQySlfk7JBi/t+XJP1JkruYfthA==", - "dev": true, - "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" - } + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", + "bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } + "optional": true }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "bare-fs": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.0.tgz", + "integrity": "sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw==", "dev": true, + "optional": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^1.0.0" } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", + "bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } + "optional": true }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "bare-path": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.2.tgz", + "integrity": "sha512-o7KSt4prEphWUHa3QUwCxUI00R86VdjiuxmJK0iNVDHYPGo+HsDaVCnqCmPbf/MiW1ok8F4p3m8RTHlWk8K2ig==", "dev": true, + "optional": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "bare-os": "^2.1.0" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "bare-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-1.0.0.tgz", + "integrity": "sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ==", "dev": true, + "optional": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "streamx": "^2.16.1" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, "basic-auth": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", "integrity": "sha512-CtGuTyWf3ig+sgRyC7uP6DM3N+5ur/p8L+FPfsd+BbIfIs74TFfCajZTHnCw6K5dqM0bZEbRIqRy1fAdiUJhTA==", "dev": true }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true }, "binary-extensions": { @@ -12406,49 +12315,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -12474,124 +12340,28 @@ "fill-range": "^7.0.1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, - "browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "requires": { - "resolve": "^1.17.0" - } - }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, "buffer": { @@ -12604,22 +12374,22 @@ "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, "bytes": { @@ -12628,14 +12398,27 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, + "cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "requires": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + } + }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -12661,43 +12444,47 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001390", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001390.tgz", - "integrity": "sha512-sS4CaUM+/+vqQUlCvCJ2WtDlV81aWtHhqeEVkLokVJJa3ViN4zDxAGfq9R8i1m90uGHxo99cy10Od+lvn3hf0g==", + "version": "1.0.30001615", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001615.tgz", + "integrity": "sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ==", "dev": true }, "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.0.tgz", + "integrity": "sha512-kDZ7MZyM6Q1DhR9jy7dalKohXQ2yrlXkk59CR52aRKxJrobmlBNqnFQxX9xOX8w+4mz8SYlKJa/7D7ddltFXCw==", "dev": true, "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "assertion-error": "^2.0.1", + "check-error": "^2.0.0", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "chalk": "^4.1.2" } }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz", + "integrity": "sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog==", "dev": true }, "chokidar": { @@ -12716,37 +12503,59 @@ "readdirp": "~3.6.0" } }, + "chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "dev": true, + "requires": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + } + } + }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "chromium-bidi": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.19.tgz", + "integrity": "sha512-UA6zL77b7RYCjJkZBsZ0wlvCTD+jTjllZ8f6wdO4buevXgTZYjV+XLB9CiEa2OuuTGGTLnI7eN9I60YxuALGQg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" } }, "clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "dev": true, "requires": { "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" } }, "cliui": { @@ -12758,31 +12567,8 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -12794,6 +12580,24 @@ "shallow-clone": "^3.0.0" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "co-body": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz", + "integrity": "sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==", + "dev": true, + "requires": { + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + } + }, "codecov": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.3.tgz", @@ -12823,37 +12627,11 @@ "dev": true }, "colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - }, - "dependencies": { - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true - } - } - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -12863,6 +12641,44 @@ "delayed-stream": "~1.0.0" } }, + "command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "command-line-usage": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", + "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", + "dev": true, + "requires": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^3.0.0", + "typical": "^7.1.1" + }, + "dependencies": { + "array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true + }, + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "dev": true + } + } + }, "commander": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", @@ -12870,9 +12686,15 @@ "dev": true }, "comment-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "concat-map": { @@ -12881,88 +12703,71 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" + "safe-buffer": "5.2.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", "dev": true, "requires": { - "object-assign": "^4", - "vary": "^1" + "depd": "~2.0.0", + "keygrip": "~1.1.0" } }, "corser": { @@ -12971,92 +12776,44 @@ "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", "dev": true }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "dependencies": { - "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==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "cross-var": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cross-var/-/cross-var-1.1.0.tgz", - "integrity": "sha512-wIcFax9RNm5ayuORUeJ5MLxPbfh8XdZhhUpKutIszU46Fs9UIhEdPJ7+YguM+7FxEj+68hSQVyathVsIu84SiA==", - "dev": true, - "requires": { - "babel-preset-es2015": "^6.18.0", - "babel-preset-stage-0": "^6.16.0", - "babel-register": "^6.18.0", - "cross-spawn": "^5.0.1", - "exit": "^0.1.2" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "css-select": { @@ -13101,18 +12858,18 @@ } } }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "daccord": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/daccord/-/daccord-1.1.0.tgz", "integrity": "sha512-LMIBv6VNgcZqD5zQEPps5xT+EyrClJwCzJR9qWGhZ4SoWylPucqtiwIWm9Z7Yla90A017+408HXh6RS4o2qkgw==", "dev": true }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -13124,10 +12881,19 @@ "whatwg-url": "^8.0.0" } }, - "date-format": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.13.tgz", - "integrity": "sha512-bnYCwf8Emc3pTD8pXnre+wfnjGtfi5ncMDKy7+cWZXbmRAsdWkOQHrfC1yz/KiwP5thDp2kCHWYWKBX4HP1hoQ==", + "date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.21.0" + } + }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", "dev": true }, "debug": { @@ -13152,13 +12918,16 @@ "dev": true }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.1.tgz", + "integrity": "sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw==", + "dev": true + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true }, "deep-is": { "version": "0.1.4", @@ -13166,23 +12935,38 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "requires": { - "clone": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" } }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" } }, "delayed-stream": { @@ -13191,21 +12975,23 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } + "dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true }, "destroy": { "version": "1.2.0", @@ -13213,46 +12999,12 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devtools-protocol": { + "version": "0.0.1273771", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1273771.tgz", + "integrity": "sha512-QDbb27xcTVReQQW/GHJsdQqGKwYBE7re7gxehj467kKP2DKuYBUj6i2k5LRiAC66J1yZG/9gsxooz/s9pcm0Og==", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -13280,18 +13032,6 @@ "utila": "~0.4" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -13311,12 +13051,6 @@ } } }, - "domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true - }, "domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -13370,10 +13104,10 @@ "tslib": "^2.0.3" } }, - "dsp.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dsp.js/-/dsp.js-1.0.1.tgz", - "integrity": "sha512-5ols1j2i2tdbtd38DMR6xGSmE8dE/qFWgqrNN1ZNnIZnOEAFjzoVq5hM57nbQS9u0VmxqCUw8YccgsS9+zhtNg==", + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, "ee-first": { @@ -13383,198 +13117,131 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.241", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.241.tgz", - "integrity": "sha512-e7Wsh4ilaioBZ5bMm6+F4V5c11dh56/5Jwz7Hl5Tu1J7cnB+Pqx5qIF2iC7HPpfyQMqGSvvLP5bBAIDd2gAtGw==", + "version": "1.4.754", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.754.tgz", + "integrity": "sha512-7Kr5jUdns5rL/M9wFFmMZAgFDuL2YOnanFH4OI4iFzUqyh3XOL7nAGbSlSMZdzKMIyyTpNSbqZsWG9odwLeKvA==", "dev": true }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, - "engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" - }, - "dependencies": { - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "requires": {} - } + "once": "^1.4.0" } }, - "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", - "dev": true - }, "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - } - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "requires": { - "ansi-colors": "^4.1.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true }, - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "is-arrayish": "^0.2.1" } }, - "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "errorstacks": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/errorstacks/-/errorstacks-2.4.1.tgz", + "integrity": "sha512-jE4i0SMYevwu/xxAuzhly/KTwtj0xDhbzB6m1xPImxTkw8wcCbgarOQPfCVMi5JKVyW7in29pNJCCJrry3Ynnw==", "dev": true }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "get-intrinsic": "^1.2.4" } }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true }, + "es-module-lexer": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", + "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==", + "dev": true + }, + "esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-html": { @@ -13590,15 +13257,14 @@ "dev": true }, "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "requires": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { @@ -13607,321 +13273,162 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } } } }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "is-glob": "^4.0.3" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "type-fest": "^0.20.2" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "argparse": "^2.0.1" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, + "eslint-plugin-file-extension-in-import-ts": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-file-extension-in-import-ts/-/eslint-plugin-file-extension-in-import-ts-2.1.0.tgz", + "integrity": "sha512-zK8HbxkWlMI+t8hmMRg8pgQB8e1WVglnpcAQ2YkEIMyUh0jb5bgU++Bjwh60qVbJUh820x7DzwJDR72r3tLbUA==", + "dev": true, + "requires": { + "is-core-module": "^2.13.1", + "resolve": "^1.22.8" + } + }, "eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-8.1.1.tgz", + "integrity": "sha512-6qmlJsc40D2m3Dn9oEH+0PAOkJhxVu0f5sVItqpCE0YWgYnyP4xCjBc3UWTHaJcY9ARkWOLIIuXLq0ndRnQOHw==", "dev": true, "requires": { - "htmlparser2": "^7.1.2" + "htmlparser2": "^9.1.0" } }, "eslint-plugin-jsdoc": { - "version": "36.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.1.1.tgz", - "integrity": "sha512-nuLDvH1EJaKx0PCa9oeQIxH6pACIhZd1gkalTUxZbaxxwokjs7TplqY0Q8Ew3CoZaf5aowm0g/Z3JGHCatt+gQ==", + "version": "48.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.3.tgz", + "integrity": "sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "0.10.8", - "comment-parser": "1.2.4", - "debug": "^4.3.2", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^1.1.1", - "lodash": "^4.17.21", - "regextras": "^0.8.0", - "semver": "^7.3.5", - "spdx-expression-parse": "^3.0.1" + "@es-joy/jsdoccomment": "~0.42.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "requires": { "lru-cache": "^6.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, @@ -13935,44 +13442,27 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true } } @@ -13984,9 +13474,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -14023,12 +13513,24 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -14041,34 +13543,41 @@ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -14126,6 +13635,15 @@ "reusify": "^1.0.4" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "fft-windowing": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/fft-windowing/-/fft-windowing-0.1.4.tgz", @@ -14150,45 +13668,13 @@ "to-regex-range": "^5.0.1" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - } + "array-back": "^3.0.1" } }, "find-up": { @@ -14208,34 +13694,69 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, "requires": { - "is-callable": "^1.1.3" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } } }, "form-data": { @@ -14249,14 +13770,17 @@ "mime-types": "^2.1.12" } }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha512-05cXDIwNbFaoFWaz5gNHlUTbH5whiss/hr/ibzPd4MH3cR4w0ZKeIPiVdbyJurg3O5r/Bjpvn9KOb1/rPMf3nA==", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } + "fourier-transform": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fourier-transform/-/fourier-transform-1.1.2.tgz", + "integrity": "sha512-TjdHddt7Wul3RXvm3O5euI64aAzUPhE1rqzuAFsIu7Puyny6CNLgL8bbKtYoIK71HSF90o+9WjUmRsXmYGYD0Q==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true }, "fs-extra": { "version": "8.1.0", @@ -14283,39 +13807,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "get-caller-file": { @@ -14325,44 +13819,111 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "resolve-pkg-maps": "^1.0.0" } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "dependencies": { + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, + "glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { @@ -14380,12 +13941,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -14408,10 +13963,25 @@ } } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "growl": { @@ -14420,30 +13990,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -14451,14 +13997,20 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "requires": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" } }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -14466,41 +14018,21 @@ "dev": true }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "has-symbols": "^1.0.3" } }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "function-bind": "^1.1.2" } }, "he": { @@ -14519,27 +14051,6 @@ "notecoord": "^1.0.1" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -14571,9 +14082,9 @@ } }, "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", "dev": true, "requires": { "@types/html-minifier-terser": "^6.0.0", @@ -14584,15 +14095,79 @@ } }, "htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + }, + "dependencies": { + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + } + } + }, + "http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + } } }, "http-errors": { @@ -14656,65 +14231,8 @@ "secure-compare": "3.0.1", "union": "~0.5.0", "url-join": "^2.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -14741,9 +14259,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "ignore-walk": { @@ -14781,6 +14299,12 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, + "inflation": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", + "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -14797,25 +14321,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", - "dev": true, - "requires": { - "source-map": "~0.5.3" - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true }, "interval-coords": { "version": "1.1.1", @@ -14823,33 +14333,35 @@ "integrity": "sha512-s7tB4gLonSlNpJ1bIzQUtdehpX7BjdCQnlBfKl6wXNo93/KIrum/DQdKOzbObjTrfYY4IwlRfJI7NZdFoRo0Qw==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } + "ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", + "dev": true }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + } } }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "is-binary-path": { "version": "2.1.0", @@ -14860,38 +14372,22 @@ "binary-extensions": "^2.0.0" } }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "builtin-modules": "^3.3.0" } }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "requires": { - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.0" } }, "is-docker": { @@ -14906,12 +14402,6 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -14936,20 +14426,10 @@ "is-extglob": "^2.1.1" } }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true }, "is-number": { @@ -14958,14 +14438,11 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true }, "is-plain-obj": { "version": "2.1.0", @@ -14988,55 +14465,20 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "@types/estree": "*" } }, - "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - } + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true }, "is-unicode-supported": { "version": "0.1.0", @@ -15044,35 +14486,14 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true + "requires": { + "is-docker": "^2.0.0" + } }, "isexe": { "version": "2.0.0", @@ -15092,72 +14513,15 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, - "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "istanbul-reports": { @@ -15170,6 +14534,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -15198,12 +14572,6 @@ } } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true - }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -15214,10 +14582,16 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "jsdoc-type-pratt-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.2.0.tgz", - "integrity": "sha512-4STjeF14jp4bqha44nKMY1OUI6d2/g6uclHWUCZ7B4DoLzaB5bmpTkQrpqU+vSVzMD0LsKAOskcnI3I3VfIpmg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true }, "jsdom": { @@ -15263,10 +14637,10 @@ } } }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "json-parse-even-better-errors": { @@ -15287,18 +14661,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", - "dev": true - }, "jsonc-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", @@ -15314,228 +14676,161 @@ "graceful-fs": "^4.1.6" } }, - "karma": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.0.tgz", - "integrity": "sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "dependencies": { - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", "dev": true, "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" + "tsscmp": "1.0.6" } }, - "karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "requires": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" + "json-buffer": "3.0.1" } }, - "karma-firefox-launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz", - "integrity": "sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ==", - "dev": true, - "requires": { - "is-wsl": "^2.1.0" - } + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, - "karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", + "koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", "dev": true, "requires": { - "minimist": "^1.2.3" + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "dependencies": { + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + } + } + } } }, - "karma-safari-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz", - "integrity": "sha512-qmypLWd6F2qrDJfAETvXDfxHvKDk+nyIjpH9xIeI3/hENr0U3nuqkxaftq73PfXZ4aOuOChA6SnLW4m4AxfRjQ==", - "dev": true, - "requires": {} + "koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true }, - "karma-sourcemap-loader": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz", - "integrity": "sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g==", + "koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2" + "co": "^4.6.0", + "koa-compose": "^4.1.0" } }, - "karma-spec-reporter": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz", - "integrity": "sha512-ZXsYERZJMTNRR2F3QN11OWF5kgnT/K2dzhM+oY3CDyMrDI3TjIWqYGG7c15rR9wjmy9lvdC+CCshqn3YZqnNrA==", + "koa-etag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", + "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", "dev": true, "requires": { - "colors": "^1.1.2" + "etag": "^1.8.1" } }, - "karma-typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/karma-typescript/-/karma-typescript-5.5.3.tgz", - "integrity": "sha512-l1FHurolXEBIzRa9ExpNtjzysAhsi/vLpTazpwLHWWK86mknvVpqor6pRZ5Nid7jvOPrTBqAq0JRuLgiCdRkFw==", + "koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", "dev": true, "requires": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2", - "assert": "^2.0.0", - "async": "^3.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.4.3", - "combine-source-map": "^0.8.0", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "convert-source-map": "^1.7.0", - "crypto-browserify": "^3.12.0", - "diff": "^4.0.1", - "domain-browser": "^4.16.0", - "events": "^3.2.0", - "glob": "^7.1.6", - "https-browserify": "^1.0.0", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.19", - "log4js": "^6.3.0", - "minimatch": "^3.0.4", - "os-browserify": "^0.3.0", - "pad": "^3.2.0", - "path-browserify": "^1.0.0", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.1.1", - "source-map": "^0.7.3", - "stream-browserify": "^3.0.0", - "stream-http": "^3.1.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.11", - "tmp": "^0.2.1", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.1", - "vm-browserify": "^1.1.2" + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" }, "dependencies": { - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true } } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } }, "levn": { "version": "0.4.1", @@ -15547,34 +14842,45 @@ "type-check": "~0.4.0" } }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true - }, - "loader-utils": { + "lighthouse-logger": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "debug": "^2.6.9", + "marky": "^1.2.2" }, "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true } } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -15590,10 +14896,16 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, "lodash.merge": { @@ -15602,12 +14914,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -15616,88 +14922,40 @@ "requires": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } } } }, - "log4js": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.6.1.tgz", - "integrity": "sha512-J8VYFH2UQq/xucdNu71io4Fo+purYYudyErgBbswWKO0MC6QVOERRomt5su/z6d3RJSmLyTGmXl3Q/XjKCf+/A==", - "dev": true, - "requires": { - "date-format": "^4.0.13", - "debug": "^4.3.4", - "flatted": "^3.2.6", - "rfdc": "^1.3.0", - "streamroller": "^3.1.2" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.0.tgz", + "integrity": "sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "lower-case": { @@ -15710,13 +14968,12 @@ } }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, "lunr": { @@ -15725,45 +14982,46 @@ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, + "magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "requires": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } + "marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "dev": true }, "media-typer": { "version": "0.3.0", @@ -15771,42 +15029,6 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -15829,24 +15051,6 @@ "picomatch": "^2.3.1" } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -15868,16 +15072,10 @@ "mime-db": "1.52.0" } }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { @@ -15895,6 +15093,18 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -16041,15 +15251,6 @@ "has-flag": "^4.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -16073,6 +15274,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanocolors": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", + "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", + "dev": true + }, "nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -16097,6 +15304,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true + }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -16141,9 +15354,9 @@ } }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "normalize-path": { @@ -16167,58 +15380,18 @@ "boolbase": "^1.0.0" } }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha512-j8ZNHg19TyIQOWCGeeQJBuu6xZYIEurf8M1Qsfd8mFrGEfIZytbw18YjKWg+LcO25NowXGZXZpKAx+Ui3TFfDw==", - "dev": true - }, "nwsapi": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -16237,6 +15410,32 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -16244,9 +15443,9 @@ "dev": true }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -16254,27 +15453,9 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -16299,20 +15480,62 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pad": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/pad/-/pad-3.2.0.tgz", - "integrity": "sha512-2u0TrjcGbOjBTJpyewEl4hBO3OeX5wWue7eIFPzQTg6wFSvoaHcBTTUY5m+n0hd04gmTCPuY0kCpVIVuw5etwg==", + "pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", "dev": true, "requires": { - "wcwidth": "^1.0.1" + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } } }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } }, "param-case": { "version": "3.0.4", @@ -16333,17 +15556,16 @@ "callsites": "^3.0.0" } }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, "parse5": { @@ -16368,12 +15590,6 @@ "tslib": "^2.0.3" } }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -16398,6 +15614,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -16405,23 +15639,16 @@ "dev": true }, "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true }, "picocolors": { "version": "1.0.0", @@ -16490,9 +15717,9 @@ } }, "plotly.js-dist": { - "version": "1.58.5", - "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-1.58.5.tgz", - "integrity": "sha512-gy4cm5gYeem1eoXeryrSfftDm/CacQUE+W6xPRGiC5PnB/WHDPaex+HVeAGdKEek57ok1j2IkDw3lnXoB0Bfiw==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-2.32.0.tgz", + "integrity": "sha512-+RnvqNTJADe3ctmCMT2YOhXu4ZwYuBi7eD4FF0oyaJ8jWj65Ru6lZVnetr7T3ZvnU5BgQWbbId+tYgf0PBFkeQ==", "dev": true }, "portfinder": { @@ -16532,6 +15759,12 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true + }, "pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -16542,40 +15775,69 @@ "renderkid": "^3.0.0" } }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true + "proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + } + } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, "psl": { @@ -16584,26 +15846,14 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "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==", - "dev": true - } + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "punycode": { @@ -16612,11 +15862,39 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true + "puppeteer": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.7.1.tgz", + "integrity": "sha512-JBCBCwQ9+dyPp5haqeecgv0N0vgWFx44woUeKJaPeJT8CU3RXrd8F/tqJQbuAmcWlbMhYJSlTJkIFrwVAs6BNA==", + "dev": true, + "requires": { + "@puppeteer/browsers": "2.2.3", + "cosmiconfig": "9.0.0", + "devtools-protocol": "0.0.1273771", + "puppeteer-core": "22.7.1" + } + }, + "puppeteer-core": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.7.1.tgz", + "integrity": "sha512-jD7T7yN7PWGuJmNT0TAEboA26s0VVnvbgCxqgQIF+eNQW2u71ENaV2JwzSJiCHO+e72H4Ue6AgKD9USQ8xAcOQ==", + "dev": true, + "requires": { + "@puppeteer/browsers": "2.2.3", + "chromium-bidi": "0.5.19", + "debug": "4.3.4", + "devtools-protocol": "0.0.1273771", + "ws": "8.16.0" + }, + "dependencies": { + "ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "dev": true, + "requires": {} + } + } }, "qs": { "version": "6.10.3", @@ -16627,18 +15905,6 @@ "side-channel": "^1.0.4" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true - }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -16651,6 +15917,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -16660,22 +15932,6 @@ "safe-buffer": "^5.1.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, "raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -16688,17 +15944,6 @@ "unpipe": "1.0.0" } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -16708,84 +15953,13 @@ "picomatch": "^2.2.1" } }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regextras": { + "rechoir": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" } }, "relateurl": { @@ -16807,12 +15981,6 @@ "strip-ansi": "^6.0.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -16830,39 +15998,15 @@ "domutils": "^2.5.2", "entities": "^2.0.0" } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } } } }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -16870,12 +16014,12 @@ "dev": true }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -16903,35 +16047,103 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "dev": true, + "requires": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "glob": "^7.1.3" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "requires": { + "glob": "^10.3.7" + } + }, + "rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" } }, "run-parallel": { @@ -16943,6 +16155,15 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -16965,9 +16186,9 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -16992,9 +16213,9 @@ "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, "serialize-javascript": { @@ -17006,11 +16227,19 @@ "randombytes": "^2.1.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } }, "setprototypeof": { "version": "1.2.0", @@ -17018,16 +16247,6 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -17038,18 +16257,24 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true }, "shiki": { @@ -17074,9 +16299,9 @@ }, "dependencies": { "commander": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", - "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true } } @@ -17092,10 +16317,10 @@ "object-inspect": "^1.9.0" } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "slice-ansi": { @@ -17107,89 +16332,78 @@ "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, - "socket.io": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", - "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true + }, + "socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" } }, - "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true - }, - "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", "dev": true, "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + } } }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { - "source-map": "^0.5.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, + "spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -17197,9 +16411,9 @@ } }, "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "sprintf-js": { @@ -17224,16 +16438,6 @@ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, "stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -17243,44 +16447,21 @@ "stubs": "^3.0.0" } }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "streamroller": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.2.tgz", - "integrity": "sha512-wZswqzbgGGsXYIrBYhOE0yP+nQ6XRk7xDcYwuQAGTYXdyAUmvgVFE0YU1g5pvQT0m7GBaQfYcSnlHbapuK0H0A==", - "dev": true, - "requires": { - "date-format": "^4.0.13", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - } + "stream-read-all": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", + "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", + "dev": true }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", "dev": true, "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "bare-events": "^2.2.0", + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" } }, "string-width": { @@ -17292,54 +16473,35 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "ansi-regex": "^5.0.1" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { @@ -17355,10 +16517,21 @@ "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } }, "supports-preserve-symlinks-flag": { "version": "1.0.0", @@ -17372,51 +16545,32 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "table-layout": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", + "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", "dev": true, "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "@75lb/deep-merge": "^1.1.1", + "array-back": "^6.2.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.0", + "stream-read-all": "^3.0.1", + "typical": "^7.1.1", + "wordwrapjs": "^5.1.0" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } } } }, @@ -17426,6 +16580,29 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, + "tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dev": true, + "requires": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "requires": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "teeny-request": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz", @@ -17453,21 +16630,21 @@ } }, "terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "commander": { @@ -17475,61 +16652,44 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, "terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "dependencies": { + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + } } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, "tmp-promise": { "version": "2.1.1", @@ -17540,6 +16700,20 @@ "tmp": "0.1.0" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -17560,12 +16734,6 @@ } } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", - "dev": true - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -17581,10 +16749,40 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "tonal": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tonal/-/tonal-6.0.1.tgz", + "integrity": "sha512-L0bxiINjnQ03+XqNWppQYYQwDXK/zd+WaschlG7OogtGiFWyp6oPkfgi9G2LJT++CflSM9W3X9qJAGVwHNHVsg==", + "dev": true, + "requires": { + "@tonaljs/abc-notation": "4.8.3", + "@tonaljs/array": "4.8.3", + "@tonaljs/chord": "6.0.0", + "@tonaljs/chord-type": "5.0.5", + "@tonaljs/collection": "4.8.1", + "@tonaljs/core": "5.0.0", + "@tonaljs/duration-value": "4.8.1", + "@tonaljs/interval": "5.0.0", + "@tonaljs/key": "4.9.4", + "@tonaljs/midi": "4.9.3", + "@tonaljs/mode": "4.8.4", + "@tonaljs/note": "4.10.3", + "@tonaljs/pcset": "4.9.2", + "@tonaljs/progression": "4.8.4", + "@tonaljs/range": "4.8.4", + "@tonaljs/roman-numeral": "4.8.3", + "@tonaljs/scale": "4.12.6", + "@tonaljs/scale-type": "4.8.5", + "@tonaljs/time-signature": "4.8.1", + "@tonaljs/voice-leading": "5.0.3", + "@tonaljs/voicing": "5.0.3", + "@tonaljs/voicing-dictionary": "5.0.3" + } + }, "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, "requires": { "psl": "^1.1.33", @@ -17610,90 +16808,46 @@ "punycode": "^2.1.1" } }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "requires": {} + }, "ts-loader": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", - "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", "micromatch": "^4.0.0", - "semver": "^6.0.0" + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "lru-cache": "^6.0.0" } - } - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { + }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, @@ -17702,27 +16856,10 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", "dev": true }, "type-check": { @@ -17734,12 +16871,6 @@ "prelude-ls": "^1.2.1" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -17789,9 +16920,15 @@ } }, "typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true }, "ua-parser-js": { @@ -17800,18 +16937,22 @@ "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", "dev": true }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "buffer": "^5.2.1", + "through": "^2.3.8" } }, + "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==", + "dev": true + }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -17834,12 +16975,12 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz", + "integrity": "sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==", "dev": true, "requires": { - "escalade": "^3.1.1", + "escalade": "^3.1.2", "picocolors": "^1.0.0" } }, @@ -17852,24 +16993,6 @@ "punycode": "^2.1.0" } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - } - } - }, "url-join": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", @@ -17895,24 +17018,10 @@ "fast-url-parser": "^1.1.3" } }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true }, "utila": { @@ -17921,23 +17030,30 @@ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", "dev": true }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } + } }, "vary": { "version": "1.1.2", @@ -17945,18 +17061,6 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true - }, "vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -17988,24 +17092,15 @@ } }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -18013,147 +17108,89 @@ "dev": true }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.16.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "requires": {} - }, - "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } } } }, "webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "dependencies": { "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "requires": { "clone-deep": "^4.0.1", + "flat": "^5.0.2", "wildcard": "^2.0.0" } }, @@ -18190,51 +17227,30 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - } - }, "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, + "wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", "dev": true }, "workerpool": { @@ -18252,47 +17268,17 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "wrappy": { @@ -18320,12 +17306,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -18333,26 +17313,37 @@ "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -18379,10 +17370,20 @@ "is-plain-obj": "^2.1.0" } }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", "dev": true }, "yocto-queue": { @@ -18390,6 +17391,22 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "dev": true + }, + "zx": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/zx/-/zx-8.0.2.tgz", + "integrity": "sha512-3g+ePtPYmyrjRuASlJiUhkje1je4a47woML/fzTKBb9PA5BzRQbSswwyJ8nlFWJjA1ORRi6TMyAdhuz/jK+Gaw==", + "dev": true, + "requires": { + "@types/fs-extra": "^11.0.4", + "@types/node": ">=20.12.5" + } } } } diff --git a/package.json b/package.json index 56498d95..48635227 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { "name": "tone", - "version": "14.9.0", + "version": "15.0.0", "description": "A Web Audio framework for making interactive music in the browser.", - "browser": "build/Tone.js", + "type": "module", "main": "build/esm/index.js", "module": "build/esm/index.js", - "type": "module", - "unpkg": "build/Tone.js", "types": "build/esm/index.d.ts", + "unpkg": "build/Tone.js", "files": [ "README.md", "LICENSE.md", @@ -16,29 +15,23 @@ "Tone" ], "scripts": { - "build": "npm run increment && rm -rf build && npm run ts:build && npm run webpack:build", - "codecov": "codecov", + "build": "npm run increment && rimraf build && npm run ts:build && npm run webpack:build", "docs": "node scripts/generate_docs.cjs", - "docs:json": "cross-var typedoc --options \"./scripts/typedoc.json\" --json \"./docs/tone.json\"", + "docs:json": "typedoc --options \"./scripts/typedoc.json\" --json \"./docs/tone.json\"", "increment": "node scripts/increment_version.cjs", - "karma": "cross-var karma start ./test/karma.conf.cjs --single-run --file $npm_config_file --dir $npm_config_dir", - "karma:browser": "cross-var karma start ./test/karma.conf.cjs --auto-watch --browsers OnlineChrome --file $npm_config_file --dir $npm_config_dir", - "karma:watch": "cross-var karma start ./test/karma.conf.cjs --auto-watch --file $npm_config_file --dir $npm_config_dir", - "lint": "eslint --ignore-pattern ./Tone/**/*.test.ts --ext ts ./Tone", - "lint:fix": "eslint --ext ts --fix ./Tone", + "lint": "eslint --ext ts ./Tone", + "lint:fix": "eslint --ext ts --fix ./Tone ./test", + "pretty": "prettier ./Tone ./test -w", "scratch": "webpack -w --env scratch=1 --mode=development", - "test": "npm run karma", - "test:browser": "npm run karma:browser", + "test": "tsc && web-test-runner --config=./test/web-test-runner.config.js", "test:examples": "node ./test/scripts/test_examples.cjs", "test:html": "node ./test/scripts/test_html.cjs", - "test:node": "node ./test/scripts/node_test.cjs", + "test:integrations": "zx ./test/scripts/test_integrations.mjs", "test:readme": "node ./test/scripts/test_readme.cjs", - "test:travis": "npm run build && npm run lint && npm run test", - "test:watch": "npm run karma:watch", + "test:watch": "tsc && concurrently --raw \"tsc -w\" \"web-test-runner --config=./test/web-test-runner.config.js --watch\"", "ts:build": "tsc --project ./scripts/tsconfig.build.json", "watch": "tsc --watch", - "webpack:watch": "webpack -w --env production=1 --mode=development --config ./webpack.config.cjs", - "webpack:build": "webpack --env production=1 --config ./webpack.config.cjs" + "webpack:build": "webpack --env production=1 --config ./scripts/webpack.config.cjs" }, "repository": { "type": "git", @@ -61,46 +54,49 @@ "url": "https://github.com/Tonejs/Tone.js/issues" }, "devDependencies": { - "@tonejs/plot": "0.0.35", + "@rollup/plugin-commonjs": "^25.0.7", "@types/chai": "^4.3.0", "@types/mocha": "^5.2.6", "@types/ua-parser-js": "^0.7.36", - "@typescript-eslint/eslint-plugin": "^5.6.0", - "@typescript-eslint/parser": "^5.6.0", - "async": "^3.2.2", - "chai": "^4.3.4", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "@web/dev-server-esbuild": "^1.0.2", + "@web/dev-server-rollup": "^0.6.1", + "@web/test-runner": "^0.18.1", + "@web/test-runner-puppeteer": "^0.16.0", + "array2d": "^0.0.5", + "audiobuffer-to-wav": "^1.0.0", + "chai": "^5.1.0", "codecov": "^3.8.3", - "cross-var": "^1.1.0", - "eslint": "^7.32.0", - "eslint-plugin-html": "^6.2.0", - "eslint-plugin-jsdoc": "^36.1.1", + "concurrently": "^8.2.2", + "eslint": "^8.56.0", + "eslint-plugin-file-extension-in-import-ts": "^2.1.0", + "eslint-plugin-html": "^8.1.1", + "eslint-plugin-jsdoc": "^48.2.3", + "fft-windowing": "^0.1.4", + "fourier-transform": "^1.1.2", "fs-extra": "^8.1.0", - "glob": "^7.2.0", + "glob": "^10.3.12", "html-webpack-plugin": "^5.5.0", "http-server": "^13.0.2", "jsdom": "^16.7.0", - "karma": "^6.3.9", - "karma-chrome-launcher": "^2.2.0", - "karma-coverage": "^2.1.0", - "karma-firefox-launcher": "^1.3.0", - "karma-mocha": "^2.0.1", - "karma-safari-launcher": "^1.0.0", - "karma-sourcemap-loader": "^0.3.8", - "karma-spec-reporter": "0.0.32", - "karma-typescript": "^5.5.2", "mocha": "^9.1.3", + "plotly.js-dist": "^2.32.0", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", "semver": "^5.7.1", - "showdown": "^2.0.0-alpha", + "showdown": "^2.1.0", "teoria": "^2.5.0", "tmp-promise": "^2.1.1", - "ts-loader": "^7.0.5", - "ts-node": "^8.10.2", + "tonal": "^6.0.1", + "ts-loader": "^9.5.1", "typedoc": "^0.25.13", - "typescript": "^4.4.4", + "typescript": "^5.4.5", "ua-parser-js": "^0.7.31", - "webpack": "^5.65.0", - "webpack-cli": "^4.10.0", - "yargs": "^17.3.0" + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4", + "yargs": "^17.3.0", + "zx": "^8.0.2" }, "dependencies": { "standardized-audio-context": "^25.3.70", diff --git a/scripts/generate_docs.cjs b/scripts/generate_docs.cjs deleted file mode 100644 index 207fed28..00000000 --- a/scripts/generate_docs.cjs +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires, no-console */ -const { resolve } = require("path"); -const { execSync } = require("child_process"); -const { writeFileSync, readFileSync, unlinkSync } = require("fs"); - -function generateDocs() { - const commitHash = execSync("git rev-parse --short HEAD").toString().trim(); - console.log(`commit hash ${commitHash}`); - const outputDir = resolve(__dirname, "../docs"); - const tmpFile = resolve(outputDir, "tmp.json"); - const outputFile = resolve(outputDir, "tone.json"); - // generate the doc file - execSync(`npm run docs:json --docs_json=${tmpFile}`); - // add the version and commit to the file - const json = JSON.parse(readFileSync(tmpFile, "utf-8")); - console.log(`doc files: ${json.children.length}`); - json.commit = commitHash; - const package = JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf-8")); - json.version = package.version; - writeFileSync(outputFile, JSON.stringify(json)); - unlinkSync(tmpFile); -} - -generateDocs(); diff --git a/scripts/tsconfig.build.json b/scripts/tsconfig.build.json index 9a80fee5..677a23c9 100644 --- a/scripts/tsconfig.build.json +++ b/scripts/tsconfig.build.json @@ -3,6 +3,7 @@ "sourceMap": true, "declaration": true, "noUnusedLocals": true, + "rootDir": "../Tone" }, "extends": "../tsconfig.json", "include": [ diff --git a/webpack.config.cjs b/scripts/webpack.config.cjs similarity index 53% rename from webpack.config.cjs rename to scripts/webpack.config.cjs index c29e91b7..79eb2342 100644 --- a/webpack.config.cjs +++ b/scripts/webpack.config.cjs @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires */ const path = require("path"); -const HtmlWebpackPlugin = require("html-webpack-plugin"); // ///////////////////////////////////// // Defaults @@ -10,17 +9,19 @@ const defaults = { mode: "development", context: __dirname, entry: { - Tone: "./Tone/index.ts", + Tone: "../Tone/index.ts", }, output: { - path: path.resolve(__dirname, "build"), + path: path.resolve(__dirname, "../build"), filename: "[name].js", library: "Tone", libraryTarget: "umd", globalObject: "typeof self !== 'undefined' ? self : this", }, resolve: { - extensions: [".ts", ".js"] + extensionAlias: { + ".js": [".js", ".ts"], + }, }, module: { rules: [ @@ -28,43 +29,12 @@ const defaults = { test: /\.ts$/, use: "ts-loader", exclude: /(node_modules)/, - } - ] + }, + ], }, devtool: "cheap-source-map", }; -// ///////////////////////////////////// -// Scratch -// ///////////////////////////////////// - -const scratch = Object.assign({}, defaults, { - entry: { - scratch: "./examples/scratch.ts", - }, - plugins: [ - new HtmlWebpackPlugin({ - template: "./examples/scratch.html" - }) - ], -}); - -// ///////////////////////////////////// -// Tests -// ///////////////////////////////////// - -const test = Object.assign({}, defaults, { - entry: { - test: "./test/test.js", - }, - plugins: [ - new HtmlWebpackPlugin({ - filename: "test.html", - template: "./test/index.html", - }) - ], -}); - // ///////////////////////////////////// // Production // ///////////////////////////////////// @@ -74,7 +44,7 @@ const production = Object.assign({}, defaults, { devtool: "source-map", }); -module.exports = env => { +module.exports = (env) => { if (env.test) { return test; } else if (env.production) { diff --git a/test/README.md b/test/README.md index 25034be2..9c85bda7 100644 --- a/test/README.md +++ b/test/README.md @@ -1,23 +1,23 @@ -Both Chrome and Firefox are required to run the run the full set of tests. +Both Chrome and Firefox are required to run the run the full set of tests. ## Basic -To run tests in both browsers headlessly and report the results: +To run tests in both browsers headlessly and report the results: -`npm run test` +`npm run test` ## Browser -To run tests in a Chrome browser not in headless mode which allows you to debug from the console: +To run tests in a Chrome browser not in headless mode which allows you to debug from the console: `npm run test:browser` ## Selective Testing -To test only an individual file: +To test only an individual file: `npm run test --file=Signal` -Or to run on an entire directory: +Or to run on an entire directory: -`npm run test --dir=signal` \ No newline at end of file +`npm run test --dir=signal` diff --git a/test/helper/Basic.ts b/test/helper/Basic.ts index 3114b3ab..91c3440c 100644 --- a/test/helper/Basic.ts +++ b/test/helper/Basic.ts @@ -1,23 +1,21 @@ import { expect } from "chai"; -import "Tone/core/clock/Transport"; -import "Tone/core/context/Destination"; -import { OfflineContext } from "Tone/core/context/OfflineContext"; -import { ToneWithContext } from "Tone/core/context/ToneWithContext"; -import { Tone } from "Tone/core/Tone"; -import { ConnectTest } from "./Connect"; -import { setLogger } from "Tone/core/util/Debug"; -import { ToneAudioNode } from "Tone/core/context/ToneAudioNode"; -import { getContext } from "Tone/core/Global"; -import * as Classes from "Tone/classes"; -import { isFunction } from "Tone/core/util/TypeCheck"; -import { noOp } from "Tone/core/util/Interface"; +import "../../Tone/core/clock/Transport.js"; +import "../../Tone/core/context/Destination.js"; +import { OfflineContext } from "../../Tone/core/context/OfflineContext.js"; +import { ToneWithContext } from "../../Tone/core/context/ToneWithContext.js"; +import { Tone } from "../../Tone/core/Tone.js"; +import { ConnectTest } from "./Connect.js"; +import { setLogger } from "../../Tone/core/util/Debug.js"; +import { ToneAudioNode } from "../../Tone/core/context/ToneAudioNode.js"; +import { getContext } from "../../Tone/core/Global.js"; +import * as Classes from "../../Tone/classes.js"; +import { isFunction } from "../../Tone/core/util/TypeCheck.js"; +import { noOp } from "../../Tone/core/util/Interface.js"; export const testAudioContext = new OfflineContext(1, 1, 11025); export function BasicTests(Constr, ...args: any[]): void { - context("Basic", () => { - before(() => { return getContext().resume(); }); @@ -30,7 +28,10 @@ export function BasicTests(Constr, ...args: any[]): void { // also check all of it's attributes to see if they also have the right context for (const member in instance) { if (instance[member] instanceof Tone && member !== "context") { - expect(instance[member].disposed, `member ${member}`).to.equal(true); + expect( + instance[member].disposed, + `member ${member}` + ).to.equal(true); } } // check that all callback functions are assigned to noOp @@ -39,7 +40,6 @@ export function BasicTests(Constr, ...args: any[]): void { expect(instance[member]).to.equal(noOp); } } - }); it("extends Tone", () => { @@ -49,15 +49,23 @@ export function BasicTests(Constr, ...args: any[]): void { }); it("can specify the AudioContext", () => { - const instance = new Constr(Object.assign({ - context: testAudioContext, - }, ...args)); + const instance = new Constr( + Object.assign( + { + context: testAudioContext, + }, + ...args + ) + ); if (instance instanceof ToneWithContext) { expect(instance.context).to.equal(testAudioContext); // also check all of it's attributes to see if they also have the right context for (const member in instance) { if (instance[member] instanceof ToneWithContext) { - expect(instance[member].context, `member: ${member}`).to.equal(testAudioContext); + expect( + instance[member].context, + `member: ${member}` + ).to.equal(testAudioContext); } } } @@ -95,7 +103,7 @@ export async function warns(fn: (...args: any[]) => any): Promise { let wasInvoked = false; setLogger({ log: () => {}, - warn: () => wasInvoked = true, + warn: () => (wasInvoked = true), }); const ret = fn(); if (ret instanceof Promise) { diff --git a/test/helper/CompareToFile.ts b/test/helper/CompareToFile.ts index 794b2367..9cb05d05 100644 --- a/test/helper/CompareToFile.ts +++ b/test/helper/CompareToFile.ts @@ -1,8 +1,7 @@ -import { Compare, TestAudioBuffer } from "@tonejs/plot"; -import "./ToneAudioBuffer"; -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; -import { Offline } from "Tone/core/context/Offline"; -import { Context } from "Tone/core/context/Context"; +import { Compare, TestAudioBuffer } from "./compare/index.js"; +import { ToneAudioBuffer } from "../../Tone/core/context/ToneAudioBuffer.js"; +import { Offline } from "../../Tone/core/context/Offline.js"; +import { Context } from "../../Tone/core/context/Context.js"; /** * Load a file for comparison @@ -21,27 +20,47 @@ async function getBuffersToCompare( } else { const loadedBuffer = await ToneAudioBuffer.fromUrl(filename); const bufferB = new TestAudioBuffer(loadedBuffer); - const renderedBuffer = await Offline(callback, bufferB.duration, bufferB.numberOfChannels, bufferB.sampleRate); + const renderedBuffer = await Offline( + callback, + bufferB.duration, + bufferB.numberOfChannels, + bufferB.sampleRate + ); const bufferA = new TestAudioBuffer(renderedBuffer); return { - bufferA, bufferB, + bufferA, + bufferB, }; } } +/** + * Compare the output of the callback to a pre-rendered file + */ export async function CompareToFile( - callback, url: string, + callback, + url: string, threshold = 0.001, RENDER_NEW = false, - duration = 0.1, channels = 1, + duration = 0.1, + channels = 1 ): Promise { - url = "audio/compare/" + url; - const response = await getBuffersToCompare(callback, url, duration, channels, 44100, RENDER_NEW); + url = "test/audio/compare/" + url; + const response = await getBuffersToCompare( + callback, + url, + duration, + channels, + 44100, + RENDER_NEW + ); if (response) { const { bufferA, bufferB } = response; const error = Compare.compareSpectra(bufferA, bufferB); if (error > threshold) { - throw new Error(`Error ${error} greater than threshold ${threshold}`); + throw new Error( + `Error ${error} greater than threshold ${threshold}` + ); } } } diff --git a/test/helper/Connect.ts b/test/helper/Connect.ts index 7452f6b2..29e9cff7 100644 --- a/test/helper/Connect.ts +++ b/test/helper/Connect.ts @@ -1,5 +1,5 @@ -import { Gain } from "Tone/core/context/Gain"; -import { ToneAudioNode } from "Tone/core/context/ToneAudioNode"; +import { Gain } from "../../Tone/core/context/Gain.js"; +import { ToneAudioNode } from "../../Tone/core/context/ToneAudioNode.js"; export function connectFrom(): Gain { return new Gain(); @@ -10,7 +10,6 @@ export function connectTo(): Gain { } export function ConnectTest(constr, ...args: any[]): void { - it("handles input and output connections", () => { const instance = new constr(...args); // test each of the input and outputs and connect diff --git a/test/helper/ConstantOutput.ts b/test/helper/ConstantOutput.ts index c1554ed4..6768371b 100644 --- a/test/helper/ConstantOutput.ts +++ b/test/helper/ConstantOutput.ts @@ -1,13 +1,14 @@ import { expect } from "chai"; -import { OfflineContext } from "Tone/core/context/OfflineContext"; -import { Offline } from "./Offline"; +import { OfflineContext } from "../../Tone/core/context/OfflineContext.js"; +import { Offline } from "./Offline.js"; /** * Test that the output of the callback is a constant value */ export async function ConstantOutput( callback: (context: OfflineContext) => Promise | void, - value: number, threshold = 0.01, + value: number, + threshold = 0.01 ): Promise { const buffer = await Offline(callback, 0.01, 1); expect(buffer.value()).to.be.closeTo(value, threshold); diff --git a/test/helper/Dispose.ts b/test/helper/Dispose.ts index 8571b037..47d4cebc 100644 --- a/test/helper/Dispose.ts +++ b/test/helper/Dispose.ts @@ -2,15 +2,19 @@ export function isDisposed(instance): void { for (const prop in instance) { if (instance.hasOwnProperty(prop)) { const member = instance[prop]; - if (typeof member !== "function" && + if ( + typeof member !== "function" && typeof member !== "string" && typeof member !== "number" && typeof member !== "boolean" && typeof member !== "undefined" && prop !== "preset" && - !(member instanceof AudioContext)) { + !(member instanceof AudioContext) + ) { if (member !== null) { - throw Error("property was not completely disposed: " + prop); + throw Error( + "property was not completely disposed: " + prop + ); } } } diff --git a/test/helper/EffectTests.ts b/test/helper/EffectTests.ts index 321b0e29..13212ea7 100644 --- a/test/helper/EffectTests.ts +++ b/test/helper/EffectTests.ts @@ -1,13 +1,11 @@ import { expect } from "chai"; -import { connectFrom, connectTo } from "test/helper/Connect"; -import { Offline } from "test/helper/Offline"; -import { PassAudio } from "test/helper/PassAudio"; -import { Signal } from "Tone/signal/Signal"; +import { connectFrom, connectTo } from "./Connect.js"; +import { Offline } from "./Offline.js"; +import { PassAudio } from "./PassAudio.js"; +import { Signal } from "../../Tone/signal/Signal.js"; export function EffectTests(Constr, args?, before?): void { - context("Effect Tests", () => { - it("has an input and output", () => { const instance = new Constr(args); if (before) { @@ -53,48 +51,60 @@ export function EffectTests(Constr, args?, before?): void { }); it("has no sound when not connected to any inputs", () => { - return Offline(() => { - const instance = new Constr(args).toDestination(); - if (before) { - before(instance); - } - }, 0.5, 1).then((buffer) => { + return Offline( + () => { + const instance = new Constr(args).toDestination(); + if (before) { + before(instance); + } + }, + 0.5, + 1 + ).then((buffer) => { expect(buffer.isSilent()).to.be.true; }); }); it.skip("can pass 100% dry signal", () => { - return Offline(() => { - const instance = new Constr(args).toDestination(); - if (before) { - before(instance); - } - const signal = new Signal(-1).connect(instance); - // make the signals ramp - signal.linearRampTo(1, 1, 0); - instance.wet.value = 0; - }, 0.5, 1).then((buffer) => { + return Offline( + () => { + const instance = new Constr(args).toDestination(); + if (before) { + before(instance); + } + const signal = new Signal(-1).connect(instance); + // make the signals ramp + signal.linearRampTo(1, 1, 0); + instance.wet.value = 0; + }, + 0.5, + 1 + ).then((buffer) => { buffer.forEach((sample, time) => { - const value = (time * 2) - 1; + const value = time * 2 - 1; expect(sample).to.be.closeTo(value, 0.1); }); }); }); it.skip("effects the incoming signal", () => { - return Offline(() => { - const instance = new Constr(args).toDestination(); - if (before) { - before(instance); - } - const signal = new Signal(-1).connect(instance); - // make the signals ramp - signal.linearRampTo(1, 1); - instance.wet.value = 1; - }, 0.5, 1).then((buffer) => { + return Offline( + () => { + const instance = new Constr(args).toDestination(); + if (before) { + before(instance); + } + const signal = new Signal(-1).connect(instance); + // make the signals ramp + signal.linearRampTo(1, 1); + instance.wet.value = 1; + }, + 0.5, + 1 + ).then((buffer) => { let affected = false; buffer.forEach((sample, time) => { - const value = (time * 2) - 1; + const value = time * 2 - 1; if (Math.abs(value - sample) > 0.01) { affected = true; } diff --git a/test/helper/InstrumentTests.ts b/test/helper/InstrumentTests.ts index eecb3e86..99afdb9b 100644 --- a/test/helper/InstrumentTests.ts +++ b/test/helper/InstrumentTests.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { Instrument } from "Tone/instrument/Instrument"; -import { connectTo } from "./Connect"; -import { Offline } from "./Offline"; -import { OutputAudio } from "./OutputAudio"; -import { Monophonic } from "Tone/instrument/Monophonic"; +import { Instrument } from "../../Tone/instrument/Instrument.js"; +import { connectTo } from "./Connect.js"; +import { Offline } from "./Offline.js"; +import { OutputAudio } from "./OutputAudio.js"; +import { Monophonic } from "../../Tone/instrument/Monophonic.js"; function wait(time) { - return new Promise(done => setTimeout(done, time)); + return new Promise((done) => setTimeout(done, time)); } export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { - context("Instrument Tests", () => { - it("extends Tone.Instrument", () => { const instance = new Constr(constrArg); expect(instance).to.be.an.instanceof(Instrument); @@ -58,7 +56,6 @@ export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { }); if (Constr.prototype.triggerRelease) { - it("can trigger release after attack", () => { return Offline(() => { const instance = new Constr(constrArg); @@ -70,7 +67,10 @@ export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { } instance.triggerRelease(0.1); }, 1).then((buffer) => { - expect(buffer.getTimeOfFirstSound()).to.be.within(0.05, 0.1); + expect(buffer.getTimeOfFirstSound()).to.be.within( + 0.05, + 0.1 + ); }); }); @@ -88,23 +88,28 @@ export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { }, 1).then((buffer) => { const bufferDuration = buffer.getTimeOfLastSound(); const secondTrigger = 0.15; - return Offline(() => { - const instance = new Constr(constrArg); - instance.toDestination(); - if (note) { - instance.triggerAttack(note, 0.05); - } else { - instance.triggerAttack(0.05); - } - instance.triggerRelease(0.1); - // star the note again before the last one has finished - if (note) { - instance.triggerAttack(note, secondTrigger); - } else { - instance.triggerAttack(secondTrigger); - } - }, bufferDuration + secondTrigger * 2).then((resultingBuffer) => { - expect(resultingBuffer.getTimeOfLastSound()).to.be.gt(bufferDuration); + return Offline( + () => { + const instance = new Constr(constrArg); + instance.toDestination(); + if (note) { + instance.triggerAttack(note, 0.05); + } else { + instance.triggerAttack(0.05); + } + instance.triggerRelease(0.1); + // star the note again before the last one has finished + if (note) { + instance.triggerAttack(note, secondTrigger); + } else { + instance.triggerAttack(secondTrigger); + } + }, + bufferDuration + secondTrigger * 2 + ).then((resultingBuffer) => { + expect(resultingBuffer.getTimeOfLastSound()).to.be.gt( + bufferDuration + ); }); }); }); @@ -119,7 +124,10 @@ export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { instance.triggerAttackRelease(0.1, 0.05); } }, 0.2).then((buffer) => { - expect(buffer.getTimeOfFirstSound()).to.be.within(0.05, 0.1); + expect(buffer.getTimeOfFirstSound()).to.be.within( + 0.05, + 0.1 + ); }); }); } @@ -171,7 +179,6 @@ export function InstrumentTest(Constr, note, constrArg?, optionsIndex?): void { }); }); - it("can unsync and re-sync triggerAttack to the Transport", () => { return Offline(async ({ transport }) => { const instance = new Constr(constrArg); diff --git a/test/helper/MonophonicTests.ts b/test/helper/MonophonicTests.ts index a2cfb08f..ca06cb29 100644 --- a/test/helper/MonophonicTests.ts +++ b/test/helper/MonophonicTests.ts @@ -1,18 +1,16 @@ import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { Monophonic } from "Tone/instrument/Monophonic"; +import { Offline } from "./Offline.js"; +import { Monophonic } from "../../Tone/instrument/Monophonic.js"; export function MonophonicTest(Constr, note, constrArg?): void { - context("Monophonic Tests", () => { - it("has an onsilence callback which is invoked after the release has finished", () => { let wasInvoked = false; return Offline(() => { const instance = new Constr(constrArg); instance.toDestination(); instance.triggerAttackRelease(note, 0.1, 0); - instance.onsilence = () => wasInvoked = true; + instance.onsilence = () => (wasInvoked = true); }, 2).then(() => { expect(wasInvoked).to.equal(true); }); @@ -31,7 +29,7 @@ export function MonophonicTest(Constr, note, constrArg?): void { instance.voice1.envelope.sustain = 0; } instance.triggerAttack(note, 0); - instance.onsilence = () => wasInvoked = true; + instance.onsilence = () => (wasInvoked = true); }, 2).then(() => { expect(wasInvoked).to.equal(true); }); diff --git a/test/helper/Offline.ts b/test/helper/Offline.ts index b905c735..21e2d20b 100644 --- a/test/helper/Offline.ts +++ b/test/helper/Offline.ts @@ -1,17 +1,30 @@ -import { TestAudioBuffer } from "@tonejs/plot"; -import { OfflineContext } from "Tone/core/context/OfflineContext"; -import { getContext, setContext } from "Tone/core/Global"; -import { Seconds } from "Tone/core/type/Units"; -import { isArray, isFunction } from "Tone/core/util/TypeCheck"; +import { TestAudioBuffer } from "./compare/index.js"; +import { OfflineContext } from "../../Tone/core/context/OfflineContext.js"; +import { getContext, setContext } from "../../Tone/core/Global.js"; +import { Seconds } from "../../Tone/core/type/Units.js"; +import { isArray, isFunction } from "../../Tone/core/util/TypeCheck.js"; type ReturnFunction = (time: Seconds) => void; export async function Offline( - callback: (context: OfflineContext) => void | ReturnFunction | ReturnFunction[] | Promise | void, - duration = 0.1, channels = 1, sampleRate = 44100, + callback: ( + context: OfflineContext + ) => + | void + | ReturnFunction + | ReturnFunction[] + | Promise + | void, + duration = 0.1, + channels = 1, + sampleRate = 44100 ): Promise { const originalContext = getContext(); - const offline = new OfflineContext(channels, duration + 1 / sampleRate, sampleRate); + const offline = new OfflineContext( + channels, + duration + 1 / sampleRate, + sampleRate + ); setContext(offline); try { let retFunction = callback(offline); @@ -23,7 +36,7 @@ export async function Offline( offline.on("tick", () => fn(offline.now())); } else if (isArray(retFunction)) { // each element in the array is a timing callback - retFunction.forEach(fn => { + retFunction.forEach((fn) => { offline.on("tick", () => fn(offline.now())); }); } @@ -36,14 +49,22 @@ export async function Offline( } } -export function whenBetween(value: Seconds, start: Seconds, stop: Seconds, callback: () => void): void { +export function whenBetween( + value: Seconds, + start: Seconds, + stop: Seconds, + callback: () => void +): void { if (value >= start && value < stop) { callback(); } } // invoked only once -export function atTime(when: Seconds, callback: (time: Seconds) => void): (time: Seconds) => void { +export function atTime( + when: Seconds, + callback: (time: Seconds) => void +): (time: Seconds) => void { let wasInvoked = false; return (time) => { if (time >= when && !wasInvoked) { diff --git a/test/helper/OscillatorTests.ts b/test/helper/OscillatorTests.ts index e9f14fb3..82eb38e9 100644 --- a/test/helper/OscillatorTests.ts +++ b/test/helper/OscillatorTests.ts @@ -1,11 +1,9 @@ import { expect } from "chai"; -import { connectFrom } from "test/helper/Connect"; -import { Offline } from "test/helper/Offline"; +import { connectFrom } from "./Connect.js"; +import { Offline } from "./Offline.js"; export function OscillatorTests(Constr, args?): void { - context("Oscillator Tests", () => { - it("can be created with an options object", () => { const instance = new Constr({ detune: -20, diff --git a/test/helper/OutputAudio.ts b/test/helper/OutputAudio.ts index 54e4bc0e..62e4f1c5 100644 --- a/test/helper/OutputAudio.ts +++ b/test/helper/OutputAudio.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { Offline } from "./Offline"; +import { Offline } from "./Offline.js"; export function OutputAudio(callback): Promise { return Offline(callback, 0.1).then((buffer) => { diff --git a/test/helper/PassAudio.ts b/test/helper/PassAudio.ts index 246b18e5..274ab220 100644 --- a/test/helper/PassAudio.ts +++ b/test/helper/PassAudio.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { ToneAudioNode } from "Tone/core/context/ToneAudioNode"; -import { Signal } from "Tone/signal/Signal"; +import { Offline } from "./Offline.js"; +import { ToneAudioNode } from "../../Tone/core/context/ToneAudioNode.js"; +import { Signal } from "../../Tone/signal/Signal.js"; /** * Make sure that the audio passes from input node @@ -12,19 +12,32 @@ export function PassAudio( passes = true ): Promise { const duration = 0.2; - return Offline(() => { - const sig = new Signal(0); - callback(sig); - sig.setValueAtTime(1, duration / 2); - }, 0.2, 1).then(buffer => { + return Offline( + () => { + const sig = new Signal(0); + callback(sig); + sig.setValueAtTime(1, duration / 2); + }, + 0.2, + 1 + ).then((buffer) => { expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.001); - expect(buffer.getValueAtTime(duration / 2 - 0.01)).to.be.closeTo(0, 0.001); + expect(buffer.getValueAtTime(duration / 2 - 0.01)).to.be.closeTo( + 0, + 0.001 + ); if (passes) { expect(buffer.getValueAtTime(duration / 2 + 0.01)).to.not.equal(0); expect(buffer.getValueAtTime(duration - 0.01)).to.not.equal(0); } else { - expect(buffer.getValueAtTime(duration / 2 + 0.01)).to.be.closeTo(0, 0.001); - expect(buffer.getValueAtTime(duration - 0.01)).to.be.closeTo(0, 0.001); + expect(buffer.getValueAtTime(duration / 2 + 0.01)).to.be.closeTo( + 0, + 0.001 + ); + expect(buffer.getValueAtTime(duration - 0.01)).to.be.closeTo( + 0, + 0.001 + ); } }); } diff --git a/test/helper/SourceTests.ts b/test/helper/SourceTests.ts index edc25fc7..587c7ccb 100644 --- a/test/helper/SourceTests.ts +++ b/test/helper/SourceTests.ts @@ -1,13 +1,11 @@ // import APITest from "helper/APITest"; import { expect } from "chai"; -import { Offline } from "test/helper/Offline"; -import { OutputAudio } from "test/helper/OutputAudio"; -import { connectFrom, connectTo } from "./Connect"; +import { Offline } from "./Offline.js"; +import { OutputAudio } from "./OutputAudio.js"; +import { connectFrom, connectTo } from "./Connect.js"; export function SourceTests(Constr, args?): void { - context("Source Tests", () => { - it("can connect the output", () => { const instance = new Constr(args); instance.connect(connectTo()); @@ -49,7 +47,7 @@ export function SourceTests(Constr, args?): void { return Offline(() => { const instance = new Constr(args); instance.toDestination(); - instance.onstop = () => wasInvoked = true; + instance.onstop = () => (wasInvoked = true); instance.start(0).stop(0.1); }, 0.2).then(() => { expect(wasInvoked).to.equal(true); @@ -115,7 +113,7 @@ export function SourceTests(Constr, args?): void { expect(buffer.getRmsAtTime(0.3)).to.equal(0); }); }); - + it("calling restart before calling start has no effect", () => { return Offline(() => { const instance = new Constr(args).toDestination(); @@ -124,6 +122,5 @@ export function SourceTests(Constr, args?): void { expect(buffer.isSilent()).to.be.true; }); }); - }); } diff --git a/test/helper/StereoSignal.ts b/test/helper/StereoSignal.ts index dc18bd18..f39393f6 100644 --- a/test/helper/StereoSignal.ts +++ b/test/helper/StereoSignal.ts @@ -1,5 +1,5 @@ -import { Merge } from "Tone/component/channel/Merge"; -import { Signal } from "Tone/signal/Signal"; +import { Merge } from "../../Tone/component/channel/Merge.js"; +import { Signal } from "../../Tone/signal/Signal.js"; export function StereoSignal(l: number, r: number): Merge { const merge = new Merge(); diff --git a/test/helper/Supports.ts b/test/helper/Supports.ts index 88bd4aa8..d406c77c 100644 --- a/test/helper/Supports.ts +++ b/test/helper/Supports.ts @@ -1,42 +1,28 @@ -import { UAParser } from "ua-parser-js"; +// // import { UAParser } from "ua-parser-js"; -const parsed = new UAParser().getBrowser(); +// // const parsed = new UAParser().getBrowser(); -const name = parsed.name as string; +// const name = "Chrome" as string; -const version = parseInt(parsed.major as string, 10); +// const version = 121; -function is(browser, above?): boolean { - above = above || 0; - return name.includes(browser) && version >= above; -} +// function is(browser, above?): boolean { +// return false; +// // above = above || 0; +// // return name.includes(browser) && version >= above; +// } -function isnt(browser, below?): boolean { - below = below || Infinity; - return !(name.includes(browser) && version <= below); -} +// function isnt(browser, below?): boolean { +// below = below || Infinity; +// return !(name.includes(browser) && version <= below); +// } -function isntVersion(browser, browserVersion?): boolean { - return name.includes(browser) && version !== browserVersion; -} +// function isntVersion(browser, browserVersion?): boolean { +// return name.includes(browser) && version !== browserVersion; +// } -// can disconnect from a specific node -export const NODE_DISCONNECT = is("Chrome", 50); +// // if the tests run in focus +// // export const ONLINE_TESTING = isntVersion("Chrome", 71); -// offline rendering matches Chrome closely -// chrome is the platform the files were rendered on -// so it is the default for continuity testing -export const CHROME_AUDIO_RENDERING = is("Chrome"); - -// firefox does not correctly handle the situation where -// a linear/exponential ramp is scheduled after setTargetValueAtTime -export const SCHEDULE_RAMP_AFTER_SET_TARGET = is("Chrome"); - -// if the tests run in focus -export const ONLINE_TESTING = isntVersion("Chrome", 71); -// the close method resolves a promise -export const AUDIO_CONTEXT_CLOSE_RESOLVES = isnt("Firefox") && isnt("Safari", 10); -// if it supports gUM testing -export const GET_USER_MEDIA = isnt("Safari"); -// firefox does not invoke AudioBufferSourceNode.onended in the offline context -export const OFFLINE_BUFFERSOURCE_ONENDED = isnt("Firefox"); +// // firefox does not invoke AudioBufferSourceNode.onended in the offline context +// // export const OFFLINE_BUFFERSOURCE_ONENDED = isnt("Firefox"); diff --git a/test/helper/ToneAudioBuffer.ts b/test/helper/ToneAudioBuffer.ts deleted file mode 100644 index 0822f804..00000000 --- a/test/helper/ToneAudioBuffer.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer"; - -// point to the relative path of the audio files -// @ts-ignore -if (window.__karma__) { - ToneAudioBuffer.baseUrl = "/base/test/"; -} else { - ToneAudioBuffer.baseUrl = "../test/"; -} diff --git a/test/helper/compare/Compare.ts b/test/helper/compare/Compare.ts new file mode 100644 index 00000000..afe76baa --- /dev/null +++ b/test/helper/compare/Compare.ts @@ -0,0 +1,147 @@ +import { OfflineRender } from "./OfflineRender.js"; +import { analyze } from "./Spectrum.js"; +import { TestAudioBuffer } from "./TestAudioBuffer.js"; + +export function compareSpectra( + bufferA: TestAudioBuffer, + bufferB: TestAudioBuffer +): number { + if (bufferA.length !== bufferB.length) { + throw new Error("buffers must be the same length to compare"); + } + const analysisA = analyze(bufferA, 1024, 64); + const analysisB = analyze(bufferB, 1024, 64); + + let diff = 0; + analysisA.forEach((columnA, columnNum) => { + const columnB = analysisB[columnNum]; + columnA.forEach((valA, index) => { + const valB = columnB[index]; + diff += Math.pow(valA - valB, 2); + }); + }); + return Math.sqrt(diff / analysisA.length); +} + +export function compareSignals( + bufferA: TestAudioBuffer, + bufferB: TestAudioBuffer +): number { + const arrayA = bufferA.toArray(); + const arrayB = bufferB.toArray(); + const diffs = arrayA.map((channelA, channelNum) => { + let diff = 0; + const channelB = arrayB[channelNum]; + channelA.forEach((valA, index) => { + const valB = channelB[index]; + diff += Math.pow(valA - valB, 2); + }); + return Math.sqrt(diff / channelA.length); + }); + // average across the channels + return diffs.reduce((t, v) => t + v, 0) / diffs.length; +} + +interface BufferResponse { + bufferA: TestAudioBuffer; + bufferB: TestAudioBuffer; +} + +type BufferResponseType = BufferResponse | void; + +async function getBuffersToCompare( + callback: (context: OfflineAudioContext) => Promise | void, + filename: string, + duration = 0.5, + channels = 1, + sampleRate = 11025, + forceRender = false +): Promise { + if (forceRender) { + const buffer = await OfflineRender( + callback, + duration, + channels, + sampleRate + ); + buffer.downloadWav(filename); + return Promise.resolve(); + } else { + const bufferB = await fetch(filename) + .then((response) => response.arrayBuffer()) + .then((buffer) => { + const context = new OfflineAudioContext( + channels, + 1, + sampleRate + ); + return context.decodeAudioData(buffer); + }) + .then((audioBuffer) => new TestAudioBuffer(audioBuffer)); + const bufferA = await OfflineRender( + callback, + bufferB.duration, + bufferB.numberOfChannels, + bufferB.sampleRate + ); + + // const [bufferA, bufferB] = await Promise.all([bufferAPromise, bufferBPromise]); + return { + bufferA, + bufferB, + }; + } +} + +export async function toFile( + callback: (context: OfflineAudioContext) => Promise | void, + filename: string, + threshold = 0.1, + forceRender = false, + duration = 0.1, + channels = 1, + sampleRate = 11025 +) { + const response = await getBuffersToCompare( + callback, + filename, + duration, + channels, + sampleRate, + forceRender + ); + if (response) { + const { bufferA, bufferB } = response; + const error = compareSpectra(bufferA, bufferB); + if (error > threshold) { + throw new Error( + `Error ${error} greater than threshold ${threshold}` + ); + } + } +} + +export async function toFileSignal( + callback: (context: OfflineAudioContext) => Promise | void, + filename: string, + threshold = 0.1, + forceRender = false, + duration = 0.1, + channels = 1, + sampleRate = 11025 +) { + const response = await getBuffersToCompare( + callback, + filename, + duration, + channels, + sampleRate, + forceRender + ); + if (response) { + const { bufferA, bufferB } = response; + if (compareSignals(bufferA, bufferB) > threshold) { + throw new Error(`generated buffer does not match file ${filename}`); + } + } +} diff --git a/test/helper/compare/OfflineRender.ts b/test/helper/compare/OfflineRender.ts new file mode 100644 index 00000000..a736f332 --- /dev/null +++ b/test/helper/compare/OfflineRender.ts @@ -0,0 +1,74 @@ +import { TestAudioBuffer } from "./TestAudioBuffer.js"; + +export async function OfflineRender( + callback: (context: OfflineAudioContext) => Promise | void, + duration = 0.001, + channels = 1, + sampleRate = 11025 +): Promise { + // the offline context + const offlineContext = new OfflineAudioContext( + channels, + Math.floor(duration * sampleRate), + sampleRate + ) as unknown as OfflineAudioContext; + + // wait for the callback + await callback(offlineContext); + + // render the buffer + const buffer = await offlineContext.startRendering(); + + // wrap the buffer + return new TestAudioBuffer(buffer); +} + +/** + * Returns true if the input passes audio to the output + */ +export async function PassesAudio( + callback: ( + context: OfflineAudioContext, + input: ConstantSourceNode, + output: AudioDestinationNode + ) => Promise | void +): Promise { + const buffer = await OfflineRender( + async (context) => { + const source = + context.createConstantSource() as unknown as ConstantSourceNode; + source.start(0); + source.offset.setValueAtTime(0, 0); + source.offset.setValueAtTime(1, 0.25); + const destination = + context.destination as unknown as AudioDestinationNode; + await callback(context, source, destination); + }, + 0.5, + 1, + 11025 + ); + const sample0 = buffer.getValueAtTime(0) === 0; + const sample1 = buffer.getValueAtTime(0.2) === 0; + const sample2 = (buffer.getValueAtTime(0.26) as number) > 0; + const sample3 = (buffer.getValueAtTime(0.49) as number) > 0; + return sample0 && sample1 && sample2 && sample3; +} + +/** + * Returns true if the callback makes a sound + */ +export async function MakesSound( + callback: (context: OfflineAudioContext) => Promise | void, + duration = 0.001, + channels = 1, + sampleRate = 11025 +): Promise { + const buffer = await OfflineRender( + callback, + duration, + channels, + sampleRate + ); + return !buffer.isSilent(); +} diff --git a/test/helper/compare/Plot.ts b/test/helper/compare/Plot.ts new file mode 100644 index 00000000..8b22aa72 --- /dev/null +++ b/test/helper/compare/Plot.ts @@ -0,0 +1,72 @@ +import { analyze } from "./Spectrum.js"; +import { TestAudioBuffer } from "./TestAudioBuffer.js"; +import type { ToneAudioBuffer } from "../../../Tone/core/context/ToneAudioBuffer.js"; +import plotly from "plotly.js-dist"; +import array2d from "array2d"; + +/** + * Generate a 2d spectrogram image of the audio buffer + */ +export function spectrogram( + buffer: TestAudioBuffer | ToneAudioBuffer, + fftSize = 2048, + hopSize = 32 +): HTMLElement { + buffer = new TestAudioBuffer(buffer); + const analysis = analyze(buffer, fftSize, hopSize); + const element = document.createElement("div"); + const rotated = array2d.rotate(analysis, array2d.DIRECTIONS.LEFT); + const flipped = array2d.flip(rotated, array2d.AXES.X); + plotly.newPlot( + element, + [ + { + z: flipped, + type: "heatmap", + colorscale: "Viridis", + }, + ], + { + yaxis: { + type: "log", + autorange: true, + }, + zaxis: { + type: "log", + autorange: true, + }, + } + ); + return element; +} + +/** + * Generate a plot of the input signal + */ +export function signal(buffer: TestAudioBuffer | ToneAudioBuffer): HTMLElement { + buffer = new TestAudioBuffer(buffer); + const descriptions = buffer.toArray().map((array, i) => { + return { + y: array, + x: array.map((_, t: number) => t / buffer.sampleRate), + xaxis: "x", + yaxis: `y${i + 1}`, + type: "scatter", + mode: "lines", + name: `channel ${i}`, + }; + }); + const element = document.createElement("div"); + plotly.newPlot(element, descriptions, { + grid: { + rows: buffer.numberOfChannels, + columns: 1, + }, + xaxis: { + title: "Seconds", + }, + showlegend: false, + colorway: ["#a600a6", "#f20076", "#ff5c40", "#ffa600"], + }); + return element; +} diff --git a/test/helper/compare/Spectrum.ts b/test/helper/compare/Spectrum.ts new file mode 100644 index 00000000..8f947976 --- /dev/null +++ b/test/helper/compare/Spectrum.ts @@ -0,0 +1,26 @@ +import { TestAudioBuffer } from "./TestAudioBuffer.js"; +import windowing from "fft-windowing"; +import ft from "fourier-transform"; + +/** + * Return a spectrogram of the buffer + */ +export function analyze(buffer: TestAudioBuffer, fftSize = 256, hopSize = 128) { + const spectrogram: number[][] = []; + buffer + .toMono() + .toArray() + .forEach((channel) => { + for ( + let index = 0; + index < channel.length - fftSize; + index += hopSize + ) { + const segment = windowing.blackman_harris( + channel.slice(index, index + fftSize) + ); + spectrogram.push(ft(segment)); + } + }); + return spectrogram; +} diff --git a/test/helper/compare/TestAudioBuffer.ts b/test/helper/compare/TestAudioBuffer.ts new file mode 100644 index 00000000..0ce91fc1 --- /dev/null +++ b/test/helper/compare/TestAudioBuffer.ts @@ -0,0 +1,327 @@ +import toWav from "audiobuffer-to-wav"; +import type { ToneAudioBuffer } from "../../../Tone/core/context/ToneAudioBuffer.js"; + +export class TestAudioBuffer { + static async fromUrl( + url: string, + channels = 1, + sampleRate = 11025 + ): Promise { + const response = await fetch(url); + if (response.ok) { + const buffer = await response.arrayBuffer(); + const context = new OfflineAudioContext(channels, 1, sampleRate); + const audioBuffer = await context.decodeAudioData(buffer); + return new TestAudioBuffer(audioBuffer); + } else { + throw new Error(`could not load url ${url}`); + } + } + + static fromTone(buffer: ToneAudioBuffer) { + return new TestAudioBuffer(buffer); + } + + private _buffer: AudioBuffer; + private _rms?: Float32Array[]; + private _array?: Float32Array[]; + + constructor(buffer: AudioBuffer | TestAudioBuffer | ToneAudioBuffer) { + if (buffer instanceof AudioBuffer) { + this._buffer = buffer; + } else if (buffer instanceof TestAudioBuffer) { + this._buffer = buffer._buffer; + } else { + this._buffer = buffer.get() as AudioBuffer; + } + } + + /** + * The number of channels of the audio file. + */ + get numberOfChannels(): number { + return this._buffer.numberOfChannels; + } + + /** + * The duration in seconds + */ + get duration(): number { + return this._buffer.duration; + } + + /** + * The length in samples + */ + get length(): number { + return this._buffer.length; + } + + /** + * The sample rate of the audio file + */ + get sampleRate(): number { + return this._buffer.sampleRate; + } + + /** + * Return the buffer as a nested array where the first axis is the number of channels + */ + toArray(): Float32Array[] { + if (!this._array) { + const output: Float32Array[] = []; + for ( + let channel = 0; + channel < this._buffer.numberOfChannels; + channel++ + ) { + output[channel] = this._buffer.getChannelData(channel); + } + this._array = output; + } + return this._array; + } + + /** + * Return a new TestAudioBuffer which has all of the channels summed to a single channel + */ + toMono(): TestAudioBuffer { + const context = new OfflineAudioContext(1, 1, this._buffer.sampleRate); + const buffer = context.createBuffer( + 1, + this._buffer.length, + this._buffer.sampleRate + ); + // sum all the channels into a single channel + const bufferArray = buffer.getChannelData(0); + this.toArray().forEach((channel) => { + channel.forEach((value, index) => { + bufferArray[index] += value; + }); + }); + return new TestAudioBuffer(buffer); + } + + /** + * Return the Root Mean Square of the channels at that slice of time. + * If buffer is mono, it will return a single value, otherwise it returns an array of numbers + * @param time Seconds + */ + getRmsAtTime(time: number): number[] | number { + if (!this._rms) { + const blockSize = 512; + this._rms = []; + this.toArray().forEach((channel) => { + const channelRMS = new Float32Array(channel.length); + this._rms?.push(channelRMS); + for (let i = 0; i < channel.length; i++) { + const sqrSum = channel + .slice(i, i + blockSize) + .reduce((total, value) => { + return total + value * value; + }, 0); + channelRMS[i] = Math.sqrt(sqrSum / blockSize); + } + }); + } + const sampleTime = Math.floor(time * this._buffer.sampleRate); + if (sampleTime < this._rms[0].length) { + const values = this._rms.map((rms) => rms[sampleTime]); + if (values.length === 1) { + return values[0]; + } else { + return values; + } + } else { + return 0; + } + } + + /** + * Get the value of a sample at the given time. if the buffer has multiple + * channels, will return an array. + * @param time seconds + */ + getValueAtTime(time: number): number[] | number { + const sampleTime = Math.floor(time * this._buffer.sampleRate); + const array = this.toArray(); + if (sampleTime < array[0].length) { + const values = array.map((channel) => channel[sampleTime]); + if (values.length === 1) { + return values[0]; + } else { + return values; + } + } else { + return 0; + } + } + + /** + * return the time in seconds of the first time + * the AudioBuffer rose above the silence threshold + */ + getTimeOfFirstSound(threshold = 1e-6): number { + const firstSampleTimes = this.toArray().map((channel) => { + for (let i = 0; i < channel.length; i++) { + const sample = channel[i]; + if (sample > threshold) { + return i / this._buffer.sampleRate; + } + } + return -1; + }); + return Math.min(...firstSampleTimes); + } + + /** + * Return the last time a sample rose above the threshold + * @param threshold + */ + getTimeOfLastSound(threshold = 1e-6): number { + const lastSampleTimes = this.toArray().map((channel) => { + for (let i = channel.length - 1; i >= 0; i--) { + const sample = channel[i]; + if (sample > threshold) { + return i / this._buffer.sampleRate; + } + } + return -1; + }); + return Math.max(...lastSampleTimes); + } + + /** + * The maximum sample value across all the channels + */ + max(): number { + let max = -Infinity; + this.toArray().forEach((channel) => { + max = Math.max(max, ...Array.from(channel)); + }); + return max; + } + + /** + * The minimum sample value across all the channels + */ + min(): number { + let min = Infinity; + this.toArray().forEach((channel) => { + min = Math.min(min, ...Array.from(channel)); + }); + return min; + } + + /** + * The value (only if it is consistent throughout the entire buffer). + * Throws an error if there are multiple values found. + */ + value(): number { + const max = this.max(); + const min = this.min(); + if (max - min > 1e-6) { + throw new Error("multiple values found in this buffer"); + } + return max; + } + + /** + * Test if the buffer has no audio data. if it is at or near 0 the entire buffer. + */ + isSilent(threshold = 1e-6): boolean { + try { + return Math.abs(this.value()) < threshold; + } catch (e) { + return false; + } + } + + /** + * Return a copy of the TestAudioBuffer + */ + clone(): TestAudioBuffer { + // should probably also clone the buffer + return new TestAudioBuffer(this._buffer); + } + + /** + * Return a new TestAudioBuffer at the given sample rate. + * @param sampleRate a new sample rate to compute the buffer ar + */ + async resample(sampleRate: number): Promise { + const offlineCtx = new OfflineAudioContext( + this._buffer.numberOfChannels, + this._buffer.duration * sampleRate, + sampleRate + ); + const resampledBuffer = offlineCtx.createBuffer( + this._buffer.numberOfChannels, + this._buffer.length, + this._buffer.sampleRate + ); + + // Copy the source data into the offline AudioBuffer + for ( + let channel = 0; + channel < resampledBuffer.numberOfChannels; + channel++ + ) { + resampledBuffer.copyToChannel( + this._buffer.getChannelData(channel), + channel + ); + } + + // Play it from the beginning. + const source = offlineCtx.createBufferSource(); + source.buffer = resampledBuffer; + source.connect(offlineCtx.destination); + source.start(0); + + // compute the results + const computedBuffer = await offlineCtx.startRendering(); + return new TestAudioBuffer(computedBuffer); + } + + toWav(): ArrayBuffer { + // check that the min and max are between -1 and 1 + return toWav(this._buffer, { + float32: false, + }); + } + + downloadWav(filename = "test_audio"): void { + const wave = this.toWav(); + const blob = new Blob([wave], { type: "audio/wav" }); + const blobUrl = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = blobUrl; + a.download = filename; + a.click(); + window.URL.revokeObjectURL(blobUrl); + } + + forEach(callback: (sample: number, time: number) => void): void { + const channels = this.toMono().toArray(); + channels[0].forEach((sample, index) => { + callback(sample, index / this.sampleRate); + }); + } + + forEachBetween( + callback: (sample: number, time: number) => void, + startTime = 0, + endTime: number = this.duration + ): void { + const channels = this.toMono().toArray(); + const startSamples = Math.floor(startTime * this.sampleRate); + const endSamples = Math.floor( + Math.min(endTime * this.sampleRate, this.length) + ); + for (let s = startSamples; s < endSamples; s++) { + const sample = channels[0][s]; + callback(sample, s / this.sampleRate); + } + } +} diff --git a/test/helper/compare/index.ts b/test/helper/compare/index.ts new file mode 100644 index 00000000..a6626e82 --- /dev/null +++ b/test/helper/compare/index.ts @@ -0,0 +1,8 @@ +import * as Compare from "./Compare.js"; +import * as Plot from "./Plot.js"; +export { OfflineRender as Offline } from "./OfflineRender.js"; +export { PassesAudio } from "./OfflineRender.js"; +export { MakesSound } from "./OfflineRender.js"; +export { TestAudioBuffer } from "./TestAudioBuffer.js"; + +export { Compare, Plot }; diff --git a/test/integration/node/package.json b/test/integration/node/package.json new file mode 100644 index 00000000..939579bd --- /dev/null +++ b/test/integration/node/package.json @@ -0,0 +1,9 @@ +{ + "name": "tone-node-test", + "dependencies": { + "tone": "file:../../.." + }, + "scripts": { + "test": "node test.mjs" + } +} diff --git a/test/integration/node/test.mjs b/test/integration/node/test.mjs new file mode 100644 index 00000000..154cb25d --- /dev/null +++ b/test/integration/node/test.mjs @@ -0,0 +1,8 @@ +/** + * @fileoverview Basic loading in node.js + */ +import * as Tone from "tone"; +import assert from "assert"; + +assert("MonoSynth" in Tone, "Tone missing expected export"); +assert("start" in Tone, "Tone missing expected export"); diff --git a/test/integration/typescript/package.json b/test/integration/typescript/package.json new file mode 100644 index 00000000..ef0beb22 --- /dev/null +++ b/test/integration/typescript/package.json @@ -0,0 +1,11 @@ +{ + "name": "tone-typescript-test", + "dependencies": { + "@types/node": "^20.12.8", + "tone": "file:../../..", + "typescript": "^5.4.5" + }, + "scripts": { + "test": "tsc ./test.ts --noEmit --lib dom" + } +} diff --git a/test/integration/typescript/test.ts b/test/integration/typescript/test.ts new file mode 100644 index 00000000..f09582a7 --- /dev/null +++ b/test/integration/typescript/test.ts @@ -0,0 +1,3 @@ +import * as Tone from "tone"; + +const synth = new Tone.MonoSynth(); diff --git a/test/integration/unpkg/package.json b/test/integration/unpkg/package.json new file mode 100644 index 00000000..b38dc7f6 --- /dev/null +++ b/test/integration/unpkg/package.json @@ -0,0 +1,10 @@ +{ + "name": "tone-unpkg-test", + "dependencies": { + "puppeteer": "^22.7.1", + "tone": "file:../../.." + }, + "scripts": { + "test": "node test.mjs" + } +} diff --git a/test/integration/unpkg/test.mjs b/test/integration/unpkg/test.mjs new file mode 100644 index 00000000..b46dc9bb --- /dev/null +++ b/test/integration/unpkg/test.mjs @@ -0,0 +1,24 @@ +/** + * @fileoverview Ensure that the unpkg link can be loaded in the browser + */ +import puppeteer from "puppeteer"; +import { fileURLToPath } from "url"; +import { readFile } from "fs/promises"; +import { resolve } from "path"; +import assert from "assert"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); +const rootDir = resolve(__dirname, "../../../"); +const pkg = JSON.parse( + (await readFile(resolve(rootDir, "package.json"))).toString() +); + +const browser = await puppeteer.launch(); +const page = await browser.newPage(); +await page.addScriptTag({ + path: resolve(rootDir, pkg.unpkg), +}); +const time = await page.evaluate("Tone.now()"); +await browser.close(); + +assert(time >= 0, new Error("did not export a time value")); diff --git a/test/integration/vite/index.html b/test/integration/vite/index.html new file mode 100644 index 00000000..4fea39b8 --- /dev/null +++ b/test/integration/vite/index.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/test/integration/vite/index.ts b/test/integration/vite/index.ts new file mode 100644 index 00000000..9cd6fb77 --- /dev/null +++ b/test/integration/vite/index.ts @@ -0,0 +1,3 @@ +import { MonoSynth } from "tone"; + +const synth = new MonoSynth(); diff --git a/test/integration/vite/package.json b/test/integration/vite/package.json new file mode 100644 index 00000000..6fc3a46e --- /dev/null +++ b/test/integration/vite/package.json @@ -0,0 +1,10 @@ +{ + "name": "tone-vite-test", + "dependencies": { + "tone": "file:../../..", + "vite": "^5.2.11" + }, + "scripts": { + "test": "vite build ./" + } +} diff --git a/test/integration/webpack/package.json b/test/integration/webpack/package.json new file mode 100644 index 00000000..722c480b --- /dev/null +++ b/test/integration/webpack/package.json @@ -0,0 +1,12 @@ +{ + "name": "tone-webpack-test", + "type": "module", + "dependencies": { + "tone": "file:../../..", + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + }, + "scripts": { + "test": "webpack ./test.js --target=web" + } +} diff --git a/test/integration/webpack/test.js b/test/integration/webpack/test.js new file mode 100644 index 00000000..9cd6fb77 --- /dev/null +++ b/test/integration/webpack/test.js @@ -0,0 +1,3 @@ +import { MonoSynth } from "tone"; + +const synth = new MonoSynth(); diff --git a/test/karma.conf.cjs b/test/karma.conf.cjs deleted file mode 100644 index 899ad6df..00000000 --- a/test/karma.conf.cjs +++ /dev/null @@ -1,171 +0,0 @@ -/* eslint-disable no-console, @typescript-eslint/no-var-requires */ -// Karma configuration -const path = require("path"); -const argv = require("yargs") - .alias("i", "file") - .alias("d", "dir") - .argv; - -let BROWSERS = ["HeadlessChrome", "HeadlessFirefox", "Safari"]; - -// get the entry point files -let entryPoints = undefined; -if (typeof argv.file === "string") { - entryPoints = RegExp(`.*\\/${argv.file}\\.test\\.ts$`); - console.log(`testing file "${argv.file}"`); -} else if (typeof argv.dir === "string") { - entryPoints = RegExp(`.*${argv.dir}.*\\/.*\\.test\\.ts$`); - console.log(`testing directory "${argv.dir}"`); -} - -if (process.env.BROWSER === "chrome") { - BROWSERS = ["HeadlessChrome"]; -} else if (process.env.BROWSER === "firefox") { - BROWSERS = ["HeadlessFirefox"]; -} else if (process.env.BROWSER === "safari") { - BROWSERS = ["Safari"]; -} else { - BROWSERS = ["HeadlessChrome", "HeadlessFirefox"]; -} - -module.exports = function(config) { - const configuration = { - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "../", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha", "karma-typescript"], - - // list of files / patterns to load in the browser - files: [ - "test/**/*.ts", - "Tone/**/*.ts", - { pattern: "test/audio/**", included: false }, - { pattern: "test/html/**", included: false }, - ], - - // Karma Typescript compiler options - karmaTypescriptConfig: { - compilerOptions: { - target: "es6", - module: "commonjs", - }, - bundlerOptions: { - resolve: { - directories: ["Tone", "node_modules", "test"], - }, - entrypoints: entryPoints - }, - coverageOptions: { - exclude: /(.*\.test\.ts|test\/.*\.ts)$/i, - }, - reports: { - html: path.resolve(__dirname, "../coverage"), - lcovonly: { - directory: path.resolve(__dirname, "../coverage"), - filename: "coverage.lcov", - }, - }, - tsconfig: "./tsconfig.json", - }, - - // list of files to exclude - exclude: [ - "node_modules/*", - ], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.ts": "karma-typescript", - // "Tone/**/*.ts": "coverage", - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["dots", "karma-typescript"], - - // coverageReporter : { - // type : "lcov", - // dir: path.resolve(__dirname, "../coverage"), - // }, - - // plugins - plugins: [ - "karma-typescript", - // "karma-coverage", - "karma-mocha", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-safari-launcher", - // "karma-sourcemap-loader", - ], - - client: { - mocha: { - reporter: "html", - timeout: 10000, - retries: 2, - ui: "bdd", - }, - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // set the inactivity level to longer - browserNoActivityTimeout: 40000, - browserDisconnectTimeout: 30000, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_ERROR, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - // restartOnFileChange : true, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: BROWSERS, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - // concurrency: process.env.TRAVIS ? 1 : Infinity, - concurrency: Infinity, - - // custom launcher for travis - customLaunchers: { - HeadlessChrome: { - base: "ChromeHeadless", - flags: ["--no-sandbox", "--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", - "--autoplay-policy=no-user-gesture-required"], - }, - HeadlessFirefox: { - base: "Firefox", - flags: ["-headless"], - prefs: { - "focusmanager.testmode": true, - "media.navigator.permission.disabled": true, - }, - }, - OnlineChrome: { - base: "Chrome", - flags: ["--no-sandbox", "--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", - "--autoplay-policy=no-user-gesture-required"], - }, - }, - }; - - config.set(configuration); -}; diff --git a/test/scripts/node_test.cjs b/test/scripts/node_test.cjs deleted file mode 100644 index 7b282d2f..00000000 --- a/test/scripts/node_test.cjs +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -// test the tone.js build -const Tone = require("../../build/esm"); -const assert = require("assert"); -const semver = require("semver"); -const { version } = require("../../package.json"); - -// test the version -const diff = semver.diff(Tone.version, version); -assert(diff === "patch" || diff === null, "wrong version listed"); diff --git a/test/scripts/test_html.cjs b/test/scripts/test_html.cjs index 191d4523..8c2835e0 100644 --- a/test/scripts/test_html.cjs +++ b/test/scripts/test_html.cjs @@ -40,7 +40,9 @@ async function testExampleString(str) { // work with file here in fd await writeFile(path, str); try { - await execPromise(`tsc --noEmit --target es5 --lib dom,ES2015 ${path}`); + await execPromise( + `tsc --noEmit --target es5 --lib dom,ES2015 ${path}` + ); } finally { cleanup(); } @@ -50,7 +52,7 @@ const htmlFiles = glob.sync(resolve(__dirname, "../../examples/*.html")); async function main() { for (let i = 0; i < htmlFiles.length; i++) { - const path = htmlFiles[i]; + const path = htmlFiles[i]; const fileAsString = (await readFile(path)).toString(); const dom = new JSDOM(fileAsString); const scriptTag = dom.window.document.querySelector("body script"); diff --git a/test/scripts/test_integrations.mjs b/test/scripts/test_integrations.mjs new file mode 100644 index 00000000..0952e683 --- /dev/null +++ b/test/scripts/test_integrations.mjs @@ -0,0 +1,15 @@ +#!/usr/bin/env zx +import "zx/globals"; +import { glob } from "glob"; +import { basename, resolve } from "path"; + +const integrations = await glob(resolve(__dirname, "../integration/*")); +for (let dir of integrations) { + await within(async () => { + cd(dir); + // eslint-disable-next-line no-console + console.log("Integration:", basename(dir)); + await $`npm i`; + await $`npm run test`; + }); +} diff --git a/test/scripts/test_readme.cjs b/test/scripts/test_readme.cjs index 00ecd518..c3adf823 100644 --- a/test/scripts/test_readme.cjs +++ b/test/scripts/test_readme.cjs @@ -32,14 +32,18 @@ async function testExampleString(str) { // work with file here in fd await writeFile(path, str); try { - await execPromise(`tsc --noEmit --target es5 --lib dom,ES2015 ${path}`); + await execPromise( + `tsc --noEmit --target es5 --lib dom,ES2015 ${path}` + ); } finally { cleanup(); } } async function main() { - const readme = (await readFile(resolve(__dirname, "../../README.md"))).toString(); + const readme = ( + await readFile(resolve(__dirname, "../../README.md")) + ).toString(); const html = new Converter().makeHtml(readme); const dom = new JSDOM(html); const scripts = dom.window.document.querySelectorAll("code.javascript"); diff --git a/test/web-test-runner.config.js b/test/web-test-runner.config.js new file mode 100644 index 00000000..ebe9b7bd --- /dev/null +++ b/test/web-test-runner.config.js @@ -0,0 +1,40 @@ +import { esbuildPlugin } from "@web/dev-server-esbuild"; +import { fromRollup } from "@web/dev-server-rollup"; +import rollupCommonjs from "@rollup/plugin-commonjs"; +import { fileURLToPath } from "url"; +import { resolve } from "path"; +import { puppeteerLauncher } from "@web/test-runner-puppeteer"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); +const commonjs = fromRollup(rollupCommonjs); + +export default { + files: ["./build/*/Tone/**/*.test.js", "./build/*/Tone/*.test.js"], + nodeResolve: true, + browsers: [ + puppeteerLauncher({ + launchOptions: { + headless: true, + args: [ + "--no-sandbox", + "--use-fake-ui-for-media-stream", + "--use-fake-device-for-media-stream", + "--autoplay-policy=no-user-gesture-required", + ], + }, + }), + ], + testFramework: { + config: { + timeout: 10000, + retries: 2, + ui: "bdd", + }, + }, + plugins: [ + commonjs({ + include: ["**/node_modules/**/*"], + }), + ], + rootDir: resolve(__dirname, "../"), +}; diff --git a/tsconfig.json b/tsconfig.json index c3d97612..64564a5f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,28 +3,23 @@ "compilerOptions": { "strictNullChecks": true, "target": "ES6", - "module": "ES2015", + "module": "Node16", "noImplicitAny": false, "importHelpers": true, "noUnusedLocals": false, "removeComments": false, "outDir": "./build/esm", "sourceMap": true, + "esModuleInterop": true, "skipLibCheck": true, - "moduleResolution": "node", + "moduleResolution": "Node16", "strictPropertyInitialization": true, "downlevelIteration": true, "experimentalDecorators": true, - "lib": [ - "es6", - "dom", - "es2015" - ], - "baseUrl": "./" + "lib": ["es6", "dom", "es2015"], + "baseUrl": "./", + "rootDir": "./" }, - "include": [ - "Tone/**/*.ts", - "test/**/*.ts" - ], - "exclude": ["node_modules"] -} \ No newline at end of file + "include": ["Tone/**/*.ts", "test/**/*.ts"], + "exclude": ["node_modules", "test/integration/**"] +} From 56fea7cb7007480b87efe94e47185f99ea108412 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Mon, 6 May 2024 10:55:55 -0400 Subject: [PATCH 15/17] Refactor options before `super` (#1244) --- Tone/component/analysis/Analyser.ts | 7 +------ Tone/component/analysis/FFT.ts | 2 +- Tone/component/analysis/Follower.ts | 6 +----- Tone/component/analysis/Meter.ts | 4 +--- Tone/component/analysis/Waveform.ts | 4 +--- Tone/component/channel/Channel.ts | 7 +------ Tone/component/channel/CrossFade.ts | 8 +------- Tone/component/channel/Merge.ts | 4 +--- Tone/component/channel/MultibandSplit.ts | 7 +------ Tone/component/channel/PanVol.ts | 7 +------ Tone/component/channel/Panner.ts | 6 +----- Tone/component/channel/Panner3D.ts | 8 +------- Tone/component/channel/Recorder.ts | 2 +- Tone/component/channel/Solo.ts | 2 +- Tone/component/channel/Split.ts | 4 +--- Tone/component/channel/Volume.ts | 4 +--- Tone/component/dynamics/Compressor.ts | 7 +------ Tone/component/dynamics/Gate.ts | 9 +-------- Tone/component/dynamics/Limiter.ts | 8 +------- Tone/component/dynamics/MidSideCompressor.ts | 6 +----- Tone/component/dynamics/MultibandCompressor.ts | 9 +-------- Tone/component/envelope/Envelope.ts | 9 +-------- Tone/component/envelope/FrequencyEnvelope.ts | 9 +-------- Tone/component/filter/BiquadFilter.ts | 7 +------ Tone/component/filter/Convolver.ts | 7 +------ Tone/component/filter/EQ3.ts | 8 +------- Tone/component/filter/FeedbackCombFilter.ts | 7 +------ Tone/component/filter/Filter.ts | 8 +------- Tone/component/filter/LowpassCombFilter.ts | 8 +------- Tone/component/filter/OnePoleFilter.ts | 7 +------ Tone/core/clock/Clock.ts | 7 +------ Tone/core/clock/TickParam.ts | 4 +--- Tone/core/clock/TickSignal.ts | 4 +--- Tone/core/clock/TickSource.ts | 6 +----- Tone/core/clock/Transport.ts | 2 +- Tone/core/context/Delay.ts | 8 +------- Tone/core/context/Destination.ts | 2 +- Tone/core/context/Gain.ts | 7 +------ Tone/core/context/Param.ts | 9 +-------- Tone/effect/AutoFilter.ts | 8 +------- Tone/effect/AutoPanner.ts | 6 +----- Tone/effect/AutoWah.ts | 8 +------- Tone/effect/BitCrusher.ts | 6 ++---- Tone/effect/Chebyshev.ts | 4 +--- Tone/effect/Chorus.ts | 8 +------- Tone/effect/Distortion.ts | 6 +----- Tone/effect/FeedbackDelay.ts | 7 +------ Tone/effect/Freeverb.ts | 7 +------ Tone/effect/FrequencyShifter.ts | 6 +----- Tone/effect/JCReverb.ts | 6 +----- Tone/effect/Phaser.ts | 8 +------- Tone/effect/PingPongDelay.ts | 7 +------ Tone/effect/PitchShift.ts | 4 +--- Tone/effect/Reverb.ts | 2 +- Tone/effect/StereoWidener.ts | 7 ++----- Tone/effect/Tremolo.ts | 7 +------ Tone/effect/Vibrato.ts | 7 +------ Tone/event/Loop.ts | 7 +------ Tone/event/Part.ts | 7 +------ Tone/event/Pattern.ts | 8 +------- Tone/event/Sequence.ts | 8 +------- Tone/event/ToneEvent.ts | 7 +------ Tone/instrument/DuoSynth.ts | 2 +- Tone/instrument/FMSynth.ts | 2 +- Tone/instrument/Instrument.ts | 2 +- Tone/instrument/MembraneSynth.ts | 2 +- Tone/instrument/MetalSynth.ts | 2 +- Tone/instrument/ModulationSynth.ts | 2 +- Tone/instrument/MonoSynth.ts | 2 +- Tone/instrument/Monophonic.ts | 2 +- Tone/instrument/NoiseSynth.ts | 3 ++- Tone/instrument/PluckSynth.ts | 2 +- Tone/instrument/PolySynth.ts | 7 +------ Tone/instrument/Sampler.ts | 9 +-------- Tone/instrument/Synth.ts | 2 +- Tone/signal/Add.ts | 6 +----- Tone/signal/GreaterThan.ts | 8 +------- Tone/signal/GreaterThanZero.ts | 6 +----- Tone/signal/Multiply.ts | 8 +------- Tone/signal/Pow.ts | 6 +----- Tone/signal/Scale.ts | 9 +-------- Tone/signal/ScaleExp.ts | 10 +--------- Tone/signal/Signal.ts | 8 +------- Tone/signal/SignalOperator.ts | 8 +++----- Tone/signal/Subtract.ts | 6 +----- Tone/signal/SyncedSignal.ts | 7 +------ Tone/signal/ToneConstantSource.ts | 6 +----- Tone/signal/WaveShaper.ts | 9 +-------- Tone/signal/Zero.ts | 4 +--- Tone/source/Noise.ts | 2 +- Tone/source/UserMedia.ts | 4 +--- Tone/source/buffer/GrainPlayer.ts | 7 +------ Tone/source/buffer/Player.ts | 7 +------ Tone/source/buffer/Players.ts | 9 +-------- Tone/source/buffer/ToneBufferSource.ts | 7 +------ Tone/source/oscillator/AMOscillator.ts | 8 +------- Tone/source/oscillator/FMOscillator.ts | 8 +------- Tone/source/oscillator/FatOscillator.ts | 8 +------- Tone/source/oscillator/LFO.ts | 8 +------- Tone/source/oscillator/OmniOscillator.ts | 7 +------ Tone/source/oscillator/Oscillator.ts | 7 +------ Tone/source/oscillator/PWMOscillator.ts | 7 +------ Tone/source/oscillator/PulseOscillator.ts | 7 +------ Tone/source/oscillator/ToneOscillatorNode.ts | 7 +------ 104 files changed, 109 insertions(+), 525 deletions(-) diff --git a/Tone/component/analysis/Analyser.ts b/Tone/component/analysis/Analyser.ts index 20aa451b..ed3244e3 100644 --- a/Tone/component/analysis/Analyser.ts +++ b/Tone/component/analysis/Analyser.ts @@ -62,17 +62,12 @@ export class Analyser extends ToneAudioNode { constructor(type?: AnalyserType, size?: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Analyser.getDefaults(), arguments, [ - "type", - "size", - ]) - ); const options = optionsFromArguments( Analyser.getDefaults(), arguments, ["type", "size"] ); + super(options); this.input = this.output = diff --git a/Tone/component/analysis/FFT.ts b/Tone/component/analysis/FFT.ts index 6f935983..1600a134 100644 --- a/Tone/component/analysis/FFT.ts +++ b/Tone/component/analysis/FFT.ts @@ -32,10 +32,10 @@ export class FFT extends MeterBase { constructor(size?: PowerOfTwo); constructor(options?: Partial); constructor() { - super(optionsFromArguments(FFT.getDefaults(), arguments, ["size"])); const options = optionsFromArguments(FFT.getDefaults(), arguments, [ "size", ]); + super(options); this.normalRange = options.normalRange; this._analyser.type = "fft"; diff --git a/Tone/component/analysis/Follower.ts b/Tone/component/analysis/Follower.ts index 46dc54d3..b1754c6c 100644 --- a/Tone/component/analysis/Follower.ts +++ b/Tone/component/analysis/Follower.ts @@ -50,16 +50,12 @@ export class Follower extends ToneAudioNode { constructor(smoothing?: Time); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Follower.getDefaults(), arguments, [ - "smoothing", - ]) - ); const options = optionsFromArguments( Follower.getDefaults(), arguments, ["smoothing"] ); + super(options); this._abs = this.input = new Abs({ context: this.context }); this._lowpass = this.output = new OnePoleFilter({ diff --git a/Tone/component/analysis/Meter.ts b/Tone/component/analysis/Meter.ts index ad96953f..2a1b6aa2 100644 --- a/Tone/component/analysis/Meter.ts +++ b/Tone/component/analysis/Meter.ts @@ -55,12 +55,10 @@ export class Meter extends MeterBase { constructor(smoothing?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]) - ); const options = optionsFromArguments(Meter.getDefaults(), arguments, [ "smoothing", ]); + super(options); this.input = this.output = diff --git a/Tone/component/analysis/Waveform.ts b/Tone/component/analysis/Waveform.ts index 07c48de9..7094d618 100644 --- a/Tone/component/analysis/Waveform.ts +++ b/Tone/component/analysis/Waveform.ts @@ -22,14 +22,12 @@ export class Waveform extends MeterBase { constructor(size?: PowerOfTwo); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]) - ); const options = optionsFromArguments( Waveform.getDefaults(), arguments, ["size"] ); + super(options); this._analyser.type = "waveform"; this.size = options.size; diff --git a/Tone/component/channel/Channel.ts b/Tone/component/channel/Channel.ts index 0fe07960..ed5ced88 100644 --- a/Tone/component/channel/Channel.ts +++ b/Tone/component/channel/Channel.ts @@ -63,16 +63,11 @@ export class Channel extends ToneAudioNode { constructor(volume?: Decibels, pan?: AudioRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Channel.getDefaults(), arguments, [ - "volume", - "pan", - ]) - ); const options = optionsFromArguments(Channel.getDefaults(), arguments, [ "volume", "pan", ]); + super(options); this._solo = this.input = new Solo({ solo: options.solo, diff --git a/Tone/component/channel/CrossFade.ts b/Tone/component/channel/CrossFade.ts index 87b3312f..2a6aa843 100644 --- a/Tone/component/channel/CrossFade.ts +++ b/Tone/component/channel/CrossFade.ts @@ -100,18 +100,12 @@ export class CrossFade extends ToneAudioNode { constructor(fade?: NormalRange); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(CrossFade.getDefaults(), arguments, [ - "fade", - ]) - ) - ); const options = optionsFromArguments( CrossFade.getDefaults(), arguments, ["fade"] ); + super(options); this.fade = new Signal({ context: this.context, diff --git a/Tone/component/channel/Merge.ts b/Tone/component/channel/Merge.ts index 85957dc0..7ae41ca0 100644 --- a/Tone/component/channel/Merge.ts +++ b/Tone/component/channel/Merge.ts @@ -44,12 +44,10 @@ export class Merge extends ToneAudioNode { constructor(channels?: Positive); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Merge.getDefaults(), arguments, ["channels"]) - ); const options = optionsFromArguments(Merge.getDefaults(), arguments, [ "channels", ]); + super(options); this._merger = this.output = diff --git a/Tone/component/channel/MultibandSplit.ts b/Tone/component/channel/MultibandSplit.ts index 82fa2edc..4ed380ec 100644 --- a/Tone/component/channel/MultibandSplit.ts +++ b/Tone/component/channel/MultibandSplit.ts @@ -106,17 +106,12 @@ export class MultibandSplit extends ToneAudioNode { constructor(lowFrequency?: Frequency, highFrequency?: Frequency); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(MultibandSplit.getDefaults(), arguments, [ - "lowFrequency", - "highFrequency", - ]) - ); const options = optionsFromArguments( MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"] ); + super(options); this.lowFrequency = new Signal({ context: this.context, diff --git a/Tone/component/channel/PanVol.ts b/Tone/component/channel/PanVol.ts index 009cba9f..3068804b 100644 --- a/Tone/component/channel/PanVol.ts +++ b/Tone/component/channel/PanVol.ts @@ -61,16 +61,11 @@ export class PanVol extends ToneAudioNode { constructor(pan?: AudioRange, volume?: Decibels); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(PanVol.getDefaults(), arguments, [ - "pan", - "volume", - ]) - ); const options = optionsFromArguments(PanVol.getDefaults(), arguments, [ "pan", "volume", ]); + super(options); this._panner = this.input = new Panner({ context: this.context, diff --git a/Tone/component/channel/Panner.ts b/Tone/component/channel/Panner.ts index f9444e63..93194d18 100644 --- a/Tone/component/channel/Panner.ts +++ b/Tone/component/channel/Panner.ts @@ -54,14 +54,10 @@ export class Panner extends ToneAudioNode { */ constructor(pan?: AudioRange); constructor() { - super( - Object.assign( - optionsFromArguments(Panner.getDefaults(), arguments, ["pan"]) - ) - ); const options = optionsFromArguments(Panner.getDefaults(), arguments, [ "pan", ]); + super(options); this.pan = new Param({ context: this.context, diff --git a/Tone/component/channel/Panner3D.ts b/Tone/component/channel/Panner3D.ts index 9641b18a..e8ca7c8d 100644 --- a/Tone/component/channel/Panner3D.ts +++ b/Tone/component/channel/Panner3D.ts @@ -54,18 +54,12 @@ export class Panner3D extends ToneAudioNode { constructor(positionX: number, positionY: number, positionZ: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Panner3D.getDefaults(), arguments, [ - "positionX", - "positionY", - "positionZ", - ]) - ); const options = optionsFromArguments( Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"] ); + super(options); this._panner = this.input = this.output = this.context.createPanner(); // set some values diff --git a/Tone/component/channel/Recorder.ts b/Tone/component/channel/Recorder.ts index 716cdeef..103d0503 100644 --- a/Tone/component/channel/Recorder.ts +++ b/Tone/component/channel/Recorder.ts @@ -57,8 +57,8 @@ export class Recorder extends ToneAudioNode { constructor(options?: Partial); constructor() { - super(optionsFromArguments(Recorder.getDefaults(), arguments)); const options = optionsFromArguments(Recorder.getDefaults(), arguments); + super(options); this.input = new Gain({ context: this.context, diff --git a/Tone/component/channel/Solo.ts b/Tone/component/channel/Solo.ts index a509e7ec..765bd70b 100644 --- a/Tone/component/channel/Solo.ts +++ b/Tone/component/channel/Solo.ts @@ -34,10 +34,10 @@ export class Solo extends ToneAudioNode { constructor(solo?: boolean); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Solo.getDefaults(), arguments, ["solo"])); const options = optionsFromArguments(Solo.getDefaults(), arguments, [ "solo", ]); + super(options); this.input = this.output = new Gain({ context: this.context, diff --git a/Tone/component/channel/Split.ts b/Tone/component/channel/Split.ts index 5eb57ee2..f73d6e8b 100644 --- a/Tone/component/channel/Split.ts +++ b/Tone/component/channel/Split.ts @@ -33,12 +33,10 @@ export class Split extends ToneAudioNode { constructor(channels?: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Split.getDefaults(), arguments, ["channels"]) - ); const options = optionsFromArguments(Split.getDefaults(), arguments, [ "channels", ]); + super(options); this._splitter = this.input = diff --git a/Tone/component/channel/Volume.ts b/Tone/component/channel/Volume.ts index 121871b8..a560a2a4 100644 --- a/Tone/component/channel/Volume.ts +++ b/Tone/component/channel/Volume.ts @@ -54,12 +54,10 @@ export class Volume extends ToneAudioNode { constructor(volume?: Decibels); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]) - ); const options = optionsFromArguments(Volume.getDefaults(), arguments, [ "volume", ]); + super(options); this.input = this.output = new Gain({ context: this.context, diff --git a/Tone/component/dynamics/Compressor.ts b/Tone/component/dynamics/Compressor.ts index 27149add..3fc2b2af 100644 --- a/Tone/component/dynamics/Compressor.ts +++ b/Tone/component/dynamics/Compressor.ts @@ -79,17 +79,12 @@ export class Compressor extends ToneAudioNode { constructor(threshold?: Decibels, ratio?: Positive); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Compressor.getDefaults(), arguments, [ - "threshold", - "ratio", - ]) - ); const options = optionsFromArguments( Compressor.getDefaults(), arguments, ["threshold", "ratio"] ); + super(options); this.threshold = new Param({ minValue: this._compressor.threshold.minValue, diff --git a/Tone/component/dynamics/Gate.ts b/Tone/component/dynamics/Gate.ts index a19401dc..ce8b42a8 100644 --- a/Tone/component/dynamics/Gate.ts +++ b/Tone/component/dynamics/Gate.ts @@ -54,18 +54,11 @@ export class Gate extends ToneAudioNode { constructor(threshold?: Decibels, smoothing?: Time); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(Gate.getDefaults(), arguments, [ - "threshold", - "smoothing", - ]) - ) - ); const options = optionsFromArguments(Gate.getDefaults(), arguments, [ "threshold", "smoothing", ]); + super(options); this._follower = new Follower({ context: this.context, diff --git a/Tone/component/dynamics/Limiter.ts b/Tone/component/dynamics/Limiter.ts index 0346299b..2d411b6a 100644 --- a/Tone/component/dynamics/Limiter.ts +++ b/Tone/component/dynamics/Limiter.ts @@ -44,16 +44,10 @@ export class Limiter extends ToneAudioNode { constructor(threshold?: Decibels); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(Limiter.getDefaults(), arguments, [ - "threshold", - ]) - ) - ); const options = optionsFromArguments(Limiter.getDefaults(), arguments, [ "threshold", ]); + super(options); this._compressor = this.input = diff --git a/Tone/component/dynamics/MidSideCompressor.ts b/Tone/component/dynamics/MidSideCompressor.ts index 9105b2ac..3ee0cacd 100644 --- a/Tone/component/dynamics/MidSideCompressor.ts +++ b/Tone/component/dynamics/MidSideCompressor.ts @@ -49,15 +49,11 @@ export class MidSideCompressor extends ToneAudioNode { constructor(options?: RecursivePartial); constructor() { - super( - Object.assign( - optionsFromArguments(MidSideCompressor.getDefaults(), arguments) - ) - ); const options = optionsFromArguments( MidSideCompressor.getDefaults(), arguments ); + super(options); this._midSideSplit = this.input = new MidSideSplit({ context: this.context, diff --git a/Tone/component/dynamics/MultibandCompressor.ts b/Tone/component/dynamics/MultibandCompressor.ts index 8290c4ad..190674d3 100644 --- a/Tone/component/dynamics/MultibandCompressor.ts +++ b/Tone/component/dynamics/MultibandCompressor.ts @@ -71,18 +71,11 @@ export class MultibandCompressor extends ToneAudioNode); constructor() { - super( - Object.assign( - optionsFromArguments( - MultibandCompressor.getDefaults(), - arguments - ) - ) - ); const options = optionsFromArguments( MultibandCompressor.getDefaults(), arguments ); + super(options); this._splitter = this.input = new MultibandSplit({ context: this.context, diff --git a/Tone/component/envelope/Envelope.ts b/Tone/component/envelope/Envelope.ts index d1d8baae..ba640275 100644 --- a/Tone/component/envelope/Envelope.ts +++ b/Tone/component/envelope/Envelope.ts @@ -186,19 +186,12 @@ export class Envelope extends ToneAudioNode { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Envelope.getDefaults(), arguments, [ - "attack", - "decay", - "sustain", - "release", - ]) - ); const options = optionsFromArguments( Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"] ); + super(options); this.attack = options.attack; this.decay = options.decay; diff --git a/Tone/component/envelope/FrequencyEnvelope.ts b/Tone/component/envelope/FrequencyEnvelope.ts index 47b0f50e..8a303fd7 100644 --- a/Tone/component/envelope/FrequencyEnvelope.ts +++ b/Tone/component/envelope/FrequencyEnvelope.ts @@ -62,19 +62,12 @@ export class FrequencyEnvelope extends Envelope { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(FrequencyEnvelope.getDefaults(), arguments, [ - "attack", - "decay", - "sustain", - "release", - ]) - ); const options = optionsFromArguments( FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"] ); + super(options); this._octaves = options.octaves; this._baseFrequency = this.toFrequency(options.baseFrequency); diff --git a/Tone/component/filter/BiquadFilter.ts b/Tone/component/filter/BiquadFilter.ts index af59bdbc..df3696ac 100644 --- a/Tone/component/filter/BiquadFilter.ts +++ b/Tone/component/filter/BiquadFilter.ts @@ -61,17 +61,12 @@ export class BiquadFilter extends ToneAudioNode { constructor(frequency?: Frequency, type?: BiquadFilterType); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(BiquadFilter.getDefaults(), arguments, [ - "frequency", - "type", - ]) - ); const options = optionsFromArguments( BiquadFilter.getDefaults(), arguments, ["frequency", "type"] ); + super(options); this._filter = this.context.createBiquadFilter(); this.input = this.output = this._filter; diff --git a/Tone/component/filter/Convolver.ts b/Tone/component/filter/Convolver.ts index b3fcd5bb..27ba1d28 100644 --- a/Tone/component/filter/Convolver.ts +++ b/Tone/component/filter/Convolver.ts @@ -50,17 +50,12 @@ export class Convolver extends ToneAudioNode { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Convolver.getDefaults(), arguments, [ - "url", - "onload", - ]) - ); const options = optionsFromArguments( Convolver.getDefaults(), arguments, ["url", "onload"] ); + super(options); this._buffer = new ToneAudioBuffer(options.url, (buffer) => { this.buffer = buffer; diff --git a/Tone/component/filter/EQ3.ts b/Tone/component/filter/EQ3.ts index 3380bee3..b25cedad 100644 --- a/Tone/component/filter/EQ3.ts +++ b/Tone/component/filter/EQ3.ts @@ -90,18 +90,12 @@ export class EQ3 extends ToneAudioNode { constructor(lowLevel?: Decibels, midLevel?: Decibels, highLevel?: Decibels); constructor(options: Partial); constructor() { - super( - optionsFromArguments(EQ3.getDefaults(), arguments, [ - "low", - "mid", - "high", - ]) - ); const options = optionsFromArguments(EQ3.getDefaults(), arguments, [ "low", "mid", "high", ]); + super(options); this.input = this._multibandSplit = new MultibandSplit({ context: this.context, diff --git a/Tone/component/filter/FeedbackCombFilter.ts b/Tone/component/filter/FeedbackCombFilter.ts index c5f48faf..151d6c4b 100644 --- a/Tone/component/filter/FeedbackCombFilter.ts +++ b/Tone/component/filter/FeedbackCombFilter.ts @@ -48,17 +48,12 @@ export class FeedbackCombFilter extends ToneAudioWorklet); constructor() { - super( - optionsFromArguments(FeedbackCombFilter.getDefaults(), arguments, [ - "delayTime", - "resonance", - ]) - ); const options = optionsFromArguments( FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"] ); + super(options); this.input = new Gain({ context: this.context }); this.output = new Gain({ context: this.context }); diff --git a/Tone/component/filter/Filter.ts b/Tone/component/filter/Filter.ts index 6ddaf7bc..1d58a851 100644 --- a/Tone/component/filter/Filter.ts +++ b/Tone/component/filter/Filter.ts @@ -73,18 +73,12 @@ export class Filter extends ToneAudioNode { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Filter.getDefaults(), arguments, [ - "frequency", - "type", - "rolloff", - ]) - ); const options = optionsFromArguments(Filter.getDefaults(), arguments, [ "frequency", "type", "rolloff", ]); + super(options); this._filters = []; diff --git a/Tone/component/filter/LowpassCombFilter.ts b/Tone/component/filter/LowpassCombFilter.ts index 2a6c1999..dfc2df6e 100644 --- a/Tone/component/filter/LowpassCombFilter.ts +++ b/Tone/component/filter/LowpassCombFilter.ts @@ -60,18 +60,12 @@ export class LowpassCombFilter extends ToneAudioNode { ); constructor(options?: RecursivePartial); constructor() { - super( - optionsFromArguments(LowpassCombFilter.getDefaults(), arguments, [ - "delayTime", - "resonance", - "dampening", - ]) - ); const options = optionsFromArguments( LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"] ); + super(options); this._combFilter = this.output = new FeedbackCombFilter({ context: this.context, diff --git a/Tone/component/filter/OnePoleFilter.ts b/Tone/component/filter/OnePoleFilter.ts index acf9d468..9cd6d404 100644 --- a/Tone/component/filter/OnePoleFilter.ts +++ b/Tone/component/filter/OnePoleFilter.ts @@ -51,17 +51,12 @@ export class OnePoleFilter extends ToneAudioNode { constructor(frequency?: Frequency, type?: OnePoleFilterType); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(OnePoleFilter.getDefaults(), arguments, [ - "frequency", - "type", - ]) - ); const options = optionsFromArguments( OnePoleFilter.getDefaults(), arguments, ["frequency", "type"] ); + super(options); this._frequency = options.frequency; this._type = options.type; diff --git a/Tone/core/clock/Clock.ts b/Tone/core/clock/Clock.ts index 1c34e95c..6e58f9c5 100644 --- a/Tone/core/clock/Clock.ts +++ b/Tone/core/clock/Clock.ts @@ -80,16 +80,11 @@ export class Clock constructor(callback?: ClockCallback, frequency?: Frequency); constructor(options: Partial); constructor() { - super( - optionsFromArguments(Clock.getDefaults(), arguments, [ - "callback", - "frequency", - ]) - ); const options = optionsFromArguments(Clock.getDefaults(), arguments, [ "callback", "frequency", ]); + super(options); this.callback = options.callback; this._tickSource = new TickSource({ diff --git a/Tone/core/clock/TickParam.ts b/Tone/core/clock/TickParam.ts index 94e41d99..c44ab7e7 100644 --- a/Tone/core/clock/TickParam.ts +++ b/Tone/core/clock/TickParam.ts @@ -44,14 +44,12 @@ export class TickParam< constructor(value?: number); constructor(options: Partial>); constructor() { - super( - optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]) - ); const options = optionsFromArguments( TickParam.getDefaults(), arguments, ["value"] ); + super(options); // set the multiplier this._multiplier = options.multiplier; diff --git a/Tone/core/clock/TickSignal.ts b/Tone/core/clock/TickSignal.ts index 9cccff77..f87011f0 100644 --- a/Tone/core/clock/TickSignal.ts +++ b/Tone/core/clock/TickSignal.ts @@ -36,14 +36,12 @@ export class TickSignal< constructor(value?: UnitMap[TypeName]); constructor(options: Partial>); constructor() { - super( - optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]) - ); const options = optionsFromArguments( TickSignal.getDefaults(), arguments, ["value"] ); + super(options); this.input = this._param = new TickParam({ context: this.context, diff --git a/Tone/core/clock/TickSource.ts b/Tone/core/clock/TickSource.ts index 490acf42..70c9cdff 100644 --- a/Tone/core/clock/TickSource.ts +++ b/Tone/core/clock/TickSource.ts @@ -79,16 +79,12 @@ export class TickSource< constructor(frequency?: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(TickSource.getDefaults(), arguments, [ - "frequency", - ]) - ); const options = optionsFromArguments( TickSource.getDefaults(), arguments, ["frequency"] ); + super(options); this.frequency = new TickSignal({ context: this.context, diff --git a/Tone/core/clock/Transport.ts b/Tone/core/clock/Transport.ts index ce8a2f72..0e73de00 100644 --- a/Tone/core/clock/Transport.ts +++ b/Tone/core/clock/Transport.ts @@ -188,11 +188,11 @@ export class TransportClass constructor(options?: Partial); constructor() { - super(optionsFromArguments(TransportClass.getDefaults(), arguments)); const options = optionsFromArguments( TransportClass.getDefaults(), arguments ); + super(options); // CLOCK/TEMPO this._ppq = options.ppq; diff --git a/Tone/core/context/Delay.ts b/Tone/core/context/Delay.ts index 7193728d..1a4783e1 100644 --- a/Tone/core/context/Delay.ts +++ b/Tone/core/context/Delay.ts @@ -54,17 +54,11 @@ export class Delay extends ToneAudioNode { constructor(delayTime?: Time, maxDelay?: Time); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Delay.getDefaults(), arguments, [ - "delayTime", - "maxDelay", - ]) - ); - const options = optionsFromArguments(Delay.getDefaults(), arguments, [ "delayTime", "maxDelay", ]); + super(options); const maxDelayInSeconds = this.toSeconds(options.maxDelay); this._maxDelay = Math.max( diff --git a/Tone/core/context/Destination.ts b/Tone/core/context/Destination.ts index d533f4df..c2a1fba8 100644 --- a/Tone/core/context/Destination.ts +++ b/Tone/core/context/Destination.ts @@ -48,11 +48,11 @@ export class DestinationClass extends ToneAudioNode { constructor(options: Partial); constructor() { - super(optionsFromArguments(DestinationClass.getDefaults(), arguments)); const options = optionsFromArguments( DestinationClass.getDefaults(), arguments ); + super(options); connectSeries( this.input, diff --git a/Tone/core/context/Gain.ts b/Tone/core/context/Gain.ts index 88a59563..930a911a 100644 --- a/Tone/core/context/Gain.ts +++ b/Tone/core/context/Gain.ts @@ -56,16 +56,11 @@ export class Gain< constructor(gain?: UnitMap[TypeName], units?: TypeName); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Gain.getDefaults(), arguments, [ - "gain", - "units", - ]) - ); const options = optionsFromArguments(Gain.getDefaults(), arguments, [ "gain", "units", ]); + super(options); this.gain = new Param({ context: this.context, diff --git a/Tone/core/context/Param.ts b/Tone/core/context/Param.ts index f6be71ca..56c27ae6 100644 --- a/Tone/core/context/Param.ts +++ b/Tone/core/context/Param.ts @@ -113,19 +113,12 @@ export class Param constructor(param: AudioParam, units?: TypeName, convert?: boolean); constructor(options: Partial>); constructor() { - super( - optionsFromArguments(Param.getDefaults(), arguments, [ - "param", - "units", - "convert", - ]) - ); - const options = optionsFromArguments(Param.getDefaults(), arguments, [ "param", "units", "convert", ]); + super(options); assert( isDefined(options.param) && diff --git a/Tone/effect/AutoFilter.ts b/Tone/effect/AutoFilter.ts index b67f3758..d03e9cba 100644 --- a/Tone/effect/AutoFilter.ts +++ b/Tone/effect/AutoFilter.ts @@ -50,18 +50,12 @@ export class AutoFilter extends LFOEffect { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(AutoFilter.getDefaults(), arguments, [ - "frequency", - "baseFrequency", - "octaves", - ]) - ); const options = optionsFromArguments( AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"] ); + super(options); this.filter = new Filter( Object.assign(options.filter, { diff --git a/Tone/effect/AutoPanner.ts b/Tone/effect/AutoPanner.ts index 34aa82d4..278db1f5 100644 --- a/Tone/effect/AutoPanner.ts +++ b/Tone/effect/AutoPanner.ts @@ -32,16 +32,12 @@ export class AutoPanner extends LFOEffect { constructor(frequency?: Frequency); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(AutoPanner.getDefaults(), arguments, [ - "frequency", - ]) - ); const options = optionsFromArguments( AutoPanner.getDefaults(), arguments, ["frequency"] ); + super(options); this._panner = new Panner({ context: this.context, diff --git a/Tone/effect/AutoWah.ts b/Tone/effect/AutoWah.ts index ece8b670..a32d6c03 100644 --- a/Tone/effect/AutoWah.ts +++ b/Tone/effect/AutoWah.ts @@ -101,18 +101,12 @@ export class AutoWah extends Effect { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(AutoWah.getDefaults(), arguments, [ - "baseFrequency", - "octaves", - "sensitivity", - ]) - ); const options = optionsFromArguments(AutoWah.getDefaults(), arguments, [ "baseFrequency", "octaves", "sensitivity", ]); + super(options); this._follower = new Follower({ context: this.context, diff --git a/Tone/effect/BitCrusher.ts b/Tone/effect/BitCrusher.ts index aa86fd46..6557fa75 100644 --- a/Tone/effect/BitCrusher.ts +++ b/Tone/effect/BitCrusher.ts @@ -44,14 +44,12 @@ export class BitCrusher extends Effect { constructor(bits?: Positive); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]) - ); const options = optionsFromArguments( BitCrusher.getDefaults(), arguments, ["bits"] ); + super(options); this._bitCrusherWorklet = new BitCrusherWorklet({ context: this.context, @@ -93,11 +91,11 @@ class BitCrusherWorklet extends ToneAudioWorklet { constructor(options?: Partial); constructor() { - super(optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments)); const options = optionsFromArguments( BitCrusherWorklet.getDefaults(), arguments ); + super(options); this.input = new Gain({ context: this.context }); this.output = new Gain({ context: this.context }); diff --git a/Tone/effect/Chebyshev.ts b/Tone/effect/Chebyshev.ts index f2f0ac05..e4d29d35 100644 --- a/Tone/effect/Chebyshev.ts +++ b/Tone/effect/Chebyshev.ts @@ -42,14 +42,12 @@ export class Chebyshev extends Effect { constructor(order?: Positive); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]) - ); const options = optionsFromArguments( Chebyshev.getDefaults(), arguments, ["order"] ); + super(options); this._shaper = new WaveShaper({ context: this.context, diff --git a/Tone/effect/Chorus.ts b/Tone/effect/Chorus.ts index aa6a18dc..5fa92c96 100644 --- a/Tone/effect/Chorus.ts +++ b/Tone/effect/Chorus.ts @@ -88,18 +88,12 @@ export class Chorus extends StereoFeedbackEffect { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Chorus.getDefaults(), arguments, [ - "frequency", - "delayTime", - "depth", - ]) - ); const options = optionsFromArguments(Chorus.getDefaults(), arguments, [ "frequency", "delayTime", "depth", ]); + super(options); this._depth = options.depth; this._delayTime = options.delayTime / 1000; diff --git a/Tone/effect/Distortion.ts b/Tone/effect/Distortion.ts index b07af346..f4e59b18 100644 --- a/Tone/effect/Distortion.ts +++ b/Tone/effect/Distortion.ts @@ -36,16 +36,12 @@ export class Distortion extends Effect { constructor(distortion?: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Distortion.getDefaults(), arguments, [ - "distortion", - ]) - ); const options = optionsFromArguments( Distortion.getDefaults(), arguments, ["distortion"] ); + super(options); this._shaper = new WaveShaper({ context: this.context, diff --git a/Tone/effect/FeedbackDelay.ts b/Tone/effect/FeedbackDelay.ts index 65b9c8a2..e0f71fb4 100644 --- a/Tone/effect/FeedbackDelay.ts +++ b/Tone/effect/FeedbackDelay.ts @@ -40,17 +40,12 @@ export class FeedbackDelay extends FeedbackEffect { constructor(delayTime?: Time, feedback?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(FeedbackDelay.getDefaults(), arguments, [ - "delayTime", - "feedback", - ]) - ); const options = optionsFromArguments( FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"] ); + super(options); this._delayNode = new Delay({ context: this.context, diff --git a/Tone/effect/Freeverb.ts b/Tone/effect/Freeverb.ts index 277e2c14..abc6ddc0 100644 --- a/Tone/effect/Freeverb.ts +++ b/Tone/effect/Freeverb.ts @@ -71,17 +71,12 @@ export class Freeverb extends StereoEffect { constructor(roomSize?: NormalRange, dampening?: Frequency); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Freeverb.getDefaults(), arguments, [ - "roomSize", - "dampening", - ]) - ); const options = optionsFromArguments( Freeverb.getDefaults(), arguments, ["roomSize", "dampening"] ); + super(options); this.roomSize = new Signal({ context: this.context, diff --git a/Tone/effect/FrequencyShifter.ts b/Tone/effect/FrequencyShifter.ts index 4836c0ac..6c841ec4 100644 --- a/Tone/effect/FrequencyShifter.ts +++ b/Tone/effect/FrequencyShifter.ts @@ -81,16 +81,12 @@ export class FrequencyShifter extends Effect { constructor(frequency?: Frequency); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(FrequencyShifter.getDefaults(), arguments, [ - "frequency", - ]) - ); const options = optionsFromArguments( FrequencyShifter.getDefaults(), arguments, ["frequency"] ); + super(options); this.frequency = new Signal({ context: this.context, diff --git a/Tone/effect/JCReverb.ts b/Tone/effect/JCReverb.ts index cffb0273..a980f317 100644 --- a/Tone/effect/JCReverb.ts +++ b/Tone/effect/JCReverb.ts @@ -73,16 +73,12 @@ export class JCReverb extends StereoEffect { constructor(roomSize?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(JCReverb.getDefaults(), arguments, [ - "roomSize", - ]) - ); const options = optionsFromArguments( JCReverb.getDefaults(), arguments, ["roomSize"] ); + super(options); this.roomSize = new Signal({ context: this.context, diff --git a/Tone/effect/Phaser.ts b/Tone/effect/Phaser.ts index ad37e22a..589734b7 100644 --- a/Tone/effect/Phaser.ts +++ b/Tone/effect/Phaser.ts @@ -83,18 +83,12 @@ export class Phaser extends StereoEffect { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Phaser.getDefaults(), arguments, [ - "frequency", - "octaves", - "baseFrequency", - ]) - ); const options = optionsFromArguments(Phaser.getDefaults(), arguments, [ "frequency", "octaves", "baseFrequency", ]); + super(options); this._lfoL = new LFO({ context: this.context, diff --git a/Tone/effect/PingPongDelay.ts b/Tone/effect/PingPongDelay.ts index 69504ab6..798ac86f 100644 --- a/Tone/effect/PingPongDelay.ts +++ b/Tone/effect/PingPongDelay.ts @@ -57,17 +57,12 @@ export class PingPongDelay extends StereoXFeedbackEffect { constructor(delayTime?: Time, feedback?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(PingPongDelay.getDefaults(), arguments, [ - "delayTime", - "feedback", - ]) - ); const options = optionsFromArguments( PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"] ); + super(options); this._leftDelay = new Delay({ context: this.context, diff --git a/Tone/effect/PitchShift.ts b/Tone/effect/PitchShift.ts index a62e01b3..5b3e9d97 100644 --- a/Tone/effect/PitchShift.ts +++ b/Tone/effect/PitchShift.ts @@ -88,14 +88,12 @@ export class PitchShift extends FeedbackEffect { constructor(pitch?: Interval); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]) - ); const options = optionsFromArguments( PitchShift.getDefaults(), arguments, ["pitch"] ); + super(options); this._frequency = new Signal({ context: this.context }); this._delayA = new Delay({ diff --git a/Tone/effect/Reverb.ts b/Tone/effect/Reverb.ts index 4a49fc9a..b9956075 100644 --- a/Tone/effect/Reverb.ts +++ b/Tone/effect/Reverb.ts @@ -56,10 +56,10 @@ export class Reverb extends Effect { constructor(decay?: Seconds); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"])); const options = optionsFromArguments(Reverb.getDefaults(), arguments, [ "decay", ]); + super(options); this._decay = options.decay; this._preDelay = options.preDelay; diff --git a/Tone/effect/StereoWidener.ts b/Tone/effect/StereoWidener.ts index af4b3f6a..04a76e5c 100644 --- a/Tone/effect/StereoWidener.ts +++ b/Tone/effect/StereoWidener.ts @@ -63,16 +63,13 @@ export class StereoWidener extends MidSideEffect { constructor(width?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(StereoWidener.getDefaults(), arguments, [ - "width", - ]) - ); const options = optionsFromArguments( StereoWidener.getDefaults(), arguments, ["width"] ); + super(options); + this.width = new Signal({ context: this.context, value: options.width, diff --git a/Tone/effect/Tremolo.ts b/Tone/effect/Tremolo.ts index 38cd15eb..3809d615 100644 --- a/Tone/effect/Tremolo.ts +++ b/Tone/effect/Tremolo.ts @@ -68,16 +68,11 @@ export class Tremolo extends StereoEffect { constructor(frequency?: Frequency, depth?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Tremolo.getDefaults(), arguments, [ - "frequency", - "depth", - ]) - ); const options = optionsFromArguments(Tremolo.getDefaults(), arguments, [ "frequency", "depth", ]); + super(options); this._lfoL = new LFO({ context: this.context, diff --git a/Tone/effect/Vibrato.ts b/Tone/effect/Vibrato.ts index 34d354c9..4dc760e7 100644 --- a/Tone/effect/Vibrato.ts +++ b/Tone/effect/Vibrato.ts @@ -48,16 +48,11 @@ export class Vibrato extends Effect { constructor(frequency?: Frequency, depth?: NormalRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Vibrato.getDefaults(), arguments, [ - "frequency", - "depth", - ]) - ); const options = optionsFromArguments(Vibrato.getDefaults(), arguments, [ "frequency", "depth", ]); + super(options); this._delayNode = new Delay({ context: this.context, diff --git a/Tone/event/Loop.ts b/Tone/event/Loop.ts index f629afa9..bffa5f50 100644 --- a/Tone/event/Loop.ts +++ b/Tone/event/Loop.ts @@ -59,16 +59,11 @@ export class Loop< constructor(callback?: (time: Seconds) => void, interval?: Time); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Loop.getDefaults(), arguments, [ - "callback", - "interval", - ]) - ); const options = optionsFromArguments(Loop.getDefaults(), arguments, [ "callback", "interval", ]); + super(options); this._event = new ToneEvent({ context: this.context, diff --git a/Tone/event/Part.ts b/Tone/event/Part.ts index b849815e..f651303a 100644 --- a/Tone/event/Part.ts +++ b/Tone/event/Part.ts @@ -83,16 +83,11 @@ export class Part extends ToneEvent { ); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Part.getDefaults(), arguments, [ - "callback", - "events", - ]) - ); const options = optionsFromArguments(Part.getDefaults(), arguments, [ "callback", "events", ]); + super(options); // make sure things are assigned in the right order this._state.increasing = true; diff --git a/Tone/event/Pattern.ts b/Tone/event/Pattern.ts index 99a68976..a84c3406 100644 --- a/Tone/event/Pattern.ts +++ b/Tone/event/Pattern.ts @@ -65,18 +65,12 @@ export class Pattern extends Loop> { ); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Pattern.getDefaults(), arguments, [ - "callback", - "values", - "pattern", - ]) - ); const options = optionsFromArguments(Pattern.getDefaults(), arguments, [ "callback", "values", "pattern", ]); + super(options); this.callback = options.callback; this._values = options.values; diff --git a/Tone/event/Sequence.ts b/Tone/event/Sequence.ts index 7fe71339..8826d85c 100644 --- a/Tone/event/Sequence.ts +++ b/Tone/event/Sequence.ts @@ -75,18 +75,12 @@ export class Sequence extends ToneEvent { ); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Sequence.getDefaults(), arguments, [ - "callback", - "events", - "subdivision", - ]) - ); const options = optionsFromArguments( Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"] ); + super(options); this._subdivision = this.toTicks(options.subdivision); diff --git a/Tone/event/ToneEvent.ts b/Tone/event/ToneEvent.ts index de698d2c..8ec857d5 100644 --- a/Tone/event/ToneEvent.ts +++ b/Tone/event/ToneEvent.ts @@ -124,17 +124,12 @@ export class ToneEvent extends ToneWithContext< constructor(callback?: ToneEventCallback, value?: ValueType); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(ToneEvent.getDefaults(), arguments, [ - "callback", - "value", - ]) - ); const options = optionsFromArguments( ToneEvent.getDefaults(), arguments, ["callback", "value"] ); + super(options); this._loop = options.loop; this.callback = options.callback; diff --git a/Tone/instrument/DuoSynth.ts b/Tone/instrument/DuoSynth.ts index 22d52c37..51cf9ac3 100644 --- a/Tone/instrument/DuoSynth.ts +++ b/Tone/instrument/DuoSynth.ts @@ -84,8 +84,8 @@ export class DuoSynth extends Monophonic { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(DuoSynth.getDefaults(), arguments)); const options = optionsFromArguments(DuoSynth.getDefaults(), arguments); + super(options); this.voice0 = new MonoSynth( Object.assign(options.voice0, { diff --git a/Tone/instrument/FMSynth.ts b/Tone/instrument/FMSynth.ts index 15642519..8a292d77 100644 --- a/Tone/instrument/FMSynth.ts +++ b/Tone/instrument/FMSynth.ts @@ -33,8 +33,8 @@ export class FMSynth extends ModulationSynth { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(FMSynth.getDefaults(), arguments)); const options = optionsFromArguments(FMSynth.getDefaults(), arguments); + super(options); this.modulationIndex = new Multiply({ context: this.context, diff --git a/Tone/instrument/Instrument.ts b/Tone/instrument/Instrument.ts index dd96760c..12124791 100644 --- a/Tone/instrument/Instrument.ts +++ b/Tone/instrument/Instrument.ts @@ -52,11 +52,11 @@ export abstract class Instrument< constructor(options?: Partial); constructor() { - super(optionsFromArguments(Instrument.getDefaults(), arguments)); const options = optionsFromArguments( Instrument.getDefaults(), arguments ); + super(options); this._volume = this.output = new Volume({ context: this.context, diff --git a/Tone/instrument/MembraneSynth.ts b/Tone/instrument/MembraneSynth.ts index 23ad8523..7e1d65a8 100644 --- a/Tone/instrument/MembraneSynth.ts +++ b/Tone/instrument/MembraneSynth.ts @@ -53,11 +53,11 @@ export class MembraneSynth extends Synth { */ constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(MembraneSynth.getDefaults(), arguments)); const options = optionsFromArguments( MembraneSynth.getDefaults(), arguments ); + super(options); this.pitchDecay = options.pitchDecay; this.octaves = options.octaves; diff --git a/Tone/instrument/MetalSynth.ts b/Tone/instrument/MetalSynth.ts index 71f745f6..6cea729f 100644 --- a/Tone/instrument/MetalSynth.ts +++ b/Tone/instrument/MetalSynth.ts @@ -97,11 +97,11 @@ export class MetalSynth extends Monophonic { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(MetalSynth.getDefaults(), arguments)); const options = optionsFromArguments( MetalSynth.getDefaults(), arguments ); + super(options); this.detune = new Signal({ context: this.context, diff --git a/Tone/instrument/ModulationSynth.ts b/Tone/instrument/ModulationSynth.ts index af743ff0..adc02e98 100644 --- a/Tone/instrument/ModulationSynth.ts +++ b/Tone/instrument/ModulationSynth.ts @@ -88,11 +88,11 @@ export abstract class ModulationSynth< constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(ModulationSynth.getDefaults(), arguments)); const options = optionsFromArguments( ModulationSynth.getDefaults(), arguments ); + super(options); this._carrier = new Synth({ context: this.context, diff --git a/Tone/instrument/MonoSynth.ts b/Tone/instrument/MonoSynth.ts index 0f3fc0a5..12aaf21a 100644 --- a/Tone/instrument/MonoSynth.ts +++ b/Tone/instrument/MonoSynth.ts @@ -77,11 +77,11 @@ export class MonoSynth extends Monophonic { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(MonoSynth.getDefaults(), arguments)); const options = optionsFromArguments( MonoSynth.getDefaults(), arguments ); + super(options); this.oscillator = new OmniOscillator( Object.assign(options.oscillator, { diff --git a/Tone/instrument/Monophonic.ts b/Tone/instrument/Monophonic.ts index 27508042..83c1aa69 100644 --- a/Tone/instrument/Monophonic.ts +++ b/Tone/instrument/Monophonic.ts @@ -49,11 +49,11 @@ export abstract class Monophonic< constructor(options?: Partial); constructor() { - super(optionsFromArguments(Monophonic.getDefaults(), arguments)); const options = optionsFromArguments( Monophonic.getDefaults(), arguments ); + super(options); this.portamento = options.portamento; this.onsilence = options.onsilence; diff --git a/Tone/instrument/NoiseSynth.ts b/Tone/instrument/NoiseSynth.ts index c465f141..fb78e9fd 100644 --- a/Tone/instrument/NoiseSynth.ts +++ b/Tone/instrument/NoiseSynth.ts @@ -43,11 +43,12 @@ export class NoiseSynth extends Instrument { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(NoiseSynth.getDefaults(), arguments)); const options = optionsFromArguments( NoiseSynth.getDefaults(), arguments ); + super(options); + this.noise = new Noise( Object.assign( { diff --git a/Tone/instrument/PluckSynth.ts b/Tone/instrument/PluckSynth.ts index ac9e404e..834d1898 100644 --- a/Tone/instrument/PluckSynth.ts +++ b/Tone/instrument/PluckSynth.ts @@ -52,11 +52,11 @@ export class PluckSynth extends Instrument { constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(PluckSynth.getDefaults(), arguments)); const options = optionsFromArguments( PluckSynth.getDefaults(), arguments ); + super(options); this._noise = new Noise({ context: this.context, diff --git a/Tone/instrument/PolySynth.ts b/Tone/instrument/PolySynth.ts index f40825c1..b5b3feb9 100644 --- a/Tone/instrument/PolySynth.ts +++ b/Tone/instrument/PolySynth.ts @@ -137,17 +137,12 @@ export class PolySynth< ); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(PolySynth.getDefaults(), arguments, [ - "voice", - "options", - ]) - ); const options = optionsFromArguments( PolySynth.getDefaults(), arguments, ["voice", "options"] ); + super(options); // check against the old API (pre 14.3.0) assert( diff --git a/Tone/instrument/Sampler.ts b/Tone/instrument/Sampler.ts index da7ff263..0f190588 100644 --- a/Tone/instrument/Sampler.ts +++ b/Tone/instrument/Sampler.ts @@ -110,20 +110,13 @@ export class Sampler extends Instrument { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments( - Sampler.getDefaults(), - arguments, - ["urls", "onload", "baseUrl"], - "urls" - ) - ); const options = optionsFromArguments( Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls" ); + super(options); const urlMap = {}; Object.keys(options.urls).forEach((note) => { diff --git a/Tone/instrument/Synth.ts b/Tone/instrument/Synth.ts index ed47f675..7f8cc2c0 100644 --- a/Tone/instrument/Synth.ts +++ b/Tone/instrument/Synth.ts @@ -64,8 +64,8 @@ export class Synth< */ constructor(options?: RecursivePartial); constructor() { - super(optionsFromArguments(Synth.getDefaults(), arguments)); const options = optionsFromArguments(Synth.getDefaults(), arguments); + super(options); this.oscillator = new OmniOscillator( Object.assign( diff --git a/Tone/signal/Add.ts b/Tone/signal/Add.ts index 903bdd67..3ab734b2 100644 --- a/Tone/signal/Add.ts +++ b/Tone/signal/Add.ts @@ -43,11 +43,7 @@ export class Add extends Signal { constructor(value?: number); constructor(options?: Partial>); constructor() { - super( - Object.assign( - optionsFromArguments(Add.getDefaults(), arguments, ["value"]) - ) - ); + super(optionsFromArguments(Add.getDefaults(), arguments, ["value"])); connectSeries(this._constantSource, this._sum); } diff --git a/Tone/signal/GreaterThan.ts b/Tone/signal/GreaterThan.ts index 9e2b88d4..463a8225 100644 --- a/Tone/signal/GreaterThan.ts +++ b/Tone/signal/GreaterThan.ts @@ -55,18 +55,12 @@ export class GreaterThan extends Signal<"number"> { constructor(value?: number); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(GreaterThan.getDefaults(), arguments, [ - "value", - ]) - ) - ); const options = optionsFromArguments( GreaterThan.getDefaults(), arguments, ["value"] ); + super(options); this._subtract = this.input = new Subtract({ context: this.context, diff --git a/Tone/signal/GreaterThanZero.ts b/Tone/signal/GreaterThanZero.ts index 0c7855e5..7023a3ce 100644 --- a/Tone/signal/GreaterThanZero.ts +++ b/Tone/signal/GreaterThanZero.ts @@ -35,11 +35,7 @@ export class GreaterThanZero extends SignalOperator { constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(GreaterThanZero.getDefaults(), arguments) - ) - ); + super(optionsFromArguments(GreaterThanZero.getDefaults(), arguments)); this._thresh = this.output = new WaveShaper({ context: this.context, diff --git a/Tone/signal/Multiply.ts b/Tone/signal/Multiply.ts index 7df6ce02..ddeaadc8 100644 --- a/Tone/signal/Multiply.ts +++ b/Tone/signal/Multiply.ts @@ -59,18 +59,12 @@ export class Multiply< constructor(value?: number); constructor(options?: Partial>); constructor() { - super( - Object.assign( - optionsFromArguments(Multiply.getDefaults(), arguments, [ - "value", - ]) - ) - ); const options = optionsFromArguments( Multiply.getDefaults(), arguments, ["value"] ); + super(options); this._mult = this.input = diff --git a/Tone/signal/Pow.ts b/Tone/signal/Pow.ts index ce2c366d..7b250150 100644 --- a/Tone/signal/Pow.ts +++ b/Tone/signal/Pow.ts @@ -33,14 +33,10 @@ export class Pow extends SignalOperator { constructor(value?: number); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(Pow.getDefaults(), arguments, ["value"]) - ) - ); const options = optionsFromArguments(Pow.getDefaults(), arguments, [ "value", ]); + super(options); this._exponentScaler = this.input = diff --git a/Tone/signal/Scale.ts b/Tone/signal/Scale.ts index cd020197..a2172b6f 100644 --- a/Tone/signal/Scale.ts +++ b/Tone/signal/Scale.ts @@ -59,18 +59,11 @@ export class Scale< constructor(min?: number, max?: number); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(Scale.getDefaults(), arguments, [ - "min", - "max", - ]) - ) - ); const options = optionsFromArguments(Scale.getDefaults(), arguments, [ "min", "max", ]); + super(options as Options); this._mult = this.input = new Multiply({ context: this.context, diff --git a/Tone/signal/ScaleExp.ts b/Tone/signal/ScaleExp.ts index 9aa8f837..ae23bb34 100644 --- a/Tone/signal/ScaleExp.ts +++ b/Tone/signal/ScaleExp.ts @@ -32,20 +32,12 @@ export class ScaleExp extends Scale { constructor(min?: number, max?: number, exponent?: number); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(ScaleExp.getDefaults(), arguments, [ - "min", - "max", - "exponent", - ]) - ) - ); const options = optionsFromArguments( ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"] ); + super(options); this.input = this._exp = new Pow({ context: this.context, diff --git a/Tone/signal/Signal.ts b/Tone/signal/Signal.ts index f1e52074..830c707e 100644 --- a/Tone/signal/Signal.ts +++ b/Tone/signal/Signal.ts @@ -66,17 +66,11 @@ export class Signal constructor(value?: UnitMap[TypeName], units?: TypeName); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Signal.getDefaults(), arguments, [ - "value", - "units", - ]) - ); - const options = optionsFromArguments(Signal.getDefaults(), arguments, [ "value", "units", ]) as SignalOptions; + super(options); this.output = this._constantSource = new ToneConstantSource({ context: this.context, diff --git a/Tone/signal/SignalOperator.ts b/Tone/signal/SignalOperator.ts index e920db8d..9b9bd4bf 100644 --- a/Tone/signal/SignalOperator.ts +++ b/Tone/signal/SignalOperator.ts @@ -17,11 +17,9 @@ export abstract class SignalOperator< constructor(options?: Partial); constructor() { super( - Object.assign( - optionsFromArguments(SignalOperator.getDefaults(), arguments, [ - "context", - ]) - ) + optionsFromArguments(SignalOperator.getDefaults(), arguments, [ + "context", + ]) ); } diff --git a/Tone/signal/Subtract.ts b/Tone/signal/Subtract.ts index c350ac0f..9a5678f3 100644 --- a/Tone/signal/Subtract.ts +++ b/Tone/signal/Subtract.ts @@ -54,11 +54,7 @@ export class Subtract extends Signal { constructor(options?: Partial>); constructor() { super( - Object.assign( - optionsFromArguments(Subtract.getDefaults(), arguments, [ - "value", - ]) - ) + optionsFromArguments(Subtract.getDefaults(), arguments, ["value"]) ); connectSeries(this._constantSource, this._neg, this._sum); diff --git a/Tone/signal/SyncedSignal.ts b/Tone/signal/SyncedSignal.ts index be373f80..082877d2 100644 --- a/Tone/signal/SyncedSignal.ts +++ b/Tone/signal/SyncedSignal.ts @@ -51,16 +51,11 @@ export class SyncedSignal< constructor(value?: UnitMap[TypeName], units?: TypeName); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(Signal.getDefaults(), arguments, [ - "value", - "units", - ]) - ); const options = optionsFromArguments(Signal.getDefaults(), arguments, [ "value", "units", ]) as SignalOptions; + super(options); this._lastVal = options.value; this._synced = this.context.transport.scheduleRepeat( diff --git a/Tone/signal/ToneConstantSource.ts b/Tone/signal/ToneConstantSource.ts index a012059d..0f4be4b5 100644 --- a/Tone/signal/ToneConstantSource.ts +++ b/Tone/signal/ToneConstantSource.ts @@ -42,16 +42,12 @@ export class ToneConstantSource< constructor(offset: UnitMap[TypeName]); constructor(options?: Partial>); constructor() { - super( - optionsFromArguments(ToneConstantSource.getDefaults(), arguments, [ - "offset", - ]) - ); const options = optionsFromArguments( ToneConstantSource.getDefaults(), arguments, ["offset"] ); + super(options); connect(this._source, this._gainNode); diff --git a/Tone/signal/WaveShaper.ts b/Tone/signal/WaveShaper.ts index 5f59274d..afa6d9e5 100644 --- a/Tone/signal/WaveShaper.ts +++ b/Tone/signal/WaveShaper.ts @@ -59,19 +59,12 @@ export class WaveShaper extends SignalOperator { constructor(mapping?: WaveShaperMapping, length?: number); constructor(options?: Partial); constructor() { - super( - Object.assign( - optionsFromArguments(WaveShaper.getDefaults(), arguments, [ - "mapping", - "length", - ]) - ) - ); const options = optionsFromArguments( WaveShaper.getDefaults(), arguments, ["mapping", "length"] ); + super(options); if ( isArray(options.mapping) || diff --git a/Tone/signal/Zero.ts b/Tone/signal/Zero.ts index 93717787..2ba3a32f 100644 --- a/Tone/signal/Zero.ts +++ b/Tone/signal/Zero.ts @@ -33,9 +33,7 @@ export class Zero extends SignalOperator { constructor(options?: Partial); constructor() { - super( - Object.assign(optionsFromArguments(Zero.getDefaults(), arguments)) - ); + super(optionsFromArguments(Zero.getDefaults(), arguments)); connect(this.context.getConstant(0), this._gain); } diff --git a/Tone/source/Noise.ts b/Tone/source/Noise.ts index 62a32e5d..dcb9bccd 100644 --- a/Tone/source/Noise.ts +++ b/Tone/source/Noise.ts @@ -69,10 +69,10 @@ export class Noise extends Source { constructor(type?: NoiseType); constructor(options?: Partial); constructor() { - super(optionsFromArguments(Noise.getDefaults(), arguments, ["type"])); const options = optionsFromArguments(Noise.getDefaults(), arguments, [ "type", ]); + super(options); this._playbackRate = options.playbackRate; this.type = options.type; diff --git a/Tone/source/UserMedia.ts b/Tone/source/UserMedia.ts index be7bf84f..7e41c963 100644 --- a/Tone/source/UserMedia.ts +++ b/Tone/source/UserMedia.ts @@ -73,14 +73,12 @@ export class UserMedia extends ToneAudioNode { constructor(volume?: Decibels); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]) - ); const options = optionsFromArguments( UserMedia.getDefaults(), arguments, ["volume"] ); + super(options); this._volume = this.output = new Volume({ context: this.context, diff --git a/Tone/source/buffer/GrainPlayer.ts b/Tone/source/buffer/GrainPlayer.ts index 8723c63d..2b0cebea 100644 --- a/Tone/source/buffer/GrainPlayer.ts +++ b/Tone/source/buffer/GrainPlayer.ts @@ -92,17 +92,12 @@ export class GrainPlayer extends Source { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(GrainPlayer.getDefaults(), arguments, [ - "url", - "onload", - ]) - ); const options = optionsFromArguments( GrainPlayer.getDefaults(), arguments, ["url", "onload"] ); + super(options); this.buffer = new ToneAudioBuffer({ onload: options.onload, diff --git a/Tone/source/buffer/Player.ts b/Tone/source/buffer/Player.ts index 2b81adc0..7167aef9 100644 --- a/Tone/source/buffer/Player.ts +++ b/Tone/source/buffer/Player.ts @@ -91,16 +91,11 @@ export class Player extends Source { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Player.getDefaults(), arguments, [ - "url", - "onload", - ]) - ); const options = optionsFromArguments(Player.getDefaults(), arguments, [ "url", "onload", ]); + super(options); this._buffer = new ToneAudioBuffer({ onload: this._onload.bind(this, options.onload), diff --git a/Tone/source/buffer/Players.ts b/Tone/source/buffer/Players.ts index cafaf7dc..19e34e4b 100644 --- a/Tone/source/buffer/Players.ts +++ b/Tone/source/buffer/Players.ts @@ -87,20 +87,13 @@ export class Players extends ToneAudioNode { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments( - Players.getDefaults(), - arguments, - ["urls", "onload"], - "urls" - ) - ); const options = optionsFromArguments( Players.getDefaults(), arguments, ["urls", "onload"], "urls" ); + super(options); /** * The output volume node diff --git a/Tone/source/buffer/ToneBufferSource.ts b/Tone/source/buffer/ToneBufferSource.ts index b15d8c59..88573ef9 100644 --- a/Tone/source/buffer/ToneBufferSource.ts +++ b/Tone/source/buffer/ToneBufferSource.ts @@ -67,17 +67,12 @@ export class ToneBufferSource extends OneShotSource { ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(ToneBufferSource.getDefaults(), arguments, [ - "url", - "onload", - ]) - ); const options = optionsFromArguments( ToneBufferSource.getDefaults(), arguments, ["url", "onload"] ); + super(options); connect(this._source, this._gainNode); this._source.onended = () => this._stopSource(); diff --git a/Tone/source/oscillator/AMOscillator.ts b/Tone/source/oscillator/AMOscillator.ts index e5e007ed..b2f298d8 100644 --- a/Tone/source/oscillator/AMOscillator.ts +++ b/Tone/source/oscillator/AMOscillator.ts @@ -97,18 +97,12 @@ export class AMOscillator ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(AMOscillator.getDefaults(), arguments, [ - "frequency", - "type", - "modulationType", - ]) - ); const options = optionsFromArguments( AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"] ); + super(options); this._carrier = new Oscillator({ context: this.context, diff --git a/Tone/source/oscillator/FMOscillator.ts b/Tone/source/oscillator/FMOscillator.ts index ee5ff080..7c787fce 100644 --- a/Tone/source/oscillator/FMOscillator.ts +++ b/Tone/source/oscillator/FMOscillator.ts @@ -99,18 +99,12 @@ export class FMOscillator ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(FMOscillator.getDefaults(), arguments, [ - "frequency", - "type", - "modulationType", - ]) - ); const options = optionsFromArguments( FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"] ); + super(options); this._carrier = new Oscillator({ context: this.context, diff --git a/Tone/source/oscillator/FatOscillator.ts b/Tone/source/oscillator/FatOscillator.ts index f1dcc8d2..2b52d93b 100644 --- a/Tone/source/oscillator/FatOscillator.ts +++ b/Tone/source/oscillator/FatOscillator.ts @@ -79,18 +79,12 @@ export class FatOscillator ); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(FatOscillator.getDefaults(), arguments, [ - "frequency", - "type", - "spread", - ]) - ); const options = optionsFromArguments( FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"] ); + super(options); this.frequency = new Signal({ context: this.context, diff --git a/Tone/source/oscillator/LFO.ts b/Tone/source/oscillator/LFO.ts index bc8d1f7b..5c16b9a5 100644 --- a/Tone/source/oscillator/LFO.ts +++ b/Tone/source/oscillator/LFO.ts @@ -124,18 +124,12 @@ export class LFO extends ToneAudioNode { constructor(frequency?: Frequency, min?: number, max?: number); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(LFO.getDefaults(), arguments, [ - "frequency", - "min", - "max", - ]) - ); const options = optionsFromArguments(LFO.getDefaults(), arguments, [ "frequency", "min", "max", ]); + super(options); this._oscillator = new Oscillator( options as ToneOscillatorConstructorOptions diff --git a/Tone/source/oscillator/OmniOscillator.ts b/Tone/source/oscillator/OmniOscillator.ts index 9c1d16b2..7f121712 100644 --- a/Tone/source/oscillator/OmniOscillator.ts +++ b/Tone/source/oscillator/OmniOscillator.ts @@ -114,17 +114,12 @@ export class OmniOscillator constructor(frequency?: Frequency, type?: OmniOscillatorType); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(OmniOscillator.getDefaults(), arguments, [ - "frequency", - "type", - ]) - ); const options = optionsFromArguments( OmniOscillator.getDefaults(), arguments, ["frequency", "type"] ); + super(options); this.frequency = new Signal({ context: this.context, diff --git a/Tone/source/oscillator/Oscillator.ts b/Tone/source/oscillator/Oscillator.ts index e661b2ba..e50afc49 100644 --- a/Tone/source/oscillator/Oscillator.ts +++ b/Tone/source/oscillator/Oscillator.ts @@ -87,17 +87,12 @@ export class Oscillator constructor(frequency?: Frequency, type?: ToneOscillatorType); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(Oscillator.getDefaults(), arguments, [ - "frequency", - "type", - ]) - ); const options = optionsFromArguments( Oscillator.getDefaults(), arguments, ["frequency", "type"] ); + super(options); this.frequency = new Signal<"frequency">({ context: this.context, diff --git a/Tone/source/oscillator/PWMOscillator.ts b/Tone/source/oscillator/PWMOscillator.ts index 7a5ffa7f..18725020 100644 --- a/Tone/source/oscillator/PWMOscillator.ts +++ b/Tone/source/oscillator/PWMOscillator.ts @@ -77,17 +77,12 @@ export class PWMOscillator constructor(frequency?: Frequency, modulationFrequency?: Frequency); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(PWMOscillator.getDefaults(), arguments, [ - "frequency", - "modulationFrequency", - ]) - ); const options = optionsFromArguments( PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"] ); + super(options); this._pulse = new PulseOscillator({ context: this.context, diff --git a/Tone/source/oscillator/PulseOscillator.ts b/Tone/source/oscillator/PulseOscillator.ts index f4c10c2e..ba11111f 100644 --- a/Tone/source/oscillator/PulseOscillator.ts +++ b/Tone/source/oscillator/PulseOscillator.ts @@ -108,17 +108,12 @@ export class PulseOscillator constructor(frequency?: Frequency, width?: AudioRange); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(PulseOscillator.getDefaults(), arguments, [ - "frequency", - "width", - ]) - ); const options = optionsFromArguments( PulseOscillator.getDefaults(), arguments, ["frequency", "width"] ); + super(options); this.width = new Signal({ context: this.context, diff --git a/Tone/source/oscillator/ToneOscillatorNode.ts b/Tone/source/oscillator/ToneOscillatorNode.ts index c0058f1a..15335107 100644 --- a/Tone/source/oscillator/ToneOscillatorNode.ts +++ b/Tone/source/oscillator/ToneOscillatorNode.ts @@ -43,17 +43,12 @@ export class ToneOscillatorNode extends OneShotSource constructor(frequency: Frequency, type: OscillatorType); constructor(options?: Partial); constructor() { - super( - optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, [ - "frequency", - "type", - ]) - ); const options = optionsFromArguments( ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"] ); + super(options); connect(this._oscillator, this._gainNode); From f06ff17f060ab44f2f848e080e98ba7b1bf7d36e Mon Sep 17 00:00:00 2001 From: Marcel Blum Date: Mon, 6 May 2024 11:25:17 -0400 Subject: [PATCH 16/17] allow worklet-based effects to be used with native contexts (#1131) * check for native context when creating AudioWorkletNode * better context check per @chrisguttandin --------- Co-authored-by: Yotam Mann --- Tone/core/context/AudioContext.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Tone/core/context/AudioContext.ts b/Tone/core/context/AudioContext.ts index a162fc68..5012e098 100644 --- a/Tone/core/context/AudioContext.ts +++ b/Tone/core/context/AudioContext.ts @@ -41,6 +41,8 @@ export type AnyAudioContext = AudioContext | OfflineAudioContext; interface ToneWindow extends Window { TONE_SILENCE_LOGGING?: boolean; TONE_DEBUG_CLASS?: string; + BaseAudioContext: any; + AudioWorkletNode: any; } /** @@ -66,10 +68,13 @@ export function createAudioWorkletNode( ): AudioWorkletNode { assert( isDefined(stdAudioWorkletNode), - "This node only works in a secure context (https or localhost)" + "AudioWorkletNode only works in a secure context (https or localhost)" ); - // @ts-ignore - return new stdAudioWorkletNode(context, name, options); + return new ( + context instanceof theWindow?.BaseAudioContext + ? theWindow?.AudioWorkletNode + : stdAudioWorkletNode + )(context, name, options); } /** From 73f158f68627548e12f3de512cdf5102396586ca Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Wed, 15 May 2024 15:24:20 -0400 Subject: [PATCH 17/17] updating example links (#1246) --- examples/amSynth.html | 130 +++++---- examples/analysis.html | 140 +++++---- examples/bembe.html | 174 +++++++----- examples/buses.html | 206 +++++++++----- examples/envelope.html | 151 ++++++---- examples/events.html | 336 +++++++++++++--------- examples/fmSynth.html | 119 ++++---- examples/grainPlayer.html | 132 +++++---- examples/jump.html | 551 +++++++++++++++++++----------------- examples/lfoEffects.html | 232 ++++++++++----- examples/meter.html | 128 +++++---- examples/mixer.html | 155 +++++----- examples/monoSynth.html | 134 +++++---- examples/noises.html | 140 +++++---- examples/offline.html | 214 ++++++++------ examples/oscillator.html | 108 ++++--- examples/pingPongDelay.html | 127 +++++---- examples/pitchShift.html | 135 +++++---- examples/player.html | 108 ++++--- examples/polySynth.html | 114 ++++---- examples/reverb.html | 111 +++++--- examples/sampler.html | 161 ++++++----- examples/signal.html | 211 ++++++++------ examples/simpleSynth.html | 140 +++++---- examples/stepSequencer.html | 134 +++++---- 25 files changed, 2493 insertions(+), 1798 deletions(-) diff --git a/examples/amSynth.html b/examples/amSynth.html index 16a86ee2..bbc3c955 100644 --- a/examples/amSynth.html +++ b/examples/amSynth.html @@ -1,64 +1,78 @@ - + - - - AMSynth + + + AMSynth - - - - - - - - - - -
- Tone.AMSynth - is composed of two - Tone.Synths - where one Tone.Synth modulates the amplitude of a second Tone.Synth. -
+ + + + + + + + + + +
+ Tone.AMSynth + is composed of two + Tone.Synths + where one Tone.Synth modulates the amplitude of a second + Tone.Synth. +
-
-
-
- - - + piano({ + tone: synth, + parent: document.querySelector("#content"), + noteon: (note) => synth.triggerAttack(note.name), + noteoff: (note) => synth.triggerRelease(), + }); + + ui({ + tone: synth, + name: "AMSynth", + parent: document.querySelector("#content"), + }); + + diff --git a/examples/analysis.html b/examples/analysis.html index b80cffb5..3b0cd97a 100644 --- a/examples/analysis.html +++ b/examples/analysis.html @@ -1,71 +1,93 @@ - + - - - Analyser + + + Analyser - - + + - - - - - + + + + + + + + + - - - - +
+ Tone.FFT + returns the amplitude of the incoming signal at different + frequencies. + Tone.Waveform + returns the signal value between 0-1. +
-
- Tone.FFT - returns the amplitude of the incoming signal at different frequencies. - Tone.Waveform - returns the signal value between 0-1. -
+
+ +
+
-
- -
-
+ - + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + + diff --git a/examples/bembe.html b/examples/bembe.html index c033eea6..6f303d6a 100644 --- a/examples/bembe.html +++ b/examples/bembe.html @@ -1,82 +1,116 @@ - + - - - MetalSynth + + + MetalSynth - - + + - - - - - + + + + + + + + +
+ Tone.MetalSynth + creates metallic, inharmonic sounds using 6 + Tone.FMOscillators + with a tuning based on the TR-808 Cymbal. + Tone.MembraneSynth + makes kick and tom-like sounds using a frequency envelope which + is triggered on notes attack. +
- - - -
- Tone.MetalSynth - creates metallic, inharmonic sounds using 6 - Tone.FMOscillators - with a tuning based on the TR-808 Cymbal. - Tone.MembraneSynth - makes kick and tom-like sounds using a frequency envelope which is triggered on notes attack. -
+
+ +
+
-
- -
-
+ - + // connect the UI with the components + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => Tone.Transport.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => Tone.Transport.stop()); + + diff --git a/examples/buses.html b/examples/buses.html index 0b4b79e1..e737741d 100644 --- a/examples/buses.html +++ b/examples/buses.html @@ -1,84 +1,142 @@ - + - - - Buses + + + Buses - - + + - - - - - - - - -
- Buses make it easy to share effects across many instruments. send - audio to a named bus from an instrument and then receive that - channel on your effect. The gain values are all in decibels. -

- Docs on send and - receive. -
-
- - - - -
-
+ + + + + + + + +
+ Buses make it easy to share effects across many instruments. + send audio to a named bus from an instrument and + then receive that channel on your effect. The gain + values are all in decibels.

+ Docs on + send + and + receive. +
+
+ + + + +
+
- - + drawer() + .add({ + tone: chorus, + }) + .add({ + tone: reverb, + }) + .add({ + tone: cheby, + }); + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + // bind the interface + document + .querySelector('[label="Chorus Send"]') + .addEventListener("input", (e) => { + chorusChannel.volume.value = parseFloat(e.target.value); + }); + document + .querySelector('[label="Chebyshev Send"]') + .addEventListener("input", (e) => { + chebyChannel.volume.value = parseFloat(e.target.value); + }); + document + .querySelector('[label="Reverb Send"]') + .addEventListener("input", (e) => { + reverbChannel.volume.value = parseFloat(e.target.value); + }); + + diff --git a/examples/envelope.html b/examples/envelope.html index e45a4127..86cf4d69 100644 --- a/examples/envelope.html +++ b/examples/envelope.html @@ -1,71 +1,100 @@ - + - - - Envelope + + + Envelope - - + + - - - - - - - - - -
- Envelopes ramp amplitude, frequency or any other parameter over time. - Tone.Envelope and the classes that extend it - implement an ADSR envelope type - which splits its ramp into four distinct phases: Attack, Decay, Sustain, Release. - -
+ tone-trigger { + margin-bottom: 10px; + } + + +
+ Envelopes ramp amplitude, frequency or any other parameter over + time. + Tone.Envelope + and the classes that extend it implement an + ADSR + envelope type which splits its ramp into four distinct phases: + Attack, Decay, Sustain, Release. + +
-
- -
+
+ +
+
-
+ - + document + .querySelector("tone-momentary-button") + .addEventListener("down", (e) => env.triggerAttack()); + document + .querySelector("tone-momentary-button") + .addEventListener("up", (e) => env.triggerRelease()); + + diff --git a/examples/events.html b/examples/events.html index ef1968e7..00c427d8 100644 --- a/examples/events.html +++ b/examples/events.html @@ -1,143 +1,197 @@ - + - - - Events - - - - - - - - - - - - -
- Tone's Event classes (Tone.ToneEvent, - Tone.Loop, - Tone.Part and - Tone.Sequence) - simplify scheduling events along the Transport. Each class abstracts away calls to - Transport.schedule or - scheduleRepeat - and lets you create precise, rhythmic events which are startable, stoppable and loopable. - (note that ToneEvent was called Event before Tone.js 14.x) -
- -
- -
-
- - - + + + Events + + + + + + + + + + + + +
+ Tone's Event classes (Tone.ToneEvent, + Tone.Loop, + Tone.Part + and + Tone.Sequence) simplify scheduling events along the Transport. Each class + abstracts away calls to + Transport.schedule + or + scheduleRepeat + and lets you create precise, rhythmic events which are + startable, stoppable and loopable. (note that ToneEvent was + called + Event + before Tone.js 14.x) +
+ +
+ +
+
+ + + diff --git a/examples/fmSynth.html b/examples/fmSynth.html index 1e0da913..0973e08e 100644 --- a/examples/fmSynth.html +++ b/examples/fmSynth.html @@ -1,59 +1,74 @@ - + - - - FMSynth + + + FMSynth - - + + - - - - - - - - -
- Tone.FMSynth - is composed of two - Tone.Synths - where one Tone.Synth modulates the frequency of a second Tone.Synth. -
+ + + + + + + + +
+ Tone.FMSynth + is composed of two + Tone.Synths + where one Tone.Synth modulates the frequency of a second + Tone.Synth. +
-
-
-
- - - + piano({ + tone: synth, + parent: document.querySelector("#content"), + noteon: (note) => synth.triggerAttack(note.name), + noteoff: (note) => synth.triggerRelease(), + }); + + ui({ + tone: synth, + name: "FMSynth", + parent: document.querySelector("#content"), + }); + + diff --git a/examples/grainPlayer.html b/examples/grainPlayer.html index d509a0ee..4c30e327 100644 --- a/examples/grainPlayer.html +++ b/examples/grainPlayer.html @@ -1,65 +1,87 @@ - + - - - Grain Player + + + Grain Player - - + + - - - - - - - - - -
- Tone.GrainPlayer uses - granular synthesis - to enable you to adjust pitch and playback rate independently. The grainSize is the - amount of time each small chunk of audio is played for and the overlap is the - amount of crossfading transition time between successive grains. -
- - + tone-fft { + background-color: black; + height: 40px; + width: 100%; + border-radius: 20px; + } + + +
+ Tone.GrainPlayer + uses + granular synthesis + to enable you to adjust pitch and playback rate independently. + The grainSize is the amount of time each small chunk of audio is + played for and the overlap is the amount of crossfading + transition time between successive grains. +
-
- -
-
+ - - + // bind the interface + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + + diff --git a/examples/jump.html b/examples/jump.html index a58cf9c9..db02ba0f 100644 --- a/examples/jump.html +++ b/examples/jump.html @@ -1,268 +1,305 @@ - + - - - FatOscillator + + + FatOscillator - - + + - - - - - - - - - -
- Tone.FatOscillator creates multiple oscillators - and detunes them slightly from each other to thicken the sound. The count parameter sets - the number of oscillators and spread sets the total spread (in cents) between the oscillators. -

- FatOscillator is also available in Tone.OmniOscillator - by prefixing another type with "fat", then use the count and spread to control the number and detune of the oscillators. To create a "supersaw": omniOscillator.type = "fatsawtooth". -

- Jump by Van Halen MIDI converted using @tonejs/midi -
+ + + + + + + + + +
+ Tone.FatOscillator + creates multiple oscillators and detunes them slightly from each + other to thicken the sound. The count parameter + sets the number of oscillators and spread sets the + total spread (in cents) between the oscillators.

+ FatOscillator is also available in + Tone.OmniOscillator + by prefixing another type with "fat", then use the count and + spread to control the number and detune of the oscillators. To + create a "supersaw": + omniOscillator.type = "fatsawtooth".

+ Jump by Van Halen MIDI + converted using + @tonejs/midi +
-
- -
-
+
+ +
+
- - + // bind the interface + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => Tone.Transport.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => Tone.Transport.stop()); + + diff --git a/examples/lfoEffects.html b/examples/lfoEffects.html index a1cddac8..9488897c 100644 --- a/examples/lfoEffects.html +++ b/examples/lfoEffects.html @@ -1,87 +1,169 @@ - + - - - LFO Effects + + + LFO Effects - - + + - - - - - - - - -
- These effects use an LFO (Low Frequency Oscillator) to modulate the effect. Click and drag the dot to change the frequency and depth of the effect. -

- Docs on Tone.AutoPanner, - Tone.AutoFilter, and - Tone.Tremolo -
+ + + + + + + + +
+ These effects use an + LFO + (Low Frequency Oscillator) to modulate the effect. Click and + drag the dot to change the frequency and depth of the effect. +

+ Docs on + Tone.AutoPanner, + Tone.AutoFilter, and + Tone.Tremolo +
-
- - - - - - - - +
+ + + + + + +
+ - - - + // bind the interface + document + .querySelector("#osc0") + .addEventListener("start", () => pannerOsc.start()); + document + .querySelector("#osc0") + .addEventListener("stop", () => pannerOsc.stop()); + document + .querySelector("#panner") + .addEventListener( + "input", + (e) => (panner.frequency.value = parseFloat(e.target.value)) + ); + document + .querySelector("#osc1") + .addEventListener("start", () => filterOsc.start()); + document + .querySelector("#osc1") + .addEventListener("stop", () => filterOsc.stop()); + document + .querySelector("#filter") + .addEventListener( + "input", + (e) => (filter.frequency.value = parseFloat(e.target.value)) + ); + document + .querySelector("#osc2") + .addEventListener("start", () => tremoloOsc.start()); + document + .querySelector("#osc2") + .addEventListener("stop", () => tremoloOsc.stop()); + document + .querySelector("#tremolo") + .addEventListener( + "input", + (e) => + (tremolo.frequency.value = parseFloat(e.target.value)) + ); + + diff --git a/examples/meter.html b/examples/meter.html index b3a11c53..809dfabe 100644 --- a/examples/meter.html +++ b/examples/meter.html @@ -1,57 +1,75 @@ - + - - - Meter - - - - - - - - - - - - - -
- Tone.Meter - gives you the level of the incoming signal in decibels. -
- -
- -
-
- - - + + + Meter + + + + + + + + + + + + + +
+ Tone.Meter + gives you the level of the incoming signal in decibels. +
+ +
+ +
+
+ + + diff --git a/examples/mixer.html b/examples/mixer.html index 8c2a7325..9c36139c 100644 --- a/examples/mixer.html +++ b/examples/mixer.html @@ -1,74 +1,99 @@ - + - - - Mixer + + + Mixer - - + + - - - - - - - - - -
- Tone.Channel provides a simple channel interface. It allows for panning and volume changes as well as the ability to solo (exclude audio in other Tone.Channels). -
- - -
- -
-
+ + + + + + + + + +
+ Tone.Channel + provides a simple channel interface. It allows for panning and + volume changes as well as the ability to + solo + (exclude audio in other Tone.Channels). +
- - + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => Tone.Transport.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => Tone.Transport.stop()); + + diff --git a/examples/monoSynth.html b/examples/monoSynth.html index 8b94d2f7..60e11812 100644 --- a/examples/monoSynth.html +++ b/examples/monoSynth.html @@ -1,69 +1,81 @@ - + - - - MonoSynth + + + MonoSynth - - + + - - - - - - - - - -
- Tone.MonoSynth - is composed of one oscillator, one filter, and two envelopes. - Both envelopes are triggered simultaneously when a note is triggered. -
+ + + + + + + + + +
+ Tone.MonoSynth + is composed of one oscillator, one filter, and two envelopes. + Both envelopes are triggered simultaneously when a note is + triggered. +
-
-
-
+
+
- - + ui({ + tone: synth, + parent: document.querySelector("#content"), + name: "MonoSynth", + }); + + diff --git a/examples/noises.html b/examples/noises.html index f130988e..35da0296 100644 --- a/examples/noises.html +++ b/examples/noises.html @@ -1,63 +1,81 @@ - + - - - Noise - - - - - - - - - - - - - -
- Tone.Noise - has 3 different types of noise. Careful, it's loud! -
- -
- -
-
- - - + + + Noise + + + + + + + + + + + + + +
+ Tone.Noise + has 3 different types of noise. Careful, it's loud! +
+ +
+ +
+
+ + + diff --git a/examples/offline.html b/examples/offline.html index c470a4b6..ac6b156d 100644 --- a/examples/offline.html +++ b/examples/offline.html @@ -1,103 +1,139 @@ - + - - - Offline + + + Offline - - + + - - - - - - - - - - -
- Tone.Offline renders a chunk of Tone.js code into an AudioBuffer. An offline instance of Tone.Transport is passed into the callback which can be used to schedule events. It may take a moment to render the sound. -

- Tone.Offline docs. -
+ + + + + + + + + + +
+ Tone.Offline renders a chunk of Tone.js code into an + AudioBuffer. An offline instance of Tone.Transport is passed + into the callback which can be used to schedule events. It may + take a moment to render the sound. +

+ Tone.Offline + docs. +
-
- -
-
+
+ +
+
- - + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + + diff --git a/examples/oscillator.html b/examples/oscillator.html index 15677bff..ab771e33 100644 --- a/examples/oscillator.html +++ b/examples/oscillator.html @@ -1,53 +1,71 @@ - + - - - Oscillator + + + Oscillator - - + + - - - - - - - - - -
- The oscillator has 4 basic types which can be altered by setting the number - of partials and partials array. -

- Tone.Oscillator docs. -
+ + + + + + + + + +
+ The oscillator has 4 basic types which can be altered by setting + the number of partials and partials array. +

+ Tone.Oscillator + docs. +
-
- -
-
+
+ +
+
+ - + // bind the interface + document + .querySelector("tone-momentary-button") + .addEventListener("down", () => osc.start()); + document + .querySelector("tone-momentary-button") + .addEventListener("up", () => osc.stop()); + + diff --git a/examples/pingPongDelay.html b/examples/pingPongDelay.html index a68133cd..8bb7e960 100644 --- a/examples/pingPongDelay.html +++ b/examples/pingPongDelay.html @@ -1,54 +1,77 @@ - + - - - Ping Pong Delay - - - - - - - - - - - - - - -
- A Ping Pong Delay is a stereo feedback delay where the delay bounces back and forth between the left and right channels. Hit the button to trigger a snare sample into the effect. -

- Tone.PingPongDelay docs. -
- -
- -
-
- - - + + + Ping Pong Delay + + + + + + + + + + + + + + +
+ A Ping Pong Delay is a stereo feedback delay where the delay + bounces back and forth between the left and right channels. Hit + the button to trigger a snare sample into the effect. +

+ Tone.PingPongDelay + docs. +
+ +
+ +
+
+ + + diff --git a/examples/pitchShift.html b/examples/pitchShift.html index ac57e1c1..32faee98 100644 --- a/examples/pitchShift.html +++ b/examples/pitchShift.html @@ -1,61 +1,90 @@ - + - - - Pitch Shift + + + Pitch Shift - - + + - - - - - - - - - -
- This example demonstrates the Pitch Shift effect. -

- Tone.Pitch Shift docs. -
- - -
- - -
-
+ + + + + + + + + +
+ This example demonstrates the Pitch Shift effect. +

+ Tone.Pitch Shift + docs. +
- - + // bind the interface + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + // document.querySelector("tone-play-toggle").addEventListener('start', () => { + // debugger; + // }); + + document + .querySelector("tone-slider") + .addEventListener("input", (e) => { + pitchShift.pitch = parseFloat(e.target.value); + }); + + diff --git a/examples/player.html b/examples/player.html index 5c1314d1..6c1598f0 100644 --- a/examples/player.html +++ b/examples/player.html @@ -1,54 +1,70 @@ - + - - - Player + + + Player - - + + - - - - - - - - - - -
- Click on the button to play the audio file on loop - using Tone.Player. -
+ + + + + + + + + + +
+ Click on the button to play the audio file on loop using + Tone.Player. +
-
- -
-
- - + ui({ + tone: player, + parent: document.querySelector("#content"), + }); - + // bind the interface + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + + diff --git a/examples/polySynth.html b/examples/polySynth.html index 096438d7..24fe971b 100644 --- a/examples/polySynth.html +++ b/examples/polySynth.html @@ -1,56 +1,68 @@ - + - - - PolySynth + + + PolySynth - - + + - - - - - - - - - -
- Tone.PolySynth - handles voice creation and allocation for any monophonic - instruments passed in as the second parameter. PolySynth is - not a synthesizer by itself, it merely manages voices of - one of the other types of synths, allowing any of the - monophonic synthesizers to be polyphonic. -
- -
-
-
- - + + + + + + + + +
+ Tone.PolySynth + handles voice creation and allocation for any monophonic + instruments passed in as the second parameter. PolySynth is not + a synthesizer by itself, it merely manages voices of one of the + other types of synths, allowing any of the monophonic + synthesizers to be polyphonic. +
+ +
+
+ + - - \ No newline at end of file + ui({ + tone: synth, + parent: document.querySelector("#content"), + }); + + + diff --git a/examples/reverb.html b/examples/reverb.html index 6efc996c..6255a234 100644 --- a/examples/reverb.html +++ b/examples/reverb.html @@ -1,56 +1,73 @@ - + - - - Reverb + + + Reverb - - + + - - - - - - - - - -
- Tone.Reverb - is a convolution-based reverb. An impulse response is created with a - decaying noise burst when you click 'Generate Reverb'. The 'Decay Time' controls - how long the noise burst lasts. If the 'Decay Time' is changed, a new noise burst - will need to be generated. -
+ + + + + + + + + +
+ Tone.Reverb + is a convolution-based reverb. An impulse response is created + with a decaying noise burst when you click 'Generate Reverb'. + The 'Decay Time' controls how long the noise burst lasts. If the + 'Decay Time' is changed, a new noise burst will need to be + generated. +
-
- -
-
- - - + // bind the interface + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => player.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => player.stop()); + + diff --git a/examples/sampler.html b/examples/sampler.html index 526fc156..690189d3 100644 --- a/examples/sampler.html +++ b/examples/sampler.html @@ -1,79 +1,98 @@ - + - - - Sampler + + + Sampler - - + + - - - - - - - - - - + + + + + + + + + + -
- Tone.Sampler makes it easy to create an instrument from audio samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time. -
+
+ Tone.Sampler + makes it easy to create an instrument from audio samples. Pass + in an object which maps the note's pitch or midi value to the + url, then you can trigger the attack and release of that note + like other instruments. By automatically repitching the samples, + it is possible to play pitches which were not explicitly + included which can save loading time. +
-
-
-
+
+
- - - + piano({ + parent: document.querySelector("#content"), + noteon: (note) => sampler.triggerAttack(note.name), + noteoff: (note) => sampler.triggerRelease(note.name), + }); + + diff --git a/examples/signal.html b/examples/signal.html index d0289e96..9ae68930 100644 --- a/examples/signal.html +++ b/examples/signal.html @@ -1,106 +1,135 @@ - + - - - Signal + + + Signal - - + + - - - - - - - - - -
- One of the most powerful features of Tone.js and the Web Audio API is the ability to - perform math and logic on audio-rate signal. Signals - can be ramped and scheduled to control Audio Parameters and - other Signals making it simple to create elaborate, - interconnected automations. -

- This example applies a series of mappings to a - signal value and applies the results of those mappings - to the frequency attribute of 2 - Tone.Oscillators - and a Tone.LFO. -
+ + + + + + + + + +
+ One of the most powerful features of Tone.js and the Web Audio + API is the ability to perform math and logic on audio-rate + signal. Signals can be ramped and scheduled to control Audio + Parameters and other Signals making it simple to create + elaborate, interconnected automations. +

+ This example applies a series of mappings to a signal value and + applies the results of those mappings to the frequency attribute + of 2 + Tone.Oscillators + and a + Tone.LFO. +
-
- - -
-
- - + // multiply the frequency by 2 to get the octave above + const detuneScale = new Tone.Scale(14, 4); + frequency.chain(detuneScale, detuneLFO.frequency); - + // start the oscillators with the play button + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => { + rightOsc.start(); + leftOsc.start(); + }); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => { + rightOsc.stop(); + leftOsc.stop(); + }); + + // ramp the frequency with the slider + document + .querySelector("tone-slider") + .addEventListener("input", (e) => { + frequency.rampTo(parseFloat(e.target.value), 0.1); + }); + + diff --git a/examples/simpleSynth.html b/examples/simpleSynth.html index 4abe621f..d8a6813e 100644 --- a/examples/simpleSynth.html +++ b/examples/simpleSynth.html @@ -1,66 +1,88 @@ - + - - - Synth + + + Synth - - + + - - - - - - - - - -
- Tone.Synth is composed simply of a - Tone.OmniOscillator - routed through a - Tone.AmplitudeEnvelope. -
+ + + + + + + + + +
+ Tone.Synth + is composed simply of a + Tone.OmniOscillator + routed through a + Tone.AmplitudeEnvelope. +
-
-
-
+
+
- - - \ No newline at end of file + ui({ + tone: synth, + name: "Synth", + parent: document.querySelector("#content"), + }); + + + diff --git a/examples/stepSequencer.html b/examples/stepSequencer.html index 4fac4fe0..e97f5a5f 100644 --- a/examples/stepSequencer.html +++ b/examples/stepSequencer.html @@ -1,57 +1,91 @@ - + - - - Step Sequencer + + + Step Sequencer - - + + - - - - - - - - - - -
- Tone.Transport - is the application-wide timekeeper. It's clock source enables sample-accurate scheduling as well as tempo-curves and automation. This example uses Tone.Sequence to invoke a callback every 16th note. -
+ + + + + + + + + + +
+ Tone.Transport + is the application-wide timekeeper. It's clock source enables + sample-accurate scheduling as well as tempo-curves and + automation. This example uses Tone.Sequence to invoke a callback + every 16th note. +
-
- - - -
-
+
+ + + +
+
- - + document + .querySelector("tone-play-toggle") + .addEventListener("start", () => Tone.Transport.start()); + document + .querySelector("tone-play-toggle") + .addEventListener("stop", () => Tone.Transport.stop()); + document + .querySelector("tone-slider") + .addEventListener( + "input", + (e) => + (Tone.Transport.bpm.value = parseFloat(e.target.value)) + ); + document + .querySelector("tone-step-sequencer") + .addEventListener("trigger", ({ detail }) => { + keys.player(detail.row).start(detail.time, 0, "16t"); + }); + +