Compare commits

..

11 Commits

Author SHA1 Message Date
alex 185abf1fc1 abandoned experiment 2023-01-21 09:12:41 +00:00
alex 37efdd9ce1 prettier 2023-01-16 21:55:16 +00:00
alex f4039d3666 Merge branch 'main' into composable 2023-01-16 21:47:46 +00:00
Alex McLean c0d6e36113 Merge branch 'main' into composable 2023-01-12 16:47:47 +00:00
Alex McLean 8261802078 more hackery, composing seems to work now 2023-01-12 16:36:42 +00:00
alex 6dda6bac66 more composable magic 2023-01-11 22:27:00 +00:00
alex d5ab1a3471 actually compose functions together 2023-01-11 21:59:10 +00:00
alex ded90733f6 mark up more function args 2023-01-11 20:30:07 +00:00
alex c64485db99 hack register to support function parameters that can be patterns which compose 2023-01-10 23:28:22 +00:00
alex afa5d6e704 prettier 2023-01-10 11:16:43 +00:00
alex bde7e79a38 failed attempt at composifying 2023-01-10 11:05:51 +00:00
193 changed files with 52280 additions and 23387 deletions
-3
View File
@@ -15,6 +15,3 @@ vite.config.js
!**/*.mjs
**/*.tsx
**/*.ts
**/*.json
**/dev-dist
**/dist
+2 -3
View File
@@ -9,9 +9,8 @@
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["import"],
"plugins": [],
"rules": {
"no-unused-vars": ["warn", { "destructuredArrayIgnorePattern": ".", "ignoreRestSiblings": false }],
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}]
"no-unused-vars": ["warn", { "destructuredArrayIgnorePattern": ".", "ignoreRestSiblings": false }]
}
}
+3 -6
View File
@@ -22,18 +22,15 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v2
- uses: pnpm/action-setup@v2
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
cache: "npm"
- name: Install Dependencies
run: pnpm install
run: npm ci && cd website && npm ci
- name: Build
run: pnpm build
run: npm run build
- name: Setup Pages
uses: actions/configure-pages@v2
+5 -8
View File
@@ -11,14 +11,11 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: pnpm/action-setup@v2
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- run: pnpm install
- run: pnpm run format-check
- run: pnpm run lint
- run: pnpm test
cache: "npm"
- run: npm install
- run: npm run format-check
- run: npm run lint
- run: npm test
+1 -3
View File
@@ -37,6 +37,4 @@ talk/public/EmuSP12
talk/public/samples
server/samples/old
repl/stats.html
coverage
public/icons/apple-splash-*
dev-dist
coverage
+1 -4
View File
@@ -6,7 +6,4 @@
**/dist
packages/mini/krill-parser.js
packages/xen/tunejs.js
paper
pnpm-lock.yaml
pnpm-workspace.yaml
**/dev-dist
paper
+1 -1
View File
@@ -7,7 +7,7 @@
"jsxSingleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": false,
"jsxBracketSameLine": false,
"arrowParens": "always",
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
+11 -34
View File
@@ -58,22 +58,23 @@ To fix a bug that has been reported,
## Write Tests
There are still many tests that have not been written yet! Reading and writing tests is a great opportunity to get familiar with the codebase.
You can find the tests in each package in the `test` folder. To run all tests, run `pnpm test` from the root folder.
You can find the tests in each package in the `test` folder. To run all tests, run `npm test` from the root folder.
## Project Setup
To get the project up and running for development, make sure you have installed:
- [git](https://git-scm.com/)
- [node](https://nodejs.org/en/) >= 18
- [pnpm](https://pnpm.io/) (`npm i pnpm -g`)
- git
- node, preferably v16
then, do the following:
```sh
git clone https://github.com/tidalcycles/strudel.git && cd strudel
pnpm i # install at root to symlink packages
pnpm start # start repl
npm i # install at root to symlink packages
npx lerna bootstrap # install all dependencies in packages
cd repl && npm i # install repl dependencies
npm run start # start repl
```
Those commands might look slightly different for your OS.
@@ -82,10 +83,6 @@ Please report any problems you've had with the setup instructions!
## Code Style
To make sure the code changes only where it should, we are using prettier to unify the code style.
- You can format all files at once by running `pnpm prettier` from the project root
- Run `pnpm format-check` from the project root to check if all files are well formatted
If you use VSCode, you can
1. install [the prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
@@ -93,29 +90,12 @@ If you use VSCode, you can
3. Choose "Configure Default Formatter..."
4. Select prettier
## ESLint
To prevent unwanted runtime errors, this project uses [eslint](https://eslint.org/).
- You can check for lint errors by running `pnpm lint`
There are also eslint extensions / plugins for most editors.
## Running Tests
- Run all tests with `pnpm test`
- Run all tests with UI using `pnpm test-ui`
## Running all CI Checks
When opening a PR, the CI runner will automatically check the code style and eslint, as well as run all tests.
You can run the same check with `pnpm check`
## Package Workflow
The project is split into multiple [packages](https://github.com/tidalcycles/strudel/tree/main/packages) with independent versioning.
When you run `pnpm i` on the root folder, [pnpm workspaces](https://pnpm.io/workspaces) will install all dependencies of all subpackages. This will allow any js file to import `@strudel.cycles/<package-name>` to get the local version,
allowing to develop multiple packages at the same time.
When you run `npm i` on the root folder, [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces) will symlink all packages
in the `node_modules` folder. This will allow any js file to import `@strudel.cycles/<package-name>` to get the local version,
which allows developing multiple packages at the same time
## Package Publishing
@@ -126,15 +106,12 @@ npm login
npx lerna publish
```
To manually publish a single package, increase the version in the `package.json`, then run `pnpm publish`.
Important: Always publish with `pnpm`, as `npm` does not support overriding main files in `publishConfig`, which is done in all the packages.
### New Packages
To add a new package, you have to publish it manually the first time, using:
```sh
cd packages/<package-name> && pnpm publish --access public
cd packages/<package-name> && npm publish --access public
```
## Have Fun
-1
View File
@@ -7,7 +7,6 @@ An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using w
- Try it here: <https://strudel.tidalcycles.org/>
- Docs: <https://strudel.tidalcycles.org/learn/>
- Technical Blog Post: <https://loophole-letters.vercel.app/strudel>
- 1 Year of Strudel Blog Post: <https://loophole-letters.vercel.app/strudel1year>
## Running Locally
+1 -3
View File
@@ -2,7 +2,5 @@
"packages": [
"packages/*"
],
"version": "independent",
"npmClient": "pnpm",
"useWorkspaces": true
"version": "independent"
}
+10 -49
View File
@@ -3,57 +3,18 @@
This directory can be used to save your own patterns, which then get
made into a pattern swatch.
Example: <https://felixroos.github.io/strudel/swatch/>
0. fork and clone the strudel repository
1. run `npm run setup` in the strudel folder
1. Save one or more .txt files in this folder
2. run `npm run repl` in the top-level strudel folder
3. open `http://localhost:3000/swatch/` !
## deploy
### 1. fork the [strudel repo on github](https://github.com/tidalcycles/strudel.git)
### 2. clone your fork to your machine `git clone https://github.com/<your-username>/strudel.git strudel && cd strudel`
### 3. create a separate branch like `git branch patternuary && git checkout patternuary`
### 4. save one or more .txt files in the my-patterns folder
### 5. edit `website/public/CNAME` to contain `<your-username>.github.io/strudel`
### 6. edit `website/astro.config.mjs` to use site: `https://<your-username>.github.io` and base `/strudel`, like this
```js
const site = 'https://<your-username>.github.io';
const base = '/strudel';
```
### 7. commit & push the changes
```sh
git add . && git commit -m "site config" && git push --set-upstream origin
```
### 8. deploy to github pages
- go to settings -> pages and select "Github Actions" as source
- go to settings -> environments -> github-pages and press the edit button next to `main` and type in `patternuary` (under "Deployment branches")
- go to Actions -> `Build and Deploy` and click `Run workflow` with branch `patternuary`
### 9. view your patterns at `<your-username>.github.io/strudel/swatch/`
1. in your fork, go to settings -> pages and select "Github Actions" as source
2. edit `website/public/CNAME` to contain `<your-username>.github.io/strudel`
3. edit `website/astro.config.mjs` to use site: `https://<your-username>.github.io` and base `/strudel`
4. go to Actions -> `Build and Deploy` and click `Run workflow`
5. view your patterns at `<your-username>.github.io/strudel/swatch/`
Alternatively, github pages allows you to use a custom domain, like https://mycooldomain.org/swatch/. [See their documentation for details](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site).
### 10. optional: automatic deployment
If you want to automatically deploy your site on push, go to `deploy.yml` and change `workflow_dispatch` to `push`.
## running locally
- install dependencies with `npm run setup`
- run dev server with `npm run repl` and open `http://localhost:3000/strudel/swatch/`
## tests fail?
Your tests might fail if the code does not follow prettiers format.
In that case, run `npm run codeformat`. To disable that, remove `npm run format-check` from `test.yml`
## updating your fork
To update your fork, you can pull the main branch and merge it into your `patternuary` branch.
+22021
View File
File diff suppressed because it is too large Load Diff
+15 -23
View File
@@ -4,20 +4,18 @@
"private": true,
"description": "Port of tidalcycles to javascript",
"scripts": {
"setup": "pnpm i",
"pretest": "npm run jsdoc-json",
"prebuild": "npm run jsdoc-json",
"prestart": "npm run jsdoc-json",
"test": "npm run pretest && vitest run --version",
"test-ui": "npm run pretest && vitest --ui",
"test-coverage": "npm run pretest && vitest --coverage",
"snapshot": "npm run pretest && vitest run -u --silent",
"repl": "npm run prestart && cd website && npm run dev",
"start": "npm run prestart && cd website && npm run dev",
"dev": "npm run prestart && cd website && npm run dev",
"build": "npm run prebuild && cd website && npm run build",
"preview": "cd website && npm run preview",
"test": "vitest run --version",
"test-ui": "vitest --ui",
"test-coverage": "vitest --coverage",
"bootstrap": "lerna bootstrap",
"setup": "npm i && npm run jsdoc-json && npm run bootstrap && cd website && npm i",
"snapshot": "vitest run -u --silent",
"repl": "cd website && npm run dev",
"osc": "cd packages/osc && npm run server",
"build": "cd website && npm run build",
"preview": "cd website && npm run preview",
"deploy": "NODE_DEBUG=gh-pages gh-pages -d out",
"jsdoc": "jsdoc packages/ -c jsdoc.config.json",
"jsdoc-json": "jsdoc packages/ --template ./node_modules/jsdoc-json --destination doc.json -c jsdoc.config.json",
@@ -28,6 +26,9 @@
"check": "npm run format-check && npm run lint && npm run test",
"iclc": "cd paper && pandoc --template=pandoc/iclc.html --citeproc --number-sections iclc2023.md -o iclc2023.html && pandoc --template=pandoc/iclc.latex --citeproc --number-sections iclc2023.md -o iclc2023.pdf"
},
"workspaces": [
"packages/*"
],
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
@@ -45,22 +46,12 @@
"url": "https://github.com/tidalcycles/strudel/issues"
},
"homepage": "https://strudel.tidalcycles.org",
"dependencies": {
"dependency-tree": "^9.0.0",
"vitest": "^0.25.7",
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/mini": "workspace:*",
"@strudel.cycles/tonal": "workspace:*",
"@strudel.cycles/transpiler": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/xen": "workspace:*"
},
"devDependencies": {
"@vitest/ui": "^0.25.7",
"c8": "^7.12.0",
"canvas": "^2.11.0",
"dependency-tree": "^9.0.0",
"eslint": "^8.28.0",
"eslint-plugin-import": "^2.27.5",
"events": "^3.3.0",
"gh-pages": "^4.0.0",
"jsdoc": "^3.6.10",
@@ -68,6 +59,7 @@
"jsdoc-to-markdown": "^7.1.1",
"lerna": "^4.0.0",
"prettier": "^2.8.1",
"rollup-plugin-visualizer": "^5.8.1"
"rollup-plugin-visualizer": "^5.8.1",
"vitest": "^0.25.7"
}
}
+3 -4
View File
@@ -33,7 +33,6 @@ b: 3/2 - 7/4
c: 7/4 - 2
```
- [play with @strudel.cycles/core on codesandbox](https://codesandbox.io/s/strudel-core-test-forked-9ywhv7?file=/src/index.js).
- [open color pattern example](https://raw.githack.com/tidalcycles/strudel/main/packages/core/examples/canvas.html)
- [open minimal repl example](https://raw.githack.com/tidalcycles/strudel/main/packages/core/examples/vanilla.html)
- [open minimal vite example](./examples/vite-vanilla-repl/)
- [play with @strudel.cycles/core on codesandbox](https://codesandbox.io/s/strudel-core-test-qmz6qr?file=/src/index.js).
- [open color pattern example](https://raw.githack.com/tidalcycles/strudel/package-examples/packages/core/examples/canvas.html)
- [open minimal repl example](https://raw.githack.com/tidalcycles/strudel/package-examples/packages/core/examples/metro.html)
+4 -4
View File
@@ -22,11 +22,11 @@ Pattern.prototype.animate = function ({ callback, sync = false, smear = 0.5 } =
ctx.fillStyle = clearColor;
ctx.fillRect(0, 0, ww, wh);
frame.forEach((f) => {
let { x, y, w, h, s, r, angle = 0, fill = 'darkseagreen' } = f.value;
let { x, y, w, h, s, r, a = 0, fill = 'darkseagreen' } = f.value;
w *= ww;
h *= wh;
if (r !== undefined && angle !== undefined) {
const radians = angle * 2 * Math.PI;
if (r !== undefined && a !== undefined) {
const radians = a * 2 * Math.PI;
const [cx, cy] = [(ww - w) / 2, (wh - h) / 2];
x = cx + Math.cos(radians) * r * cx;
y = cy + Math.sin(radians) * r * cy;
@@ -51,7 +51,7 @@ Pattern.prototype.animate = function ({ callback, sync = false, smear = 0.5 } =
return silence;
};
export const { x, y, w, h, angle, r, fill, smear } = createParams('x', 'y', 'w', 'h', 'angle', 'r', 'fill', 'smear');
export const { x, y, w, h, a, r, fill, smear } = createParams('x', 'y', 'w', 'h', 'a', 'r', 'fill', 'smear');
export const rescale = register('rescale', function (f, pat) {
return pat.mul(x(f).w(f).y(f).h(f));
+79 -88
View File
@@ -4,13 +4,22 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Pattern, sequence, registerControl } from './pattern.mjs';
import { Pattern, sequence } from './pattern.mjs';
const controls = {};
const generic_params = [
/**
* Select a sound / sample by name.
*
* <details style={{display:'none'}}>
* <summary>show all sounds</summary>
*
* 808 (6) 808bd (25) 808cy (25) 808hc (5) 808ht (5) 808lc (5) 808lt (5) 808mc (5) 808mt (5) 808oh (5) 808sd (25) 909 (1) ab (12) ade (10) ades2 (9) ades3 (7) ades4 (6) alex (2) alphabet (26) amencutup (32) armora (7) arp (2) arpy (11) auto (11) baa (7) baa2 (7) bass (4) bass0 (3) bass1 (30) bass2 (5) bass3 (11) bassdm (24) bassfoo (3) battles (2) bd (24) bend (4) bev (2) bin (2) birds (10) birds3 (19) bleep (13) blip (2) blue (2) bottle (13) breaks125 (2) breaks152 (1) breaks157 (1) breaks165 (1) breath (1) bubble (8) can (14) casio (3) cb (1) cc (6) chin (4) circus (3) clak (2) click (4) clubkick (5) co (4) coins (1) control (2) cosmicg (15) cp (2) cr (6) crow (4) d (4) db (13) diphone (38) diphone2 (12) dist (16) dork2 (4) dorkbot (2) dr (42) dr2 (6) dr55 (4) dr_few (8) drum (6) drumtraks (13) e (8) east (9) electro1 (13) em2 (6) erk (1) f (1) feel (7) feelfx (8) fest (1) fire (1) flick (17) fm (17) foo (27) future (17) gab (10) gabba (4) gabbaloud (4) gabbalouder (4) glasstap (3) glitch (8) glitch2 (8) gretsch (24) gtr (3) h (7) hand (17) hardcore (12) hardkick (6) haw (6) hc (6) hh (13) hh27 (13) hit (6) hmm (1) ho (6) hoover (6) house (8) ht (16) if (5) ifdrums (3) incoming (8) industrial (32) insect (3) invaders (18) jazz (8) jungbass (20) jungle (13) juno (12) jvbass (13) kicklinn (1) koy (2) kurt (7) latibro (8) led (1) less (4) lighter (33) linnhats (6) lt (16) made (7) made2 (1) mash (2) mash2 (4) metal (10) miniyeah (4) monsterb (6) moog (7) mouth (15) mp3 (4) msg (9) mt (16) mute (28) newnotes (15) noise (1) noise2 (8) notes (15) numbers (9) oc (4) odx (15) off (1) outdoor (6) pad (3) padlong (1) pebbles (1) perc (6) peri (15) pluck (17) popkick (10) print (11) proc (2) procshort (8) psr (30) rave (8) rave2 (4) ravemono (2) realclaps (4) reverbkick (1) rm (2) rs (1) sax (22) sd (2) seawolf (3) sequential (8) sf (18) sheffield (1) short (5) sid (12) sine (6) sitar (8) sn (52) space (18) speakspell (12) speech (7) speechless (10) speedupdown (9) stab (23) stomp (10) subroc3d (11) sugar (2) sundance (6) tabla (26) tabla2 (46) tablex (3) tacscan (22) tech (13) techno (7) tink (5) tok (4) toys (13) trump (11) ul (10) ulgab (5) uxay (3) v (6) voodoo (5) wind (10) wobble (1) world (3) xmas (1) yeah (31)
*
* <a href="https://tidalcycles.org/docs/configuration/Audio%20Samples/default_library" target="_blank">more info</a>
*
* </details>
*
* @name s
* @param {string | Pattern} sound The sound / pattern of sounds to pick
* @example
@@ -19,36 +28,20 @@ const generic_params = [
*/
['s', 's', 'sound'],
/**
* Selects the given index from the sample map.
* Numbers too high will wrap around.
* `n` can also be used to play midi numbers, but it is recommended to use `note` instead.
* The note or sample number to choose for a synth or sampleset
* Note names currently not working yet, but will hopefully soon. Just stick to numbers for now
*
* @name n
* @param {number | Pattern} value sample index starting from 0
* @param {string | number | Pattern} value note name, note number or sample number
* @example
* s("bd sd,hh*3").n("<0 1>")
* s('superpiano').n("<0 1 2 3>").osc()
* @example
* s('superpiano').n("<c4 d4 e4 g4>").osc()
* @example
* n("0 1 2 3").s('east').osc()
*/
// also see https://github.com/tidalcycles/strudel/pull/63
['f', 'n', 'The sample number to choose for a synth or sampleset'],
/**
* Plays the given note name or midi number. A note name consists of
*
* - a letter (a-g or A-G)
* - optional accidentals (b or #)
* - optional octave number (0-9). Defaults to 3
*
* Examples of valid note names: `c`, `bb`, `Bb`, `f#`, `c3`, `A4`, `Eb2`, `c#5`
*
* You can also use midi numbers instead of note names, where 69 is mapped to A4 440Hz in 12EDO.
*
* @name note
* @example
* note("c a f e")
* @example
* note("c4 a4 f4 e4")
* @example
* note("60 69 65 64")
*/
['f', 'n', 'The note or sample number to choose for a synth or sampleset'],
['f', 'note', 'The note or pitch to play a sound or synth with'],
//['s', 'toArg', 'for internal sound routing'],
// ["f", "from", "for internal sound routing"),
@@ -90,7 +83,8 @@ const generic_params = [
*/
['f', 'amp', 'like @gain@, but linear.'],
/**
* Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset.
* A pattern of numbers to specify the attack time of an envelope applied to each sample.
* [More info about envelopes](/learn/synths-samples-effects/#envelope)
*
* @name attack
* @param {number | Pattern} attack time in seconds.
@@ -98,7 +92,11 @@ const generic_params = [
* note("c3 e3").attack("<0 .1 .5>")
*
*/
['f', 'attack'],
[
'f',
'attack',
'a pattern of numbers to specify the attack time (in seconds) of an envelope applied to each sample.',
],
/**
* Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`.
@@ -112,8 +110,8 @@ const generic_params = [
['f', 'bank', 'selects sound bank to use'],
/**
* Amplitude envelope decay time: the time it takes after the attack time to reach the sustain level.
* Note that the decay is only audible if the sustain value is lower than 1.
* Gain envelope decay time = the time it takes after the attack time to reach the sustain level.
* [More info about envelopes](/learn/synths-samples-effects/#envelope)
*
* @name decay
* @param {number | Pattern} time decay time in seconds
@@ -123,7 +121,7 @@ const generic_params = [
*/
['f', 'decay', ''],
/**
* Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset.
* Gain envelope sustain level. [More info about envelopes](/learn/synths-samples-effects/#envelope)
*
* @name sustain
* @param {number | Pattern} gain sustain level between 0 and 1
@@ -133,7 +131,7 @@ const generic_params = [
*/
['f', 'sustain', ''],
/**
* Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero.
* Gain envelope release time. [More info about envelopes](/learn/synths-samples-effects/#envelope)
*
* @name release
* @param {number | Pattern} time release time in seconds
@@ -153,30 +151,30 @@ const generic_params = [
],
// TODO: in tidal, it seems to be normalized
/**
* Sets the center frequency of the **b**and-**p**ass **f**ilter.
* Sets the center frequency of the band-pass filter.
*
* @name bpf
* @name bandf
* @param {number | Pattern} frequency center frequency
* @synonyms bandf
* @synonyms bpf
* @example
* s("bd sd,hh*3").bpf("<1000 2000 4000 8000>")
* s("bd sd,hh*3").bandf("<1000 2000 4000 8000>")
*
*/
['f', 'bpf', ''],
['f', 'bandf', 'A pattern of numbers from 0 to 1. Sets the center frequency of the band-pass filter.'],
['f', 'bpf', ''],
// TODO: in tidal, it seems to be normalized
/**
* Sets the **b**and-**p**ass **q**-factor (resonance)
* Sets the q-factor of the band-pass filter
*
* @name bpq
* @name bandq
* @param {number | Pattern} q q factor
* @synonyms bandq
* @synonyms bpq
* @example
* s("bd sd").bpf(500).bpq("<0 1 2 3>")
* s("bd sd").bandf(500).bandq("<0 1 2 3>")
*
*/
['f', 'bpq', ''],
['f', 'bandq', 'a pattern of anumbers from 0 to 1. Sets the q-factor of the band-pass filter.'],
['f', 'bpq', ''],
/**
* a pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample.
*
@@ -284,49 +282,50 @@ const generic_params = [
'In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played. An example would be an open hi-hat followed by a closed one, essentially muting the open.',
],
/**
* Applies the cutoff frequency of the **l**ow-**p**ass **f**ilter.
* Applies the cutoff frequency of the low-pass filter.
*
* @name lpf
* @name cutoff
* @param {number | Pattern} frequency audible between 0 and 20000
* @synonyms cutoff
* @synonyms lpf
* @example
* s("bd sd,hh*3").lpf("<4000 2000 1000 500 200 100>")
* s("bd sd,hh*3").cutoff("<4000 2000 1000 500 200 100>")
*
*/
['f', 'lpf'],
['f', 'cutoff', 'a pattern of numbers from 0 to 1. Applies the cutoff frequency of the low-pass filter.'],
['f', 'lpf'],
/**
* Applies the cutoff frequency of the **h**igh-**p**ass **f**ilter.
* Applies the cutoff frequency of the high-pass filter.
*
* @name hpf
* @name hcutoff
* @param {number | Pattern} frequency audible between 0 and 20000
* @synonyms hcutoff
* @synonyms hpf
* @example
* s("bd sd,hh*4").hpf("<4000 2000 1000 500 200 100>")
* s("bd sd,hh*4").hcutoff("<4000 2000 1000 500 200 100>")
*
*/
['f', 'hpf', ''],
['f', 'hcutoff', ''],
['f', 'hpf', ''],
/**
* Controls the **h**igh-**p**ass **q**-value.
* Applies the resonance of the high-pass filter.
*
* @name hpq
* @name hresonance
* @param {number | Pattern} q resonance factor between 0 and 50
* @synonyms hresonance
* @synonyms hpq
* @example
* s("bd sd,hh*4").hpf(2000).hpq("<0 10 20 30>")
* s("bd sd,hh*4").hcutoff(2000).hresonance("<0 10 20 30>")
*
*/
['f', 'hresonance', ''],
['f', 'hpq', ''],
['f', 'hresonance', ''],
// TODO: add hpq synonym
/**
* Controls the **l**ow-**p**ass **q**-value.
* Applies the cutoff frequency of the low-pass filter.
*
* @name lpq
* @name resonance
* @param {number | Pattern} q resonance factor between 0 and 50
* @synonyms resonance
* @synonyms lpq
* @example
* s("bd sd,hh*4").lpf(2000).lpq("<0 10 20 30>")
* s("bd sd,hh*4").cutoff(2000).resonance("<0 10 20 30>")
*
*/
['f', 'lpq'],
@@ -393,7 +392,6 @@ const generic_params = [
*
* @name detune
* @param {number | Pattern} amount between 0 and 1
* @superdirtOnly
* @example
* n("0 3 7").s('superzow').octave(3).detune("<0 .25 .5 1 2>").osc()
*
@@ -406,7 +404,6 @@ const generic_params = [
* @param {number | Pattern} dry 0 = wet, 1 = dry
* @example
* n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc()
* @superdirtOnly
*
*/
[
@@ -465,7 +462,6 @@ const generic_params = [
* @param {number | Pattern} wet between 0 and 1
* @example
* n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc()
* @superdirtOnly
*
*/
['f', 'leslie', ''],
@@ -476,7 +472,6 @@ const generic_params = [
* @param {number | Pattern} rate 6.7 for fast, 0.7 for slow
* @example
* n("0,4,7").s("supersquare").leslie(1).lrate("<1 2 4 8>").osc()
* @superdirtOnly
*
*/
// TODO: the rate seems to "lag" (in the example, 1 will be fast)
@@ -488,7 +483,6 @@ const generic_params = [
* @param {number | Pattern} meters somewhere between 0 and 1
* @example
* n("0,4,7").s("supersquare").leslie(1).lrate(2).lsize("<.1 .5 1>").osc()
* @superdirtOnly
*
*/
['f', 'lsize', ''],
@@ -524,7 +518,6 @@ const generic_params = [
* @param {number | Pattern} octave octave number
* @example
* n("0,4,7").s('supersquare').octave("<3 4 5 6>").osc()
* @superDirtOnly
*/
['i', 'octave', ''],
['f', 'offset', ''], // TODO: what is this? not found in tidal doc
@@ -689,7 +682,6 @@ const generic_params = [
* @param {number | string | Pattern} unit see description above
* @example
* speed("1 2 .5 3").s("bd").unit("c").osc()
* @superdirtOnly
*
*/
[
@@ -706,7 +698,6 @@ const generic_params = [
* @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc.
* @example
* squiz("2 4/2 6 [8 16]").s("bd").osc()
* @superdirtOnly
*
*/
['f', 'squiz', ''],
@@ -813,41 +804,41 @@ const generic_params = [
['f', 'uid', ''],
['f', 'val', ''],
['f', 'cps', ''],
/**
* If set to 1, samples will be cut to the duration of their event.
* In tidal, this would be done with legato, which [is about to land in strudel too](https://github.com/tidalcycles/strudel/issues/111)
*
* @name clip
* @param {number | Pattern} active 1 or 0
* @example
* note("c a f e ~").s("piano").clip(1)
*
*/
['f', 'clip', ''],
];
// TODO: slice / splice https://www.youtube.com/watch?v=hKhPdO0RKDQ&list=PL2lW1zNIIwj3bDkh-Y3LUGDuRcoUigoDs&index=13
const makeControl = function (name) {
const func = (...pats) => sequence(...pats).withValue((x) => ({ [name]: x }));
const setter = function (...pats) {
const _name = (name, ...pats) => sequence(...pats).withValue((x) => ({ [name]: x }));
const _setter = (func, name) =>
function (...pats) {
if (!pats.length) {
return this.fmap((value) => ({ [name]: value }));
}
return this.set(func(...pats));
};
Pattern.prototype[name] = setter;
registerControl(name, func);
return func;
};
generic_params.forEach(([type, name, description]) => {
controls[name] = makeControl(name);
controls[name] = function (...pats) {
const result = _name(name, ...pats);
// Add a function for composing this control with another pattern
result.__as_function = function (pat) {
return pat[name](...pats);
};
return result;
};
Pattern.__registered.push(name);
Pattern.prototype[name] = _setter(controls[name], name);
});
// create custom param
controls.createParam = (name) => {
return makeControl(name);
const func = (...pats) => _name(name, ...pats);
Pattern.__registered.push(name);
Pattern.prototype[name] = _setter(func, name);
return (...pats) => _name(name, ...pats);
};
controls.createParams = (...names) =>
+2 -2
View File
@@ -1,13 +1,13 @@
<input
type="text"
id="text"
value="seq('a', ['b', 'c'])"
value="cat('a', 'b')"
style="width: 100%; font-size: 2em; outline: none; margin-bottom: 10px"
spellcheck="false"
/>
<div id="output"></div>
<script type="module">
const strudel = await import('https://cdn.skypack.dev/@strudel.cycles/core@0.6.8');
const strudel = await import('https://cdn.skypack.dev/@strudel.cycles/core@0.0.2');
Object.assign(window, strudel); // assign all strudel functions to global scope to use with eval
const input = document.getElementById('text');
const getEvents = () => {
+2 -2
View File
@@ -2,13 +2,13 @@
<input
type="text"
id="text"
value="seq('tomato', 'indigo', ['white', 'steelblue']).fast(4)"
value="cat('orange', 'indigo')"
style="width: 100%; font-size: 2em; background: black; color: white; outline: none; position: absolute; top: 0"
spellcheck="false"
/>
<canvas id="canvas"></canvas>
<script type="module">
const strudel = await import('https://cdn.skypack.dev/@strudel.cycles/core@0.6.8');
const strudel = await import('https://cdn.skypack.dev/@strudel.cycles/core@0.0.2');
// this adds all strudel functions to the global scope, to be used by eval
Object.assign(window, strudel);
// setup elements
+90
View File
@@ -0,0 +1,90 @@
<div style="position: absolute; bottom: 0; right: 0; padding: 4px; width: 100vw; display: flex">
<button id="start" style="font-size: 2em">start</button>
<button id="stop" style="font-size: 2em">stop</button>
<button id="slower" style="font-size: 2em">slower</button>
<button id="faster" style="font-size: 2em">faster</button>
</div>
<textarea
style="font-size: 2em; background: #052b49; color: #fff; height: 100%; width: 100%; outline: none; border: 0"
id="text"
spellcheck="false"
>
Loading...</textarea
>
<script type="module">
document.body.style = 'margin: 0';
import * as strudel from '@strudel.cycles/core';
const { cat, State, TimeSpan, Scheduler, getPlayableNoteValue, getFreq } = strudel;
Object.assign(window, strudel); // add strudel to eval scope
const ctx = new AudioContext();
const scheduler = new Scheduler({
// audioContext: getAudioContext(),
interval: 0.1,
onTrigger: (hap, time, duration) => {
const freq = getFrequency(hap);
const osc = ctx.createOscillator();
const gain = 0.2;
osc.frequency.value = freq;
osc.type = 'triangle';
const onset = ctx.currentTime + time;
const offset = onset + duration;
const attack = 0.05;
const release = 0.05;
osc.start(onset);
osc.stop(offset + release);
const g = ctx.createGain();
g.gain.setValueAtTime(gain, onset);
g.gain.linearRampToValueAtTime(gain, onset + attack);
g.gain.setValueAtTime(gain, offset - release);
g.gain.linearRampToValueAtTime(0, offset);
osc.connect(g);
g.connect(ctx.destination);
},
});
let initialCode = `stack('c4','e4',cat('g4','a4','b4','a4'))
.add(cat(0,1,2,3,4,3,2,1).slow(8))
.fast(2)
.cps(tri.range(1,8).slow(32))`;
try {
const base64 = decodeURIComponent(window.location.href.split('#')[1]);
initialCode = atob(base64);
} catch (err) {
console.warn('failed to decode', err);
}
const input = document.getElementById('text');
input.value = initialCode;
const evaluate = () => {
try {
const pattern = eval(input.value);
scheduler.setPattern(pattern);
window.location.hash = '#' + encodeURIComponent(btoa(input.value)); // update url hash
} catch (err) {
console.warn(err);
}
};
evaluate();
input.addEventListener('input', () => evaluate());
document.getElementById('start').addEventListener('click', async () => {
await ctx.resume();
scheduler.start();
});
document.getElementById('stop').addEventListener('click', () => scheduler.stop());
document.getElementById('slower').addEventListener('click', () => scheduler.setCps(scheduler.cps - 0.1));
document.getElementById('faster').addEventListener('click', () => scheduler.setCps(scheduler.cps + 0.1));
</script>
<!--
sequence(1,2).mul(55/2) // frequencies
.mul(slowcat(1,2))
.mul(slowcat(1,3/2,4/3,5/3).slow(8))
.fast(3)
.freq()
.velocity(.5)
.s('sawtooth')
.cutoff(800)
.out()
-->
+44
View File
@@ -0,0 +1,44 @@
<input
type="text"
id="text"
value="seq('c3','eb3','g3').note().s('sawtooth').out()"
style="width: 100%; font-size: 2em; outline: none; margin-bottom: 10px"
spellcheck="false"
/>
<button id="start">play</button>
<div id="output"></div>
<script type="module">
const strudel = await import('https://cdn.skypack.dev/@strudel.cycles/core@latest');
const controls = await import('https://cdn.skypack.dev/@strudel.cycles/core@latest/controls.mjs');
const { getAudioContext, Scheduler } = await import('https://cdn.skypack.dev/@strudel.cycles/webaudio@latest');
let scheduler;
const audioContext = getAudioContext();
const latency = 0.2;
Object.assign(window, strudel);
Object.assign(window, controls.default);
scheduler = new Scheduler({
audioContext,
interval: 0.1,
latency,
onEvent: (hap) => {
if (!hap.context.onTrigger) {
console.warn('no output chosen. use one of .out() .webdirt() .osc()');
}
},
});
let started;
document.getElementById('start').addEventListener('click', async () => {
const code = document.getElementById('text').value;
const pattern = eval(code);
const events = pattern._firstCycleValues;
console.log(code, '->', events);
scheduler.setPattern(pattern);
if (!started) {
scheduler.start();
started = true;
}
});
</script>
+29 -16
View File
@@ -6,36 +6,46 @@
<title>Buildless Vanilla Strudel REPL</title>
</head>
<body style="margin: 0; background: #222">
<div style="display: grid; height: 100vh; grid-template-rows: 32px auto">
<button id="start" style="width: 100vw; height: 32px">evaluate</button>
<div style="display: grid; height: 100vh">
<textarea
id="text"
style="font-size: 2em; border: 0; color: white; background: transparent; outline: none; padding: 20px"
spellcheck="false"
></textarea>
</div>
<button
id="start"
style="
position: absolute;
border-radius: 10px;
top: 20px;
right: 20px;
padding: 20px;
border: 2px solid white;
background: transparent;
color: white;
cursor: pointer;
"
>
evaluate
</button>
<div id="output"></div>
<script type="module">
import { controls, repl, evalScope } from 'https://cdn.skypack.dev/@strudel.cycles/core@0.6.8';
import { mini } from 'https://cdn.skypack.dev/@strudel.cycles/mini@0.6.0';
import { transpiler } from 'https://cdn.skypack.dev/@strudel.cycles/transpiler@0.6.0';
import {
getAudioContext,
webaudioOutput,
initAudioOnFirstClick,
} from 'https://cdn.skypack.dev/@strudel.cycles/webaudio@0.6.0';
import { controls, repl, evalScope } from 'https://cdn.skypack.dev/@strudel.cycles/core@0.3.2';
import { mini } from 'https://cdn.skypack.dev/@strudel.cycles/mini@0.3.2';
import { transpiler } from 'https://cdn.skypack.dev/@strudel.cycles/transpiler@0.3.2';
import { getAudioContext, webaudioOutput } from 'https://cdn.skypack.dev/@strudel.cycles/webaudio@0.3.3';
initAudioOnFirstClick();
const ctx = getAudioContext();
const input = document.getElementById('text');
input.innerHTML = getTune();
evalScope(
controls,
import('https://cdn.skypack.dev/@strudel.cycles/core@0.6.8'),
import('https://cdn.skypack.dev/@strudel.cycles/mini@0.6.0'),
import('https://cdn.skypack.dev/@strudel.cycles/tonal@0.6.0'),
import('https://cdn.skypack.dev/@strudel.cycles/webaudio@0.6.0'),
import('https://cdn.skypack.dev/@strudel.cycles/core@0.3.2'),
import('https://cdn.skypack.dev/@strudel.cycles/mini@0.3.2'),
import('https://cdn.skypack.dev/@strudel.cycles/tonal@0.3.3'),
import('https://cdn.skypack.dev/@strudel.cycles/webaudio@0.3.3'),
);
const { evaluate } = repl({
@@ -43,7 +53,10 @@
getTime: () => ctx.currentTime,
transpiler,
});
document.getElementById('start').addEventListener('click', () => evaluate(input.value));
document.getElementById('start').addEventListener('click', () => {
ctx.resume();
evaluate(input.value);
});
function getTune() {
return `await samples('github:tidalcycles/Dirt-Samples/master')
@@ -1,12 +1,12 @@
import { controls, repl, evalScope } from '@strudel.cycles/core';
import { getAudioContext, webaudioOutput, initAudioOnFirstClick } from '@strudel.cycles/webaudio';
import { transpiler } from '@strudel.cycles/transpiler';
import { controls, repl, evalScope, setStringParser } from '@strudel.cycles/core';
import { mini } from '@strudel.cycles/mini';
import { getAudioContext, webaudioOutput } from '@strudel.cycles/webaudio';
// import { transpiler } from '@strudel.cycles/transpiler';
import tune from './tune.mjs';
const ctx = getAudioContext();
const input = document.getElementById('text');
input.innerHTML = tune;
initAudioOnFirstClick();
evalScope(
controls,
@@ -16,13 +16,14 @@ evalScope(
import('@strudel.cycles/tonal'),
);
setStringParser(mini);
const { evaluate } = repl({
defaultOutput: webaudioOutput,
getTime: () => ctx.currentTime,
transpiler,
// transpiler,
});
document.getElementById('start').addEventListener('click', () => {
ctx.resume();
console.log('eval', input.value);
evaluate(input.value);
});
+885
View File
@@ -0,0 +1,885 @@
{
"name": "vite-vanilla-repl",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "vite-vanilla-repl",
"version": "0.0.0",
"devDependencies": {
"vite": "^3.2.0"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz",
"integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz",
"integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz",
"integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.15.13",
"@esbuild/linux-loong64": "0.15.13",
"esbuild-android-64": "0.15.13",
"esbuild-android-arm64": "0.15.13",
"esbuild-darwin-64": "0.15.13",
"esbuild-darwin-arm64": "0.15.13",
"esbuild-freebsd-64": "0.15.13",
"esbuild-freebsd-arm64": "0.15.13",
"esbuild-linux-32": "0.15.13",
"esbuild-linux-64": "0.15.13",
"esbuild-linux-arm": "0.15.13",
"esbuild-linux-arm64": "0.15.13",
"esbuild-linux-mips64le": "0.15.13",
"esbuild-linux-ppc64le": "0.15.13",
"esbuild-linux-riscv64": "0.15.13",
"esbuild-linux-s390x": "0.15.13",
"esbuild-netbsd-64": "0.15.13",
"esbuild-openbsd-64": "0.15.13",
"esbuild-sunos-64": "0.15.13",
"esbuild-windows-32": "0.15.13",
"esbuild-windows-64": "0.15.13",
"esbuild-windows-arm64": "0.15.13"
}
},
"node_modules/esbuild-android-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz",
"integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-android-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz",
"integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz",
"integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz",
"integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz",
"integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz",
"integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-32": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz",
"integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz",
"integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz",
"integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz",
"integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-mips64le": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz",
"integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-ppc64le": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz",
"integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-riscv64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz",
"integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-s390x": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz",
"integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-netbsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz",
"integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-openbsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz",
"integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-sunos-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz",
"integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-32": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz",
"integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz",
"integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz",
"integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"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/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/is-core-module": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/postcss": {
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
}
],
"dependencies": {
"nanoid": "^3.3.4",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"dependencies": {
"is-core-module": "^2.9.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/rollup": {
"version": "2.79.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=10.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/vite": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.2.tgz",
"integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==",
"dev": true,
"dependencies": {
"esbuild": "^0.15.9",
"postcss": "^8.4.18",
"resolve": "^1.22.1",
"rollup": "^2.79.1"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"peerDependencies": {
"less": "*",
"sass": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"less": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
}
}
},
"dependencies": {
"@esbuild/android-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz",
"integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz",
"integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==",
"dev": true,
"optional": true
},
"esbuild": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz",
"integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==",
"dev": true,
"requires": {
"@esbuild/android-arm": "0.15.13",
"@esbuild/linux-loong64": "0.15.13",
"esbuild-android-64": "0.15.13",
"esbuild-android-arm64": "0.15.13",
"esbuild-darwin-64": "0.15.13",
"esbuild-darwin-arm64": "0.15.13",
"esbuild-freebsd-64": "0.15.13",
"esbuild-freebsd-arm64": "0.15.13",
"esbuild-linux-32": "0.15.13",
"esbuild-linux-64": "0.15.13",
"esbuild-linux-arm": "0.15.13",
"esbuild-linux-arm64": "0.15.13",
"esbuild-linux-mips64le": "0.15.13",
"esbuild-linux-ppc64le": "0.15.13",
"esbuild-linux-riscv64": "0.15.13",
"esbuild-linux-s390x": "0.15.13",
"esbuild-netbsd-64": "0.15.13",
"esbuild-openbsd-64": "0.15.13",
"esbuild-sunos-64": "0.15.13",
"esbuild-windows-32": "0.15.13",
"esbuild-windows-64": "0.15.13",
"esbuild-windows-arm64": "0.15.13"
}
},
"esbuild-android-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz",
"integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==",
"dev": true,
"optional": true
},
"esbuild-android-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz",
"integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==",
"dev": true,
"optional": true
},
"esbuild-darwin-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz",
"integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==",
"dev": true,
"optional": true
},
"esbuild-darwin-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz",
"integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==",
"dev": true,
"optional": true
},
"esbuild-freebsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz",
"integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==",
"dev": true,
"optional": true
},
"esbuild-freebsd-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz",
"integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==",
"dev": true,
"optional": true
},
"esbuild-linux-32": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz",
"integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==",
"dev": true,
"optional": true
},
"esbuild-linux-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz",
"integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==",
"dev": true,
"optional": true
},
"esbuild-linux-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz",
"integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==",
"dev": true,
"optional": true
},
"esbuild-linux-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz",
"integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==",
"dev": true,
"optional": true
},
"esbuild-linux-mips64le": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz",
"integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==",
"dev": true,
"optional": true
},
"esbuild-linux-ppc64le": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz",
"integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==",
"dev": true,
"optional": true
},
"esbuild-linux-riscv64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz",
"integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==",
"dev": true,
"optional": true
},
"esbuild-linux-s390x": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz",
"integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==",
"dev": true,
"optional": true
},
"esbuild-netbsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz",
"integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==",
"dev": true,
"optional": true
},
"esbuild-openbsd-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz",
"integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==",
"dev": true,
"optional": true
},
"esbuild-sunos-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz",
"integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==",
"dev": true,
"optional": true
},
"esbuild-windows-32": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz",
"integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==",
"dev": true,
"optional": true
},
"esbuild-windows-64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz",
"integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==",
"dev": true,
"optional": true
},
"esbuild-windows-arm64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz",
"integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==",
"dev": true,
"optional": true
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"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
},
"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"
}
},
"is-core-module": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"dev": true
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"postcss": {
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"dev": true,
"requires": {
"nanoid": "^3.3.4",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"requires": {
"is-core-module": "^2.9.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"rollup": {
"version": "2.79.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
"dev": true,
"requires": {
"fsevents": "~2.3.2"
}
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true
},
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"vite": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.2.tgz",
"integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==",
"dev": true,
"requires": {
"esbuild": "^0.15.9",
"fsevents": "~2.3.2",
"postcss": "^8.4.18",
"resolve": "^1.22.1",
"rollup": "^2.79.1"
}
}
}
}
@@ -11,12 +11,5 @@
},
"devDependencies": {
"vite": "^3.2.0"
},
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/mini": "workspace:*",
"@strudel.cycles/transpiler": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/tonal": "workspace:*"
}
}
@@ -1,4 +1,4 @@
export default `await samples('github:tidalcycles/Dirt-Samples/master')
/* export default `await samples('github:tidalcycles/Dirt-Samples/master')
stack(
// amen
@@ -29,3 +29,11 @@ stack(
,
n("0 1").s("east").delay(.5).degradeBy(.8).speed(rand.range(.5,1.5))
).reset("<x@7 x(5,8)>")`;
*/
export default `stack(
n("c3 [eb3,g3]")
.delay("<0 .5>")
.delaytime(".16 | .33")
.delayfeedback(".6 | .8")
).sometimes(x=>x.speed("-1"))`;
+65
View File
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Buildless Vanilla Strudel REPL</title>
</head>
<body style="margin: 0; background: #222">
<div style="display: grid; height: 100vh">
<textarea
id="text"
style="font-size: 2em; border: 0; color: white; background: transparent; outline: none; padding: 20px"
spellcheck="false"
>
// LOADING</textarea
>
</div>
<button
id="start"
style="
position: absolute;
border-radius: 10px;
top: 20px;
right: 20px;
padding: 20px;
border: 2px solid white;
background: transparent;
color: white;
cursor: pointer;
"
>
evaluate
</button>
<div id="output"></div>
<script type="module">
import { controls, repl, evalScope } from 'https://cdn.skypack.dev/@strudel.cycles/core@0.4.1';
import { transpiler } from 'https://cdn.skypack.dev/@strudel.cycles/transpiler@0.4.1';
const modules = [
import('https://cdn.skypack.dev/@strudel.cycles/core@0.4.1'),
import('https://cdn.skypack.dev/@strudel.cycles/mini@0.4.1'),
];
const input = document.getElementById('text');
Promise.all(modules).then(() => {
input.innerHTML = `note("<c3 [d3 e3]>").cutoff(1000)`;
document.getElementById('start').addEventListener('click', () => {
evaluate(input.value);
});
});
evalScope(controls, ...modules);
const { evaluate } = repl({
defaultOutput: (hap, deadline, duration) => {
console.log(deadline, duration, hap.value);
},
getTime: () => Date.now() / 1000,
transpiler,
beforeEval: (code) => console.log('evaluate', code),
afterEval: (code) => {},
});
</script>
</body>
</html>
+1639
View File
File diff suppressed because it is too large Load Diff
+3 -13
View File
@@ -1,17 +1,11 @@
{
"name": "@strudel.cycles/core",
"version": "0.6.8",
"version": "0.5.0",
"description": "Port of Tidal Cycles to JavaScript",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
"build": "vite build",
"prepublishOnly": "pnpm build"
"test": "vitest run"
},
"repository": {
"type": "git",
@@ -33,9 +27,5 @@
"dependencies": {
"fraction.js": "^4.2.0"
},
"gitHead": "0e26d4e741500f5bae35b023608f062a794905c2",
"devDependencies": {
"vite": "^3.2.2",
"vitest": "^0.25.7"
}
"gitHead": "0e26d4e741500f5bae35b023608f062a794905c2"
}
+215 -386
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -114,14 +114,6 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
*
*/
/**
* A discrete pattern of numbers from 0 to n-1
* @example
* run(4).scale('C4 major').note()
* // "0 1 2 3".scale('C4 major').note()
*/
export const run = (n) => saw.range(0, n).floor().segment(n);
/**
* A continuous pattern of random numbers, between 0 and 1.
*
+3 -48
View File
@@ -44,9 +44,6 @@ import {
ply,
rev,
time,
run,
hitch,
set,
} from '../index.mjs';
import { steady } from '../signal.mjs';
@@ -206,7 +203,7 @@ describe('Pattern', () => {
),
);
});
it('can squeezeout() structure', () => {
it('can SqueezeOut() structure', () => {
sameFirst(
sequence(1, [2, 3]).add.squeezeout(10, 20, 30),
sequence([11, [12, 13]], [21, [22, 23]], [31, [32, 33]]),
@@ -254,7 +251,7 @@ describe('Pattern', () => {
),
);
});
it('can squeezeout() structure', () => {
it('can SqueezeOut() structure', () => {
sameFirst(sequence(1, [2, 3]).keep.squeezeout(10, 20, 30), sequence([1, [2, 3]], [1, [2, 3]], [1, [2, 3]]));
});
});
@@ -296,7 +293,7 @@ describe('Pattern', () => {
),
);
});
it('can squeezeout() structure', () => {
it('can SqueezeOut() structure', () => {
sameFirst(sequence(1, [2, 3]).keepif.squeezeout(true, true, false), sequence([1, [2, 3]], [1, [2, 3]], silence));
});
});
@@ -911,18 +908,6 @@ describe('Pattern', () => {
);
});
});
describe('run', () => {
it('Can run', () => {
expect(run(4).firstCycle()).toStrictEqual(sequence(0, 1, 2, 3).firstCycle());
});
});
describe('ribbon', () => {
it('Can ribbon', () => {
expect(cat(0, 1, 2, 3, 4, 5, 6, 7).ribbon(2, 4).fast(4).firstCycle()).toStrictEqual(
sequence(2, 3, 4, 5).firstCycle(),
);
});
});
describe('linger', () => {
it('Can linger on the first quarter of a cycle', () => {
expect(sequence(0, 1, 2, 3, 4, 5, 6, 7).linger(0.25).firstCycle()).toStrictEqual(
@@ -931,14 +916,6 @@ describe('Pattern', () => {
});
});
describe('alignments', () => {
it('Can combine controls', () => {
sameFirst(s('bd').set.in.n(3), s('bd').n(3));
sameFirst(s('bd').set.squeeze.n(3, 4), sequence(s('bd').n(3), s('bd').n(4)));
});
it('Can combine functions with alignmed controls', () => {
sameFirst(s('bd').apply(fast(2).set(n(3))), s('bd').fast(2).set.in.n(3));
sameFirst(s('bd').apply(fast(2).set.in.n(3)), s('bd').fast(2).set.in.n(3));
});
it('Can squeeze arguments', () => {
expect(sequence(1, 2).add.squeeze(4, 5).firstCycle()).toStrictEqual(sequence(5, 6, 6, 7).firstCycle());
});
@@ -959,26 +936,4 @@ describe('Pattern', () => {
expect(stack(sequence('a', silence), pure('a').mask(0, 1)).defragmentHaps().firstCycle().length).toStrictEqual(2);
});
});
describe('press', () => {
it('Can syncopate events', () => {
sameFirst(sequence('a', 'b', 'c', 'd').press(), sequence(silence, 'a', silence, 'b', silence, 'c', silence, 'd'));
});
});
describe('hurry', () => {
it('Can speed up patterns and sounds', () => {
sameFirst(s('a', 'b').hurry(2), s('a', 'b').fast(2).speed(2));
});
});
describe('composable functions', () => {
it('Can compose functions', () => {
sameFirst(sequence(3, 4).fast(2).rev().fast(2), fast(2).rev().fast(2)(sequence(3, 4)));
});
it('Can compose by method chaining operators with controls', () => {
sameFirst(s('bd').apply(set.n(3).fast(2)), s('bd').set.n(3).fast(2));
});
it('Can compose by method chaining operators and alignments with controls', () => {
sameFirst(s('bd').apply(set.in.n(3).fast(2)), s('bd').set.n(3).fast(2));
// sameFirst(s('bd').apply(set.squeeze.n(3).fast(2)), s('bd').set.squeeze.n(3).fast(2));
});
});
});
+1 -1
View File
@@ -26,7 +26,7 @@ export const backgroundImage = function (src, animateOptions = {}) {
({
style: () => (container.style = bg + ';' + value),
className: () => (container.className = value + ' ' + initialClassName),
})[option]();
}[option]());
};
const funcOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === 'function');
const stringOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === 'string');
+22 -3
View File
@@ -4,6 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Pattern } from './pattern.mjs';
// returns true if the given string is a note
export const isNoteWithOctave = (name) => /^[a-gA-G][#bs]*[0-9]$/.test(name);
export const isNote = (name) => /^[a-gA-G][#bs]*[0-9]?$/.test(name);
@@ -58,7 +60,6 @@ export const valueToMidi = (value, fallbackValue) => {
/**
* @deprecated does not appear to be referenced or invoked anywhere in the codebase
* @noAutocomplete
*/
export const getFreq = (noteOrMidi) => {
if (typeof noteOrMidi === 'number') {
@@ -69,7 +70,6 @@ export const getFreq = (noteOrMidi) => {
/**
* @deprecated does not appear to be referenced or invoked anywhere in the codebase
* @noAutocomplete
*/
export const midi2note = (n) => {
const oct = Math.floor(n / 12) - 1;
@@ -139,7 +139,7 @@ export const removeUndefineds = (xs) => xs.filter((x) => x != undefined);
export const flatten = (arr) => [].concat(...arr);
export const id = (a) => a;
export const constant = curry((a, b) => a);
export const constant = (a, b) => a;
export const listRange = (min, max) => Array.from({ length: max - min + 1 }, (_, i) => i + min);
@@ -151,6 +151,25 @@ export function curry(func, overload, arity = func.length) {
const partial = function (...args2) {
return curried.apply(this, args.concat(args2));
};
if (args.length == arity - 1) {
// The penultimate arg.. so add some composition magic
// TODO - To make this useful, we also need to add stub functions for every pattern method to
// do the actual composing
for (const r of Pattern.__registered) {
partial[r] = function (...args) {
const result = new Pattern(() => []);
result.__compose = function (pat) {
return partial(pat)[r](...args);
};
return result;
};
}
partial.__compose = function (pat) {
return partial(pat);
};
}
if (overload) {
overload(partial, args);
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
@@ -92,7 +92,6 @@ async function load() {
['message'].forEach((k) => _csound.on(k, (...args) => eventLogger(k, args)));
await _csound.setOption('-m0d'); // see -m flag https://csound.com/docs/manual/CommandFlags.html
await _csound.setOption('--sample-accurate');
await _csound.setOption('-odac');
await _csound.compileCsdText(csd);
// await _csound.compileOrc(livecodeOrc);
await _csound.compileOrc(presetsOrc);
+4 -14
View File
@@ -1,15 +1,10 @@
{
"name": "@strudel.cycles/csound",
"version": "0.6.2",
"version": "0.5.1",
"description": "csound bindings for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"main": "csound.mjs",
"scripts": {
"build": "vite build",
"prepublishOnly": "npm run build"
"test": "echo \"No tests present.\" && exit 0"
},
"repository": {
"type": "git",
@@ -32,11 +27,6 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@csound/browser": "6.18.5",
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*"
},
"devDependencies": {
"vite": "^3.2.2"
"@csound/browser": "^6.18.3"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+1 -2
View File
@@ -30,5 +30,4 @@ note(`[[e5 [b4 c5] d5 [c5 b4]]
</strudel-repl>
```
- Note that the Code is placed inside HTML comments to prevent the browser from treating it as HTML.
- [Play with this example on stackblitz](https://stackblitz.com/edit/js-75cvww?file=index.html)
Note that the Code is placed inside HTML comments to prevent the browser from treating it as HTML.
-4
View File
@@ -3,10 +3,6 @@
This package contains the strudel code transformer and evaluator.
It allows creating strudel patterns from input code that is optimized for minimal keystrokes and human readability.
## Deprecation Note
This package will not be developed further. Consider using `@strudel.cycles/transpiler` as a replacement.
## Install
```sh
+297
View File
@@ -0,0 +1,297 @@
{
"name": "@strudel.cycles/eval",
"version": "0.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@strudel.cycles/eval",
"version": "0.1.1",
"license": "AGPL-3.0-or-later",
"dependencies": {
"estraverse": "^5.3.0",
"shift-ast": "^6.1.0",
"shift-codegen": "^7.0.3",
"shift-parser": "^7.0.3",
"shift-spec": "^2018.0.2",
"shift-traverser": "^1.0.0"
}
},
"node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/multimap": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
"integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw=="
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/shift-ast": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.1.0.tgz",
"integrity": "sha512-Vj4XUIJIFPIh6VcBGJ1hjH/kM88XGer94Pr7Rvxa+idEylDsrwtLw268HoxGo5xReL6T3DdRl/9/Pr1XihZ/8Q=="
},
"node_modules/shift-codegen": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-codegen/-/shift-codegen-7.0.3.tgz",
"integrity": "sha512-dfCVVdBF0qZ6pkajQ3bjxRdNEltyxEITVe7tBJkQt2eCI3znUkSxq0VSe/tTWq1LKHeAS4HuOiqYEuHMFkSq9w==",
"dependencies": {
"esutils": "^2.0.2",
"object-assign": "^4.1.0",
"shift-reducer": "6.0.0"
}
},
"node_modules/shift-parser": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-parser/-/shift-parser-7.0.3.tgz",
"integrity": "sha512-uYX2ORyZfKZrUc4iKKkO9KOhzUSxCrSBk7QK6ZmShId+BOo1gh1IwecVy97ynyOTpmhPWUttjC8BzsnQl65Zew==",
"dependencies": {
"multimap": "^1.0.2",
"shift-ast": "6.0.0",
"shift-reducer": "6.0.0",
"shift-regexp-acceptor": "2.0.3"
}
},
"node_modules/shift-parser/node_modules/shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
},
"node_modules/shift-reducer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-reducer/-/shift-reducer-6.0.0.tgz",
"integrity": "sha512-2rJraRP8drIOjvaE/sALa+0tGJmMVUzlmS3wIJerJbaYuCjpFAiF0WjkTOFVtz1144Nm/ECmqeG+7yRhuMVsMg==",
"dependencies": {
"shift-ast": "6.0.0"
}
},
"node_modules/shift-reducer/node_modules/shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
},
"node_modules/shift-regexp-acceptor": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shift-regexp-acceptor/-/shift-regexp-acceptor-2.0.3.tgz",
"integrity": "sha512-sxL7e5JNUFxm+gutFRXktX2D6KVgDAHNuDsk5XHB9Z+N5yXooZG6pdZ1GEbo3Jz6lF7ETYLBC4WAjIFm2RKTmA==",
"dependencies": {
"unicode-match-property-ecmascript": "1.0.4",
"unicode-match-property-value-ecmascript": "1.0.2",
"unicode-property-aliases-ecmascript": "1.0.4"
}
},
"node_modules/shift-spec": {
"version": "2018.0.2",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.2.tgz",
"integrity": "sha512-5CP/cKDEim4rZ6ViCSipTLY2U7HJr8q/kpDuCBmebFqbx/0DeozWO+9ienHmYjgGLDfHrqj+LBAN67FRK2vE6w=="
},
"node_modules/shift-traverser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shift-traverser/-/shift-traverser-1.0.0.tgz",
"integrity": "sha512-DMY3512wJbdC+IC+nhLH3/Stgr2BbxbNcg7qyZ6+e5qNnNs8TBQJWdMsRgHlX1JXwF4C0ONKS8VUxsPT0Tf7aw==",
"dependencies": {
"estraverse": "4.2.0",
"shift-spec": "2018.0.0"
}
},
"node_modules/shift-traverser/node_modules/estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/shift-traverser/node_modules/shift-spec": {
"version": "2018.0.0",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz",
"integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ=="
},
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
"integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-match-property-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
"integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^1.0.4",
"unicode-property-aliases-ecmascript": "^1.0.4"
},
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-match-property-value-ecmascript": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
"integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-property-aliases-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
"integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==",
"engines": {
"node": ">=4"
}
}
},
"dependencies": {
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"multimap": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
"integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw=="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"shift-ast": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.1.0.tgz",
"integrity": "sha512-Vj4XUIJIFPIh6VcBGJ1hjH/kM88XGer94Pr7Rvxa+idEylDsrwtLw268HoxGo5xReL6T3DdRl/9/Pr1XihZ/8Q=="
},
"shift-codegen": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-codegen/-/shift-codegen-7.0.3.tgz",
"integrity": "sha512-dfCVVdBF0qZ6pkajQ3bjxRdNEltyxEITVe7tBJkQt2eCI3znUkSxq0VSe/tTWq1LKHeAS4HuOiqYEuHMFkSq9w==",
"requires": {
"esutils": "^2.0.2",
"object-assign": "^4.1.0",
"shift-reducer": "6.0.0"
}
},
"shift-parser": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-parser/-/shift-parser-7.0.3.tgz",
"integrity": "sha512-uYX2ORyZfKZrUc4iKKkO9KOhzUSxCrSBk7QK6ZmShId+BOo1gh1IwecVy97ynyOTpmhPWUttjC8BzsnQl65Zew==",
"requires": {
"multimap": "^1.0.2",
"shift-ast": "6.0.0",
"shift-reducer": "6.0.0",
"shift-regexp-acceptor": "2.0.3"
},
"dependencies": {
"shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
}
}
},
"shift-reducer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-reducer/-/shift-reducer-6.0.0.tgz",
"integrity": "sha512-2rJraRP8drIOjvaE/sALa+0tGJmMVUzlmS3wIJerJbaYuCjpFAiF0WjkTOFVtz1144Nm/ECmqeG+7yRhuMVsMg==",
"requires": {
"shift-ast": "6.0.0"
},
"dependencies": {
"shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
}
}
},
"shift-regexp-acceptor": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shift-regexp-acceptor/-/shift-regexp-acceptor-2.0.3.tgz",
"integrity": "sha512-sxL7e5JNUFxm+gutFRXktX2D6KVgDAHNuDsk5XHB9Z+N5yXooZG6pdZ1GEbo3Jz6lF7ETYLBC4WAjIFm2RKTmA==",
"requires": {
"unicode-match-property-ecmascript": "1.0.4",
"unicode-match-property-value-ecmascript": "1.0.2",
"unicode-property-aliases-ecmascript": "1.0.4"
}
},
"shift-spec": {
"version": "2018.0.2",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.2.tgz",
"integrity": "sha512-5CP/cKDEim4rZ6ViCSipTLY2U7HJr8q/kpDuCBmebFqbx/0DeozWO+9ienHmYjgGLDfHrqj+LBAN67FRK2vE6w=="
},
"shift-traverser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shift-traverser/-/shift-traverser-1.0.0.tgz",
"integrity": "sha512-DMY3512wJbdC+IC+nhLH3/Stgr2BbxbNcg7qyZ6+e5qNnNs8TBQJWdMsRgHlX1JXwF4C0ONKS8VUxsPT0Tf7aw==",
"requires": {
"estraverse": "4.2.0",
"shift-spec": "2018.0.0"
},
"dependencies": {
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"shift-spec": {
"version": "2018.0.0",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz",
"integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ=="
}
}
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
"integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ=="
},
"unicode-match-property-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
"integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
"requires": {
"unicode-canonical-property-names-ecmascript": "^1.0.4",
"unicode-property-aliases-ecmascript": "^1.0.4"
}
},
"unicode-match-property-value-ecmascript": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
"integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ=="
},
"unicode-property-aliases-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
"integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg=="
}
}
}
+5 -16
View File
@@ -1,21 +1,15 @@
{
"name": "@strudel.cycles/eval",
"version": "0.6.2",
"version": "0.5.0",
"description": "Code evaluator for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
"test": "vitest run",
"prepublishOnly": "npm run build"
},
"type": "module",
"directories": {
"test": "test"
},
"scripts": {
"test": "vitest run"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
@@ -34,17 +28,12 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/core": "^0.5.0",
"estraverse": "^5.3.0",
"shift-ast": "^7.0.0",
"shift-codegen": "^8.1.0",
"shift-parser": "^8.0.0",
"shift-spec": "^2019.0.0",
"shift-traverser": "^1.0.0"
},
"devDependencies": {
"@strudel.cycles/mini": "workspace:*",
"vite": "^3.2.2",
"vitest": "^0.25.7"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+4
View File
@@ -7,3 +7,7 @@ This package adds midi functionality to strudel Patterns.
```sh
npm i @strudel.cycles/midi --save
```
## Dev Notes
- is this package really necessary? currently, /tone also depends on webmidi through @tonejs/piano. Either move piano out of /tone or merge /midi into /tone...
+130
View File
@@ -0,0 +1,130 @@
{
"name": "@strudel.cycles/midi",
"version": "0.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@strudel.cycles/midi",
"version": "0.1.1",
"license": "AGPL-3.0-or-later",
"dependencies": {
"tone": "^14.7.77",
"webmidi": "^2.5.2"
}
},
"node_modules/@babel/runtime": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/automation-events": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-4.0.14.tgz",
"integrity": "sha512-CB2Me0yW8sz7gSGwMiSfgfs1Oqlgs53k+eVESN6axvRyMAD3zlSp2nqndD2TQAtW3yOtSEJWNGsw0r48+f1wtw==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"tslib": "^2.3.1"
},
"engines": {
"node": ">=12.20.1"
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"node_modules/standardized-audio-context": {
"version": "25.3.21",
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.21.tgz",
"integrity": "sha512-CZEnayJJjNefeU+z1QGDhaid1LAAYxWYa2ipNk75ropwec9rq6fmclyhXb1wGtDsZ402irX3HLt1U/PwP9+1fA==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"automation-events": "^4.0.14",
"tslib": "^2.3.1"
}
},
"node_modules/tone": {
"version": "14.7.77",
"resolved": "https://registry.npmjs.org/tone/-/tone-14.7.77.tgz",
"integrity": "sha512-tCfK73IkLHyzoKUvGq47gyDyxiKLFvKiVCOobynGgBB9Dl0NkxTM2p+eRJXyCYrjJwy9Y0XCMqD3uOYsYt2Fdg==",
"dependencies": {
"standardized-audio-context": "^25.1.8",
"tslib": "^2.0.1"
}
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg==",
"engines": {
"node": ">0.6.x"
}
}
},
"dependencies": {
"@babel/runtime": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"automation-events": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-4.0.14.tgz",
"integrity": "sha512-CB2Me0yW8sz7gSGwMiSfgfs1Oqlgs53k+eVESN6axvRyMAD3zlSp2nqndD2TQAtW3yOtSEJWNGsw0r48+f1wtw==",
"requires": {
"@babel/runtime": "^7.17.2",
"tslib": "^2.3.1"
}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"standardized-audio-context": {
"version": "25.3.21",
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.21.tgz",
"integrity": "sha512-CZEnayJJjNefeU+z1QGDhaid1LAAYxWYa2ipNk75ropwec9rq6fmclyhXb1wGtDsZ402irX3HLt1U/PwP9+1fA==",
"requires": {
"@babel/runtime": "^7.17.2",
"automation-events": "^4.0.14",
"tslib": "^2.3.1"
}
},
"tone": {
"version": "14.7.77",
"resolved": "https://registry.npmjs.org/tone/-/tone-14.7.77.tgz",
"integrity": "sha512-tCfK73IkLHyzoKUvGq47gyDyxiKLFvKiVCOobynGgBB9Dl0NkxTM2p+eRJXyCYrjJwy9Y0XCMqD3uOYsYt2Fdg==",
"requires": {
"standardized-audio-context": "^25.1.8",
"tslib": "^2.0.1"
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg=="
}
}
}
+3 -14
View File
@@ -1,16 +1,8 @@
{
"name": "@strudel.cycles/midi",
"version": "0.6.0",
"version": "0.5.0",
"description": "Midi API for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
"prepublishOnly": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
@@ -29,11 +21,8 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/tone": "^0.5.0",
"tone": "^14.7.77",
"webmidi": "^3.0.21"
},
"devDependencies": {
"vite": "^3.2.2"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+1 -1
View File
@@ -40,5 +40,5 @@ The parser [krill-parser.js] is generated from [krill.pegjs](./krill.pegjs) usin
To generate the parser, run
```js
npm build:parser
npm run build:parser
```
+1031
View File
File diff suppressed because it is too large Load Diff
+6 -12
View File
@@ -1,18 +1,12 @@
{
"name": "@strudel.cycles/mini",
"version": "0.6.0",
"version": "0.5.0",
"description": "Mini notation for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
"build:parser": "peggy -o krill-parser.js --format es ./krill.pegjs",
"build": "vite build",
"prepublishOnly": "npm run build"
"build:parser": "peggy -o krill-parser.js --format es ./krill.pegjs"
},
"repository": {
"type": "git",
@@ -32,11 +26,11 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*"
"@strudel.cycles/core": "^0.5.0",
"@strudel.cycles/eval": "^0.5.0",
"@strudel.cycles/tone": "^0.5.0"
},
"devDependencies": {
"peggy": "^2.0.1",
"vite": "^3.2.2",
"vitest": "^0.25.7"
"peggy": "^2.0.1"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+2 -2
View File
@@ -34,6 +34,6 @@ Now open the REPL and type:
s("<bd sd> hh").osc()
```
or just [click here](https://strudel.tidalcycles.org/#cygiPGJkIHNkPiBoaCIpLm9zYygp)...
or just [click here](http://localhost:3000/#cygiPGJkIHNkPiBoaCIpLm9zYygp)...
You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.tidalcycles.org/learn/input-output/#superdirt-api)
You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.tidalcycles.org/learn/outputs#superdirt-api)
-1
View File
@@ -39,7 +39,6 @@ let startedAt = -1;
/**
*
* Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software.
* For more info, read [MIDI & OSC in the docs](https://strudel.tidalcycles.org/learn/input-output)
*
* @name osc
* @memberof Pattern
+60
View File
@@ -0,0 +1,60 @@
{
"name": "@strudel.cycles/osc",
"version": "0.4.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@strudel.cycles/osc",
"version": "0.1.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"osc-js": "^2.3.2"
}
},
"node_modules/osc-js": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/osc-js/-/osc-js-2.3.2.tgz",
"integrity": "sha512-9i7J4u1hH+glooGMh+ki1ni0JGqKmylT8r0nXKugHbRK63rR+kl4O+5tGW6+/EszjbCju3KV+eXQQzFDdGrmhg==",
"dependencies": {
"ws": "^8.5.0"
}
},
"node_modules/ws": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==",
"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
}
}
}
},
"dependencies": {
"osc-js": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/osc-js/-/osc-js-2.3.2.tgz",
"integrity": "sha512-9i7J4u1hH+glooGMh+ki1ni0JGqKmylT8r0nXKugHbRK63rR+kl4O+5tGW6+/EszjbCju3KV+eXQQzFDdGrmhg==",
"requires": {
"ws": "^8.5.0"
}
},
"ws": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==",
"requires": {}
}
}
}
+4 -11
View File
@@ -1,19 +1,14 @@
{
"name": "@strudel.cycles/osc",
"version": "0.6.0",
"version": "0.4.0",
"description": "OSC messaging for strudel",
"main": "osc.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"test": "echo \"No tests present.\" && exit 0",
"server": "node server.js",
"tidal-sniffer": "node tidal-sniffer.js",
"client": "npx serve -p 4321",
"build-bin": "npx pkg server.js --targets node16-macos-x64,node16-win-x64,node16-linux-x64 --out-path bin",
"build": "vite build",
"prepublishOnly": "npm run build"
"build": "npx pkg server.js --targets node16-macos-x64,node16-win-x64,node16-linux-x64 --out-path bin"
},
"repository": {
"type": "git",
@@ -36,11 +31,9 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"osc-js": "^2.4.0"
},
"devDependencies": {
"pkg": "^5.7.0",
"vite": "^3.2.2"
"pkg": "^5.7.0"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'osc.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+2
View File
@@ -11,6 +11,8 @@ node_modules
dist-ssr
*.local
!dist
# Editor directories and files
.vscode/*
!.vscode/extensions.json
+8 -1
View File
@@ -33,4 +33,11 @@ export function Repl({ tune }) {
}
```
For a more sophisticated example, check out the [nano-repl](./examples/nano-repl/)!
## Development
If you change something in here and want to see the changes in the repl, make sure to run `npm run build` inside this folder!
```js
npm run dev # dev server
npm run build # build package
```
File diff suppressed because one or more lines are too long
+442
View File
@@ -0,0 +1,442 @@
import d, { useCallback as E, useRef as A, useEffect as k, useMemo as Q, useState as _, useLayoutEffect as te } from "react";
import ue from "@uiw/react-codemirror";
import { Decoration as M, EditorView as re } from "@codemirror/view";
import { StateEffect as ne, StateField as oe } from "@codemirror/state";
import { javascript as de } from "@codemirror/lang-javascript";
import { tags as u } from "@lezer/highlight";
import { createTheme as fe } from "@uiw/codemirror-themes";
import { webaudioOutput as me, getAudioContext as he } from "@strudel.cycles/webaudio";
import { useInView as ge } from "react-hook-inview";
import { repl as pe, logger as ve } from "@strudel.cycles/core";
import { transpiler as be } from "@strudel.cycles/transpiler";
const Ee = fe({
theme: "dark",
settings: {
background: "#222",
foreground: "#75baff",
caret: "#ffcc00",
selection: "rgba(128, 203, 196, 0.5)",
selectionMatch: "#036dd626",
lineHighlight: "#00000050",
gutterBackground: "transparent",
gutterForeground: "#8a919966"
},
styles: [
{ tag: u.keyword, color: "#c792ea" },
{ tag: u.operator, color: "#89ddff" },
{ tag: u.special(u.variableName), color: "#eeffff" },
{ tag: u.typeName, color: "#c3e88d" },
{ tag: u.atom, color: "#f78c6c" },
{ tag: u.number, color: "#c3e88d" },
{ tag: u.definition(u.variableName), color: "#82aaff" },
{ tag: u.string, color: "#c3e88d" },
{ tag: u.special(u.string), color: "#c3e88d" },
{ tag: u.comment, color: "#7d8799" },
{ tag: u.variableName, color: "#c792ea" },
{ tag: u.tagName, color: "#c3e88d" },
{ tag: u.bracket, color: "#525154" },
{ tag: u.meta, color: "#ffcb6b" },
{ tag: u.attributeName, color: "#c792ea" },
{ tag: u.propertyName, color: "#c792ea" },
{ tag: u.className, color: "#decb6b" },
{ tag: u.invalid, color: "#ffffff" }
]
});
const X = ne.define(), ye = oe.define({
create() {
return M.none;
},
update(e, t) {
try {
for (let r of t.effects)
if (r.is(X))
if (r.value) {
const n = M.mark({ attributes: { style: "background-color: #FFCA2880" } });
e = M.set([n.range(0, t.newDoc.length)]);
} else
e = M.set([]);
return e;
} catch (r) {
return console.warn("flash error", r), e;
}
},
provide: (e) => re.decorations.from(e)
}), we = (e) => {
e.dispatch({ effects: X.of(!0) }), setTimeout(() => {
e.dispatch({ effects: X.of(!1) });
}, 200);
}, B = ne.define(), ke = oe.define({
create() {
return M.none;
},
update(e, t) {
try {
for (let r of t.effects)
if (r.is(B)) {
const n = r.value.map(
(l) => (l.context.locations || []).map(({ start: m, end: f }) => {
const c = l.context.color || "#FFCA28";
let s = t.newDoc.line(m.line).from + m.column, g = t.newDoc.line(f.line).from + f.column;
const b = t.newDoc.length;
return s > b || g > b ? void 0 : M.mark({ attributes: { style: `outline: 1.5px solid ${c};` } }).range(s, g);
})
).flat().filter(Boolean) || [];
e = M.set(n, !0);
}
return e;
} catch {
return M.set([]);
}
},
provide: (e) => re.decorations.from(e)
}), Fe = [de(), Ee, ke, ye];
function _e({ value: e, onChange: t, onViewChanged: r, onSelectionChange: n, options: l, editorDidMount: m }) {
const f = E(
(g) => {
t?.(g);
},
[t]
), c = E(
(g) => {
r?.(g);
},
[r]
), s = E(
(g) => {
g.selectionSet && n && n?.(g.state.selection);
},
[n]
);
return /* @__PURE__ */ d.createElement(d.Fragment, null, /* @__PURE__ */ d.createElement(ue, {
value: e,
onChange: f,
onCreateEditor: c,
onUpdate: s,
extensions: Fe
}));
}
function T(...e) {
return e.filter(Boolean).join(" ");
}
function Me({ view: e, pattern: t, active: r, getTime: n }) {
const l = A([]), m = A(0);
k(() => {
if (e)
if (t && r) {
m.current = 0;
let f = requestAnimationFrame(function c() {
try {
const s = n(), b = [Math.max(m.current ?? s, s - 1 / 10, -0.01), s + 1 / 60];
m.current = b[1], l.current = l.current.filter((h) => h.whole.end > s);
const i = t.queryArc(...b).filter((h) => h.hasOnset());
l.current = l.current.concat(i), e.dispatch({ effects: B.of(l.current) });
} catch {
e.dispatch({ effects: B.of([]) });
}
f = requestAnimationFrame(c);
});
return () => {
cancelAnimationFrame(f);
};
} else
l.current = [], e.dispatch({ effects: B.of([]) });
}, [t, r, e]);
}
function Ae(e, t = !1) {
const r = A(), n = A(), l = (c) => {
if (n.current !== void 0) {
const s = c - n.current;
e(c, s);
}
n.current = c, r.current = requestAnimationFrame(l);
}, m = () => {
r.current = requestAnimationFrame(l);
}, f = () => {
r.current && cancelAnimationFrame(r.current), delete r.current;
};
return k(() => {
r.current && (f(), m());
}, [e]), k(() => (t && m(), f), []), {
start: m,
stop: f
};
}
function Ne({ pattern: e, started: t, getTime: r, onDraw: n, drawTime: l = [-2, 2] }) {
let [m, f] = l;
m = Math.abs(m);
let c = A([]), s = A(null);
k(() => {
if (e && t) {
const i = r(), h = e.queryArc(Math.max(i, 0), i + f + 0.1);
c.current = c.current.filter((p) => p.whole.begin < i), c.current = c.current.concat(h);
}
}, [e, t]);
const { start: g, stop: b } = Ae(
E(() => {
const i = r() + f;
if (s.current === null) {
s.current = i;
return;
}
const h = e.queryArc(Math.max(s.current, i - 1 / 10), i);
s.current = i, c.current = (c.current || []).filter((p) => p.whole.end >= i - m - f).concat(h.filter((p) => p.hasOnset())), n(e, i - f, c.current, l);
}, [e])
);
return k(() => {
t ? g() : (c.current = [], b());
}, [t]), {
clear: () => {
c.current = [];
}
};
}
function Ce(e) {
return k(() => (window.addEventListener("message", e), () => window.removeEventListener("message", e)), [e]), E((t) => window.postMessage(t, "*"), []);
}
function De({
defaultOutput: e,
interval: t,
getTime: r,
evalOnMount: n = !1,
initialCode: l = "",
autolink: m = !1,
beforeEval: f,
afterEval: c,
editPattern: s,
onEvalError: g,
onToggle: b,
canvasId: i,
drawContext: h,
drawTime: p = [-2, 2]
}) {
const D = Q(() => Re(), []);
i = i || `canvas-${D}`;
const [P, R] = _(), [z, H] = _(), [y, S] = _(l), [V, q] = _(), [x, I] = _(), [N, O] = _(!1), K = y !== V, L = E((a) => !!(a?.context?.onPaint && h), [h]), { scheduler: C, evaluate: o, start: v, stop: j, pause: U } = Q(
() => pe({
interval: t,
defaultOutput: e,
onSchedulerError: R,
onEvalError: (a) => {
H(a), g?.(a);
},
getTime: r,
drawContext: h,
transpiler: be,
editPattern: s,
beforeEval: ({ code: a }) => {
S(a), f?.();
},
afterEval: ({ pattern: a, code: w }) => {
q(w), I(a), H(), R(), m && (window.location.hash = "#" + encodeURIComponent(btoa(w))), c?.();
},
onToggle: (a) => {
O(a), b?.(a);
}
}),
[e, t, r]
), ce = Ce(({ data: { from: a, type: w } }) => {
w === "start" && a !== D && j();
}), Y = E(
async (a = !0) => {
const w = await o(y, a);
return ce({ type: "start", from: D }), w;
},
[o, y]
), W = E(
(a, w, G, J) => {
const { onPaint: ie } = a.context || {}, le = typeof h == "function" ? h(i) : h;
ie?.(le, w, G, J);
},
[h, i]
), $ = E(
(a) => {
if (L(a)) {
const [w, G] = p, J = a.queryArc(0, G);
W(a, -1e-3, J, p);
}
},
[p, W, L]
), Z = A();
k(() => {
!Z.current && n && y && (Z.current = !0, o(y, !1).then((a) => $(a)));
}, [n, y, o, $]), k(() => () => {
C.stop();
}, [C]);
const ae = async () => {
N ? (C.stop(), $(x)) : await Y();
}, se = P || z;
return Ne({
pattern: x,
started: L(x) && N,
getTime: () => C.now(),
drawTime: p,
onDraw: W
}), {
id: D,
canvasId: i,
code: y,
setCode: S,
error: se,
schedulerError: P,
scheduler: C,
evalError: z,
evaluate: o,
activateCode: Y,
activeCode: V,
isDirty: K,
pattern: x,
started: N,
start: v,
stop: j,
pause: U,
togglePlay: ae
};
}
function Re() {
return Math.floor((1 + Math.random()) * 65536).toString(16).substring(1);
}
function ee({ type: e }) {
return /* @__PURE__ */ d.createElement("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "sc-h-5 sc-w-5",
viewBox: "0 0 20 20",
fill: "currentColor"
}, {
refresh: /* @__PURE__ */ d.createElement("path", {
fillRule: "evenodd",
d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z",
clipRule: "evenodd"
}),
play: /* @__PURE__ */ d.createElement("path", {
fillRule: "evenodd",
d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z",
clipRule: "evenodd"
}),
pause: /* @__PURE__ */ d.createElement("path", {
fillRule: "evenodd",
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z",
clipRule: "evenodd"
}),
stop: /* @__PURE__ */ d.createElement("path", {
fillRule: "evenodd",
d: "M2 10a8 8 0 1116 0 8 8 0 01-16 0zm5-2.25A.75.75 0 017.75 7h4.5a.75.75 0 01.75.75v4.5a.75.75 0 01-.75.75h-4.5a.75.75 0 01-.75-.75v-4.5z",
clipRule: "evenodd"
})
}[e]);
}
const xe = "_container_3i85k_1", Le = "_header_3i85k_5", Pe = "_buttons_3i85k_9", qe = "_button_3i85k_9", ze = "_buttonDisabled_3i85k_17", He = "_error_3i85k_21", Se = "_body_3i85k_25", F = {
container: xe,
header: Le,
buttons: Pe,
button: qe,
buttonDisabled: ze,
error: He,
body: Se
}, Ve = () => he().currentTime;
function Ze({ tune: e, hideOutsideView: t = !1, enableKeyboard: r, drawTime: n, punchcard: l, canvasHeight: m = 200 }) {
n = n || (l ? [0, 4] : void 0);
const f = !!n, c = E(
n ? (o) => document.querySelector("#" + o)?.getContext("2d") : null,
[n]
), {
code: s,
setCode: g,
evaluate: b,
activateCode: i,
error: h,
isDirty: p,
activeCode: D,
pattern: P,
started: R,
scheduler: z,
togglePlay: H,
stop: y,
canvasId: S,
id: V
} = De({
initialCode: e,
defaultOutput: me,
editPattern: (o) => l ? o.punchcard() : o,
getTime: Ve,
evalOnMount: f,
drawContext: c,
drawTime: n
}), [q, x] = _(), [I, N] = ge({
threshold: 0.01
}), O = A(), K = Q(() => ((N || !t) && (O.current = !0), N || O.current), [N, t]);
Me({
view: q,
pattern: P,
active: R && !D?.includes("strudel disable-highlighting"),
getTime: () => z.now()
}), te(() => {
if (r) {
const o = async (v) => {
(v.ctrlKey || v.altKey) && (v.code === "Enter" ? (v.preventDefault(), we(q), await i()) : v.code === "Period" && (y(), v.preventDefault()));
};
return window.addEventListener("keydown", o, !0), () => window.removeEventListener("keydown", o, !0);
}
}, [r, P, s, b, y, q]);
const [L, C] = _([]);
return Oe(
E((o) => {
const { data: v } = o.detail;
v?.hap?.context?.id === V && C((U) => U.concat([o.detail]).slice(-10));
}, [])
), /* @__PURE__ */ d.createElement("div", {
className: F.container,
ref: I
}, /* @__PURE__ */ d.createElement("div", {
className: F.header
}, /* @__PURE__ */ d.createElement("div", {
className: F.buttons
}, /* @__PURE__ */ d.createElement("button", {
className: T(F.button, R ? "sc-animate-pulse" : ""),
onClick: () => H()
}, /* @__PURE__ */ d.createElement(ee, {
type: R ? "stop" : "play"
})), /* @__PURE__ */ d.createElement("button", {
className: T(p ? F.button : F.buttonDisabled),
onClick: () => i()
}, /* @__PURE__ */ d.createElement(ee, {
type: "refresh"
}))), h && /* @__PURE__ */ d.createElement("div", {
className: F.error
}, h.message)), /* @__PURE__ */ d.createElement("div", {
className: F.body
}, K && /* @__PURE__ */ d.createElement(_e, {
value: s,
onChange: g,
onViewChanged: x
})), n && /* @__PURE__ */ d.createElement("canvas", {
id: S,
className: "w-full pointer-events-none",
height: m,
ref: (o) => {
o && o.width !== o.clientWidth && (o.width = o.clientWidth);
}
}), !!L.length && /* @__PURE__ */ d.createElement("div", {
className: "sc-bg-gray-800 sc-rounded-md sc-p-2"
}, L.map(({ message: o }, v) => /* @__PURE__ */ d.createElement("div", {
key: v
}, o))));
}
function Oe(e) {
Be(ve.key, e);
}
function Be(e, t, r = !1) {
k(() => (document.addEventListener(e, t, r), () => {
document.removeEventListener(e, t, r);
}), [t]);
}
const Te = (e) => te(() => (window.addEventListener("keydown", e, !0), () => window.removeEventListener("keydown", e, !0)), [e]);
export {
_e as CodeMirror,
Ze as MiniRepl,
T as cx,
we as flash,
Me as useHighlighting,
Te as useKeydown,
Ce as usePostMessage,
De as useStrudel
};
+1
View File
@@ -0,0 +1 @@
.cm-editor{background-color:transparent!important;height:100%;z-index:11;font-size:18px}.cm-theme-light{width:100%}.cm-line>*{background:#00000095}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sc-h-5{height:1.25rem}.sc-w-5{width:1.25rem}@keyframes sc-pulse{50%{opacity:.5}}.sc-animate-pulse{animation:sc-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.sc-rounded-md{border-radius:.375rem}.sc-bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity))}.sc-p-2{padding:.5rem}._container_3i85k_1{overflow:hidden;border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(34 34 34 / var(--tw-bg-opacity))}._header_3i85k_5{display:flex;justify-content:space-between;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(100 116 139 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity))}._buttons_3i85k_9{display:flex}._button_3i85k_9{display:flex;width:4rem;cursor:pointer;align-items:center;justify-content:center;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(100 116 139 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity));padding:.25rem;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}._button_3i85k_9:hover{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity))}._buttonDisabled_3i85k_17{display:flex;width:4rem;cursor:pointer;cursor:not-allowed;align-items:center;justify-content:center;--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity));padding:.25rem;--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}._error_3i85k_21{padding:.25rem;text-align:right;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity))}._body_3i85k_25{position:relative;overflow:auto}
+1 -1
View File
@@ -8,7 +8,7 @@ pnpm-debug.log*
lerna-debug.log*
node_modules
dist
!dist
dist-ssr
*.local
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.cm-editor{background-color:transparent!important;height:100%;z-index:11;font-size:16px}.cm-theme-light{width:100%}.cm-line>*{background:#00000095}*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.fixed{position:fixed}.absolute{position:absolute}.bottom-0{bottom:0px}.z-\[12\]{z-index:12}.flex{display:flex}.w-full{width:100%}.justify-center{justify-content:center}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.bg-slate-500{--tw-bg-opacity: 1;background-color:rgb(100 116 139 / var(--tw-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}body{background:#123}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{f as s,i as t,h as o,j as d,q as f,l as p,k as u,p as i,o as l,n as r,w as g}from"./index.ec9f9930.js";export{s as getAudioContext,t as getCachedBuffer,o as getDestination,d as getLoadedBuffer,f as getLoadedSamples,p as loadBuffer,u as loadGithubSamples,i as panic,l as resetLoadedSamples,r as samples,g as webaudioOutput};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{P as w}from"./index.ec9f9930.js";var i,f=!1;async function b(a=38400){if(!f){if(f=!0,i)return i;if("serial"in navigator){const r=await navigator.serial.requestPort();await r.open({baudRate:a});const o=new TextEncoderStream;o.readable.pipeTo(r.writable);const s=o.writable.getWriter();i=function(e){s.write(e)}}else throw"Webserial is not available in this browser."}}const g=.1;w.prototype.serial=function(...a){return this._withHap(r=>{i||b(...a);const o=(s,e,u)=>{var t="";if(typeof e.value=="object")if("action"in e.value){t+=e.value.action+"(";var c=!0;for(const[n,l]of Object.entries(e.value))n!=="action"&&(c?c=!1:t+=",",t+=`${n}:${l}`);t+=")"}else for(const[n,l]of Object.entries(e.value))t+=`${n}:${l};`;else t=e.value;const v=(s-u+g)*1e3;window.setTimeout(i,v,t)};return r.setContext({...r.context,onTrigger:o})})};export{b as getWriter};
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Strudel Nano REPL</title>
<script type="module" crossorigin src="./assets/index.ec9f9930.js"></script>
<link rel="stylesheet" href="./assets/index.75f8960b.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
File diff suppressed because it is too large Load Diff
+3 -10
View File
@@ -1,7 +1,7 @@
{
"name": "@strudel.cycles/nano-repl",
"name": "nano-repl",
"private": true,
"version": "0.6.0",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
@@ -10,14 +10,7 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/osc": "workspace:*",
"@strudel.cycles/mini": "workspace:*",
"@strudel.cycles/transpiler": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/tonal": "workspace:*",
"@strudel.cycles/react": "workspace:*"
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.17",
+17 -9
View File
@@ -1,21 +1,27 @@
import { controls, evalScope } from '@strudel.cycles/core';
import { CodeMirror, useHighlighting, useKeydown, useStrudel, flash } from '@strudel.cycles/react';
import { getAudioContext, initAudioOnFirstClick, panic, webaudioOutput } from '@strudel.cycles/webaudio';
import { evalScope, controls } from '@strudel.cycles/core';
import { getAudioContext, panic, webaudioOutput } from '@strudel.cycles/webaudio';
import { useCallback, useState } from 'react';
import CodeMirror, { flash } from '../../../src/components/CodeMirror6';
import useKeydown from '../../../src/hooks/useKeydown.mjs';
import useStrudel from '../../../src/hooks/useStrudel';
import useHighlighting from '../../../src/hooks/useHighlighting';
import './style.css';
// import { prebake } from '../../../../../repl/src/prebake.mjs';
initAudioOnFirstClick();
// TODO: only import stuff when play is pressed?
evalScope(
controls,
import('@strudel.cycles/core'),
// import('@strudel.cycles/tone'),
// import('@strudel.cycles/midi'), // TODO: find out why midi loads tone.js
import('@strudel.cycles/tonal'),
import('@strudel.cycles/mini'),
import('@strudel.cycles/xen'),
import('@strudel.cycles/webaudio'),
import('@strudel.cycles/osc'),
import('@strudel.cycles/webdirt'),
import('@strudel.cycles/serial'),
import('@strudel.cycles/soundfonts'),
);
const defaultTune = `samples({
@@ -24,7 +30,7 @@ const defaultTune = `samples({
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
stack(
s("bd,[~ <sd!3 sd(3,4,2)>],hh*8") // drums
s("bd,[~ <sd!3 sd(3,4,2)>],hh(3,4)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
//.hush()
,"<a1 b1*2 a1(3,8) e2>" // bassline
@@ -37,7 +43,7 @@ stack(
.gain(.4) // turn down
.cutoff(sine.slow(7).range(300,5000)) // automate cutoff
//.hush()
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings('lefthand') // chords
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings() // chords
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
.add(perlin.range(0,.5)) // random pitch variation
.n() // wrap in "n"
@@ -97,7 +103,7 @@ function App() {
scheduler.start();
}
} else if (e.code === 'Period') {
scheduler.stop();
scheduler.pause();
panic();
e.preventDefault();
}
@@ -108,11 +114,13 @@ function App() {
);
return (
<div>
<nav className="z-[12] w-full flex justify-center fixed bottom-0">
{/* <textarea value={code} onChange={(e) => setCode(e.target.value)} cols="64" rows="30" /> */}
<nav className="z-[12] w-full flex justify-center absolute bottom-0">
<div className="bg-slate-500 space-x-2 px-2 rounded-t-md">
<button
onClick={async () => {
await evaluate(code);
await getAudioContext().resume();
scheduler.start();
}}
>
+17 -14
View File
@@ -1,18 +1,24 @@
{
"name": "@strudel.cycles/react",
"version": "0.6.0",
"version": "0.5.0",
"description": "React components for strudel",
"main": "src/index.js",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"exports": {
".": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.es.js"
},
"./dist/style.css": "./dist/style.css"
},
"files": [
"dist"
],
"scripts": {
"dev": "vite",
"build": "vite build",
"watch": "vite build --watch",
"preview": "vite preview",
"prepublishOnly": "npm run build"
"preview": "vite preview"
},
"repository": {
"type": "git",
@@ -32,14 +38,11 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@codemirror/autocomplete": "^6.4.0",
"@codemirror/lang-javascript": "^6.1.1",
"@codemirror/state": "^6.2.0",
"@codemirror/view": "^6.7.3",
"@lezer/highlight": "^1.1.3",
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/transpiler": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/core": "^0.5.0",
"@strudel.cycles/tone": "^0.5.0",
"@strudel.cycles/transpiler": "^0.5.0",
"@strudel.cycles/webaudio": "^0.5.0",
"@uiw/codemirror-themes": "^4.12.4",
"@uiw/react-codemirror": "^4.12.4",
"react-hook-inview": "^4.5.0"
+1
View File
@@ -6,6 +6,7 @@ import { controls, evalScope } from '@strudel.cycles/core';
evalScope(
controls,
import('@strudel.cycles/core'),
// import('@strudel.cycles/tone'),
import('@strudel.cycles/tonal'),
import('@strudel.cycles/mini'),
import('@strudel.cycles/midi'),
@@ -1,77 +0,0 @@
import { createRoot } from 'react-dom/client';
import jsdoc from '../../../../doc.json';
const getDocLabel = (doc) => doc.name || doc.longname;
const getInnerText = (html) => {
var div = document.createElement('div');
div.innerHTML = html;
return div.textContent || div.innerText || '';
};
export function Autocomplete({ doc }) {
return (
<div className="prose dark:prose-invert max-h-[400px] overflow-auto">
<h3 className="pt-0 mt-0">{getDocLabel(doc)}</h3>
<div dangerouslySetInnerHTML={{ __html: doc.description }} />
<ul>
{doc.params?.map(({ name, type, description }, i) => (
<li key={i}>
{name} : {type.names?.join(' | ')} {description ? <> - {getInnerText(description)}</> : ''}
</li>
))}
</ul>
<div>
{doc.examples?.map((example, i) => (
<div key={i}>
<pre
className="cursor-pointer"
onMouseDown={(e) => {
console.log('ola!');
navigator.clipboard.writeText(example);
e.stopPropagation();
}}
>
{example}
</pre>
</div>
))}
</div>
</div>
);
}
const jsdocCompletions = jsdoc.docs
.filter(
(doc) =>
getDocLabel(doc) &&
!getDocLabel(doc).startsWith('_') &&
!['package'].includes(doc.kind) &&
!['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)),
)
// https://codemirror.net/docs/ref/#autocomplete.Completion
.map((doc) /*: Completion */ => ({
label: getDocLabel(doc),
// detail: 'xxx', // An optional short piece of information to show (with a different style) after the label.
info: () => {
const node = document.createElement('div');
// if Autocomplete is non-interactive, it could also be rendered at build time..
// .. using renderToStaticMarkup
createRoot(node).render(<Autocomplete doc={doc} />);
return node;
},
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
}));
export const strudelAutocomplete = (context /* : CompletionContext */) => {
let word = context.matchBefore(/\w*/);
if (word.from == word.to && !context.explicit) return null;
return {
from: word.from,
options: jsdocCompletions,
/* options: [
{ label: 'match', type: 'keyword' },
{ label: 'hello', type: 'variable', info: '(World)' },
{ label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' },
], */
};
};
+4 -23
View File
@@ -6,8 +6,6 @@ import { javascript } from '@codemirror/lang-javascript';
import strudelTheme from '../themes/strudel-theme';
import './style.css';
import { useCallback } from 'react';
import { autocompletion } from '@codemirror/autocomplete';
import { strudelAutocomplete } from './Autocomplete';
export const setFlash = StateEffect.define();
const flashField = StateField.define({
@@ -51,12 +49,11 @@ const highlightField = StateField.define({
try {
for (let e of tr.effects) {
if (e.is(setHighlights)) {
const { haps } = e.value;
const marks =
haps
e.value
.map((hap) =>
(hap.context.locations || []).map(({ start, end }) => {
const color = hap.context.color || e.value.color || '#FFCA28';
const color = hap.context.color || '#FFCA28';
let from = tr.newDoc.line(start.line).from + start.column;
let to = tr.newDoc.line(end.line).from + end.column;
const l = tr.newDoc.length;
@@ -82,24 +79,9 @@ const highlightField = StateField.define({
provide: (f) => EditorView.decorations.from(f),
});
const extensions = [
javascript(),
highlightField,
flashField,
// javascriptLanguage.data.of({ autocomplete: strudelAutocomplete }),
// autocompletion({ override: [strudelAutocomplete] }),
autocompletion({ override: [] }), // wait for https://github.com/uiwjs/react-codemirror/pull/458
];
const extensions = [javascript(), strudelTheme, highlightField, flashField];
export default function CodeMirror({
value,
onChange,
onViewChanged,
onSelectionChange,
theme,
options,
editorDidMount,
}) {
export default function CodeMirror({ value, onChange, onViewChanged, onSelectionChange, options, editorDidMount }) {
const handleOnChange = useCallback(
(value) => {
onChange?.(value);
@@ -124,7 +106,6 @@ export default function CodeMirror({
<>
<_CodeMirror
value={value}
theme={theme || strudelTheme}
onChange={handleOnChange}
onCreateEditor={handleOnCreateEditor}
onUpdate={handleOnUpdate}
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
export function Icon({ type }) {
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<svg xmlns="http://www.w3.org/2000/svg" className="sc-h-5 sc-w-5" viewBox="0 0 20 20" fill="currentColor">
{
{
refresh: (
+14 -37
View File
@@ -10,21 +10,10 @@ import { Icon } from './Icon';
import styles from './MiniRepl.module.css';
import './style.css';
import { logger } from '@strudel.cycles/core';
import useEvent from '../hooks/useEvent.mjs';
import useKeydown from '../hooks/useKeydown.mjs';
const getTime = () => getAudioContext().currentTime;
export function MiniRepl({
tune,
hideOutsideView = false,
enableKeyboard,
drawTime,
punchcard,
canvasHeight = 200,
theme,
highlightColor,
}) {
export function MiniRepl({ tune, hideOutsideView = false, enableKeyboard, drawTime, punchcard, canvasHeight = 200 }) {
drawTime = drawTime || (punchcard ? [0, 4] : undefined);
const evalOnMount = !!drawTime;
const drawContext = useCallback(
@@ -72,30 +61,8 @@ export function MiniRepl({
pattern,
active: started && !activeCode?.includes('strudel disable-highlighting'),
getTime: () => scheduler.now(),
color: highlightColor,
});
// keyboard shortcuts
useKeydown(
useCallback(
async (e) => {
if (view?.hasFocus) {
if (e.ctrlKey || e.altKey) {
if (e.code === 'Enter') {
e.preventDefault();
flash(view);
await activateCode();
} else if (e.code === 'Period') {
stop();
e.preventDefault();
}
}
}
},
[activateCode, stop, view],
),
);
// set active pattern on ctrl+enter
useLayoutEffect(() => {
if (enableKeyboard) {
@@ -134,7 +101,7 @@ export function MiniRepl({
<div className={styles.container} ref={ref}>
<div className={styles.header}>
<div className={styles.buttons}>
<button className={cx(styles.button, started ? 'animate-pulse' : '')} onClick={() => togglePlay()}>
<button className={cx(styles.button, started ? 'sc-animate-pulse' : '')} onClick={() => togglePlay()}>
<Icon type={started ? 'stop' : 'play'} />
</button>
<button className={cx(isDirty ? styles.button : styles.buttonDisabled)} onClick={() => activateCode()}>
@@ -144,7 +111,7 @@ export function MiniRepl({
{error && <div className={styles.error}>{error.message}</div>}
</div>
<div className={styles.body}>
{show && <CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} theme={theme} />}
{show && <CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} />}
</div>
{drawTime && (
<canvas
@@ -159,7 +126,7 @@ export function MiniRepl({
></canvas>
)}
{!!log.length && (
<div className="bg-gray-800 rounded-md p-2">
<div className="sc-bg-gray-800 sc-rounded-md sc-p-2">
{log.map(({ message }, i) => (
<div key={i}>{message}</div>
))}
@@ -173,3 +140,13 @@ export function MiniRepl({
function useLogger(onTrigger) {
useEvent(logger.key, onTrigger);
}
// TODO: dedupe
function useEvent(name, onTrigger, useCapture = false) {
useEffect(() => {
document.addEventListener(name, onTrigger, useCapture);
return () => {
document.removeEventListener(name, onTrigger, useCapture);
};
}, [onTrigger]);
}
@@ -1,27 +1,27 @@
.container {
@apply overflow-hidden;
@apply sc-rounded-md sc-overflow-hidden sc-bg-[#222222];
}
.header {
@apply flex justify-between bg-lineHighlight border-t border-l border-r border-lineHighlight rounded-t-md overflow-hidden;
@apply sc-flex sc-justify-between sc-bg-slate-700 sc-border-t sc-border-slate-500;
}
.buttons {
@apply flex;
@apply sc-flex;
}
.button {
@apply cursor-pointer w-16 flex items-center justify-center p-1 border-r border-lineHighlight text-foreground hover:bg-background;
@apply sc-cursor-pointer sc-w-16 sc-flex sc-items-center sc-justify-center sc-p-1 sc-bg-slate-700 sc-border-r sc-border-slate-500 sc-text-white hover:sc-bg-slate-600;
}
.buttonDisabled {
@apply w-16 flex items-center justify-center p-1 opacity-50 cursor-not-allowed border-r border-lineHighlight;
@apply sc-cursor-pointer sc-w-16 sc-flex sc-items-center sc-justify-center sc-p-1 sc-bg-slate-600 sc-text-slate-400 sc-cursor-not-allowed;
}
.error {
@apply text-right p-1 text-sm text-red-200;
@apply sc-text-right sc-p-1 sc-text-sm sc-text-red-200;
}
.body {
@apply overflow-auto relative;
@apply sc-overflow-auto sc-relative;
}
+4 -4
View File
@@ -5,10 +5,10 @@
font-size: 18px;
}
.cm-theme {
width: 100%;
}
.cm-theme-light {
width: 100%;
}
.cm-line > * {
background: #00000095;
}
-12
View File
@@ -1,12 +0,0 @@
import { useEffect } from 'react';
function useEvent(name, onTrigger, useCapture = false) {
useEffect(() => {
document.addEventListener(name, onTrigger, useCapture);
return () => {
document.removeEventListener(name, onTrigger, useCapture);
};
}, [onTrigger]);
}
export default useEvent;
+5 -5
View File
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react';
import { setHighlights } from '../components/CodeMirror6';
function useHighlighting({ view, pattern, active, getTime, color }) {
function useHighlighting({ view, pattern, active, getTime }) {
const highlights = useRef([]);
const lastEnd = useRef(0);
useEffect(() => {
@@ -19,9 +19,9 @@ function useHighlighting({ view, pattern, active, getTime, color }) {
highlights.current = highlights.current.filter((hap) => hap.whole.end > audioTime); // keep only highlights that are still active
const haps = pattern.queryArc(...span).filter((hap) => hap.hasOnset());
highlights.current = highlights.current.concat(haps); // add potential new onsets
view.dispatch({ effects: setHighlights.of({ haps: highlights.current, color }) }); // highlight all still active + new active haps
view.dispatch({ effects: setHighlights.of(highlights.current) }); // highlight all still active + new active haps
} catch (err) {
view.dispatch({ effects: setHighlights.of({ haps: [] }) });
view.dispatch({ effects: setHighlights.of([]) });
}
frame = requestAnimationFrame(updateHighlights);
});
@@ -30,10 +30,10 @@ function useHighlighting({ view, pattern, active, getTime, color }) {
};
} else {
highlights.current = [];
view.dispatch({ effects: setHighlights.of({ haps: [] }) });
view.dispatch({ effects: setHighlights.of([]) });
}
}
}, [pattern, active, view, color]);
}, [pattern, active, view]);
}
export default useHighlighting;
+4 -6
View File
@@ -1,11 +1,9 @@
// import 'tailwindcss/tailwind.css';
export { default as CodeMirror, flash } from './components/CodeMirror6'; // !SSR
export * from './components/MiniRepl'; // !SSR
export { default as useHighlighting } from './hooks/useHighlighting'; // !SSR
export { default as useStrudel } from './hooks/useStrudel'; // !SSR
export { default as CodeMirror, flash } from './components/CodeMirror6';
export * from './components/MiniRepl';
export { default as useHighlighting } from './hooks/useHighlighting';
export { default as usePostMessage } from './hooks/usePostMessage';
export { default as useStrudel } from './hooks/useStrudel';
export { default as useKeydown } from './hooks/useKeydown';
export { default as useEvent } from './hooks/useEvent';
export { default as strudelTheme } from './themes/strudel-theme';
export { default as cx } from './cx';
+1
View File
@@ -7,4 +7,5 @@ module.exports = {
corePlugins: {
preflight: false,
},
prefix: 'sc-',
};
+1 -1
View File
@@ -14,7 +14,7 @@ export default defineConfig({
lib: {
entry: resolve(__dirname, 'src', 'index.js'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
fileName: (ext) => `index.${ext}.js`,
// for UMD name: 'GlobalName'
},
rollupOptions: {
+1
View File
@@ -1,3 +1,4 @@
# @strudel.cycles/serial
This package adds webserial functionality to strudel Patterns, for e.g. sending messages to arduino microcontrollers.
+2 -16
View File
@@ -1,16 +1,8 @@
{
"name": "@strudel.cycles/serial",
"version": "0.6.0",
"version": "0.3.0",
"description": "Webserial API for strudel",
"main": "serial.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
"prepublishOnly": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
@@ -27,11 +19,5 @@
"bugs": {
"url": "https://github.com/tidalcycles/strudel/issues"
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*"
},
"devDependencies": {
"vite": "^3.2.2"
}
"homepage": "https://github.com/tidalcycles/strudel#readme"
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'serial.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+301
View File
@@ -0,0 +1,301 @@
{
"name": "@strudel.cycles/soundfonts",
"version": "0.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@strudel.cycles/soundfonts",
"version": "0.1.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"webaudiofont": "^3.0.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=="
},
"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==",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
},
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"node_modules/marked": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"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==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/shiki": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
"dependencies": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "5.2.0"
}
},
"node_modules/typedoc": {
"version": "0.22.17",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz",
"integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==",
"dependencies": {
"glob": "^8.0.3",
"lunr": "^2.3.9",
"marked": "^4.0.16",
"minimatch": "^5.1.0",
"shiki": "^0.10.1"
},
"bin": {
"typedoc": "bin/typedoc"
},
"engines": {
"node": ">= 12.10.0"
},
"peerDependencies": {
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x"
}
},
"node_modules/typescript": {
"version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/vscode-oniguruma": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA=="
},
"node_modules/vscode-textmate": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
},
"node_modules/webaudiofont": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz",
"integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==",
"dependencies": {
"typedoc": "^0.22.14"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
},
"dependencies": {
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
},
"lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"marked": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA=="
},
"minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"requires": {
"brace-expansion": "^2.0.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"shiki": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
"requires": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "5.2.0"
}
},
"typedoc": {
"version": "0.22.17",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz",
"integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==",
"requires": {
"glob": "^8.0.3",
"lunr": "^2.3.9",
"marked": "^4.0.16",
"minimatch": "^5.1.0",
"shiki": "^0.10.1"
}
},
"typescript": {
"version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"peer": true
},
"vscode-oniguruma": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA=="
},
"vscode-textmate": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
},
"webaudiofont": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz",
"integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==",
"requires": {
"typedoc": "^0.22.14"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
}
}
+4 -13
View File
@@ -1,16 +1,8 @@
{
"name": "@strudel.cycles/soundfonts",
"version": "0.6.0",
"version": "0.5.0",
"description": "Soundsfont support for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
"prepublishOnly": "npm run build"
},
"type": "module",
"repository": {
"type": "git",
@@ -30,13 +22,12 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/webaudio": "workspace:*",
"@strudel.cycles/core": "^0.5.0",
"@strudel.cycles/webaudio": "^0.5.0",
"sfumato": "^0.1.2",
"soundfont2": "^0.4.0"
},
"devDependencies": {
"node-fetch": "^3.2.6",
"vite": "^3.2.2"
"node-fetch": "^3.2.6"
}
}
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+2694
View File
File diff suppressed because it is too large Load Diff
+5 -15
View File
@@ -1,18 +1,12 @@
{
"name": "@strudel.cycles/tonal",
"version": "0.6.0",
"version": "0.5.0",
"description": "Tonal functions for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
"test": "vitest run",
"prepublishOnly": "npm run build"
},
"type": "module",
"scripts": {
"test": "vitest run"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
@@ -31,13 +25,9 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "workspace:*",
"@strudel.cycles/core": "^0.5.0",
"@tonaljs/tonal": "^4.7.2",
"chord-voicings": "^0.0.1",
"webmidi": "^3.0.21"
},
"devDependencies": {
"vite": "^3.2.2",
"vitest": "^0.25.7"
}
}
+5 -6
View File
@@ -123,18 +123,17 @@ export const scaleTranspose = register('scaleTranspose', function (offset /* : n
/**
* Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like {@link Pattern#scaleTranspose}.
*
* A scale consists of a root note (e.g. `c4`, `c`, `f#`, `bb4`) followed by a [scale type](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts).
* The root note defaults to octave 3, if no octave number is given.
* Note that you currently cannot pattern `scale` with the mini notation, because the scale name includes a space.
* This will be improved in the future. Until then, use a sequence function like `cat` or `seq`.
* The scale name has the form "TO? N" wher
*
* - T = Tonic
* - O = Octave (optional, defaults to 3)
* - N = Name of scale, available names can be found [here](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts).
*
* @memberof Pattern
* @name scale
* @param {string} scale Name of scale
* @returns Pattern
* @example
* "0 2 4 6 4 2".scale('C2 major').note()
* @example
* "0 2 4 6 4 2"
* .scale(seq('C2 major', 'C2 minor').slow(2))
* .note()
-19
View File
@@ -1,19 +0,0 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [],
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' }[ext]),
},
rollupOptions: {
external: [...Object.keys(dependencies)],
},
target: 'esnext',
},
});
+5 -4
View File
@@ -1,11 +1,9 @@
# @strudel.cycles/tone
Note: This package still works but is no longer maintained in favor of `@strudel.cycles/webaudio`.
This package adds Tone.js functions to strudel Patterns.
## Deprecation Note
This package will not be developed further. Consider using `@strudel.cycles/webaudio` as a replacement.
## Install
```sh
@@ -32,3 +30,6 @@ document.getElementById('play').addEventListener('click', async () => {
Tone.getTransport().start('+0.1');
});
```
[open in codesandbox](https://codesandbox.io/s/strudel-tone-example-5ph2te?file=/src/index.js:0-708)
+603
View File
@@ -0,0 +1,603 @@
{
"name": "@strudel.cycles/tone",
"version": "0.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@strudel.cycles/tone",
"version": "0.1.1",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@tonejs/piano": "^0.2.1",
"chord-voicings": "^0.0.1",
"tone": "^14.7.77"
}
},
"node_modules/@babel/runtime": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@tonaljs/abc-notation": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/abc-notation/-/abc-notation-4.6.5.tgz",
"integrity": "sha512-1S0Jnx0NfDLgyhkQOMEHqOacELL6RUdPcWWUP+nAnsOsb9owvB9RKYLSzp5odd16FVUR7U8c/JLc2yxIRvSeJw==",
"dependencies": {
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/array": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/array/-/array-4.6.5.tgz",
"integrity": "sha512-7A3DbBQ+qIQ134FqE518b4tJ8V2a15Sn303JjHzgnqZqKrNh/s3wqwkL60F7LKcd09tcp+vIKQP/MYt4xMcRAA==",
"dependencies": {
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/chord": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord/-/chord-4.6.5.tgz",
"integrity": "sha512-Pjdel4aDVv4kcx9PW6Qozt5BB9nAt13AOExfzKztpgPmlBSy0SKHse7Jp1cA4MGAuLHU8dzVssTFYpCskEFw3w==",
"dependencies": {
"@tonaljs/chord-detect": "^4.6.5",
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"node_modules/@tonaljs/chord-detect": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord-detect/-/chord-detect-4.6.5.tgz",
"integrity": "sha512-4xu53UP4kNTfdTNpAAVijhXcQ+ypJqmeMnsST08ZXSjoYfJUhmf5rWDWfz36KOTtNdCA6AbYgdtTYV/Xw0nd/w==",
"dependencies": {
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"node_modules/@tonaljs/chord-type": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord-type/-/chord-type-4.6.5.tgz",
"integrity": "sha512-Ol4DDopqpZCF9odosO2i8I+plud3Ul7VWJGNvL+PPCf4Qnwuz87q3aJQDLNoRUz4VyW0u66mq3LyVh6A8kb6Ug==",
"dependencies": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"node_modules/@tonaljs/collection": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/collection/-/collection-4.6.2.tgz",
"integrity": "sha512-bfPCotLJNB/tG1NrdbsQPLDKZB5jlMs7uPQ6RYKiNkaena3345ZKkbCGl5pj6YTXeDm/oblXiSbFAn7SlLRZdQ=="
},
"node_modules/@tonaljs/core": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/core/-/core-4.6.5.tgz",
"integrity": "sha512-t7Vx0+L3j/ubQj2AhI1H45D/K745np4DwJjJjXNi5FlGD+TL2wyw50dCwkHKGHsrLDqup1qqP6yN7LBpC6UwNg=="
},
"node_modules/@tonaljs/duration-value": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/duration-value/-/duration-value-4.6.2.tgz",
"integrity": "sha512-zrXT0L/qsDQ6251Mlqz54vcUbYUB9xb6uJhlxUzc6VauXOt8UOfrdTULubRTXTaBwWt1h8J5n9pXTQmNGzNI9A=="
},
"node_modules/@tonaljs/interval": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/interval/-/interval-4.6.5.tgz",
"integrity": "sha512-7EDWhqZ7Nnh9oD4ahRYJHLc799ACGxYL4hDHwMKD16B2MgXqPvDeDvwQ31qUuO0ruGz8tMb3FDlgg0Hplowcbw==",
"dependencies": {
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/key": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/key/-/key-4.6.5.tgz",
"integrity": "sha512-ZdZWb5IStx6CLRmdEjawR66CqNpoW3EVUua2nVZBMdgnNebWxt4nvgH/ZNvGlCQGFZkUZzRhCfTwqsS6e3OmSA==",
"dependencies": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5"
}
},
"node_modules/@tonaljs/midi": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/midi/-/midi-4.6.5.tgz",
"integrity": "sha512-fJEZtNvV3M6yW1w+Tep60Rbv5PvuKszQcQzaJS1Loq5mHOKAzdmRfuJSpEpZBiaKEZ1WAMh1QKXYyOd+imyGQg==",
"dependencies": {
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/mode": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/mode/-/mode-4.6.5.tgz",
"integrity": "sha512-54iaON1rJ6q8fV5iuei8RGDxYhKBGGxZz3rjAxGSqdTUwBRVOdPqtzOkofThf9gRGYOMhzPp1BMbxbV+UCAPsA==",
"dependencies": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/interval": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"node_modules/@tonaljs/note": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/note/-/note-4.6.5.tgz",
"integrity": "sha512-Y0/eTzcReXzfcSLLG4k/dLLayqbvh/XYIkybG/QMDyR0BREuJq0Sw+NavbzhTtO0dadIQb/qfe0GFq4k2xS+NQ==",
"dependencies": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/midi": "^4.6.5"
}
},
"node_modules/@tonaljs/pcset": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/pcset/-/pcset-4.6.5.tgz",
"integrity": "sha512-oWAKflP3cREnUfScqsBzg2LLKNevxSnpDtrq8CPtwOAsrAa8PjQG07NQfhqIiFMjPUdgkDiER3qVA1n8dDwAJA==",
"dependencies": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/progression": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/progression/-/progression-4.6.5.tgz",
"integrity": "sha512-ijYEgMFQG4izHYUw5cRtBRNBuoYzmpGvb/tRiykhJNI6XIjekZEMiMsOMfb1u5q+EGvnVNXRmrluMRDIz2rmRw==",
"dependencies": {
"@tonaljs/chord": "^4.6.5",
"@tonaljs/core": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5"
}
},
"node_modules/@tonaljs/range": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/range/-/range-4.6.5.tgz",
"integrity": "sha512-99cOvVJ3l4X0UJuTSa6qE87JriREnnWIsi3xo1/n7RoqFxnfi8YPh4SfJJyysvHcT18X4EfcTNde9ancMBVu6A==",
"dependencies": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/midi": "^4.6.5"
}
},
"node_modules/@tonaljs/roman-numeral": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/roman-numeral/-/roman-numeral-4.6.5.tgz",
"integrity": "sha512-bWYQNZWKmYDDcmbQQNwcWAHfTWanpzmvI0wplrMnGd4x0op5etwUEv+Yzjg0B1ef+E+zcU02Sl0WwRJhaDK3hg==",
"dependencies": {
"@tonaljs/core": "^4.6.5"
}
},
"node_modules/@tonaljs/scale": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/scale/-/scale-4.6.5.tgz",
"integrity": "sha512-isYDamelOBtcd5bEnJ8QV0Js7jKRwZ0FlFVE/+bUN3wsyo9u6KLL5gMyfH9RKdx74m8lE13JXYTXgKqe+AOa4A==",
"dependencies": {
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"node_modules/@tonaljs/scale-type": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/scale-type/-/scale-type-4.6.5.tgz",
"integrity": "sha512-rwcDOYf2UifjLJhmuQ8f8bJSeOCMDQJ1lB7lzlqdFxes03OeQhdOEfrT0nPtW8BhBEvq4GMM2NA6CLxX8MTwOQ==",
"dependencies": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"node_modules/@tonaljs/time-signature": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/time-signature/-/time-signature-4.6.2.tgz",
"integrity": "sha512-OlZY4gdLd21WpMeAI1nS9E9zWcYU6oAzh6ptAUndqmVnFIrIWIWKCkWapdFx8dWdqrX8jqya3m4T33wmeo7w5Q=="
},
"node_modules/@tonaljs/tonal": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/tonal/-/tonal-4.6.5.tgz",
"integrity": "sha512-lmsWinI9dy7nQyzCEgDVeVAwJtsk4ey05cJZd6oa4QVuSFD+CR8ebaEiwT4/Na+W0kHrKicT3h0uYc2PJIvx5Q==",
"dependencies": {
"@tonaljs/abc-notation": "^4.6.5",
"@tonaljs/array": "^4.6.5",
"@tonaljs/chord": "^4.6.5",
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/duration-value": "^4.6.2",
"@tonaljs/interval": "^4.6.5",
"@tonaljs/key": "^4.6.5",
"@tonaljs/midi": "^4.6.5",
"@tonaljs/mode": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/progression": "^4.6.5",
"@tonaljs/range": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5",
"@tonaljs/scale": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5",
"@tonaljs/time-signature": "^4.6.2"
}
},
"node_modules/@tonejs/piano": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@tonejs/piano/-/piano-0.2.1.tgz",
"integrity": "sha512-JIwZ91RSFR7Rt16o7cA7O7G30wenFl0lY5yhTsuwZmn48MO9KV+X7kyXE98Bqvs/dCBVg9PoAJ1GKMabPOW4yQ==",
"dependencies": {
"tslib": "^1.11.1"
},
"peerDependencies": {
"tone": "^14.6.1",
"webmidi": "^2.5.1"
}
},
"node_modules/automation-events": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-4.0.14.tgz",
"integrity": "sha512-CB2Me0yW8sz7gSGwMiSfgfs1Oqlgs53k+eVESN6axvRyMAD3zlSp2nqndD2TQAtW3yOtSEJWNGsw0r48+f1wtw==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"tslib": "^2.3.1"
},
"engines": {
"node": ">=12.20.1"
}
},
"node_modules/automation-events/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/chord-voicings": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/chord-voicings/-/chord-voicings-0.0.1.tgz",
"integrity": "sha512-SutgB/4ynkkuiK6qdQ/k3QvCFcH0Vj8Ch4t6LbRyRQbVzP/TOztiCk3kvXd516UZ6fqk7ijDRELEFcKN+6V8sA==",
"dependencies": {
"@tonaljs/tonal": "^4.6.5"
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"node_modules/standardized-audio-context": {
"version": "25.3.21",
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.21.tgz",
"integrity": "sha512-CZEnayJJjNefeU+z1QGDhaid1LAAYxWYa2ipNk75ropwec9rq6fmclyhXb1wGtDsZ402irX3HLt1U/PwP9+1fA==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"automation-events": "^4.0.14",
"tslib": "^2.3.1"
}
},
"node_modules/standardized-audio-context/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tone": {
"version": "14.7.77",
"resolved": "https://registry.npmjs.org/tone/-/tone-14.7.77.tgz",
"integrity": "sha512-tCfK73IkLHyzoKUvGq47gyDyxiKLFvKiVCOobynGgBB9Dl0NkxTM2p+eRJXyCYrjJwy9Y0XCMqD3uOYsYt2Fdg==",
"dependencies": {
"standardized-audio-context": "^25.1.8",
"tslib": "^2.0.1"
}
},
"node_modules/tone/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg==",
"peer": true,
"engines": {
"node": ">0.6.x"
}
}
},
"dependencies": {
"@babel/runtime": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@tonaljs/abc-notation": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/abc-notation/-/abc-notation-4.6.5.tgz",
"integrity": "sha512-1S0Jnx0NfDLgyhkQOMEHqOacELL6RUdPcWWUP+nAnsOsb9owvB9RKYLSzp5odd16FVUR7U8c/JLc2yxIRvSeJw==",
"requires": {
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/array": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/array/-/array-4.6.5.tgz",
"integrity": "sha512-7A3DbBQ+qIQ134FqE518b4tJ8V2a15Sn303JjHzgnqZqKrNh/s3wqwkL60F7LKcd09tcp+vIKQP/MYt4xMcRAA==",
"requires": {
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/chord": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord/-/chord-4.6.5.tgz",
"integrity": "sha512-Pjdel4aDVv4kcx9PW6Qozt5BB9nAt13AOExfzKztpgPmlBSy0SKHse7Jp1cA4MGAuLHU8dzVssTFYpCskEFw3w==",
"requires": {
"@tonaljs/chord-detect": "^4.6.5",
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"@tonaljs/chord-detect": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord-detect/-/chord-detect-4.6.5.tgz",
"integrity": "sha512-4xu53UP4kNTfdTNpAAVijhXcQ+ypJqmeMnsST08ZXSjoYfJUhmf5rWDWfz36KOTtNdCA6AbYgdtTYV/Xw0nd/w==",
"requires": {
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"@tonaljs/chord-type": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/chord-type/-/chord-type-4.6.5.tgz",
"integrity": "sha512-Ol4DDopqpZCF9odosO2i8I+plud3Ul7VWJGNvL+PPCf4Qnwuz87q3aJQDLNoRUz4VyW0u66mq3LyVh6A8kb6Ug==",
"requires": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"@tonaljs/collection": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/collection/-/collection-4.6.2.tgz",
"integrity": "sha512-bfPCotLJNB/tG1NrdbsQPLDKZB5jlMs7uPQ6RYKiNkaena3345ZKkbCGl5pj6YTXeDm/oblXiSbFAn7SlLRZdQ=="
},
"@tonaljs/core": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/core/-/core-4.6.5.tgz",
"integrity": "sha512-t7Vx0+L3j/ubQj2AhI1H45D/K745np4DwJjJjXNi5FlGD+TL2wyw50dCwkHKGHsrLDqup1qqP6yN7LBpC6UwNg=="
},
"@tonaljs/duration-value": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/duration-value/-/duration-value-4.6.2.tgz",
"integrity": "sha512-zrXT0L/qsDQ6251Mlqz54vcUbYUB9xb6uJhlxUzc6VauXOt8UOfrdTULubRTXTaBwWt1h8J5n9pXTQmNGzNI9A=="
},
"@tonaljs/interval": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/interval/-/interval-4.6.5.tgz",
"integrity": "sha512-7EDWhqZ7Nnh9oD4ahRYJHLc799ACGxYL4hDHwMKD16B2MgXqPvDeDvwQ31qUuO0ruGz8tMb3FDlgg0Hplowcbw==",
"requires": {
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/key": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/key/-/key-4.6.5.tgz",
"integrity": "sha512-ZdZWb5IStx6CLRmdEjawR66CqNpoW3EVUua2nVZBMdgnNebWxt4nvgH/ZNvGlCQGFZkUZzRhCfTwqsS6e3OmSA==",
"requires": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5"
}
},
"@tonaljs/midi": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/midi/-/midi-4.6.5.tgz",
"integrity": "sha512-fJEZtNvV3M6yW1w+Tep60Rbv5PvuKszQcQzaJS1Loq5mHOKAzdmRfuJSpEpZBiaKEZ1WAMh1QKXYyOd+imyGQg==",
"requires": {
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/mode": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/mode/-/mode-4.6.5.tgz",
"integrity": "sha512-54iaON1rJ6q8fV5iuei8RGDxYhKBGGxZz3rjAxGSqdTUwBRVOdPqtzOkofThf9gRGYOMhzPp1BMbxbV+UCAPsA==",
"requires": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/interval": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"@tonaljs/note": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/note/-/note-4.6.5.tgz",
"integrity": "sha512-Y0/eTzcReXzfcSLLG4k/dLLayqbvh/XYIkybG/QMDyR0BREuJq0Sw+NavbzhTtO0dadIQb/qfe0GFq4k2xS+NQ==",
"requires": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/midi": "^4.6.5"
}
},
"@tonaljs/pcset": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/pcset/-/pcset-4.6.5.tgz",
"integrity": "sha512-oWAKflP3cREnUfScqsBzg2LLKNevxSnpDtrq8CPtwOAsrAa8PjQG07NQfhqIiFMjPUdgkDiER3qVA1n8dDwAJA==",
"requires": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/progression": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/progression/-/progression-4.6.5.tgz",
"integrity": "sha512-ijYEgMFQG4izHYUw5cRtBRNBuoYzmpGvb/tRiykhJNI6XIjekZEMiMsOMfb1u5q+EGvnVNXRmrluMRDIz2rmRw==",
"requires": {
"@tonaljs/chord": "^4.6.5",
"@tonaljs/core": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5"
}
},
"@tonaljs/range": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/range/-/range-4.6.5.tgz",
"integrity": "sha512-99cOvVJ3l4X0UJuTSa6qE87JriREnnWIsi3xo1/n7RoqFxnfi8YPh4SfJJyysvHcT18X4EfcTNde9ancMBVu6A==",
"requires": {
"@tonaljs/collection": "^4.6.2",
"@tonaljs/midi": "^4.6.5"
}
},
"@tonaljs/roman-numeral": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/roman-numeral/-/roman-numeral-4.6.5.tgz",
"integrity": "sha512-bWYQNZWKmYDDcmbQQNwcWAHfTWanpzmvI0wplrMnGd4x0op5etwUEv+Yzjg0B1ef+E+zcU02Sl0WwRJhaDK3hg==",
"requires": {
"@tonaljs/core": "^4.6.5"
}
},
"@tonaljs/scale": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/scale/-/scale-4.6.5.tgz",
"integrity": "sha512-isYDamelOBtcd5bEnJ8QV0Js7jKRwZ0FlFVE/+bUN3wsyo9u6KLL5gMyfH9RKdx74m8lE13JXYTXgKqe+AOa4A==",
"requires": {
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5"
}
},
"@tonaljs/scale-type": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/scale-type/-/scale-type-4.6.5.tgz",
"integrity": "sha512-rwcDOYf2UifjLJhmuQ8f8bJSeOCMDQJ1lB7lzlqdFxes03OeQhdOEfrT0nPtW8BhBEvq4GMM2NA6CLxX8MTwOQ==",
"requires": {
"@tonaljs/core": "^4.6.5",
"@tonaljs/pcset": "^4.6.5"
}
},
"@tonaljs/time-signature": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@tonaljs/time-signature/-/time-signature-4.6.2.tgz",
"integrity": "sha512-OlZY4gdLd21WpMeAI1nS9E9zWcYU6oAzh6ptAUndqmVnFIrIWIWKCkWapdFx8dWdqrX8jqya3m4T33wmeo7w5Q=="
},
"@tonaljs/tonal": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/@tonaljs/tonal/-/tonal-4.6.5.tgz",
"integrity": "sha512-lmsWinI9dy7nQyzCEgDVeVAwJtsk4ey05cJZd6oa4QVuSFD+CR8ebaEiwT4/Na+W0kHrKicT3h0uYc2PJIvx5Q==",
"requires": {
"@tonaljs/abc-notation": "^4.6.5",
"@tonaljs/array": "^4.6.5",
"@tonaljs/chord": "^4.6.5",
"@tonaljs/chord-type": "^4.6.5",
"@tonaljs/collection": "^4.6.2",
"@tonaljs/core": "^4.6.5",
"@tonaljs/duration-value": "^4.6.2",
"@tonaljs/interval": "^4.6.5",
"@tonaljs/key": "^4.6.5",
"@tonaljs/midi": "^4.6.5",
"@tonaljs/mode": "^4.6.5",
"@tonaljs/note": "^4.6.5",
"@tonaljs/pcset": "^4.6.5",
"@tonaljs/progression": "^4.6.5",
"@tonaljs/range": "^4.6.5",
"@tonaljs/roman-numeral": "^4.6.5",
"@tonaljs/scale": "^4.6.5",
"@tonaljs/scale-type": "^4.6.5",
"@tonaljs/time-signature": "^4.6.2"
}
},
"@tonejs/piano": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@tonejs/piano/-/piano-0.2.1.tgz",
"integrity": "sha512-JIwZ91RSFR7Rt16o7cA7O7G30wenFl0lY5yhTsuwZmn48MO9KV+X7kyXE98Bqvs/dCBVg9PoAJ1GKMabPOW4yQ==",
"requires": {
"tslib": "^1.11.1"
}
},
"automation-events": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-4.0.14.tgz",
"integrity": "sha512-CB2Me0yW8sz7gSGwMiSfgfs1Oqlgs53k+eVESN6axvRyMAD3zlSp2nqndD2TQAtW3yOtSEJWNGsw0r48+f1wtw==",
"requires": {
"@babel/runtime": "^7.17.2",
"tslib": "^2.3.1"
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"chord-voicings": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/chord-voicings/-/chord-voicings-0.0.1.tgz",
"integrity": "sha512-SutgB/4ynkkuiK6qdQ/k3QvCFcH0Vj8Ch4t6LbRyRQbVzP/TOztiCk3kvXd516UZ6fqk7ijDRELEFcKN+6V8sA==",
"requires": {
"@tonaljs/tonal": "^4.6.5"
}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"standardized-audio-context": {
"version": "25.3.21",
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.21.tgz",
"integrity": "sha512-CZEnayJJjNefeU+z1QGDhaid1LAAYxWYa2ipNk75ropwec9rq6fmclyhXb1wGtDsZ402irX3HLt1U/PwP9+1fA==",
"requires": {
"@babel/runtime": "^7.17.2",
"automation-events": "^4.0.14",
"tslib": "^2.3.1"
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"tone": {
"version": "14.7.77",
"resolved": "https://registry.npmjs.org/tone/-/tone-14.7.77.tgz",
"integrity": "sha512-tCfK73IkLHyzoKUvGq47gyDyxiKLFvKiVCOobynGgBB9Dl0NkxTM2p+eRJXyCYrjJwy9Y0XCMqD3uOYsYt2Fdg==",
"requires": {
"standardized-audio-context": "^25.1.8",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg==",
"peer": true
}
}
}

Some files were not shown because too many files have changed in this diff Show More