diff --git a/bower.json b/bower.json index ce56a872c..465546183 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "h2o-flow", - "version": "0.2.25", + "version": "0.2.26", "homepage": "https://github.com/h2oai/h2o-flow", "authors": [ "Prithvi Prabhu " diff --git a/build/js/flow.js b/build/js/flow.js index 73dea5a06..c5990e916 100755 --- a/build/js/flow.js +++ b/build/js/flow.js @@ -11,4046 +11,4059 @@ } }.call(this)); (function () { - Flow.ApplicationContext = function (_) { - _.ready = Flow.Dataflow.slots(); - _.status = Flow.Dataflow.slot(); - _.selectCell = Flow.Dataflow.slot(); - _.insertCell = Flow.Dataflow.slot(); - _.insertAndExecuteCell = Flow.Dataflow.slot(); - _.showHelp = Flow.Dataflow.slot(); - _.showOutline = Flow.Dataflow.slot(); - _.showBrowser = Flow.Dataflow.slot(); - _.showClipboard = Flow.Dataflow.slot(); - _.saveClip = Flow.Dataflow.slot(); - _.loadNotebook = Flow.Dataflow.slot(); - return _.storeNotebook = Flow.Dataflow.slot(); - }; -}.call(this)); -(function () { - Flow.Application = function (_, routines) { - var _notebook, _renderers, _routines, _sandbox; - Flow.ApplicationContext(_); - _routines = routines(_); - _sandbox = Flow.Sandbox(_, _routines); - _renderers = Flow.Renderers(_, _sandbox); - _notebook = Flow.Notebook(_, _renderers); - return { - context: _, - sandbox: _sandbox, - view: _notebook - }; - }; -}.call(this)); -(function () { - var createBuffer, iterate, pipe, renderable, _applicate, _async, _find, _find$2, _find$3, _fork, _get, _isFuture, _join, _noop, __slice = [].slice; - createBuffer = function (array) { - var buffer, _array, _go; - _array = array || []; - _go = null; - buffer = function (element) { - if (element === void 0) { - return _array; + var FLOW_VERSION; + FLOW_VERSION = '0.2.26'; + Flow.About = function (_) { + var _properties; + _properties = Flow.Dataflow.signals([]); + Flow.Dataflow.link(_.ready, function () { + if (Flow.Version) { + return _properties(Flow.Version); } else { - _array.push(element); - if (_go) { - _go(element); - } - return element; - } - }; - buffer.subscribe = function (go) { - return _go = go; - }; - buffer.buffer = _array; - buffer.isBuffer = true; - return buffer; - }; - _noop = function (go) { - return go(null); - }; - _applicate = function (go) { - return function (error, args) { - if (lodash.isFunction(go)) { - return go.apply(null, [error].concat(args)); + return _.requestAbout(function (error, response) { + var name, properties, value, _i, _len, _ref, _ref1; + properties = []; + if (!error) { + _ref = response.entries; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + _ref1 = _ref[_i], name = _ref1.name, value = _ref1.value; + properties.push({ + caption: 'H2O ' + name, + value: value + }); + } + } + properties.push({ + caption: 'Flow version', + value: FLOW_VERSION + }); + return _properties(Flow.Version = properties); + }); } - }; - }; - renderable = function () { - var args, f, ft, render, _i; - f = arguments[0], args = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), render = arguments[_i++]; - ft = _fork(f, args); - ft.render = render; - return ft; + }); + return { properties: _properties }; }; - _fork = function (f, args) { - var self; - self = function (go) { - var canGo; - canGo = lodash.isFunction(go); - if (self.settled) { - if (self.rejected) { - if (canGo) { - return go(self.error); +}.call(this)); +(function () { + Flow.Browser = function (_) { + var createDocView, loadNotebooks, storeNotebook, _docs, _hasDocs, _sortedDocs; + _docs = Flow.Dataflow.signals([]); + _sortedDocs = Flow.Dataflow.lift(_docs, function (docs) { + return lodash.sortBy(docs, function (doc) { + return -doc.date().getTime(); + }); + }); + _hasDocs = Flow.Dataflow.lift(_docs, function (docs) { + return docs.length > 0; + }); + createDocView = function (_arg) { + var doc, id, load, purge, self, type, _date, _fromNow, _title; + type = _arg[0], id = _arg[1], doc = _arg[2]; + _title = Flow.Dataflow.signal(doc.title); + _date = Flow.Dataflow.signal(new Date(doc.modifiedDate)); + _fromNow = Flow.Dataflow.lift(_date, Flow.Util.fromNow); + load = function () { + return _.loadNotebook(id, doc); + }; + purge = function () { + return _.requestDeleteObject(type, id, function (error) { + if (error) { + return console.debug(error); + } else { + return _docs.remove(self); } - } else { - if (canGo) { - return go(null, self.result); + }); + }; + return self = { + id: id, + title: _title, + doc: doc, + date: _date, + fromNow: _fromNow, + load: load, + purge: purge + }; + }; + storeNotebook = function (id, doc, go) { + if (id) { + return _.requestPutObject('notebook', id, doc, function (error) { + var index, source, _i, _len, _ref; + if (error) { + return go(error); + } else { + _ref = _docs(); + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + source = _ref[index]; + if (source.id === id) { + break; + } + } + _docs.splice(index, 1, createDocView([ + 'notebook', + id, + doc + ])); + return go(null, id); } - } + }); } else { - return _join(args, function (error, args) { + id = uuid(); + return _.requestPutObject('notebook', id, doc, function (error) { if (error) { - self.error = error; - self.fulfilled = false; - self.rejected = true; - if (canGo) { - return go(error); - } + return go(error); } else { - return f.apply(null, args.concat(function (error, result) { - if (error) { - self.error = error; - self.fulfilled = false; - self.rejected = true; - if (canGo) { - go(error); - } - } else { - self.result = result; - self.fulfilled = true; - self.rejected = false; - if (canGo) { - go(null, result); - } - } - self.settled = true; - return self.pending = false; - })); + _docs.push(createDocView([ + 'notebook', + id, + doc + ])); + return go(null, id); } }); } }; - self.method = f; - self.args = args; - self.fulfilled = false; - self.rejected = false; - self.settled = false; - self.pending = true; - self.isFuture = true; - return self; - }; - _isFuture = function (a) { - if (a != null ? a.isFuture : void 0) { - return true; - } else { - return false; - } - }; - _join = function (args, go) { - var arg, i, _actual, _i, _len, _results, _settled, _tasks; - if (args.length === 0) { - return go(null, []); - } - _tasks = []; - _results = []; - for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { - arg = args[i]; - if (arg != null ? arg.isFuture : void 0) { - _tasks.push({ - future: arg, - resultIndex: i - }); - } else { - _results[i] = arg; - } - } - if (_tasks.length === 0) { - return go(null, _results); - } - _actual = 0; - _settled = false; - lodash.forEach(_tasks, function (task) { - return task.future.call(null, function (error, result) { - if (_settled) { - return; - } + loadNotebooks = function () { + return _.requestObjects('notebook', function (error, objs) { if (error) { - _settled = true; - go(new Flow.Error('Error evaluating future[' + task.resultIndex + ']', error)); + return console.debug(error); } else { - _results[task.resultIndex] = result; - _actual++; - if (_actual === _tasks.length) { - _settled = true; - go(null, _results); - } + return _docs(lodash.map(objs, createDocView)); } }); + }; + Flow.Dataflow.link(_.ready, function () { + return loadNotebooks(); }); + Flow.Dataflow.link(_.storeNotebook, storeNotebook); + return { + docs: _sortedDocs, + hasDocs: _hasDocs, + loadNotebooks: loadNotebooks + }; }; - pipe = function (tasks) { - var next, _tasks; - _tasks = tasks.slice(0); - next = function (args, go) { - var task; - task = _tasks.shift(); - if (task) { - return task.apply(null, args.concat(function () { - var error, results; - error = arguments[0], results = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - if (error) { - return go(error); - } else { - return next(results, go); - } - })); - } else { - return go.apply(null, [null].concat(args)); +}.call(this)); +(function () { + Flow.Cell = function (_, _renderers, type, input) { + var activate, clip, execute, navigate, select, self, _actions, _guid, _hasError, _hasInput, _hasOutput, _input, _isActive, _isBusy, _isCode, _isInputVisible, _isOutputHidden, _isReady, _isSelected, _outputs, _render, _result, _type; + if (type == null) { + type = 'cs'; + } + if (input == null) { + input = ''; + } + _guid = lodash.uniqueId(); + _type = Flow.Dataflow.signal(type); + _render = Flow.Dataflow.lift(_type, function (type) { + return _renderers[type](_guid); + }); + _isCode = Flow.Dataflow.lift(_render, function (render) { + return render.isCode; + }); + _isSelected = Flow.Dataflow.signal(false); + _isActive = Flow.Dataflow.signal(false); + _hasError = Flow.Dataflow.signal(false); + _isBusy = Flow.Dataflow.signal(false); + _isReady = Flow.Dataflow.lift(_isBusy, function (isBusy) { + return !isBusy; + }); + _hasInput = Flow.Dataflow.signal(true); + _input = Flow.Dataflow.signal(input); + _outputs = Flow.Dataflow.signals([]); + _result = Flow.Dataflow.signal(null); + _hasOutput = Flow.Dataflow.lift(_outputs, function (outputs) { + return outputs.length > 0; + }); + _isInputVisible = Flow.Dataflow.signal(true); + _isOutputHidden = Flow.Dataflow.signal(false); + _actions = {}; + Flow.Dataflow.act(_isActive, function (isActive) { + if (isActive) { + _.selectCell(self); + _hasInput(true); + if (!_isCode()) { + _outputs([]); + } + } + }); + Flow.Dataflow.act(_isSelected, function (isSelected) { + if (!isSelected) { + return _isActive(false); } + }); + select = function () { + _.selectCell(self, false); + return true; }; - return function () { - var args, go, _i; - args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), go = arguments[_i++]; - return next(args, go); + navigate = function () { + _.selectCell(self); + return true; }; - }; - iterate = function (tasks) { - var next, _results, _tasks; - _tasks = tasks.slice(0); - _results = []; - next = function (go) { - var task; - task = _tasks.shift(); - if (task) { - return task(function (error, result) { - if (error) { - _results.push([error]); + activate = function () { + return _isActive(true); + }; + clip = function () { + return _.saveClip('user', _type(), _input()); + }; + execute = function (go) { + var render; + input = _input().trim(); + if (!input) { + if (go) { + return go(); + } else { + return void 0; + } + } + render = _render(); + _isBusy(true); + _result(null); + _outputs([]); + _hasError(false); + render(input, { + data: function (result) { + return _outputs.push(result); + }, + close: function (result) { + return _result(result); + }, + error: function (error) { + _hasError(true); + if (error.name === 'FlowError') { + return _outputs.push(Flow.Failure(error)); } else { - _results.push([ - null, - result - ]); + return _outputs.push({ + text: JSON.stringify(error, null, 2), + template: 'flow-raw' + }); } - return next(go); - }); - } else { - return go(null, _results); - } + }, + end: function () { + _hasInput(render.isCode); + _isBusy(false); + if (go) { + return go(); + } + } + }); + return _isActive(false); }; - return function (go) { - return next(go); + return self = { + guid: _guid, + type: _type, + isCode: _isCode, + isSelected: _isSelected, + isActive: _isActive, + hasError: _hasError, + isBusy: _isBusy, + isReady: _isReady, + input: _input, + hasInput: _hasInput, + outputs: _outputs, + result: _result, + hasOutput: _hasOutput, + isInputVisible: _isInputVisible, + toggleInput: function () { + return _isInputVisible(!_isInputVisible()); + }, + isOutputHidden: _isOutputHidden, + toggleOutput: function () { + return _isOutputHidden(!_isOutputHidden()); + }, + select: select, + navigate: navigate, + activate: activate, + execute: execute, + clip: clip, + _actions: _actions, + getCursorPosition: function () { + return _actions.getCursorPosition(); + }, + autoResize: function () { + return _actions.autoResize(); + }, + scrollIntoView: function () { + return _actions.scrollIntoView(); + }, + templateOf: function (view) { + return view.template; + }, + template: 'flow-cell' }; }; - _async = function () { - var args, f, later; - f = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - later = function () { - var args, error, go, result, _i; - args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), go = arguments[_i++]; - try { - result = f.apply(null, args); - return go(null, result); - } catch (_error) { - error = _error; - return go(error); +}.call(this)); +(function () { + var SystemClips; + SystemClips = [ + 'assist', + 'importFiles', + 'getFrames', + 'getModels', + 'getPredictions', + 'getJobs', + 'buildModel', + 'predict' + ]; + Flow.Clipboard = function (_) { + var addClip, createClip, emptyTrash, initialize, lengthOf, removeClip, _hasTrashClips, _hasUserClips, _systemClipCount, _systemClips, _trashClipCount, _trashClips, _userClipCount, _userClips; + lengthOf = function (array) { + if (array.length) { + return '(' + array.length + ')'; + } else { + return ''; } }; - return _fork(later, args); - }; - _find$3 = function (attr, prop, obj) { - var v, _i, _len; - if (_isFuture(obj)) { - return _async(_find$3, attr, prop, obj); - } else if (lodash.isArray(obj)) { - for (_i = 0, _len = obj.length; _i < _len; _i++) { - v = obj[_i]; - if (v[attr] === prop) { - return v; - } + _systemClips = Flow.Dataflow.signals([]); + _systemClipCount = Flow.Dataflow.lift(_systemClips, lengthOf); + _userClips = Flow.Dataflow.signals([]); + _userClipCount = Flow.Dataflow.lift(_userClips, lengthOf); + _hasUserClips = Flow.Dataflow.lift(_userClips, function (clips) { + return clips.length > 0; + }); + _trashClips = Flow.Dataflow.signals([]); + _trashClipCount = Flow.Dataflow.lift(_trashClips, lengthOf); + _hasTrashClips = Flow.Dataflow.lift(_trashClips, function (clips) { + return clips.length > 0; + }); + createClip = function (_list, _type, _input, _canRemove) { + var execute, insert, self; + if (_canRemove == null) { + _canRemove = true; } - return; - } - }; - _find$2 = function (attr, obj) { - if (_isFuture(obj)) { - return _async(_find$2, attr, obj); - } else if (lodash.isString(attr)) { - if (lodash.isArray(obj)) { - return _find$3('name', attr, obj); - } else { - return obj[attr]; - } - } - }; - _find = function () { - var a, args, b, c, ta, tb, tc; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - switch (args.length) { - case 3: - a = args[0], b = args[1], c = args[2]; - ta = Flow.Prelude.typeOf(a); - tb = Flow.Prelude.typeOf(b); - tc = Flow.Prelude.typeOf(c); - if (ta === 'Array' && tb === 'String') { - return _find$3(b, c, a); - } else if (ta === 'String' && (tc = 'Array')) { - return _find$3(a, b, c); - } - break; - case 2: - a = args[0], b = args[1]; - if (!a) { - return; - } - if (!b) { - return; - } - if (lodash.isString(b)) { - return _find$2(b, a); - } else if (lodash.isString(a)) { - return _find$2(a, b); - } - } - }; - _get = function (attr, obj) { - if (_isFuture(obj)) { - return _async(_get, attr, obj); - } else if (lodash.isString(attr)) { - if (lodash.isArray(obj)) { - return _find$3('name', attr, obj); - } else { - return obj[attr]; - } - } - }; - Flow.Async = { - createBuffer: createBuffer, - noop: _noop, - applicate: _applicate, - renderable: renderable, - isFuture: _isFuture, - fork: _fork, - join: _join, - pipe: pipe, - iterate: iterate, - async: _async, - find: _find, - get: _get - }; -}.call(this)); -(function () { - Flow.CoffeescriptKernel = function () { - var coalesceScopes, compileCoffeescript, compileJavascript, createGlobalScope, createLocalScope, createRootScope, deleteAstNode, executeJavascript, generateJavascript, identifyDeclarations, parseDeclarations, parseJavascript, removeHoistedDeclarations, rewriteJavascript, safetyWrapCoffeescript, traverseJavascript, traverseJavascriptScoped; - safetyWrapCoffeescript = function (guid) { - return function (cs, go) { - var block, lines; - lines = cs.replace(/[\n\r]/g, '\n').split('\n'); - block = lodash.map(lines, function (line) { - return ' ' + line; - }); - block.unshift('_h2o_results_[\'' + guid + '\'].result do ->'); - return go(null, block.join('\n')); + execute = function () { + return _.insertAndExecuteCell(_type, _input); + }; + insert = function () { + return _.insertCell(_type, _input); + }; + Flow.Prelude.remove = function () { + if (_canRemove) { + return removeClip(_list, self); + } + }; + return self = { + type: _type, + input: _input, + execute: execute, + insert: insert, + remove: Flow.Prelude.remove, + canRemove: _canRemove }; }; - compileCoffeescript = function (cs, go) { - var error; - try { - return go(null, CoffeeScript.compile(cs, { bare: true })); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error compiling coffee-script', error)); - } + addClip = function (list, type, input) { + return list.push(createClip(list, type, input)); }; - parseJavascript = function (js, go) { - var error; - try { - return go(null, esprima.parse(js)); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error parsing javascript expression', error)); + removeClip = function (list, clip) { + if (list === _userClips) { + _userClips.remove(clip); + return _trashClips.push(createClip(_trashClips, clip.type, clip.input)); + } else { + return _trashClips.remove(clip); } }; - identifyDeclarations = function (node) { - var declaration; - if (!node) { - return null; - } - switch (node.type) { - case 'VariableDeclaration': - return function () { - var _i, _len, _ref, _results; - _ref = node.declarations; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - declaration = _ref[_i]; - if (declaration.type === 'VariableDeclarator' && declaration.id.type === 'Identifier') { - _results.push({ - name: declaration.id.name, - object: '_h2o_context_' - }); - } - } - return _results; - }(); - case 'FunctionDeclaration': - if (node.id.type === 'Identifier') { - return [{ - name: node.id.name, - object: '_h2o_context_' - }]; - } - break; - case 'ForStatement': - return identifyDeclarations(node.init); - case 'ForInStatement': - case 'ForOfStatement': - return identifyDeclarations(node.left); - } - return null; + emptyTrash = function () { + return _trashClips.removeAll(); }; - parseDeclarations = function (block) { - var declaration, declarations, identifiers, node, _i, _j, _len, _len1, _ref; - identifiers = []; - _ref = block.body; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - node = _ref[_i]; - if (declarations = identifyDeclarations(node)) { - for (_j = 0, _len1 = declarations.length; _j < _len1; _j++) { - declaration = declarations[_j]; - identifiers.push(declaration); + initialize = function () { + _systemClips(lodash.map(SystemClips, function (input) { + return createClip(_systemClips, 'cs', input, false); + })); + return Flow.Dataflow.link(_.ready, function () { + return Flow.Dataflow.link(_.saveClip, function (category, type, input) { + input = input.trim(); + if (input) { + if (category === 'user') { + return addClip(_userClips, type, input); + } else { + return addClip(_trashClips, type, input); + } } - } - } - return lodash.indexBy(identifiers, function (identifier) { - return identifier.name; + }); }); }; - traverseJavascript = function (parent, key, node, f) { - var child, i; - if (lodash.isArray(node)) { - i = node.length; - while (i--) { - child = node[i]; - if (lodash.isObject(child)) { - traverseJavascript(node, i, child, f); - f(node, i, child); - } - } - } else { - for (i in node) { - child = node[i]; - if (lodash.isObject(child)) { - traverseJavascript(node, i, child, f); - f(node, i, child); - } - } - } + initialize(); + return { + systemClips: _systemClips, + systemClipCount: _systemClipCount, + userClips: _userClips, + hasUserClips: _hasUserClips, + userClipCount: _userClipCount, + trashClips: _trashClips, + trashClipCount: _trashClipCount, + hasTrashClips: _hasTrashClips, + emptyTrash: emptyTrash }; - deleteAstNode = function (parent, i) { - if (_.isArray(parent)) { - return parent.splice(i, 1); - } else if (lodash.isObject(parent)) { - return delete parent[i]; + }; +}.call(this)); +(function () { + Flow.Coffeescript = function (_, guid, sandbox) { + var isRoutine, print, render, _kernel; + _kernel = Flow.CoffeescriptKernel; + print = function (arg) { + if (arg !== print) { + sandbox.results[guid].outputs(arg); } + return print; }; - createLocalScope = function (node) { - var localScope, param, _i, _len, _ref; - localScope = parseDeclarations(node.body); - _ref = node.params; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - param = _ref[_i]; - if (param.type === 'Identifier') { - localScope[param.name] = { - name: param.name, - object: 'local' - }; + isRoutine = function (f) { + var name, routine, _ref; + _ref = sandbox.routines; + for (name in _ref) { + routine = _ref[name]; + if (f === routine) { + return true; } } - return localScope; + return false; }; - coalesceScopes = function (scopes) { - var currentScope, i, identifier, name, scope, _i, _len; - currentScope = {}; - for (i = _i = 0, _len = scopes.length; _i < _len; i = ++_i) { - scope = scopes[i]; - if (i === 0) { - for (name in scope) { - identifier = scope[name]; - currentScope[name] = identifier; - } - } else { - for (name in scope) { - identifier = scope[name]; - currentScope[name] = null; - } + render = function (input, output) { + var cellResult, evaluate, outputBuffer, tasks; + sandbox.results[guid] = cellResult = { + result: Flow.Dataflow.signal(null), + outputs: outputBuffer = Flow.Async.createBuffer([]) + }; + evaluate = function (ft) { + if (ft != null ? ft.isFuture : void 0) { + return ft(function (error, result) { + var _ref; + if (error) { + return output.error(new Flow.Error('Error evaluating cell', error)); + } else { + if (ft.render) { + return ft.render(result, function (error, result) { + if (error) { + return output.error(new Flow.Error('Error rendering output', error)); + } else { + return output.data(result); + } + }); + } else if (result != null ? (_ref = result._flow_) != null ? _ref.render : void 0 : void 0) { + return output.data(result._flow_.render()); + } else { + return output.data(Flow.ObjectBrowser('output', result)); + } + } + }); + } else { + return output.data(Flow.ObjectBrowser('output', ft)); } - } - return currentScope; - }; - traverseJavascriptScoped = function (scopes, parentScope, parent, key, node, f) { - var child, currentScope, isNewScope; - isNewScope = node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration'; - if (isNewScope) { - scopes.push(createLocalScope(node)); - currentScope = coalesceScopes(scopes); - } else { - currentScope = parentScope; - } - for (key in node) { - child = node[key]; - if (lodash.isObject(child)) { - traverseJavascriptScoped(scopes, currentScope, node, key, child, f); - f(currentScope, node, key, child); + }; + outputBuffer.subscribe(evaluate); + tasks = [ + _kernel.safetyWrapCoffeescript(guid), + _kernel.compileCoffeescript, + _kernel.parseJavascript, + _kernel.createRootScope(sandbox), + _kernel.removeHoistedDeclarations, + _kernel.rewriteJavascript(sandbox), + _kernel.generateJavascript, + _kernel.compileJavascript, + _kernel.executeJavascript(sandbox, print) + ]; + return Flow.Async.pipe(tasks)(input, function (error) { + var result; + if (error) { + output.error(error); } - } - if (isNewScope) { - scopes.pop(); - } - }; - createRootScope = function (sandbox) { - return function (program, go) { - var error, name, rootScope; - try { - rootScope = parseDeclarations(program.body[0].expression['arguments'][0].callee.body); - for (name in sandbox.context) { - rootScope[name] = { - name: name, - object: '_h2o_context_' - }; + output.end(); + result = cellResult.result(); + if (lodash.isFunction(result)) { + if (isRoutine(result)) { + return print(result()); + } else { + return evaluate(result); } - return go(null, rootScope, program); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error parsing root scope', error)); + } else { + return output.close(Flow.ObjectBrowser('result', result)); } - }; + }); }; - removeHoistedDeclarations = function (rootScope, program, go) { - var error; - try { - traverseJavascript(null, null, program, function (parent, key, node) { - var declarations; - if (node.type === 'VariableDeclaration') { - declarations = node.declarations.filter(function (declaration) { - return declaration.type === 'VariableDeclarator' && declaration.id.type === 'Identifier' && !rootScope[declaration.id.name]; - }); - if (declarations.length === 0) { - return deleteAstNode(parent, key); - } else { - return node.declarations = declarations; - } - } - }); - return go(null, rootScope, program); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error rewriting javascript', error)); - } + render.isCode = true; + return render; + }; +}.call(this)); +(function () { +}.call(this)); +(function () { + var traceCauses; + traceCauses = function (error, causes) { + causes.push(error.message); + if (error.cause) { + traceCauses(error.cause, causes); + } + return causes; + }; + Flow.Failure = function (error) { + var causes, message, toggleStack, _isStackVisible; + causes = traceCauses(error, []); + message = causes.shift(); + _isStackVisible = Flow.Dataflow.signal(false); + toggleStack = function () { + return _isStackVisible(!_isStackVisible()); }; - createGlobalScope = function (rootScope, routines) { - var globalScope, identifier, name; - globalScope = {}; - for (name in rootScope) { - identifier = rootScope[name]; - globalScope[name] = identifier; - } - for (name in routines) { - globalScope[name] = { - name: name, - object: 'h2o' - }; + return { + message: message, + stack: error.stack, + causes: causes, + isStackVisible: _isStackVisible, + toggleStack: toggleStack, + template: 'flow-failure' + }; + }; +}.call(this)); +(function () { + Flow.Form = function (_, _form) { + return { + form: _form, + template: 'flow-form', + templateOf: function (control) { + return control.template; } - return globalScope; }; - rewriteJavascript = function (sandbox) { - return function (rootScope, program, go) { - var error, globalScope; - globalScope = createGlobalScope(rootScope, sandbox.routines); - try { - traverseJavascriptScoped([globalScope], globalScope, null, null, program, function (globalScope, parent, key, node) { - var identifier; - if (node.type === 'Identifier') { - if (parent.type === 'VariableDeclarator' && key === 'id') { - return; - } - if (key === 'property') { - return; - } - if (!(identifier = globalScope[node.name])) { - return; - } - return parent[key] = { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: identifier.object - }, - property: { - type: 'Identifier', - name: identifier.name - } - }; - } - }); - return go(null, program); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error rewriting javascript', error)); - } - }; + }; +}.call(this)); +(function () { + Flow.Heading = function (_, level) { + var render; + render = function (input, output) { + output.data({ + text: input.trim() || '(Untitled)', + template: 'flow-' + level + }); + return output.end(); }; - generateJavascript = function (program, go) { - var error; - try { - return go(null, escodegen.generate(program)); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error generating javascript', error)); + render.isCode = false; + return render; + }; +}.call(this)); +(function () { + Flow.Help = function (_) { + return { + assist: function () { + return _.insertAndExecuteCell('cs', 'assist'); } }; - compileJavascript = function (js, go) { - var closure, error; + }; +}.call(this)); +(function () { + Flow.Markdown = function (_) { + var render; + render = function (input, output) { + var error; try { - closure = new Function('h2o', '_h2o_context_', '_h2o_results_', 'print', js); - return go(null, closure); + return output.data({ + html: marked(input.trim() || '(No content)'), + template: 'flow-html' + }); } catch (_error) { error = _error; - return go(new Flow.Error('Error compiling javascript', error)); + return output.error(error); + } finally { + output.end(); } }; - executeJavascript = function (sandbox, print) { - return function (closure, go) { - var error; - try { - return go(null, closure(sandbox.routines, sandbox.context, sandbox.results, print)); - } catch (_error) { - error = _error; - return go(new Flow.Error('Error executing javascript', error)); - } - }; - }; - return { - safetyWrapCoffeescript: safetyWrapCoffeescript, - compileCoffeescript: compileCoffeescript, - parseJavascript: parseJavascript, - createRootScope: createRootScope, - removeHoistedDeclarations: removeHoistedDeclarations, - rewriteJavascript: rewriteJavascript, - generateJavascript: generateJavascript, - compileJavascript: compileJavascript, - executeJavascript: executeJavascript - }; - }(); + render.isCode = false; + return render; + }; }.call(this)); (function () { - var combineRanges, computeRange, createAbstractVariable, createCompiledPrototype, createFactor, createNumericVariable, createRecordConstructor, createTable, createVariable, factor, includeZeroInRange, nextPrototypeName, permute, _prototypeCache, _prototypeId, __slice = [].slice; - _prototypeId = 0; - nextPrototypeName = function () { - return 'Map' + ++_prototypeId; + Flow.Renderers = function (_, _sandbox) { + return { + h1: function () { + return Flow.Heading(_, 'h1'); + }, + h2: function () { + return Flow.Heading(_, 'h2'); + }, + h3: function () { + return Flow.Heading(_, 'h3'); + }, + h4: function () { + return Flow.Heading(_, 'h4'); + }, + h5: function () { + return Flow.Heading(_, 'h5'); + }, + h6: function () { + return Flow.Heading(_, 'h6'); + }, + md: function () { + return Flow.Markdown(_); + }, + cs: function (guid) { + return Flow.Coffeescript(_, guid, _sandbox); + }, + raw: function () { + return Flow.Raw(_); + } + }; }; - _prototypeCache = {}; - createCompiledPrototype = function (attrs) { - var attr, cacheKey, i, inits, params, proto, prototypeName; - cacheKey = attrs.join('\0'); - if (proto = _prototypeCache[cacheKey]) { - return proto; - } - params = function () { - var _i, _ref, _results; - _results = []; - for (i = _i = 0, _ref = attrs.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - _results.push('a' + i); + Flow.Notebook = function (_, _renderers) { + var checkConsistency, clearAllCells, clearCell, cloneCell, convertCellToCode, convertCellToHeading, convertCellToMarkdown, convertCellToRaw, copyCell, createCell, createMenu, createMenuItem, createNotebook, createTool, cutCell, deleteCell, deserialize, displayAbout, displayDocumentation, displayKeyboardShortcuts, duplicateNotebook, editModeKeyboardShortcuts, editModeKeyboardShortcutsHelp, editTitle, executeCommand, goToUrl, initialize, insertAbove, insertBelow, insertCell, insertCellAbove, insertCellAboveAndRun, insertCellBelow, insertCellBelowAndRun, insertNewCellAbove, insertNewCellBelow, menuDivider, mergeCellAbove, mergeCellBelow, moveCellDown, moveCellUp, normalModeKeyboardShortcuts, normalModeKeyboardShortcutsHelp, notImplemented, pasteCellAbove, pasteCellBelow, pasteCellandReplace, printPreview, removeCell, runAllCells, runCell, runCellAndInsertBelow, runCellAndSelectBelow, saveNotebook, saveTitle, selectCell, selectNextCell, selectPreviousCell, serialize, setupKeyboardHandling, showBrowser, showClipboard, showHelp, showOutline, splitCell, startTour, switchToCommandMode, switchToEditMode, switchToPresentationMode, toKeyboardHelp, toggleAllInputs, toggleAllOutputs, toggleInput, toggleOutput, toggleSidebar, undoLastDelete, _about, _areInputsHidden, _areOutputsHidden, _cells, _clipboardCell, _createdDate, _id, _isEditingTitle, _isSidebarHidden, _lastDeletedCell, _menus, _modifiedDate, _selectedCell, _selectedCellIndex, _sidebar, _status, _title, _toolbar; + _id = Flow.Dataflow.signal(''); + _title = Flow.Dataflow.signal('Untitled Flow'); + _createdDate = Flow.Dataflow.signal(new Date()); + _modifiedDate = Flow.Dataflow.signal(new Date()); + _isEditingTitle = Flow.Dataflow.signal(false); + editTitle = function () { + return _isEditingTitle(true); + }; + saveTitle = function () { + return _isEditingTitle(false); + }; + _cells = Flow.Dataflow.signals([]); + _selectedCell = null; + _selectedCellIndex = -1; + _clipboardCell = null; + _lastDeletedCell = null; + _areInputsHidden = Flow.Dataflow.signal(false); + _areOutputsHidden = Flow.Dataflow.signal(false); + _isSidebarHidden = Flow.Dataflow.signal(false); + _status = Flow.Status(_); + _sidebar = Flow.Sidebar(_, _cells); + _about = Flow.About(_); + serialize = function () { + var cell, cells; + cells = function () { + var _i, _len, _ref, _results; + _ref = _cells(); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + cell = _ref[_i]; + _results.push({ + type: cell.type(), + input: cell.input() + }); + } + return _results; + }(); + return { + title: _title(), + cells: cells, + createdDate: _createdDate().getTime(), + modifiedDate: new Date().getTime() + }; + }; + deserialize = function (id, doc) { + var cell, cells, _i, _len, _ref; + _id(id); + _title(doc.title); + _createdDate(new Date(doc.createdDate)); + _modifiedDate(new Date(doc.modifiedDate)); + cells = function () { + var _i, _len, _ref, _results; + _ref = doc.cells; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + cell = _ref[_i]; + _results.push(createCell(cell.type, cell.input)); + } + return _results; + }(); + _cells(cells); + _ref = _cells(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + cell = _ref[_i]; + if (!cell.isCode()) { + cell.execute(); + } } - return _results; - }(); - inits = function () { - var _i, _len, _results; - _results = []; - for (i = _i = 0, _len = attrs.length; _i < _len; i = ++_i) { - attr = attrs[i]; - _results.push('this[' + JSON.stringify(attr) + ']=a' + i + ';'); + selectCell(lodash.head(cells)); + }; + createCell = function (type, input) { + if (type == null) { + type = 'cs'; } - return _results; - }(); - prototypeName = nextPrototypeName(); - return _prototypeCache[cacheKey] = new Function('function ' + prototypeName + '(' + params.join(',') + '){' + inits.join('') + '} return ' + prototypeName + ';')(); - }; - createRecordConstructor = function (variables) { - var variable; - return createCompiledPrototype(function () { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = variables.length; _i < _len; _i++) { - variable = variables[_i]; - _results.push(variable.label); + if (input == null) { + input = ''; } - return _results; - }()); - }; - createTable = function (opts) { - var description, expand, fill, label, meta, rows, schema, variable, variables, _i, _len; - label = opts.label, description = opts.description, variables = opts.variables, rows = opts.rows, meta = opts.meta; - if (!description) { - description = 'No description available.'; - } - schema = {}; - for (_i = 0, _len = variables.length; _i < _len; _i++) { - variable = variables[_i]; - schema[variable.label] = variable; - } - fill = function (i, go) { - _fill(i, function (error, result) { - var index, startIndex, value, _j, _len1; - if (error) { - return go(error); + return Flow.Cell(_, _renderers, type, input); + }; + checkConsistency = function () { + var cell, i, selectionCount, _i, _len, _ref; + selectionCount = 0; + _ref = _cells(); + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + cell = _ref[i]; + if (!cell) { + error('index ' + i + ' is empty'); } else { - startIndex = result.index, lodash.values = result.values; - for (index = _j = 0, _len1 = lodash.values.length; _j < _len1; index = ++_j) { - value = lodash.values[index]; - rows[startIndex + index] = lodash.values[index]; + if (cell.isSelected()) { + selectionCount++; } - return go(null); } - }); + } + if (selectionCount !== 1) { + error('selected cell count = ' + selectionCount); + } }; - expand = function () { - var type, types, _j, _len1, _results; - types = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_j = 0, _len1 = types.length; _j < _len1; _j++) { - type = types[_j]; - label = lodash.uniqueId('__flow_variable_'); - _results.push(schema[label] = createNumericVariable(label)); + selectCell = function (target, scrollIntoView) { + if (scrollIntoView == null) { + scrollIntoView = true; } - return _results; + if (_selectedCell === target) { + return; + } + if (_selectedCell) { + _selectedCell.isSelected(false); + } + _selectedCell = target; + _selectedCell.isSelected(true); + _selectedCellIndex = _cells.indexOf(_selectedCell); + checkConsistency(); + if (scrollIntoView) { + lodash.defer(_selectedCell.scrollIntoView); + } + return _selectedCell; }; - return { - label: label, - description: description, - schema: schema, - variables: variables, - rows: rows, - meta: meta, - fill: fill, - expand: expand, - _is_table_: true + cloneCell = function (cell) { + return createCell(cell.type(), cell.input()); }; - }; - includeZeroInRange = function (range) { - var hi, lo; - lo = range[0], hi = range[1]; - if (lo > 0 && hi > 0) { - return [ - 0, - hi - ]; - } else if (lo < 0 && hi < 0) { - return [ - lo, - 0 - ]; - } else { - return range; - } - }; - combineRanges = function () { - var hi, lo, range, ranges, value, _i, _len; - ranges = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - lo = Number.POSITIVE_INFINITY; - hi = Number.NEGATIVE_INFINITY; - for (_i = 0, _len = ranges.length; _i < _len; _i++) { - range = ranges[_i]; - if (lo > (value = range[0])) { - lo = value; - } - if (hi < (value = range[1])) { - hi = value; - } - } - return [ - lo, - hi - ]; - }; - computeRange = function (rows, attr) { - var hi, lo, row, value, _i, _len; - if (rows.length) { - lo = Number.POSITIVE_INFINITY; - hi = Number.NEGATIVE_INFINITY; - for (_i = 0, _len = rows.length; _i < _len; _i++) { - row = rows[_i]; - value = row[attr]; - if (value < lo) { - lo = value; + switchToCommandMode = function () { + return _selectedCell.isActive(false); + }; + switchToEditMode = function () { + _selectedCell.isActive(true); + return false; + }; + convertCellToCode = function () { + return _selectedCell.type('cs'); + }; + convertCellToHeading = function (level) { + return function () { + _selectedCell.type('h' + level); + return _selectedCell.execute(); + }; + }; + convertCellToMarkdown = function () { + _selectedCell.type('md'); + return _selectedCell.execute(); + }; + convertCellToRaw = function () { + _selectedCell.type('raw'); + return _selectedCell.execute(); + }; + copyCell = function () { + return _clipboardCell = _selectedCell; + }; + cutCell = function () { + copyCell(); + return removeCell(); + }; + deleteCell = function () { + _lastDeletedCell = _selectedCell; + return removeCell(); + }; + removeCell = function () { + var cells, removedCell; + cells = _cells(); + if (cells.length > 1) { + if (_selectedCellIndex === cells.length - 1) { + removedCell = lodash.head(_cells.splice(_selectedCellIndex, 1)); + selectCell(cells[_selectedCellIndex - 1]); + } else { + removedCell = lodash.head(_cells.splice(_selectedCellIndex, 1)); + selectCell(cells[_selectedCellIndex]); } - if (value > hi) { - hi = value; + if (removedCell) { + _.saveClip('trash', removedCell.type(), removedCell.input()); } } - return [ - lo, - hi - ]; - } else { - return [ - -1, - 1 - ]; - } - }; - permute = function (array, indices) { - var i, index, permuted, _i, _len; - permuted = new Array(array.length); - for (i = _i = 0, _len = indices.length; _i < _len; i = ++_i) { - index = indices[i]; - permuted[i] = array[index]; - } - return permuted; - }; - createAbstractVariable = function (_label, _type, _domain, _format, _read) { - return { - label: _label, - type: _type, - domain: _domain || [], - format: _format || lodash.identity, - read: _read }; - }; - createNumericVariable = function (_label, _domain, _format, _read) { - var self; - self = createAbstractVariable(_label, Flow.TNumber, _domain || [ - Number.POSITIVE_INFINITY, - Number.NEGATIVE_INFINITY - ], _format, _read); - if (!self.read) { - self.read = function (datum) { - if (datum < self.domain[0]) { - self.domain[0] = datum; - } - if (datum > self.domain[1]) { - self.domain[1] = datum; + insertCell = function (index, cell) { + _cells.splice(index, 0, cell); + selectCell(cell); + return cell; + }; + insertAbove = function (cell) { + return insertCell(_selectedCellIndex, cell); + }; + insertBelow = function (cell) { + return insertCell(_selectedCellIndex + 1, cell); + }; + insertCellAbove = function (type, input) { + return insertAbove(createCell(type, input)); + }; + insertCellBelow = function (type, input) { + return insertBelow(createCell(type, input)); + }; + insertNewCellAbove = function () { + return insertAbove(createCell('cs')); + }; + insertNewCellBelow = function () { + return insertBelow(createCell('cs')); + }; + insertCellAboveAndRun = function (type, input) { + var cell; + cell = insertAbove(createCell(type, input)); + cell.execute(); + return cell; + }; + insertCellBelowAndRun = function (type, input) { + var cell; + cell = insertBelow(createCell(type, input)); + cell.execute(); + return cell; + }; + moveCellDown = function () { + var cells; + cells = _cells(); + if (_selectedCellIndex !== cells.length - 1) { + _cells.splice(_selectedCellIndex, 1); + _selectedCellIndex++; + _cells.splice(_selectedCellIndex, 0, _selectedCell); + } + }; + moveCellUp = function () { + var cells; + if (_selectedCellIndex !== 0) { + cells = _cells(); + _cells.splice(_selectedCellIndex, 1); + _selectedCellIndex--; + _cells.splice(_selectedCellIndex, 0, _selectedCell); + } + }; + mergeCellBelow = function () { + var cells, nextCell; + cells = _cells(); + if (_selectedCellIndex !== cells.length - 1) { + nextCell = cells[_selectedCellIndex + 1]; + if (_selectedCell.type() === nextCell.type()) { + nextCell.input(_selectedCell.input() + '\n' + nextCell.input()); + removeCell(); } - return datum; - }; - } - return self; - }; - createVariable = function (_label, _type, _domain, _format, _read) { - if (_type === Flow.TNumber) { - return createNumericVariable(_label, _domain, _format, _read); - } else { - return createAbstractVariable(_label, _type, _domain, _format, _read); - } - }; - createFactor = function (_label, _domain, _format, _read) { - var level, self, _i, _id, _len, _levels, _ref; - self = createAbstractVariable(_label, Flow.TFactor, _domain || [], _format, _read); - _id = 0; - _levels = {}; - if (self.domain.length) { - _ref = self.domain; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - level = _ref[_i]; - _levels[level] = _id++; } - } - if (!self.read) { - self.read = function (datum) { - var id; - level = datum === void 0 || datum === null ? 'null' : datum; - if (void 0 === (id = _levels[level])) { - _levels[level] = id = _id++; - self.domain.push(level); + }; + splitCell = function () { + var cursorPosition, input, left, right; + if (_selectedCell.isActive()) { + input = _selectedCell.input(); + if (input.length > 1) { + cursorPosition = _selectedCell.getCursorPosition(); + if (0 < cursorPosition && cursorPosition < input.length - 1) { + left = input.substr(0, cursorPosition); + right = input.substr(cursorPosition); + _selectedCell.input(left); + insertCell(_selectedCellIndex + 1, createCell('cs', right)); + _selectedCell.isActive(true); + } } - return id; - }; - } - return self; - }; - factor = function (array) { - var data, domain, i, id, level, levels, _i, _id, _len; - _id = 0; - levels = {}; - domain = []; - data = new Array(array.length); - for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) { - level = array[i]; - if (void 0 === (id = levels[level])) { - levels[level] = id = _id++; - domain.push(level); } - data[i] = id; - } - return [ - domain, - data - ]; - }; - Flow.Data = { - Table: createTable, - Variable: createVariable, - Factor: createFactor, - computeColumnInterpretation: function (type) { - if (type === Flow.TNumber) { - return 'c'; - } else if (type === Flow.TFactor) { - return 'd'; - } else { - return 't'; - } - }, - Record: createRecordConstructor, - computeRange: computeRange, - combineRanges: combineRanges, - includeZeroInRange: includeZeroInRange, - factor: factor, - permute: permute - }; -}.call(this)); -(function () { - var __slice = [].slice; - Flow.Dataflow = function () { - var createObservable, createObservableArray, createSignal, createSignals, createSlot, createSlots, isObservable, _act, _apply, _isSignal, _lift, _link, _merge, _react, _unlink; - createSlot = function () { - var arrow, self; - arrow = null; - self = function () { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (arrow) { - return arrow.func.apply(null, args); - } else { - return void 0; - } - }; - self.subscribe = function (func) { - console.assert(lodash.isFunction(func)); - if (arrow) { - throw new Error('Cannot re-attach slot'); - } else { - return arrow = { - func: func, - dispose: function () { - return arrow = null; - } - }; - } - }; - self.dispose = function () { - if (arrow) { - return arrow.dispose(); - } - }; - return self; - }; - createSlots = function () { - var arrows, self; - arrows = []; - self = function () { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return lodash.map(arrows, function (arrow) { - return arrow.func.apply(null, args); - }); - }; - self.subscribe = function (func) { - var arrow; - console.assert(lodash.isFunction(func)); - arrows.push(arrow = { - func: func, - dispose: function () { - return Flow.Prelude.remove(arrows, arrow); - } - }); - return arrow; - }; - self.dispose = function () { - return lodash.forEach(Flow.Prelude.copy(arrows), function (arrow) { - return arrow.dispose(); - }); - }; - return self; }; - if (typeof ko !== 'undefined' && ko !== null) { - createObservable = ko.observable; - createObservableArray = ko.observableArray; - isObservable = ko.isObservable; - } else { - createObservable = function (initialValue) { - var arrows, currentValue, notifySubscribers, self; - arrows = []; - currentValue = initialValue; - notifySubscribers = function (arrows, newValue) { - var arrow, _i, _len; - for (_i = 0, _len = arrows.length; _i < _len; _i++) { - arrow = arrows[_i]; - arrow.func(newValue); - } - }; - self = function (newValue) { - var unchanged; - if (arguments.length === 0) { - return currentValue; - } else { - unchanged = self.equalityComparer ? self.equalityComparer(currentValue, newValue) : currentValue === newValue; - if (!unchanged) { - currentValue = newValue; - return notifySubscribers(arrows, newValue); - } - } - }; - self.subscribe = function (func) { - var arrow; - console.assert(lodash.isFunction(func)); - arrows.push(arrow = { - func: func, - dispose: function () { - return Flow.Prelude.remove(arrows, arrow); - } - }); - return arrow; - }; - self.__observable__ = true; - return self; - }; - createObservableArray = createObservable; - isObservable = function (obj) { - if (obj.__observable__) { - return true; - } else { - return false; - } - }; - } - createSignal = function (value, equalityComparer) { - var observable; - if (arguments.length === 0) { - return createSignal(void 0, Flow.Prelude.never); - } else { - observable = createObservable(value); - if (lodash.isFunction(equalityComparer)) { - observable.equalityComparer = equalityComparer; - } - return observable; + pasteCellAbove = function () { + if (_clipboardCell) { + return insertCell(_selectedCellIndex, cloneCell(_clipboardCell)); } }; - _isSignal = isObservable; - createSignals = function (array) { - return createObservableArray(array || []); - }; - _link = function (source, func) { - console.assert(lodash.isFunction(source, '[signal] is not a function')); - console.assert(lodash.isFunction(source.subscribe, '[signal] does not have a [dispose] method')); - console.assert(lodash.isFunction(func, '[func] is not a function')); - return source.subscribe(func); + pasteCellBelow = function () { + if (_clipboardCell) { + return insertCell(_selectedCellIndex + 1, cloneCell(_clipboardCell)); + } }; - _unlink = function (arrows) { - var arrow, _i, _len, _results; - if (lodash.isArray(arrows)) { - _results = []; - for (_i = 0, _len = arrows.length; _i < _len; _i++) { - arrow = arrows[_i]; - console.assert(lodash.isFunction(arrow.dispose, '[arrow] does not have a [dispose] method')); - _results.push(arrow.dispose()); - } - return _results; - } else { - console.assert(lodash.isFunction(arrows.dispose, '[arrow] does not have a [dispose] method')); - return arrows.dispose(); + undoLastDelete = function () { + if (_lastDeletedCell) { + insertCell(_selectedCellIndex + 1, _lastDeletedCell); } + return _lastDeletedCell = null; }; - _apply = function (sources, func) { - return func.apply(null, lodash.map(sources, function (source) { - return source(); - })); + runCell = function () { + _selectedCell.execute(); + return false; }; - _act = function () { - var func, sources, _i; - sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; - _apply(sources, func); - return lodash.map(sources, function (source) { - return _link(source, function () { - return _apply(sources, func); - }); + runCellAndInsertBelow = function () { + _selectedCell.execute(function () { + return insertNewCellBelow(); }); + return false; }; - _react = function () { - var func, sources, _i; - sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; - return lodash.map(sources, function (source) { - return _link(source, function () { - return _apply(sources, func); - }); + runCellAndSelectBelow = function () { + _selectedCell.execute(function () { + return selectNextCell(); }); + return false; }; - _lift = function () { - var evaluate, func, sources, target, _i; - sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; - evaluate = function () { - return _apply(sources, func); - }; - target = createSignal(evaluate()); - lodash.map(sources, function (source) { - return _link(source, function () { - return target(evaluate()); - }); + saveNotebook = function () { + return _.storeNotebook(_id(), serialize(), function (error, id) { + if (error) { + return console.debug(error); + } else { + return _id(id); + } }); - return target; }; - _merge = function () { - var evaluate, func, sources, target, _i; - sources = 3 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 2) : (_i = 0, []), target = arguments[_i++], func = arguments[_i++]; - evaluate = function () { - return _apply(sources, func); - }; - target(evaluate()); - return lodash.map(sources, function (source) { - return _link(source, function () { - return target(evaluate()); - }); - }); + toggleInput = function () { + return _selectedCell.toggleInput(); }; - return { - slot: createSlot, - slots: createSlots, - signal: createSignal, - signals: createSignals, - isSignal: _isSignal, - link: _link, - unlink: _unlink, - act: _act, - react: _react, - lift: _lift, - merge: _merge + toggleOutput = function () { + return _selectedCell.toggleOutput(); }; - }(); -}.call(this)); -(function () { - var FlowError, __hasProp = {}.hasOwnProperty, __extends = function (child, parent) { - for (var key in parent) { - if (__hasProp.call(parent, key)) - child[key] = parent[key]; - } - function ctor() { - this.constructor = child; + toggleAllInputs = function () { + var cell, wereHidden, _i, _len, _ref; + wereHidden = _areInputsHidden(); + _areInputsHidden(!wereHidden); + if (wereHidden) { + _ref = _cells(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + cell = _ref[_i]; + cell.autoResize(); + } } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - child.__super__ = parent.prototype; - return child; }; - FlowError = function (_super) { - __extends(FlowError, _super); - function FlowError(message, cause) { - var error; - this.message = message; - this.cause = cause; - this.name = 'FlowError'; - error = new Error(); - if (error.stack) { - this.stack = error.stack; - } else { - this.stack = printStackTrace(); - } - } - return FlowError; - }(Error); - Flow.Error = FlowError; -}.call(this)); -(function () { - var Digits, formatDate, formatReal, formatTime, significantDigitsBeforeDecimal, __formatReal; - significantDigitsBeforeDecimal = function (value) { - return 1 + Math.floor(Math.log(Math.abs(value)) / Math.LN10); - }; - Digits = function (digits, value) { - var magnitude, sd; - if (value === 0) { - return 0; - } else { - sd = significantDigitsBeforeDecimal(value); - if (sd >= digits) { - return value.toFixed(0); - } else { - magnitude = Math.pow(10, digits - sd); - return Math.round(value * magnitude) / magnitude; - } - } - }; - if (typeof exports === 'undefined' || exports === null) { - formatTime = d3.time.format('%Y-%m-%d %H:%M:%S'); - } - formatDate = function (time) { - if (time) { - return formatTime(new Date(time)); - } else { - return '-'; - } - }; - __formatReal = {}; - formatReal = function (precision) { - var cached, format; - format = (cached = __formatReal[precision]) ? cached : __formatReal[precision] = precision === -1 ? lodash.identity : d3.format('.' + precision + 'f'); - return function (value) { - return format(value); + toggleAllOutputs = function () { + return _areOutputsHidden(!_areOutputsHidden()); }; - }; - Flow.Format = { - Digits: Digits, - Real: formatReal, - Date: formatDate - }; -}.call(this)); -(function () { - var button, checkbox, content, control, dropdown, html, listbox, markdown, text, textarea, textbox, wrapArray, wrapValue; - wrapValue = function (value, init) { - if (value === void 0) { - return Flow.Dataflow.signal(init); - } else { - if (Flow.Dataflow.isSignal(value)) { - return value; - } else { - return Flow.Dataflow.signal(value); + toggleSidebar = function () { + return _isSidebarHidden(!_isSidebarHidden()); + }; + showBrowser = function () { + _isSidebarHidden(false); + return _.showBrowser(); + }; + showOutline = function () { + _isSidebarHidden(false); + return _.showOutline(); + }; + showClipboard = function () { + _isSidebarHidden(false); + return _.showClipboard(); + }; + selectNextCell = function () { + var cells; + cells = _cells(); + if (_selectedCellIndex !== cells.length - 1) { + selectCell(cells[_selectedCellIndex + 1]); } - } - }; - wrapArray = function (elements) { - var element; - if (elements) { - if (Flow.Dataflow.isSignal(elements)) { - element = elements(); - if (lodash.isArray(element)) { - return elements; - } else { - return Flow.Dataflow.signal([element]); - } - } else { - return Flow.Dataflow.signals(lodash.isArray(elements) ? elements : [elements]); + return false; + }; + selectPreviousCell = function () { + var cells; + if (_selectedCellIndex !== 0) { + cells = _cells(); + selectCell(cells[_selectedCellIndex - 1]); } - } else { - return Flow.Dataflow.signals([]); - } - }; - control = function (type, opts) { - var guid; - if (!opts) { - opts = {}; - } - guid = 'gui_' + lodash.uniqueId(); - return { - type: type, - id: opts.id || guid, - label: Flow.Dataflow.signal(opts.label || ' '), - description: Flow.Dataflow.signal(opts.description || ' '), - visible: Flow.Dataflow.signal(opts.visible === false ? false : true), - disable: Flow.Dataflow.signal(opts.disable === true ? true : false), - template: 'flow-form-' + type, - templateOf: function (control) { - return control.template; + return false; + }; + displayKeyboardShortcuts = function () { + return $('#keyboardShortcutsDialog').modal(); + }; + displayDocumentation = function () { + var hash, hashEntry; + hash = Flow.Version ? (hashEntry = lodash.find(Flow.Version, function (entry) { + return entry.caption === 'H2O Build git hash'; + }), hashEntry ? hashEntry.value : 'master') : 'master'; + return window.open('https://github.com/h2oai/h2o-dev/blob/' + hash + '/h2o-docs/src/product/flow/README.md', '_blank'); + }; + executeCommand = function (command) { + return function () { + return _.insertAndExecuteCell('cs', command); + }; + }; + displayAbout = function () { + return $('#aboutDialog').modal(); + }; + showHelp = function () { + _isSidebarHidden(false); + return _.showHelp(); + }; + createNotebook = function () { + var currentTime; + currentTime = new Date().getTime(); + return deserialize(null, { + title: 'Untitled Flow', + cells: [{ + type: 'cs', + input: '' + }], + createdDate: currentTime, + modifiedDate: currentTime + }); + }; + duplicateNotebook = function () { + var doc; + doc = serialize(); + doc.title = 'Copy of ' + doc.title; + doc.createdDate = doc.modifiedDate; + deserialize(null, doc); + return saveNotebook(); + }; + goToUrl = function (url) { + return function () { + return window.open(url, '_blank'); + }; + }; + notImplemented = function () { + }; + printPreview = notImplemented; + pasteCellandReplace = notImplemented; + mergeCellAbove = notImplemented; + switchToPresentationMode = notImplemented; + runAllCells = notImplemented; + clearCell = notImplemented; + clearAllCells = notImplemented; + startTour = notImplemented; + createMenu = function (label, items) { + return { + label: label, + items: items + }; + }; + createMenuItem = function (label, action, isDisabled) { + if (isDisabled == null) { + isDisabled = false; } + return { + label: label, + action: action, + isAction: true, + isDisabled: isDisabled + }; }; - }; - content = function (type, opts) { - var self; - self = control(type, opts); - self.value = wrapValue(opts.value, ''); - return self; - }; - text = function (opts) { - return content('text', opts); - }; - html = function (opts) { - return content('html', opts); - }; - markdown = function (opts) { - return content('markdown', opts); - }; - checkbox = function (opts) { - var self; - self = control('checkbox', opts); - self.value = wrapValue(opts.value, opts.value ? true : false); - return self; - }; - dropdown = function (opts) { - var self; - self = control('dropdown', opts); - self.options = opts.options || []; - self.value = wrapValue(opts.value); - self.caption = opts.caption || 'Choose...'; - return self; - }; - listbox = function (opts) { - var self; - self = control('listbox', opts); - self.options = opts.options || []; - self.values = wrapArray(opts.values); - return self; - }; - textbox = function (opts) { - var self; - self = control('textbox', opts); - self.value = wrapValue(opts.value, ''); - self.event = lodash.isString(opts.event) ? opts.event : null; - return self; - }; - textarea = function (opts) { - var self; - self = control('textarea', opts); - self.value = wrapValue(opts.value, ''); - self.event = lodash.isString(opts.event) ? opts.event : null; - self.rows = lodash.isNumber(opts.rows) ? opts.rows : 5; - return self; - }; - button = function (opts) { - var self; - self = control('button', opts); - self.click = lodash.isFunction(opts.click) ? opts.click : lodash.noop; - return self; - }; - Flow.Gui = { - text: text, - html: html, - markdown: markdown, - checkbox: checkbox, - dropdown: dropdown, - listbox: listbox, - textbox: textbox, - textarea: textarea, - button: button - }; -}.call(this)); -(function () { - var compile, _templateCache, __slice = [].slice; - compile = function (template, type) { - var attrs, beginTag, classes, closeTag, id, index, name, tmpl, _ref; - if (0 <= (index = template.indexOf(' '))) { - tmpl = template.substr(0, index); - attrs = template.substr(index); - } else { - tmpl = template; - } - _ref = tmpl.split(/\.+/g), name = _ref[0], classes = 2 <= _ref.length ? __slice.call(_ref, 1) : []; - if (0 === name.indexOf('#')) { - id = name.substr(1); - name = 'div'; - } - if (name === '') { - name = 'div'; - } - beginTag = '<' + name; - if (id) { - beginTag += ' id=\'' + id + '\''; - } - if (classes.length) { - beginTag += ' class=\'' + classes.join(' ') + '\''; - } - if (attrs) { - beginTag += attrs; - } - beginTag += '>'; - closeTag = ''; - if (type === '=') { - return function (content) { - return beginTag + (content !== null && content !== void 0 ? content : '') + closeTag; - }; - } else if (type === '+') { - return function (content, arg0) { - var tag; - tag = beginTag.replace('{0}', arg0); - return tag + content + closeTag; - }; - } else { - return function (contents) { - return beginTag + contents.join('') + closeTag; - }; - } - }; - _templateCache = {}; - Flow.HTML = { - template: function () { - var cached, template, templates, type, _i, _len, _results; - templates = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_i = 0, _len = templates.length; _i < _len; _i++) { - template = templates[_i]; - if (cached = _templateCache[template]) { - _results.push(cached); - } else { - type = template.charAt(0); - if (type === '=' || type === '+') { - _results.push(_templateCache[template] = compile(template.substr(1), type)); - } else { - _results.push(_templateCache[template] = compile(template)); - } - } - } - return _results; - }, - render: function (name, html) { - var el; - el = document.createElement(name); - if (html) { - if (lodash.isString(html)) { - el.innerHTML = html; - } else { - el.appendChild(html); - } - } - return el; - } - }; -}.call(this)); -(function () { - if ((typeof window !== 'undefined' && window !== null ? window.ko : void 0) == null) { - return; - } - ko.bindingHandlers.raw = { - update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $element, arg; - arg = ko.unwrap(valueAccessor()); - if (arg) { - $element = $(element); - $element.empty(); - $element.append(arg); - } - } - }; - ko.bindingHandlers.markdown = { - update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var data, error, html; - data = ko.unwrap(valueAccessor()); - try { - html = marked(data || ''); - } catch (_error) { - error = _error; - html = error.message || 'Error rendering markdown.'; - } - return $(element).html(html); - } - }; - ko.bindingHandlers.stringify = { - update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var data; - data = ko.unwrap(valueAccessor()); - return $(element).text(JSON.stringify(data, null, 2)); - } - }; - ko.bindingHandlers.enterKey = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $element, action; - if (action = ko.unwrap(valueAccessor())) { - if (lodash.isFunction(action)) { - $element = $(element); - $element.keydown(function (e) { - if (e.which === 13) { - action(viewModel); - } - }); - } else { - throw 'Enter key action is not a function'; - } + menuDivider = { isAction: false }; + _menus = [ + createMenu('Flow', [ + createMenuItem('New', createNotebook), + createMenuItem('Save', saveNotebook), + menuDivider, + createMenuItem('Duplicate', duplicateNotebook), + menuDivider, + createMenuItem('Print Preview', printPreview, true) + ]), + createMenu('Edit', [ + createMenuItem('Cut Cell', cutCell), + createMenuItem('Copy Cell', copyCell), + createMenuItem('Paste Cell Above', pasteCellAbove), + createMenuItem('Paste Cell Below', pasteCellBelow), + createMenuItem('Paste Cell and Replace', pasteCellandReplace, true), + createMenuItem('Delete Cell', deleteCell), + createMenuItem('Undo Delete Cell', undoLastDelete), + menuDivider, + createMenuItem('Insert Cell Above', insertNewCellAbove), + createMenuItem('Insert Cell Below', insertNewCellBelow), + menuDivider, + createMenuItem('Split Cell', splitCell), + createMenuItem('Merge Cell Above', mergeCellAbove, true), + createMenuItem('Merge Cell Below', mergeCellBelow), + menuDivider, + createMenuItem('Move Cell Up', moveCellUp), + createMenuItem('Move Cell Down', moveCellDown) + ]), + createMenu('View', [ + createMenuItem('Toggle Input', toggleInput), + createMenuItem('Toggle Output', toggleOutput), + menuDivider, + createMenuItem('Toggle All Inputs', toggleAllInputs), + createMenuItem('Toggle All Outputs', toggleAllOutputs), + menuDivider, + createMenuItem('Toggle Sidebar', toggleSidebar), + createMenuItem('Outline', showOutline), + createMenuItem('Files', showBrowser), + createMenuItem('Clipboard', showClipboard), + menuDivider, + createMenuItem('Presentation Mode', switchToPresentationMode, true) + ]), + createMenu('Format', [ + createMenuItem('Code', convertCellToCode), + menuDivider, + createMenuItem('Heading 1', convertCellToHeading(1)), + createMenuItem('Heading 2', convertCellToHeading(2)), + createMenuItem('Heading 3', convertCellToHeading(3)), + createMenuItem('Heading 4', convertCellToHeading(4)), + createMenuItem('Heading 5', convertCellToHeading(5)), + createMenuItem('Heading 6', convertCellToHeading(6)), + createMenuItem('Markdown', convertCellToMarkdown), + createMenuItem('Raw', convertCellToRaw) + ]), + createMenu('Run', [ + createMenuItem('Run', runCell), + createMenuItem('Run and Select Below', runCellAndSelectBelow), + createMenuItem('Run and Insert Below', runCellAndInsertBelow), + menuDivider, + createMenuItem('Run All', runAllCells, true), + menuDivider, + createMenuItem('Clear Cell', clearCell, true), + menuDivider, + createMenuItem('Clear All', clearAllCells, true) + ]), + createMenu('Admin', [ + createMenuItem('Jobs', executeCommand('getJobs')), + createMenuItem('Cluster Status', executeCommand('getCloud')), + createMenuItem('Inspect Log', executeCommand('getLogFile 0')), + createMenuItem('Download Log', goToUrl('/Logs/download')), + createMenuItem('Profiler', executeCommand('getProfile depth: 10')), + createMenuItem('Stack Trace', executeCommand('getStackTrace')), + createMenuItem('Timeline', executeCommand('getTimeline')) + ]), + createMenu('Help', [ + createMenuItem('Tour', startTour, true), + createMenuItem('Contents', showHelp), + createMenuItem('Keyboard Shortcuts', displayKeyboardShortcuts), + menuDivider, + createMenuItem('H2O Documentation', displayDocumentation), + createMenuItem('h2o.ai', goToUrl('http://h2o.ai/')), + menuDivider, + createMenuItem('About', displayAbout) + ]) + ]; + createTool = function (icon, label, action, isDisabled) { + if (isDisabled == null) { + isDisabled = false; } - } - }; - ko.bindingHandlers.typeahead = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $element, action; - if (action = ko.unwrap(valueAccessor())) { - if (lodash.isFunction(action)) { - $element = $(element); - $element.typeahead(null, { - displayKey: 'value', - source: action - }); - } else { - throw 'Typeahead action is not a function'; - } + return { + label: label, + action: action, + isDisabled: isDisabled, + icon: 'fa fa-' + icon + }; + }; + _toolbar = [ + [createTool('save', 'Save', saveNotebook)], + [ + createTool('plus', 'Insert Cell Below', insertNewCellBelow), + createTool('arrow-up', 'Move Cell Up', moveCellUp), + createTool('arrow-down', 'Move Cell Down', moveCellDown) + ], + [ + createTool('cut', 'Cut Cell', cutCell), + createTool('copy', 'Copy Cell', copyCell), + createTool('paste', 'Paste Cell Below', pasteCellBelow) + ], + [createTool('play', 'Run', runCell)] + ]; + normalModeKeyboardShortcuts = [ + [ + 'enter', + 'edit mode', + switchToEditMode + ], + [ + 'y', + 'to code', + convertCellToCode + ], + [ + 'm', + 'to markdown', + convertCellToMarkdown + ], + [ + 'r', + 'to raw', + convertCellToRaw + ], + [ + '1', + 'to heading 1', + convertCellToHeading(1) + ], + [ + '2', + 'to heading 2', + convertCellToHeading(2) + ], + [ + '3', + 'to heading 3', + convertCellToHeading(3) + ], + [ + '4', + 'to heading 4', + convertCellToHeading(4) + ], + [ + '5', + 'to heading 5', + convertCellToHeading(5) + ], + [ + '6', + 'to heading 6', + convertCellToHeading(6) + ], + [ + 'up', + 'select previous cell', + selectPreviousCell + ], + [ + 'down', + 'select next cell', + selectNextCell + ], + [ + 'k', + 'select previous cell', + selectPreviousCell + ], + [ + 'j', + 'select next cell', + selectNextCell + ], + [ + 'ctrl+k', + 'move cell up', + moveCellUp + ], + [ + 'ctrl+j', + 'move cell down', + moveCellDown + ], + [ + 'a', + 'insert cell above', + insertNewCellAbove + ], + [ + 'b', + 'insert cell below', + insertNewCellBelow + ], + [ + 'x', + 'cut cell', + cutCell + ], + [ + 'c', + 'copy cell', + copyCell + ], + [ + 'shift+v', + 'paste cell above', + pasteCellAbove + ], + [ + 'v', + 'paste cell below', + pasteCellBelow + ], + [ + 'z', + 'undo last delete', + undoLastDelete + ], + [ + 'd d', + 'delete cell (press twice)', + deleteCell + ], + [ + 'shift+m', + 'merge cell below', + mergeCellBelow + ], + [ + 's', + 'save notebook', + saveNotebook + ], + [ + 'o', + 'toggle output', + toggleOutput + ], + [ + 'h', + 'keyboard shortcuts', + displayKeyboardShortcuts + ] + ]; + editModeKeyboardShortcuts = [ + [ + 'esc', + 'command mode', + switchToCommandMode + ], + [ + 'ctrl+m', + 'command mode', + switchToCommandMode + ], + [ + 'shift+enter', + 'run cell, select below', + runCellAndSelectBelow + ], + [ + 'ctrl+enter', + 'run cell', + runCell + ], + [ + 'alt+enter', + 'run cell, insert below', + runCellAndInsertBelow + ], + [ + 'ctrl+shift+-', + 'split cell', + splitCell + ], + [ + 'mod+s', + 'save notebook', + saveNotebook + ] + ]; + toKeyboardHelp = function (shortcut) { + var caption, keystrokes, sequence; + sequence = shortcut[0], caption = shortcut[1]; + keystrokes = lodash.map(sequence.split(/\+/g), function (key) { + return '' + key + ''; + }).join(' '); + return { + keystrokes: keystrokes, + caption: caption + }; + }; + normalModeKeyboardShortcutsHelp = lodash.map(normalModeKeyboardShortcuts, toKeyboardHelp); + editModeKeyboardShortcutsHelp = lodash.map(editModeKeyboardShortcuts, toKeyboardHelp); + setupKeyboardHandling = function (mode) { + var caption, f, shortcut, _i, _j, _len, _len1, _ref, _ref1; + for (_i = 0, _len = normalModeKeyboardShortcuts.length; _i < _len; _i++) { + _ref = normalModeKeyboardShortcuts[_i], shortcut = _ref[0], caption = _ref[1], f = _ref[2]; + Mousetrap.bind(shortcut, f); } - } - }; - ko.bindingHandlers.cursorPosition = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var arg; - if (arg = ko.unwrap(valueAccessor())) { - arg.getCursorPosition = function () { - return $(element).textrange('get', 'position'); - }; + for (_j = 0, _len1 = editModeKeyboardShortcuts.length; _j < _len1; _j++) { + _ref1 = editModeKeyboardShortcuts[_j], shortcut = _ref1[0], caption = _ref1[1], f = _ref1[2]; + Mousetrap.bindGlobal(shortcut, f); } - } - }; - ko.bindingHandlers.autoResize = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $el, arg, resize; - if (arg = ko.unwrap(valueAccessor())) { - arg.autoResize = resize = function () { - return lodash.defer(function () { - return $el.css('height', 'auto').height(element.scrollHeight); - }); - }; - $el = $(element).on('input', resize); - resize(); + }; + initialize = function () { + setupKeyboardHandling('normal'); + insertNewCellBelow(); + Flow.Dataflow.link(_.loadNotebook, deserialize); + Flow.Dataflow.link(_.selectCell, selectCell); + Flow.Dataflow.link(_.insertAndExecuteCell, function (type, input) { + return lodash.defer(insertCellBelowAndRun, type, input); + }); + return Flow.Dataflow.link(_.insertCell, function (type, input) { + return lodash.defer(insertCellBelow, type, input); + }); + }; + Flow.Dataflow.link(_.ready, initialize); + return { + title: _title, + isEditingTitle: _isEditingTitle, + editTitle: editTitle, + saveTitle: saveTitle, + menus: _menus, + sidebar: _sidebar, + status: _status, + toolbar: _toolbar, + cells: _cells, + areInputsHidden: _areInputsHidden, + areOutputsHidden: _areOutputsHidden, + isSidebarHidden: _isSidebarHidden, + shortcutsHelp: { + normalMode: normalModeKeyboardShortcutsHelp, + editMode: editModeKeyboardShortcutsHelp + }, + about: _about, + templateOf: function (view) { + return view.template; } - } + }; }; - ko.bindingHandlers.scrollIntoView = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $el, $viewport, arg; - if (arg = ko.unwrap(valueAccessor())) { - $el = $(element); - $viewport = $el.closest('.flow-box-notebook'); - arg.scrollIntoView = function () { - var height, position, top; - position = $viewport.scrollTop(); - top = $el.position().top + position; - height = $viewport.height(); - if (top - 20 < position || top + 20 > position + height) { - return $viewport.animate({ scrollTop: top }, 'fast'); - } - }; - } +}.call(this)); +(function () { + var isExpandable, preview, previewArray, previewObject; + isExpandable = function (type) { + switch (type) { + case 'null': + case 'undefined': + case 'Boolean': + case 'String': + case 'Number': + case 'Date': + case 'RegExp': + case 'Arguments': + case 'Function': + return false; + default: + return true; } }; - ko.bindingHandlers.dom = { - update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var $element, arg; - arg = ko.unwrap(valueAccessor()); - if (arg) { - $element = $(element); - $element.empty(); - $element.append(arg); + previewArray = function (array) { + var element, ellipsis, previews; + ellipsis = array.length > 5 ? ', ...' : ''; + previews = function () { + var _i, _len, _ref, _results; + _ref = lodash.head(array, 5); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + element = _ref[_i]; + _results.push(preview(element)); } - } - }; - ko.bindingHandlers.dump = { - init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { - var object; - return object = ko.unwrap(valueAccessor()); - } - }; -}.call(this)); -(function () { - var keyOf, list, purge, purgeAll, read, write, _ls; - _ls = window.localStorage; - keyOf = function (type, id) { - return '' + type + ':' + id; + return _results; + }(); + return '[' + previews.join(', ') + ellipsis + ']'; }; - list = function (type) { - var i, id, key, objs, t, _i, _ref, _ref1; - objs = []; - for (i = _i = 0, _ref = _ls.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - key = _ls.key(i); - _ref1 = key.split(':'), t = _ref1[0], id = _ref1[1]; - if (type === t) { - objs.push([ - type, - id, - JSON.parse(_ls.getItem(key)) - ]); + previewObject = function (object) { + var count, ellipsis, key, previews, value; + count = 0; + previews = []; + ellipsis = ''; + for (key in object) { + value = object[key]; + if (!(key !== '_flow_')) { + continue; + } + previews.push('' + key + ': ' + preview(value)); + if (++count === 5) { + ellipsis = ', ...'; + break; } } - return objs; + return '{' + previews.join(', ') + ellipsis + '}'; }; - read = function (type, id) { - var raw; - if (raw = _ls.getobj(keyOf(type, id))) { - return JSON.parse(raw); - } else { - return null; + preview = function (element, recurse) { + var type; + if (recurse == null) { + recurse = false; } - }; - write = function (type, id, obj) { - return _ls.setItem(keyOf(type, id), JSON.stringify(obj)); - }; - purge = function (type, id) { - if (id) { - return _ls.removeItem(keyOf(type, id)); - } else { - return purgeAll(type); + type = Flow.Prelude.typeOf(element); + switch (type) { + case 'Boolean': + case 'String': + case 'Number': + case 'Date': + case 'RegExp': + return element; + case 'undefined': + case 'null': + case 'Function': + case 'Arguments': + return type; + case 'Array': + if (recurse) { + return previewArray(element); + } else { + return type; + } + break; + default: + if (recurse) { + return previewObject(element); + } else { + return type; + } } }; - purgeAll = function (type) { - var i, key, _i, _len; - lodash.keys = function () { - var _i, _ref, _results; - _results = []; - for (i = _i = 0, _ref = _ls.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - _results.push(_ls.key(i)); + Flow.ObjectBrowserElement = function (key, object) { + var toggle, _canExpand, _expansions, _isExpanded, _type; + _expansions = Flow.Dataflow.signal(null); + _isExpanded = Flow.Dataflow.signal(false); + _type = Flow.Prelude.typeOf(object); + _canExpand = isExpandable(_type); + toggle = function () { + var expansions, value; + if (!_canExpand) { + return; } - return _results; - }(); - for (_i = 0, _len = lodash.keys.length; _i < _len; _i++) { - key = lodash.keys[_i]; - if (type === lodash.head(key.split(':'))) { - _ls.removeItem(key); + if (_expansions() === null) { + expansions = []; + for (key in object) { + value = object[key]; + if (key !== '_flow_') { + expansions.push(Flow.ObjectBrowserElement(key, value)); + } + } + _expansions(expansions); } - } + return _isExpanded(!_isExpanded()); + }; + return { + key: key, + preview: preview(object, true), + toggle: toggle, + expansions: _expansions, + isExpanded: _isExpanded, + canExpand: _canExpand + }; }; - Flow.LocalStorage = { - list: list, - read: read, - write: write, - purge: purge + Flow.ObjectBrowser = function (key, object) { + return { + object: Flow.ObjectBrowserElement(key, object), + template: 'flow-object' + }; }; }.call(this)); (function () { - if ((typeof window !== 'undefined' && window !== null ? window.marked : void 0) == null) { - return; - } - marked.setOptions({ - smartypants: true, - highlight: function (code, lang) { - if (window.hljs) { - return window.hljs.highlightAuto(code, [lang]).value; - } else { - return code; - } - } - }); + Flow.Outline = function (_, _cells) { + return { cells: _cells }; + }; }.call(this)); (function () { - var computeDomain, createAxis, createLinearScale, createOrdinalBandScale, plot, renderD3BarChart, renderD3StackedBar, stack; - computeDomain = function (table, variableName) { - var level, levels, row, value, _i, _len, _ref; - levels = {}; - _ref = table.rows; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - row = _ref[_i]; - value = row[variableName]; - if (!(level = levels[value])) { - levels[value] = true; - } - } - return lodash.keys(levels); + Flow.Raw = function (_) { + var render; + render = function (input, output) { + output.data({ + text: input, + template: 'flow-raw' + }); + return output.end(); + }; + render.isCode = false; + return render; }; - createOrdinalBandScale = function (domain, range) { - return d3.scale.ordinal().domain(domain).rangeRoundBands(range, 0.1); +}.call(this)); +(function () { + Flow.Sidebar = function (_, cells) { + var switchToBrowser, switchToClipboard, switchToHelp, switchToOutline, _browser, _clipboard, _help, _isBrowserMode, _isClipboardMode, _isHelpMode, _isOutlineMode, _mode, _outline; + _mode = Flow.Dataflow.signal('help'); + _outline = Flow.Outline(_, cells); + _isOutlineMode = Flow.Dataflow.lift(_mode, function (mode) { + return mode === 'outline'; + }); + switchToOutline = function () { + return _mode('outline'); + }; + _browser = Flow.Browser(_); + _isBrowserMode = Flow.Dataflow.lift(_mode, function (mode) { + return mode === 'browser'; + }); + switchToBrowser = function () { + return _mode('browser'); + }; + _clipboard = Flow.Clipboard(_); + _isClipboardMode = Flow.Dataflow.lift(_mode, function (mode) { + return mode === 'clipboard'; + }); + switchToClipboard = function () { + return _mode('clipboard'); + }; + _help = Flow.Help(_); + _isHelpMode = Flow.Dataflow.lift(_mode, function (mode) { + return mode === 'help'; + }); + switchToHelp = function () { + return _mode('help'); + }; + Flow.Dataflow.link(_.ready, function () { + Flow.Dataflow.link(_.showHelp, function () { + return switchToHelp(); + }); + Flow.Dataflow.link(_.showClipboard, function () { + return switchToClipboard(); + }); + Flow.Dataflow.link(_.showBrowser, function () { + return switchToBrowser(); + }); + return Flow.Dataflow.link(_.showOutline, function () { + return switchToOutline(); + }); + }); + return { + outline: _outline, + isOutlineMode: _isOutlineMode, + switchToOutline: switchToOutline, + browser: _browser, + isBrowserMode: _isBrowserMode, + switchToBrowser: switchToBrowser, + clipboard: _clipboard, + isClipboardMode: _isClipboardMode, + switchToClipboard: switchToClipboard, + help: _help, + isHelpMode: _isHelpMode, + switchToHelp: switchToHelp + }; }; - createLinearScale = function (domain, range) { - return d3.scale.linear().domain(domain).range(range); +}.call(this)); +(function () { + Flow.Status = function (_) { + var defaultMessage, onStatus, _connections, _isBusy, _message; + defaultMessage = 'Ready'; + _message = Flow.Dataflow.signal(defaultMessage); + _connections = Flow.Dataflow.signal(0); + _isBusy = Flow.Dataflow.lift(_connections, function (connections) { + return connections > 0; + }); + onStatus = function (category, type, data) { + var connections; + console.debug(category, type, data); + switch (category) { + case 'server': + switch (type) { + case 'request': + _connections(_connections() + 1); + return lodash.defer(_message, 'Requesting ' + data); + case 'response': + case 'error': + _connections(connections = _connections() - 1); + if (connections) { + return lodash.defer(_message, 'Waiting for ' + connections + ' responses...'); + } else { + return lodash.defer(_message, defaultMessage); + } + } + } + }; + Flow.Dataflow.link(_.ready, function () { + return Flow.Dataflow.link(_.status, onStatus); + }); + return { + message: _message, + connections: _connections, + isBusy: _isBusy + }; }; - createAxis = function (scale, opts) { - var axis; - axis = d3.svg.axis().scale(scale); - if (opts.orient) { - axis.orient(opts.orient); - } - if (opts.ticks) { - axis.ticks(opts.ticks); - } - return axis; +}.call(this)); +(function () { + Flow.ApplicationContext = function (_) { + _.ready = Flow.Dataflow.slots(); + _.status = Flow.Dataflow.slot(); + _.selectCell = Flow.Dataflow.slot(); + _.insertCell = Flow.Dataflow.slot(); + _.insertAndExecuteCell = Flow.Dataflow.slot(); + _.showHelp = Flow.Dataflow.slot(); + _.showOutline = Flow.Dataflow.slot(); + _.showBrowser = Flow.Dataflow.slot(); + _.showClipboard = Flow.Dataflow.slot(); + _.saveClip = Flow.Dataflow.slot(); + _.loadNotebook = Flow.Dataflow.slot(); + return _.storeNotebook = Flow.Dataflow.slot(); }; - renderD3StackedBar = function (title, table, attrX1, attrX2, attrColor) { - var availableHeight, availableWidth, axisX, bar, d, domainX, el, h4, height, items, label, legend, legendEl, legends, margin, rows, scaleColor, scaleX, schema, svg, svgAxisX, swatch, tooltip, variableColor, variableX1, variableX2, variables, viz, width, _ref; - schema = table.schema, variables = table.variables, rows = table.rows; - variableX1 = table.schema[attrX1]; - variableX2 = table.schema[attrX2]; - variableColor = table.schema[attrColor]; - domainX = Flow.Data.combineRanges(variableX1.domain, variableX2.domain); - availableWidth = 450; - availableHeight = 16 + 30; - margin = { - top: 0, - right: 10, - bottom: 30, - left: 10 - }; - width = availableWidth - margin.left - margin.right; - height = availableHeight - margin.top - margin.bottom; - scaleX = d3.scale.linear().domain(domainX).range([ - 0, - width - ]); - scaleColor = d3.scale.ordinal().domain(variableColor.domain).range(d3.scale.category10().range()); - axisX = createAxis(scaleX, { orient: 'bottom' }); - svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - viz = d3.select(svg).attr('class', 'plot').attr('width', availableWidth).attr('height', availableHeight).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - svgAxisX = viz.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axisX); - tooltip = function (d) { - var tip, variable, _i, _len; - tip = ''; - for (_i = 0, _len = variables.length; _i < _len; _i++) { - variable = variables[_i]; - tip += '' + variable.label + ': ' + (variable.type === Flow.TFactor ? variable.domain[d[variable.label]] : d[variable.label]) + '\n'; - } - return tip.trim(); +}.call(this)); +(function () { + Flow.Application = function (_, routines) { + var _notebook, _renderers, _routines, _sandbox; + Flow.ApplicationContext(_); + _routines = routines(_); + _sandbox = Flow.Sandbox(_, _routines); + _renderers = Flow.Renderers(_, _sandbox); + _notebook = Flow.Notebook(_, _renderers); + return { + context: _, + sandbox: _sandbox, + view: _notebook }; - bar = viz.selectAll('.bar').data(rows).enter().append('rect').attr('class', 'bar').attr('x', function (d) { - return scaleX(d[attrX1]); - }).attr('width', function (d) { - return scaleX(d[attrX2] - d[attrX1]); - }).attr('height', height).style('fill', function (d) { - return scaleColor(variableColor.domain[d[attrColor]]); - }).append('title').text(tooltip); - _ref = Flow.HTML.template('.flow-legend', 'span.flow-legend-item', '+span.flow-legend-swatch style=\'background:{0}\'', '=span.flow-legend-label'), legends = _ref[0], legend = _ref[1], swatch = _ref[2], label = _ref[3]; - items = function () { - var _i, _len, _ref1, _results; - _ref1 = variableColor.domain; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - d = _ref1[_i]; - _results.push(legend([ - swatch('', scaleColor(d)), - label(d) - ])); - } - return _results; - }(); - legendEl = Flow.HTML.render('div', legends(items)); - el = document.createElement('div'); - if (title) { - h4 = Flow.HTML.template('=h4')[0]; - el.appendChild(Flow.HTML.render('div', h4(lodash.escape(title)))); - } - el.appendChild(svg); - el.appendChild(legendEl); - return el; }; - renderD3BarChart = function (title, table, attrX, attrY) { - var availableHeight, availableWidth, axisX, axisY, domainX, domainY, el, h4, height, heightY, interpretationX, interpretationXY, interpretationY, margin, positionX, positionY, row, rows, scaleX, scaleY, schema, svg, svgAxisX, svgAxisY, variableX, variableY, variables, viz, width, widthX; - schema = table.schema, variables = table.variables, rows = table.rows; - variableX = schema[attrX]; - variableY = schema[attrY]; - interpretationX = Flow.Data.computevariableInterpretation(variableX.type); - interpretationY = Flow.Data.computevariableInterpretation(variableY.type); - interpretationXY = interpretationX + interpretationY; - domainX = function () { - var _i, _len, _results; - if (interpretationX === 'c') { - return Flow.Data.includeZeroInRange(variableX.domain); +}.call(this)); +(function () { + var createBuffer, iterate, pipe, renderable, _applicate, _async, _find, _find$2, _find$3, _fork, _get, _isFuture, _join, _noop, __slice = [].slice; + createBuffer = function (array) { + var buffer, _array, _go; + _array = array || []; + _go = null; + buffer = function (element) { + if (element === void 0) { + return _array; } else { - _results = []; - for (_i = 0, _len = rows.length; _i < _len; _i++) { - row = rows[_i]; - _results.push(variableX.domain[row[attrX]]); + _array.push(element); + if (_go) { + _go(element); } - return _results; + return element; } - }(); - domainY = function () { - var _i, _len, _results; - if (interpretationY === 'c') { - return Flow.Data.includeZeroInRange(variableY.domain); - } else { - _results = []; - for (_i = 0, _len = rows.length; _i < _len; _i++) { - row = rows[_i]; - _results.push(variableY.domain[row[attrY]]); + }; + buffer.subscribe = function (go) { + return _go = go; + }; + buffer.buffer = _array; + buffer.isBuffer = true; + return buffer; + }; + _noop = function (go) { + return go(null); + }; + _applicate = function (go) { + return function (error, args) { + if (lodash.isFunction(go)) { + return go.apply(null, [error].concat(args)); + } + }; + }; + renderable = function () { + var args, f, ft, render, _i; + f = arguments[0], args = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), render = arguments[_i++]; + ft = _fork(f, args); + ft.render = render; + return ft; + }; + _fork = function (f, args) { + var self; + self = function (go) { + var canGo; + canGo = lodash.isFunction(go); + if (self.settled) { + if (self.rejected) { + if (canGo) { + return go(self.error); + } + } else { + if (canGo) { + return go(null, self.result); + } } - return _results; + } else { + return _join(args, function (error, args) { + if (error) { + self.error = error; + self.fulfilled = false; + self.rejected = true; + if (canGo) { + return go(error); + } + } else { + return f.apply(null, args.concat(function (error, result) { + if (error) { + self.error = error; + self.fulfilled = false; + self.rejected = true; + if (canGo) { + go(error); + } + } else { + self.result = result; + self.fulfilled = true; + self.rejected = false; + if (canGo) { + go(null, result); + } + } + self.settled = true; + return self.pending = false; + })); + } + }); } - }(); - availableWidth = interpretationX === 'c' ? 500 : domainX.length * 20; - availableHeight = interpretationY === 'c' ? 500 : domainY.length * 20; - margin = { - top: 20, - right: 20, - bottom: 30, - left: 40 }; - width = availableWidth - margin.left - margin.right; - height = availableHeight - margin.top - margin.bottom; - scaleX = interpretationX === 'd' ? createOrdinalBandScale(domainX, [ - 0, - width - ]) : createLinearScale(domainX, [ - 0, - width - ]); - scaleY = interpretationY === 'd' ? createOrdinalBandScale(domainY, [ - 0, - height - ]) : createLinearScale(domainY, [ - height, - 0 - ]); - axisX = createAxis(scaleX, { orient: 'bottom' }); - axisY = createAxis(scaleY, { orient: 'left' }); - if (interpretationXY === 'dc') { - positionX = function (d) { - return scaleX(variableX.domain[d[attrX]]); - }; - positionY = function (d) { - return scaleY(d[attrY]); - }; - widthX = scaleX.rangeBand(); - heightY = function (d) { - return height - scaleY(d[attrY]); - }; + self.method = f; + self.args = args; + self.fulfilled = false; + self.rejected = false; + self.settled = false; + self.pending = true; + self.isFuture = true; + return self; + }; + _isFuture = function (a) { + if (a != null ? a.isFuture : void 0) { + return true; } else { - positionX = function (d) { - return scaleX(0); - }; - positionY = function (d) { - return scaleY(variableY.domain[d[attrY]]); - }; - widthX = function (d) { - return scaleX(d[attrX]); - }; - heightY = scaleY.rangeBand(); + return false; } - svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - viz = d3.select(svg).attr('class', 'plot').attr('width', availableWidth).attr('height', availableHeight).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - svgAxisX = viz.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axisX); - svgAxisY = viz.append('g').attr('class', 'axis').call(axisY); - if (false) { - svgAxisY.append('text').attr('transform', 'rotate(-90)').attr('y', 6).attr('dy', '.71em').style('text-anchor', 'end').text(variableY.label); + }; + _join = function (args, go) { + var arg, i, _actual, _i, _len, _results, _settled, _tasks; + if (args.length === 0) { + return go(null, []); } - viz.selectAll('.bar').data(rows).enter().append('rect').attr('class', 'bar').attr('x', positionX).attr('width', widthX).attr('y', positionY).attr('height', heightY); - el = document.createElement('div'); - if (title) { - h4 = Flow.HTML.template('=h4')[0]; - el.appendChild(Flow.HTML.render('div', h4(lodash.escape(title)))); + _tasks = []; + _results = []; + for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { + arg = args[i]; + if (arg != null ? arg.isFuture : void 0) { + _tasks.push({ + future: arg, + resultIndex: i + }); + } else { + _results[i] = arg; + } } - el.appendChild(svg); - return el; - }; - plot = function (_config, go) { - var initialize, renderText, renderUsingVega; - renderText = function (config, go) { - var grid, h4, p, row, table, tbody, td, tdr, tds, th, thead, thr, ths, tr, trs, value, variable, _ref; - _ref = Flow.HTML.template('.grid', '=h4', '=p', 'table', '=thead', 'tbody', 'tr', '=th', '=th.rt', '=td', '=td.rt'), grid = _ref[0], h4 = _ref[1], p = _ref[2], table = _ref[3], thead = _ref[4], tbody = _ref[5], tr = _ref[6], th = _ref[7], thr = _ref[8], td = _ref[9], tdr = _ref[10]; - ths = function () { - var _i, _len, _ref1, _results; - _ref1 = config.data.variables; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - variable = _ref1[_i]; - switch (variable.type) { - case Flow.TNumber: - _results.push(thr(lodash.escape(variable.label))); - break; - default: - _results.push(th(lodash.escape(variable.label))); - } + if (_tasks.length === 0) { + return go(null, _results); + } + _actual = 0; + _settled = false; + lodash.forEach(_tasks, function (task) { + return task.future.call(null, function (error, result) { + if (_settled) { + return; } - return _results; - }(); - trs = function () { - var _i, _len, _ref1, _results; - _ref1 = config.data.rows; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - row = _ref1[_i]; - tds = function () { - var _j, _len1, _ref2, _results1; - _ref2 = config.data.variables; - _results1 = []; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - variable = _ref2[_j]; - value = row[variable.label]; - switch (variable.type) { - case Flow.TFactor: - _results1.push(td(value === null ? '-' : lodash.escape(variable.domain[value]))); - break; - case Flow.TNumber: - _results1.push(tdr(value === null ? '-' : value)); - break; - case Flow.TArray: - _results1.push(td(value === null ? '-' : value.join(', '))); - break; - case Flow.TObject: - _results1.push(td(value === null ? '-' : variable.format(value))); - break; - default: - _results1.push(td(value === null ? '-' : value)); - } - } - return _results1; - }(); - _results.push(tr(tds)); + if (error) { + _settled = true; + go(new Flow.Error('Error evaluating future[' + task.resultIndex + ']', error)); + } else { + _results[task.resultIndex] = result; + _actual++; + if (_actual === _tasks.length) { + _settled = true; + go(null, _results); + } } - return _results; - }(); - return go(null, Flow.HTML.render('div', grid([ - h4(config.data.label), - p(config.data.description), - table([ - thead(tr(ths)), - tbody(trs) - ]) - ]))); - }; - renderUsingVega = function (config, go) { - var color, data, domainX, domainY, el, enter, height, mark, scaleTypeX, scaleTypeY, spec, transformX, transformY, type, variableColor, variableX, variableY, width, x, y, _ref, _ref1; - width = config.width, height = config.height, type = config.type, data = config.data, x = config.x, y = config.y, color = config.color; - if (lodash.isFunction(x)) { - _ref = x(), transformX = _ref[0], x = _ref[1]; - transformX.point = 'data.' + y; - } - variableX = data.schema[x]; - if (lodash.isFunction(y)) { - _ref1 = y(), transformY = _ref1[0], y = _ref1[1]; - transformY.point = 'data.' + x; + }); + }); + }; + pipe = function (tasks) { + var next, _tasks; + _tasks = tasks.slice(0); + next = function (args, go) { + var task; + task = _tasks.shift(); + if (task) { + return task.apply(null, args.concat(function () { + var error, results; + error = arguments[0], results = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + if (error) { + return go(error); + } else { + return next(results, go); + } + })); + } else { + return go.apply(null, [null].concat(args)); } - variableY = data.schema[y]; - variableColor = data.schema[color]; - if (!variableX) { - return go(new Flow.Error('Invalid \'x\' variable: \'' + x + '\'')); + }; + return function () { + var args, go, _i; + args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), go = arguments[_i++]; + return next(args, go); + }; + }; + iterate = function (tasks) { + var next, _results, _tasks; + _tasks = tasks.slice(0); + _results = []; + next = function (go) { + var task; + task = _tasks.shift(); + if (task) { + return task(function (error, result) { + if (error) { + _results.push([error]); + } else { + _results.push([ + null, + result + ]); + } + return next(go); + }); + } else { + return go(null, _results); } - if (!variableY) { - return go(new Flow.Error('Invalid \'y\' variable: \'' + y + '\'')); + }; + return function (go) { + return next(go); + }; + }; + _async = function () { + var args, f, later; + f = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + later = function () { + var args, error, go, result, _i; + args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), go = arguments[_i++]; + try { + result = f.apply(null, args); + return go(null, result); + } catch (_error) { + error = _error; + return go(error); } - if (color) { - if (!variableColor) { - return go(new Flow.Error('Invalid \'color\' variable: \'' + color + '\'')); - } - if (variableColor.type === Flow.TNumber) { - return go(new Flow.Error('Encoding numeric variables into mark color is not supported.')); + }; + return _fork(later, args); + }; + _find$3 = function (attr, prop, obj) { + var v, _i, _len; + if (_isFuture(obj)) { + return _async(_find$3, attr, prop, obj); + } else if (lodash.isArray(obj)) { + for (_i = 0, _len = obj.length; _i < _len; _i++) { + v = obj[_i]; + if (v[attr] === prop) { + return v; } } - spec = {}; - scaleTypeX = variableX.type === Flow.TNumber ? 'linear' : 'ordinal'; - scaleTypeY = variableY.type === Flow.TNumber ? 'linear' : 'ordinal'; - if (scaleTypeX === 'ordinal') { - domainX = computeDomain(data, variableX.label); + return; + } + }; + _find$2 = function (attr, obj) { + if (_isFuture(obj)) { + return _async(_find$2, attr, obj); + } else if (lodash.isString(attr)) { + if (lodash.isArray(obj)) { + return _find$3('name', attr, obj); + } else { + return obj[attr]; } - if (scaleTypeY === 'ordinal') { - domainY = computeDomain(data, variableY.label); + } + }; + _find = function () { + var a, args, b, c, ta, tb, tc; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + switch (args.length) { + case 3: + a = args[0], b = args[1], c = args[2]; + ta = Flow.Prelude.typeOf(a); + tb = Flow.Prelude.typeOf(b); + tc = Flow.Prelude.typeOf(c); + if (ta === 'Array' && tb === 'String') { + return _find$3(b, c, a); + } else if (ta === 'String' && (tc = 'Array')) { + return _find$3(a, b, c); } - spec.width = width ? width : scaleTypeX === 'linear' ? 250 : 20 * domainX.length; - spec.height = height ? height : scaleTypeY === 'linear' ? 250 : 15 * domainY.length; - spec.data = [{ name: 'table' }]; - spec.scales = [ - { - name: 'x', - type: scaleTypeX, - domain: { - data: 'table', - field: 'data.' + x - }, - range: 'width', - nice: true - }, - { - name: 'y', - type: scaleTypeY, - domain: { - data: 'table', - field: 'data.' + y - }, - range: 'height', - nice: true - } - ]; - if (color) { - spec.scales.push({ - name: 'color', - type: 'ordinal', - range: 'category20' + break; + case 2: + a = args[0], b = args[1]; + if (!a) { + return; + } + if (!b) { + return; + } + if (lodash.isString(b)) { + return _find$2(b, a); + } else if (lodash.isString(a)) { + return _find$2(a, b); + } + } + }; + _get = function (attr, obj) { + if (_isFuture(obj)) { + return _async(_get, attr, obj); + } else if (lodash.isString(attr)) { + if (lodash.isArray(obj)) { + return _find$3('name', attr, obj); + } else { + return obj[attr]; + } + } + }; + Flow.Async = { + createBuffer: createBuffer, + noop: _noop, + applicate: _applicate, + renderable: renderable, + isFuture: _isFuture, + fork: _fork, + join: _join, + pipe: pipe, + iterate: iterate, + async: _async, + find: _find, + get: _get + }; +}.call(this)); +(function () { + Flow.CoffeescriptKernel = function () { + var coalesceScopes, compileCoffeescript, compileJavascript, createGlobalScope, createLocalScope, createRootScope, deleteAstNode, executeJavascript, generateJavascript, identifyDeclarations, parseDeclarations, parseJavascript, removeHoistedDeclarations, rewriteJavascript, safetyWrapCoffeescript, traverseJavascript, traverseJavascriptScoped; + safetyWrapCoffeescript = function (guid) { + return function (cs, go) { + var block, lines; + lines = cs.replace(/[\n\r]/g, '\n').split('\n'); + block = lodash.map(lines, function (line) { + return ' ' + line; }); + block.unshift('_h2o_results_[\'' + guid + '\'].result do ->'); + return go(null, block.join('\n')); + }; + }; + compileCoffeescript = function (cs, go) { + var error; + try { + return go(null, CoffeeScript.compile(cs, { bare: true })); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error compiling coffee-script', error)); } - spec.axes = [ - { - type: 'x', - scale: 'x', - title: x - }, - { - type: 'y', - scale: 'y', - title: y - } - ]; - if (type === 'point') { - mark = { - type: 'symbol', - from: { data: 'table' }, - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - y: { - scale: 'y', - field: 'data.' + y - }, - stroke: { value: 'steelblue' }, - strokeWidth: { value: 1.5 } - } - } - }; - } else if (type === 'line') { - if (color) { - mark = { - type: 'group', - from: { - data: 'table', - transform: [{ - type: 'facet', - keys: ['data.' + color] - }] - }, - marks: [{ - type: 'line', - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - y: { - scale: 'y', - field: 'data.' + y - }, - stroke: { - scale: 'color', - field: 'data.' + color - }, - strokeWidth: { value: 1.5 } - } - } - }] - }; - } else { - mark = { - type: 'line', - from: { data: 'table' }, - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - y: { - scale: 'y', - field: 'data.' + y - }, - stroke: { value: 'steelblue' }, - strokeWidth: { value: 1.5 } - } + }; + parseJavascript = function (js, go) { + var error; + try { + return go(null, esprima.parse(js)); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error parsing javascript expression', error)); + } + }; + identifyDeclarations = function (node) { + var declaration; + if (!node) { + return null; + } + switch (node.type) { + case 'VariableDeclaration': + return function () { + var _i, _len, _ref, _results; + _ref = node.declarations; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + declaration = _ref[_i]; + if (declaration.type === 'VariableDeclarator' && declaration.id.type === 'Identifier') { + _results.push({ + name: declaration.id.name, + object: '_h2o_context_' + }); } - }; + } + return _results; + }(); + case 'FunctionDeclaration': + if (node.id.type === 'Identifier') { + return [{ + name: node.id.name, + object: '_h2o_context_' + }]; } - } else if (type === 'area') { - if (scaleTypeX === 'ordinal' && scaleTypeY === 'linear') { - enter = { - x: { - scale: 'x', - field: 'data.' + x - }, - y: { - scale: 'y', - field: 'data.' + y - }, - y2: { - scale: 'y', - value: 0 - }, - fill: { value: 'steelblue' } - }; - } else if (scaleTypeX === 'linear' && scaleTypeY === 'ordinal') { - enter = { - x: { - scale: 'x', - field: 'data.' + x - }, - x2: { - scale: 'x', - value: 0 - }, - y: { - scale: 'y', - field: 'data.' + y - }, - fill: { value: 'steelblue' } - }; - } else if (scaleTypeX === 'linear' && scaleTypeY === 'linear') { - enter = { - x: { - scale: 'x', - field: 'data.' + x - }, - y: { - scale: 'y', - field: 'data.' + y - }, - y2: { - scale: 'y', - value: 0 - }, - fill: { value: 'steelblue' } + break; + case 'ForStatement': + return identifyDeclarations(node.init); + case 'ForInStatement': + case 'ForOfStatement': + return identifyDeclarations(node.left); + } + return null; + }; + parseDeclarations = function (block) { + var declaration, declarations, identifiers, node, _i, _j, _len, _len1, _ref; + identifiers = []; + _ref = block.body; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + if (declarations = identifyDeclarations(node)) { + for (_j = 0, _len1 = declarations.length; _j < _len1; _j++) { + declaration = declarations[_j]; + identifiers.push(declaration); + } + } + } + return lodash.indexBy(identifiers, function (identifier) { + return identifier.name; + }); + }; + traverseJavascript = function (parent, key, node, f) { + var child, i; + if (lodash.isArray(node)) { + i = node.length; + while (i--) { + child = node[i]; + if (lodash.isObject(child)) { + traverseJavascript(node, i, child, f); + f(node, i, child); + } + } + } else { + for (i in node) { + child = node[i]; + if (lodash.isObject(child)) { + traverseJavascript(node, i, child, f); + f(node, i, child); + } + } + } + }; + deleteAstNode = function (parent, i) { + if (_.isArray(parent)) { + return parent.splice(i, 1); + } else if (lodash.isObject(parent)) { + return delete parent[i]; + } + }; + createLocalScope = function (node) { + var localScope, param, _i, _len, _ref; + localScope = parseDeclarations(node.body); + _ref = node.params; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + param = _ref[_i]; + if (param.type === 'Identifier') { + localScope[param.name] = { + name: param.name, + object: 'local' }; + } + } + return localScope; + }; + coalesceScopes = function (scopes) { + var currentScope, i, identifier, name, scope, _i, _len; + currentScope = {}; + for (i = _i = 0, _len = scopes.length; _i < _len; i = ++_i) { + scope = scopes[i]; + if (i === 0) { + for (name in scope) { + identifier = scope[name]; + currentScope[name] = identifier; + } } else { - return go(new Flow.Error('Not implemented')); + for (name in scope) { + identifier = scope[name]; + currentScope[name] = null; + } } - mark = { - type: 'area', - from: { data: 'table' }, - properties: { enter: enter } - }; - } else if (type === 'interval') { - if (scaleTypeX === 'ordinal' && scaleTypeY === 'linear') { - if (color) { - mark = { - type: 'group', - from: { - data: 'table', - transform: [ - { - type: 'facet', - keys: ['data.' + color] - }, - transformY - ] - }, - marks: [{ - type: 'rect', - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - width: { - scale: 'x', - band: true, - offset: -1 - }, - y: { - scale: 'y', - field: 'y' - }, - y2: { - scale: 'y', - field: 'y2' - }, - fill: { - scale: 'color', - field: 'data.' + color - } - } - } - }] - }; - } else { - mark = { - type: 'rect', - from: { data: 'table' }, - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - width: { - scale: 'x', - band: true, - offset: -1 - }, - y: { - scale: 'y', - field: 'data.' + y - }, - y2: { - scale: 'y', - value: 0 - }, - fill: { value: 'steelblue' } - } - } - }; - } - } else if (scaleTypeX === 'linear' && scaleTypeY === 'ordinal') { - if (color) { - mark = { - type: 'group', - from: { - data: 'table', - transform: [ - { - type: 'facet', - keys: ['data.' + color] - }, - transformX - ] - }, - marks: [{ - type: 'rect', - properties: { - enter: { - x: { - scale: 'x', - field: 'y' - }, - x2: { - scale: 'x', - field: 'y2' - }, - y: { - scale: 'y', - field: 'data.' + y - }, - height: { - scale: 'y', - band: true, - offset: -1 - }, - fill: { - scale: 'color', - field: 'data.' + color - } - } - } - }] - }; - } else { - mark = { - type: 'rect', - from: { data: 'table' }, - properties: { - enter: { - x: { - scale: 'x', - field: 'data.' + x - }, - x2: { - scale: 'x', - value: 0 - }, - y: { - scale: 'y', - field: 'data.' + y - }, - height: { - scale: 'y', - band: true, - offset: -1 - }, - fill: { value: 'steelblue' } - } - } + } + return currentScope; + }; + traverseJavascriptScoped = function (scopes, parentScope, parent, key, node, f) { + var child, currentScope, isNewScope; + isNewScope = node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration'; + if (isNewScope) { + scopes.push(createLocalScope(node)); + currentScope = coalesceScopes(scopes); + } else { + currentScope = parentScope; + } + for (key in node) { + child = node[key]; + if (lodash.isObject(child)) { + traverseJavascriptScoped(scopes, currentScope, node, key, child, f); + f(currentScope, node, key, child); + } + } + if (isNewScope) { + scopes.pop(); + } + }; + createRootScope = function (sandbox) { + return function (program, go) { + var error, name, rootScope; + try { + rootScope = parseDeclarations(program.body[0].expression['arguments'][0].callee.body); + for (name in sandbox.context) { + rootScope[name] = { + name: name, + object: '_h2o_context_' }; } - } else if (scaleTypeX === 'linear' && scaleTypeY === 'linear') { - return go(new Flow.Error('Not implemented')); - } else { - return go(new Flow.Error('Not implemented')); + return go(null, rootScope, program); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error parsing root scope', error)); } - } - spec.marks = [mark]; - go(null, Flow.HTML.render('div', el = document.createElement('div'))); - vg.parse.spec(spec, function (ctor) { - var chart; - chart = ctor({ - el: el, - data: { table: data.rows } - }); - return chart.update(); - }); + }; }; - initialize = function (config) { + removeHoistedDeclarations = function (rootScope, program, go) { var error; try { - switch (config.type) { - case 'point': - case 'line': - case 'area': - case 'interval': - return renderUsingVega(config, go); - case 'schema': - return go(new Flow.Error('Not implemented: ' + config.type)); - case 'text': - return renderText(config, go); - default: - return go(new Flow.Error('Invalid mark type: ' + config.type)); - } + traverseJavascript(null, null, program, function (parent, key, node) { + var declarations; + if (node.type === 'VariableDeclaration') { + declarations = node.declarations.filter(function (declaration) { + return declaration.type === 'VariableDeclarator' && declaration.id.type === 'Identifier' && !rootScope[declaration.id.name]; + }); + if (declarations.length === 0) { + return deleteAstNode(parent, key); + } else { + return node.declarations = declarations; + } + } + }); + return go(null, rootScope, program); } catch (_error) { error = _error; - return go(new Flow.Error('Error creating plot.', error)); + return go(new Flow.Error('Error rewriting javascript', error)); } }; - return initialize(_config); - }; - stack = function (attr) { - var self; - return function () { - var transform; - transform = { - type: 'stack', - height: 'data.' + attr - }; - return [ - transform, - attr - ]; - }; - self = function (table) { - var end, endVariable, n, p, row, start, startVariable, type, value, _i, _len, _ref, _ref1; - type = table.schema[attr].type; - _ref = table.expand(type, type), startVariable = _ref[0], endVariable = _ref[1]; - start = startVariable.label; - end = endVariable.label; - n = 0; - p = 0; - _ref1 = table.rows; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - row = _ref1[_i]; - value = row[attr]; - if (value >= 0) { - row[start] = p; - row[end] = p = p + value; - } else { - row[start] = n; - row[end] = n = n + value; - } + createGlobalScope = function (rootScope, routines) { + var globalScope, identifier, name; + globalScope = {}; + for (name in rootScope) { + identifier = rootScope[name]; + globalScope[name] = identifier; } - startVariable.domain = [ - n, - p - ]; - endVariable.domain = [ - n, - p - ]; - return [ - start, - end - ]; - }; - return self; - }; - Flow.Plot = plot; - plot.stack = stack; -}.call(this)); -(function () { - Flow.Prelude = function () { - var _always, _copy, _deepClone, _isDefined, _isFalsy, _isTruthy, _negative, _never, _remove, _repeat, _typeOf, _words; - _isDefined = function (value) { - return !lodash.isUndefined(value); + for (name in routines) { + globalScope[name] = { + name: name, + object: 'h2o' + }; + } + return globalScope; }; - _isTruthy = function (value) { - if (value) { - return true; - } else { - return false; - } - }; - _isFalsy = function (value) { - if (value) { - return false; - } else { - return true; - } - }; - _negative = function (value) { - return !value; - }; - _always = function () { - return true; - }; - _never = function () { - return false; - }; - _copy = function (array) { - return array.slice(0); + rewriteJavascript = function (sandbox) { + return function (rootScope, program, go) { + var error, globalScope; + globalScope = createGlobalScope(rootScope, sandbox.routines); + try { + traverseJavascriptScoped([globalScope], globalScope, null, null, program, function (globalScope, parent, key, node) { + var identifier; + if (node.type === 'Identifier') { + if (parent.type === 'VariableDeclarator' && key === 'id') { + return; + } + if (key === 'property') { + return; + } + if (!(identifier = globalScope[node.name])) { + return; + } + return parent[key] = { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: identifier.object + }, + property: { + type: 'Identifier', + name: identifier.name + } + }; + } + }); + return go(null, program); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error rewriting javascript', error)); + } + }; }; - _remove = function (array, element) { - var index; - if (-1 < (index = lodash.indexOf(array, element))) { - return lodash.head(arra.splice(index, 1)); - } else { - return void 0; + generateJavascript = function (program, go) { + var error; + try { + return go(null, escodegen.generate(program)); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error generating javascript', error)); } }; - _words = function (text) { - return text.split(/\s+/); - }; - _repeat = function (count, value) { - var array, i, _i; - array = []; - for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) { - array.push(value); + compileJavascript = function (js, go) { + var closure, error; + try { + closure = new Function('h2o', '_h2o_context_', '_h2o_results_', 'print', js); + return go(null, closure); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error compiling javascript', error)); } - return array; }; - _typeOf = function (a) { - var type; - type = Object.prototype.toString.call(a); - if (a === null) { - return Flow.TNull; - } else if (a === void 0) { - return Flow.TUndefined; - } else if (a === true || a === false || type === '[object Boolean]') { - return Flow.TBoolean; - } else { - switch (type) { - case '[object String]': - return Flow.TString; - case '[object Number]': - return Flow.TNumber; - case '[object Function]': - return Flow.TFunction; - case '[object Object]': - return Flow.TObject; - case '[object Array]': - return Flow.TArray; - case '[object Arguments]': - return Flow.TArguments; - case '[object Date]': - return Flow.TDate; - case '[object RegExp]': - return Flow.TRegExp; - case '[object Error]': - return Flow.TError; - default: - return type; + executeJavascript = function (sandbox, print) { + return function (closure, go) { + var error; + try { + return go(null, closure(sandbox.routines, sandbox.context, sandbox.results, print)); + } catch (_error) { + error = _error; + return go(new Flow.Error('Error executing javascript', error)); } - } - }; - _deepClone = function (obj) { - return JSON.parse(JSON.stringify(obj)); + }; }; return { - isDefined: _isDefined, - isTruthy: _isTruthy, - isFalsy: _isFalsy, - negative: _negative, - always: _always, - never: _never, - copy: _copy, - remove: _remove, - words: _words, - repeat: _repeat, - typeOf: _typeOf, - deepClone: _deepClone, - stringify: JSON.stringify + safetyWrapCoffeescript: safetyWrapCoffeescript, + compileCoffeescript: compileCoffeescript, + parseJavascript: parseJavascript, + createRootScope: createRootScope, + removeHoistedDeclarations: removeHoistedDeclarations, + rewriteJavascript: rewriteJavascript, + generateJavascript: generateJavascript, + compileJavascript: compileJavascript, + executeJavascript: executeJavascript }; }(); }.call(this)); (function () { - Flow.Sandbox = function (_, routines) { - return { - routines: routines, - context: {}, - results: {} - }; + var combineRanges, computeRange, createAbstractVariable, createCompiledPrototype, createFactor, createNumericVariable, createRecordConstructor, createTable, createVariable, factor, includeZeroInRange, nextPrototypeName, permute, _prototypeCache, _prototypeId, __slice = [].slice; + _prototypeId = 0; + nextPrototypeName = function () { + return 'Map' + ++_prototypeId; }; -}.call(this)); -(function () { - Flow.TUndefined = 'undefined'; - Flow.TNull = 'null'; - Flow.TBoolean = 'Boolean'; - Flow.TString = 'String'; - Flow.TNumber = 'Number'; - Flow.TFunction = 'Function'; - Flow.TObject = 'Object'; - Flow.TArray = 'Array'; - Flow.TArguments = 'Arguments'; - Flow.TDate = 'Date'; - Flow.TRegExp = 'RegExp'; - Flow.TError = 'Error'; - Flow.TFactor = 'Factor'; -}.call(this)); -(function () { - var describeCount, fromNow; - describeCount = function (count, singular, plural) { - if (!plural) { - plural = singular + 's'; - } - switch (count) { - case 0: - return 'No ' + plural; - case 1: - return '1 ' + singular; - default: - return '' + count + ' ' + plural; + _prototypeCache = {}; + createCompiledPrototype = function (attrs) { + var attr, cacheKey, i, inits, params, proto, prototypeName; + cacheKey = attrs.join('\0'); + if (proto = _prototypeCache[cacheKey]) { + return proto; } + params = function () { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = attrs.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push('a' + i); + } + return _results; + }(); + inits = function () { + var _i, _len, _results; + _results = []; + for (i = _i = 0, _len = attrs.length; _i < _len; i = ++_i) { + attr = attrs[i]; + _results.push('this[' + JSON.stringify(attr) + ']=a' + i + ';'); + } + return _results; + }(); + prototypeName = nextPrototypeName(); + return _prototypeCache[cacheKey] = new Function('function ' + prototypeName + '(' + params.join(',') + '){' + inits.join('') + '} return ' + prototypeName + ';')(); }; - fromNow = function (date) { - return moment(date).fromNow(); - }; - Flow.Util = { - describeCount: describeCount, - fromNow: fromNow - }; -}.call(this)); -(function () { - var FLOW_VERSION; - FLOW_VERSION = '0.2.25'; - Flow.About = function (_) { - var _properties; - _properties = Flow.Dataflow.signals([]); - Flow.Dataflow.link(_.ready, function () { - return _.requestAbout(function (error, response) { - var name, value, _i, _len, _ref, _ref1; - if (!error) { - _ref = response.entries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], name = _ref1.name, value = _ref1.value; - _properties.push({ - caption: 'H2O ' + name, - value: value - }); - } - } - return _properties.push({ - caption: 'Flow version', - value: FLOW_VERSION - }); - }); - }); - return { properties: _properties }; + createRecordConstructor = function (variables) { + var variable; + return createCompiledPrototype(function () { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = variables.length; _i < _len; _i++) { + variable = variables[_i]; + _results.push(variable.label); + } + return _results; + }()); }; -}.call(this)); -(function () { - Flow.Browser = function (_) { - var createDocView, loadNotebooks, storeNotebook, _docs, _hasDocs, _sortedDocs; - _docs = Flow.Dataflow.signals([]); - _sortedDocs = Flow.Dataflow.lift(_docs, function (docs) { - return lodash.sortBy(docs, function (doc) { - return -doc.date().getTime(); - }); - }); - _hasDocs = Flow.Dataflow.lift(_docs, function (docs) { - return docs.length > 0; - }); - createDocView = function (_arg) { - var doc, id, load, purge, self, type, _date, _fromNow, _title; - type = _arg[0], id = _arg[1], doc = _arg[2]; - _title = Flow.Dataflow.signal(doc.title); - _date = Flow.Dataflow.signal(new Date(doc.modifiedDate)); - _fromNow = Flow.Dataflow.lift(_date, Flow.Util.fromNow); - load = function () { - return _.loadNotebook(id, doc); - }; - purge = function () { - return _.requestDeleteObject(type, id, function (error) { - if (error) { - return console.debug(error); - } else { - return _docs.remove(self); - } - }); - }; - return self = { - id: id, - title: _title, - doc: doc, - date: _date, - fromNow: _fromNow, - load: load, - purge: purge - }; - }; - storeNotebook = function (id, doc, go) { - if (id) { - return _.requestPutObject('notebook', id, doc, function (error) { - var index, source, _i, _len, _ref; - if (error) { - return go(error); - } else { - _ref = _docs(); - for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { - source = _ref[index]; - if (source.id === id) { - break; - } - } - _docs.splice(index, 1, createDocView([ - 'notebook', - id, - doc - ])); - return go(null, id); - } - }); - } else { - id = uuid(); - return _.requestPutObject('notebook', id, doc, function (error) { - if (error) { - return go(error); - } else { - _docs.push(createDocView([ - 'notebook', - id, - doc - ])); - return go(null, id); - } - }); - } - }; - loadNotebooks = function () { - return _.requestObjects('notebook', function (error, objs) { + createTable = function (opts) { + var description, expand, fill, label, meta, rows, schema, variable, variables, _i, _len; + label = opts.label, description = opts.description, variables = opts.variables, rows = opts.rows, meta = opts.meta; + if (!description) { + description = 'No description available.'; + } + schema = {}; + for (_i = 0, _len = variables.length; _i < _len; _i++) { + variable = variables[_i]; + schema[variable.label] = variable; + } + fill = function (i, go) { + _fill(i, function (error, result) { + var index, startIndex, value, _j, _len1; if (error) { - return console.debug(error); + return go(error); } else { - return _docs(lodash.map(objs, createDocView)); + startIndex = result.index, lodash.values = result.values; + for (index = _j = 0, _len1 = lodash.values.length; _j < _len1; index = ++_j) { + value = lodash.values[index]; + rows[startIndex + index] = lodash.values[index]; + } + return go(null); } }); }; - Flow.Dataflow.link(_.ready, function () { - return loadNotebooks(); - }); - Flow.Dataflow.link(_.storeNotebook, storeNotebook); + expand = function () { + var type, types, _j, _len1, _results; + types = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_j = 0, _len1 = types.length; _j < _len1; _j++) { + type = types[_j]; + label = lodash.uniqueId('__flow_variable_'); + _results.push(schema[label] = createNumericVariable(label)); + } + return _results; + }; return { - docs: _sortedDocs, - hasDocs: _hasDocs, - loadNotebooks: loadNotebooks + label: label, + description: description, + schema: schema, + variables: variables, + rows: rows, + meta: meta, + fill: fill, + expand: expand, + _is_table_: true }; }; -}.call(this)); -(function () { - Flow.Cell = function (_, _renderers, type, input) { - var activate, clip, execute, navigate, select, self, _actions, _guid, _hasError, _hasInput, _hasOutput, _input, _isActive, _isBusy, _isCode, _isInputVisible, _isOutputHidden, _isReady, _isSelected, _outputs, _render, _result, _type; - if (type == null) { - type = 'cs'; - } - if (input == null) { - input = ''; + includeZeroInRange = function (range) { + var hi, lo; + lo = range[0], hi = range[1]; + if (lo > 0 && hi > 0) { + return [ + 0, + hi + ]; + } else if (lo < 0 && hi < 0) { + return [ + lo, + 0 + ]; + } else { + return range; } - _guid = lodash.uniqueId(); - _type = Flow.Dataflow.signal(type); - _render = Flow.Dataflow.lift(_type, function (type) { - return _renderers[type](_guid); - }); - _isCode = Flow.Dataflow.lift(_render, function (render) { - return render.isCode; - }); - _isSelected = Flow.Dataflow.signal(false); - _isActive = Flow.Dataflow.signal(false); - _hasError = Flow.Dataflow.signal(false); - _isBusy = Flow.Dataflow.signal(false); - _isReady = Flow.Dataflow.lift(_isBusy, function (isBusy) { - return !isBusy; - }); - _hasInput = Flow.Dataflow.signal(true); - _input = Flow.Dataflow.signal(input); - _outputs = Flow.Dataflow.signals([]); - _result = Flow.Dataflow.signal(null); - _hasOutput = Flow.Dataflow.lift(_outputs, function (outputs) { - return outputs.length > 0; - }); - _isInputVisible = Flow.Dataflow.signal(true); - _isOutputHidden = Flow.Dataflow.signal(false); - _actions = {}; - Flow.Dataflow.act(_isActive, function (isActive) { - if (isActive) { - _.selectCell(self); - _hasInput(true); - if (!_isCode()) { - _outputs([]); - } + }; + combineRanges = function () { + var hi, lo, range, ranges, value, _i, _len; + ranges = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + lo = Number.POSITIVE_INFINITY; + hi = Number.NEGATIVE_INFINITY; + for (_i = 0, _len = ranges.length; _i < _len; _i++) { + range = ranges[_i]; + if (lo > (value = range[0])) { + lo = value; } - }); - Flow.Dataflow.act(_isSelected, function (isSelected) { - if (!isSelected) { - return _isActive(false); + if (hi < (value = range[1])) { + hi = value; } - }); - select = function () { - _.selectCell(self, false); - return true; - }; - navigate = function () { - _.selectCell(self); - return true; - }; - activate = function () { - return _isActive(true); - }; - clip = function () { - return _.saveClip('user', _type(), _input()); - }; - execute = function (go) { - var render; - input = _input().trim(); - if (!input) { - if (go) { - return go(); - } else { - return void 0; + } + return [ + lo, + hi + ]; + }; + computeRange = function (rows, attr) { + var hi, lo, row, value, _i, _len; + if (rows.length) { + lo = Number.POSITIVE_INFINITY; + hi = Number.NEGATIVE_INFINITY; + for (_i = 0, _len = rows.length; _i < _len; _i++) { + row = rows[_i]; + value = row[attr]; + if (value < lo) { + lo = value; + } + if (value > hi) { + hi = value; } } - render = _render(); - _isBusy(true); - _result(null); - _outputs([]); - _hasError(false); - render(input, { - data: function (result) { - return _outputs.push(result); - }, - close: function (result) { - return _result(result); - }, - error: function (error) { - _hasError(true); - if (error.name === 'FlowError') { - return _outputs.push(Flow.Failure(error)); - } else { - return _outputs.push({ - text: JSON.stringify(error, null, 2), - template: 'flow-raw' - }); - } - }, - end: function () { - _hasInput(render.isCode); - _isBusy(false); - if (go) { - return go(); - } - } - }); - return _isActive(false); - }; - return self = { - guid: _guid, + return [ + lo, + hi + ]; + } else { + return [ + -1, + 1 + ]; + } + }; + permute = function (array, indices) { + var i, index, permuted, _i, _len; + permuted = new Array(array.length); + for (i = _i = 0, _len = indices.length; _i < _len; i = ++_i) { + index = indices[i]; + permuted[i] = array[index]; + } + return permuted; + }; + createAbstractVariable = function (_label, _type, _domain, _format, _read) { + return { + label: _label, type: _type, - isCode: _isCode, - isSelected: _isSelected, - isActive: _isActive, - hasError: _hasError, - isBusy: _isBusy, - isReady: _isReady, - input: _input, - hasInput: _hasInput, - outputs: _outputs, - result: _result, - hasOutput: _hasOutput, - isInputVisible: _isInputVisible, - toggleInput: function () { - return _isInputVisible(!_isInputVisible()); - }, - isOutputHidden: _isOutputHidden, - toggleOutput: function () { - return _isOutputHidden(!_isOutputHidden()); - }, - select: select, - navigate: navigate, - activate: activate, - execute: execute, - clip: clip, - _actions: _actions, - getCursorPosition: function () { - return _actions.getCursorPosition(); - }, - autoResize: function () { - return _actions.autoResize(); - }, - scrollIntoView: function () { - return _actions.scrollIntoView(); - }, - templateOf: function (view) { - return view.template; - }, - template: 'flow-cell' + domain: _domain || [], + format: _format || lodash.identity, + read: _read }; }; -}.call(this)); -(function () { - var SystemClips; - SystemClips = [ - 'assist', - 'importFiles', - 'getFrames', - 'getModels', - 'getPredictions', - 'getJobs', - 'buildModel', - 'predict' - ]; - Flow.Clipboard = function (_) { - var addClip, createClip, emptyTrash, initialize, lengthOf, removeClip, _hasTrashClips, _hasUserClips, _systemClipCount, _systemClips, _trashClipCount, _trashClips, _userClipCount, _userClips; - lengthOf = function (array) { - if (array.length) { - return '(' + array.length + ')'; - } else { - return ''; - } - }; - _systemClips = Flow.Dataflow.signals([]); - _systemClipCount = Flow.Dataflow.lift(_systemClips, lengthOf); - _userClips = Flow.Dataflow.signals([]); - _userClipCount = Flow.Dataflow.lift(_userClips, lengthOf); - _hasUserClips = Flow.Dataflow.lift(_userClips, function (clips) { - return clips.length > 0; - }); - _trashClips = Flow.Dataflow.signals([]); - _trashClipCount = Flow.Dataflow.lift(_trashClips, lengthOf); - _hasTrashClips = Flow.Dataflow.lift(_trashClips, function (clips) { - return clips.length > 0; - }); - createClip = function (_list, _type, _input, _canRemove) { - var execute, insert, self; - if (_canRemove == null) { - _canRemove = true; - } - execute = function () { - return _.insertAndExecuteCell(_type, _input); - }; - insert = function () { - return _.insertCell(_type, _input); - }; - Flow.Prelude.remove = function () { - if (_canRemove) { - return removeClip(_list, self); + createNumericVariable = function (_label, _domain, _format, _read) { + var self; + self = createAbstractVariable(_label, Flow.TNumber, _domain || [ + Number.POSITIVE_INFINITY, + Number.NEGATIVE_INFINITY + ], _format, _read); + if (!self.read) { + self.read = function (datum) { + if (datum < self.domain[0]) { + self.domain[0] = datum; } + if (datum > self.domain[1]) { + self.domain[1] = datum; + } + return datum; }; - return self = { - type: _type, - input: _input, - execute: execute, - insert: insert, - remove: Flow.Prelude.remove, - canRemove: _canRemove - }; - }; - addClip = function (list, type, input) { - return list.push(createClip(list, type, input)); - }; - removeClip = function (list, clip) { - if (list === _userClips) { - _userClips.remove(clip); - return _trashClips.push(createClip(_trashClips, clip.type, clip.input)); - } else { - return _trashClips.remove(clip); - } - }; - emptyTrash = function () { - return _trashClips.removeAll(); - }; - initialize = function () { - _systemClips(lodash.map(SystemClips, function (input) { - return createClip(_systemClips, 'cs', input, false); - })); - return Flow.Dataflow.link(_.ready, function () { - return Flow.Dataflow.link(_.saveClip, function (category, type, input) { - input = input.trim(); - if (input) { - if (category === 'user') { - return addClip(_userClips, type, input); - } else { - return addClip(_trashClips, type, input); - } - } - }); - }); - }; - initialize(); - return { - systemClips: _systemClips, - systemClipCount: _systemClipCount, - userClips: _userClips, - hasUserClips: _hasUserClips, - userClipCount: _userClipCount, - trashClips: _trashClips, - trashClipCount: _trashClipCount, - hasTrashClips: _hasTrashClips, - emptyTrash: emptyTrash - }; + } + return self; }; -}.call(this)); -(function () { - Flow.Coffeescript = function (_, guid, sandbox) { - var isRoutine, print, render, _kernel; - _kernel = Flow.CoffeescriptKernel; - print = function (arg) { - if (arg !== print) { - sandbox.results[guid].outputs(arg); + createVariable = function (_label, _type, _domain, _format, _read) { + if (_type === Flow.TNumber) { + return createNumericVariable(_label, _domain, _format, _read); + } else { + return createAbstractVariable(_label, _type, _domain, _format, _read); + } + }; + createFactor = function (_label, _domain, _format, _read) { + var level, self, _i, _id, _len, _levels, _ref; + self = createAbstractVariable(_label, Flow.TFactor, _domain || [], _format, _read); + _id = 0; + _levels = {}; + if (self.domain.length) { + _ref = self.domain; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + level = _ref[_i]; + _levels[level] = _id++; } - return print; - }; - isRoutine = function (f) { - var name, routine, _ref; - _ref = sandbox.routines; - for (name in _ref) { - routine = _ref[name]; - if (f === routine) { - return true; + } + if (!self.read) { + self.read = function (datum) { + var id; + level = datum === void 0 || datum === null ? 'null' : datum; + if (void 0 === (id = _levels[level])) { + _levels[level] = id = _id++; + self.domain.push(level); } - } - return false; - }; - render = function (input, output) { - var cellResult, evaluate, outputBuffer, tasks; - sandbox.results[guid] = cellResult = { - result: Flow.Dataflow.signal(null), - outputs: outputBuffer = Flow.Async.createBuffer([]) + return id; }; - evaluate = function (ft) { - if (ft != null ? ft.isFuture : void 0) { - return ft(function (error, result) { - var _ref; - if (error) { - return output.error(new Flow.Error('Error evaluating cell', error)); - } else { - if (ft.render) { - return ft.render(result, function (error, result) { - if (error) { - return output.error(new Flow.Error('Error rendering output', error)); - } else { - return output.data(result); - } - }); - } else if (result != null ? (_ref = result._flow_) != null ? _ref.render : void 0 : void 0) { - return output.data(result._flow_.render()); - } else { - return output.data(Flow.ObjectBrowser('output', result)); - } - } - }); + } + return self; + }; + factor = function (array) { + var data, domain, i, id, level, levels, _i, _id, _len; + _id = 0; + levels = {}; + domain = []; + data = new Array(array.length); + for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) { + level = array[i]; + if (void 0 === (id = levels[level])) { + levels[level] = id = _id++; + domain.push(level); + } + data[i] = id; + } + return [ + domain, + data + ]; + }; + Flow.Data = { + Table: createTable, + Variable: createVariable, + Factor: createFactor, + computeColumnInterpretation: function (type) { + if (type === Flow.TNumber) { + return 'c'; + } else if (type === Flow.TFactor) { + return 'd'; + } else { + return 't'; + } + }, + Record: createRecordConstructor, + computeRange: computeRange, + combineRanges: combineRanges, + includeZeroInRange: includeZeroInRange, + factor: factor, + permute: permute + }; +}.call(this)); +(function () { + var __slice = [].slice; + Flow.Dataflow = function () { + var createObservable, createObservableArray, createSignal, createSignals, createSlot, createSlots, isObservable, _act, _apply, _isSignal, _lift, _link, _merge, _react, _unlink; + createSlot = function () { + var arrow, self; + arrow = null; + self = function () { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + if (arrow) { + return arrow.func.apply(null, args); } else { - return output.data(Flow.ObjectBrowser('output', ft)); + return void 0; } }; - outputBuffer.subscribe(evaluate); - tasks = [ - _kernel.safetyWrapCoffeescript(guid), - _kernel.compileCoffeescript, - _kernel.parseJavascript, - _kernel.createRootScope(sandbox), - _kernel.removeHoistedDeclarations, - _kernel.rewriteJavascript(sandbox), - _kernel.generateJavascript, - _kernel.compileJavascript, - _kernel.executeJavascript(sandbox, print) - ]; - return Flow.Async.pipe(tasks)(input, function (error) { - var result; - if (error) { - output.error(error); + self.subscribe = function (func) { + console.assert(lodash.isFunction(func)); + if (arrow) { + throw new Error('Cannot re-attach slot'); + } else { + return arrow = { + func: func, + dispose: function () { + return arrow = null; + } + }; } - output.end(); - result = cellResult.result(); - if (lodash.isFunction(result)) { - if (isRoutine(result)) { - return print(result()); + }; + self.dispose = function () { + if (arrow) { + return arrow.dispose(); + } + }; + return self; + }; + createSlots = function () { + var arrows, self; + arrows = []; + self = function () { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return lodash.map(arrows, function (arrow) { + return arrow.func.apply(null, args); + }); + }; + self.subscribe = function (func) { + var arrow; + console.assert(lodash.isFunction(func)); + arrows.push(arrow = { + func: func, + dispose: function () { + return Flow.Prelude.remove(arrows, arrow); + } + }); + return arrow; + }; + self.dispose = function () { + return lodash.forEach(Flow.Prelude.copy(arrows), function (arrow) { + return arrow.dispose(); + }); + }; + return self; + }; + if (typeof ko !== 'undefined' && ko !== null) { + createObservable = ko.observable; + createObservableArray = ko.observableArray; + isObservable = ko.isObservable; + } else { + createObservable = function (initialValue) { + var arrows, currentValue, notifySubscribers, self; + arrows = []; + currentValue = initialValue; + notifySubscribers = function (arrows, newValue) { + var arrow, _i, _len; + for (_i = 0, _len = arrows.length; _i < _len; _i++) { + arrow = arrows[_i]; + arrow.func(newValue); + } + }; + self = function (newValue) { + var unchanged; + if (arguments.length === 0) { + return currentValue; } else { - return evaluate(result); + unchanged = self.equalityComparer ? self.equalityComparer(currentValue, newValue) : currentValue === newValue; + if (!unchanged) { + currentValue = newValue; + return notifySubscribers(arrows, newValue); + } } + }; + self.subscribe = function (func) { + var arrow; + console.assert(lodash.isFunction(func)); + arrows.push(arrow = { + func: func, + dispose: function () { + return Flow.Prelude.remove(arrows, arrow); + } + }); + return arrow; + }; + self.__observable__ = true; + return self; + }; + createObservableArray = createObservable; + isObservable = function (obj) { + if (obj.__observable__) { + return true; } else { - return output.close(Flow.ObjectBrowser('result', result)); + return false; } - }); - }; - render.isCode = true; - return render; - }; -}.call(this)); -(function () { -}.call(this)); -(function () { - var traceCauses; - traceCauses = function (error, causes) { - causes.push(error.message); - if (error.cause) { - traceCauses(error.cause, causes); + }; } - return causes; - }; - Flow.Failure = function (error) { - var causes, message, toggleStack, _isStackVisible; - causes = traceCauses(error, []); - message = causes.shift(); - _isStackVisible = Flow.Dataflow.signal(false); - toggleStack = function () { - return _isStackVisible(!_isStackVisible()); + createSignal = function (value, equalityComparer) { + var observable; + if (arguments.length === 0) { + return createSignal(void 0, Flow.Prelude.never); + } else { + observable = createObservable(value); + if (lodash.isFunction(equalityComparer)) { + observable.equalityComparer = equalityComparer; + } + return observable; + } }; - return { - message: message, - stack: error.stack, - causes: causes, - isStackVisible: _isStackVisible, - toggleStack: toggleStack, - template: 'flow-failure' + _isSignal = isObservable; + createSignals = function (array) { + return createObservableArray(array || []); }; - }; -}.call(this)); -(function () { - Flow.Form = function (_, _form) { - return { - form: _form, - template: 'flow-form', - templateOf: function (control) { - return control.template; - } + _link = function (source, func) { + console.assert(lodash.isFunction(source, '[signal] is not a function')); + console.assert(lodash.isFunction(source.subscribe, '[signal] does not have a [dispose] method')); + console.assert(lodash.isFunction(func, '[func] is not a function')); + return source.subscribe(func); }; - }; -}.call(this)); -(function () { - Flow.Heading = function (_, level) { - var render; - render = function (input, output) { - output.data({ - text: input.trim() || '(Untitled)', - template: 'flow-' + level + _unlink = function (arrows) { + var arrow, _i, _len, _results; + if (lodash.isArray(arrows)) { + _results = []; + for (_i = 0, _len = arrows.length; _i < _len; _i++) { + arrow = arrows[_i]; + console.assert(lodash.isFunction(arrow.dispose, '[arrow] does not have a [dispose] method')); + _results.push(arrow.dispose()); + } + return _results; + } else { + console.assert(lodash.isFunction(arrows.dispose, '[arrow] does not have a [dispose] method')); + return arrows.dispose(); + } + }; + _apply = function (sources, func) { + return func.apply(null, lodash.map(sources, function (source) { + return source(); + })); + }; + _act = function () { + var func, sources, _i; + sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; + _apply(sources, func); + return lodash.map(sources, function (source) { + return _link(source, function () { + return _apply(sources, func); + }); }); - return output.end(); }; - render.isCode = false; - return render; - }; + _react = function () { + var func, sources, _i; + sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; + return lodash.map(sources, function (source) { + return _link(source, function () { + return _apply(sources, func); + }); + }); + }; + _lift = function () { + var evaluate, func, sources, target, _i; + sources = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), func = arguments[_i++]; + evaluate = function () { + return _apply(sources, func); + }; + target = createSignal(evaluate()); + lodash.map(sources, function (source) { + return _link(source, function () { + return target(evaluate()); + }); + }); + return target; + }; + _merge = function () { + var evaluate, func, sources, target, _i; + sources = 3 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 2) : (_i = 0, []), target = arguments[_i++], func = arguments[_i++]; + evaluate = function () { + return _apply(sources, func); + }; + target(evaluate()); + return lodash.map(sources, function (source) { + return _link(source, function () { + return target(evaluate()); + }); + }); + }; + return { + slot: createSlot, + slots: createSlots, + signal: createSignal, + signals: createSignals, + isSignal: _isSignal, + link: _link, + unlink: _unlink, + act: _act, + react: _react, + lift: _lift, + merge: _merge + }; + }(); }.call(this)); (function () { - Flow.Help = function (_) { - return { - assist: function () { - return _.insertAndExecuteCell('cs', 'assist'); + var FlowError, __hasProp = {}.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) + child[key] = parent[key]; } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; }; - }; + FlowError = function (_super) { + __extends(FlowError, _super); + function FlowError(message, cause) { + var error; + this.message = message; + this.cause = cause; + this.name = 'FlowError'; + error = new Error(); + if (error.stack) { + this.stack = error.stack; + } else { + this.stack = printStackTrace(); + } + } + return FlowError; + }(Error); + Flow.Error = FlowError; }.call(this)); (function () { - Flow.Markdown = function (_) { - var render; - render = function (input, output) { - var error; - try { - return output.data({ - html: marked(input.trim() || '(No content)'), - template: 'flow-html' - }); - } catch (_error) { - error = _error; - return output.error(error); - } finally { - output.end(); + var Digits, formatDate, formatReal, formatTime, significantDigitsBeforeDecimal, __formatReal; + significantDigitsBeforeDecimal = function (value) { + return 1 + Math.floor(Math.log(Math.abs(value)) / Math.LN10); + }; + Digits = function (digits, value) { + var magnitude, sd; + if (value === 0) { + return 0; + } else { + sd = significantDigitsBeforeDecimal(value); + if (sd >= digits) { + return value.toFixed(0); + } else { + magnitude = Math.pow(10, digits - sd); + return Math.round(value * magnitude) / magnitude; } + } + }; + if (typeof exports === 'undefined' || exports === null) { + formatTime = d3.time.format('%Y-%m-%d %H:%M:%S'); + } + formatDate = function (time) { + if (time) { + return formatTime(new Date(time)); + } else { + return '-'; + } + }; + __formatReal = {}; + formatReal = function (precision) { + var cached, format; + format = (cached = __formatReal[precision]) ? cached : __formatReal[precision] = precision === -1 ? lodash.identity : d3.format('.' + precision + 'f'); + return function (value) { + return format(value); }; - render.isCode = false; - return render; + }; + Flow.Format = { + Digits: Digits, + Real: formatReal, + Date: formatDate }; }.call(this)); (function () { - Flow.Renderers = function (_, _sandbox) { + var button, checkbox, content, control, dropdown, html, listbox, markdown, text, textarea, textbox, wrapArray, wrapValue; + wrapValue = function (value, init) { + if (value === void 0) { + return Flow.Dataflow.signal(init); + } else { + if (Flow.Dataflow.isSignal(value)) { + return value; + } else { + return Flow.Dataflow.signal(value); + } + } + }; + wrapArray = function (elements) { + var element; + if (elements) { + if (Flow.Dataflow.isSignal(elements)) { + element = elements(); + if (lodash.isArray(element)) { + return elements; + } else { + return Flow.Dataflow.signal([element]); + } + } else { + return Flow.Dataflow.signals(lodash.isArray(elements) ? elements : [elements]); + } + } else { + return Flow.Dataflow.signals([]); + } + }; + control = function (type, opts) { + var guid; + if (!opts) { + opts = {}; + } + guid = 'gui_' + lodash.uniqueId(); return { - h1: function () { - return Flow.Heading(_, 'h1'); - }, - h2: function () { - return Flow.Heading(_, 'h2'); - }, - h3: function () { - return Flow.Heading(_, 'h3'); - }, - h4: function () { - return Flow.Heading(_, 'h4'); - }, - h5: function () { - return Flow.Heading(_, 'h5'); - }, - h6: function () { - return Flow.Heading(_, 'h6'); - }, - md: function () { - return Flow.Markdown(_); - }, - cs: function (guid) { - return Flow.Coffeescript(_, guid, _sandbox); - }, - raw: function () { - return Flow.Raw(_); + type: type, + id: opts.id || guid, + label: Flow.Dataflow.signal(opts.label || ' '), + description: Flow.Dataflow.signal(opts.description || ' '), + visible: Flow.Dataflow.signal(opts.visible === false ? false : true), + disable: Flow.Dataflow.signal(opts.disable === true ? true : false), + template: 'flow-form-' + type, + templateOf: function (control) { + return control.template; } }; }; - Flow.Notebook = function (_, _renderers) { - var checkConsistency, clearAllCells, clearCell, cloneCell, convertCellToCode, convertCellToHeading, convertCellToMarkdown, convertCellToRaw, copyCell, createCell, createMenu, createMenuItem, createNotebook, createTool, cutCell, deleteCell, deserialize, displayAbout, displayKeyboardShortcuts, duplicateNotebook, editModeKeyboardShortcuts, editModeKeyboardShortcutsHelp, editTitle, executeCommand, goToUrl, initialize, insertAbove, insertBelow, insertCell, insertCellAbove, insertCellAboveAndRun, insertCellBelow, insertCellBelowAndRun, insertNewCellAbove, insertNewCellBelow, menuDivider, mergeCellAbove, mergeCellBelow, moveCellDown, moveCellUp, normalModeKeyboardShortcuts, normalModeKeyboardShortcutsHelp, notImplemented, pasteCellAbove, pasteCellBelow, pasteCellandReplace, printPreview, removeCell, runAllCells, runCell, runCellAndInsertBelow, runCellAndSelectBelow, saveNotebook, saveTitle, selectCell, selectNextCell, selectPreviousCell, serialize, setupKeyboardHandling, showBrowser, showClipboard, showHelp, showOutline, splitCell, startTour, switchToCommandMode, switchToEditMode, switchToPresentationMode, toKeyboardHelp, toggleAllInputs, toggleAllOutputs, toggleInput, toggleOutput, toggleSidebar, undoLastDelete, _about, _areInputsHidden, _areOutputsHidden, _cells, _clipboardCell, _createdDate, _id, _isEditingTitle, _isSidebarHidden, _lastDeletedCell, _menus, _modifiedDate, _selectedCell, _selectedCellIndex, _sidebar, _status, _title, _toolbar; - _id = Flow.Dataflow.signal(''); - _title = Flow.Dataflow.signal('Untitled Flow'); - _createdDate = Flow.Dataflow.signal(new Date()); - _modifiedDate = Flow.Dataflow.signal(new Date()); - _isEditingTitle = Flow.Dataflow.signal(false); - editTitle = function () { - return _isEditingTitle(true); - }; - saveTitle = function () { - return _isEditingTitle(false); - }; - _cells = Flow.Dataflow.signals([]); - _selectedCell = null; - _selectedCellIndex = -1; - _clipboardCell = null; - _lastDeletedCell = null; - _areInputsHidden = Flow.Dataflow.signal(false); - _areOutputsHidden = Flow.Dataflow.signal(false); - _isSidebarHidden = Flow.Dataflow.signal(false); - _status = Flow.Status(_); - _sidebar = Flow.Sidebar(_, _cells); - _about = Flow.About(_); - serialize = function () { - var cell, cells; - cells = function () { - var _i, _len, _ref, _results; - _ref = _cells(); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cell = _ref[_i]; - _results.push({ - type: cell.type(), - input: cell.input() - }); - } - return _results; - }(); - return { - title: _title(), - cells: cells, - createdDate: _createdDate().getTime(), - modifiedDate: new Date().getTime() + content = function (type, opts) { + var self; + self = control(type, opts); + self.value = wrapValue(opts.value, ''); + return self; + }; + text = function (opts) { + return content('text', opts); + }; + html = function (opts) { + return content('html', opts); + }; + markdown = function (opts) { + return content('markdown', opts); + }; + checkbox = function (opts) { + var self; + self = control('checkbox', opts); + self.value = wrapValue(opts.value, opts.value ? true : false); + return self; + }; + dropdown = function (opts) { + var self; + self = control('dropdown', opts); + self.options = opts.options || []; + self.value = wrapValue(opts.value); + self.caption = opts.caption || 'Choose...'; + return self; + }; + listbox = function (opts) { + var self; + self = control('listbox', opts); + self.options = opts.options || []; + self.values = wrapArray(opts.values); + return self; + }; + textbox = function (opts) { + var self; + self = control('textbox', opts); + self.value = wrapValue(opts.value, ''); + self.event = lodash.isString(opts.event) ? opts.event : null; + return self; + }; + textarea = function (opts) { + var self; + self = control('textarea', opts); + self.value = wrapValue(opts.value, ''); + self.event = lodash.isString(opts.event) ? opts.event : null; + self.rows = lodash.isNumber(opts.rows) ? opts.rows : 5; + return self; + }; + button = function (opts) { + var self; + self = control('button', opts); + self.click = lodash.isFunction(opts.click) ? opts.click : lodash.noop; + return self; + }; + Flow.Gui = { + text: text, + html: html, + markdown: markdown, + checkbox: checkbox, + dropdown: dropdown, + listbox: listbox, + textbox: textbox, + textarea: textarea, + button: button + }; +}.call(this)); +(function () { + var compile, _templateCache, __slice = [].slice; + compile = function (template, type) { + var attrs, beginTag, classes, closeTag, id, index, name, tmpl, _ref; + if (0 <= (index = template.indexOf(' '))) { + tmpl = template.substr(0, index); + attrs = template.substr(index); + } else { + tmpl = template; + } + _ref = tmpl.split(/\.+/g), name = _ref[0], classes = 2 <= _ref.length ? __slice.call(_ref, 1) : []; + if (0 === name.indexOf('#')) { + id = name.substr(1); + name = 'div'; + } + if (name === '') { + name = 'div'; + } + beginTag = '<' + name; + if (id) { + beginTag += ' id=\'' + id + '\''; + } + if (classes.length) { + beginTag += ' class=\'' + classes.join(' ') + '\''; + } + if (attrs) { + beginTag += attrs; + } + beginTag += '>'; + closeTag = ''; + if (type === '=') { + return function (content) { + return beginTag + (content !== null && content !== void 0 ? content : '') + closeTag; }; - }; - deserialize = function (id, doc) { - var cell, cells, _i, _len, _ref; - _id(id); - _title(doc.title); - _createdDate(new Date(doc.createdDate)); - _modifiedDate(new Date(doc.modifiedDate)); - cells = function () { - var _i, _len, _ref, _results; - _ref = doc.cells; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cell = _ref[_i]; - _results.push(createCell(cell.type, cell.input)); - } - return _results; - }(); - _cells(cells); - _ref = _cells(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cell = _ref[_i]; - if (!cell.isCode()) { - cell.execute(); - } - } - selectCell(lodash.head(cells)); - }; - createCell = function (type, input) { - if (type == null) { - type = 'cs'; - } - if (input == null) { - input = ''; - } - return Flow.Cell(_, _renderers, type, input); - }; - checkConsistency = function () { - var cell, i, selectionCount, _i, _len, _ref; - selectionCount = 0; - _ref = _cells(); - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - cell = _ref[i]; - if (!cell) { - error('index ' + i + ' is empty'); + } else if (type === '+') { + return function (content, arg0) { + var tag; + tag = beginTag.replace('{0}', arg0); + return tag + content + closeTag; + }; + } else { + return function (contents) { + return beginTag + contents.join('') + closeTag; + }; + } + }; + _templateCache = {}; + Flow.HTML = { + template: function () { + var cached, template, templates, type, _i, _len, _results; + templates = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = templates.length; _i < _len; _i++) { + template = templates[_i]; + if (cached = _templateCache[template]) { + _results.push(cached); } else { - if (cell.isSelected()) { - selectionCount++; + type = template.charAt(0); + if (type === '=' || type === '+') { + _results.push(_templateCache[template] = compile(template.substr(1), type)); + } else { + _results.push(_templateCache[template] = compile(template)); } } } - if (selectionCount !== 1) { - error('selected cell count = ' + selectionCount); + return _results; + }, + render: function (name, html) { + var el; + el = document.createElement(name); + if (html) { + if (lodash.isString(html)) { + el.innerHTML = html; + } else { + el.appendChild(html); + } } - }; - selectCell = function (target, scrollIntoView) { - if (scrollIntoView == null) { - scrollIntoView = true; + return el; + } + }; +}.call(this)); +(function () { + if ((typeof window !== 'undefined' && window !== null ? window.ko : void 0) == null) { + return; + } + ko.bindingHandlers.raw = { + update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $element, arg; + arg = ko.unwrap(valueAccessor()); + if (arg) { + $element = $(element); + $element.empty(); + $element.append(arg); } - if (_selectedCell === target) { - return; + } + }; + ko.bindingHandlers.markdown = { + update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var data, error, html; + data = ko.unwrap(valueAccessor()); + try { + html = marked(data || ''); + } catch (_error) { + error = _error; + html = error.message || 'Error rendering markdown.'; } - if (_selectedCell) { - _selectedCell.isSelected(false); - } - _selectedCell = target; - _selectedCell.isSelected(true); - _selectedCellIndex = _cells.indexOf(_selectedCell); - checkConsistency(); - if (scrollIntoView) { - lodash.defer(_selectedCell.scrollIntoView); - } - return _selectedCell; - }; - cloneCell = function (cell) { - return createCell(cell.type(), cell.input()); - }; - switchToCommandMode = function () { - return _selectedCell.isActive(false); - }; - switchToEditMode = function () { - _selectedCell.isActive(true); - return false; - }; - convertCellToCode = function () { - return _selectedCell.type('cs'); - }; - convertCellToHeading = function (level) { - return function () { - _selectedCell.type('h' + level); - return _selectedCell.execute(); - }; - }; - convertCellToMarkdown = function () { - _selectedCell.type('md'); - return _selectedCell.execute(); - }; - convertCellToRaw = function () { - _selectedCell.type('raw'); - return _selectedCell.execute(); - }; - copyCell = function () { - return _clipboardCell = _selectedCell; - }; - cutCell = function () { - copyCell(); - return removeCell(); - }; - deleteCell = function () { - _lastDeletedCell = _selectedCell; - return removeCell(); - }; - removeCell = function () { - var cells, removedCell; - cells = _cells(); - if (cells.length > 1) { - if (_selectedCellIndex === cells.length - 1) { - removedCell = lodash.head(_cells.splice(_selectedCellIndex, 1)); - selectCell(cells[_selectedCellIndex - 1]); + return $(element).html(html); + } + }; + ko.bindingHandlers.stringify = { + update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var data; + data = ko.unwrap(valueAccessor()); + return $(element).text(JSON.stringify(data, null, 2)); + } + }; + ko.bindingHandlers.enterKey = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $element, action; + if (action = ko.unwrap(valueAccessor())) { + if (lodash.isFunction(action)) { + $element = $(element); + $element.keydown(function (e) { + if (e.which === 13) { + action(viewModel); + } + }); } else { - removedCell = lodash.head(_cells.splice(_selectedCellIndex, 1)); - selectCell(cells[_selectedCellIndex]); - } - if (removedCell) { - _.saveClip('trash', removedCell.type(), removedCell.input()); + throw 'Enter key action is not a function'; } } - }; - insertCell = function (index, cell) { - _cells.splice(index, 0, cell); - selectCell(cell); - return cell; - }; - insertAbove = function (cell) { - return insertCell(_selectedCellIndex, cell); - }; - insertBelow = function (cell) { - return insertCell(_selectedCellIndex + 1, cell); - }; - insertCellAbove = function (type, input) { - return insertAbove(createCell(type, input)); - }; - insertCellBelow = function (type, input) { - return insertBelow(createCell(type, input)); - }; - insertNewCellAbove = function () { - return insertAbove(createCell('cs')); - }; - insertNewCellBelow = function () { - return insertBelow(createCell('cs')); - }; - insertCellAboveAndRun = function (type, input) { - var cell; - cell = insertAbove(createCell(type, input)); - cell.execute(); - return cell; - }; - insertCellBelowAndRun = function (type, input) { - var cell; - cell = insertBelow(createCell(type, input)); - cell.execute(); - return cell; - }; - moveCellDown = function () { - var cells; - cells = _cells(); - if (_selectedCellIndex !== cells.length - 1) { - _cells.splice(_selectedCellIndex, 1); - _selectedCellIndex++; - _cells.splice(_selectedCellIndex, 0, _selectedCell); + } + }; + ko.bindingHandlers.typeahead = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $element, action; + if (action = ko.unwrap(valueAccessor())) { + if (lodash.isFunction(action)) { + $element = $(element); + $element.typeahead(null, { + displayKey: 'value', + source: action + }); + } else { + throw 'Typeahead action is not a function'; + } } - }; - moveCellUp = function () { - var cells; - if (_selectedCellIndex !== 0) { - cells = _cells(); - _cells.splice(_selectedCellIndex, 1); - _selectedCellIndex--; - _cells.splice(_selectedCellIndex, 0, _selectedCell); + } + }; + ko.bindingHandlers.cursorPosition = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var arg; + if (arg = ko.unwrap(valueAccessor())) { + arg.getCursorPosition = function () { + return $(element).textrange('get', 'position'); + }; } - }; - mergeCellBelow = function () { - var cells, nextCell; - cells = _cells(); - if (_selectedCellIndex !== cells.length - 1) { - nextCell = cells[_selectedCellIndex + 1]; - if (_selectedCell.type() === nextCell.type()) { - nextCell.input(_selectedCell.input() + '\n' + nextCell.input()); - removeCell(); - } + } + }; + ko.bindingHandlers.autoResize = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $el, arg, resize; + if (arg = ko.unwrap(valueAccessor())) { + arg.autoResize = resize = function () { + return lodash.defer(function () { + return $el.css('height', 'auto').height(element.scrollHeight); + }); + }; + $el = $(element).on('input', resize); + resize(); } - }; - splitCell = function () { - var cursorPosition, input, left, right; - if (_selectedCell.isActive()) { - input = _selectedCell.input(); - if (input.length > 1) { - cursorPosition = _selectedCell.getCursorPosition(); - if (0 < cursorPosition && cursorPosition < input.length - 1) { - left = input.substr(0, cursorPosition); - right = input.substr(cursorPosition); - _selectedCell.input(left); - insertCell(_selectedCellIndex + 1, createCell('cs', right)); - _selectedCell.isActive(true); + } + }; + ko.bindingHandlers.scrollIntoView = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $el, $viewport, arg; + if (arg = ko.unwrap(valueAccessor())) { + $el = $(element); + $viewport = $el.closest('.flow-box-notebook'); + arg.scrollIntoView = function () { + var height, position, top; + position = $viewport.scrollTop(); + top = $el.position().top + position; + height = $viewport.height(); + if (top - 20 < position || top + 20 > position + height) { + return $viewport.animate({ scrollTop: top }, 'fast'); } - } + }; } - }; - pasteCellAbove = function () { - if (_clipboardCell) { - return insertCell(_selectedCellIndex, cloneCell(_clipboardCell)); + } + }; + ko.bindingHandlers.dom = { + update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var $element, arg; + arg = ko.unwrap(valueAccessor()); + if (arg) { + $element = $(element); + $element.empty(); + $element.append(arg); } - }; - pasteCellBelow = function () { - if (_clipboardCell) { - return insertCell(_selectedCellIndex + 1, cloneCell(_clipboardCell)); + } + }; + ko.bindingHandlers.dump = { + init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { + var object; + return object = ko.unwrap(valueAccessor()); + } + }; +}.call(this)); +(function () { + var keyOf, list, purge, purgeAll, read, write, _ls; + _ls = window.localStorage; + keyOf = function (type, id) { + return '' + type + ':' + id; + }; + list = function (type) { + var i, id, key, objs, t, _i, _ref, _ref1; + objs = []; + for (i = _i = 0, _ref = _ls.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + key = _ls.key(i); + _ref1 = key.split(':'), t = _ref1[0], id = _ref1[1]; + if (type === t) { + objs.push([ + type, + id, + JSON.parse(_ls.getItem(key)) + ]); } - }; - undoLastDelete = function () { - if (_lastDeletedCell) { - insertCell(_selectedCellIndex + 1, _lastDeletedCell); + } + return objs; + }; + read = function (type, id) { + var raw; + if (raw = _ls.getobj(keyOf(type, id))) { + return JSON.parse(raw); + } else { + return null; + } + }; + write = function (type, id, obj) { + return _ls.setItem(keyOf(type, id), JSON.stringify(obj)); + }; + purge = function (type, id) { + if (id) { + return _ls.removeItem(keyOf(type, id)); + } else { + return purgeAll(type); + } + }; + purgeAll = function (type) { + var i, key, _i, _len; + lodash.keys = function () { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = _ls.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push(_ls.key(i)); } - return _lastDeletedCell = null; - }; - runCell = function () { - _selectedCell.execute(); - return false; - }; - runCellAndInsertBelow = function () { - _selectedCell.execute(function () { - return insertNewCellBelow(); - }); - return false; + return _results; + }(); + for (_i = 0, _len = lodash.keys.length; _i < _len; _i++) { + key = lodash.keys[_i]; + if (type === lodash.head(key.split(':'))) { + _ls.removeItem(key); + } + } + }; + Flow.LocalStorage = { + list: list, + read: read, + write: write, + purge: purge + }; +}.call(this)); +(function () { + if ((typeof window !== 'undefined' && window !== null ? window.marked : void 0) == null) { + return; + } + marked.setOptions({ + smartypants: true, + highlight: function (code, lang) { + if (window.hljs) { + return window.hljs.highlightAuto(code, [lang]).value; + } else { + return code; + } + } + }); +}.call(this)); +(function () { + var computeDomain, createAxis, createLinearScale, createOrdinalBandScale, plot, renderD3BarChart, renderD3StackedBar, stack; + computeDomain = function (table, variableName) { + var level, levels, row, value, _i, _len, _ref; + levels = {}; + _ref = table.rows; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + row = _ref[_i]; + value = row[variableName]; + if (!(level = levels[value])) { + levels[value] = true; + } + } + return lodash.keys(levels); + }; + createOrdinalBandScale = function (domain, range) { + return d3.scale.ordinal().domain(domain).rangeRoundBands(range, 0.1); + }; + createLinearScale = function (domain, range) { + return d3.scale.linear().domain(domain).range(range); + }; + createAxis = function (scale, opts) { + var axis; + axis = d3.svg.axis().scale(scale); + if (opts.orient) { + axis.orient(opts.orient); + } + if (opts.ticks) { + axis.ticks(opts.ticks); + } + return axis; + }; + renderD3StackedBar = function (title, table, attrX1, attrX2, attrColor) { + var availableHeight, availableWidth, axisX, bar, d, domainX, el, h4, height, items, label, legend, legendEl, legends, margin, rows, scaleColor, scaleX, schema, svg, svgAxisX, swatch, tooltip, variableColor, variableX1, variableX2, variables, viz, width, _ref; + schema = table.schema, variables = table.variables, rows = table.rows; + variableX1 = table.schema[attrX1]; + variableX2 = table.schema[attrX2]; + variableColor = table.schema[attrColor]; + domainX = Flow.Data.combineRanges(variableX1.domain, variableX2.domain); + availableWidth = 450; + availableHeight = 16 + 30; + margin = { + top: 0, + right: 10, + bottom: 30, + left: 10 }; - runCellAndSelectBelow = function () { - _selectedCell.execute(function () { - return selectNextCell(); - }); - return false; + width = availableWidth - margin.left - margin.right; + height = availableHeight - margin.top - margin.bottom; + scaleX = d3.scale.linear().domain(domainX).range([ + 0, + width + ]); + scaleColor = d3.scale.ordinal().domain(variableColor.domain).range(d3.scale.category10().range()); + axisX = createAxis(scaleX, { orient: 'bottom' }); + svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + viz = d3.select(svg).attr('class', 'plot').attr('width', availableWidth).attr('height', availableHeight).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + svgAxisX = viz.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axisX); + tooltip = function (d) { + var tip, variable, _i, _len; + tip = ''; + for (_i = 0, _len = variables.length; _i < _len; _i++) { + variable = variables[_i]; + tip += '' + variable.label + ': ' + (variable.type === Flow.TFactor ? variable.domain[d[variable.label]] : d[variable.label]) + '\n'; + } + return tip.trim(); }; - saveNotebook = function () { - return _.storeNotebook(_id(), serialize(), function (error, id) { - if (error) { - return console.debug(error); - } else { - return _id(id); + bar = viz.selectAll('.bar').data(rows).enter().append('rect').attr('class', 'bar').attr('x', function (d) { + return scaleX(d[attrX1]); + }).attr('width', function (d) { + return scaleX(d[attrX2] - d[attrX1]); + }).attr('height', height).style('fill', function (d) { + return scaleColor(variableColor.domain[d[attrColor]]); + }).append('title').text(tooltip); + _ref = Flow.HTML.template('.flow-legend', 'span.flow-legend-item', '+span.flow-legend-swatch style=\'background:{0}\'', '=span.flow-legend-label'), legends = _ref[0], legend = _ref[1], swatch = _ref[2], label = _ref[3]; + items = function () { + var _i, _len, _ref1, _results; + _ref1 = variableColor.domain; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + d = _ref1[_i]; + _results.push(legend([ + swatch('', scaleColor(d)), + label(d) + ])); + } + return _results; + }(); + legendEl = Flow.HTML.render('div', legends(items)); + el = document.createElement('div'); + if (title) { + h4 = Flow.HTML.template('=h4')[0]; + el.appendChild(Flow.HTML.render('div', h4(lodash.escape(title)))); + } + el.appendChild(svg); + el.appendChild(legendEl); + return el; + }; + renderD3BarChart = function (title, table, attrX, attrY) { + var availableHeight, availableWidth, axisX, axisY, domainX, domainY, el, h4, height, heightY, interpretationX, interpretationXY, interpretationY, margin, positionX, positionY, row, rows, scaleX, scaleY, schema, svg, svgAxisX, svgAxisY, variableX, variableY, variables, viz, width, widthX; + schema = table.schema, variables = table.variables, rows = table.rows; + variableX = schema[attrX]; + variableY = schema[attrY]; + interpretationX = Flow.Data.computevariableInterpretation(variableX.type); + interpretationY = Flow.Data.computevariableInterpretation(variableY.type); + interpretationXY = interpretationX + interpretationY; + domainX = function () { + var _i, _len, _results; + if (interpretationX === 'c') { + return Flow.Data.includeZeroInRange(variableX.domain); + } else { + _results = []; + for (_i = 0, _len = rows.length; _i < _len; _i++) { + row = rows[_i]; + _results.push(variableX.domain[row[attrX]]); } - }); - }; - toggleInput = function () { - return _selectedCell.toggleInput(); - }; - toggleOutput = function () { - return _selectedCell.toggleOutput(); - }; - toggleAllInputs = function () { - var cell, wereHidden, _i, _len, _ref; - wereHidden = _areInputsHidden(); - _areInputsHidden(!wereHidden); - if (wereHidden) { - _ref = _cells(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cell = _ref[_i]; - cell.autoResize(); + return _results; + } + }(); + domainY = function () { + var _i, _len, _results; + if (interpretationY === 'c') { + return Flow.Data.includeZeroInRange(variableY.domain); + } else { + _results = []; + for (_i = 0, _len = rows.length; _i < _len; _i++) { + row = rows[_i]; + _results.push(variableY.domain[row[attrY]]); } + return _results; } + }(); + availableWidth = interpretationX === 'c' ? 500 : domainX.length * 20; + availableHeight = interpretationY === 'c' ? 500 : domainY.length * 20; + margin = { + top: 20, + right: 20, + bottom: 30, + left: 40 }; - toggleAllOutputs = function () { - return _areOutputsHidden(!_areOutputsHidden()); - }; - toggleSidebar = function () { - return _isSidebarHidden(!_isSidebarHidden()); - }; - showBrowser = function () { - _isSidebarHidden(false); - return _.showBrowser(); - }; - showOutline = function () { - _isSidebarHidden(false); - return _.showOutline(); - }; - showClipboard = function () { - _isSidebarHidden(false); - return _.showClipboard(); - }; - selectNextCell = function () { - var cells; - cells = _cells(); - if (_selectedCellIndex !== cells.length - 1) { - selectCell(cells[_selectedCellIndex + 1]); - } - return false; - }; - selectPreviousCell = function () { - var cells; - if (_selectedCellIndex !== 0) { - cells = _cells(); - selectCell(cells[_selectedCellIndex - 1]); - } - return false; - }; - displayKeyboardShortcuts = function () { - return $('#keyboardShortcutsDialog').modal(); - }; - executeCommand = function (command) { - return function () { - return _.insertAndExecuteCell('cs', command); + width = availableWidth - margin.left - margin.right; + height = availableHeight - margin.top - margin.bottom; + scaleX = interpretationX === 'd' ? createOrdinalBandScale(domainX, [ + 0, + width + ]) : createLinearScale(domainX, [ + 0, + width + ]); + scaleY = interpretationY === 'd' ? createOrdinalBandScale(domainY, [ + 0, + height + ]) : createLinearScale(domainY, [ + height, + 0 + ]); + axisX = createAxis(scaleX, { orient: 'bottom' }); + axisY = createAxis(scaleY, { orient: 'left' }); + if (interpretationXY === 'dc') { + positionX = function (d) { + return scaleX(variableX.domain[d[attrX]]); }; - }; - displayAbout = function () { - return $('#aboutDialog').modal(); - }; - showHelp = function () { - _isSidebarHidden(false); - return _.showHelp(); - }; - createNotebook = function () { - var currentTime; - currentTime = new Date().getTime(); - return deserialize(null, { - title: 'Untitled Flow', - cells: [{ - type: 'cs', - input: '' - }], - createdDate: currentTime, - modifiedDate: currentTime - }); - }; - duplicateNotebook = function () { - var doc; - doc = serialize(); - doc.title = 'Copy of ' + doc.title; - doc.createdDate = doc.modifiedDate; - deserialize(null, doc); - return saveNotebook(); - }; - goToUrl = function (url) { - return function () { - return window.open(url, '_blank'); + positionY = function (d) { + return scaleY(d[attrY]); }; - }; - notImplemented = function () { - }; - printPreview = notImplemented; - pasteCellandReplace = notImplemented; - mergeCellAbove = notImplemented; - switchToPresentationMode = notImplemented; - runAllCells = notImplemented; - clearCell = notImplemented; - clearAllCells = notImplemented; - startTour = notImplemented; - createMenu = function (label, items) { - return { - label: label, - items: items + widthX = scaleX.rangeBand(); + heightY = function (d) { + return height - scaleY(d[attrY]); }; - }; - createMenuItem = function (label, action, isDisabled) { - if (isDisabled == null) { - isDisabled = false; - } - return { - label: label, - action: action, - isAction: true, - isDisabled: isDisabled + } else { + positionX = function (d) { + return scaleX(0); }; - }; - menuDivider = { isAction: false }; - _menus = [ - createMenu('Flow', [ - createMenuItem('New', createNotebook), - createMenuItem('Save', saveNotebook), - menuDivider, - createMenuItem('Duplicate', duplicateNotebook), - menuDivider, - createMenuItem('Print Preview', printPreview, true) - ]), - createMenu('Edit', [ - createMenuItem('Cut Cell', cutCell), - createMenuItem('Copy Cell', copyCell), - createMenuItem('Paste Cell Above', pasteCellAbove), - createMenuItem('Paste Cell Below', pasteCellBelow), - createMenuItem('Paste Cell and Replace', pasteCellandReplace, true), - createMenuItem('Delete Cell', deleteCell), - createMenuItem('Undo Delete Cell', undoLastDelete), - menuDivider, - createMenuItem('Insert Cell Above', insertNewCellAbove), - createMenuItem('Insert Cell Below', insertNewCellBelow), - menuDivider, - createMenuItem('Split Cell', splitCell), - createMenuItem('Merge Cell Above', mergeCellAbove, true), - createMenuItem('Merge Cell Below', mergeCellBelow), - menuDivider, - createMenuItem('Move Cell Up', moveCellUp), - createMenuItem('Move Cell Down', moveCellDown) - ]), - createMenu('View', [ - createMenuItem('Toggle Input', toggleInput), - createMenuItem('Toggle Output', toggleOutput), - menuDivider, - createMenuItem('Toggle All Inputs', toggleAllInputs), - createMenuItem('Toggle All Outputs', toggleAllOutputs), - menuDivider, - createMenuItem('Toggle Sidebar', toggleSidebar), - createMenuItem('Outline', showOutline), - createMenuItem('Files', showBrowser), - createMenuItem('Clipboard', showClipboard), - menuDivider, - createMenuItem('Presentation Mode', switchToPresentationMode, true) - ]), - createMenu('Format', [ - createMenuItem('Code', convertCellToCode), - menuDivider, - createMenuItem('Heading 1', convertCellToHeading(1)), - createMenuItem('Heading 2', convertCellToHeading(2)), - createMenuItem('Heading 3', convertCellToHeading(3)), - createMenuItem('Heading 4', convertCellToHeading(4)), - createMenuItem('Heading 5', convertCellToHeading(5)), - createMenuItem('Heading 6', convertCellToHeading(6)), - createMenuItem('Markdown', convertCellToMarkdown), - createMenuItem('Raw', convertCellToRaw) - ]), - createMenu('Run', [ - createMenuItem('Run', runCell), - createMenuItem('Run and Select Below', runCellAndSelectBelow), - createMenuItem('Run and Insert Below', runCellAndInsertBelow), - menuDivider, - createMenuItem('Run All', runAllCells, true), - menuDivider, - createMenuItem('Clear Cell', clearCell, true), - menuDivider, - createMenuItem('Clear All', clearAllCells, true) - ]), - createMenu('Admin', [ - createMenuItem('Jobs', executeCommand('getJobs')), - createMenuItem('Cluster Status', executeCommand('getCloud')), - createMenuItem('Inspect Log', executeCommand('getLogFile 0')), - createMenuItem('Download Log', goToUrl('/Logs/download')), - createMenuItem('Profiler', executeCommand('getProfile depth: 10')), - createMenuItem('Stack Trace', executeCommand('getStackTrace')), - createMenuItem('Timeline', executeCommand('getTimeline')) - ]), - createMenu('Help', [ - createMenuItem('Tour', startTour, true), - createMenuItem('Contents', showHelp), - createMenuItem('Keyboard Shortcuts', displayKeyboardShortcuts), - menuDivider, - createMenuItem('H2O Documentation', goToUrl('http://docs.h2o.ai/')), - createMenuItem('h2o.ai', goToUrl('http://h2o.ai/')), - menuDivider, - createMenuItem('About', displayAbout) - ]) - ]; - createTool = function (icon, label, action, isDisabled) { - if (isDisabled == null) { - isDisabled = false; - } - return { - label: label, - action: action, - isDisabled: isDisabled, - icon: 'fa fa-' + icon + positionY = function (d) { + return scaleY(variableY.domain[d[attrY]]); }; - }; - _toolbar = [ - [createTool('save', 'Save', saveNotebook)], - [ - createTool('plus', 'Insert Cell Below', insertNewCellBelow), - createTool('arrow-up', 'Move Cell Up', moveCellUp), - createTool('arrow-down', 'Move Cell Down', moveCellDown) - ], - [ - createTool('cut', 'Cut Cell', cutCell), - createTool('copy', 'Copy Cell', copyCell), - createTool('paste', 'Paste Cell Below', pasteCellBelow) - ], - [createTool('play', 'Run', runCell)] - ]; - normalModeKeyboardShortcuts = [ - [ - 'enter', - 'edit mode', - switchToEditMode - ], - [ - 'y', - 'to code', - convertCellToCode - ], - [ - 'm', - 'to markdown', - convertCellToMarkdown - ], - [ - 'r', - 'to raw', - convertCellToRaw - ], - [ - '1', - 'to heading 1', - convertCellToHeading(1) - ], - [ - '2', - 'to heading 2', - convertCellToHeading(2) - ], - [ - '3', - 'to heading 3', - convertCellToHeading(3) - ], - [ - '4', - 'to heading 4', - convertCellToHeading(4) - ], - [ - '5', - 'to heading 5', - convertCellToHeading(5) - ], - [ - '6', - 'to heading 6', - convertCellToHeading(6) - ], - [ - 'up', - 'select previous cell', - selectPreviousCell - ], - [ - 'down', - 'select next cell', - selectNextCell - ], - [ - 'k', - 'select previous cell', - selectPreviousCell - ], - [ - 'j', - 'select next cell', - selectNextCell - ], - [ - 'ctrl+k', - 'move cell up', - moveCellUp - ], - [ - 'ctrl+j', - 'move cell down', - moveCellDown - ], - [ - 'a', - 'insert cell above', - insertNewCellAbove - ], - [ - 'b', - 'insert cell below', - insertNewCellBelow - ], - [ - 'x', - 'cut cell', - cutCell - ], - [ - 'c', - 'copy cell', - copyCell - ], - [ - 'shift+v', - 'paste cell above', - pasteCellAbove - ], - [ - 'v', - 'paste cell below', - pasteCellBelow - ], - [ - 'z', - 'undo last delete', - undoLastDelete - ], - [ - 'd d', - 'delete cell (press twice)', - deleteCell - ], - [ - 'shift+m', - 'merge cell below', - mergeCellBelow - ], - [ - 's', - 'save notebook', - saveNotebook - ], - [ - 'o', - 'toggle output', - toggleOutput - ], - [ - 'h', - 'keyboard shortcuts', - displayKeyboardShortcuts - ] - ]; - editModeKeyboardShortcuts = [ - [ - 'esc', - 'command mode', - switchToCommandMode - ], - [ - 'ctrl+m', - 'command mode', - switchToCommandMode - ], - [ - 'shift+enter', - 'run cell, select below', - runCellAndSelectBelow - ], - [ - 'ctrl+enter', - 'run cell', - runCell - ], - [ - 'alt+enter', - 'run cell, insert below', - runCellAndInsertBelow - ], - [ - 'ctrl+shift+-', - 'split cell', - splitCell - ], - [ - 'mod+s', - 'save notebook', - saveNotebook - ] - ]; - toKeyboardHelp = function (shortcut) { - var caption, keystrokes, sequence; - sequence = shortcut[0], caption = shortcut[1]; - keystrokes = lodash.map(sequence.split(/\+/g), function (key) { - return '' + key + ''; - }).join(' '); - return { - keystrokes: keystrokes, - caption: caption + widthX = function (d) { + return scaleX(d[attrX]); }; + heightY = scaleY.rangeBand(); + } + svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + viz = d3.select(svg).attr('class', 'plot').attr('width', availableWidth).attr('height', availableHeight).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + svgAxisX = viz.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axisX); + svgAxisY = viz.append('g').attr('class', 'axis').call(axisY); + if (false) { + svgAxisY.append('text').attr('transform', 'rotate(-90)').attr('y', 6).attr('dy', '.71em').style('text-anchor', 'end').text(variableY.label); + } + viz.selectAll('.bar').data(rows).enter().append('rect').attr('class', 'bar').attr('x', positionX).attr('width', widthX).attr('y', positionY).attr('height', heightY); + el = document.createElement('div'); + if (title) { + h4 = Flow.HTML.template('=h4')[0]; + el.appendChild(Flow.HTML.render('div', h4(lodash.escape(title)))); + } + el.appendChild(svg); + return el; + }; + plot = function (_config, go) { + var initialize, renderText, renderUsingVega; + renderText = function (config, go) { + var grid, h4, p, row, table, tbody, td, tdr, tds, th, thead, thr, ths, tr, trs, value, variable, _ref; + _ref = Flow.HTML.template('.grid', '=h4', '=p', 'table', '=thead', 'tbody', 'tr', '=th', '=th.rt', '=td', '=td.rt'), grid = _ref[0], h4 = _ref[1], p = _ref[2], table = _ref[3], thead = _ref[4], tbody = _ref[5], tr = _ref[6], th = _ref[7], thr = _ref[8], td = _ref[9], tdr = _ref[10]; + ths = function () { + var _i, _len, _ref1, _results; + _ref1 = config.data.variables; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + variable = _ref1[_i]; + switch (variable.type) { + case Flow.TNumber: + _results.push(thr(lodash.escape(variable.label))); + break; + default: + _results.push(th(lodash.escape(variable.label))); + } + } + return _results; + }(); + trs = function () { + var _i, _len, _ref1, _results; + _ref1 = config.data.rows; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + row = _ref1[_i]; + tds = function () { + var _j, _len1, _ref2, _results1; + _ref2 = config.data.variables; + _results1 = []; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + variable = _ref2[_j]; + value = row[variable.label]; + switch (variable.type) { + case Flow.TFactor: + _results1.push(td(value === null ? '-' : lodash.escape(variable.domain[value]))); + break; + case Flow.TNumber: + _results1.push(tdr(value === null ? '-' : value)); + break; + case Flow.TArray: + _results1.push(td(value === null ? '-' : value.join(', '))); + break; + case Flow.TObject: + _results1.push(td(value === null ? '-' : variable.format(value))); + break; + default: + _results1.push(td(value === null ? '-' : value)); + } + } + return _results1; + }(); + _results.push(tr(tds)); + } + return _results; + }(); + return go(null, Flow.HTML.render('div', grid([ + h4(config.data.label), + p(config.data.description), + table([ + thead(tr(ths)), + tbody(trs) + ]) + ]))); }; - normalModeKeyboardShortcutsHelp = lodash.map(normalModeKeyboardShortcuts, toKeyboardHelp); - editModeKeyboardShortcutsHelp = lodash.map(editModeKeyboardShortcuts, toKeyboardHelp); - setupKeyboardHandling = function (mode) { - var caption, f, shortcut, _i, _j, _len, _len1, _ref, _ref1; - for (_i = 0, _len = normalModeKeyboardShortcuts.length; _i < _len; _i++) { - _ref = normalModeKeyboardShortcuts[_i], shortcut = _ref[0], caption = _ref[1], f = _ref[2]; - Mousetrap.bind(shortcut, f); + renderUsingVega = function (config, go) { + var color, data, domainX, domainY, el, enter, height, mark, scaleTypeX, scaleTypeY, spec, transformX, transformY, type, variableColor, variableX, variableY, width, x, y, _ref, _ref1; + width = config.width, height = config.height, type = config.type, data = config.data, x = config.x, y = config.y, color = config.color; + if (lodash.isFunction(x)) { + _ref = x(), transformX = _ref[0], x = _ref[1]; + transformX.point = 'data.' + y; + } + variableX = data.schema[x]; + if (lodash.isFunction(y)) { + _ref1 = y(), transformY = _ref1[0], y = _ref1[1]; + transformY.point = 'data.' + x; + } + variableY = data.schema[y]; + variableColor = data.schema[color]; + if (!variableX) { + return go(new Flow.Error('Invalid \'x\' variable: \'' + x + '\'')); + } + if (!variableY) { + return go(new Flow.Error('Invalid \'y\' variable: \'' + y + '\'')); + } + if (color) { + if (!variableColor) { + return go(new Flow.Error('Invalid \'color\' variable: \'' + color + '\'')); + } + if (variableColor.type === Flow.TNumber) { + return go(new Flow.Error('Encoding numeric variables into mark color is not supported.')); + } + } + spec = {}; + scaleTypeX = variableX.type === Flow.TNumber ? 'linear' : 'ordinal'; + scaleTypeY = variableY.type === Flow.TNumber ? 'linear' : 'ordinal'; + if (scaleTypeX === 'ordinal') { + domainX = computeDomain(data, variableX.label); + } + if (scaleTypeY === 'ordinal') { + domainY = computeDomain(data, variableY.label); + } + spec.width = width ? width : scaleTypeX === 'linear' ? 250 : 20 * domainX.length; + spec.height = height ? height : scaleTypeY === 'linear' ? 250 : 15 * domainY.length; + spec.data = [{ name: 'table' }]; + spec.scales = [ + { + name: 'x', + type: scaleTypeX, + domain: { + data: 'table', + field: 'data.' + x + }, + range: 'width', + nice: true + }, + { + name: 'y', + type: scaleTypeY, + domain: { + data: 'table', + field: 'data.' + y + }, + range: 'height', + nice: true + } + ]; + if (color) { + spec.scales.push({ + name: 'color', + type: 'ordinal', + range: 'category20' + }); + } + spec.axes = [ + { + type: 'x', + scale: 'x', + title: x + }, + { + type: 'y', + scale: 'y', + title: y + } + ]; + if (type === 'point') { + mark = { + type: 'symbol', + from: { data: 'table' }, + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + y: { + scale: 'y', + field: 'data.' + y + }, + stroke: { value: 'steelblue' }, + strokeWidth: { value: 1.5 } + } + } + }; + } else if (type === 'line') { + if (color) { + mark = { + type: 'group', + from: { + data: 'table', + transform: [{ + type: 'facet', + keys: ['data.' + color] + }] + }, + marks: [{ + type: 'line', + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + y: { + scale: 'y', + field: 'data.' + y + }, + stroke: { + scale: 'color', + field: 'data.' + color + }, + strokeWidth: { value: 1.5 } + } + } + }] + }; + } else { + mark = { + type: 'line', + from: { data: 'table' }, + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + y: { + scale: 'y', + field: 'data.' + y + }, + stroke: { value: 'steelblue' }, + strokeWidth: { value: 1.5 } + } + } + }; + } + } else if (type === 'area') { + if (scaleTypeX === 'ordinal' && scaleTypeY === 'linear') { + enter = { + x: { + scale: 'x', + field: 'data.' + x + }, + y: { + scale: 'y', + field: 'data.' + y + }, + y2: { + scale: 'y', + value: 0 + }, + fill: { value: 'steelblue' } + }; + } else if (scaleTypeX === 'linear' && scaleTypeY === 'ordinal') { + enter = { + x: { + scale: 'x', + field: 'data.' + x + }, + x2: { + scale: 'x', + value: 0 + }, + y: { + scale: 'y', + field: 'data.' + y + }, + fill: { value: 'steelblue' } + }; + } else if (scaleTypeX === 'linear' && scaleTypeY === 'linear') { + enter = { + x: { + scale: 'x', + field: 'data.' + x + }, + y: { + scale: 'y', + field: 'data.' + y + }, + y2: { + scale: 'y', + value: 0 + }, + fill: { value: 'steelblue' } + }; + } else { + return go(new Flow.Error('Not implemented')); + } + mark = { + type: 'area', + from: { data: 'table' }, + properties: { enter: enter } + }; + } else if (type === 'interval') { + if (scaleTypeX === 'ordinal' && scaleTypeY === 'linear') { + if (color) { + mark = { + type: 'group', + from: { + data: 'table', + transform: [ + { + type: 'facet', + keys: ['data.' + color] + }, + transformY + ] + }, + marks: [{ + type: 'rect', + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + width: { + scale: 'x', + band: true, + offset: -1 + }, + y: { + scale: 'y', + field: 'y' + }, + y2: { + scale: 'y', + field: 'y2' + }, + fill: { + scale: 'color', + field: 'data.' + color + } + } + } + }] + }; + } else { + mark = { + type: 'rect', + from: { data: 'table' }, + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + width: { + scale: 'x', + band: true, + offset: -1 + }, + y: { + scale: 'y', + field: 'data.' + y + }, + y2: { + scale: 'y', + value: 0 + }, + fill: { value: 'steelblue' } + } + } + }; + } + } else if (scaleTypeX === 'linear' && scaleTypeY === 'ordinal') { + if (color) { + mark = { + type: 'group', + from: { + data: 'table', + transform: [ + { + type: 'facet', + keys: ['data.' + color] + }, + transformX + ] + }, + marks: [{ + type: 'rect', + properties: { + enter: { + x: { + scale: 'x', + field: 'y' + }, + x2: { + scale: 'x', + field: 'y2' + }, + y: { + scale: 'y', + field: 'data.' + y + }, + height: { + scale: 'y', + band: true, + offset: -1 + }, + fill: { + scale: 'color', + field: 'data.' + color + } + } + } + }] + }; + } else { + mark = { + type: 'rect', + from: { data: 'table' }, + properties: { + enter: { + x: { + scale: 'x', + field: 'data.' + x + }, + x2: { + scale: 'x', + value: 0 + }, + y: { + scale: 'y', + field: 'data.' + y + }, + height: { + scale: 'y', + band: true, + offset: -1 + }, + fill: { value: 'steelblue' } + } + } + }; + } + } else if (scaleTypeX === 'linear' && scaleTypeY === 'linear') { + return go(new Flow.Error('Not implemented')); + } else { + return go(new Flow.Error('Not implemented')); + } } - for (_j = 0, _len1 = editModeKeyboardShortcuts.length; _j < _len1; _j++) { - _ref1 = editModeKeyboardShortcuts[_j], shortcut = _ref1[0], caption = _ref1[1], f = _ref1[2]; - Mousetrap.bindGlobal(shortcut, f); + spec.marks = [mark]; + go(null, Flow.HTML.render('div', el = document.createElement('div'))); + vg.parse.spec(spec, function (ctor) { + var chart; + chart = ctor({ + el: el, + data: { table: data.rows } + }); + return chart.update(); + }); + }; + initialize = function (config) { + var error; + try { + switch (config.type) { + case 'point': + case 'line': + case 'area': + case 'interval': + return renderUsingVega(config, go); + case 'schema': + return go(new Flow.Error('Not implemented: ' + config.type)); + case 'text': + return renderText(config, go); + default: + return go(new Flow.Error('Invalid mark type: ' + config.type)); + } + } catch (_error) { + error = _error; + return go(new Flow.Error('Error creating plot.', error)); } }; - initialize = function () { - setupKeyboardHandling('normal'); - insertNewCellBelow(); - Flow.Dataflow.link(_.loadNotebook, deserialize); - Flow.Dataflow.link(_.selectCell, selectCell); - Flow.Dataflow.link(_.insertAndExecuteCell, function (type, input) { - return lodash.defer(insertCellBelowAndRun, type, input); - }); - return Flow.Dataflow.link(_.insertCell, function (type, input) { - return lodash.defer(insertCellBelow, type, input); - }); + return initialize(_config); + }; + stack = function (attr) { + var self; + return function () { + var transform; + transform = { + type: 'stack', + height: 'data.' + attr + }; + return [ + transform, + attr + ]; }; - Flow.Dataflow.link(_.ready, initialize); - return { - title: _title, - isEditingTitle: _isEditingTitle, - editTitle: editTitle, - saveTitle: saveTitle, - menus: _menus, - sidebar: _sidebar, - status: _status, - toolbar: _toolbar, - cells: _cells, - areInputsHidden: _areInputsHidden, - areOutputsHidden: _areOutputsHidden, - isSidebarHidden: _isSidebarHidden, - shortcutsHelp: { - normalMode: normalModeKeyboardShortcutsHelp, - editMode: editModeKeyboardShortcutsHelp - }, - about: _about, - templateOf: function (view) { - return view.template; + self = function (table) { + var end, endVariable, n, p, row, start, startVariable, type, value, _i, _len, _ref, _ref1; + type = table.schema[attr].type; + _ref = table.expand(type, type), startVariable = _ref[0], endVariable = _ref[1]; + start = startVariable.label; + end = endVariable.label; + n = 0; + p = 0; + _ref1 = table.rows; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + row = _ref1[_i]; + value = row[attr]; + if (value >= 0) { + row[start] = p; + row[end] = p = p + value; + } else { + row[start] = n; + row[end] = n = n + value; + } } + startVariable.domain = [ + n, + p + ]; + endVariable.domain = [ + n, + p + ]; + return [ + start, + end + ]; }; + return self; }; + Flow.Plot = plot; + plot.stack = stack; }.call(this)); (function () { - var isExpandable, preview, previewArray, previewObject; - isExpandable = function (type) { - switch (type) { - case 'null': - case 'undefined': - case 'Boolean': - case 'String': - case 'Number': - case 'Date': - case 'RegExp': - case 'Arguments': - case 'Function': - return false; - default: - return true; - } - }; - previewArray = function (array) { - var element, ellipsis, previews; - ellipsis = array.length > 5 ? ', ...' : ''; - previews = function () { - var _i, _len, _ref, _results; - _ref = lodash.head(array, 5); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - element = _ref[_i]; - _results.push(preview(element)); - } - return _results; - }(); - return '[' + previews.join(', ') + ellipsis + ']'; - }; - previewObject = function (object) { - var count, ellipsis, key, previews, value; - count = 0; - previews = []; - ellipsis = ''; - for (key in object) { - value = object[key]; - if (!(key !== '_flow_')) { - continue; - } - previews.push('' + key + ': ' + preview(value)); - if (++count === 5) { - ellipsis = ', ...'; - break; + Flow.Prelude = function () { + var _always, _copy, _deepClone, _isDefined, _isFalsy, _isTruthy, _negative, _never, _remove, _repeat, _typeOf, _words; + _isDefined = function (value) { + return !lodash.isUndefined(value); + }; + _isTruthy = function (value) { + if (value) { + return true; + } else { + return false; } - } - return '{' + previews.join(', ') + ellipsis + '}'; - }; - preview = function (element, recurse) { - var type; - if (recurse == null) { - recurse = false; - } - type = Flow.Prelude.typeOf(element); - switch (type) { - case 'Boolean': - case 'String': - case 'Number': - case 'Date': - case 'RegExp': - return element; - case 'undefined': - case 'null': - case 'Function': - case 'Arguments': - return type; - case 'Array': - if (recurse) { - return previewArray(element); + }; + _isFalsy = function (value) { + if (value) { + return false; } else { - return type; + return true; } - break; - default: - if (recurse) { - return previewObject(element); + }; + _negative = function (value) { + return !value; + }; + _always = function () { + return true; + }; + _never = function () { + return false; + }; + _copy = function (array) { + return array.slice(0); + }; + _remove = function (array, element) { + var index; + if (-1 < (index = lodash.indexOf(array, element))) { + return lodash.head(arra.splice(index, 1)); } else { - return type; + return void 0; } - } - }; - Flow.ObjectBrowserElement = function (key, object) { - var toggle, _canExpand, _expansions, _isExpanded, _type; - _expansions = Flow.Dataflow.signal(null); - _isExpanded = Flow.Dataflow.signal(false); - _type = Flow.Prelude.typeOf(object); - _canExpand = isExpandable(_type); - toggle = function () { - var expansions, value; - if (!_canExpand) { - return; + }; + _words = function (text) { + return text.split(/\s+/); + }; + _repeat = function (count, value) { + var array, i, _i; + array = []; + for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) { + array.push(value); } - if (_expansions() === null) { - expansions = []; - for (key in object) { - value = object[key]; - if (key !== '_flow_') { - expansions.push(Flow.ObjectBrowserElement(key, value)); - } + return array; + }; + _typeOf = function (a) { + var type; + type = Object.prototype.toString.call(a); + if (a === null) { + return Flow.TNull; + } else if (a === void 0) { + return Flow.TUndefined; + } else if (a === true || a === false || type === '[object Boolean]') { + return Flow.TBoolean; + } else { + switch (type) { + case '[object String]': + return Flow.TString; + case '[object Number]': + return Flow.TNumber; + case '[object Function]': + return Flow.TFunction; + case '[object Object]': + return Flow.TObject; + case '[object Array]': + return Flow.TArray; + case '[object Arguments]': + return Flow.TArguments; + case '[object Date]': + return Flow.TDate; + case '[object RegExp]': + return Flow.TRegExp; + case '[object Error]': + return Flow.TError; + default: + return type; } - _expansions(expansions); } - return _isExpanded(!_isExpanded()); }; - return { - key: key, - preview: preview(object, true), - toggle: toggle, - expansions: _expansions, - isExpanded: _isExpanded, - canExpand: _canExpand + _deepClone = function (obj) { + return JSON.parse(JSON.stringify(obj)); }; - }; - Flow.ObjectBrowser = function (key, object) { return { - object: Flow.ObjectBrowserElement(key, object), - template: 'flow-object' + isDefined: _isDefined, + isTruthy: _isTruthy, + isFalsy: _isFalsy, + negative: _negative, + always: _always, + never: _never, + copy: _copy, + remove: _remove, + words: _words, + repeat: _repeat, + typeOf: _typeOf, + deepClone: _deepClone, + stringify: JSON.stringify }; - }; -}.call(this)); -(function () { - Flow.Outline = function (_, _cells) { - return { cells: _cells }; - }; + }(); }.call(this)); (function () { - Flow.Raw = function (_) { - var render; - render = function (input, output) { - output.data({ - text: input, - template: 'flow-raw' - }); - return output.end(); + Flow.Sandbox = function (_, routines) { + return { + routines: routines, + context: {}, + results: {} }; - render.isCode = false; - return render; }; }.call(this)); (function () { - Flow.Sidebar = function (_, cells) { - var switchToBrowser, switchToClipboard, switchToHelp, switchToOutline, _browser, _clipboard, _help, _isBrowserMode, _isClipboardMode, _isHelpMode, _isOutlineMode, _mode, _outline; - _mode = Flow.Dataflow.signal('help'); - _outline = Flow.Outline(_, cells); - _isOutlineMode = Flow.Dataflow.lift(_mode, function (mode) { - return mode === 'outline'; - }); - switchToOutline = function () { - return _mode('outline'); - }; - _browser = Flow.Browser(_); - _isBrowserMode = Flow.Dataflow.lift(_mode, function (mode) { - return mode === 'browser'; - }); - switchToBrowser = function () { - return _mode('browser'); - }; - _clipboard = Flow.Clipboard(_); - _isClipboardMode = Flow.Dataflow.lift(_mode, function (mode) { - return mode === 'clipboard'; - }); - switchToClipboard = function () { - return _mode('clipboard'); - }; - _help = Flow.Help(_); - _isHelpMode = Flow.Dataflow.lift(_mode, function (mode) { - return mode === 'help'; - }); - switchToHelp = function () { - return _mode('help'); - }; - Flow.Dataflow.link(_.ready, function () { - Flow.Dataflow.link(_.showHelp, function () { - return switchToHelp(); - }); - Flow.Dataflow.link(_.showClipboard, function () { - return switchToClipboard(); - }); - Flow.Dataflow.link(_.showBrowser, function () { - return switchToBrowser(); - }); - return Flow.Dataflow.link(_.showOutline, function () { - return switchToOutline(); - }); - }); - return { - outline: _outline, - isOutlineMode: _isOutlineMode, - switchToOutline: switchToOutline, - browser: _browser, - isBrowserMode: _isBrowserMode, - switchToBrowser: switchToBrowser, - clipboard: _clipboard, - isClipboardMode: _isClipboardMode, - switchToClipboard: switchToClipboard, - help: _help, - isHelpMode: _isHelpMode, - switchToHelp: switchToHelp - }; - }; + Flow.TUndefined = 'undefined'; + Flow.TNull = 'null'; + Flow.TBoolean = 'Boolean'; + Flow.TString = 'String'; + Flow.TNumber = 'Number'; + Flow.TFunction = 'Function'; + Flow.TObject = 'Object'; + Flow.TArray = 'Array'; + Flow.TArguments = 'Arguments'; + Flow.TDate = 'Date'; + Flow.TRegExp = 'RegExp'; + Flow.TError = 'Error'; + Flow.TFactor = 'Factor'; }.call(this)); (function () { - Flow.Status = function (_) { - var defaultMessage, onStatus, _connections, _isBusy, _message; - defaultMessage = 'Ready'; - _message = Flow.Dataflow.signal(defaultMessage); - _connections = Flow.Dataflow.signal(0); - _isBusy = Flow.Dataflow.lift(_connections, function (connections) { - return connections > 0; - }); - onStatus = function (category, type, data) { - var connections; - console.debug(category, type, data); - switch (category) { - case 'server': - switch (type) { - case 'request': - _connections(_connections() + 1); - return lodash.defer(_message, 'Requesting ' + data); - case 'response': - case 'error': - _connections(connections = _connections() - 1); - if (connections) { - return lodash.defer(_message, 'Waiting for ' + connections + ' responses...'); - } else { - return lodash.defer(_message, defaultMessage); - } - } - } - }; - Flow.Dataflow.link(_.ready, function () { - return Flow.Dataflow.link(_.status, onStatus); - }); - return { - message: _message, - connections: _connections, - isBusy: _isBusy - }; + var describeCount, fromNow; + describeCount = function (count, singular, plural) { + if (!plural) { + plural = singular + 's'; + } + switch (count) { + case 0: + return 'No ' + plural; + case 1: + return '1 ' + singular; + default: + return '' + count + ' ' + plural; + } + }; + fromNow = function (date) { + return moment(date).fromNow(); + }; + Flow.Util = { + describeCount: describeCount, + fromNow: fromNow }; }.call(this)); (function () { diff --git a/src/core/components/about.coffee b/src/core/components/about.coffee index c0e02347a..aaa77c3e0 100644 --- a/src/core/components/about.coffee +++ b/src/core/components/about.coffee @@ -1,4 +1,4 @@ -FLOW_VERSION = '0.2.25' +FLOW_VERSION = '0.2.26' Flow.About = (_) -> _properties = signals []