From 22508acb9fc15bcd89b77ebaaca7db54ffd007bc Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Sun, 26 Nov 2023 23:06:49 +0100 Subject: [PATCH] lint --- .github/workflows/build_docker.yml | 17 +-- .vscode/settings.json | 3 +- README.md | 7 +- docker-compose.yml | 8 +- favicon/site.webmanifest | 34 +++--- fonts/index.css | 135 ++++++++++++----------- postcss.config.js | 2 +- src/API.ts | 74 ++++++------- src/AudioVisualisation.ts | 26 ++--- src/Clock.ts | 5 +- src/Documentation.ts | 4 +- src/Evaluator.ts | 12 +- src/FileManagement.ts | 6 +- src/Utils/Generic.ts | 33 +++--- src/WindowBehavior.ts | 10 +- src/classes/SoundEvent.ts | 25 +++-- src/classes/ZPlayer.ts | 12 +- src/documentation/more/bonus.ts | 10 +- src/documentation/samples/sample_list.ts | 24 ++-- src/main.ts | 26 ++--- tsconfig.json | 2 +- 21 files changed, 243 insertions(+), 232 deletions(-) diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 80aae64..71a6250 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -3,28 +3,23 @@ name: Build and Push Docker Images on: push: branches: - - 'main' + - "main" jobs: topos: runs-on: ubuntu-latest steps: - - - name: Checkout + - name: Checkout uses: actions/checkout@v2 - - - name: Set up QEMU + - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub + - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push + - name: Build and push uses: docker/build-push-action@v5 with: push: true diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a73a41..0967ef4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1 @@ -{ -} \ No newline at end of file +{} diff --git a/README.md b/README.md index 2d9ee97..eb55eb5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@

