This commit is contained in:
Felix Roos
2022-02-22 00:48:00 +01:00
parent f6be175af0
commit 413d401567
14 changed files with 873 additions and 471 deletions
File diff suppressed because one or more lines are too long
@@ -7338,29 +7338,28 @@ It aims to be `, /*#__PURE__*/ _react1.mdx("a", {
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
const drums = stack(
'c1*2'.m.tone(kick).bypass('<0@7 1>/8'.m),
'~ <x!7 [x@3 x]>'.m.tone(snare).bypass('<0@7 1>/4'.m),
'[~ c4]*2'.m.tone(hihat)
"c1*2".tone(kick).bypass("<0@7 1>/8"),
"~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
"[~ c4]*2".tone(hihat)
);
const thru = (x) => x.transpose('<0 1>/8'.m).transpose(-1);
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
const synths = stack(
'<eb4 d4 c4 b3>/2'.m.scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove('[~ x]*2'.m)
"<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove("[~ x]*2")
.edit(
scaleTranspose(0).early(0),
scaleTranspose(2).early(1/8),
scaleTranspose(7).early(1/4),
scaleTranspose(8).early(3/8)
).edit(thru).tone(keys).bypass('<1 0>/16'.m),
'<C2 Bb1 Ab1 [G1 [G2 G1]]>/2'.m.groove('[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2'.m.fast(2)).edit(thru).tone(bass),
'<Cm7 Bb7 Fm7 G7b13>/2'.m.groove('~ [x@0.1 ~]'.m.fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass('<0@7 1>/8'.m.early(1/4))
).edit(thru).tone(keys).bypass("<1 0>/16"),
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).edit(thru).tone(bass),
"<Cm7 Bb7 Fm7 G7b13>/2".groove("~ [x@0.1 ~]".fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4))
)
return stack(
drums.fast(2),
synths
).slow(2);
}`,
height: 400,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
@@ -7392,7 +7391,6 @@ Before diving deeper into the details, here is a flavor of how the mini language
[[a1 a2]*4]
]
]/16\``,
height: 600,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The snippet above is enclosed in backticks (\`), which allows you to write multi-line strings.
You can also use double quotes (") for single line mini notation.`), /*#__PURE__*/ _react1.mdx("h2", null, `Notes`), /*#__PURE__*/ _react1.mdx("p", null, `Notes are notated with the note letter, followed by the octave number. You can notate flats with `, /*#__PURE__*/ _react1.mdx("inlineCode", {
@@ -7496,7 +7494,6 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
stack(b3,d3,fs4),
stack(b3,e4,g4)
)`,
height: 200,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The above is equivalent to`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`,
@@ -7541,7 +7538,7 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
}, `early`), `.`), /*#__PURE__*/ _react1.mdx("p", null, `There is the shorthand `, /*#__PURE__*/ _react1.mdx("strong", {
parentName: "p"
}, `p`), ` for this:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.late(0.5))`,
tune: `cat(e5, b4.late(0.5))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `late(cycles)`), /*#__PURE__*/ _react1.mdx("p", null, `Like early, but in the other direction:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.late(0.5))`,
@@ -7550,10 +7547,10 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
tune: `cat(c3,d3,e3,f3).rev()`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `every(n, func)`), /*#__PURE__*/ _react1.mdx("p", null, `Will apply the given function every n cycles:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.every(4, late(0.5)))`,
tune: `cat(e5, pure(b4).every(4, late(0.5)))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Note that late is called directly. This is a shortcut for:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.every(4, x => x.late(0.5)))`,
tune: `cat(e5, pure(b4).every(4, x => x.late(0.5)))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: should the function really run the first cycle?`), /*#__PURE__*/ _react1.mdx("h3", null, `Functions not documented yet`), /*#__PURE__*/ _react1.mdx("ul", null, /*#__PURE__*/ _react1.mdx("li", {
parentName: "ul"
@@ -7591,21 +7588,20 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
"href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/tone.ts"
}, `Show Source on Github`)), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `stack(
"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".m
"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~"
.tone(synth(adsr(0,.1,0,0)).chain(out)),
"[c2 c3]*8".m
"[c2 c3]*8"
.tone(synth({
...osc('sawtooth'),
...adsr(0,.1,0.4,0)
}).chain(lowpass(300), out))
).slow(4)`,
height: 300,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `tone(instrument)`), /*#__PURE__*/ _react1.mdx("p", null, `To change the instrument of a pattern, you can pass any `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://tonejs.github.io/docs/14.7.77/index.html"
}, `Tone.js Source`), ` to .tone:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(new FMSynth().toDestination())`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `While this works, it is a little bit verbose. To simplify things, all Tone Synths have a shortcut:`), /*#__PURE__*/ _react1.mdx("pre", null, /*#__PURE__*/ _react1.mdx("code", {
@@ -7623,15 +7619,15 @@ const polysynth = (options) => new PolySynth(options);
const sampler = (options) => new Sampler(options);
const synth = (options) => new Synth(options);
`)), /*#__PURE__*/ _react1.mdx("h3", null, `out`), /*#__PURE__*/ _react1.mdx("p", null, `Shortcut for Tone.Destination. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(membrane().chain(out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `This alone is not really useful, so read on..`), /*#__PURE__*/ _react1.mdx("h3", null, `vol(volume)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Gain Node with the given volume. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(noise().chain(vol(0.5), out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `osc(type)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the waveform of a synth, monosynth or polysynth:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth4')).chain(out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The base types are `, /*#__PURE__*/ _react1.mdx("inlineCode", {
@@ -7643,72 +7639,71 @@ const synth = (options) => new Synth(options);
}, `sawtooth`), `, `, /*#__PURE__*/ _react1.mdx("inlineCode", {
parentName: "p"
}, `triangle`), `. You can also append a number between 1 and 32 to reduce the harmonic partials.`), /*#__PURE__*/ _react1.mdx("h3", null, `lowpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type lowpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth')).chain(lowpass(800), out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `highpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type highpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth')).chain(highpass(2000), out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the envelope of a Tone.js instrument. Intended to be used with Tone's .set:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4)
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(adsr(0,.1,0,0)).chain(out))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `Experimental: Patternification`), /*#__PURE__*/ _react1.mdx("p", null, `While the above methods work for static sounds, there is also the option to patternify tone methods.
This is currently experimental, because the performance is not stable, and audio glitches will appear after some time.
It would be great to get this to work without glitches though, because it is fun!`), /*#__PURE__*/ _react1.mdx("h4", null, `synth(type)`), /*#__PURE__*/ _react1.mdx("p", null, `With .synth, you can create a synth with a variable wave type:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.
synth('<sawtooth8 square8>'.m).slow(4)`,
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
.synth("<sawtooth8 square8>").slow(4)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Chainable Envelope helper:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".m.slow(4).
synth('sawtooth16').adsr(0,.1,0,0)`,
tune: `"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".slow(4)
.synth('sawtooth16').adsr(0,.1,0,0)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Due to having more than one argument, this method is not patternified.`), /*#__PURE__*/ _react1.mdx("h4", null, `filter(cuttoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified filter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.
synth('sawtooth16').filter('[500 2000]*8'.m).slow(4)`,
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
.synth('sawtooth16').filter("[500 2000]*8").slow(4)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `gain(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified gain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.
synth('sawtooth16').gain('[.2 .8]*8'.m).slow(4)`,
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
.synth('sawtooth16').gain("[.2 .8]*8").slow(4)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `autofilter(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified autofilter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.
synth('sawtooth16').autofilter('<1 4 8>'.m)`,
tune: `"c2 c3"
.synth('sawtooth16').autofilter("<1 4 8>"")`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h2", null, `Tonal API`), /*#__PURE__*/ _react1.mdx("p", null, `The Tonal API, uses `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://github.com/tonaljs/tonal"
}, `tonaljs`), ` to provide helpers for musical operations.`), /*#__PURE__*/ _react1.mdx("h3", null, `transpose(semitones)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes all notes to the given number of semitones:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<0 -2 5 3>'.m.slow(2)).transpose(0)`,
tune: `"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `This method gets really exciting when we use it with a pattern as above.`), /*#__PURE__*/ _react1.mdx("p", null, `Instead of numbers, scientific interval notation can be used as well:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<1P -2M 4P 3m>'.m.slow(2)).transpose(1)`,
tune: `"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(1)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `scale(name)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"0 2 4 6 4 2".m
tune: `"0 2 4 6 4 2"
.scale(slowcat('C2 major', 'C2 minor').slow(2))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.`), /*#__PURE__*/ _react1.mdx("p", null, `All the available scale names can be found `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts"
}, `here`), `.`), /*#__PURE__*/ _react1.mdx("h3", null, `scaleTranspose(steps)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes notes inside the scale by the number of steps:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"-8 [2,4,6]".m
tune: `"-8 [2,4,6]"
.scale('C4 bebop major')
.scaleTranspose('<0 -1 -2 -3 -4 -5 -6 -4>'.m)`,
.scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `voicings(range?)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into voicings, using the smoothest voice leading possible:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `stack("<C^7 A7 Dm7 G7>".m.voicings(), '<C3 A2 D3 G2>'.m)`,
tune: `stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use voicing collection as first param + patternify.`), /*#__PURE__*/ _react1.mdx("h3", null, `rootNotes(octave = 2)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into root notes of chords in given octave.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.rootNotes(3)`,
tune: `"<C^7 A7b13 Dm7 G7>".rootNotes(3)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Together with edit, groove and voicings, this can be used to create a basic backing track:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.edit(
x => x.voicings(['d3','g4']).groove('~ x'.m),
tune: `"<C^7 A7b13 Dm7 G7>".edit(
x => x.voicings(['d3','g4']).groove("~ x"),
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out))
)`,
height: 150,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use range instead of octave.
TODO: find out why composition does not work`), /*#__PURE__*/ _react1.mdx("h2", null, `MIDI API`), /*#__PURE__*/ _react1.mdx("p", null, `Strudel also supports midi via `, /*#__PURE__*/ _react1.mdx("a", {
@@ -7963,44 +7958,97 @@ const defaultSynth = new _tone.PolySynth().chain(new _tone.Gain(0.5), _tone.Dest
release: 0.01
}
});
function MiniRepl({ tune , height =100 }) {
const { code , setCode , activateCode , activeCode , setPattern , error , cycle , dirty , log , togglePlay } = _useReplDefault.default({
function MiniRepl({ tune , maxHeight =500 }) {
const [editor, setEditor] = _react.useState();
const { code , setCode , activateCode , activeCode , setPattern , error , cycle , dirty , log , togglePlay , hash } = _useReplDefault.default({
tune,
defaultSynth,
autolink: false
autolink: false,
onEvent: _react.useCallback(_codeMirror.markEvent(editor), [
editor
])
});
const lines = code.split('\n').length;
const height = Math.min(lines * 30 + 30, maxHeight);
return(/*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "flex space-y-0 overflow-auto",
style: {
height
},
className: "rounded-md overflow-hidden",
children: [
/*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "w-16 flex flex-col",
className: "flex justify-between bg-slate-700 border-t border-slate-500",
children: [
/*#__PURE__*/ _jsxRuntime.jsx("button", {
className: "grow bg-slate-700 border-b border-slate-500 text-white hover:bg-slate-600 ",
onClick: ()=>togglePlay()
,
children: cycle.started ? 'pause' : 'play'
/*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "flex",
children: [
/*#__PURE__*/ _jsxRuntime.jsx("button", {
className: _cxDefault.default('w-16 flex items-center justify-center p-1 bg-slate-700 border-r border-slate-500 text-white hover:bg-slate-600', cycle.started ? 'animate-pulse' : ''),
onClick: ()=>togglePlay()
,
children: !cycle.started ? /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("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"
})
}) : /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("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"
})
})
}),
/*#__PURE__*/ _jsxRuntime.jsx("button", {
className: _cxDefault.default('w-16 flex items-center justify-center p-1 border-slate-500 hover:bg-slate-600', dirty ? 'bg-slate-700 border-r border-slate-500 text-white' : 'bg-slate-600 text-slate-400 cursor-not-allowed'),
onClick: ()=>activateCode()
,
children: /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("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"
})
})
})
]
}),
/*#__PURE__*/ _jsxRuntime.jsx("button", {
className: _cxDefault.default('grow border-slate-500 hover:bg-slate-600', activeCode && dirty ? 'bg-slate-700 text-white' : 'bg-slate-600 text-slate-400 cursor-not-allowed'),
onClick: ()=>activateCode()
,
children: "update"
})
/*#__PURE__*/ _jsxRuntime.jsx("div", {
className: "text-right p-1 text-sm",
children: error && /*#__PURE__*/ _jsxRuntime.jsx("span", {
className: "text-red-200",
children: error.message
})
}),
' '
]
}),
/*#__PURE__*/ _jsxRuntime.jsx(_codeMirrorDefault.default, {
className: "w-full",
value: code,
options: {
mode: 'javascript',
theme: 'material',
lineNumbers: true
/*#__PURE__*/ _jsxRuntime.jsx("div", {
className: "flex space-y-0 overflow-auto",
style: {
height
},
onChange: (_, __, value)=>setCode(value)
children: /*#__PURE__*/ _jsxRuntime.jsx(_codeMirrorDefault.default, {
className: "w-full",
value: code,
editorDidMount: setEditor,
options: {
mode: 'javascript',
theme: 'material',
lineNumbers: true
},
onChange: (_, __, value)=>setCode(value)
})
})
]
}));
@@ -41626,8 +41674,11 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
const [activeCode, setActiveCode] = _react.useState();
const [log1, setLog] = _react.useState('');
const [error, setError] = _react.useState();
const [hash, setHash] = _react.useState('');
const [pattern, setPattern] = _react.useState();
const dirty = code !== activeCode;
const dirty = code !== activeCode || error;
const generateHash = ()=>encodeURIComponent(btoa(code))
;
const activateCode = (_code = code)=>{
!cycle1.started && cycle1.start();
broadcast({
@@ -41643,6 +41694,7 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
setPattern(()=>parsed.pattern
);
if (autolink) window.location.hash = '#' + encodeURIComponent(btoa(code));
setHash(generateHash());
setError(undefined);
setActiveCode(_code);
} catch (err) {
@@ -41749,7 +41801,8 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
togglePlay,
activateCode,
activeCode,
pushLog
pushLog,
hash
};
}
exports.default = useRepl;
@@ -41800,14 +41853,19 @@ const evaluate = (code)=>{
// console.log('shapeshifted', shapeshifted);
let evaluated = eval(shapeshifted);
if (typeof evaluated === 'function') evaluated = evaluated();
const pattern = _parse.minify(evaluated); // eval and minify (if user entered a string)
if (pattern?.constructor?.name !== 'Pattern') {
const message = `got "${typeof pattern}" instead of pattern`;
throw new Error(message + (typeof pattern === 'function' ? ', did you forget to call a function?' : '.'));
if (typeof evaluated === 'string') evaluated = _strudelMjs.withLocationOffset(_parse.minify(evaluated), {
start: {
line: 1,
column: -1
}
});
if (evaluated?.constructor?.name !== 'Pattern') {
const message = `got "${typeof evaluated}" instead of pattern`;
throw new Error(message + (typeof evaluated === 'function' ? ', did you forget to call a function?' : '.'));
}
return {
mode: 'javascript',
pattern: pattern
pattern: evaluated
};
};
@@ -41816,6 +41874,32 @@ var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "curry", ()=>curry
);
parcelHelpers.export(exports, "signal", ()=>signal
);
parcelHelpers.export(exports, "sine2", ()=>sine2
);
parcelHelpers.export(exports, "sine", ()=>sine
);
parcelHelpers.export(exports, "cosine2", ()=>cosine2
);
parcelHelpers.export(exports, "cosine", ()=>cosine
);
parcelHelpers.export(exports, "saw", ()=>saw
);
parcelHelpers.export(exports, "saw2", ()=>saw2
);
parcelHelpers.export(exports, "isaw", ()=>isaw
);
parcelHelpers.export(exports, "isaw2", ()=>isaw2
);
parcelHelpers.export(exports, "tri2", ()=>tri2
);
parcelHelpers.export(exports, "tri", ()=>tri
);
parcelHelpers.export(exports, "square", ()=>square
);
parcelHelpers.export(exports, "square2", ()=>square2
);
// adds Pattern.prototype.composable to given function as child functions
// then you can do transpose(2).late(0.2) instead of x => x.transpose(2).late(0.2)
parcelHelpers.export(exports, "makeComposable", ()=>makeComposable
@@ -42010,7 +42094,7 @@ class TimeSpan {
const result = this.intersection(other);
return result;
}
get midpoint() {
midpoint() {
return this.begin.add(this.end.sub(this.begin).div(_fractionJsDefault.default(2)));
}
equals(other) {
@@ -42461,6 +42545,9 @@ class Pattern {
return stack(...funcs.map((func)=>func(this)
));
}
pipe(func) {
return func(this);
}
_bypass(on) {
on = Boolean(parseInt(on));
return on ? silence : this;
@@ -42508,6 +42595,35 @@ function steady(value) {
return new Pattern((span)=>Hap(undefined, span, value)
);
}
const signal = (func)=>{
const query = (span)=>[
new Hap(undefined, span, func(span.midpoint()))
]
;
return new Pattern(query);
};
const _toBipolar = (pat)=>pat.fmap((x)=>x * 2 - 1
)
;
const _fromBipolar = (pat)=>pat.fmap((x)=>(x + 1) / 2
)
;
const sine2 = signal((t)=>Math.sin(Math.PI * 2 * t)
);
const sine = _fromBipolar(sine2);
const cosine2 = sine2._early(0.25);
const cosine = sine._early(0.25);
const saw = signal((t)=>t % 1
);
const saw2 = _toBipolar(saw);
const isaw = signal((t)=>1 - t % 1
);
const isaw2 = _toBipolar(isaw);
const tri2 = fastcat(isaw2, saw2);
const tri = fastcat(isaw, saw);
const square = signal((t)=>Math.floor(t * 2 % 2)
);
const square2 = _toBipolar(square);
function reify(thing) {
// Tunrs something into a pattern, unless it's already a pattern
if (thing?.constructor?.name == "Pattern") return thing;
@@ -62614,17 +62730,40 @@ const addLocations = true;
const addMiniLocations = true;
exports.default = (code)=>{
const ast = _indexJs.parseScriptWithLocation(code);
const nodesWithLocation = [];
const artificialNodes = [];
const parents = [];
const shifted = replace(ast.tree, {
enter (node, parent) {
parents.push(parent);
const isSynthetic = parents.some((p)=>nodesWithLocation.includes(p)
const isSynthetic = parents.some((p)=>artificialNodes.includes(p)
);
if (isSynthetic) return node;
const grandparent = parents[parents.length - 2];
const isTimeCat = parent?.type === 'ArrayExpression' && isPatternFactory(grandparent);
const isMarkable = isPatternFactory(parent) || isTimeCat;
// replace template string `xxx` with 'xxx'.m
if (isBackTickString(node)) {
const minified = getMinified(node.elements[0].rawValue);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// allows to use top level strings, which are normally directives... but we don't need directives
if (node.type === 'Script' && node.directives.length === 1 && !node.statements.length) {
const minified = getMinified(node.directives[0].rawValue);
const wrapped = wrapLocationOffset(minified, node.directives[0], ast.locations, artificialNodes);
return new _shiftAst.Script({
directives: [],
statements: [
wrapped
]
});
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// operator overloading => still not done
const operators = {
'*': 'fast',
@@ -62638,22 +62777,25 @@ exports.default = (code)=>{
'IdentifierExpression'
].includes(node.right?.type) && canBeOverloaded(node.left)) {
let arg = node.left;
if (node.left.type === 'IdentifierExpression') arg = wrapReify(node.left);
if (node.left.type === 'IdentifierExpression') arg = wrapFunction('reify', node.left);
return new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({
property: operators[node.operator],
object: wrapReify(arg)
object: wrapFunction('reify', arg)
}),
arguments: [
node.right
]
});
}
const isMarkable = isPatternArg(parents) || hasModifierCall(parent);
// add to location to pure(x) calls
if (node.type === 'CallExpression' && node.callee.name === 'pure') return reifyWithLocation(node.arguments[0].name, node.arguments[0], ast.locations, artificialNodes);
// replace pseudo note variables
if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
if (addLocations && isMarkable) return reifyWithLocation(value, node, ast.locations, nodesWithLocation);
if (addLocations && isMarkable) return reifyWithLocation(value, node, ast.locations, artificialNodes);
return new _shiftAst.LiteralStringExpression({
value
});
@@ -62663,8 +62805,8 @@ exports.default = (code)=>{
});
}
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node);
return reifyWithLocation(node.value, node, ast.locations, nodesWithLocation);
if (!addMiniLocations) return node;
return reifyWithLocation(node.value, node, ast.locations, artificialNodes);
if (!addMiniLocations) return wrapFunction('reify', node);
// mini notation location handling
const miniFunctions = [
'mini',
@@ -62678,10 +62820,10 @@ exports.default = (code)=>{
console.warn('multi arg mini locations not supported yet...');
return node;
}
return wrapLocationOffset(node, node.arguments, ast.locations, nodesWithLocation);
return wrapLocationOffset(node, node.arguments, ast.locations, artificialNodes);
}
if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) // 'c3'.mini or 'c3'.m
return wrapLocationOffset(node, node.object, ast.locations, nodesWithLocation);
return wrapLocationOffset(node, node.object, ast.locations, artificialNodes);
return node;
},
leave () {
@@ -62690,16 +62832,46 @@ exports.default = (code)=>{
});
return _shiftCodegenDefault.default(shifted);
};
function wrapReify(node) {
function wrapFunction(name, ...args) {
return new _shiftAst.CallExpression({
callee: new _shiftAst.IdentifierExpression({
name: 'reify'
name
}),
arguments: [
node
]
arguments: args
});
}
function getMinified(value) {
return new _shiftAst.StaticMemberExpression({
object: new _shiftAst.LiteralStringExpression({
value
}),
property: 'm'
});
}
function isBackTickString(node) {
return node.type === 'TemplateExpression' && node.elements.length === 1;
}
function isStringWithDoubleQuotes(node, locations, code) {
if (node.type !== 'LiteralStringExpression') return false;
const loc = locations.get(node);
const snippet = code.slice(loc.start.offset, loc.end.offset);
return snippet[0] === '"'; // we can trust the end is also ", as the parsing did not fail
}
// returns true if the given parents belong to a pattern argument node
// this is used to check if a node should receive a location for highlighting
function isPatternArg(parents) {
if (!parents.length) return false;
const ancestors = parents.slice(0, -1);
const parent = parents[parents.length - 1];
if (isPatternFactory(parent)) return true;
if (parent?.type === 'ArrayExpression') return isPatternArg(ancestors);
return false;
}
function hasModifierCall(parent) {
// TODO: modifiers are more than composables, for example every is not composable but should be seen as modifier..
// need all prototypes of Pattern
return parent?.type === 'StaticMemberExpression' && Object.keys(Pattern.prototype.composable).includes(parent.property);
}
function isPatternFactory(node) {
return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name);
}
@@ -62708,7 +62880,7 @@ function canBeOverloaded(node) {
// TODO: support sequence(c3).transpose(3).x.y.z
}
// turn node into withLocationOffset(node, location)
function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
function wrapLocationOffset(node, stringNode, locations, artificialNodes) {
// console.log('wrapppp', stringNode);
const expression = {
type: 'CallExpression',
@@ -62721,33 +62893,25 @@ function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
getLocationObject(stringNode, locations)
]
};
nodesWithLocation.push(expression);
artificialNodes.push(expression);
// console.log('wrapped', codegen(expression));
return expression;
}
// turns node in reify(value).withLocation(location), where location is the node's location in the source code
// with this, the reified pattern can pass its location to the event, to know where to highlight when it's active
function reifyWithLocation(value, node, locations, nodesWithLocation) {
// console.log('reifyWithLocation', value, node);
function reifyWithLocation(value, node, locations, artificialNodes) {
const withLocation = new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({
object: new _shiftAst.CallExpression({
callee: new _shiftAst.IdentifierExpression({
name: 'reify'
}),
arguments: [
new _shiftAst.LiteralStringExpression({
value
})
]
}),
object: wrapFunction('reify', new _shiftAst.LiteralStringExpression({
value
})),
property: 'withLocation'
}),
arguments: [
getLocationObject(node, locations)
]
});
nodesWithLocation.push(withLocation);
artificialNodes.push(withLocation);
return withLocation;
}
// returns ast for source location object
@@ -98032,20 +98196,24 @@ exports.default = usePostMessage;
},{"react":"21dqq","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"f5BgG":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "markEvent", ()=>markEvent
);
var _jsxRuntime = require("react/jsx-runtime");
var _react = require("react");
var _reactDefault = parcelHelpers.interopDefault(_react);
var _reactCodemirror2 = require("react-codemirror2");
var _javascriptJs = require("codemirror/mode/javascript/javascript.js");
var _pegjsJs = require("codemirror/mode/pegjs/pegjs.js");
var _materialCss = require("codemirror/theme/material.css");
// import 'codemirror/theme/material.css';
var _codemirrorCss = require("codemirror/lib/codemirror.css");
var _materialCss = require("codemirror/theme/material.css");
function CodeMirror({ value , onChange , options , editorDidMount }) {
options = options || {
mode: 'javascript',
theme: 'material',
lineNumbers: true,
styleSelectedText: true
styleSelectedText: true,
cursorBlinkRate: 500
};
return(/*#__PURE__*/ _jsxRuntime.jsx(_reactCodemirror2.Controlled, {
value: value,
@@ -98055,8 +98223,30 @@ function CodeMirror({ value , onChange , options , editorDidMount }) {
}));
}
exports.default = CodeMirror;
const markEvent = (editor)=>(event)=>{
const locs = event.value.locations;
if (!locs || !editor) return;
// mark active event
const marks = locs.map(({ start , end })=>editor.getDoc().markText({
line: start.line - 1,
ch: start.column
}, {
line: end.line - 1,
ch: end.column
}, {
css: 'background-color: #FFCA28; color: black'
})
);
//Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler...
setTimeout(()=>{
marks.forEach((mark)=>mark.clear()
);
// }, '+' + event.duration * 0.5);
}, event.duration * 900);
}
;
},{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/theme/material.css":"5kHRb","codemirror/lib/codemirror.css":"4uIDj","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) {
},{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/lib/codemirror.css":"4uIDj","codemirror/theme/material.css":"5kHRb","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) {
'use strict';
var global = arguments[3];
function _extends() {
@@ -109263,7 +109453,7 @@ exports.UnControlled = UnControlled;
}, "javascript");
});
},{"../../lib/codemirror":"2Peje","../javascript/javascript":"6YWC8"}],"5kHRb":[function() {},{}],"4uIDj":[function() {},{}],"aTay5":[function(require,module,exports) {
},{"../../lib/codemirror":"2Peje","../javascript/javascript":"6YWC8"}],"4uIDj":[function() {},{}],"5kHRb":[function() {},{}],"aTay5":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
function cx(...classes) {
@@ -109273,4 +109463,4 @@ exports.default = cx;
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
//# sourceMappingURL=index.a96519ca.js.map
//# sourceMappingURL=index.fbb1ad94.js.map
File diff suppressed because one or more lines are too long
@@ -695,12 +695,16 @@ Ensure the default browser behavior of the `hidden` attribute.
display: block;
}.flex {
display: flex;
}.inline-flex {
display: inline-flex;
}.contents {
display: contents;
}.h-16 {
height: 4rem;
}.h-full {
height: 100%;
}.h-5 {
height: 1.25rem;
}.min-h-screen {
min-height: 100vh;
}.min-h-\[200px\] {
@@ -709,6 +713,8 @@ Ensure the default browser behavior of the `hidden` attribute.
width: 100%;
}.w-16 {
width: 4rem;
}.w-5 {
width: 1.25rem;
}.max-w-3xl {
max-width: 48rem;
}.flex-none {
@@ -717,6 +723,19 @@ Ensure the default browser behavior of the `hidden` attribute.
flex-grow: 1;
}.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}@-webkit-keyframes pulse {
50% {
opacity: .5;
}
}@keyframes pulse {
50% {
opacity: .5;
}
}.animate-pulse {
-webkit-animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}.cursor-not-allowed {
cursor: not-allowed;
}.flex-col {
@@ -741,14 +760,22 @@ Ensure the default browser behavior of the `hidden` attribute.
margin-bottom: calc(0px * var(--tw-space-y-reverse));
}.overflow-auto {
overflow: auto;
}.overflow-hidden {
overflow: hidden;
}.whitespace-pre {
white-space: pre;
}.rounded-md {
border-radius: 0.375rem;
}.border {
border-width: 1px;
}.border-0 {
border-width: 0px;
}.border-b {
border-bottom-width: 1px;
}.border-t {
border-top-width: 1px;
}.border-r {
border-right-width: 1px;
}.border-gray-200 {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity));
@@ -777,9 +804,13 @@ Ensure the default browser behavior of the `hidden` attribute.
padding: 1rem;
}.p-2 {
padding: 0.5rem;
}.p-1 {
padding: 0.25rem;
}.px-2 {
padding-left: 0.5rem;
padding-right: 0.5rem;
}.pr-2 {
padding-right: 0.5rem;
}.text-right {
text-align: right;
}.text-2xl {
@@ -788,6 +819,9 @@ Ensure the default browser behavior of the `hidden` attribute.
}.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}.text-gray-100 {
--tw-text-opacity: 1;
color: rgb(243 244 246 / var(--tw-text-opacity));
@@ -800,6 +834,9 @@ Ensure the default browser behavior of the `hidden` attribute.
}.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}.text-red-200 {
--tw-text-opacity: 1;
color: rgb(254 202 202 / var(--tw-text-opacity));
}.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}.react-codemirror2,
@@ -822,148 +859,6 @@ Ensure the default browser behavior of the `hidden` attribute.
--tw-ring-color: rgb(30 41 59 / var(--tw-ring-opacity));
}
/*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material.CodeMirror {
background-color: #263238;
color: #EEFFFF;
}
.cm-s-material .CodeMirror-gutters {
background: #263238;
color: #546E7A;
border: none;
}
.cm-s-material .CodeMirror-guttermarker,
.cm-s-material .CodeMirror-guttermarker-subtle,
.cm-s-material .CodeMirror-linenumber {
color: #546E7A;
}
.cm-s-material .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material .cm-animate-fat-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material.CodeMirror-focused div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::selection,
.cm-s-material .CodeMirror-line>span::selection,
.cm-s-material .CodeMirror-line>span>span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::-moz-selection,
.cm-s-material .CodeMirror-line>span::-moz-selection,
.cm-s-material .CodeMirror-line>span>span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material .cm-keyword {
color: #C792EA;
}
.cm-s-material .cm-operator {
color: #89DDFF;
}
.cm-s-material .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #f07178;
}
.cm-s-material .cm-builtin {
color: #FFCB6B;
}
.cm-s-material .cm-atom {
color: #F78C6C;
}
.cm-s-material .cm-number {
color: #FF5370;
}
.cm-s-material .cm-def {
color: #82AAFF;
}
.cm-s-material .cm-string {
color: #C3E88D;
}
.cm-s-material .cm-string-2 {
color: #f07178;
}
.cm-s-material .cm-comment {
color: #546E7A;
}
.cm-s-material .cm-variable {
color: #f07178;
}
.cm-s-material .cm-tag {
color: #FF5370;
}
.cm-s-material .cm-meta {
color: #FFCB6B;
}
.cm-s-material .cm-attribute {
color: #C792EA;
}
.cm-s-material .cm-property {
color: #C792EA;
}
.cm-s-material .cm-qualifier {
color: #DECB6B;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #DECB6B;
}
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #FF5370;
}
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
/* BASICS */
.CodeMirror {
@@ -1309,4 +1204,146 @@ div.CodeMirror-dragcursors {
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
/*# sourceMappingURL=index.1e09ac22.css.map */
/*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material.CodeMirror {
background-color: #263238;
color: #EEFFFF;
}
.cm-s-material .CodeMirror-gutters {
background: #263238;
color: #546E7A;
border: none;
}
.cm-s-material .CodeMirror-guttermarker,
.cm-s-material .CodeMirror-guttermarker-subtle,
.cm-s-material .CodeMirror-linenumber {
color: #546E7A;
}
.cm-s-material .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material .cm-animate-fat-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material.CodeMirror-focused div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::selection,
.cm-s-material .CodeMirror-line>span::selection,
.cm-s-material .CodeMirror-line>span>span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::-moz-selection,
.cm-s-material .CodeMirror-line>span::-moz-selection,
.cm-s-material .CodeMirror-line>span>span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material .cm-keyword {
color: #C792EA;
}
.cm-s-material .cm-operator {
color: #89DDFF;
}
.cm-s-material .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #f07178;
}
.cm-s-material .cm-builtin {
color: #FFCB6B;
}
.cm-s-material .cm-atom {
color: #F78C6C;
}
.cm-s-material .cm-number {
color: #FF5370;
}
.cm-s-material .cm-def {
color: #82AAFF;
}
.cm-s-material .cm-string {
color: #C3E88D;
}
.cm-s-material .cm-string-2 {
color: #f07178;
}
.cm-s-material .cm-comment {
color: #546E7A;
}
.cm-s-material .cm-variable {
color: #f07178;
}
.cm-s-material .cm-tag {
color: #FF5370;
}
.cm-s-material .cm-meta {
color: #FFCB6B;
}
.cm-s-material .cm-attribute {
color: #C792EA;
}
.cm-s-material .cm-property {
color: #C792EA;
}
.cm-s-material .cm-qualifier {
color: #DECB6B;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #DECB6B;
}
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #FF5370;
}
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
/*# sourceMappingURL=index.fd7d9b66.css.map */
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico">
<link rel="stylesheet" type="text/css" href="/tutorial/index.1e09ac22.css">
<link rel="stylesheet" type="text/css" href="/tutorial/index.fd7d9b66.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Strudel REPL">
<title>Strudel Tutorial</title>
@@ -11,6 +11,6 @@
<body>
<div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/tutorial/index.a96519ca.js" defer=""></script>
<script src="/tutorial/index.fbb1ad94.js" defer=""></script>
</body>
</html>