Created
November 27, 2019 16:42
-
-
Save jussiry/942b4ed3521d981229ab1c599ed66048 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, '&').replace(/</g, '<').replace(/>/g, '>'); | |
}; | |
//.replace(/"/g, '"').replace(/'/g, ''') # " 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