-Topos is a web-based live coding environment. It lives [here](https://topos.live). Documentation is directly embedded in the application itself. Topos is an emulation and extension of the [Monome Teletype](https://monome.org/docs/teletype/) that gradually evolved into something a bit more personal. +Topos is a web-based live coding environment. It lives [here](https://topos.live). Documentation is directly embedded in the application itself. Topos is an emulation and extension of the [Monome Teletype](https://monome.org/docs/teletype/) that gradually evolved into something a bit more personal. ![Screenshot](https://github.com/Bubobubobubobubo/Topos/blob/main/img/topos_gif.gif) @@ -46,15 +46,18 @@ The `tauri` version is only here to quickstart future developments but nothing ## Docker ### Run the application + `docker run -p 8001:80 yassinsiouda/topos:latest` ### Build and run the prod image + `docker compose --profile prod up` ### Build and run the dev image **First installation** First you need to map node_modules to your local machine for your ide intellisense to work properly + ```bash docker compose --profile dev up -d docker cp topos-dev:/app/node_modules . @@ -62,7 +65,7 @@ docker compose --profile dev down ``` **Then** + ```bash docker compose --profile dev up ``` - diff --git a/docker-compose.yml b/docker-compose.yml index 0021919..62f86ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ -version: '3.7' +version: "3.7" services: topos-dev: container_name: topos-dev profiles: ["dev"] - build: + build: context: . target: "dev" volumes: @@ -21,8 +21,8 @@ services: topos-prod: container_name: topos-prod profiles: ["prod"] - build: + build: context: . target: "prod" ports: - - "8001:80" \ No newline at end of file + - "8001:80" diff --git a/favicon/site.webmanifest b/favicon/site.webmanifest index b20abb7..fa99de7 100644 --- a/favicon/site.webmanifest +++ b/favicon/site.webmanifest @@ -1,19 +1,19 @@ { - "name": "", - "short_name": "", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" } diff --git a/fonts/index.css b/fonts/index.css index 967bf0c..159b271 100644 --- a/fonts/index.css +++ b/fonts/index.css @@ -1,7 +1,8 @@ @font-face { font-family: "IBM Plex Mono"; - src: url("woff2/IBMPlexMono-Regular.woff2") format("woff2"), - url("woff/IBMPlexMono-Regular.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Regular.woff2") format("woff2"), + url("woff/IBMPlexMono-Regular.woff") format("woff"); font-weight: 400; font-style: normal; font-display: swap; @@ -9,8 +10,9 @@ @font-face { font-family: "IBM PLex Mono"; - src: url("woff2/IBMPlexMono-Italic.woff2") format("woff2"), - url("woff/IBMPlexMono-Italic.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Italic.woff2") format("woff2"), + url("woff/IBMPlexMono-Italic.woff") format("woff"); font-weight: 400; font-style: italic; font-display: swap; @@ -18,8 +20,9 @@ @font-face { font-family: "IBM PLex Mono"; - src: url("woff2/IBMPlexMono-Bold.woff2") format("woff2"), - url("woff/IBMPlexMono-Bold.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Bold.woff2") format("woff2"), + url("woff/IBMPlexMono-Bold.woff") format("woff"); font-weight: 700; font-style: normal; font-display: swap; @@ -27,8 +30,9 @@ @font-face { font-family: "IBM Plex Mono"; - src: url("woff2/IBMPlexMono-BoldItalic.woff2") format("woff2"), - url("woff/IBMPlexMono-BoldItalic.woff") format("woff"); + src: + url("woff2/IBMPlexMono-BoldItalic.woff2") format("woff2"), + url("woff/IBMPlexMono-BoldItalic.woff") format("woff"); font-weight: 700; font-style: italic; font-display: swap; @@ -37,84 +41,85 @@ @font-face { font-family: "Comic Mono"; font-weight: normal; - src: url(./woff/ComicMono.woff) format("woff"), - url(./woff2/ComicMono.woff2) format("wooff2"); + src: + url(./woff/ComicMono.woff) format("woff"), + url(./woff2/ComicMono.woff2) format("wooff2"); } @font-face { font-family: "Comic Mono"; font-weight: bold; - src: url(./woff/ComicMono-Bold.woff) format("woff"), - url(./woff/ComicMono-Bold.woff2) format("woff2"), -} - - -@font-face { - font-family: 'jgs7'; - src: url('./woff2/jgs7.woff2') format('woff2'), - url('./woff/jgs7.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + src: + url(./woff/ComicMono-Bold.woff) format("woff"), + url(./woff/ComicMono-Bold.woff2) format("woff2"); } @font-face { - font-family: 'jgs5'; - src: url('./woff2/jgs5.woff2') format('woff2'), - url('./woff/jgs5.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs7"; + src: + url("./woff2/jgs7.woff2") format("woff2"), + url("./woff/jgs7.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'jgs9'; - src: url('./woff2/jgs9.woff2') format('woff2'), - url('./woff/jgs9.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - - -@font-face { - font-family: 'jgs_vecto'; - src: url('./woff2/jgs_vecto.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs5"; + src: + url("./woff2/jgs5.woff2") format("woff2"), + url("./woff/jgs5.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Steps Mono'; - src: url('./woff2/Steps-Mono.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs9"; + src: + url("./woff2/jgs9.woff2") format("woff2"), + url("./woff/jgs9.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Steps Mono Thin'; - src: url('./woff2/Steps-Mono-Thin.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs_vecto"; + src: url("./woff2/jgs_vecto.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; } - @font-face { - font-family: 'Jet Brains'; - src: url('./woff2/JetBrainsMono-Regular.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "Steps Mono"; + src: url("./woff2/Steps-Mono.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; } - @font-face { - font-family: 'Jet Brains'; - src: url('./woff2/JetBrainsMono-Bold.woff2') format('woff2'); - font-weight: 700; - font-style: normal; - font-display: swap; + font-family: "Steps Mono Thin"; + src: url("./woff2/Steps-Mono-Thin.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Jet Brains"; + src: url("./woff2/JetBrainsMono-Regular.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Jet Brains"; + src: url("./woff2/JetBrainsMono-Bold.woff2") format("woff2"); + font-weight: 700; + font-style: normal; + font-display: swap; } diff --git a/postcss.config.js b/postcss.config.js index 2e7af2b..2aa7205 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/src/API.ts b/src/API.ts index c29b6bb..3269f6d 100644 --- a/src/API.ts +++ b/src/API.ts @@ -111,7 +111,7 @@ export class UserAPI { } this.app.settings.saveApplicationToLocalStorage( this.app.universes, - this.app.settings + this.app.settings, ); this.app.updateKnownUniversesView(); }; @@ -203,7 +203,7 @@ export class UserAPI { // @ts-ignore this.errorTimeoutID = setTimeout( () => this.app.interface.error_line.classList.add("hidden"), - 2000 + 2000, ); }; @@ -217,7 +217,7 @@ export class UserAPI { // @ts-ignore this.printTimeoutID = setTimeout( () => this.app.interface.error_line.classList.add("hidden"), - 4000 + 4000, ); }; @@ -268,7 +268,7 @@ export class UserAPI { */ this.app.clock.tick = beat * this.app.clock.ppqn; this.app.clock.time_position = this.app.clock.convertTicksToTimeposition( - beat * this.app.clock.ppqn + beat * this.app.clock.ppqn, ); }; @@ -325,7 +325,7 @@ export class UserAPI { blinkScript(this.app, "local", arg); tryEvaluate( this.app, - this.app.universes[this.app.selected_universe].locals[arg] + this.app.universes[this.app.selected_universe].locals[arg], ); } }); @@ -372,7 +372,7 @@ export class UserAPI { delete this.app.universes[universe]; this.app.settings.saveApplicationToLocalStorage( this.app.universes, - this.app.settings + this.app.settings, ); this.app.updateKnownUniversesView(); }; @@ -388,7 +388,7 @@ export class UserAPI { }; this.app.settings.saveApplicationToLocalStorage( this.app.universes, - this.app.settings + this.app.settings, ); } this.app.selected_universe = "Default"; @@ -425,7 +425,7 @@ export class UserAPI { value: number | number[] = 60, velocity?: number | number[], channel?: number | number[], - port?: number | string | number[] | string[] + port?: number | string | number[] | string[], ): MidiEvent => { /** * Sends a MIDI note to the current MIDI output. @@ -500,7 +500,7 @@ export class UserAPI { }; public active_note_events = ( - channel?: number + channel?: number, ): MidiNoteEvent[] | undefined => { /** * @returns A list of currently active MIDI notes @@ -637,7 +637,7 @@ export class UserAPI { scale: number | string, channel: number = 0, port: number | string = this.MidiConnection.currentOutputIndex || 0, - soundOff: boolean = false + soundOff: boolean = false, ): void => { /** * Sends given scale to midi output for visual aid @@ -661,7 +661,7 @@ export class UserAPI { // @ts-ignore scale: number | string = 0, channel: number = 0, - port: number | string = this.MidiConnection.currentOutputIndex || 0 + port: number | string = this.MidiConnection.currentOutputIndex || 0, ): void => { /** * Hides all notes by sending all notes off to midi output @@ -676,7 +676,7 @@ export class UserAPI { midi_notes_off = ( channel: number = 0, - port: number | string = this.MidiConnection.currentOutputIndex || 0 + port: number | string = this.MidiConnection.currentOutputIndex || 0, ): void => { /** * Sends all notes off to midi output @@ -686,7 +686,7 @@ export class UserAPI { midi_sound_off = ( channel: number = 0, - port: number | string = this.MidiConnection.currentOutputIndex || 0 + port: number | string = this.MidiConnection.currentOutputIndex || 0, ): void => { /** * Sends all sound off to midi output @@ -713,7 +713,7 @@ export class UserAPI { public z = ( input: string | Generator, options: InputOptions = {}, - id: number | string = "" + id: number | string = "", ): Player => { const zid = "z" + id.toString(); const key = id === "" ? this.generateCacheKey(input, options) : zid; @@ -790,7 +790,7 @@ export class UserAPI { public counter = ( name: string | number, limit?: number, - step?: number + step?: number, ): number => { /** * Returns the current value of a counter, and increments it by the step value. @@ -1297,8 +1297,8 @@ export class UserAPI { const results: boolean[] = nArray.map( (value) => (this.app.clock.pulses_since_origin - Math.floor(nudge * this.ppqn())) % - Math.floor(value * this.ppqn()) === - 0 + Math.floor(value * this.ppqn()) === + 0, ); return results.some((value) => value === true); }; @@ -1317,8 +1317,8 @@ export class UserAPI { const results: boolean[] = nArray.map( (value) => (this.app.clock.pulses_since_origin - nudgeInPulses) % - Math.floor(value * barLength) === - 0 + Math.floor(value * barLength) === + 0, ); return results.some((value) => value === true); }; @@ -1333,7 +1333,7 @@ export class UserAPI { */ const nArray = Array.isArray(n) ? n : [n]; const results: boolean[] = nArray.map( - (value) => (this.app.clock.pulses_since_origin - nudge) % value === 0 + (value) => (this.app.clock.pulses_since_origin - nudge) % value === 0, ); return results.some((value) => value === true); }; @@ -1342,7 +1342,7 @@ export class UserAPI { public tick = (tick: number | number[], offset: number = 0): boolean => { const nArray = Array.isArray(tick) ? tick : [tick]; const results: boolean[] = nArray.map( - (value) => this.app.clock.time_position.pulse === value + offset + (value) => this.app.clock.time_position.pulse === value + offset, ); return results.some((value) => value === true); }; @@ -1391,7 +1391,7 @@ export class UserAPI { public onbar = ( bars: number[] | number, - n: number = this.app.clock.time_signature[0] + n: number = this.app.clock.time_signature[0], ): boolean => { let current_bar = (this.app.clock.time_position.bar % n) + 1; return typeof bars === "number" @@ -1419,7 +1419,7 @@ export class UserAPI { if (decimal_part <= 0) decimal_part = decimal_part + this.ppqn() * this.nominator(); final_pulses.push( - integral_part === this.cbeat() && this.cpulse() === decimal_part + integral_part === this.cbeat() && this.cpulse() === decimal_part, ); }); return final_pulses.some((p) => p == true); @@ -1501,7 +1501,7 @@ export class UserAPI { iterator: number, pulses: number, length: number, - rotate: number = 0 + rotate: number = 0, ): boolean => { /** * Returns a euclidean cycle of size length, with n pulses, rotated or not. @@ -1520,7 +1520,7 @@ export class UserAPI { div: number, pulses: number, length: number, - rotate: number = 0 + rotate: number = 0, ): boolean => { return ( this.beat(div) && this._euclidean_cycle(pulses, length, rotate).beat(div) @@ -1530,7 +1530,7 @@ export class UserAPI { _euclidean_cycle( pulses: number, length: number, - rotate: number = 0 + rotate: number = 0, ): boolean[] { if (pulses == length) return Array.from({ length }, () => true); function startsDescent(list: number[], i: number): boolean { @@ -1541,7 +1541,7 @@ export class UserAPI { if (pulses >= length) return [true]; const resList = Array.from( { length }, - (_, i) => (((pulses * (i - 1)) % length) + length) % length + (_, i) => (((pulses * (i - 1)) % length) + length) % length, ); let cycle = resList.map((_, i) => startsDescent(resList, i)); if (rotate != 0) { @@ -1660,7 +1660,7 @@ export class UserAPI { triangle = ( freq: number = 1, times: number = 1, - offset: number = 0 + offset: number = 0, ): number => { /** * Returns a triangle wave between -1 and 1. @@ -1677,7 +1677,7 @@ export class UserAPI { utriangle = ( freq: number = 1, times: number = 1, - offset: number = 0 + offset: number = 0, ): number => { /** * Returns a triangle wave between 0 and 1. @@ -1694,7 +1694,7 @@ export class UserAPI { freq: number = 1, times: number = 1, offset: number = 0, - duty: number = 0.5 + duty: number = 0.5, ): number => { /** * Returns a square wave with a specified duty cycle between -1 and 1. @@ -1714,7 +1714,7 @@ export class UserAPI { freq: number = 1, times: number = 1, offset: number = 0, - duty: number = 0.5 + duty: number = 0.5, ): number => { /** * Returns a square wave between 0 and 1. @@ -1774,7 +1774,7 @@ export class UserAPI { */ const sum = values.reduce( (accumulator, currentValue) => accumulator + currentValue, - 0 + 0, ); return sum / values.length; }; @@ -1784,7 +1784,7 @@ export class UserAPI { yMin: number, yMax: number, xMin: number, - xMax: number + xMax: number, ): number => { const percent = (inputY - yMin) / (yMax - yMin); const outputX = percent * (xMax - xMin) + xMin; @@ -1814,7 +1814,7 @@ export class UserAPI { lang: string = "en-US", voice: number = 0, rate: number = 1, - pitch: number = 1 + pitch: number = 1, ): void => { /* * Speaks the given text using the browser's speech synthesis API. @@ -1889,7 +1889,7 @@ export class UserAPI { const elements = args.slice(1); // Get the rest of the arguments as an array const timepos = this.app.clock.pulses_since_origin; const slice_count = Math.floor( - timepos / Math.floor(chunk_size * this.ppqn()) + timepos / Math.floor(chunk_size * this.ppqn()), ); return elements[slice_count % elements.length]; }; @@ -1917,7 +1917,7 @@ export class UserAPI { // ============================================================= register = (name: string, operation: EventOperation): void => { - AbstractEvent.prototype[name] = function( + AbstractEvent.prototype[name] = function ( this: AbstractEvent, ...args: any[] ) { @@ -2024,7 +2024,7 @@ export class UserAPI { ".cm-comment": { fontFamily: commentFont, }, - }) + }), ), }); }; diff --git a/src/AudioVisualisation.ts b/src/AudioVisualisation.ts index a74cce8..07a9c8e 100644 --- a/src/AudioVisualisation.ts +++ b/src/AudioVisualisation.ts @@ -14,7 +14,7 @@ export const drawCircle = ( x: number, y: number, radius: number, - color: string + color: string, ): void => { // @ts-ignore const canvas: HTMLCanvasElement = app.interface.feedback; @@ -36,7 +36,7 @@ export const blinkScript = ( */ app: Editor, script: "local" | "global" | "init", - no?: number + no?: number, ) => { if (no !== undefined && no < 1 && no > 9) return; const blinkDuration = @@ -55,7 +55,7 @@ export const blinkScript = ( horizontalOffset + shift, app.interface.feedback.clientHeight - 15, 8, - "#fdba74" + "#fdba74", ); }; @@ -91,7 +91,7 @@ export const blinkScript = ( 0, 0, (app.interface.feedback as HTMLCanvasElement).width, - (app.interface.feedback as HTMLCanvasElement).height + (app.interface.feedback as HTMLCanvasElement).height, ); }, blinkDuration); } @@ -137,7 +137,7 @@ let lastRenderTime: number = 0; export const runOscilloscope = ( canvas: HTMLCanvasElement, - app: Editor + app: Editor, ): void => { /** * Runs the oscilloscope visualization on the provided canvas element. @@ -157,7 +157,7 @@ export const runOscilloscope = ( width: number, height: number, offset_height: number, - offset_width: number + offset_width: number, ) { const maxFPS = 30; const now = performance.now(); @@ -172,11 +172,11 @@ export const runOscilloscope = ( const performanceFactor = 1; const reducedDataSize = Math.floor( - freqDataArray.length * performanceFactor + freqDataArray.length * performanceFactor, ); const numBars = Math.min( reducedDataSize, - app.osc.orientation === "horizontal" ? width : height + app.osc.orientation === "horizontal" ? width : height, ); const barWidth = app.osc.orientation === "horizontal" ? width / numBars : height / numBars; @@ -189,7 +189,7 @@ export const runOscilloscope = ( for (let i = 0; i < numBars; i++) { barHeight = Math.floor( freqDataArray[Math.floor((i * freqDataArray.length) / numBars)] * - ((height / 256) * app.osc.size) + ((height / 256) * app.osc.size), ); if (app.osc.orientation === "horizontal") { @@ -197,7 +197,7 @@ export const runOscilloscope = ( x + offset_width, (height - barHeight) / 2 + offset_height, barWidth + 1, - barHeight + barHeight, ); x += barWidth; } else { @@ -205,7 +205,7 @@ export const runOscilloscope = ( (width - barHeight) / 2 + offset_width, y + offset_height, barHeight, - barWidth + 1 + barWidth + 1, ); y += barWidth; } @@ -234,7 +234,7 @@ export const runOscilloscope = ( -OFFSET_WIDTH, -OFFSET_HEIGHT, WIDTH + 2 * OFFSET_WIDTH, - HEIGHT + 2 * OFFSET_HEIGHT + HEIGHT + 2 * OFFSET_HEIGHT, ); return; } @@ -261,7 +261,7 @@ export const runOscilloscope = ( -OFFSET_WIDTH, -OFFSET_HEIGHT, WIDTH + 2 * OFFSET_WIDTH, - HEIGHT + 2 * OFFSET_HEIGHT + HEIGHT + 2 * OFFSET_HEIGHT, ); } canvasCtx.lineWidth = app.osc.thickness; diff --git a/src/Clock.ts b/src/Clock.ts index e0c3a8b..2d78671 100644 --- a/src/Clock.ts +++ b/src/Clock.ts @@ -48,7 +48,10 @@ export class Clock { lastPlayPressTime: number; totalPauseTime: number; - constructor(public app: Editor, ctx: AudioContext) { + constructor( + public app: Editor, + ctx: AudioContext, + ) { this.time_position = { bar: 0, beat: 0, pulse: 0 }; this.time_signature = [4, 4]; this.logicalTime = 0; diff --git a/src/Documentation.ts b/src/Documentation.ts index b480491..5a86c77 100644 --- a/src/Documentation.ts +++ b/src/Documentation.ts @@ -47,7 +47,7 @@ export const makeExampleFactory = (application: Editor): Function => { const make_example = ( description: string, code: string, - open: boolean = false + open: boolean = false, ) => { const codeId = `codeExample${application.exampleCounter++}`; // Store the code snippet in the data structure @@ -160,7 +160,7 @@ export const updateDocumentationContent = (app: Editor, bindings: any) => { extensions: [showdownHighlight({ auto_detection: true }), ...bindings], }); const converted_markdown = converter.makeHtml( - app.docs[app.currentDocumentationPane] + app.docs[app.currentDocumentationPane], ); document.getElementById("documentation-content")!.innerHTML = converted_markdown; diff --git a/src/Evaluator.ts b/src/Evaluator.ts index 7c5b586..2df2272 100644 --- a/src/Evaluator.ts +++ b/src/Evaluator.ts @@ -8,7 +8,7 @@ const codeReplace = (code: string): string => { const tryCatchWrapper = async ( application: Editor, - code: string + code: string, ): Promise => { /** * Wraps the provided code in a try-catch block and executes it. @@ -20,7 +20,7 @@ const tryCatchWrapper = async ( try { await new Function(`"use strict"; ${codeReplace(code)}`).call( - application.api + application.api, ); return true; } catch (error) { @@ -48,7 +48,7 @@ const addFunctionToCache = (code: string, fn: Function) => { export const tryEvaluate = async ( application: Editor, code: File, - timeout = 5000 + timeout = 5000, ): Promise => { /** * Tries to evaluate the provided code within a specified timeout period. @@ -77,7 +77,7 @@ export const tryEvaluate = async ( if (isCodeValid) { code.committed = code.candidate; const newFunction = new Function( - `"use strict"; ${codeReplace(wrappedCode)}` + `"use strict"; ${codeReplace(wrappedCode)}`, ); addFunctionToCache(candidateCode, newFunction); } else { @@ -93,7 +93,7 @@ export const tryEvaluate = async ( export const evaluate = async ( application: Editor, code: File, - timeout = 1000 + timeout = 1000, ): Promise => { /** * Evaluates the given code using the provided application and timeout. @@ -117,7 +117,7 @@ export const evaluate = async ( export const evaluateOnce = async ( application: Editor, - code: string + code: string, ): Promise => { /** * Evaluates the code once without any caching or error-handling mechanisms besides the tryCatchWrapper. diff --git a/src/FileManagement.ts b/src/FileManagement.ts index 093af7a..145b3d1 100644 --- a/src/FileManagement.ts +++ b/src/FileManagement.ts @@ -154,7 +154,7 @@ export class AppSettings { constructor() { const settingsFromStorage = JSON.parse( - localStorage.getItem("topos") || "{}" + localStorage.getItem("topos") || "{}", ); if (settingsFromStorage && Object.keys(settingsFromStorage).length !== 0) { @@ -210,7 +210,7 @@ export class AppSettings { saveApplicationToLocalStorage( universes: Universes, - settings: Settings + settings: Settings, ): void { /** * Main method to store the application to local storage. @@ -328,7 +328,7 @@ export const loadUniverserFromUrl = (app: Editor): void => { export const loadUniverse = ( app: Editor, universeName: string, - universe: Universe = template_universe + universe: Universe = template_universe, ): void => { /** * Loads a universe into the application. diff --git a/src/Utils/Generic.ts b/src/Utils/Generic.ts index 7b0d309..e6c9190 100644 --- a/src/Utils/Generic.ts +++ b/src/Utils/Generic.ts @@ -1,6 +1,6 @@ export function objectWithArraysToArrayOfObjects( input: Record, - arraysToArrays: string[] + arraysToArrays: string[], ): Record[] { /* * Transforms object with arrays into array of objects @@ -24,7 +24,7 @@ export function objectWithArraysToArrayOfObjects( acc.keys.push(key); return acc; }, - { keys: [] as string[], maxLength: 0 } + { keys: [] as string[], maxLength: 0 }, ); const output: Record[] = []; @@ -44,7 +44,7 @@ export function objectWithArraysToArrayOfObjects( export function arrayOfObjectsToObjectWithArrays>( array: T[], - mergeObject: Record = {} + mergeObject: Record = {}, ): Record { /* * Transforms array of objects into object with arrays @@ -54,21 +54,24 @@ export function arrayOfObjectsToObjectWithArrays>( * @returns {object} Merged object with arrays * */ - return array.reduce((acc, obj) => { - const mergedObj = { ...obj, ...mergeObject }; - Object.keys(mergedObj).forEach((key) => { - if (!acc[key]) { - acc[key] = []; - } - acc[key].push(mergedObj[key]); - }); - return acc; - }, {} as Record); + return array.reduce( + (acc, obj) => { + const mergedObj = { ...obj, ...mergeObject }; + Object.keys(mergedObj).forEach((key) => { + if (!acc[key]) { + acc[key] = []; + } + acc[key].push(mergedObj[key]); + }); + return acc; + }, + {} as Record, + ); } export function filterObject( obj: Record, - filter: string[] + filter: string[], ): Record { /* * Filter certain keys from object @@ -79,6 +82,6 @@ export function filterObject( * */ return Object.fromEntries( - Object.entries(obj).filter(([key]) => filter.includes(key)) + Object.entries(obj).filter(([key]) => filter.includes(key)), ); } diff --git a/src/WindowBehavior.ts b/src/WindowBehavior.ts index b5e5a1d..1282738 100644 --- a/src/WindowBehavior.ts +++ b/src/WindowBehavior.ts @@ -32,13 +32,13 @@ export const saveBeforeExit = (app: Editor): null => { export const installWindowBehaviors = ( app: Editor, window: Window, - preventMultipleTabs: boolean = false + preventMultipleTabs: boolean = false, ) => { window.addEventListener("resize", () => - handleResize(app.interface.scope as HTMLCanvasElement) + handleResize(app.interface.scope as HTMLCanvasElement), ); window.addEventListener("resize", () => - handleResize(app.interface.feedback as HTMLCanvasElement) + handleResize(app.interface.feedback as HTMLCanvasElement), ); window.addEventListener("beforeunload", (event) => { event.preventDefault(); @@ -61,11 +61,11 @@ export const installWindowBehaviors = ( if (e.key == "page_available") { document.getElementById("all")!.classList.add("invisible"); alert( - "Topos is already opened in another tab. Close this tab now to prevent data loss." + "Topos is already opened in another tab. Close this tab now to prevent data loss.", ); } }, - false + false, ); } }; diff --git a/src/classes/SoundEvent.ts b/src/classes/SoundEvent.ts index cb65f6d..7aef672 100644 --- a/src/classes/SoundEvent.ts +++ b/src/classes/SoundEvent.ts @@ -38,7 +38,7 @@ export class SoundEvent extends AudibleEvent { public updateValue( key: string, - value: T | T[] | SoundParams[] | null + value: T | T[] | SoundParams[] | null, ): this { if (value == null) return this; this.values[key] = value; @@ -82,7 +82,7 @@ export class SoundEvent extends AudibleEvent { a: number, d: number, s: number, - r: number + r: number, ) { self.updateValue("fmattack", a); self.updateValue("fmdecay", d); @@ -106,7 +106,7 @@ export class SoundEvent extends AudibleEvent { a: number, d: number, s: number, - r: number + r: number, ) { self.updateValue("attack", a); self.updateValue("decay", d); @@ -152,7 +152,7 @@ export class SoundEvent extends AudibleEvent { a: number, d: number, s: number, - r: number + r: number, ) { self.updateValue("lpenv", depth); self.updateValue("lpattack", a); @@ -198,7 +198,7 @@ export class SoundEvent extends AudibleEvent { a: number, d: number, s: number, - r: number + r: number, ) { self.updateValue("hpenv", depth); self.updateValue("hpattack", a); @@ -241,7 +241,7 @@ export class SoundEvent extends AudibleEvent { a: number, d: number, s: number, - r: number + r: number, ) { self.updateValue("bpenv", depth); self.updateValue("bpattack", a); @@ -336,7 +336,10 @@ export class SoundEvent extends AudibleEvent { }, }; - constructor(sound: string | string[] | SoundParams, public app: Editor) { + constructor( + sound: string | string[] | SoundParams, + public app: Editor, + ) { super(app); this.nudge = app.dough_nudge / 100; @@ -367,7 +370,7 @@ export class SoundEvent extends AudibleEvent { } private processSound = ( - sound: string | string[] | SoundParams | SoundParams[] + sound: string | string[] | SoundParams | SoundParams[], ): SoundParams => { if (Array.isArray(sound) && typeof sound[0] === "string") { const s: string[] = []; @@ -438,7 +441,7 @@ export class SoundEvent extends AudibleEvent { (event.key as number) || "C4", (event.pitch as number) || 0, (event.parsedScale as number[]) || event.scale || "MAJOR", - (event.octave as number) || 0 + (event.octave as number) || 0, ); event.note = note; event.freq = midiToFreq(note); @@ -458,7 +461,7 @@ export class SoundEvent extends AudibleEvent { public invert = (howMany: number = 0) => { if (this.values.chord) { let notes = this.values.chord.map( - (obj: { [key: string]: number }) => obj.note + (obj: { [key: string]: number }) => obj.note, ); notes = howMany < 0 ? [...notes].reverse() : notes; for (let i = 0; i < Math.abs(howMany); i++) { @@ -500,7 +503,7 @@ export class SoundEvent extends AudibleEvent { superdough( filteredEvent, this.nudge - this.app.clock.deviation, - filteredEvent.dur + filteredEvent.dur, ); } }; diff --git a/src/classes/ZPlayer.ts b/src/classes/ZPlayer.ts index c4f13fa..d945fde 100644 --- a/src/classes/ZPlayer.ts +++ b/src/classes/ZPlayer.ts @@ -29,7 +29,7 @@ export class Player extends AbstractEvent { input: string | number | Generator, options: InputOptions, public app: Editor, - zid: string = "" + zid: string = "", ) { super(app); this.options = options; @@ -159,7 +159,7 @@ export class Player extends AbstractEvent { if (this.areWeThereYet()) { const event = this.next() as Pitch | Chord | ZRest; const noteLengthInSeconds = this.app.clock.convertPulseToSecond( - event.duration * 4 * this.app.clock.ppqn + event.duration * 4 * this.app.clock.ppqn, ); if (event instanceof Pitch) { const obj = event.getExisting( @@ -169,7 +169,7 @@ export class Player extends AbstractEvent { "key", "scale", "octave", - "parsedScale" + "parsedScale", ) as SoundParams; if (event.sound) name = event.sound as string; if (event.soundIndex) obj.n = event.soundIndex as number; @@ -184,14 +184,14 @@ export class Player extends AbstractEvent { "key", "scale", "octave", - "parsedScale" + "parsedScale", ); }) as SoundParams[]; const add = { dur: noteLengthInSeconds } as SoundParams; if (name) add.s = name; let sound = arrayOfObjectsToObjectWithArrays( pitches, - add + add, ) as SoundParams; return new SoundEvent(sound, this.app); } else if (event instanceof ZRest) { @@ -212,7 +212,7 @@ export class Player extends AbstractEvent { "key", "scale", "octave", - "parsedScale" + "parsedScale", ) as MidiParams; if (event instanceof Pitch) { if (event.soundIndex) obj.channel = event.soundIndex as number; diff --git a/src/documentation/more/bonus.ts b/src/documentation/more/bonus.ts index 1138c04..a262288 100644 --- a/src/documentation/more/bonus.ts +++ b/src/documentation/more/bonus.ts @@ -20,11 +20,11 @@ Some features have been included as a bonus. These features are often about patt ${makeExample( "Hydra integration", `beat(4) :: hydra.osc(3, 0.5, 2).out()`, - true + true, )} Close the documentation to see the effect: ${key_shortcut( - "Ctrl+D" + "Ctrl+D", )}! **Boom, all shiny!** Be careful not to call hydra too often as it can impact performances. You can use any rhythmical function like beat() function to limit the number of function calls. You can write any Topos code like [1,2,3].beat() to bring some life and movement in your Hydra sketches. @@ -37,7 +37,7 @@ ${makeExample( beat(4) :: stop_hydra() // this one beat(4) :: hydra.hush() // or this one `, - true + true, )} @@ -48,7 +48,7 @@ You can change Hydra resolution using this simple method: ${makeExample( "Changing Hydra resolution", `hydra.setResolution(1024, 768)`, - true + true, )} ### Documentation @@ -82,7 +82,7 @@ beat(0.25)::gif({ posX: ir(1,1200), // CSS Horizontal Position posY: ir(1, 800), // CSS Vertical Position `, - true + true, )} `; }; diff --git a/src/documentation/samples/sample_list.ts b/src/documentation/samples/sample_list.ts index 49b1c85..b8ba417 100644 --- a/src/documentation/samples/sample_list.ts +++ b/src/documentation/samples/sample_list.ts @@ -65,12 +65,12 @@ On this page, you will find an exhaustive list of all the samples currently load A very large collection of wavetables for wavetable synthesis. This collection has been released by Kristoffer Ekstrand: [AKWF Waveforms](https://www.adventurekid.se/akrt/waveforms/adventure-kid-waveforms/). Every sound sample that starts with wt_ will be looped. Look at this demo: ${makeExample( - "Wavetable synthesis made easy :)", - ` + "Wavetable synthesis made easy :)", + ` beat(0.5)::sound('wt_stereo').n([0, 1].pick()).ad(0, .25).out() `, - true, - )} + true, +)} Pick one folder and spend some time exploring it. There is a lot of different waveforms. @@ -84,12 +84,12 @@ ${samples_to_markdown(application, "Waveforms")} A set of 72 classic drum machines created by **Geikha**: [Geikha Drum Machines](https://github.com/geikha/tidal-drum-machines). To use them efficiently, it is best to use the .bank() parameter like so: ${makeExample( - "Using a classic drum machine", - ` + "Using a classic drum machine", + ` beat(0.5)::sound(['bd', 'cp'].pick()).bank("AkaiLinn").out() `, - true, - )} + true, +)} Here is the complete list of available machines: @@ -119,12 +119,12 @@ ${samples_to_markdown(application, "Amiga")} A collection of many different amen breaks. Use .stretch() to play with these: ${makeExample( - "Stretching an amen break", - ` + "Stretching an amen break", + ` beat(4)::sound('amen1').stretch(4).out() `, - true, - )} + true, +)} The stretch should be adapted based on the length of each amen break. diff --git a/src/main.ts b/src/main.ts index 26990cc..a8d8677 100644 --- a/src/main.ts +++ b/src/main.ts @@ -246,7 +246,7 @@ export class Editor { * If any required elements or templates are missing, warning messages are logged and the function returns early. */ let itemTemplate = document.getElementById( - "ui-known-universe-item-template" + "ui-known-universe-item-template", ) as HTMLTemplateElement; if (!itemTemplate) { console.warn("Missing template #ui-known-universe-item-template"); @@ -274,10 +274,10 @@ export class Editor { item .querySelector(".delete-universe") ?.addEventListener("click", () => - api._deleteUniverseFromInterface(it) + api._deleteUniverseFromInterface(it), ); return item; - }) + }), ); existing_universes.innerHTML = ""; @@ -369,7 +369,7 @@ export class Editor { this.view.dispatch({ effects: this.chosenLanguage.reconfigure( - this.editor_mode == "notes" ? [markdown()] : [javascript()] + this.editor_mode == "notes" ? [markdown()] : [javascript()], ), }); @@ -378,7 +378,7 @@ export class Editor { setButtonHighlighting( button: "play" | "pause" | "stop" | "clear", - highlight: boolean + highlight: boolean, ) { /** * Sets the highlighting for a specific button. @@ -432,7 +432,7 @@ export class Editor { // All other buttons must lose the highlighting document .querySelectorAll( - possible_selectors.filter((_, index) => index != selector).join(",") + possible_selectors.filter((_, index) => index != selector).join(","), ) .forEach((button) => { button.children[0].classList.remove("animate-pulse"); @@ -478,28 +478,28 @@ export class Editor { */ const domElement = this.view.dom; const gutters = domElement.getElementsByClassName( - "cm-gutter" + "cm-gutter", ) as HTMLCollectionOf; domElement.classList.add("fluid-bg-transition"); Array.from(gutters).forEach((gutter) => - gutter.classList.add("fluid-bg-transition") + gutter.classList.add("fluid-bg-transition"), ); domElement.style.backgroundColor = color; Array.from(gutters).forEach( - (gutter) => (gutter.style.backgroundColor = color) + (gutter) => (gutter.style.backgroundColor = color), ); setTimeout(() => { domElement.style.backgroundColor = ""; Array.from(gutters).forEach( - (gutter) => (gutter.style.backgroundColor = "") + (gutter) => (gutter.style.backgroundColor = ""), ); domElement.classList.remove("fluid-bg-transition"); Array.from(gutters).forEach((gutter) => - gutter.classList.remove("fluid-bg-transition") + gutter.classList.remove("fluid-bg-transition"), ); }, duration); } @@ -507,7 +507,7 @@ export class Editor { private initializeElements(): void { for (const [key, value] of Object.entries(singleElements)) { this.interface[key] = document.getElementById( - value + value, ) as ElementMap[keyof ElementMap]; } } @@ -515,7 +515,7 @@ export class Editor { private initializeButtonGroups(): void { for (const [key, ids] of Object.entries(buttonGroups)) { this.buttonElements[key] = ids.map( - (id) => document.getElementById(id) as HTMLButtonElement + (id) => document.getElementById(id) as HTMLButtonElement, ); } } diff --git a/tsconfig.json b/tsconfig.json index 1ad475b..641e63e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ /* Linting */ "strict": true, - "forceConsistentCasingInFileNames": true, + "forceConsistentCasingInFileNames": true, "useDefineForClassFields": true, "noUnusedLocals": true, "noUnusedParameters": true,