Skip to content

Instantly share code, notes, and snippets.

@jussiry
Created November 27, 2019 16:42
Show Gist options
  • Save jussiry/942b4ed3521d981229ab1c599ed66048 to your computer and use it in GitHub Desktop.
Save jussiry/942b4ed3521d981229ab1c599ed66048 to your computer and use it in GitHub Desktop.
var global = typeof global !== 'undefined' ? global : window;
global.edide = {};
"use strict";edide.set = (function _set (edide) {
return (...args) => new Set(args)
return this;
}).call({}, edide);
//# sourceURL=set-1
"use strict";edide.inEditor = (function _inEditor (edide) {
// Tells if the code is being executed in context of the editor.
// (false indicating production environment)
// Has special handling in production, so that
// if (!inEditor) { return }
// at root level will cause rest of the code not to be processed
return typeof window === 'object' &&
typeof window.serverModule === 'object'
return this;
}).call({}, edide);
//# sourceURL=inEditor-2
"use strict";edide.global = (function _global (edide) {
return typeof global !== 'undefined' ? global : window;
return this;
}).call({}, edide);
//# sourceURL=global-3
"use strict";edide.typeof = (function (edide) {
// typeof with 'array' and 'null' types added
return function(arg) {
var type;
type = typeof arg;
if (type === 'object') {
if (arg instanceof Array || ArrayBuffer.isView(arg)) {
return 'array';
}
if (arg === null) {
return 'null';
}
}
return type;
};
return this;
}).call({}, edide);
//# sourceURL=typeof-4
"use strict";edide.argumentTypes = (function _argumentTypes (edide) {
// Transform arguments array to an object based on argument types,
// allowing varying argument order.
// You can use default name mapping, or give custom mapping.
// When there are multiple arguments with same type, they are grouped
// in an array (e.g. 'str' example). NOTE: don't use multiple array arguments!
// DEPRECATE use of custom mapping and just do:
// { fun, boo, str } = argumentTypes arguments
// [funcProp, booleanVar, whatever] = [fun, boo, str]
// OR.. make \:argTypes with just edide.typeof instead of any mapping
var defaultMapping;
defaultMapping = {
string: 'str',
number: 'num',
object: 'obj',
array: 'arr',
boolean: 'boo', // should be bool
function: 'fun', // should be func
undefined: 'nil',
null: 'nil'
};
// rest: all non-defined types end up in rest (when own typeMapping used)
return function(args, typeMapping = defaultMapping, defaultValues) {
var arg, argTypes, current, i, key, len, ref, ref1, typeName, val;
argTypes = {};
for (i = 0, len = args.length; i < len; i++) {
arg = args[i];
typeName = (ref = (ref1 = typeMapping[edide.typeof(arg)]) != null ? ref1 : typeMapping.rest) != null ? ref : 'rest';
if (current = argTypes[typeName]) {
if (Array.isArray(current)) {
current.push(arg);
} else {
argTypes[typeName] = [argTypes[typeName], arg];
}
} else {
argTypes[typeName] = arg;
}
}
for (key in defaultValues) {
val = defaultValues[key];
if (argTypes[key] == null) {
argTypes[key] = val;
}
}
return argTypes;
};
return this;
}).call({}, edide);
//# sourceURL=argumentTypes-5
"use strict";edide.editorModule = (function _editorModule (edide) {
// acces editor modules without requiring them
// NOTE: if editor->edide, editorModule->edideModule
var ref;
return typeof file !== "undefined" && file !== null ? (ref = file.modules) != null ? ref.all : void 0 : void 0;
return this;
}).call({}, edide);
//# sourceURL=editorModule-6
"use strict";edide.logProd = (function _logProd (edide) {
// production safe version of console log
return (...args) => {
var console, ref;
({console} = (ref = edide.editorModule) != null ? ref : window);
return console.log(...args);
};
return this;
}).call({}, edide);
//# sourceURL=logProd-7
"use strict";edide.assert = (function _assert (edide) {
// Use to assert code validity
// Arguments:
// boolean or function: result of assert (truthy is ok and falsy is error)
// string: error message
// TODO: remove assert rows from code in tools/export
var argMapping, assert;
argMapping = {
function: 'testFunc',
string: 'errorMessage',
//rest: 'result'
boolean: 'result',
object: 'debug',
array: 'debug'
};
return assert = (...args) => {
var debug, errorMessage, result, testFunc;
// throw 'depracated assert call' if arguments.length > 2
({result, testFunc, errorMessage, debug} = edide.argumentTypes(args, argMapping));
if (testFunc) {
result = testFunc();
}
if (!result) {
if (debug != null) {
edide.logProd('assert debug', debug);
}
throw Error(`assert failed: '${errorMessage}'`);
}
};
// NOTE: requiring edit_debug would case endless require loop (without throwing an error)
return this;
}).call({}, edide);
//# sourceURL=assert-8
"use strict";edide.moduleGate = (function _moduleGate (edide) {Object.defineProperty(this, 'module_name', {value:'moduleGate'});
// editor "module getter"
// access @root, @active, @executing module
// properties updated by \:moduleGateHandler
if (!edide.inEditor) {
return this;
}
// DEPRECATE, use #edide.editorModule
this.all = typeof serverModule !== "undefined" && serverModule !== null ? serverModule.modules.all : void 0; // why not just use \:modules.all ?
this.root; // module that is edited in root
this.rootName;
this.active; // module that is currently being edited (can be root or in window)
this.activeName;
this.executing;
this.executingName;
return this;
}).call({}, edide);
//# sourceURL=moduleGate-9
"use strict";edide.keep = (function _keep (edide) {
// Keeps given property over recompiles and module changes.
// Cleared only on browser reload (or manually here >>>)
// See \:hold for a version that holds values only for recompiles.
// WARNING: careful when modifying this; browser reload likely needed
var base, keep, nthCallInModule, prevExecutingModule, prodMock;
prodMock = (prop) => {
return prop;
};
if (!edide.inEditor) {
return prodMock;
}
if ((base = edide.global).keepPropertyContainer == null) {
base.keepPropertyContainer = new Map();
}
prevExecutingModule = null;
nthCallInModule = null; // number
keep = (prop) => { // name,
var executingName, modulesProps;
edide.assert(edide.moduleGate.executing != null, "keep can only be used in synchronous init of module");
// use global variable and executing module to check if previous property exists.
// when many retains in same module, give them in same order
({executingName} = edide.moduleGate);
// get / initialize module container
if (!(modulesProps = keepPropertyContainer.get(executingName))) {
keepPropertyContainer.set(executingName, (modulesProps = []));
}
// if typeof name is 'string'
// return modulesProps[name] ? (modulesProps[name] = prop)
if (executingName !== prevExecutingModule) {
nthCallInModule = 0;
prevExecutingModule = executingName;
} else {
nthCallInModule++;
}
if (modulesProps[nthCallInModule] != null) {
return modulesProps[nthCallInModule];
}
if (typeof prop === 'function') {
prop = prop();
}
return modulesProps[nthCallInModule] = prop;
};
keep.reset = (moduleName = edide.moduleGate.executingName) => {
if (moduleName) {
return edide.global.keepPropertyContainer.delete(moduleName);
} else {
return edide.global.keepPropertyContainer = new Map();
}
};
keep.moduleRecompiled = () => {
return prevExecutingModule = null;
};
return keep;
return this;
}).call({}, edide);
//# sourceURL=keep-10
"use strict";edide.rethrow = (function _rethrow (edide) {
// uses error.original to show both errors
// (could also call showError on original and throw new one?)
return (errMsg, originalError) => {
var err;
err = new Error(errMsg);
err.original = originalError;
throw err;
};
return this;
}).call({}, edide);
//# sourceURL=rethrow-11
"use strict";edide.var = (function _var (edide) {
// TODO:
// - also should setting vars inside react be allowed (as it is now)
// Creates reactive variables
// Refactor to revar ?
var currentReact, debugging, dependees, dependsOn, depsRequired, inInitCall, infinityCheck, initSetter, newVar, parent, setLinks, setters, updateVar, values;
values = new Map; // TODO edide.keep
setters = new Map; // varName => setter:func
dependees = new Map; // varName => deps:
setLinks = new Map; // for reactiveGraph, show setters inside reactive/setter:s
debugging = false; //edide.editorModule?
// TODO
depsRequired = new Map; // varName : dependsOn
// on init add all deps
// on set remove
// fire only once
inInitCall = false; // TODO use dependsOn? instead
dependsOn = new Set(); // remove
initSetter = (name, setter) => {
var debugName, err, parent, ref, val;
debugName = (ref = setter.type) != null ? ref : name;
if ((setters.get(name)) != null) {
throw Error(`Reactive for '${debugName}' already exists`);
}
setters.set(name, setter);
// call setter with possible dependencies
if (inInitCall) {
throw Error(`can't create reactive setter (for '${debugName}') inside reactive context`);
}
inInitCall = name;
dependsOn.clear(); // TODO clear => new Set
try {
//parent = name
val = setter(); // TODO: some day add revar and unvar as params; helps with multiple reactives to keep the separated
} catch (error) {
err = error;
inInitCall = false;
err.message = `Reactive initialization of '${debugName}' failed: ${err.message}`;
throw err; // deprecate edide.rethrow ? Would show both errors...
}
//edide.rethrow "Reactive initSetter for '#{debugName}' failed", err
// e = new Error "initSetter failed"
// e.original = err
// #e.stack = err.stack
// throw e
parent = null;
//# add updated dependencies
dependsOn.forEach((depName) => {
var deps;
if ((deps = dependees.get(depName)) == null) {
//edide.console.log "creating dependees to #{depName}"
dependees.set(depName, deps = new Set);
}
//edide.console.log "adding dependee #{name} to #{depName}"
return deps.add(name);
});
// TODO
// depsRequired.set name, dependsOn
// dependsOn = null
// reset state
inInitCall = false;
return val;
};
infinityCheck = new Set; //edide.keep
parent = null;
updateVar = function(name, val) {
var ref, ref1, type;
if (arguments.length === 1) {
val = setters.get(name)();
if (debugging && (type = setters.get(name).type)) {
edide.logProd(`running ${(setters.get(name).type)}`);
}
}
if (typeof name !== 'string') { // symbol ~ react function
return;
}
if (values.get(name) === val) { // can't reset same value
return;
}
if (infinityCheck.has(name)) {
// Not very useful log but something.. figure out this better!
infinityCheck.forEach((k) => {
return edide.logProd(k);
});
edide.logProd(name);
if ((ref = edide.editorModule) != null) {
if (typeof ref.reactiveGraph === "function") {
ref.reactiveGraph();
}
}
throw Error("Inifinite loop in \:var dependencies");
}
if (debugging) {
edide.logProd(`updating ${name}`);
}
values.set(name, val);
// dependees don't get fired on init
if (!inInitCall) {
infinityCheck.add(name);
if ((ref1 = dependees.get(name)) != null) {
ref1.forEach((depName) => {
return updateVar(depName);
});
}
infinityCheck.delete(name);
}
return val;
};
currentReact = [];
// (string, func) - reactive setter
// (string, any) - static setter
// (string) - getter
// (func) - reactive
newVar = function(name, setter) {
var context, contextSet, err;
//edide.assert (typeof name is 'function') or (typeof name is 'string')
if (arguments.length === 1) {
if (typeof name === 'string') {
if (inInitCall) {
// (string)
dependsOn.add(name);
}
return values.get(name);
} else {
// (func) edide.assert typeof name is 'function'
setter = name;
name = Symbol();
values.set(name, name); // for debugging (showing react/dom funcs in graph)
}
}
// shows setters inside setters
// TODO: wrap setter call (in updateVar and initSetter inside "callSetter" func
// and check currentReact and infinityCheck there
// TODO2: only when debugging?
if (currentReact.length) { // and debugging
context = currentReact[currentReact.length - 1];
if (!(contextSet = setLinks.get(context))) {
setLinks.set(context, contextSet = new Set);
}
contextSet.add(name);
}
currentReact.push(name);
if (typeof setter === 'function') {
// (string, func) and (func)
setter = initSetter(name, setter); // setter becomes value
}
if (typeof name === 'string') {
try {
// (string, func) and (string, any)
updateVar(name, setter);
} catch (error) {
err = error;
infinityCheck.clear();
throw err;
}
}
currentReact.pop();
return setter;
};
Object.assign(newVar, {dependees, values, setters, setLinks});
return newVar;
return this;
}).call({}, edide);
//# sourceURL=var-12
"use strict";edide.str = (function _str (edide) {Object.defineProperty(this, 'module_name', {value:'str'});
// utility methods for strings
// (the first argument is typically the string being modified)
var ifs;
this.if = ifs = function(arg, true_str, false_str) {
if (true_str == null) {
true_str = arg;
}
if (arg) {
return true_str;
} else {
if (false_str != null) {
return false_str;
} else {
return '';
}
}
};
this.capitalize = function(str) {
return str[0].toUpperCase() + str.slice(1);
};
this.dasherize = function(str) {
return str.replace(/([A-Z])/g, function(full, match) {
return '-' + match.toLowerCase();
}).replace(/ /g, '-');
};
// TODO \:speed_test comparison to:
// @dasherize = (str)->
// str.replace /([A-Z ])/g, (full, match)->
// if match is ' '
// then '-'
// else '-' + match.toLowerCase()
this.parsesToNumber = this.isNumber = function(str) {
return !Number.isNaN(parseInt(str));
};
this.truncate = function(str, limit, truncStr = '...') {
if (str.length > limit) {
return str.slice(0, limit) + truncStr;
} else {
return str;
}
};
this.titleize = function(str) {
return str.replace(/[-_]/g, ' ').replace(/(^| )(\w)/g, function(full, s, firstChar) {
return s + firstChar.toUpperCase();
}).replace(/(\w)([A-Z])/g, function(f, s, c) {
return s + ' ' + c;
});
};
//.replace(/ (\w)/g, (full,firstChar)-> ' ' + firstChar.toUpperCase())
//str.titleize() # TODO: drom sugar req
this.random = function(limit = 20) {
return (Math.random() + '').slice(2, +(limit + 1) + 1 || 9e9);
};
this.remove = function(full, remove) {
return full.replace(remove, '');
};
this.reverse = function(str) {
return str.split("").reverse().join('');
};
return this;
}).call({}, edide);
//# sourceURL=str-13
"use strict";edide.object = (function _object (edide) {Object.defineProperty(this, 'module_name', {value:'object'});
// utility functions for object
// TODO
// go through all methods and move less common ones to \:keyval
// helpers
var identity;
identity = function(el) {
return el;
};
// methods
//@clone = _?.clone
//@isEqual = _?.isEqual # deprecate; use \:isEqual
// remove all children; more inefficient than creating new,
// but necessary to retain object references
this.dellAll = function(obj) {
var key;
for (key in obj) {
delete obj[key];
}
};
this.filter = function(obj, filterer) {
var filtered, key, val;
filtered = {};
for (key in obj) {
val = obj[key];
if (filterer(key, val)) {
filtered[key] = val;
}
}
return filtered;
};
this.forEach = function(obj, func) {
var key, val;
for (key in obj) {
val = obj[key];
func(val, key);
}
};
// Transfrom array to object with given key and value transfrom functions
this.fromArray = function(array, valFromEl, keyFromEl) {
var el, i, ind, len, obj;
if (valFromEl == null) {
valFromEl = identity;
}
if (keyFromEl == null) {
keyFromEl = identity;
}
obj = {};
for (ind = i = 0, len = array.length; i < len; ind = ++i) {
el = array[ind];
obj[keyFromEl(el, ind)] = valFromEl(el, ind);
}
return obj;
};
this.isObject = function(o) {
return typeof o === 'object' && !Array.isArray(o) && o !== null;
};
// returns array
this.map = function(obj, mapFunc) {
var key, results, val;
results = [];
for (key in obj) {
val = obj[key];
results.push(mapFunc(val, key));
}
return results;
};
// returns object
this.maps = function(obj, mapFuncs) {
var key, newObj, val;
edide.assert("'mapFuncs' argument should include 'key' and/or 'val' transform functions", (mapFuncs.key != null) || (mapFuncs.val != null));
if (mapFuncs.key == null) {
mapFuncs.key = identity;
}
if (mapFuncs.val == null) {
mapFuncs.val = identity;
}
newObj = {};
for (key in obj) {
val = obj[key];
newObj[mapFuncs.key(key, val)] = mapFuncs.val(val, key);
}
return newObj;
};
// see also Object.assign (no IE support though)
this.merge = function(first, ...rest) {
var i, key, len, obj, val;
for (i = 0, len = rest.length; i < len; i++) {
obj = rest[i];
for (key in obj) {
val = obj[key];
first[key] = val;
}
}
return first;
};
this.mergeWary = function(first, ...rest) {
var i, key, len, obj, val;
for (i = 0, len = rest.length; i < len; i++) {
obj = rest[i];
for (key in obj) {
val = obj[key];
//key += ' ' while first[key]? # never ovewrite existing value
if (first[key] == null) {
first[key] = val;
}
}
}
return first;
};
this.mergeDeep = function(target, source) {
var key, targetProp, val;
for (key in source) {
val = source[key];
targetProp = target[key];
if (this.isObject(targetProp) && this.isObject(val)) {
this.mergeDeep(targetProp, val);
} else {
target[key] = val;
}
}
return target;
};
this.eachDeep = function(rootObj, func, filter) {
var depth, hasBeenExecuted, iterator;
if (filter == null) {
filter = function() {
return true;
};
}
depth = 1;
hasBeenExecuted = new Map;
iterator = function(obj, parent) {
var key, val;
if (hasBeenExecuted.get(obj)) {
return;
}
hasBeenExecuted.set(obj, true);
// iterate
for (key in obj) {
val = obj[key];
if (!(filter(key, val, depth))) {
continue;
}
if (typeof val === 'object') {
depth++;
iterator(val, obj);
depth--;
}
func(key, val, parent);
}
};
//hasBeenExecuted.delete obj # uncomment to skip only circular references
iterator(rootObj);
};
this.select = function(obj, keysArr) {
var i, key, len, newObj;
newObj = {};
for (i = 0, len = keysArr.length; i < len; i++) {
key = keysArr[i];
newObj[key] = obj[key];
}
return newObj;
};
this.values = function(obj) {
var k, results, value;
results = [];
for (k in obj) {
value = obj[k];
results.push(value);
}
return results;
};
//Object.keys(obj).map (k)-> obj[k]
//@entries = TODO {a:1, b:2} -> [['a',1], ['b', 2]] # https://github.com/es-shims/Object.entries
return this;
}).call({}, edide);
//# sourceURL=object-14
"use strict";edide.HTML = (function _HTML (edide) {Object.defineProperty(this, 'module_name', {value:'HTML'});
// HTML utility functions
// (required from node_from_obj; try to keep small)
this.eventAttrs = ['onKeyDown', 'onKeyUp', 'onKeyPress', 'onBlur', 'onFocus', 'onLoad', 'onChange', 'onInput', 'onSubmit', 'onSelect', 'onPaste', 'onClick', 'onDoubleClick', 'onContextMenu', 'onMouseEnter', 'onMouseLeave', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseDown', 'onMouseUp', 'onDragEnter', 'onDragExit', 'onDragLeave', 'onDragOver', 'onDrag', 'onDragEnd', 'onDragStart', 'onDrop', 'onResize', 'onTouchStart', 'onTouchMove', 'onTouchEnd'];
this.standardAttrs = [
"accept",
"action",
"alt",
"async",
"checked",
"class",
"cols",
"content",
"controls",
"coords",
"data",
"defer",
"dir",
"disabled",
"download",
"draggable",
"form",
"height",
"hidden",
"href",
"icon",
"id",
"lang",
"list",
"loop",
"manifest",
"max",
"media",
"method",
"min",
"multiple",
"muted",
"name",
"open",
"pattern",
"placeholder",
"poster",
"preload",
"rel",
"required",
"role",
"rows",
"sandbox",
"scope",
"scrolling",
"seamless",
"selected",
"shape",
"size",
"sizes",
"spellcheck",
"src",
"start",
"step",
"style",
"target",
"title",
"type",
"value",
"width",
"wmode" // "span", "label",
];
this.standardTags = ['a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr'];
this.condenseTags = function(htmlStr) { // remove empty space between tags
return htmlStr.replace(/>( |\n)+<(\w)/g, function(full, content, char) {
return '><' + char;
});
};
// indent minified html
this.prettify = function(htmlStr) {
var indent;
if (htmlStr instanceof Element) {
htmlStr = htmlStr.outerHTML;
}
//console.log htmlStr
indent = '';
return htmlStr.replace(/<(\/)?[^>]+>/g, function(full, closing, pos) {
var followingIsClosing, indentBeg, res;
indentBeg = indent;
if (closing) {
followingIsClosing = htmlStr.slice(pos + full.length, +(pos + full.length + 1) + 1 || 9e9) === '</';
indent = indent.substr(2);
res = full + edide.str.if(followingIsClosing, "\n" + indent);
} else {
indent += ' ';
res = "\n" + indent + full;
}
return res;
});
};
this.safeString = function(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
//.replace(/"/g, '&quot;').replace(/'/g, '&apos;') # " and ' replace not necessary?
return this;
}).call({}, edide);
//# sourceURL=HTML-15
"use strict";edide.stylesUtils = (function _stylesUtils (edide) {Object.defineProperty(this, 'module_name', {value:'stylesUtils'});
// TODO: make Set instead of array
var vendors;
this.non_pixel_props = ['font-weight', 'opacity', 'z-index', 'zoom'];
vendors = (property_name, val) => {
var i, len, obj, ref, vendor;
obj = {};
ref = ['webkit', 'moz', 'ms'];
for (i = 0, len = ref.length; i < len; i++) {
vendor = ref[i];
obj[`-${vendor}-${property_name}`] = val;
}
obj[property_name] = val; // standard
return obj;
};
this.sizeUnit = 'px'; // in the future move to em?
this.create_property_string = (key, value) => {
var val;
// borderRadius -> border-radius
key = key.replace(/[A-Z]/g, function(s) {
return '-' + s.toLowerCase();
});
//key = key.replace(/_/g,'-') # DEPRECATED
// 13 -> 13px
if (typeof value === 'number' && this.non_pixel_props.indexOf(key) === -1) {
value = `${value}${this.sizeUnit}`;
}
// "borderRadius -v" -> all verdor versions
if (key.match(/ -v$/)) {
key = key.slice(0, -3);
return ((function() {
var ref, results;
ref = vendors(key, val);
results = [];
for (key in ref) {
val = ref[key];
results.push(` ${key}: ${value};\n`);
}
return results;
})()).join('');
} else {
return ` ${key}: ${value};\n`;
}
};
//@sizeUnit = 'px'
//@create_property_string = (key, value)->
// # borderRadius -> border-radius
// key = key.replace /[A-Z]/g, (s) -> '-' + s.toLowerCase()
// if typeof value is 'number' and @non_pixel_vars.indexOf(key) is -1
// value = "#{value}#{@sizeUnit}"
// if key.match ' -v'
// key = key.split(' ')[0]
// (for key, val of @vendors(key, val)
// " #{key}: #{value};\n"
// ).join ''
// else
// " #{key}: #{value};\n"
return this;
}).call({}, edide);
//# sourceURL=stylesUtils-16
"use strict";edide.catchError = (function _catchError (edide) {
return (action) => {
var err, ref;
try {
return action(); //.call thisObj
} catch (error) {
err = error;
if ((ref = edide.editorModule) != null) {
ref.editor_error.show(err);
}
return console.error(err);
}
};
return this;
}).call({}, edide);
//# sourceURL=catchError-17
"use strict";edide.unload = (function _unload (edide) {Object.defineProperty(this, 'module_name', {value:'unload'});
// Use @add to create unloadAction to be called on module unload.
// Order of unloading modules is based on dependecy hierarcy,
// so that modules at top hierarchy get unloaded before
// modules below (see moduleExecTop).
// Typically there is no need to define module and
// in synchronous execution unloadAction will be bound to
// currently executing module.
// You may need to define the module when @add is called
// asynchronously, for unloading to work properly.
var unloading;
unloading = false;
this.unloads = edide.keep({});
// Global unloads are used in async code when module is not defined.
this.global = edide.keep([]);
this.add = (module, unloadAction) => {
var base, module_name;
if (!edide.inEditor) {
return;
}
if (unloading) {
debugger;
throw Error("Cannot add new unload, when unloading in progress");
}
if (!unloadAction) {
unloadAction = module;
module = null;
}
if (module) {
({module_name} = module); // is this really needed (or good idea to begin with?)
} else {
module_name = edide.moduleGate.executingName;
}
if (module_name == null) {
return this.addGlobal(unloadAction); // TODO: change to throwing error and suggesting using unload.addGlobal
}
edide.assert(typeof module_name === 'string', 'unknown unload module');
if ((base = this.unloads)[module_name] == null) {
base[module_name] = [];
}
this.unloads[module_name].push(unloadAction);
};
// Rest of the methods are called by edide;
// normally you only need to use @add
this.addGlobal = (unloadAction) => {
return this.global.unshift(unloadAction);
};
this.call = (moduleName) => { // "call" is a bit confusing name for function..
var i, len, unloadAction, unloads;
edide.assert(typeof moduleName === 'string', 'moduleName should be string');
if (!(unloads = this.unloads[moduleName])) {
return;
}
unloading = true;
for (i = 0, len = unloads.length; i < len; i++) {
unloadAction = unloads[i];
edide.catchError(unloadAction); //, module
}
unloads.length = 0;
return unloading = false;
};
this.callGlobalWithWait = async() => {
var unloadAction;
unloading = true;
await Promise.all((function() {
var i, len, ref, results;
ref = this.global;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
unloadAction = ref[i];
results.push(edide.catchError(unloadAction, {}));
}
return results;
}).call(this));
this.global.length = 0;
return unloading = false;
};
// DEPRECATE (replace with @callGlobalWithWait) ?
this.callGlobal = () => {
var i, len, ref, unloadAction;
unloading = true;
ref = this.global;
for (i = 0, len = ref.length; i < len; i++) {
unloadAction = ref[i];
edide.catchError(unloadAction, {});
}
this.global.length = 0;
return unloading = false;
};
this.clear = (module) => {
return module.unload = [];
};
return this;
}).call({}, edide);
//# sourceURL=unload-18
"use strict";edide.stylesInline = (function _stylesInline (edide) {Object.defineProperty(this, 'module_name', {value:'stylesInline'});
// inline styles from json
// create style string to be added to
this.fromObj = (stylesObj, styleStr = '') => {
var addition, additions, i, key, len, ref, value;
if (additions = stylesObj['&']) {
ref = (Array.isArray(additions) ? additions : [additions]);
for (i = 0, len = ref.length; i < len; i++) {
addition = ref[i];
styleStr += this.fromObj(addition);
}
}
for (key in stylesObj) {
value = stylesObj[key];
if (key !== '&') {
styleStr += edide.stylesUtils.create_property_string(key, value);
}
}
return styleStr;
};
// replace elements style with new style
this.set = (element, stylesObj) => {
return element.setAttribute('style', this.fromObj(stylesObj));
};
// concatenate new styles to elements current styles
this.add = (element, stylesObj) => {
var styleStr;
styleStr = element.getAttribute('style') || '';
return element.setAttribute('style', styleStr + this.fromObj(stylesObj));
};
this.addUnloading = (element, stylesObj) => {
this.add(element, stylesObj);
return edide.unload.add(() => {
var key;
for (key in stylesObj) {
element.style[key] = '';
}
});
};
return this;
}).call({}, edide);
//# sourceURL=stylesInline-19
"use strict";edide.create_html_node = (function _create_html_node (edide) {
var create_html_node;
return create_html_node = function(sKey = 'div') {
var classes, domElName, el, idName, ref, ref1, ref2;
domElName = ((ref = sKey.match(/^(h[1-6]|[^ #._0123456789]+)\d?/)) != null ? ref[1] : void 0) || 'div';
idName = (ref1 = sKey.match(/#[^ ]+/)) != null ? ref1[0].slice(1) : void 0;
classes = (ref2 = sKey.match(/\.[^ #.]+/g)) != null ? ref2.map(function(cStr) {
return cStr.slice(1);
}) : void 0;
// create el
el = document.createElement(domElName);
if (idName != null) {
el.id = idName;
}
if (classes != null ? classes.length : void 0) {
el.setAttribute('class', classes.join(' '));
}
return el;
};
// do @test = ->
// node = create_html_node('.jii.jaa')
// node.innerHTML = 'joopa joo'
// #edide.debug.txt '-'+node.className+'-'
return this;
}).call({}, edide);
//# sourceURL=create_html_node-20
"use strict";edide.node_from_obj = (function _node_from_obj (edide) {
// parses DocumentFragment (DOM node collection) from object
//# ATTRIBUTES
// DIFFERENT from jsonHtml
var allAttrActions, bindEvent, defaultAttrsMap, eventAttrsMap, iterate, node_from_obj, setAttribute, specialAttrsMap, stackDepth;
bindEvent = function(attrName, attrVal, node) {
var eventName;
eventName = attrName.toLowerCase().slice(2);
node.addEventListener(eventName, attrVal, false);
if (node.listeners == null) {
node.listeners = {};
}
if (node.listeners[attrName] != null) {
throw "Event system don't allow binding two events of same type to same node";
}
// well, it could, but 'listeners' only remeber last one of them
return node.listeners[eventName] = attrVal; //.bind(node)
};
setAttribute = function(attrName, attrVal, node) {
if (attrVal != null) {
return node.setAttribute(attrName, attrVal);
}
};
defaultAttrsMap = edide.object.fromArray(edide.HTML.standardAttrs, function() {
return setAttribute;
});
eventAttrsMap = edide.object.fromArray(edide.HTML.eventAttrs, function() {
return bindEvent;
});
specialAttrsMap = {
raw: (attrName, attrVal, node) => {
return node.innerHTML = attrVal;
},
node: (attrName, attrVal, node) => {
return node.appendChild(attrVal);
},
text: (attrName, attrVal, node) => {
if (typeof attrVal === 'function') {
return attrVal(node, attrName); // used with reactive
} else {
return node.textContent = attrVal;
}
},
styles: (attrName, attrVal, node) => {
return edide.stylesInline.set(node, attrVal); // attrVal is object with inline styles
}
};
allAttrActions = edide.object.merge(defaultAttrsMap, eventAttrsMap);
edide.object.merge(allAttrActions, specialAttrsMap);
//# PARSER
stackDepth = 0;
iterate = function(node, val) {
var attrName, i, key, len, nonStandard, subVal, tag;
if (val == null) {
return node;
}
if (stackDepth > 100) {
stackDepth = 0;
node_from_obj.error = {val, node};
throw Error("node_from_obj stack depth > 100; endless loop?");
}
stackDepth++;
if (typeof val === 'function') {
val = val(node);
if (val === node) { // it's common pattern to set (and return) node in some variable
return;
}
}
if (val instanceof Array) {
for (i = 0, len = val.length; i < len; i++) {
subVal = val[i];
iterate(node, subVal); //, data
}
} else if (val instanceof Node) {
node.appendChild(val);
} else if (typeof val === 'object') {
if (val.constructor !== Object) {
throw Error('only basic object allowed in jsonHTML');
}
// key is val when 1 argument
for (key in val) {
subVal = val[key];
if (allAttrActions[key] || (nonStandard = /^\w*[A-Z]/.test(key))) { // Why not /[A-Z]/ ?
if (node.setAttribute == null) {
throw new Error(`Can't set attributes ('${key}') for root list (${key})`);
}
if (nonStandard) {
attrName = key.replace(/[A-Z]/g, function(match, ind) {
return (edide.str.if(ind !== 0, '-')) + match.toLowerCase(); // TODO: drop \:str dependency; how has ifs worked before??
});
if (typeof subVal === 'function') {
subVal(node, attrName); // used with reactive
} else {
setAttribute(attrName, subVal, node);
}
nonStandard = null; // make sure this is re-evald when other attributes in same loop
} else {
allAttrActions[key](key, subVal, node);
}
} else if (key.match(/^me[0-9]?$/)) { // should this be dropped? (use array as parent instead)
iterate(node, subVal);
} else {
// "normal" key, create tag and iterate children
tag = edide.create_html_node(key);
iterate(tag, subVal);
node.appendChild(tag);
}
}
} else {
node.textContent = val;
}
stackDepth--;
return node;
};
// TODO: currently return must be the last expression
// for requiring this module to work...
return node_from_obj = function(tmplObj) {
var fragment;
// start iteration with empty fragment
stackDepth = 0;
fragment = iterate(document.createDocumentFragment(), tmplObj);
//if fragment.children.length is 1
//then fragment.children[0] # if only on
//else fragment.children
return fragment;
};
// OLD KEY CHECKING
// check for special key (attributes, me, render)
// if key[0] is '_' # attrName value
// console.warn "node_from_obj _ attributes will deprecate"
// unless node.setAttribute?
// throw new Error "Can't set attributes for root list (#{key})"
// attrName = key.slice 1
// if eventAttrs.indexOf(attrName) isnt -1
// node.addEventListener attrName, subVal, false
// else switch attrName
// when 'raw' then node.innerHTML = subVal
// else node.setAttribute attrName, subVal
return this;
}).call({}, edide);
//# sourceURL=node_from_obj-21
"use strict";edide.dom = (function _dom (edide) {Object.defineProperty(this, 'module_name', {value:'dom'});
// utility methods for manipulating DOM nodes
// deprecate?
this.addChilds = function(node, children) {
var child, i, len, results;
results = [];
for (i = 0, len = children.length; i < len; i++) {
child = children[i];
results.push(node.appendChild(child));
}
return results;
};
// deprecate?
this.getAttr = function(node, attrName) {
var val;
val = node.attributes.getNamedItem(attrName).value;
if (edide.str.parsesToNumber(val)) {
return parseFloat(val);
} else {
return val;
}
};
this.get = function(selector, parentEl = document) {
return parentEl.querySelector(selector);
};
this.getAll = function(selector, parentEl = document) {
return parentEl.querySelectorAll(selector);
};
// deprecate?
this.fragment = document.createDocumentFragment.bind(document);
this.fromStr = (htmLStr) => {
var div;
div = document.createElement('div');
div.innerHTML = htmLStr;
return document.createDocumentFragment(div.children[0]);
};
this.new = (nodeDef) => { //, props
if (typeof nodeDef === 'object') {
return edide.node_from_obj(nodeDef).childNodes[0];
} else {
return edide.create_html_node(nodeDef);
}
};
// return edide.node_from_obj nodeDef)
// el = nodeDef # document.createElement elType
// switch typeof props
// when 'string' then el.innerHTML = props
// when 'object' then edide.object.merge el, props if props
// el
// this is not very usefull.. mode elsewhere?
this.append = this.addTo = this.appendTo = function(parent_element, content) {
if (typeof content === 'object' && !(content instanceof Node)) {
content = edide.node_from_obj(content);
}
return parent_element.appendChild(content);
};
// this, though, is more useful
this.prepend = function(parentEl, content) {
if (typeof content === 'object') {
content = edide.node_from_obj(content);
}
return parentEl.insertBefore(content, parentEl.firstChild);
};
this.after = (ref, newNode) => {
return ref.parentNode.insertBefore(edide.node_from_obj(newNode), ref.nextSibling);
};
this.before = (ref, newNode) => {
return ref.parentNode.insertBefore(edide.node_from_obj(newNode), ref);
};
this.wrap = (node, tagStr) => {
var wrapper;
wrapper = edide.create_html_node(tagStr);
node.parentNode.insertBefore(wrapper, node);
wrapper.appendChild(node);
return wrapper;
};
// IE supported way of removing element
// (for chrome, firefox: el.remove())
this.remove = function(element) {
var parentEl;
if (typeof element === 'string') {
element = this.get(element);
}
if ((parentEl = element != null ? element.parentElement : void 0) != null) {
return parentEl.removeChild(element);
} else {
return console.info("failed to remove node", element);
}
};
this.removeChildren = (node) => {
while (node.firstChild) {
node.removeChild(node.firstChild);
}
};
// TODO: this should be in \:render modulein
this.render = function(node, htmlObj) {
console.warn(":dom.render will deprecate");
this.removeChildren(node);
return node.appendChild(edide.node_from_obj(htmlObj));
};
// TODO deprecate @replaceChilds
this.replaceChildren = this.replaceChilds = function(node, newContent) {
edide.assert(node instanceof Element, 'requires DOM node');
this.removeChildren(node);
return this.append(node, newContent);
};
this.replace = function(oldEl, newEl) {
var parentEl;
if (typeof newEl === 'object') {
newEl = edide.node_from_obj(newEl);
}
if ((parentEl = oldEl.parentElement) != null) {
parentEl.replaceChild(newEl, oldEl); // returns oldEl..
} else {
console.info("failed to replace node", newEl, oldEl);
}
return newEl; // don't work when newEl was object, since documentFragment will be empty
};
return this;
}).call({}, edide);
//# sourceURL=dom-22
"use strict";edide.reactiveEl = (function _reactiveEl (edide) {
// Combines \:node_from_obj with reactive \:var's
// TODO
// - can this be made to work also on attribute level??
// - drop dependency to \:dom?
var reactiveEl;
return reactiveEl = (contentFunc) => {
if (typeof contentFunc === 'string') {
return reactiveEl(() => {
return edide.var(contentFunc);
});
}
contentFunc.type = 'dom'; // for debugging
return (node, attrName) => {
var setter;
setter = () => {
var content;
content = contentFunc(node);
if (attrName != null) {
if (attrName === 'text') {
node.textContent = content;
} else {
node.setAttribute(attrName, content);
}
return;
}
switch (typeof content) {
case 'string':
node.textContent = content;
break;
case 'object':
edide.dom.replaceChildren(node, content);
}
return node;
};
setter.type = `dom ${(attrName ? 'attr' : 'node') // for graph debugging
}`;
return edide.var(setter);
};
};
return this;
}).call({}, edide);
//# sourceURL=reactiveEl-23
"use strict";edide.reactive = (function _reactive (edide) {
// TODO replace use of edide.var with own methods
// revar -> rea, revar .. ?
// unvar vai offvar ?
return (initialVars = {}) => {
var dom, handler, id, key, react, revar, todoMap, unvar, val;
id = edide.str.random();
handler = {
get: (map, prop) => {
var ref;
if ((ref = edide.editorModule) != null ? ref.editor_inspector.inspectingNow : void 0) {
console.log('IN inspector? Find out is it possible to end up here form inside setter');
return edide.var.values.get(`${id}.${prop}`);
}
return edide.var(`${id}.${prop}`);
},
set: (map, prop, value) => {
edide.var(`${id}.${prop}`, value);
return true; // Proxy set must return true if set is successfull; In the future use Reflect.set, which returns true automatically?
}
};
//ownKeys: (a, b) => ['foo', 'bar']
revar = new Proxy((todoMap = new Map), handler); // NOTE: map is not used yet
// stat = static
// TODO: figure revar, stat naming
unvar = new Proxy(todoMap, {
get: (map, prop) => {
return edide.var.values.get(`${id}.${prop}`);
},
set: (map, prop, value) => {
return edide.var.values.set(`${id}.${prop}`, value);
}
});
// TODO: can initial revar be made "lazy" (would allow setter function in them)
for (key in initialVars) {
val = initialVars[key];
revar[key] = val;
}
dom = (content) => {
if (typeof content === 'string') {
content = `${id}.${content}`;
}
return edide.reactiveEl(content);
};
react = (nameOrFunc, func) => {
if (func != null) {
func.type = nameOrFunc;
} else {
func = nameOrFunc;
func.type = 'react'; // for debugging
}
return edide.var(func);
};
return {revar, unvar, dom, react};
};
return this;
}).call({}, edide);
//# sourceURL=reactive-24
"use strict";edide.addEventListener = (function _addEventListener (edide) {
// Bind event to dom element so, that it will be removed on unload
// Define module when not executed on module init (synchronously)
return (element, eventName, action, module) => {
var remove;
element.addEventListener(eventName, action);
edide.unload.add(module, remove = () => {
return element.removeEventListener(eventName, action);
});
return remove;
};
return this;
}).call({}, edide);
//# sourceURL=addEventListener-25
"use strict";edide.mmState = (function _mmState (edide) {Object.defineProperty(this, 'module_name', {value:'mmState'});
var defaults, previous, ref, storeProps, storeState;
this.lsKey = 'musicmakersState';
defaults = {
playing: false,
recorderOn: false,
sheet: '',
diffText: '',
note: null, // currently playing note
// sliders
bpm: 400, // -> beatDelay
//distortion: 0
blur: 0,
itch: 0,
//reverb: 1
// dropdowns
//instrumentInd: 5 # should match electric guitar
instrument: 'guitar-electric',
scale: 'pentatonicMinor',
highlight: null,
keyboardInd: 0 // TODO --> keyboard
};
storeProps = edide.set('bpm', 'distortion', 'lowpass', 'sheet', 'scale', 'instrument', 'keyboardInd');
previous = JSON.parse((ref = localStorage.getItem(this.lsKey)) != null ? ref : '{}');
({dom: this.dom, react: this.react, revar: this.revar, unvar: this.unvar} = edide.reactive(Object.assign({}, defaults, previous)));
// TODO: add state versioning to reset it when critical changes are made
storeState = () => {
var state;
state = {};
edide.var.values.forEach((val, key) => {
if (typeof key === 'string') {
key = key.split('.')[1];
if (storeProps.has(key)) {
return state[key] = val;
}
}
});
return localStorage.setItem(this.lsKey, JSON.stringify(state));
};
edide.unload.add(storeState);
edide.addEventListener(window, 'beforeunload', storeState);
this.resetStorage = () => {
var key, val;
localStorage.removeItem(this.lsKey);
for (key in defaults) {
val = defaults[key];
edide.logProd(key, val);
this.revar[key] = val;
}
};
return this;
}).call({}, edide);
//# sourceURL=mmState-26
"use strict";edide.musicScales = (function _musicScales (edide) {Object.defineProperty(this, 'module_name', {value:'musicScales'});
this.full = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
this.scaleSteps = {
// rock
// 0, 3, 2, 2, 3, (2)
pentatonicMinor: [
0,
3,
2,
2,
3 // hidden 2
],
//pentatonicMajor: ['C, D, E, G, A']
// blues: minor penta +
// whole – whole – half – whole – whole – whole – half
naturalMajor: [
0,
2,
2,
1,
2,
2,
2 // hidden to beginning: 1
],
// whole – half – whole – whole – half – whole – whole
naturalMinor: [
0,
2,
1,
2,
2,
1,
2 // hidden to beginning: 2
]
};
// http://whatmusicreallyis.com/papers/sacred_sounds_scale.html
this.get = (base, scale) => {
var i, ind, len, notes, ref, step;
notes = [];
ind = this.full.indexOf(base);
ref = this.scaleSteps[scale];
for (i = 0, len = ref.length; i < len; i++) {
step = ref[i];
ind += step;
if (ind >= 12) {
ind -= 12;
}
notes.push(this.full[ind]);
}
return notes;
};
this.triadSteps = {
major: [
0,
4,
3 // positive valence
],
minor: [0, 3, 4]
};
// M = major triad
// m = minor triar
// i = number of (half) steps from first triad to second
// (source: https://www.youtube.com/watch?v=YSKAt3pmYBs)
this.triadCombinations = {
protagonism: 'M2M',
outerSpace: 'M6M',
fantastical: 'M8M',
sadness: 'M4m',
romantic: 'M5m', // and middle eastern
wonder: 'm5M', // and trancendence
mystery: 'm2M', // and dark comedy
dramatic: 'm11M',
antagonismDanger: 'm6m', // less character based
antagonismEvil: 'm8m' // cahracter based
};
return this;
}).call({}, edide);
//# sourceURL=musicScales-27
"use strict";edide.rootElement = (function _rootElement (edide) {Object.defineProperty(this, 'module_name', {value:'rootElement'});
// Root DOM container to render content in
if (edide.inEditor) {
if (this.node == null) {
this.node = document.createElement('div');
}
this.node.id = 'right_side';
this.selector = '#' + this.node.id;
} else {
this.selector = 'body';
this.node = document.querySelector(this.selector);
}
//if edide.inEditor
//then edide.editorModule?.render_editor.on 'rendered', @init
//else @init()
return this;
}).call({}, edide);
//# sourceURL=rootElement-28
"use strict";edide.randomId = (function _randomId (edide) {
return function() {
return Math.random().toString().substr(2);
};
return this;
}).call({}, edide);
//# sourceURL=randomId-29
"use strict";edide.isModule = (function _isModule (edide) {
return function(maybeModule) {
return typeof (maybeModule != null ? maybeModule.module_name : void 0) === 'string';
};
return this;
}).call({}, edide);
//# sourceURL=isModule-30
"use strict";edide.coffee_styles = (function _coffee_styles (edide) {Object.defineProperty(this, 'module_name', {value:'coffee_styles'});
// ups to James Campos for original idea: https://github.com/aeosynth/ccss
this.styleIdPostfix = '--styles';
// TODO: move this to \:styles to allow adding CSS styles without this dependency
this.addStyles = function(el_id, rules) {
var cssStr, styleEl;
if (typeof window === "undefined" || window === null) {
return console.error("Trying to create StyleSheet rules on server side!");
}
if (arguments.length === 1) {
rules = el_id;
el_id = 'main';
}
// add styles post fix, since often the same id is used as with the component it styles
el_id = el_id + this.styleIdPostfix;
if (typeof rules === 'function') { //then rules.call(@helpers) else rules
rules = rules();
}
this.stack = [];
cssStr = typeof rules === 'object' ? this.compile(rules) : rules;
styleEl = document.getElementById(el_id);
if (styleEl == null) {
styleEl = document.createElement('style');
styleEl.id = el_id;
document.head.appendChild(styleEl);
}
if (el_id === 'main_styles') {
styleEl.innerHTML += cssStr;
} else {
styleEl.innerHTML = cssStr;
}
return styleEl;
};
this.compile = function(rulesObj) { // , styleSheet
var childRules, childSelector, children, combineStr, cssStr, declarations, firstChar, i, j, key, len, len1, me, meRules, mixin, nested, newCSS, parentSelector, ref, ref1, selector, val, value;
if (this.stack.indexOf(rulesObj) !== -1 || this.stack.length === 100) {
console.warn('@stack', this.stack);
throw Error("Endless stack ccss.compile_to_str!");
}
this.stack.push(rulesObj);
cssStr = '';
for (selector in rulesObj) {
childRules = rulesObj[selector];
declarations = '';
nested = {};
// media queries TODO: implement also in jsonCss
if (selector.slice(0, 1) === '@') {
cssStr += selector + ' { \n';
cssStr += this.compile(childRules);
return cssStr + '}\n';
}
// merge mixin(s)
// DEPRECATE mixin -> me
while ((childRules != null ? childRules.mixin : void 0) || (childRules != null ? childRules.me : void 0)) {
({mixin, me} = childRules);
childRules.mixin = null;
childRules.me = null;
meRules = Object.assign({}, mixin, me);
for (key in meRules) {
val = meRules[key];
if (childRules[key] == null) {
childRules[key] = val; // mixins don't overwrite existing definitions
}
}
}
// umm.. should have "childRules = childRules?.me" here for while to work..?
//a pair is either a css declaration, or a nested rule
for (key in childRules) {
value = childRules[key];
if (typeof value === 'object') {
children = [];
ref = key.split(/\s*,\s*/);
for (i = 0, len = ref.length; i < len; i++) {
childSelector = ref[i];
ref1 = selector.split(/\s*,\s*/);
for (j = 0, len1 = ref1.length; j < len1; j++) {
parentSelector = ref1[j];
firstChar = childSelector.slice(0, 1);
combineStr = (function() {
switch (firstChar) {
case ':':
return '';
case '&':
childSelector = childSelector.slice(1);
return '';
default:
return ' ';
}
})();
children.push(parentSelector + combineStr + childSelector);
}
}
nested[children.join(',')] = value;
} else {
declarations += edide.stylesUtils.create_property_string(key, value);
}
}
if (declarations.length) {
newCSS = `${selector} {\n${declarations}}\n`;
try {
cssStr += newCSS;
} catch (error) {
console.log("failed with ", newCSS);
return;
}
}
cssStr += this.compile(nested); //, styleSheet
}
return cssStr;
};
return this;
}).call({}, edide);
//# sourceURL=coffee_styles-31
"use strict";edide.styles = (function _styles (edide) {Object.defineProperty(this, 'module_name', {value:'styles'});
// LOAD HANDLER
this.addedStyles = edide.keep({});
// scope styles with ID of given module's name
this.addScoped = function(module, stylesObj) {
stylesObj = {
[`#${module.module_name}`]: stylesObj
};
return this.add(module, stylesObj);
};
this.addRoot = function(stylesObj) {
return this.add({
[`${edide.rootElement.selector}`]: stylesObj
});
};
this.editorSelector = "#editor_top, #left_side, #popup-windows";
this.addEditor = (stylesObj) => {
return this.add({
[`${this.editorSelector}`]: stylesObj
});
};
this.addProd = (stylesObj) => {
if (edide.inEditor) {
return;
}
return this.add(stylesObj);
};
this.add = function(modOrId, jsonCss) {
var id, unload;
if (arguments.length === 1) {
jsonCss = modOrId;
id = 's' + edide.randomId();
} else if (edide.isModule(modOrId)) {
id = modOrId.module_name;
} else if (typeof modOrId === 'string') {
id = modOrId;
unload = false; // !! to disable unloading, provide string ID
} else {
throw Error("invalid arguments to styles");
}
if (unload == null) {
unload = true;
}
this.addedStyles[id] = edide.coffee_styles.addStyles(id, jsonCss);
if (unload) {
return edide.unload.add(() => {
return this.remove(id);
});
}
};
this.addRoot = function(jsonCss) {
jsonCss = { // > *
[`${(edide.inEditor ? '#right_side' : 'body')}`]: jsonCss
};
return this.add(jsonCss);
};
this.parseNode = function(dom_element_style_definitions) {};
this.clear = function() { // umm, this isn't very usefull
var idStr, results;
results = [];
for (idStr in this.addedStyles) {
results.push(this.remove(idStr));
}
return results;
};
// @remove DOM style elements from head
this.remove = (idStr) => { // idStr == parent module name
var i, len, ref, styleEl;
if (!idStr) {
return;
}
ref = document.querySelectorAll(`head #${idStr}${edide.coffee_styles.styleIdPostfix}`);
for (i = 0, len = ref.length; i < len; i++) {
styleEl = ref[i];
edide.dom.remove(styleEl);
}
return delete this.addedStyles[idStr];
};
return this;
}).call({}, edide);
//# sourceURL=styles-32
"use strict";edide.yesOrNull = (function _yesOrNull (edide) {
// Used with dom attributes
// '' => attribute exists (without value)
// null => attribute don't exist
return (truthy) => {
if (truthy) {
return '';
} else {
return null;
}
};
return this;
}).call({}, edide);
//# sourceURL=yesOrNull-33
"use strict";edide.mathOp = (function _mathOp (edide) {Object.defineProperty(this, 'module_name', {value:'mathOp'});
this.sum = function(a, b) {
return a + b;
};
this.multiply = function(a, b) {
return a * b;
};
return this;
}).call({}, edide);
//# sourceURL=mathOp-34
"use strict";edide.mmScales = (function _mmScales (edide) {Object.defineProperty(this, 'module_name', {value:'mmScales'});
// settings
var dom, revar, scales, unvar;
scales = Object.keys(edide.musicScales.scaleSteps);
({revar, unvar, dom} = edide.mmState);
//revar.scale = => scales[revar.scaleInd]
revar.scaleSteps = () => {
return edide.musicScales.scaleSteps[revar.scale];
};
edide.styles.add({
'.notes': {
columnWidth: '4em'
}
});
// TODO: change to name (not index) based, like instrument dropdown
this.dropdown = dom(() => {
return {
select: (el) => {
var scale;
({scale} = revar);
return {
styles: {
marginTop: '1em'
},
me: scales.map((item, ind) => {
return {
option: {
text: item,
//value: ind
selected: edide.yesOrNull(item === scale)
}
};
}),
onChange: (ev) => {
return revar.scale = ev.target.value;
}
};
}
};
});
this.render = (node) => {
return edide.dom.replaceChilds(node, {
'.steps': dom(() => {
var steps;
steps = revar.scaleSteps.slice(1);
steps.push(12 - steps.reduce(edide.mathOp.sum));
return {
div: {
text: steps.map((step) => {
return '+' + step;
}).join(' '),
styles: {
margin: '0.5em 0'
}
}
};
})
});
};
return this;
}).call({}, edide);
//# sourceURL=mmScales-35
"use strict";edide.noteFreq = (function _noteFreq (edide) {Object.defineProperty(this, 'module_name', {value:'noteFreq'});
var a4;
this.notes = [
['C0',
16.35,
2109.89],
[
'C#0',
17.32,
1991.47 // /Db0
],
['D0',
18.35,
1879.69],
[
'D#0',
19.45,
1774.20 // /Eb0
],
['E0',
20.60,
1674.62],
['F0',
21.83,
1580.63],
[
'F#0',
23.12,
1491.91 // /Gb0
],
['G0',
24.50,
1408.18],
[
'G#0',
25.96,
1329.14 // /Ab0
],
['A0',
27.50,
1254.55],
[
'A#0',
29.14,
1184.13 // /Bb0
],
['B0',
30.87,
1117.67],
['C1',
32.70,
1054.94],
[
'C#1',
34.65,
995.73 // /Db1
],
['D1',
36.71,
939.85],
[
'D#1',
38.89,
887.10 // /Eb1
],
['E1',
41.20,
837.31],
['F1',
43.65,
790.31],
[
'F#1',
46.25,
745.96 // /Gb1
],
['G1',
49.00,
704.09],
[
'G#1',
51.91,
664.57 // /Ab1
],
['A1',
55.00,
627.27],
[
'A#1',
58.27,
592.07 // /Bb1
],
['B1',
61.74,
558.84],
['C2',
65.41,
527.47],
[
'C#2',
69.30,
497.87 // /Db2
],
['D2',
73.42,
469.92],
[
'D#2',
77.78,
443.55 // /Eb2
],
['E2',
82.41,
418.65],
['F2',
87.31,
395.16],
[
'F#2',
92.50,
372.98 // /Gb2
],
['G2',
98.00,
352.04],
[
'G#2',
103.83,
332.29 // /Ab2
],
['A2',
110.00,
313.64],
[
'A#2',
116.54,
296.03 // /Bb2
],
['B2',
123.47,
279.42],
['C3',
130.81,
263.74],
[
'C#3',
138.59,
248.93 // /Db3
],
['D3',
146.83,
234.96],
[
'D#3',
155.56,
221.77 // /Eb3
],
['E3',
164.81,
209.33],
['F3',
174.61,
197.58],
[
'F#3',
185.00,
186.49 // /Gb3
],
['G3',
196.00,
176.02],
[
'G#3',
207.65,
166.14 // /Ab3
],
['A3',
220.00,
156.82],
[
'A#3',
233.08,
148.02 // /Bb3
],
['B3',
246.94,
139.71],
['C4',
261.63,
131.87],
[
'C#4',
277.18,
124.47 // /Db4
],
['D4',
293.66,
117.48],
[
'D#4',
311.13,
110.89 // /Eb4
],
['E4',
329.63,
104.66],
['F4',
349.23,
98.79],
[
'F#4',
369.99,
93.24 // /Gb4
],
['G4',
392.00,
88.01],
[
'G#4',
415.30,
83.07 // /Ab4
],
['A4',
440.00,
78.41],
[
'A#4',
466.16,
74.01 // /Bb4
],
['B4',
493.88,
69.85],
['C5',
523.25,
65.93],
[
'C#5',
554.37,
62.23 // /Db5
],
['D5',
587.33,
58.74],
[
'D#5',
622.25,
55.44 // /Eb5
],
['E5',
659.25,
52.33],
['F5',
698.46,
49.39],
[
'F#5',
739.99,
46.62 // /Gb5
],
['G5',
783.99,
44.01],
[
'G#5',
830.61,
41.54 // /Ab5
],
['A5',
880.00,
39.20],
[
'A#5',
932.33,
37.00 // /Bb5
],
['B5',
987.77,
34.93],
['C6',
1046.50,
32.97],
[
'C#6',
1108.73,
31.12 // /Db6
],
['D6',
1174.66,
29.37],
[
'D#6',
1244.51,
27.72 // /Eb6
],
['E6',
1318.51,
26.17],
['F6',
1396.91,
24.70],
[
'F#6',
1479.98,
23.31 // /Gb6
],
['G6',
1567.98,
22.00],
[
'G#6',
1661.22,
20.77 // /Ab6
],
['A6',
1760.00,
19.60],
[
'A#6',
1864.66,
18.50 // /Bb6
],
['B6',
1975.53,
17.46],
['C7',
2093.00,
16.48],
[
'C#7',
2217.46,
15.56 // /Db7
],
['D7',
2349.32,
14.69],
[
'D#7',
2489.02,
13.86 // /Eb7
],
['E7',
2637.02,
13.08],
['F7',
2793.83,
12.35],
[
'F#7',
2959.96,
11.66 // /Gb7
],
['G7',
3135.96,
11.00],
[
'G#7',
3322.44,
10.38 // /Ab7
],
['A7',
3520.00,
9.80],
[
'A#7',
3729.31,
9.25 // /Bb7
],
['B7',
3951.07,
8.73],
['C8',
4186.01,
8.24],
[
'C#8',
4434.92,
7.78 // /Db8
],
['D8',
4698.63,
7.34],
[
'D#8',
4978.03,
6.93 // /Eb8
],
['E8',
5274.04,
6.54],
['F8',
5587.65,
6.17],
[
'F#8',
5919.91,
5.83 // /Gb8
],
['G8',
6271.93,
5.50],
[
'G#8',
6644.88,
5.19 // /Ab8
],
['A8',
7040.00,
4.90],
[
'A#8',
7458.62,
4.63 // /Bb8
],
['B8',
7902.13,
4.37]
];
this.findNote = (name) => {
var ind;
ind = this.notes.findIndex((arr) => {
return arr[0] === name;
});
if (ind === -1) {
return edide.logProd(`can't find: ${name}`);
}
return [ind, name, this.notes[ind][1]];
};
a4 = this.findNote('A4');
this.diffToA4 = (name) => {
var note;
note = this.findNote(name);
return note[0] - a4[0];
};
this.diff = (n1, n2) => {
return this.findNote(n2)[0] - this.findNote(n1)[0];
};
return this;
}).call({}, edide);
//# sourceURL=noteFreq-36
"use strict";edide.mmKeyboard = (function _mmKeyboard (edide) {Object.defineProperty(this, 'module_name', {value:'mmKeyboard'});
var A, a, char, chari, i, j, keyboards, len, len1, noncaps, qwertyChar, qwertyRows, revar, row, rowi, space, unvar;
({revar, unvar} = edide.mmState);
edide.mmScales; // defines revar.scaleSteps
this.special = {
rest: '.',
long: '=',
comment: '#',
var: ':',
confStart: '{',
confEnd: '}'
};
this.specialKeyCodes = new Set(Object.values(this.special).map((s) => {
return s.charCodeAt(0);
}));
this.specialChars = new Set(Object.values(this.special));
this.isPauseKey = (keyCode) => {
return this.specialKeyCodes.has(keyCode);
};
this.isSpecialChar = (char) => {
return this.specialChars.has(char);
};
this.isPauseChar = this.isSpecialChar; // not really...
keyboards = ['qwerty', 'abc'];
this.render = () => {
var ind, keyboard;
return {
select: {
onChange: (ev) => {
return revar.keyboardInd = parseInt(ev.target.value);
},
me: (function() {
var i, len, results;
results = [];
for (ind = i = 0, len = keyboards.length; i < len; ind = ++i) {
keyboard = keyboards[ind];
results.push({
option: {
value: ind,
text: keyboard,
selected: edide.yesOrNull(ind === revar.keyboardInd)
}
});
}
return results;
})()
}
};
};
a = 'a'.charCodeAt(0);
A = 'A'.charCodeAt(0);
space = ' '.charCodeAt(0);
// ABC -> abc
this.isCaps = (key) => {
return A <= key && key < a;
};
this.capsDiff = a - A;
noncaps = (key) => {
if (this.isCaps(key)) {
return key + this.capsDiff;
} else {
return key;
}
};
// TODO PERF calc and cache already on instrument/scale/keyboard change
this.getNoteInd = (key) => {
var maxInstrumentNoteInd, noteBaseInd, noteInd, notes, startNote, step;
({startNote, notes, step} = revar.instrumentConf);
noteBaseInd = edide.noteFreq.findNote(startNote)[0];
noteInd = this[keyboards[revar.keyboardInd]](noncaps(key), noteBaseInd);
maxInstrumentNoteInd = noteBaseInd + notes * step;
//edide.console.sparse noteInd
while (noteInd > maxInstrumentNoteInd) {
noteInd -= 2 * 12;
}
return noteInd;
};
// ABC
this.abc = (key, baseInd) => {
var fromLowest, noteInd, stepsFromClosestOctave;
fromLowest = key - a;
// if true # wrap is 'maxNote'
// # This is BS; wrapLimit should be (notes*step) and then taken
// wrapLimit = revar.instrumentConf.notes + 1
// fromLowest -= wrapLimit if fromLowest >= wrapLimit # if -> while if one drop is not enough
stepsFromClosestOctave = fromLowest % revar.scaleSteps.length;
noteInd = 0;
noteInd += revar.scaleSteps.slice(0, +stepsFromClosestOctave + 1 || 9e9).reduce(edide.mathOp.sum);
// unless wrap is 'octave'
noteInd += 12 * Math.floor(fromLowest / revar.scaleSteps.length);
return baseInd + noteInd;
};
// QWERTY
qwertyRows = ['1234567890', 'qwertyuiop', 'asdfghjkl', 'zxcvbnm'];
qwertyChar = {};
for (rowi = i = 0, len = qwertyRows.length; i < len; rowi = ++i) {
row = qwertyRows[rowi];
for (chari = j = 0, len1 = row.length; j < len1; chari = ++j) {
char = row[chari];
qwertyChar[char.charCodeAt(0)] = [rowi, chari];
}
}
this.qwerty = (key, baseInd) => {
var charSteps, halfSteps, noteInd, octave, rowchar;
if (!(rowchar = qwertyChar[key])) {
return;
}
[row, char] = rowchar;
octave = qwertyRows.length - 1 - row + Math.floor(char / unvar.scaleSteps.length);
char = char % revar.scaleSteps.length;
charSteps = revar.scaleSteps.slice(0, +char + 1 || 9e9).reduce((a, b) => {
return a + b;
});
halfSteps = 12 * octave + charSteps;
return noteInd = baseInd + halfSteps;
};
//noteBaseInd = edide.noteFreq.findNote(revar.instrumentConf.startNote)[0]
//edide.setTimeout => @qwerty 'y'.charCodeAt 0
return this;
}).call({}, edide);
//# sourceURL=mmKeyboard-37
"use strict";edide.mmNote = (function _mmNote (edide) {Object.defineProperty(this, 'module_name', {value:'mmNote'});
// TODO: move some of the edide.mmKeyboard.getNoteInd stuff here
this.fromChar = (char) => {
return this.fromKeyCode(char.charCodeAt(0));
};
// returns 'true' when special
this.fromKeyCode = (key) => {
var noteInd, ref;
if (typeof (noteInd = edide.mmKeyboard.getNoteInd(key)) === 'number') {
return (ref = edide.noteFreq.notes[noteInd]) != null ? ref[0] : void 0;
}
};
return this;
}).call({}, edide);
//# sourceURL=mmNote-38
"use strict";edide.new = (function (edide) {
// REFACTOR to \:clone ?
return function(...objects) {
if (Array.isArray(objects[0])) {
return Object.assign([], ...objects);
} else {
return Object.assign({}, ...objects);
}
};
return this;
}).call({}, edide);
//# sourceURL=new-39
"use strict";edide.mmConfigs = (function _mmConfigs (edide) {Object.defineProperty(this, 'module_name', {value:'mmConfigs'});
var defaultVars, mutatingProp, mutatingVars, vars;
vars = {}; // varName: config object
mutatingVars = {};
this.hasVar = (varName) => {
var ref;
return !!((ref = vars[varName]) != null ? ref : mutatingVars[varName]);
};
this.activateVar = (name, value) => {
var configs;
if (value != null) {
configs = edide.new(mutatingVars[name]);
edide.assert(configs != null, "giving value, but mutating variable not found");
if (edide.str.parsesToNumber(value)) {
value = parseFloat(value);
}
configs[mutatingProp(configs)] = value;
return this.activate(configs);
} else {
return this.activate(vars[name]);
}
};
mutatingProp = (configs) => {
var name, val;
for (name in configs) {
val = configs[name];
if (val === '*') {
return name;
}
}
return false;
};
this.activate = (conf) => {
if (conf.name != null) {
return; // throw warning?
}
return Object.assign(edide.mmState.revar, conf);
};
this.addVar = (varName, config) => { // , activate=true
if (mutatingProp(config)) {
return mutatingVars[varName] = config;
} else {
return vars[varName] = config;
}
};
//@activateVar varName if activate # shold config be activated by default (when "name" given)?
defaultVars = {
bass: {
"instrument": "bass-electric"
},
cello: {
"instrument": "cello"
},
guitar: {
"instrument": "guitar-acoustic"
},
eguitar: {
"instrument": "guitar-electric"
},
piano: {
"instrument": "piano"
},
synth: {
"instrument": "synth-simple"
},
xylophone: {
"instrument": "xylophone"
},
pentatonic: {
"scale": "pentatonicMinor"
},
major: {
"scale": "naturalMajor"
},
minor: {
"scale": "naturalMinor"
}
};
//dist: { }
this.init = () => {
var conf, name, results;
vars = {};
results = [];
for (name in defaultVars) {
conf = defaultVars[name];
results.push(this.addVar(name, conf, false));
}
return results;
};
this.init();
return this;
}).call({}, edide);
//# sourceURL=mmConfigs-40
"use strict";edide.edideConstants = (function _edideConstants (edide) {Object.defineProperty(this, 'module_name', {value:'edideConstants'});
// module special names
var TEST_DEPS_ID = this.TEST_DEPS_ID = '*test'
var CURRENT_DEPS_ID = this.CURRENT_DEPS_ID = '*currently-edited'
var TOP_DEPS_ID = this.TOP_DEPS_ID = '*top-dependency'
var RECOVERY_ERROR_KEY = this.RECOVERY_ERROR_KEY = 'recoveryModeError'
var RECOVERY_PATH = this.RECOVERY_PATH = '/recoveryMode'
var FORCE_NO_RECOVERY = this.FORCE_NO_RECOVERY = '/forceNoRecovery'
var NAMESPACE = this.NAMESPACE = 'edide'
// make accessible to db modules:
if (typeof serverModule != 'undefined')
serverModule.constants = { TEST_DEPS_ID, CURRENT_DEPS_ID, TOP_DEPS_ID, NAMESPACE }
return this;
}).call({}, edide);
//# sourceURL=edideConstants-41
"use strict";edide.showError = (function _showError (edide) {
var showError;
showError = (err) => {
if (edide.inEditor) {
return edide.editorModule.editor_error.show(err);
} else if (typeof edide.global.require === 'object' && (edide.global[edide.edideConstants.NAMESPACE].prodErrorPrinter != null)) {
return edide.global[edide.edideConstants.NAMESPACE].prodErrorPrinter.showError(err);
} else {
return console.error(err);
}
};
return (err) => {
var error;
if (err != null ? err.stack : void 0) {
return showError(err); // create error to capture stack trace
} else {
try {
throw Error(err);
} catch (error1) {
error = error1;
return showError(error);
}
}
};
return this;
}).call({}, edide);
//# sourceURL=showError-42
"use strict";edide.mmParserSpecial = (function _mmParserSpecial (edide) {Object.defineProperty(this, 'module_name', {value:'mmParserSpecial'});
// parse config { .. } and variable : .. : syntaxes
this.config = (trackStr, ts = {}) => {
var endInd, err, name;
endInd = trackStr.search('}') || trackStr.length;
try {
ts.conf = JSON.parse(trackStr.slice(0, +endInd + 1 || 9e9));
if (ts.conf.name != null) {
({name} = ts.conf);
delete ts.conf.name;
edide.mmConfigs.addVar(name, ts.conf);
} else {
edide.mmConfigs.activate(ts.conf); // add variable if exists
}
} catch (error) {
//Object.assign edide.mmState.revar, conf
err = error;
ts.skip = true; // could be used to show error highlighting in editor
edide.showError(err); // remove this if error highlighting implemented
}
return endInd;
};
// parse variable from curren track row
// returns false if parsing fails
this.var = (track, trackState) => {
var i, value, varLength, varName, varStr;
({i} = trackState);
varLength = track.slice(i + 1).indexOf(edide.mmKeyboard.special.var);
if (varLength === -1) {
return false;
}
varStr = track.slice(i + 1, +(i + varLength) + 1 || 9e9);
[varName, value] = varStr.split(' ');
if (!edide.mmConfigs.hasVar(varName)) {
return false;
}
edide.mmConfigs.activateVar(varName, value);
trackState.i += varLength + 2;
return true;
};
return this;
}).call({}, edide);
//# sourceURL=mmParserSpecial-43
"use strict";edide.mmPipe = (function _mmPipe (edide) {Object.defineProperty(this, 'module_name', {value:'mmPipe'});
var dist, lowpass, react, revar, reverber, unvar;
({revar, unvar, react} = edide.mmState);
dist = lowpass = reverber = null;
this.initPipe = () => {
edide.assert(!lowpass, "pipe already initialized");
lowpass = new Tone.Filter(unvar.lowpass, 'lowpass', -12);
dist = new Tone.Distortion(unvar.distortion);
this.output = lowpass;
lowpass.toMaster();
dist.connect(lowpass);
//dist.distortion = parseFloat unvar.distortion
//reverber = new Tone.Freeverb 0.7, 3000 #(revar.reverb)
//reverber.decay = revar.reverb
//dist.connect(reverber)
//reverber.connect(dist)
revar.pipeReady = true;
return edide.unload.add(() => {
if (dist != null) {
if (typeof dist.dipose === "function") {
dist.dipose();
}
}
return lowpass != null ? typeof lowpass.dispose === "function" ? lowpass.dispose() : void 0 : void 0;
});
};
this.initInstrument = (instrument) => {
instrument.connect(dist);
edide.unload.add(() => {
return instrument != null ? instrument.disconnect() : void 0;
});
// else
// instrument.toMaster()
// @output = instrument
// reverber?.dispose()
//Tone.Master.input.disconnect() # can't be reconnected?
return instrument;
};
react('pipe distortion', () => {
var ref;
revar.distortion;
revar.lowpass;
//return unless dist?.context?
if (dist != null) {
dist.distortion = revar.distortion;
}
return lowpass != null ? (ref = lowpass.frequency) != null ? ref.linearRampTo(revar.lowpass, 0) : void 0 : void 0;
});
//if reverber?.context?
//reverber.decay = reverb
return this;
}).call({}, edide);
//# sourceURL=mmPipe-44
"use strict";edide.code = (function _code (edide) {
// dependency front for serverModule: code
return edide.global.serverModule && edide.global.serverModule.code
return this;
}).call({}, edide);
//# sourceURL=code-45
"use strict";edide.modules = (function _modules (edide) {
// dependency front for serverModule 'modules'
var me;
if (!edide.inEditor) {
return {};
}
me = serverModule.modules;
// TODO: \:moduleCache(?) and move there
// and combive with code.cache
this.listUnsaved = function() {
var key, unsaved, val;
unsaved = [];
for (key in localStorage) {
val = localStorage[key];
if (key.slice(0, edide.code.cache.pre_str.length) === edide.code.cache.pre_str) {
unsaved.push(key.slice(edide.code.cache.pre_str.length));
}
}
return unsaved;
};
Object.assign(me, this);
return me;
return this;
}).call({}, edide);
//# sourceURL=modules-46
"use strict";edide.rejectIfRecompiled = (function _rejectIfRecompiled (edide) {
// Also rejects on root module change
if (!edide.inEditor) {
return;
}
return (promise) => {
var recompiled, rootModuleFunc, rootName;
({rootName} = edide.moduleGate);
recompiled = false;
edide.editorModule.editor_events.on('before_recompile', () => {
return recompiled = true;
});
rootModuleFunc = edide.modules.moduleFunc[rootName];
return promise.then(function(arg) {
if (recompiled || rootName !== edide.moduleGate.rootName) { // root module changed
return Promise.reject(); // quiet rejection; no need to show error
} else {
return arg; // arg get wrapped in promise
}
});
};
return this;
}).call({}, edide);
//# sourceURL=rejectIfRecompiled-47
"use strict";edide.promise = (function _promise (edide) {Object.defineProperty(this, 'module_name', {value:'promise'});
this.new = function(cb) {
if (edide.inEditor) {
return edide.rejectIfRecompiled(new Promise(cb)); // don't fire cb if code has been re-executed in the meantime
} else {
return new Promise(cb); //, edide.editorModule?.editor_error.show
}
};
// TODO promise / promise.all that cancels on unload
this.all = function(cbArray) {
if (edide.inEditor) { // check that after resolved, still editing same module
// { rootName } = edide.moduleGate
// resolved = await Promise.all cbArray
// if edide.moduleGate.rootName is rootName
// then Promise.resolve resolved
// else Promise.reject()
return edide.rejectIfRecompiled(Promise.all(cbArray));
} else {
return Promise.all(cbArray);
}
};
this.resolve = Promise.resolve.bind(Promise);
this.reject = Promise.reject.bind(Promise);
return this;
}).call({}, edide);
//# sourceURL=promise-48
"use strict";edide.scriptContainer = (function _scriptContainer (edide) {
//debugger
var ref;
return (ref = edide.dom.get('#scripts')) != null ? ref : document.body.appendChild(edide.dom.new('#scripts'));
return this;
}).call({}, edide);
//# sourceURL=scriptContainer-49
"use strict";edide.requireScript = (function _requireScript (edide) {
// TODO: use \:keep instead?
var base;
if ((base = edide.global).requireScriptPromises == null) {
base.requireScriptPromises = new Map;
}
return (scriptSrc) => {
var promise;
if (promise = requireScriptPromises.get(scriptSrc)) {
return promise;
} else {
requireScriptPromises.set(scriptSrc, promise = edide.promise.new((resolve) => {
var el;
console.log('adding promised', scriptSrc);
el = document.createElement('script');
edide.scriptContainer.appendChild(el);
el.onload = resolve; //load_ready
el.type = 'application/javascript';
return el.src = scriptSrc;
}));
return promise.catch((err) => {
edide.showError(err);
return requireScriptPromises.delete(scriptSrc);
});
}
};
return this;
}).call({}, edide);
//# sourceURL=requireScript-50
"use strict";edide.array = (function _array (edide) {Object.defineProperty(this, 'module_name', {value:'array'});
// Array helpers
// All methods take array as first argument
// ['a'] -> { a: func(a) }
var flatten;
this.toObject = function(array, val_from_el, key_from_el) {
var el, i, ind, len, obj;
console.warn(":array.toObject will deprecate, use \:object.fromArray");
obj = {};
if (key_from_el == null) {
key_from_el = function(el) {
return el;
};
}
for (ind = i = 0, len = array.length; i < len; ind = ++i) {
el = array[ind];
obj[key_from_el(el, ind)] = val_from_el(el, ind);
}
return obj;
};
this.toArray = function(arrayish) {
return Array.prototype.slice.call(arrayish);
};
this.diff = function(arrA, arrB) {
var diff, el, i, len, unchecked;
unchecked = arrB.slice(0);
diff = [];
for (i = 0, len = arrA.length; i < len; i++) {
el = arrA[i];
if (arrB.indexOf(el) !== -1) {
this.remove(unchecked, el);
} else {
diff.push(el);
}
}
return diff.concat(unchecked);
};
this.flatten = flatten = (arr) => {
return arr.reduce((function(a, b) {
return a.concat(Array.isArray(b) ? flatten(b) : b);
}), []);
};
// returns array of results (unlike Array.prototype.forEach)
// @each = (arr, func)->
// console.warn ":array.each will deprecate; use [].map instead"
// for el, ind in arr
// func el, ind
this.last = this.lastOf = (arr) => {
return arr[arr.length - 1];
};
this.lastIndexOf = (arr) => {
return arr.length - 1;
};
this.setLast = (arr, newVal) => {
return arr[arr.length - 1] = newVal;
};
this.pushArray = (arr, arr2) => {
return arr.push.apply(arr, arr2);
};
this.remove = (arr, el) => {
var ind;
if ((ind = arr.indexOf(el)) !== -1) {
arr.splice(ind, 1);
}
return arr;
};
this.removeIf = (arr, test) => {
var ind;
ind = arr.length;
while (ind--) {
if (test(arr[ind], ind)) {
arr.splice(ind, 1);
}
}
return arr;
};
// not used at the momen.. perf compared to @remove ?
this.removeAll = function(arr, el) {
var arrEl, i, ind;
for (ind = i = arr.length - 1; i >= 0; ind = i += -1) {
arrEl = arr[ind];
if (arrEl === el) {
arr.splice(ind, 1);
}
}
return arr;
};
this.unique = function(...arrs) {
var arr, el, i, j, len, len1, unique;
unique = [];
for (i = 0, len = arrs.length; i < len; i++) {
arr = arrs[i];
for (j = 0, len1 = arr.length; j < len1; j++) {
el = arr[j];
if (!unique.includes(el)) {
unique.push(el);
}
}
}
return unique;
};
// LESS USED (move elsewhere?):
this.isEqual = (arr1, arr2) => {
var i, ind, len, val;
if (arr1.length !== arr2.length) {
return false;
}
for (ind = i = 0, len = arr1.length; i < len; ind = ++i) {
val = arr1[ind];
if (val !== arr2[ind]) {
return false;
}
}
return true;
};
this.count = function(arr, filterFunc) {
var count, e, filterEl, i, len;
if (typeof filterFunc !== 'function') {
filterEl = filterFunc;
filterFunc = function(e) {
return e === filterEl;
};
}
count = 0;
for (i = 0, len = arr.length; i < len; i++) {
e = arr[i];
(filterFunc(e) ? count++ : void 0);
}
return count;
};
return this;
}).call({}, edide);
//# sourceURL=array-51
"use strict";edide.error_parser = (function _error_parser (edide) {Object.defineProperty(this, 'module_name', {value:'error_parser'});
// Parses error objects stack into files, methods and row&column positions.
// Mainly for chrome, differenr browsers can have differently formed stacks.
this.getFileStr = (fileName, loc) => {
var fileHref, str, truncdFile;
// /^\w+.?\w+/ - used to be
truncdFile = (/\w+.?\w+/.exec(edide.array.lastOf(fileName.split('/'))))[0];
//truncdFile = truncdFile.replace /0test$/, ''
truncdFile = edide.str.truncate(truncdFile, 20);
fileHref = (edide.modules.all[fileName] != null) && fileName !== edide.moduleGate.rootName ? `${fileName}` : fileName.slice(0, 4) === 'http' ? fileName : void 0;
str = fileHref ? `<a href='${fileHref}'>${truncdFile}</a>` : truncdFile;
if (loc) {
str += ' ' + (loc.join(':'));
}
return str;
};
this.clear = () => {
this.stack = null;
this.errorObj = {};
this.stack_methods = [];
this.stack_files = [];
return this.stack_rowAndColumn = [];
};
this.parse_errorObj = (error) => {
var fileAndLoc, fileName, file_combine_start_ind, ind, j, k, keyStr, len, len1, loc, m, methodsInFile, ref, ref1, ref2, ref3, ref4, res, row;
this.error = error;
//debugger
this.clear();
this.stack = this.error.stack.split(/\n/g);
// if #edide.browser.isFirefox
// [ @errorObj, @stack_methods, @stack_files, @stack_rowAndColumn] = \
// #edide.error_parser_firefox.parseStack @stack
// else
if ((this.stack[0].indexOf(this.error.message) !== -1) && this.stack[1].match(/^ *at/)) {
// @errorObj = {}
// @stack_methods = []
// @stack_files = []
// @stack_rowAndColumn = []
// @stack trace
this.stack = this.stack.splice(1).map(function(str) {
return str.replace(/(^ *at |named_obj\.)/g, '').replace(/Object\./, '');
}).filter(function(s) {
return s;
});
ref = this.stack;
//alert @stack.length
for (j = 0, len = ref.length; j < len; j++) {
row = ref[j];
//console.log 'row', row
if (row.slice(-1) === ')') {
//if row.match /:\d+\)?$/
//alert 'match'
this.stack_methods.push((/[^ ]+/.exec(row))[0]);
fileAndLoc = (/ \((.+)/.exec(row))[1].slice(0, -1);
} else {
fileAndLoc = row; //(/ \((.+)/.exec row)[1][0...-1]
}
loc = (ref1 = /(:\d+:\d+)/.exec(fileAndLoc)) != null ? ref1[1] : void 0;
fileName = fileAndLoc.slice(0, +(-((ref3 = (loc != null ? loc.length : void 0) + 1) != null ? ref3 : 1)) + 1 || 9e9);
fileName = fileName.replace(/-\d+$/, '');
// replace natives with fileName name of where they are called from
if (edide.array.lastOf(this.stack_files) === 'native') {
edide.array.setLast(this.stack_files, fileName);
}
this.stack_files.push(fileName);
if (loc) {
this.stack_rowAndColumn.push(res = loc.split(':').slice(1));
} else {
// chome breakpoint location @error:
// https://code.google.com/p/v8/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Owner%20Summary%20HW%20OS%20Area%20Stars&groupby=&sort=&id=2825
//res[0] = parseInt(@stack_rowAndColumn[0]) + 2 + ''
this.stack_rowAndColumn.push(void 0);
}
}
// create @error object that is shown
file_combine_start_ind = null;
ref4 = this.stack_files;
for (ind = k = 0, len1 = ref4.length; k < len1; ind = ++k) {
fileName = ref4[ind];
loc = this.stack_rowAndColumn[ind];
if (fileName === this.stack_files[ind + 1]) {
if (file_combine_start_ind == null) {
file_combine_start_ind = ind;
}
} else if (file_combine_start_ind != null) {
methodsInFile = ind - file_combine_start_ind + 1;
keyStr = `in ${this.getFileStr(fileName) // #{methodsInFile}
}`;
this.errorObj[keyStr] = edide.object.fromArray(this.stack_methods.slice(file_combine_start_ind, +ind + 1 || 9e9), (function() {
return void 0;
}), (key, i) => {
loc = this.stack_rowAndColumn[file_combine_start_ind + i];
if (loc) {
return `${key} ${loc.join(':')}`;
} else {
return key;
}
});
file_combine_start_ind = null;
} else {
//console.log 'file', fileName
keyStr = (edide.str.if((m = this.stack_methods[ind]), `${m} in `)) + this.getFileStr(fileName, loc);
this.errorObj[keyStr] = void 0;
}
}
}
return this.errorObj = {
[`${this.error.message} (${this.error.name})`]: this.errorObj
};
};
return this;
}).call({}, edide);
//# sourceURL=error_parser-52
"use strict";edide.miniStack = (function _miniStack (edide) {
var daa, maxNameLength;
maxNameLength = 36;
return daa = (...args) => {
var boo, methods, num, reverse, showFiles, stackSize, truncate;
({boo, num} = edide.argumentTypes(args));
[showFiles, stackSize] = [boo != null ? boo : true, num != null ? num : 4];
edide.error_parser.parse_errorObj(new Error("showStack"));
methods = edide.error_parser.stack_methods.slice(1, +stackSize + 1 || 9e9);
({truncate, reverse} = edide.str);
if (showFiles) {
methods = methods.map((method, ind) => {
var str;
if ((str = `${edide.error_parser.stack_files[ind + 1]}.${method}`).length > maxNameLength) {
return reverse(truncate(reverse(str), maxNameLength));
} else {
return str;
}
});
}
return '| ' + methods.reverse().join(' → ') + ' |';
};
return this;
}).call({}, edide);
//# sourceURL=miniStack-53
"use strict";edide.membrameSynth = (function _membrameSynth (edide) {Object.defineProperty(this, 'module_name', {value:'membrameSynth'});
this.startNote = 'A0';
this.init = () => {
var bd, compressor, distortion, gain, reverb;
distortion = new Tone.Distortion({
distortion: 0.1,
oversample: "4x" // none, 2x, 4x
});
reverb = new Tone.Freeverb(0.75, 1000);
gain = new Tone.Gain(0.5);
//feedbackDelay = new Tone.FeedbackDelay("8n",0.25)
compressor = new Tone.Compressor({
ratio: 12,
threshold: -24,
release: 0.05,
attack: 0.003,
knee: 1
});
bd = new Tone.MembraneSynth({
pitchDecay: 0.05,
octaves: 4,
// oscillator: {
// type :"fmsine",
// phase: 140,
// modulationType: "sine",
// modulationIndex:0.8,
// partials: [1] # 1,0.1,0.01,0.01
// },
envelope: {
// modulationIndex: 1
attack: 0.01,
decay: 0.74,
sustain: 0.71,
release: 0.05,
attackCurve: "exponential"
}
});
//res = gain.chain(gain, reverb, compressor)
// gain.chain(compressor, Tone.Master)
//edide.unload.add => reverb.dispose()
bd.chain(gain, distortion, reverb, compressor);
return [bd, compressor];
};
return this;
}).call({}, edide);
//# sourceURL=membrameSynth-54
"use strict";edide.toneSynth = (function _toneSynth (edide) {Object.defineProperty(this, 'module_name', {value:'toneSynth'});
this.startNote = 'C3';
this.init = () => {
var ss;
//#[ss, ss]
return ss = new Tone.PolySynth(12, Tone.Synth, {
oscillator: {
type: 'sine'
},
envelope: {
attack: 0.005,
decay: 0.1,
sustain: 0.3,
release: 1
}
});
};
//ss
return this;
}).call({}, edide);
//# sourceURL=toneSynth-55
"use strict";edide.instrumentConfigs = (function _instrumentConfigs (edide) {Object.defineProperty(this, 'module_name', {value:'instrumentConfigs'});
var defaultUrl = '//nbrosowsky.github.io/tonejs-instruments/samples/'
var { revar, unvar, react } = edide.mmState
var defaultInstrument = 'electric-guitar'
//this.kept = edide.keep({})
// get inst of current type that is not playing
//this.getFree = () => {
// return this.current
// this.current.context.state
//}
//var setActive = (name, instStartEnd) => {
// var [inst, endOfPipe] = Array.isArray(this.kept[name])
// ? this.kept[name]
// : [this.kept[name], this.kept[name]]
//// this.current = inst
// edide.mmPipe.initInstrument(endOfPipe)
// revar.instrumentConf = this.instruments[name]
//}
this.initInstrument = async (resolve) => {
await edide.requireScript('https://cdnjs.cloudflare.com/ajax/libs/tone/13.8.9/Tone.js')
edide.mmPipe.initPipe()
}
this.createNew = () => {
//edide.console.log(edide.miniStack())
var {name} = unvar.instrumentConf
var instrument, endOfPipe
var instrumentConf = this.instruments[name]
//edide.console.log('instrument', instrumentConf)
if (instrumentConf.module_name) {
var res = instrumentConf.init()
if (Array.isArray(res)) {
instrument = res[0]
endOfPipe = res[1]
} else {
instrument = endOfPipe = res
}
} else {
var noteFiles = buildNotes(instrumentConf)
var inst = new Tone.Sampler(noteFiles, { //edide.instrumentConfigssAll[name]
"release" : 1,
"baseUrl" : instrumentConf.url || defaultUrl + name + '/'
})
inst.soundFontInstrument = true
instrument = endOfPipe = inst //[inst, inst]
}
//edide.unload.add(() => instStartEnd[0].disconnect())
edide.mmPipe.initInstrument(endOfPipe)
//setActive(inst)
return instrument
}
this.isReady = () => {
var { current } = this
return current && (typeof current.loaded == 'undefined' || current.loaded === true)
}
function buildNotes({startNote, notes, step, skipNotes}) {
var [startInd] = edide.noteFreq.findNote(startNote)
var noteFiles = {}
if (Array.isArray(notes)) {
notes.forEach(note => {
noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]'
})
} else {
for (let i=0; i < notes*step; i+=step) {
let note = edide.noteFreq.notes[startInd + i][0];
if (skipNotes && skipNotes.has(note))
continue
noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]'
}
}
// noteFiles.forEach(note => {
// edide.assert(!!manualInst[note], `${note} don't exist`)
// })
return noteFiles
}
this.instruments = {
'bass-electric': {
startNote: 'C#2',
notes: 8, // 16
step: 3
},
'cello': {
startNote: 'C2',
notes: 11,
step: 2,
skipNotes: edide.set('F#2', 'C4')
},
'drum-electric': edide.membrameSynth,
'guitar-acoustic': {
startNote: 'D1',
notes: 26, // 36
step: 2,
skipNotes: edide.set('E4', 'F#4', 'G#4', 'A#4', 'C5', 'D5', 'E5')
}, // umm, would be simpler to just add all notes
'guitar-electric': {
startNote: 'F#2',
notes: 15, // 15
step: 3,
},
'piano': {
startNote: 'A1',
notes: 30, // 29
step: 2,
volume: -6, // TODO implement this
baseUrl: "https://tonejs.github.io/examples/audio/salamander/"
},
'synth-simple': edide.toneSynth,
'xylophone': {
startNote: 'G3',
notes: ['G3', 'C4', 'G4', 'C5', 'G5', 'C6', 'G6', 'C7']
}
}
for (let inst in this.instruments) {
this.instruments[inst].name = inst
}
this.instrumentList = Object.values(this.instruments)
react('active instrument config', () => {
revar.instrumentConf = this.instruments[revar.instrument] // this.instrumentList[revar.instrumentInd]
})
// abcdefghijklmnop
//var manualInst = //edide.instrumentConfigssAll['piano'],
// inst = this.instruments['piano']
//buildNotes(inst)
return this;
}).call({}, edide);
//# sourceURL=instrumentConfigs-56
"use strict";edide.cloneSibling = (function _cloneSibling (edide) {
// clone with inheritance tree and (shallow) properties
return (srcObj) => {
var o;
o = Object.create(Object.getPrototypeOf(srcObj));
Object.assign(o, srcObj);
return o;
};
return this;
}).call({}, edide);
//# sourceURL=cloneSibling-57
"use strict";edide.times = (function _times (edide) {
return (timesNum, action) => {
while (timesNum-- > 0) {
action(timesNum + 1);
}
};
return this;
}).call({}, edide);
//# sourceURL=times-58
"use strict";edide.setTimeout = (function _setTimeout (edide) {
return function() {
var fun, id, num;
({fun, num} = edide.argumentTypes(arguments));
id = setTimeout(fun, num);
edide.unload.add(() => {
return clearTimeout(id);
});
return id;
};
return this;
}).call({}, edide);
//# sourceURL=setTimeout-59
"use strict";edide.sleep = (function _sleep (edide) {
// see \:sleepy for version with wakeup option
var sleep;
sleep = (ms) => {
var resolve, timeout;
timeout = resolve = null;
return edide.promise.new((res) => {
resolve = res;
return timeout = edide.setTimeout(ms, res);
});
};
return sleep;
return this;
}).call({}, edide);
//# sourceURL=sleep-60
"use strict";edide.mmInstrument = (function _mmInstrument (edide) {Object.defineProperty(this, 'module_name', {value:'mmInstrument'});
// PLAY notes/chords and initializes new instruments when needed
var cloneOrCreateInstrument, dom, getInstruments, instruments, play, react, revar, unvar;
({unvar, revar, react, dom} = edide.mmState);
revar.beatDelay = () => {
return (1 / revar.bpm) * 60 * 1000;
};
instruments = {}; // name: [instrument instances...]
react('create first instrument', () => {
var name, ref;
if (!(name = (ref = revar.instrumentConf) != null ? ref.name : void 0)) { // e.g. illegal instrument name
return edide.showError(`Unknown instrument: ${unvar.instrument}`);
}
if (revar.pipeReady && !instruments[name]) {
'create initial instrument';
return instruments[name] = [edide.instrumentConfigs.createNew()];
}
});
cloneOrCreateInstrument = (name) => {
var inst;
if (instruments[name][0].soundFontInstrument) {
inst = edide.cloneSibling(instruments[name][0]);
inst.isPlaying = false;
return inst;
} else {
return edide.instrumentConfigs.createNew();
}
};
getInstruments = (n) => {
var all, free, name;
({name} = unvar.instrumentConf);
all = instruments[name];
edide.assert(all.length != null, "first instrument should be initialized already");
free = all.filter((i) => {
return !i.isPlaying;
});
// create new instruments if not enough many free
edide.times(n - free.length, () => {
var inst;
free.push(inst = cloneOrCreateInstrument(name));
return all.push(inst);
});
return free.slice(0, n);
};
// TODO: playNote / playChord separation
this.playChord = (chord, noteLength = 1) => {};
this.playNote = (chord, noteLength = 1) => {
var ind, inst, insts, j, len, ref;
if (!Array.isArray(chord)) {
chord = [chord];
}
ref = insts = getInstruments(chord.length);
for (ind = j = 0, len = ref.length; j < len; ind = ++j) {
inst = ref[ind];
edide.assert(!inst.isPlaying, "instrument already playing");
play(inst, chord[ind], noteLength);
}
};
// note = chord[ind]
// #else noteLength = 1
// inst.isPlaying = note # true
// inst.triggerAttackRelease note, (noteLength * unvar.beatDelay) / 1000 + 's'
// revar.note = note
//# catch err
//# edide.showError "Error in playing note #{chord[ind]}, probably don't exist for the instrument"
// await edide.sleep unvar.nextDelay
// for inst in insts
// inst.isPlaying = false
// return
//setTimeout (=> #edide.console.log 'note played'), (length * unvar.beatDelay)
play = async(instrument, note, length) => {
var err;
instrument.isPlaying = note; // true
try {
instrument.triggerAttackRelease(note, (length * unvar.beatDelay) / 1000);
} catch (error) {
err = error;
err.message = `Error in playing note ${note}, '${unvar.instrumentConf.name}' probably not loaded yet`;
edide.showError(err);
}
revar.note = note;
await edide.sleep(unvar.nextDelay);
return instrument.isPlaying = false;
};
// UI
this.dropdown = dom(() => {
var ind, name;
return {
select: {
me: (function() {
var j, len, ref, results;
ref = edide.instrumentConfigs.instrumentList;
results = [];
for (ind = j = 0, len = ref.length; j < len; ind = ++j) {
({name} = ref[ind]);
results.push({
option: {
text: name,
//value: name # ind
selected: edide.yesOrNull(name === revar.instrument) // ind is revar.instrumentInd
}
});
}
return results;
})(),
onChange: (ev) => {
return revar.instrument = ev.target.value; //revar.instrumentInd = parseInt ev.target.value
}
}
};
});
return this;
}).call({}, edide);
//# sourceURL=mmInstrument-61
"use strict";edide.mmParser = (function _mmParser (edide) {Object.defineProperty(this, 'module_name', {value:'mmParser'});
var getNoteLength, processTrack, react, revar, unvar;
({revar, unvar, react} = edide.mmState);
getNoteLength = (row, noteInd) => {
var char, length;
length = 1;
while (char = row[++noteInd]) {
if (char === edide.mmKeyboard.special.long) {
length++;
} else {
//else if meaningfullChar char
break;
}
}
return length;
};
//meaningfullChar = (char) =>
// edide.mmNote.fromChar(char) or edide.mmKeyboard.isPauseChar char
// Processes one char in a track, and iteratively calls itself if needed.
// ccs - "current column state" - inline chord + played?
// ts - tack state: char index, configs
processTrack = (track, ccs, ts) => {
var chord, keyCode, note;
if (!track[ts.i]) {
return;
}
if (ts.skip) { // comment or erroneous chars
return;
}
// bracket chords
switch (track[ts.i]) {
case '{':
return ts.i += edide.mmParserSpecial.config(track.slice(ts.i), ts); // parseConfigs
case '[':
ccs.chord = [];
ts.i++;
return processTrack(track, ccs, ts);
case ']':
({chord} = ccs);
ccs.chord = null;
ts.i++;
if (chord.length) {
edide.mmInstrument.playNote(chord, getNoteLength(track, ts.i));
ccs.played = true;
} else {
processTrack(track, ccs, ts);
}
return;
case edide.mmKeyboard.special.var:
if (edide.mmParserSpecial.var(track, ts)) {
processTrack(track, ccs, ts); // recursive, since next char could be another var, e.g. \:bass::minor:
} else {
ts.skip = true; // parse error
}
return;
case edide.mmKeyboard.special.comment:
return ts.skip = true;
}
// TODO: merge switch and bottom code OR put them in a different functions
if (!(keyCode = track.charCodeAt(ts.i))) {
return;
}
ts.i++;
if (note = edide.mmNote.fromKeyCode(keyCode)) {
if (ccs.chord) {
ccs.chord.push(note);
processTrack(track, ccs, ts);
} else {
edide.mmInstrument.playNote(note, getNoteLength(track, ts.i));
ccs.played = true;
}
} else if (edide.mmKeyboard.isPauseKey(keyCode)) {
ccs.played = true; // "play silence"
// meaningless char
} else {
processTrack(track, ccs, ts);
}
};
// TODO figure sheetStart != 0 -- maybe makes more sense to remove textarea first
//edide.mmHighlight.add textRow, ts.iStart, i
this.splitSections = (str) => {
var i, j, prevInd, ref, row, section, sections;
str = str.replace('&\n', ''); // TODO fix row tracking with &\n
sections = [];
section = null;
row = 0;
prevInd = 0;
for (i = j = 0, ref = str.length; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) {
if (!(str[i] === '\n' || i === str.length)) {
continue;
}
if (str[i - 1] === '\n') {
if (section != null) {
sections.push(section);
}
section = null;
}
if (i > prevInd) {
if (section == null) {
section = {
row: row,
tracks: []
};
}
section.tracks.push(str.slice(prevInd, i));
}
row++;
prevInd = i + 1;
}
if (section != null) {
sections.push(section);
}
sections.row = 0;
return sections;
};
this.play = (song, sectionInd, trackStates) => {
var ccs, section;
//debugger
if (!unvar.playing) {
return;
}
revar.highlight = null;
//edide.mmHighlight.removeAll()
sectionInd = sectionInd || 0;
// split song into sections if haven't already
if (typeof song === 'string') {
//song = song.split /\n\n+/
song = this.splitSections(song);
}
section = song[sectionInd];
// if typeof (section = song[sectionInd]) is 'string'
// #section = processSections
// section = section.split /\n/
if (!section) { // song finished
return revar.playing = false;
}
if (!Array.isArray(trackStates)) {
trackStates = section.tracks.map(() => {
return {
i: 0 // initi track indices on first call to section
};
});
}
// init @play ccs
ccs = {}; // chord, played # TODO change back to chord: [C3, D3] and [].played = true
// OR: why not just ts.chord?
section.tracks.forEach((track, tInd) => {
var conf, i, iStart;
if (conf = trackStates[tInd].conf) {
// config row and already parsed (NOTE: config row can only have one config object and nothing else)
//edide.console.log "#{sectionInd}-#{tInd}", conf
return edide.mmConfigs.activate(conf);
} else {
trackStates[tInd].iStart = trackStates[tInd].i;
//highStart = trackStates[tInd].i
processTrack(track, ccs, trackStates[tInd]);
({iStart, i} = trackStates[tInd]);
if (i > iStart) {
return revar.highlight = [song.row + section.row + tInd, iStart, i - 1];
}
}
});
//edide.mmHighlight.add song.row+section.row+tInd, iStart, i - 1
//return
if (ccs.played) {
edide.setTimeout(() => {
return this.play(song, sectionInd, trackStates);
}, unvar.beatDelay);
} else {
// using timeout fixes bug where revar.playing is set false in same exec where it's set true (infinite loop)
edide.setTimeout(() => {
return this.play(song, sectionInd + 1);
});
}
};
//split = (sa, at) ->
// if typeof sa is 'string' then sa.split(at) else sa
//# Only used when key pressed, could be simplified a lot!
//@playNote = (note) =>
// #return unless edide.instrumentConfigs.isReady()
// note = edide.mmNote.fromKeyCode note if typeof note is 'number'
// return false unless note
// return true if note is true #or note.pause # delay char
// if typeof note is 'string' or Array.isArray(note)
// edide.mmInstrument.playNote note
// else
// throw Error "Unkown note #{note}"
// note
return this;
}).call({}, edide);
//# sourceURL=mmParser-62
"use strict";edide.music = (function _music (edide) {Object.defineProperty(this, 'module_name', {value:'music'});
var { revar, unvar, react } = edide.mmState
var playQueue = []
this.play = (str) => {
if (!unvar.pipeReady) return playQueue.push(str)
revar.playing = true
edide.mmParser.play(str)
}
this.stop = () => revar.playing = false
edide.instrumentConfigs.initInstrument()
var initialSettings = {
"instrument": "piano"
}
react(() => {
if(!revar.pipeReady) return
this.play(JSON.stringify(initialSettings))
this.play(playQueue.join("\n\n"))
}) // TEMP init instrument
return this;
}).call({}, edide);
//# sourceURL=music-63
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment