UNPKG

wam-community

Version:

A collection of prebuilt Web Audio Modules ready for use

1,271 lines (1,208 loc) 126 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/FunctionKernel.ts": /*!*******************************!*\ !*** ./src/FunctionKernel.ts ***! \*******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ FunctionKernel: () => (/* binding */ FunctionKernel) /* harmony export */ }); /* harmony import */ var _FunctionSequencer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FunctionSequencer */ "./src/FunctionSequencer.ts"); /* harmony import */ var _RemoteUI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./RemoteUI */ "./src/RemoteUI.ts"); /* harmony import */ var _RemoteUIController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./RemoteUIController */ "./src/RemoteUIController.ts"); /* harmony import */ var tonal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tonal */ "./node_modules/tonal/dist/index.mjs"); class FunctionKernel { constructor(processor) { this.remoteUI = new _RemoteUI__WEBPACK_IMPORTED_MODULE_1__.RemoteUI(this); this.api = new _FunctionSequencer__WEBPACK_IMPORTED_MODULE_0__.FunctionAPI(this.remoteUI, this); this.transport = { tempo: 120, timeSigDenominator: 4, timeSigNumerator: 4, playing: false, currentBar: 0, currentBarStarted: 0 }; this.registerParametersCalled = false; this.parameterIds = []; this.processor = processor; this.additionalState = {}; this.additionalStateDirty = false; this.cachedSetState = []; this.uiController = new _RemoteUIController__WEBPACK_IMPORTED_MODULE_2__.RemoteUIController(this, processor.port); } onTick(ticks) { if (!this.function) { return; } try { if (this.function.onTick) { this.function.onTick(ticks); } this.flush(); } catch (e) { this.processor.port.postMessage({ source: "functionSeq", action: "error", error: e.toString(), stack: e.stack }); this.function = undefined; } } /** * Messages from main thread appear here. * @param {MessageEvent} message */ async onMessage(message) { if (message.data && message.data.action == "function") { try { this.uiController.register(undefined); this.registerParametersCalled = false; this.function = new Function('api', 'ui', 'tonal', message.data.code)(this.api, this.remoteUI, tonal__WEBPACK_IMPORTED_MODULE_3__); if (!!this.function.init) { this.function.init(); } if (this.noteList && this.function.onCustomNoteList) { this.function.onCustomNoteList(this.noteList); } if (!this.registerParametersCalled) { // may have to not clear the cached set state or something like that. not sure. this.registerParameters([]); } } catch (e) { this.error(e); } this.flush(); } else if (message.data && message.data.action == "noteList") { this.noteList = message.data.noteList; if (this.function && this.function.onCustomNoteList) { this.function.onCustomNoteList(message.data.noteList); } this.flush(); } else if (message.data && message.data.action == "additionalState") { this.additionalState = message.data.state; this.onStateChange(); } else { // @ts-ignore super._onMessage(message); } } onTransport(transportData) { try { if (this.transport && this.function) { if (this.transport.playing && !transportData.playing) { if (this.function.onTransportStop) { this.function.onTransportStop(transportData); } } else if (!this.transport.playing && transportData.playing) { if (this.function.onTransportStart) { this.function.onTransportStart(transportData); } } this.flush(); this.transport = transportData; } } catch (e) { this.error(e); } } onMidi(event) { if (this.function && this.function.onMidi) { try { this.function.onMidi(event.bytes); this.flush(); } catch (e) { this.error(e); } } } onAction(name) { if (this.function && this.function.onAction) { try { this.function.onAction(name); this.flush(); } catch (e) { this.error(e); } } } onStateChange() { if (this.function && this.function.onStateChange) { try { this.function.onStateChange({ ...this.additionalState }); this.flush(); } catch (e) { this.error(e); } } } registerParameters(parameters) { let map = {}; this.parameterIds = []; for (let p of parameters) { this.validateParameter(p); map[p.id] = p.config; this.parameterIds.push(p.id); } this.processor.port.postMessage({ source: "functionSeq", action: "newParams", params: parameters }); this.processor.updateParameters(map); for (let state of this.cachedSetState) { this.processor._setParameterValues(state, false); } this.cachedSetState = []; this.registerParametersCalled = true; } validateParameter(p) { if (p.id === undefined || p.config === undefined) { throw new Error(`Invalid parameter ${p}: must have id and config defined`); } if (p.id.length == 0) { throw new Error("Invalid parameter: id must be string and not blank"); } if (['float', 'int', 'boolean', 'choice'].findIndex(t => t == p.config.type) == -1) { throw new Error(`Invalid parameter type ${p.config.type}`); } const VALID_CONFIG_KEYS = ["label", "type", "defaultValue", "minValue", "maxValue", "discreteStep", "exponent", "choices", "units"]; for (let key of Object.keys(p.config)) { if (VALID_CONFIG_KEYS.indexOf(key) == -1) { throw new Error(`Param ${p.id}: Invalid configuration key ${key}. Valid configuration keys are ${VALID_CONFIG_KEYS.join(",")}`); } } } setAdditionalState(name, value) { this.additionalState[name] = value; this.additionalStateDirty = true; } getAdditionalState(name) { return this.additionalState[name]; } error(e) { this.processor.port.postMessage({ source: "functionSeq", action: "error", error: e.toString(), stack: e.stack }); this.function = undefined; } flush() { this.uiController.flush(); if (this.additionalStateDirty) { this.additionalStateDirty = false; this.processor.port.postMessage({ source: "functionSeq", action: "additionalState", state: this.additionalState }); this.onStateChange(); } } } /***/ }), /***/ "./src/FunctionSeqProcessor.ts": /*!*************************************!*\ !*** ./src/FunctionSeqProcessor.ts ***! \*************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ FunctionSequencerProcessor: () => (/* binding */ FunctionSequencerProcessor), /* harmony export */ MIDI: () => (/* binding */ MIDI) /* harmony export */ }); /* harmony import */ var _FunctionKernel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FunctionKernel */ "./src/FunctionKernel.ts"); const moduleId = "com.sequencerParty.functionSeq"; const audioWorkletGlobalScope = globalThis; const PPQN = 96; class MIDI { } MIDI.NOTE_ON = 0x90; MIDI.NOTE_OFF = 0x80; MIDI.CC = 0xB0; const { registerProcessor } = audioWorkletGlobalScope; const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId); const { WamProcessor, } = ModuleScope; const DynamicParameterProcessor = ModuleScope.DynamicParameterProcessor; class FunctionSequencerProcessor extends DynamicParameterProcessor { constructor(options) { super(options); this.count = 0; this.function = new _FunctionKernel__WEBPACK_IMPORTED_MODULE_0__.FunctionKernel(this); } /** * Implement custom DSP here. * @param {number} startSample beginning of processing slice * @param {number} endSample end of processing slice * @param {Float32Array[][]} inputs * @param {Float32Array[][]} outputs */ _process(startSample, endSample, inputs, outputs) { const { currentTime } = audioWorkletGlobalScope; if (!this.transportData) { return; } if (this.transportData.playing && currentTime >= this.transportData.currentBarStarted) { var timeElapsed = currentTime - this.transportData.currentBarStarted; var beatPosition = (this.transportData.currentBar * this.transportData.timeSigNumerator) + ((this.transportData.tempo / 60.0) * timeElapsed); var tickPosition = Math.floor(beatPosition * PPQN); if (this.ticks != tickPosition) { this.ticks = tickPosition; this.function.onTick(this.ticks); } } return; } /** * Messages from main thread appear here. * @param {MessageEvent} message */ async _onMessage(message) { var _a, _b, _c; if (message.data && message.data.source == "function") { this.function.onMessage(message); } else if (message.data && message.data.source == "remoteUI") { this.function.uiController.onMessage(message); } else { if (message.data && message.data.request == "set/state") { if (!this.function.registerParametersCalled && ((_c = (_b = (_a = message.data) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.parameterValues)) { // we queue up any setState calls until the script registers parameters, and then we send them out. // otherwise we drop initial state values saved in the script this.function.cachedSetState.push(message.data.content.state.parameterValues); } } // @ts-ignore super._onMessage(message); } } _onTransport(transportData) { this.transportData = transportData; this.function.onTransport(transportData); } _onMidi(midiData) { this.function.onMidi(midiData); } } try { registerProcessor('com.sequencerParty.functionSeq', FunctionSequencerProcessor); } catch (error) { // eslint-disable-next-line no-console console.warn(error); } /***/ }), /***/ "./src/FunctionSequencer.ts": /*!**********************************!*\ !*** ./src/FunctionSequencer.ts ***! \**********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ FunctionAPI: () => (/* binding */ FunctionAPI) /* harmony export */ }); /* harmony import */ var _FunctionSeqProcessor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FunctionSeqProcessor */ "./src/FunctionSeqProcessor.ts"); var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _FunctionAPI_ui, _FunctionAPI_kernel; const PPQN = 96; const audioWorkletGlobalScope = globalThis; class FunctionAPI { constructor(ui, kernel) { _FunctionAPI_ui.set(this, void 0); _FunctionAPI_kernel.set(this, void 0); __classPrivateFieldSet(this, _FunctionAPI_ui, ui, "f"); __classPrivateFieldSet(this, _FunctionAPI_kernel, kernel, "f"); } /** * emits a MIDI Note on message followed by a MIDI Note off message delayed by the duration * @param channel {number} the MIDI channel minus one, from 0-15. So to emit on channel 1, send a 0. * @param note {number} the MIDI note number, from 0-127 * @param velocity {number} MIDI note on velocity, from 0-127 * @param duration {number} the midi note duration, in seconds. * @param startTime {number} optionally set the starting time of the note, in relation to api.getCurrentTime() * */ emitNote(channel, note, velocity, duration, startTime) { if (startTime === undefined) { startTime = audioWorkletGlobalScope.currentTime; } if (!(Number.isInteger(channel) && channel >= 0 && channel <= 15)) { throw new Error(`emitNote: channel value ${channel} invalid. Must be integer value from 0-15 (ch#1-#16)`); } this.emitMidiEvent([_FunctionSeqProcessor__WEBPACK_IMPORTED_MODULE_0__.MIDI.NOTE_ON | channel, note, velocity], startTime); this.emitMidiEvent([_FunctionSeqProcessor__WEBPACK_IMPORTED_MODULE_0__.MIDI.NOTE_OFF | channel, note, velocity], startTime + duration); } /** * Emit a regular, non-sysex MIDI message up to 3 bytes in length. * @param bytes {number[]} a 1 to 3 array of bytes, the raw MIDI message. * @param eventTime {number} the time to emit the event, relative to api.getCurrentTime() * */ emitMidiEvent(bytes, eventTime) { if (bytes.length > 3) { throw new Error("emitMidiEvent can only emit regular MIDI messages - use emitSysex to emit sysex messages."); } for (let i = 0; i < bytes.length; i++) { if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) { throw new Error(`MIDI event byte at index ${i} is not an integer between 0-255, is ${bytes[i]}`); } } __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").processor.emitEvents({ type: 'wam-midi', time: eventTime, data: { bytes } }); } /** * returns the current time * @returns {number} the current audioContext time, in seconds */ getCurrentTime() { return audioWorkletGlobalScope.currentTime; } /** * returns the duration, in seconds, for the input number of ticks * @param ticks {number} the number of ticks to convert to seconds */ getTickDuration(ticks) { return ticks * 1.0 / ((__classPrivateFieldGet(this, _FunctionAPI_kernel, "f").transport.tempo / 60.0) * PPQN); } /** * Set (or unset) a list of named MIDI notes. Used to inform earlier MIDI processors what MIDI notes are valid. * @param noteList {NoteDefinition[]} a list of midi notes this processor accepts. Set to undefined to clear the custom note list. */ setCustomNoteList(noteList) { __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").processor.port.postMessage({ source: "functionSeq", action: "noteList", noteList }); } /** * Register the complete list of plugin parameters. These parameters can be mapped to UI controls and are exposed to the host for automation. * @param parameters {ParameterDefinition[]} the list of parameters to register for the plugin. */ registerParameters(parameters) { __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").registerParameters(parameters); } /** * Register a custom UI interface. * @params root {RemoteUIElement} the top-level root UI element, usually a ui.Col or ui.Row. */ registerUI(root) { __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").uiController.register(root); } /** * Stores an additional variable into the patch. This gets sent to other collaborators and will be restored after refreshing the page. * Be warned: this is an expensive operation as the value change is sent to the server and all other users. Only use this function * to hold state that is not in a registered parameter (which are automatically synced to the server). * Calling setState() will result in your onStateChange() callback running on all plugin instances including locally. * @param name {string} the variable name * @param value {any} the value to store */ setState(name, value) { __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").setAdditionalState(name, value); } /** * Returns the stored value for a variable name that was previously stored with setState. * @param name {string} the variable name to return * @returns {any} the previously stored value, or undefined if nothing is stored. */ getState(name) { return __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").getAdditionalState(name); } /** * Returns the values for all parameters that were registered by registerParameters. * @returns {Record<string, number>} a map of parameter names to parameter values */ getParams() { let params = {}; for (let id of __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").parameterIds) { params[id] = __classPrivateFieldGet(this, _FunctionAPI_kernel, "f").processor._parameterState[id].value; } return params; } } _FunctionAPI_ui = new WeakMap(), _FunctionAPI_kernel = new WeakMap(); /***/ }), /***/ "./src/RemoteUI.ts": /*!*************************!*\ !*** ./src/RemoteUI.ts ***! \*************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ RemoteUI: () => (/* binding */ RemoteUI) /* harmony export */ }); var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _RemoteUI_kernel; class RemoteUI { constructor(kernel) { _RemoteUI_kernel.set(this, void 0); __classPrivateFieldSet(this, _RemoteUI_kernel, kernel, "f"); } Col(name, children, properties) { return { type: "col", name, children, props: properties !== null && properties !== void 0 ? properties : {} }; } Row(name, children, properties) { return { type: "row", name, children, props: properties !== null && properties !== void 0 ? properties : {} }; } Action(name, properties) { return { type: "action", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Toggle(name, properties) { return { type: "toggle", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Knob(name, properties) { return { type: "knob", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Slider(name, properties) { return { type: "slider", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Label(name, properties) { return { type: "label", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Select(name, properties) { return { type: "select", name, props: properties !== null && properties !== void 0 ? properties : {} }; } Highlight(name, value) { __classPrivateFieldGet(this, _RemoteUI_kernel, "f").uiController.highlight(name, value); } } _RemoteUI_kernel = new WeakMap(); /***/ }), /***/ "./src/RemoteUIController.ts": /*!***********************************!*\ !*** ./src/RemoteUIController.ts ***! \***********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ RemoteUIController: () => (/* binding */ RemoteUIController) /* harmony export */ }); // this class runs in the remote context, handling the client's ui perspective class RemoteUIController { constructor(kernel, port) { this.kernel = kernel; this.port = port; this.pendingUpdates = []; } register(root) { this.ui = root; this.uiMap = {}; if (this.ui) { const setMapValues = (el) => { if (this.uiMap[el.name]) { throw new Error(`UI has two elements named ${el.name}`); } this.uiMap[el.name] = {}; if (el.children) { for (let child of el.children) { setMapValues(child); } } }; setMapValues(this.ui); } this.port.postMessage({ source: "remoteUI", action: "ui", ui: root ? JSON.stringify(root) : undefined }); } highlight(name, value) { try { if (this.uiMap[name].highlighted != value) { this.uiMap[name].highlighted = value; this.pendingUpdates.push({ t: "high", f: name, v: value }); } } catch (e) { console.error(`error highlighting ${name}: ${e}`); } } flush() { const updates = this.pendingUpdates; this.pendingUpdates = []; if (updates.length > 0) { this.port.postMessage({ source: "remoteUI", action: "up", updates }); } } onMessage(message) { if (!message.data || message.data.source != "remoteUI") { return; } if (message.data.action == "action" && message.data.name) { this.kernel.onAction(message.data.name); } } } /***/ }), /***/ "./node_modules/@tonaljs/abc-notation/dist/index.mjs": /*!***********************************************************!*\ !*** ./node_modules/@tonaljs/abc-notation/dist/index.mjs ***! \***********************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ abcToScientificNotation: () => (/* binding */ abcToScientificNotation), /* harmony export */ "default": () => (/* binding */ abc_notation_default), /* harmony export */ distance: () => (/* binding */ distance), /* harmony export */ scientificToAbcNotation: () => (/* binding */ scientificToAbcNotation), /* harmony export */ tokenize: () => (/* binding */ tokenize), /* harmony export */ transpose: () => (/* binding */ transpose) /* harmony export */ }); /* harmony import */ var _tonaljs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tonaljs/core */ "./node_modules/@tonaljs/core/dist/index.mjs"); // index.ts var fillStr = (character, times) => Array(times + 1).join(character); var REGEX = /^(_{1,}|=|\^{1,}|)([abcdefgABCDEFG])([,']*)$/; function tokenize(str) { const m = REGEX.exec(str); if (!m) { return ["", "", ""]; } return [m[1], m[2], m[3]]; } function abcToScientificNotation(str) { const [acc, letter, oct] = tokenize(str); if (letter === "") { return ""; } let o = 4; for (let i = 0; i < oct.length; i++) { o += oct.charAt(i) === "," ? -1 : 1; } const a = acc[0] === "_" ? acc.replace(/_/g, "b") : acc[0] === "^" ? acc.replace(/\^/g, "#") : ""; return letter.charCodeAt(0) > 96 ? letter.toUpperCase() + a + (o + 1) : letter + a + o; } function scientificToAbcNotation(str) { const n = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.note)(str); if (n.empty || !n.oct && n.oct !== 0) { return ""; } const { letter, acc, oct } = n; const a = acc[0] === "b" ? acc.replace(/b/g, "_") : acc.replace(/#/g, "^"); const l = oct > 4 ? letter.toLowerCase() : letter; const o = oct === 5 ? "" : oct > 4 ? fillStr("'", oct - 5) : fillStr(",", 4 - oct); return a + l + o; } function transpose(note2, interval) { return scientificToAbcNotation((0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.transpose)(abcToScientificNotation(note2), interval)); } function distance(from, to) { return (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.distance)(abcToScientificNotation(from), abcToScientificNotation(to)); } var abc_notation_default = { abcToScientificNotation, scientificToAbcNotation, tokenize, transpose, distance }; //# sourceMappingURL=index.mjs.map /***/ }), /***/ "./node_modules/@tonaljs/array/dist/index.mjs": /*!****************************************************!*\ !*** ./node_modules/@tonaljs/array/dist/index.mjs ***! \****************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ compact: () => (/* binding */ compact), /* harmony export */ permutations: () => (/* binding */ permutations), /* harmony export */ range: () => (/* binding */ range), /* harmony export */ rotate: () => (/* binding */ rotate), /* harmony export */ shuffle: () => (/* binding */ shuffle), /* harmony export */ sortedNoteNames: () => (/* binding */ sortedNoteNames), /* harmony export */ sortedUniqNoteNames: () => (/* binding */ sortedUniqNoteNames) /* harmony export */ }); /* harmony import */ var _tonaljs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tonaljs/core */ "./node_modules/@tonaljs/core/dist/index.mjs"); // index.ts var isArray = Array.isArray; function ascR(b, n) { const a = []; for (; n--; a[n] = n + b) ; return a; } function descR(b, n) { const a = []; for (; n--; a[n] = b - n) ; return a; } function range(from, to) { return from < to ? ascR(from, to - from + 1) : descR(from, from - to + 1); } function rotate(times, arr) { const len = arr.length; const n = (times % len + len) % len; return arr.slice(n, len).concat(arr.slice(0, n)); } function compact(arr) { return arr.filter((n) => n === 0 || n); } function sortedNoteNames(notes) { const valid = notes.map((n) => (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.note)(n)).filter((n) => !n.empty); return valid.sort((a, b) => a.height - b.height).map((n) => n.name); } function sortedUniqNoteNames(arr) { return sortedNoteNames(arr).filter((n, i, a) => i === 0 || n !== a[i - 1]); } function shuffle(arr, rnd = Math.random) { let i; let t; let m = arr.length; while (m) { i = Math.floor(rnd() * m--); t = arr[m]; arr[m] = arr[i]; arr[i] = t; } return arr; } function permutations(arr) { if (arr.length === 0) { return [[]]; } return permutations(arr.slice(1)).reduce((acc, perm) => { return acc.concat( arr.map((e, pos) => { const newPerm = perm.slice(); newPerm.splice(pos, 0, arr[0]); return newPerm; }) ); }, []); } //# sourceMappingURL=index.mjs.map /***/ }), /***/ "./node_modules/@tonaljs/chord-detect/dist/index.mjs": /*!***********************************************************!*\ !*** ./node_modules/@tonaljs/chord-detect/dist/index.mjs ***! \***********************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ chord_detect_default), /* harmony export */ detect: () => (/* binding */ detect) /* harmony export */ }); /* harmony import */ var _tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tonaljs/chord-type */ "./node_modules/@tonaljs/chord-type/dist/index.mjs"); /* harmony import */ var _tonaljs_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tonaljs/core */ "./node_modules/@tonaljs/core/dist/index.mjs"); /* harmony import */ var _tonaljs_pcset__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @tonaljs/pcset */ "./node_modules/@tonaljs/pcset/dist/index.mjs"); // index.ts var namedSet = (notes) => { const pcToName = notes.reduce((record, n) => { const chroma = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_1__.note)(n).chroma; if (chroma !== void 0) { record[chroma] = record[chroma] || (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_1__.note)(n).name; } return record; }, {}); return (chroma) => pcToName[chroma]; }; function detect(source, options = {}) { const notes = source.map((n) => (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_1__.note)(n).pc).filter((x) => x); if (_tonaljs_core__WEBPACK_IMPORTED_MODULE_1__.note.length === 0) { return []; } const found = findMatches(notes, 1, options); return found.filter((chord) => chord.weight).sort((a, b) => b.weight - a.weight).map((chord) => chord.name); } var BITMASK = { anyThirds: 384, perfectFifth: 16, nonPerfectFifths: 40, anySeventh: 3 }; var testChromaNumber = (bitmask) => (chromaNumber) => Boolean(chromaNumber & bitmask); var hasAnyThird = testChromaNumber(BITMASK.anyThirds); var hasPerfectFifth = testChromaNumber(BITMASK.perfectFifth); var hasAnySeventh = testChromaNumber(BITMASK.anySeventh); var hasNonPerfectFifth = testChromaNumber(BITMASK.nonPerfectFifths); function hasAnyThirdAndPerfectFifthAndAnySeventh(chordType) { const chromaNumber = parseInt(chordType.chroma, 2); return hasAnyThird(chromaNumber) && hasPerfectFifth(chromaNumber) && hasAnySeventh(chromaNumber); } function withPerfectFifth(chroma) { const chromaNumber = parseInt(chroma, 2); return hasNonPerfectFifth(chromaNumber) ? chroma : (chromaNumber | 16).toString(2); } function findMatches(notes, weight, options) { const tonic = notes[0]; const tonicChroma = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_1__.note)(tonic).chroma; const noteName = namedSet(notes); const allModes = (0,_tonaljs_pcset__WEBPACK_IMPORTED_MODULE_2__.modes)(notes, false); const found = []; allModes.forEach((mode, index) => { const modeWithPerfectFifth = options.assumePerfectFifth && withPerfectFifth(mode); const chordTypes = (0,_tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_0__.all)().filter((chordType) => { if (options.assumePerfectFifth && hasAnyThirdAndPerfectFifthAndAnySeventh(chordType)) { return chordType.chroma === modeWithPerfectFifth; } return chordType.chroma === mode; }); chordTypes.forEach((chordType) => { const chordName = chordType.aliases[0]; const baseNote = noteName(index); const isInversion = index !== tonicChroma; if (isInversion) { found.push({ weight: 0.5 * weight, name: `${baseNote}${chordName}/${tonic}` }); } else { found.push({ weight: 1 * weight, name: `${baseNote}${chordName}` }); } }); }); return found; } var chord_detect_default = { detect }; //# sourceMappingURL=index.mjs.map /***/ }), /***/ "./node_modules/@tonaljs/chord-type/dist/index.mjs": /*!*********************************************************!*\ !*** ./node_modules/@tonaljs/chord-type/dist/index.mjs ***! \*********************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ add: () => (/* binding */ add), /* harmony export */ addAlias: () => (/* binding */ addAlias), /* harmony export */ all: () => (/* binding */ all), /* harmony export */ chordType: () => (/* binding */ chordType), /* harmony export */ "default": () => (/* binding */ chord_type_default), /* harmony export */ entries: () => (/* binding */ entries), /* harmony export */ get: () => (/* binding */ get), /* harmony export */ keys: () => (/* binding */ keys), /* harmony export */ names: () => (/* binding */ names), /* harmony export */ removeAll: () => (/* binding */ removeAll), /* harmony export */ symbols: () => (/* binding */ symbols) /* harmony export */ }); /* harmony import */ var _tonaljs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tonaljs/core */ "./node_modules/@tonaljs/core/dist/index.mjs"); /* harmony import */ var _tonaljs_pcset__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tonaljs/pcset */ "./node_modules/@tonaljs/pcset/dist/index.mjs"); // index.ts // data.ts var CHORDS = [ ["1P 3M 5P", "major", "M ^ maj"], ["1P 3M 5P 7M", "major seventh", "maj7 \u0394 ma7 M7 Maj7 ^7"], ["1P 3M 5P 7M 9M", "major ninth", "maj9 \u03949 ^9"], ["1P 3M 5P 7M 9M 13M", "major thirteenth", "maj13 Maj13 ^13"], ["1P 3M 5P 6M", "sixth", "6 add6 add13 M6"], ["1P 3M 5P 6M 9M", "sixth/ninth", "6/9 69 M69"], ["1P 3M 6m 7M", "major seventh flat sixth", "M7b6 ^7b6"], [ "1P 3M 5P 7M 11A", "major seventh sharp eleventh", "maj#4 \u0394#4 \u0394#11 M7#11 ^7#11 maj7#11" ], ["1P 3m 5P", "minor", "m min -"], ["1P 3m 5P 7m", "minor seventh", "m7 min7 mi7 -7"], [ "1P 3m 5P 7M", "minor/major seventh", "m/ma7 m/maj7 mM7 mMaj7 m/M7 -\u03947 m\u0394 -^7" ], ["1P 3m 5P 6M", "minor sixth", "m6 -6"], ["1P 3m 5P 7m 9M", "minor ninth", "m9 -9"], ["1P 3m 5P 7M 9M", "minor/major ninth", "mM9 mMaj9 -^9"], ["1P 3m 5P 7m 9M 11P", "minor eleventh", "m11 -11"], ["1P 3m 5P 7m 9M 13M", "minor thirteenth", "m13 -13"], ["1P 3m 5d", "diminished", "dim \xB0 o"], ["1P 3m 5d 7d", "diminished seventh", "dim7 \xB07 o7"], ["1P 3m 5d 7m", "half-diminished", "m7b5 \xF8 -7b5 h7 h"], ["1P 3M 5P 7m", "dominant seventh", "7 dom"], ["1P 3M 5P 7m 9M", "dominant ninth", "9"], ["1P 3M 5P 7m 9M 13M", "dominant thirteenth", "13"], ["1P 3M 5P 7m 11A", "lydian dominant seventh", "7#11 7#4"], ["1P 3M 5P 7m 9m", "dominant flat ninth", "7b9"], ["1P 3M 5P 7m 9A", "dominant sharp ninth", "7#9"], ["1P 3M 7m 9m", "altered", "alt7"], ["1P 4P 5P", "suspended fourth", "sus4 sus"], ["1P 2M 5P", "suspended second", "sus2"], ["1P 4P 5P 7m", "suspended fourth seventh", "7sus4 7sus"], ["1P 5P 7m 9M 11P", "eleventh", "11"], [ "1P 4P 5P 7m 9m", "suspended fourth flat ninth", "b9sus phryg 7b9sus 7b9sus4" ], ["1P 5P", "fifth", "5"], ["1P 3M 5A", "augmented", "aug + +5 ^#5"], ["1P 3m 5A", "minor augmented", "m#5 -#5 m+"], ["1P 3M 5A 7M", "augmented seventh", "maj7#5 maj7+5 +maj7 ^7#5"], [ "1P 3M 5P 7M 9M 11A", "major sharp eleventh (lydian)", "maj9#11 \u03949#11 ^9#11" ], ["1P 2M 4P 5P", "", "sus24 sus4add9"], ["1P 3M 5A 7M 9M", "", "maj9#5 Maj9#5"], ["1P 3M 5A 7m", "", "7#5 +7 7+ 7aug aug7"], ["1P 3M 5A 7m 9A", "", "7#5#9 7#9#5 7alt"], ["1P 3M 5A 7m 9M", "", "9#5 9+"], ["1P 3M 5A 7m 9M 11A", "", "9#5#11"], ["1P 3M 5A 7m 9m", "", "7#5b9 7b9#5"], ["1P 3M 5A 7m 9m 11A", "", "7#5b9#11"], ["1P 3M 5A 9A", "", "+add#9"], ["1P 3M 5A 9M", "", "M#5add9 +add9"], ["1P 3M 5P 6M 11A", "", "M6#11 M6b5 6#11 6b5"], ["1P 3M 5P 6M 7M 9M", "", "M7add13"], ["1P 3M 5P 6M 9M 11A", "", "69#11"], ["1P 3m 5P 6M 9M", "", "m69 -69"], ["1P 3M 5P 6m 7m", "", "7b6"], ["1P 3M 5P 7M 9A 11A", "", "maj7#9#11"], ["1P 3M 5P 7M 9M 11A 13M", "", "M13#11 maj13#11 M13+4 M13#4"], ["1P 3M 5P 7M 9m", "", "M7b9"], ["1P 3M 5P 7m 11A 13m", "", "7#11b13 7b5b13"], ["1P 3M 5P 7m 13M", "", "7add6 67 7add13"], ["1P 3M 5P 7m 9A 11A", "", "7#9#11 7b5#9 7#9b5"], ["1P 3M 5P 7m 9A 11A 13M", "", "13#9#11"], ["1P 3M 5P 7m 9A 11A 13m", "", "7#9#11b13"], ["1P 3M 5P 7m 9A 13M", "", "13#9"], ["1P 3M 5P 7m 9A 13m", "", "7#9b13"], ["1P 3M 5P 7m 9M 11A", "", "9#11 9+4 9#4"], ["1P 3M 5P 7m 9M 11A 13M", "", "13#11 13+4 13#4"], ["1P 3M 5P 7m 9M 11A 13m", "", "9#11b13 9b5b13"], ["1P 3M 5P 7m 9m 11A", "", "7b9#11 7b5b9 7b9b5"], ["1P 3M 5P 7m 9m 11A 13M", "", "13b9#11"], ["1P 3M 5P 7m 9m 11A 13m", "", "7b9b13#11 7b9#11b13 7b5b9b13"], ["1P 3M 5P 7m 9m 13M", "", "13b9"], ["1P 3M 5P 7m 9m 13m", "", "7b9b13"], ["1P 3M 5P 7m 9m 9A", "", "7b9#9"], ["1P 3M 5P 9M", "", "Madd9 2 add9 add2"], ["1P 3M 5P 9m", "", "Maddb9"], ["1P 3M 5d", "", "Mb5"], ["1P 3M 5d 6M 7m 9M", "", "13b5"], ["1P 3M 5d 7M", "", "M7b5"], ["1P 3M 5d 7M 9M", "", "M9b5"], ["1P 3M 5d 7m", "", "7b5"], ["1P 3M 5d 7m 9M", "", "9b5"], ["1P 3M 7m", "", "7no5"], ["1P 3M 7m 13m", "", "7b13"], ["1P 3M 7m 9M", "", "9no5"], ["1P 3M 7m 9M 13M", "", "13no5"], ["1P 3M 7m 9M 13m", "", "9b13"], ["1P 3m 4P 5P", "", "madd4"], ["1P 3m 5P 6m 7M", "", "mMaj7b6"], ["1P 3m 5P 6m 7M 9M", "", "mMaj9b6"], ["1P 3m 5P 7m 11P", "", "m7add11 m7add4"], ["1P 3m 5P 9M", "", "madd9"], ["1P 3m 5d 6M 7M", "", "o7M7"], ["1P 3m 5d 7M", "", "oM7"], ["1P 3m 6m 7M", "", "mb6M7"], ["1P 3m 6m 7m", "", "m7#5"], ["1P 3m 6m 7m 9M", "", "m9#5"], ["1P 3m 5A 7m 9M 11P", "", "m11A"], ["1P 3m 6m 9m", "", "mb6b9"], ["1P 2M 3m 5d 7m", "", "m9b5"], ["1P 4P 5A 7M", "", "M7#5sus4"], ["1P 4P 5A 7M 9M", "", "M9#5sus4"], ["1P 4P 5A 7m", "", "7#5sus4"], ["1P 4P 5P 7M", "", "M7sus4"], ["1P 4P 5P 7M 9M", "", "M9sus4"], ["1P 4P 5P 7m 9M", "", "9sus4 9sus"], ["1P 4P 5P 7m 9M 13M", "", "13sus4 13sus"], ["1P 4P 5P 7m 9m 13m", "", "7sus4b9b13 7b9b13sus4"], ["1P 4P 7m 10m", "", "4 quartal"], ["1P 5P 7m 9m 11P", "", "11b9"] ]; var data_default = CHORDS; // index.ts var NoChordType = { ..._tonaljs_pcset__WEBPACK_IMPORTED_MODULE_1__.EmptyPcset, name: "", quality: "Unknown", intervals: [], aliases: [] }; var dictionary = []; var index = {}; function get(type) { return index[type] || NoChordType; } var chordType = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.deprecate)("ChordType.chordType", "ChordType.get", get); function names() { return dictionary.map((chord) => chord.name).filter((x) => x); } function symbols() { return dictionary.map((chord) => chord.aliases[0]).filter((x) => x); } function keys() { return Object.keys(index); } function all() { return dictionary.slice(); } var entries = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_0__.deprecate)("ChordType.entries", "ChordType.all", all); function removeAll() { dictionary = []; index = {}; } function add(intervals, aliases, fullName) { const quality = getQuality(intervals); const chord = { ...(0,_tonaljs_pcset__WEBPACK_IMPORTED_MODULE_1__.get)(intervals), name: fullName || "", quality, intervals, aliases }; dictionary.push(chord); if (chord.name) { index[chord.name] = chord; } index[chord.setNum] = chord; index[chord.chroma] = chord; chord.aliases.forEach((alias) => addAlias(chord, alias)); } function addAlias(chord, alias) { index[alias] = chord; } function getQuality(intervals) { const has = (interval) => intervals.indexOf(interval) !== -1; return has("5A") ? "Augmented" : has("3M") ? "Major" : has("5d") ? "Diminished" : has("3m") ? "Minor" : "Unknown"; } data_default.forEach( ([ivls, fullName, names2]) => add(ivls.split(" "), names2.split(" "), fullName) ); dictionary.sort((a, b) => a.setNum - b.setNum); var chord_type_default = { names, symbols, get, all, add, removeAll, keys, entries, chordType }; //# sourceMappingURL=index.mjs.map /***/ }), /***/ "./node_modules/@tonaljs/chord/dist/index.mjs": /*!****************************************************!*\ !*** ./node_modules/@tonaljs/chord/dist/index.mjs ***! \****************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ chord: () => (/* binding */ chord), /* harmony export */ chordScales: () => (/* binding */ chordScales), /* harmony export */ "default": () => (/* binding */ chord_default), /* harmony export */ detect: () => (/* reexport safe */ _tonaljs_chord_detect__WEBPACK_IMPORTED_MODULE_0__.detect), /* harmony export */ extended: () => (/* binding */ extended), /* harmony export */ get: () => (/* binding */ get), /* harmony export */ getChord: () => (/* binding */ getChord), /* harmony export */ reduced: () => (/* binding */ reduced), /* harmony export */ tokenize: () => (/* binding */ tokenize), /* harmony export */ transpose: () => (/* binding */ transpose) /* harmony export */ }); /* harmony import */ var _tonaljs_chord_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tonaljs/chord-detect */ "./node_modules/@tonaljs/chord-detect/dist/index.mjs"); /* harmony import */ var _tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tonaljs/chord-type */ "./node_modules/@tonaljs/chord-type/dist/index.mjs"); /* harmony import */ var _tonaljs_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @tonaljs/core */ "./node_modules/@tonaljs/core/dist/index.mjs"); /* harmony import */ var _tonaljs_pcset__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tonaljs/pcset */ "./node_modules/@tonaljs/pcset/dist/index.mjs"); /* harmony import */ var _tonaljs_scale_type__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tonaljs/scale-type */ "./node_modules/@tonaljs/scale-type/dist/index.mjs"); // index.ts var NoChord = { empty: true, name: "", symbol: "", root: "", rootDegree: 0, type: "", tonic: null, setNum: NaN, quality: "Unknown", chroma: "", normalized: "", aliases: [], notes: [], intervals: [] }; var NUM_TYPES = /^(6|64|7|9|11|13)$/; function tokenize(name) { const [letter, acc, oct, type] = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.tokenizeNote)(name); if (letter === "") { return ["", name]; } if (letter === "A" && type === "ug") { return ["", "aug"]; } if (!type && (oct === "4" || oct === "5")) { return [letter + acc, oct]; } if (NUM_TYPES.test(oct)) { return [letter + acc, oct + type]; } else { return [letter + acc + oct, type]; } } function get(src) { if (src === "") { return NoChord; } if (Array.isArray(src) && src.length === 2) { return getChord(src[1], src[0]); } else { const [tonic, type] = tokenize(src); const chord2 = getChord(type, tonic); return chord2.empty ? getChord(src) : chord2; } } function getChord(typeName, optionalTonic, optionalRoot) { const type = (0,_tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_1__.get)(typeName); const tonic = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.note)(optionalTonic || ""); const root = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.note)(optionalRoot || ""); if (type.empty || optionalTonic && tonic.empty || optionalRoot && root.empty) { return NoChord; } const rootInterval = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.distance)(tonic.pc, root.pc); const rootDegree = type.intervals.indexOf(rootInterval) + 1; if (!root.empty && !rootDegree) { return NoChord; } const intervals = Array.from(type.intervals); for (let i = 1; i < rootDegree; i++) { const num = intervals[0][0]; const quality = intervals[0][1]; const newNum = parseInt(num, 10) + 7; intervals.push(`${newNum}${quality}`); intervals.shift(); } const notes = tonic.empty ? [] : intervals.map((i) => (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.transpose)(tonic, i)); typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0]; const symbol = `${tonic.empty ? "" : tonic.pc}${typeName}${root.empty || rootDegree <= 1 ? "" : "/" + root.pc}`; const name = `${optionalTonic ? tonic.pc + " " : ""}${type.name}${rootDegree > 1 && optionalRoot ? " over " + root.pc : ""}`; return { ...type, name, symbol, type: type.name, root: root.name, intervals, rootDegree, tonic: tonic.name, notes }; } var chord = (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.deprecate)("Chord.chord", "Chord.get", get); function transpose(chordName, interval) { const [tonic, type] = tokenize(chordName); if (!tonic) { return chordName; } return (0,_tonaljs_core__WEBPACK_IMPORTED_MODULE_2__.transpose)(tonic, interval) + type; } function chordScales(name) { const s = get(name); const isChordIncluded = (0,_tonaljs_pcset__WEBPACK_IMPORTED_MODULE_3__.isSupersetOf)(s.chroma); return (0,_tonaljs_scale_type__WEBPACK_IMPORTED_MODULE_4__.all)().filter((scale) => isChordIncluded(scale.chroma)).map((scale) => scale.name); } function extended(chordName) { const s = get(chordName); const isSuperset = (0,_tonaljs_pcset__WEBPACK_IMPORTED_MODULE_3__.isSupersetOf)(s.chroma); return (0,_tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_1__.all)().filter((chord2) => isSuperset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]); } function reduced(chordName) { const s = get(chordName); const isSubset = (0,_tonaljs_pcset__WEBPACK_IMPORTED_MODULE_3__.isSubsetOf)(s.chroma); return (0,_tonaljs_chord_type__WEBPACK_IMPORTED_MODULE_1__.all)().filter((chord2) => isSubset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]); } var chord_default = { getChord, get, detect: _tonaljs_chord_detect__WEBPACK_IMPORTED_MODULE_0__.detect, chordScales, extended, reduced, tokenize, transpose, chord }; //# sourceMappingURL=index.mjs.map /***/ }), /***/ "./node_modules/@tonaljs/collection/dist/index.mjs": /*!*********************************************************!*\ !*** ./node_modules/@tonaljs/collection/dist/index.mjs ***! \*********************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ compact: () => (/* binding */ compact), /* harmony export */ "default": () => (/* binding */ collection_default), /* harmony export */ permutations: () => (/* binding */ permutations), /* harmony export */ range: () => (/* binding */ range), /* harmony export */ rotate: () => (/* binding */ rotate), /* harmony export */ shuffle: () => (/* binding */ shuffle) /* harmony export */ }); // index.ts function ascR(b, n) { const a = []; for (; n--; a[n] = n + b) ; return a; } function descR(b, n) { const a = []; for (; n--; a[n] = b - n) ; return a; } function range(from, to) { return from < to ? ascR(from, to - from + 1) : descR(from, from - to + 1); } function rotate(times, arr) { const len = arr.length; const n = (times % len + len) % len; return arr.slice(n, len).concat(arr.slice(0, n)); } function compact(arr) { return arr.filter((n) => n === 0 || n); } function shuffle(arr, rnd = Math.random) { let i; let t; let m = arr.length; while (m) { i = Math.floor