From 16f51fd9dc454b26d9866b080caa17ffe2f8ce27 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Mon, 13 Aug 2012 23:36:38 -0400 Subject: Updated to use sprockets! Ah, much cleaner. --- bin/dashing | 2 +- dashing.gemspec | 3 +- javascripts/batman.jquery.js | 109 + javascripts/batman.js | 11811 +++++++++++++++++++ javascripts/dashing.coffee | 96 + javascripts/es5-shim.js | 1021 ++ javascripts/jquery.js | 4 + lib/dashing.rb | 57 +- .../project/assets/fonts/fontawesome-webfont.eot | Bin 0 -> 38708 bytes .../project/assets/fonts/fontawesome-webfont.svg | 255 + .../project/assets/fonts/fontawesome-webfont.ttf | Bin 0 -> 68476 bytes .../project/assets/fonts/fontawesome-webfont.woff | Bin 0 -> 41752 bytes templates/project/assets/images/.empty_directory | 1 + templates/project/assets/images/favicon.ico | Bin 0 -> 5430 bytes .../project/assets/javascripts/.empty_directory | 1 + .../project/assets/javascripts/application.coffee | 25 + .../assets/javascripts/dashing.gridster.coffee | 32 + .../javascripts/gridster/jquery.collision.js | 224 + .../assets/javascripts/gridster/jquery.coords.js | 108 + .../javascripts/gridster/jquery.draggable.js | 327 + .../assets/javascripts/gridster/jquery.gridster.js | 2890 +++++ .../javascripts/gridster/jquery.leanModal.min.js | 5 + .../project/assets/javascripts/gridster/utils.js | 41 + .../project/assets/javascripts/jquery.knob.js | 646 + .../project/assets/stylesheets/application.scss | 227 + .../project/assets/stylesheets/font-awesome.css | 303 + .../project/assets/stylesheets/jquery.gridster.css | 57 + templates/project/config.ru | 11 + templates/project/dashboards/layout.erb | 43 +- templates/project/public/.empty_directory | 1 + .../project/public/fonts/fontawesome-webfont.eot | Bin 38708 -> 0 bytes .../project/public/fonts/fontawesome-webfont.svg | 255 - .../project/public/fonts/fontawesome-webfont.ttf | Bin 68476 -> 0 bytes .../project/public/fonts/fontawesome-webfont.woff | Bin 41752 -> 0 bytes templates/project/public/images/.empty_directory | 1 - templates/project/public/images/favicon.ico | Bin 5430 -> 0 bytes .../project/public/javascripts/.empty_directory | 1 - .../project/public/javascripts/jquery.knob.js | 28 - .../public/javascripts/jquery.masonry.min.js | 10 - .../project/public/stylesheets/application.scss | 238 - .../project/public/stylesheets/font-awesome.css | 303 - vendor/javascripts/application.coffee | 68 - vendor/javascripts/batman.jquery.js | 109 - vendor/javascripts/batman.js | 11811 ------------------- vendor/javascripts/es5-shim.js | 1021 -- vendor/javascripts/jquery.js | 4 - vendor/javascripts/widget.coffee | 20 - 47 files changed, 18235 insertions(+), 13934 deletions(-) create mode 100644 javascripts/batman.jquery.js create mode 100644 javascripts/batman.js create mode 100644 javascripts/dashing.coffee create mode 100644 javascripts/es5-shim.js create mode 100644 javascripts/jquery.js create mode 100755 templates/project/assets/fonts/fontawesome-webfont.eot create mode 100755 templates/project/assets/fonts/fontawesome-webfont.svg create mode 100755 templates/project/assets/fonts/fontawesome-webfont.ttf create mode 100755 templates/project/assets/fonts/fontawesome-webfont.woff create mode 100644 templates/project/assets/images/.empty_directory create mode 100644 templates/project/assets/images/favicon.ico create mode 100644 templates/project/assets/javascripts/.empty_directory create mode 100644 templates/project/assets/javascripts/application.coffee create mode 100644 templates/project/assets/javascripts/dashing.gridster.coffee create mode 100755 templates/project/assets/javascripts/gridster/jquery.collision.js create mode 100755 templates/project/assets/javascripts/gridster/jquery.coords.js create mode 100755 templates/project/assets/javascripts/gridster/jquery.draggable.js create mode 100755 templates/project/assets/javascripts/gridster/jquery.gridster.js create mode 100644 templates/project/assets/javascripts/gridster/jquery.leanModal.min.js create mode 100755 templates/project/assets/javascripts/gridster/utils.js create mode 100644 templates/project/assets/javascripts/jquery.knob.js create mode 100644 templates/project/assets/stylesheets/application.scss create mode 100644 templates/project/assets/stylesheets/font-awesome.css create mode 100755 templates/project/assets/stylesheets/jquery.gridster.css create mode 100644 templates/project/public/.empty_directory delete mode 100755 templates/project/public/fonts/fontawesome-webfont.eot delete mode 100755 templates/project/public/fonts/fontawesome-webfont.svg delete mode 100755 templates/project/public/fonts/fontawesome-webfont.ttf delete mode 100755 templates/project/public/fonts/fontawesome-webfont.woff delete mode 100644 templates/project/public/images/.empty_directory delete mode 100644 templates/project/public/images/favicon.ico delete mode 100644 templates/project/public/javascripts/.empty_directory delete mode 100644 templates/project/public/javascripts/jquery.knob.js delete mode 100644 templates/project/public/javascripts/jquery.masonry.min.js delete mode 100644 templates/project/public/stylesheets/application.scss delete mode 100644 templates/project/public/stylesheets/font-awesome.css delete mode 100644 vendor/javascripts/application.coffee delete mode 100644 vendor/javascripts/batman.jquery.js delete mode 100644 vendor/javascripts/batman.js delete mode 100644 vendor/javascripts/es5-shim.js delete mode 100644 vendor/javascripts/jquery.js delete mode 100644 vendor/javascripts/widget.coffee diff --git a/bin/dashing b/bin/dashing index 32c89c8..a9e6022 100755 --- a/bin/dashing +++ b/bin/dashing @@ -50,7 +50,7 @@ module Dashing directory :project, @name end - desc "generate GENERATOR NAME", "Creates a new widget with all the fixins'" + desc "generate GENERATOR NAME", "Creates a new wigdget, dashboard, or job." def generate(type, name) send("generate_#{type}".to_sym, name) rescue NoMethodError => e diff --git a/dashing.gemspec b/dashing.gemspec index a1a8cbc..5bacdfa 100644 --- a/dashing.gemspec +++ b/dashing.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.files = ["lib/Dashing.rb"] s.homepage = 'http://Dashing.shopify.com' - s.files = Dir['README.md', 'vendor/**/*', 'templates/**/*','templates/**/.[a-z]*', 'lib/**/*'] + s.files = Dir['README.md', 'javascripts/**/*', 'templates/**/*','templates/**/.[a-z]*', 'lib/**/*'] s.add_dependency('sass') s.add_dependency('coffee-script') @@ -21,5 +21,6 @@ Gem::Specification.new do |s| s.add_dependency('thin') s.add_dependency('rufus-scheduler') s.add_dependency('thor') + s.add_dependency('sprockets') end \ No newline at end of file diff --git a/javascripts/batman.jquery.js b/javascripts/batman.jquery.js new file mode 100644 index 0000000..6407098 --- /dev/null +++ b/javascripts/batman.jquery.js @@ -0,0 +1,109 @@ +(function() { + + Batman.Request.prototype._parseResponseHeaders = function(xhr) { + var headers; + return headers = xhr.getAllResponseHeaders().split('\n').reduce(function(acc, header) { + var key, matches, value; + if (matches = header.match(/([^:]*):\s*(.*)/)) { + key = matches[1]; + value = matches[2]; + acc[key] = value; + } + return acc; + }, {}); + }; + + Batman.Request.prototype._prepareOptions = function(data) { + var options, _ref, + _this = this; + options = { + url: this.get('url'), + type: this.get('method'), + dataType: this.get('type'), + data: data || this.get('data'), + username: this.get('username'), + password: this.get('password'), + headers: this.get('headers'), + beforeSend: function() { + return _this.fire('loading'); + }, + success: function(response, textStatus, xhr) { + _this.mixin({ + xhr: xhr, + status: xhr.status, + response: response, + responseHeaders: _this._parseResponseHeaders(xhr) + }); + return _this.fire('success', response); + }, + error: function(xhr, status, error) { + _this.mixin({ + xhr: xhr, + status: xhr.status, + response: xhr.responseText, + responseHeaders: _this._parseResponseHeaders(xhr) + }); + xhr.request = _this; + return _this.fire('error', xhr); + }, + complete: function() { + return _this.fire('loaded'); + } + }; + if ((_ref = this.get('method')) === 'PUT' || _ref === 'POST') { + if (!this.hasFileUploads()) { + options.contentType = this.get('contentType'); + if (typeof options.data === 'object') { + options.processData = false; + options.data = Batman.URI.queryFromParams(options.data); + } + } else { + options.contentType = false; + options.processData = false; + options.data = this.constructor.objectToFormData(options.data); + } + } + return options; + }; + + Batman.Request.prototype.send = function(data) { + return jQuery.ajax(this._prepareOptions(data)); + }; + + Batman.mixins.animation = { + show: function(addToParent) { + var jq, show, _ref, _ref1; + jq = $(this); + show = function() { + return jq.show(600); + }; + if (addToParent) { + if ((_ref = addToParent.append) != null) { + _ref.appendChild(this); + } + if ((_ref1 = addToParent.before) != null) { + _ref1.parentNode.insertBefore(this, addToParent.before); + } + jq.hide(); + setTimeout(show, 0); + } else { + show(); + } + return this; + }, + hide: function(removeFromParent) { + var _this = this; + $(this).hide(600, function() { + var _ref; + if (removeFromParent) { + if ((_ref = _this.parentNode) != null) { + _ref.removeChild(_this); + } + } + return Batman.DOM.didRemoveNode(_this); + }); + return this; + } + }; + +}).call(this); \ No newline at end of file diff --git a/javascripts/batman.js b/javascripts/batman.js new file mode 100644 index 0000000..22c7b3a --- /dev/null +++ b/javascripts/batman.js @@ -0,0 +1,11811 @@ +(function() { + var Batman, + __slice = [].slice; + + Batman = function() { + var mixins; + mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.Object, mixins, function(){}); + }; + + Batman.version = '0.10.0'; + + Batman.config = { + pathPrefix: '/', + usePushState: false, + minificationErrors: true + }; + + (Batman.container = (function() { + return this; + })()).Batman = Batman; + + if (typeof define === 'function') { + define('batman', [], function() { + return Batman; + }); + } + + Batman.exportHelpers = function(onto) { + var k, _i, _len, _ref; + _ref = ['mixin', 'extend', 'unmixin', 'redirect', 'typeOf', 'redirect', 'setImmediate', 'clearImmediate']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + onto["$" + k] = Batman[k]; + } + return onto; + }; + + Batman.exportGlobals = function() { + return Batman.exportHelpers(Batman.container); + }; + +}).call(this); + +(function() { + var __slice = [].slice, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Batman.Inflector = (function() { + + Inflector.prototype.plural = function(regex, replacement) { + return this._plural.unshift([regex, replacement]); + }; + + Inflector.prototype.singular = function(regex, replacement) { + return this._singular.unshift([regex, replacement]); + }; + + Inflector.prototype.human = function(regex, replacement) { + return this._human.unshift([regex, replacement]); + }; + + Inflector.prototype.uncountable = function() { + var strings; + strings = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return this._uncountable = this._uncountable.concat(strings.map(function(x) { + return new RegExp("" + x + "$", 'i'); + })); + }; + + Inflector.prototype.irregular = function(singular, plural) { + if (singular.charAt(0) === plural.charAt(0)) { + this.plural(new RegExp("(" + (singular.charAt(0)) + ")" + (singular.slice(1)) + "$", "i"), "$1" + plural.slice(1)); + this.plural(new RegExp("(" + (singular.charAt(0)) + ")" + (plural.slice(1)) + "$", "i"), "$1" + plural.slice(1)); + return this.singular(new RegExp("(" + (plural.charAt(0)) + ")" + (plural.slice(1)) + "$", "i"), "$1" + singular.slice(1)); + } else { + this.plural(new RegExp("" + singular + "$", 'i'), plural); + this.plural(new RegExp("" + plural + "$", 'i'), plural); + return this.singular(new RegExp("" + plural + "$", 'i'), singular); + } + }; + + function Inflector() { + this._plural = []; + this._singular = []; + this._uncountable = []; + this._human = []; + } + + Inflector.prototype.ordinalize = function(number) { + var absNumber, _ref; + absNumber = Math.abs(parseInt(number)); + if (_ref = absNumber % 100, __indexOf.call([11, 12, 13], _ref) >= 0) { + return number + "th"; + } else { + switch (absNumber % 10) { + case 1: + return number + "st"; + case 2: + return number + "nd"; + case 3: + return number + "rd"; + default: + return number + "th"; + } + } + }; + + Inflector.prototype.pluralize = function(word) { + var regex, replace_string, uncountableRegex, _i, _j, _len, _len1, _ref, _ref1, _ref2; + _ref = this._uncountable; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + uncountableRegex = _ref[_i]; + if (uncountableRegex.test(word)) { + return word; + } + } + _ref1 = this._plural; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + _ref2 = _ref1[_j], regex = _ref2[0], replace_string = _ref2[1]; + if (regex.test(word)) { + return word.replace(regex, replace_string); + } + } + return word; + }; + + Inflector.prototype.singularize = function(word) { + var regex, replace_string, uncountableRegex, _i, _j, _len, _len1, _ref, _ref1, _ref2; + _ref = this._uncountable; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + uncountableRegex = _ref[_i]; + if (uncountableRegex.test(word)) { + return word; + } + } + _ref1 = this._singular; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + _ref2 = _ref1[_j], regex = _ref2[0], replace_string = _ref2[1]; + if (regex.test(word)) { + return word.replace(regex, replace_string); + } + } + return word; + }; + + Inflector.prototype.humanize = function(word) { + var regex, replace_string, _i, _len, _ref, _ref1; + _ref = this._human; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + _ref1 = _ref[_i], regex = _ref1[0], replace_string = _ref1[1]; + if (regex.test(word)) { + return word.replace(regex, replace_string); + } + } + return word; + }; + + return Inflector; + + })(); + +}).call(this); + +(function() { + var Inflector, camelize_rx, capitalize_rx, humanize_rx1, humanize_rx2, humanize_rx3, underscore_rx1, underscore_rx2; + + camelize_rx = /(?:^|_|\-)(.)/g; + + capitalize_rx = /(^|\s)([a-z])/g; + + underscore_rx1 = /([A-Z]+)([A-Z][a-z])/g; + + underscore_rx2 = /([a-z\d])([A-Z])/g; + + humanize_rx1 = /_id$/; + + humanize_rx2 = /_|-/g; + + humanize_rx3 = /^\w/g; + + Batman.helpers = { + ordinalize: function() { + return Batman.helpers.inflector.ordinalize.apply(Batman.helpers.inflector, arguments); + }, + singularize: function() { + return Batman.helpers.inflector.singularize.apply(Batman.helpers.inflector, arguments); + }, + pluralize: function(count, singular, plural, includeCount) { + var result; + if (includeCount == null) { + includeCount = true; + } + if (arguments.length < 2) { + return Batman.helpers.inflector.pluralize(count); + } else { + result = +count === 1 ? singular : plural || Batman.helpers.inflector.pluralize(singular); + if (includeCount) { + result = ("" + (count || 0) + " ") + result; + } + return result; + } + }, + camelize: function(string, firstLetterLower) { + string = string.replace(camelize_rx, function(str, p1) { + return p1.toUpperCase(); + }); + if (firstLetterLower) { + return string.substr(0, 1).toLowerCase() + string.substr(1); + } else { + return string; + } + }, + underscore: function(string) { + return string.replace(underscore_rx1, '$1_$2').replace(underscore_rx2, '$1_$2').replace('-', '_').toLowerCase(); + }, + capitalize: function(string) { + return string.replace(capitalize_rx, function(m, p1, p2) { + return p1 + p2.toUpperCase(); + }); + }, + trim: function(string) { + if (string) { + return string.trim(); + } else { + return ""; + } + }, + interpolate: function(stringOrObject, keys) { + var key, string, value; + if (typeof stringOrObject === 'object') { + string = stringOrObject[keys.count]; + if (!string) { + string = stringOrObject['other']; + } + } else { + string = stringOrObject; + } + for (key in keys) { + value = keys[key]; + string = string.replace(new RegExp("%\\{" + key + "\\}", "g"), value); + } + return string; + }, + humanize: function(string) { + string = Batman.helpers.underscore(string); + string = Batman.helpers.inflector.humanize(string); + return string.replace(humanize_rx1, '').replace(humanize_rx2, ' ').replace(humanize_rx3, function(match) { + return match.toUpperCase(); + }); + } + }; + + Inflector = new Batman.Inflector; + + Batman.helpers.inflector = Inflector; + + Inflector.plural(/$/, 's'); + + Inflector.plural(/s$/i, 's'); + + Inflector.plural(/(ax|test)is$/i, '$1es'); + + Inflector.plural(/(octop|vir)us$/i, '$1i'); + + Inflector.plural(/(octop|vir)i$/i, '$1i'); + + Inflector.plural(/(alias|status)$/i, '$1es'); + + Inflector.plural(/(bu)s$/i, '$1ses'); + + Inflector.plural(/(buffal|tomat)o$/i, '$1oes'); + + Inflector.plural(/([ti])um$/i, '$1a'); + + Inflector.plural(/([ti])a$/i, '$1a'); + + Inflector.plural(/sis$/i, 'ses'); + + Inflector.plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves'); + + Inflector.plural(/(hive)$/i, '$1s'); + + Inflector.plural(/([^aeiouy]|qu)y$/i, '$1ies'); + + Inflector.plural(/(x|ch|ss|sh)$/i, '$1es'); + + Inflector.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'); + + Inflector.plural(/([m|l])ouse$/i, '$1ice'); + + Inflector.plural(/([m|l])ice$/i, '$1ice'); + + Inflector.plural(/^(ox)$/i, '$1en'); + + Inflector.plural(/^(oxen)$/i, '$1'); + + Inflector.plural(/(quiz)$/i, '$1zes'); + + Inflector.singular(/s$/i, ''); + + Inflector.singular(/(n)ews$/i, '$1ews'); + + Inflector.singular(/([ti])a$/i, '$1um'); + + Inflector.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '$1$2sis'); + + Inflector.singular(/(^analy)ses$/i, '$1sis'); + + Inflector.singular(/([^f])ves$/i, '$1fe'); + + Inflector.singular(/(hive)s$/i, '$1'); + + Inflector.singular(/(tive)s$/i, '$1'); + + Inflector.singular(/([lr])ves$/i, '$1f'); + + Inflector.singular(/([^aeiouy]|qu)ies$/i, '$1y'); + + Inflector.singular(/(s)eries$/i, '$1eries'); + + Inflector.singular(/(m)ovies$/i, '$1ovie'); + + Inflector.singular(/(x|ch|ss|sh)es$/i, '$1'); + + Inflector.singular(/([m|l])ice$/i, '$1ouse'); + + Inflector.singular(/(bus)es$/i, '$1'); + + Inflector.singular(/(o)es$/i, '$1'); + + Inflector.singular(/(shoe)s$/i, '$1'); + + Inflector.singular(/(cris|ax|test)es$/i, '$1is'); + + Inflector.singular(/(octop|vir)i$/i, '$1us'); + + Inflector.singular(/(alias|status)es$/i, '$1'); + + Inflector.singular(/^(ox)en/i, '$1'); + + Inflector.singular(/(vert|ind)ices$/i, '$1ex'); + + Inflector.singular(/(matr)ices$/i, '$1ix'); + + Inflector.singular(/(quiz)zes$/i, '$1'); + + Inflector.singular(/(database)s$/i, '$1'); + + Inflector.irregular('person', 'people'); + + Inflector.irregular('man', 'men'); + + Inflector.irregular('child', 'children'); + + Inflector.irregular('sex', 'sexes'); + + Inflector.irregular('move', 'moves'); + + Inflector.irregular('cow', 'kine'); + + Inflector.irregular('zombie', 'zombies'); + + Inflector.uncountable('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans'); + +}).call(this); + +(function() { + var _implementImmediates, _objectToString, + __slice = [].slice, + __hasProp = {}.hasOwnProperty, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Batman.typeOf = function(object) { + if (typeof object === 'undefined') { + return "Undefined"; + } + return _objectToString.call(object).slice(8, -1); + }; + + _objectToString = Object.prototype.toString; + + Batman.extend = function() { + var key, object, objects, to, value, _i, _len; + to = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + for (_i = 0, _len = objects.length; _i < _len; _i++) { + object = objects[_i]; + for (key in object) { + value = object[key]; + to[key] = value; + } + } + return to; + }; + + Batman.mixin = function() { + var hasSet, key, mixin, mixins, to, value, _i, _len; + to = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + hasSet = typeof to.set === 'function'; + for (_i = 0, _len = mixins.length; _i < _len; _i++) { + mixin = mixins[_i]; + if (Batman.typeOf(mixin) !== 'Object') { + continue; + } + for (key in mixin) { + if (!__hasProp.call(mixin, key)) continue; + value = mixin[key]; + if (key === 'initialize' || key === 'uninitialize' || key === 'prototype') { + continue; + } + if (hasSet) { + to.set(key, value); + } else if (to.nodeName != null) { + Batman.data(to, key, value); + } else { + to[key] = value; + } + } + if (typeof mixin.initialize === 'function') { + mixin.initialize.call(to); + } + } + return to; + }; + + Batman.unmixin = function() { + var from, key, mixin, mixins, _i, _len; + from = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + for (_i = 0, _len = mixins.length; _i < _len; _i++) { + mixin = mixins[_i]; + for (key in mixin) { + if (key === 'initialize' || key === 'uninitialize') { + continue; + } + delete from[key]; + } + if (typeof mixin.uninitialize === 'function') { + mixin.uninitialize.call(from); + } + } + return from; + }; + + Batman._functionName = Batman.functionName = function(f) { + var _ref; + if (f.__name__) { + return f.__name__; + } + if (f.name) { + return f.name; + } + return (_ref = f.toString().match(/\W*function\s+([\w\$]+)\(/)) != null ? _ref[1] : void 0; + }; + + Batman._isChildOf = Batman.isChildOf = function(parentNode, childNode) { + var node; + node = childNode.parentNode; + while (node) { + if (node === parentNode) { + return true; + } + node = node.parentNode; + } + return false; + }; + + Batman.setImmediate = Batman.clearImmediate = null; + + _implementImmediates = function(container) { + var canUsePostMessage, count, functions, getHandle, handler, prefix, tasks; + canUsePostMessage = function() { + var async, oldMessage; + if (!container.postMessage) { + return false; + } + async = true; + oldMessage = container.onmessage; + container.onmessage = function() { + return async = false; + }; + container.postMessage("", "*"); + container.onmessage = oldMessage; + return async; + }; + tasks = new Batman.SimpleHash; + count = 0; + getHandle = function() { + return "go" + (++count); + }; + if (container.setImmediate) { + Batman.setImmediate = container.setImmediate; + Batman.clearImmediate = container.clearImmediate; + } else if (container.msSetImmediate) { + Batman.setImmediate = msSetImmediate; + Batman.clearImmediate = msClearImmediate; + } else if (canUsePostMessage()) { + prefix = 'com.batman.'; + functions = new Batman.SimpleHash; + handler = function(e) { + var handle, _base; + if (!~e.data.search(prefix)) { + return; + } + handle = e.data.substring(prefix.length); + return typeof (_base = tasks.unset(handle)) === "function" ? _base() : void 0; + }; + if (container.addEventListener) { + container.addEventListener('message', handler, false); + } else { + container.attachEvent('onmessage', handler); + } + Batman.setImmediate = function(f) { + var handle; + tasks.set(handle = getHandle(), f); + container.postMessage(prefix + handle, "*"); + return handle; + }; + Batman.clearImmediate = function(handle) { + return tasks.unset(handle); + }; + } else if (typeof document !== 'undefined' && __indexOf.call(document.createElement("script"), "onreadystatechange") >= 0) { + Batman.setImmediate = function(f) { + var handle, script; + handle = getHandle(); + script = document.createElement("script"); + script.onreadystatechange = function() { + var _base; + if (typeof (_base = tasks.get(handle)) === "function") { + _base(); + } + script.onreadystatechange = null; + script.parentNode.removeChild(script); + return script = null; + }; + document.documentElement.appendChild(script); + return handle; + }; + Batman.clearImmediate = function(handle) { + return tasks.unset(handle); + }; + } else if (typeof process !== "undefined" && process !== null ? process.nextTick : void 0) { + functions = {}; + Batman.setImmediate = function(f) { + var handle; + handle = getHandle(); + functions[handle] = f; + process.nextTick(function() { + if (typeof functions[handle] === "function") { + functions[handle](); + } + return delete functions[handle]; + }); + return handle; + }; + Batman.clearImmediate = function(handle) { + return delete functions[handle]; + }; + } else { + Batman.setImmediate = function(f) { + return setTimeout(f, 0); + }; + Batman.clearImmediate = function(handle) { + return clearTimeout(handle); + }; + } + Batman.setImmediate = Batman.setImmediate; + return Batman.clearImmediate = Batman.clearImmediate; + }; + + Batman.setImmediate = function() { + _implementImmediates(Batman.container); + return Batman.setImmediate.apply(this, arguments); + }; + + Batman.clearImmediate = function() { + _implementImmediates(Batman.container); + return Batman.clearImmediate.apply(this, arguments); + }; + + Batman.forEach = function(container, iterator, ctx) { + var e, i, k, v, _i, _len, _results, _results1; + if (container.forEach) { + return container.forEach(iterator, ctx); + } else if (container.indexOf) { + _results = []; + for (i = _i = 0, _len = container.length; _i < _len; i = ++_i) { + e = container[i]; + _results.push(iterator.call(ctx, e, i, container)); + } + return _results; + } else { + _results1 = []; + for (k in container) { + v = container[k]; + _results1.push(iterator.call(ctx, k, v, container)); + } + return _results1; + } + }; + + Batman.objectHasKey = function(object, key) { + if (typeof object.hasKey === 'function') { + return object.hasKey(key); + } else { + return key in object; + } + }; + + Batman.contains = function(container, item) { + if (container.indexOf) { + return __indexOf.call(container, item) >= 0; + } else if (typeof container.has === 'function') { + return container.has(item); + } else { + return Batman.objectHasKey(container, item); + } + }; + + Batman.get = function(base, key) { + if (typeof base.get === 'function') { + return base.get(key); + } else { + return Batman.Property.forBaseAndKey(base, key).getValue(); + } + }; + + Batman.getPath = function(base, segments) { + var segment, _i, _len; + for (_i = 0, _len = segments.length; _i < _len; _i++) { + segment = segments[_i]; + if (base != null) { + base = Batman.get(base, segment); + if (base == null) { + return base; + } + } else { + return void 0; + } + } + return base; + }; + + Batman.escapeHTML = (function() { + var replacements; + replacements = { + "&": "&", + "<": "<", + ">": ">", + "\"": """, + "'": "'" + }; + return function(s) { + return ("" + s).replace(/[&<>'"]/g, function(c) { + return replacements[c]; + }); + }; + })(); + + Batman.translate = function(x, values) { + if (values == null) { + values = {}; + } + return Batman.helpers.interpolate(Batman.get(Batman.translate.messages, x), values); + }; + + Batman.translate.messages = {}; + + Batman.t = function() { + return Batman.translate.apply(Batman, arguments); + }; + + Batman.redirect = function(url) { + var _ref; + return (_ref = Batman.navigator) != null ? _ref.redirect(url) : void 0; + }; + + Batman.initializeObject = function(object) { + if (object._batman != null) { + return object._batman.check(object); + } else { + return object._batman = new Batman._Batman(object); + } + }; + +}).call(this); + +(function() { + var developer; + + Batman.developer = { + suppressed: false, + DevelopmentError: (function() { + var DevelopmentError; + DevelopmentError = function(message) { + this.message = message; + return this.name = "DevelopmentError"; + }; + DevelopmentError.prototype = Error.prototype; + return DevelopmentError; + })(), + _ie_console: function(f, args) { + var arg, _i, _len, _results; + if (args.length !== 1) { + if (typeof console !== "undefined" && console !== null) { + console[f]("..." + f + " of " + args.length + " items..."); + } + } + _results = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + _results.push(typeof console !== "undefined" && console !== null ? console[f](arg) : void 0); + } + return _results; + }, + suppress: function(f) { + developer.suppressed = true; + if (f) { + f(); + return developer.suppressed = false; + } + }, + unsuppress: function() { + return developer.suppressed = false; + }, + log: function() { + if (developer.suppressed || !((typeof console !== "undefined" && console !== null ? console.log : void 0) != null)) { + return; + } + if (console.log.apply) { + return console.log.apply(console, arguments); + } else { + return developer._ie_console("log", arguments); + } + }, + warn: function() { + if (developer.suppressed || !((typeof console !== "undefined" && console !== null ? console.warn : void 0) != null)) { + return; + } + if (console.warn.apply) { + return console.warn.apply(console, arguments); + } else { + return developer._ie_console("warn", arguments); + } + }, + error: function(message) { + throw new developer.DevelopmentError(message); + }, + assert: function(result, message) { + if (!result) { + return developer.error(message); + } + }, + "do": function(f) { + if (!developer.suppressed) { + return f(); + } + }, + addFilters: function() { + return Batman.extend(Batman.Filters, { + log: function(value, key) { + if (typeof console !== "undefined" && console !== null) { + if (typeof console.log === "function") { + console.log(arguments); + } + } + return value; + }, + logStack: function(value) { + if (typeof console !== "undefined" && console !== null) { + if (typeof console.log === "function") { + console.log(developer.currentFilterStack); + } + } + return value; + } + }); + } + }; + + developer = Batman.developer; + + Batman.developer.assert((function() {}).bind, "Error! Batman needs Function.bind to work! Please shim it using something like es5-shim or augmentjs!"); + +}).call(this); + +(function() { + var _Batman; + + Batman._Batman = _Batman = (function() { + + function _Batman(object) { + this.object = object; + } + + _Batman.prototype.check = function(object) { + if (object !== this.object) { + object._batman = new Batman._Batman(object); + return false; + } + return true; + }; + + _Batman.prototype.get = function(key) { + var reduction, results; + results = this.getAll(key); + switch (results.length) { + case 0: + return void 0; + case 1: + return results[0]; + default: + reduction = results[0].concat != null ? function(a, b) { + return a.concat(b); + } : results[0].merge != null ? function(a, b) { + return a.merge(b); + } : results.every(function(x) { + return typeof x === 'object'; + }) ? (results.unshift({}), function(a, b) { + return Batman.extend(a, b); + }) : void 0; + if (reduction) { + return results.reduceRight(reduction); + } else { + return results; + } + } + }; + + _Batman.prototype.getFirst = function(key) { + var results; + results = this.getAll(key); + return results[0]; + }; + + _Batman.prototype.getAll = function(keyOrGetter) { + var getter, results, val; + if (typeof keyOrGetter === 'function') { + getter = keyOrGetter; + } else { + getter = function(ancestor) { + var _ref; + return (_ref = ancestor._batman) != null ? _ref[keyOrGetter] : void 0; + }; + } + results = this.ancestors(getter); + if (val = getter(this.object)) { + results.unshift(val); + } + return results; + }; + + _Batman.prototype.ancestors = function(getter) { + var isClass, parent, proto, results, val, _ref, _ref1; + if (getter == null) { + getter = function(x) { + return x; + }; + } + results = []; + isClass = !!this.object.prototype; + parent = isClass ? (_ref = this.object.__super__) != null ? _ref.constructor : void 0 : (proto = Object.getPrototypeOf(this.object)) === this.object ? this.object.constructor.__super__ : proto; + if (parent != null) { + if ((_ref1 = parent._batman) != null) { + _ref1.check(parent); + } + val = getter(parent); + if (val != null) { + results.push(val); + } + if (parent._batman != null) { + results = results.concat(parent._batman.ancestors(getter)); + } + } + return results; + }; + + _Batman.prototype.set = function(key, value) { + return this[key] = value; + }; + + return _Batman; + + })(); + +}).call(this); + +(function() { + + Batman.Event = (function() { + + Event.forBaseAndKey = function(base, key) { + if (base.isEventEmitter) { + return base.event(key); + } else { + return new Batman.Event(base, key); + } + }; + + function Event(base, key) { + this.base = base; + this.key = key; + this.handlers = []; + this._preventCount = 0; + } + + Event.prototype.isEvent = true; + + Event.prototype.isEqual = function(other) { + return this.constructor === other.constructor && this.base === other.base && this.key === other.key; + }; + + Event.prototype.hashKey = function() { + var key; + this.hashKey = function() { + return key; + }; + return key = ""; + }; + + Event.prototype.addHandler = function(handler) { + if (this.handlers.indexOf(handler) === -1) { + this.handlers.push(handler); + } + if (this.oneShot) { + this.autofireHandler(handler); + } + return this; + }; + + Event.prototype.removeHandler = function(handler) { + var index; + if ((index = this.handlers.indexOf(handler)) !== -1) { + this.handlers.splice(index, 1); + } + return this; + }; + + Event.prototype.eachHandler = function(iterator) { + var key, _ref, _ref1; + this.handlers.slice().forEach(iterator); + if ((_ref = this.base) != null ? _ref.isEventEmitter : void 0) { + key = this.key; + return (_ref1 = this.base._batman) != null ? _ref1.ancestors(function(ancestor) { + var handlers, _ref2, _ref3; + if (ancestor.isEventEmitter && ((_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.events) != null ? _ref3.hasOwnProperty(key) : void 0 : void 0)) { + handlers = ancestor.event(key).handlers; + return handlers.slice().forEach(iterator); + } + }) : void 0; + } + }; + + Event.prototype.clearHandlers = function() { + return this.handlers = []; + }; + + Event.prototype.handlerContext = function() { + return this.base; + }; + + Event.prototype.prevent = function() { + return ++this._preventCount; + }; + + Event.prototype.allow = function() { + if (this._preventCount) { + --this._preventCount; + } + return this._preventCount; + }; + + Event.prototype.isPrevented = function() { + return this._preventCount > 0; + }; + + Event.prototype.autofireHandler = function(handler) { + if (this._oneShotFired && (this._oneShotArgs != null)) { + return handler.apply(this.handlerContext(), this._oneShotArgs); + } + }; + + Event.prototype.resetOneShot = function() { + this._oneShotFired = false; + return this._oneShotArgs = null; + }; + + Event.prototype.fire = function() { + var args, context; + if (this.isPrevented() || this._oneShotFired) { + return false; + } + context = this.handlerContext(); + args = arguments; + if (this.oneShot) { + this._oneShotFired = true; + this._oneShotArgs = arguments; + } + return this.eachHandler(function(handler) { + return handler.apply(context, args); + }); + }; + + Event.prototype.allowAndFire = function() { + this.allow(); + return this.fire.apply(this, arguments); + }; + + return Event; + + })(); + +}).call(this); + +(function() { + var __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; }; + + Batman.PropertyEvent = (function(_super) { + + __extends(PropertyEvent, _super); + + function PropertyEvent() { + return PropertyEvent.__super__.constructor.apply(this, arguments); + } + + PropertyEvent.prototype.eachHandler = function(iterator) { + return this.base.eachObserver(iterator); + }; + + PropertyEvent.prototype.handlerContext = function() { + return this.base.base; + }; + + return PropertyEvent; + + })(Batman.Event); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.EventEmitter = { + isEventEmitter: true, + hasEvent: function(key) { + var _ref, _ref1; + return (_ref = this._batman) != null ? typeof _ref.get === "function" ? (_ref1 = _ref.get('events')) != null ? _ref1.hasOwnProperty(key) : void 0 : void 0 : void 0; + }, + event: function(key) { + var eventClass, events, existingEvent, newEvent, _base; + Batman.initializeObject(this); + eventClass = this.eventClass || Batman.Event; + events = (_base = this._batman).events || (_base.events = {}); + if (events.hasOwnProperty(key)) { + return existingEvent = events[key]; + } else { + this._batman.ancestors(function(ancestor) { + var _ref, _ref1; + return existingEvent || (existingEvent = (_ref = ancestor._batman) != null ? (_ref1 = _ref.events) != null ? _ref1[key] : void 0 : void 0); + }); + newEvent = events[key] = new eventClass(this, key); + newEvent.oneShot = existingEvent != null ? existingEvent.oneShot : void 0; + return newEvent; + } + }, + on: function(key, handler) { + return this.event(key).addHandler(handler); + }, + once: function(key, originalHandler) { + var event, handler; + event = this.event(key); + handler = function() { + originalHandler.apply(this, arguments); + return event.removeHandler(handler); + }; + return event.addHandler(handler); + }, + registerAsMutableSource: function() { + return Batman.Property.registerSource(this); + }, + mutation: function(wrappedFunction) { + return function() { + var result; + result = wrappedFunction.apply(this, arguments); + this.event('change').fire(this, this); + return result; + }; + }, + prevent: function(key) { + this.event(key).prevent(); + return this; + }, + allow: function(key) { + this.event(key).allow(); + return this; + }, + isPrevented: function(key) { + return this.event(key).isPrevented(); + }, + fire: function() { + var args, key, _ref; + key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + return (_ref = this.event(key)).fire.apply(_ref, args); + }, + allowAndFire: function() { + var args, key, _ref; + key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + return (_ref = this.event(key)).allowAndFire.apply(_ref, args); + } + }; + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.Enumerable = { + isEnumerable: true, + map: function(f, ctx) { + var r; + if (ctx == null) { + ctx = Batman.container; + } + r = []; + this.forEach(function() { + return r.push(f.apply(ctx, arguments)); + }); + return r; + }, + mapToProperty: function(key) { + var r; + r = []; + this.forEach(function(item) { + return r.push(item.get(key)); + }); + return r; + }, + every: function(f, ctx) { + var r; + if (ctx == null) { + ctx = Batman.container; + } + r = true; + this.forEach(function() { + return r = r && f.apply(ctx, arguments); + }); + return r; + }, + some: function(f, ctx) { + var r; + if (ctx == null) { + ctx = Batman.container; + } + r = false; + this.forEach(function() { + return r = r || f.apply(ctx, arguments); + }); + return r; + }, + reduce: function(f, r) { + var count, self; + count = 0; + self = this; + this.forEach(function() { + if (r != null) { + return r = f.apply(null, [r].concat(__slice.call(arguments), [count], [self])); + } else { + return r = arguments[0]; + } + }); + return r; + }, + filter: function(f) { + var r, wrap; + r = new this.constructor; + if (r.add) { + wrap = function(r, e) { + if (f(e)) { + r.add(e); + } + return r; + }; + } else if (r.set) { + wrap = function(r, k, v) { + if (f(k, v)) { + r.set(k, v); + } + return r; + }; + } else { + if (!r.push) { + r = []; + } + wrap = function(r, e) { + if (f(e)) { + r.push(e); + } + return r; + }; + } + return this.reduce(wrap, r); + }, + inGroupsOf: function(n) { + var current, i, r; + r = []; + current = false; + i = 0; + this.forEach(function(x) { + if (i++ % n === 0) { + current = []; + r.push(current); + } + return current.push(x); + }); + return r; + } + }; + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.SimpleHash = (function() { + + function SimpleHash(obj) { + this._storage = {}; + this.length = 0; + if (obj != null) { + this.update(obj); + } + } + + Batman.extend(SimpleHash.prototype, Batman.Enumerable); + + SimpleHash.prototype.propertyClass = Batman.Property; + + SimpleHash.prototype.hasKey = function(key) { + var pair, pairs, _i, _len; + if (this.objectKey(key)) { + if (!this._objectStorage) { + return false; + } + if (pairs = this._objectStorage[this.hashKeyFor(key)]) { + for (_i = 0, _len = pairs.length; _i < _len; _i++) { + pair = pairs[_i]; + if (this.equality(pair[0], key)) { + return true; + } + } + } + return false; + } else { + key = this.prefixedKey(key); + return this._storage.hasOwnProperty(key); + } + }; + + SimpleHash.prototype.get = function(key) { + var pair, pairs, _i, _len; + if (this.objectKey(key)) { + if (!this._objectStorage) { + return void 0; + } + if (pairs = this._objectStorage[this.hashKeyFor(key)]) { + for (_i = 0, _len = pairs.length; _i < _len; _i++) { + pair = pairs[_i]; + if (this.equality(pair[0], key)) { + return pair[1]; + } + } + } + } else { + return this._storage[this.prefixedKey(key)]; + } + }; + + SimpleHash.prototype.set = function(key, val) { + var pair, pairs, _base, _i, _len, _name; + if (this.objectKey(key)) { + this._objectStorage || (this._objectStorage = {}); + pairs = (_base = this._objectStorage)[_name = this.hashKeyFor(key)] || (_base[_name] = []); + for (_i = 0, _len = pairs.length; _i < _len; _i++) { + pair = pairs[_i]; + if (this.equality(pair[0], key)) { + return pair[1] = val; + } + } + this.length++; + pairs.push([key, val]); + return val; + } else { + key = this.prefixedKey(key); + if (this._storage[key] == null) { + this.length++; + } + return this._storage[key] = val; + } + }; + + SimpleHash.prototype.unset = function(key) { + var hashKey, index, obj, pair, pairs, val, value, _i, _len, _ref; + if (this.objectKey(key)) { + if (!this._objectStorage) { + return void 0; + } + hashKey = this.hashKeyFor(key); + if (pairs = this._objectStorage[hashKey]) { + for (index = _i = 0, _len = pairs.length; _i < _len; index = ++_i) { + _ref = pairs[index], obj = _ref[0], value = _ref[1]; + if (this.equality(obj, key)) { + pair = pairs.splice(index, 1); + if (!pairs.length) { + delete this._objectStorage[hashKey]; + } + this.length--; + return pair[0][1]; + } + } + } + } else { + key = this.prefixedKey(key); + val = this._storage[key]; + if (this._storage[key] != null) { + this.length--; + delete this._storage[key]; + } + return val; + } + }; + + SimpleHash.prototype.getOrSet = function(key, valueFunction) { + var currentValue; + currentValue = this.get(key); + if (!currentValue) { + currentValue = valueFunction(); + this.set(key, currentValue); + } + return currentValue; + }; + + SimpleHash.prototype.prefixedKey = function(key) { + return "_" + key; + }; + + SimpleHash.prototype.unprefixedKey = function(key) { + return key.slice(1); + }; + + SimpleHash.prototype.hashKeyFor = function(obj) { + return (obj != null ? typeof obj.hashKey === "function" ? obj.hashKey() : void 0 : void 0) || obj; + }; + + SimpleHash.prototype.equality = function(lhs, rhs) { + if (lhs === rhs) { + return true; + } + if (lhs !== lhs && rhs !== rhs) { + return true; + } + if ((lhs != null ? typeof lhs.isEqual === "function" ? lhs.isEqual(rhs) : void 0 : void 0) && (rhs != null ? typeof rhs.isEqual === "function" ? rhs.isEqual(lhs) : void 0 : void 0)) { + return true; + } + return false; + }; + + SimpleHash.prototype.objectKey = function(key) { + return typeof key !== 'string'; + }; + + SimpleHash.prototype.forEach = function(iterator, ctx) { + var key, obj, results, value, values, _i, _len, _ref, _ref1, _ref2, _ref3; + results = []; + if (this._objectStorage) { + _ref = this._objectStorage; + for (key in _ref) { + values = _ref[key]; + _ref1 = values.slice(); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + _ref2 = _ref1[_i], obj = _ref2[0], value = _ref2[1]; + results.push(iterator.call(ctx, obj, value, this)); + } + } + } + _ref3 = this._storage; + for (key in _ref3) { + value = _ref3[key]; + results.push(iterator.call(ctx, this.unprefixedKey(key), value, this)); + } + return results; + }; + + SimpleHash.prototype.keys = function() { + var result; + result = []; + Batman.SimpleHash.prototype.forEach.call(this, function(key) { + return result.push(key); + }); + return result; + }; + + SimpleHash.prototype.toArray = SimpleHash.prototype.keys; + + SimpleHash.prototype.clear = function() { + this._storage = {}; + delete this._objectStorage; + return this.length = 0; + }; + + SimpleHash.prototype.isEmpty = function() { + return this.length === 0; + }; + + SimpleHash.prototype.merge = function() { + var hash, merged, others, _i, _len; + others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + merged = new this.constructor; + others.unshift(this); + for (_i = 0, _len = others.length; _i < _len; _i++) { + hash = others[_i]; + hash.forEach(function(obj, value) { + return merged.set(obj, value); + }); + } + return merged; + }; + + SimpleHash.prototype.update = function(object) { + var k, v, _results; + _results = []; + for (k in object) { + v = object[k]; + _results.push(this.set(k, v)); + } + return _results; + }; + + SimpleHash.prototype.replace = function(object) { + var _this = this; + this.forEach(function(key, value) { + if (!(key in object)) { + return _this.unset(key); + } + }); + return this.update(object); + }; + + SimpleHash.prototype.toObject = function() { + var key, obj, pair, value, _ref, _ref1; + obj = {}; + _ref = this._storage; + for (key in _ref) { + value = _ref[key]; + obj[this.unprefixedKey(key)] = value; + } + if (this._objectStorage) { + _ref1 = this._objectStorage; + for (key in _ref1) { + pair = _ref1[key]; + obj[key] = pair[0][1]; + } + } + return obj; + }; + + SimpleHash.prototype.toJSON = SimpleHash.prototype.toObject; + + return SimpleHash; + + })(); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.AssociationCurator = (function(_super) { + + __extends(AssociationCurator, _super); + + AssociationCurator.availableAssociations = ['belongsTo', 'hasOne', 'hasMany']; + + function AssociationCurator(model) { + this.model = model; + AssociationCurator.__super__.constructor.call(this); + this._byTypeStorage = new Batman.SimpleHash; + } + + AssociationCurator.prototype.add = function(association) { + var associationTypeSet; + this.set(association.label, association); + if (!(associationTypeSet = this._byTypeStorage.get(association.associationType))) { + associationTypeSet = new Batman.SimpleSet; + this._byTypeStorage.set(association.associationType, associationTypeSet); + } + return associationTypeSet.add(association); + }; + + AssociationCurator.prototype.getByType = function(type) { + return this._byTypeStorage.get(type); + }; + + AssociationCurator.prototype.getByLabel = function(label) { + return this.get(label); + }; + + AssociationCurator.prototype.reset = function() { + this.forEach(function(label, association) { + return association.reset(); + }); + return true; + }; + + AssociationCurator.prototype.merge = function() { + var others, result; + others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + result = AssociationCurator.__super__.merge.apply(this, arguments); + result._byTypeStorage = this._byTypeStorage.merge(others.map(function(other) { + return other._byTypeStorage; + })); + return result; + }; + + AssociationCurator.prototype._markDirtyAttribute = function(key, oldValue) { + var _ref; + if ((_ref = this.lifecycle.get('state')) !== 'loading' && _ref !== 'creating' && _ref !== 'saving' && _ref !== 'saved') { + if (this.lifecycle.startTransition('set')) { + return this.dirtyKeys.set(key, oldValue); + } else { + throw new Batman.StateMachine.InvalidTransitionError("Can't set while in state " + (this.lifecycle.get('state'))); + } + } + }; + + return AssociationCurator; + + })(Batman.SimpleHash); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.SimpleSet = (function() { + + function SimpleSet() { + this._storage = []; + this.length = 0; + if (arguments.length > 0) { + this.add.apply(this, arguments); + } + } + + Batman.extend(SimpleSet.prototype, Batman.Enumerable); + + SimpleSet.prototype.has = function(item) { + return !!(~this._indexOfItem(item)); + }; + + SimpleSet.prototype.add = function() { + var addedItems, item, items, _i, _len; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + addedItems = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!(!~this._indexOfItem(item))) { + continue; + } + this._storage.push(item); + addedItems.push(item); + } + this.length = this._storage.length; + if (this.fire && addedItems.length !== 0) { + this.fire('change', this, this); + this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedItems))); + } + return addedItems; + }; + + SimpleSet.prototype.remove = function() { + var index, item, items, removedItems, _i, _len; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + removedItems = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!(~(index = this._indexOfItem(item)))) { + continue; + } + this._storage.splice(index, 1); + removedItems.push(item); + } + this.length = this._storage.length; + if (this.fire && removedItems.length !== 0) { + this.fire('change', this, this); + this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(removedItems))); + } + return removedItems; + }; + + SimpleSet.prototype.find = function(f) { + var item, _i, _len, _ref; + _ref = this._storage; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + item = _ref[_i]; + if (f(item)) { + return item; + } + } + }; + + SimpleSet.prototype.forEach = function(iterator, ctx) { + var container; + container = this; + return this._storage.slice().forEach(function(key) { + return iterator.call(ctx, key, null, container); + }); + }; + + SimpleSet.prototype.isEmpty = function() { + return this.length === 0; + }; + + SimpleSet.prototype.clear = function() { + var items; + items = this._storage; + this._storage = []; + this.length = 0; + if (this.fire && items.length !== 0) { + this.fire('change', this, this); + this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(items))); + } + return items; + }; + + SimpleSet.prototype.replace = function(other) { + try { + if (typeof this.prevent === "function") { + this.prevent('change'); + } + this.clear(); + return this.add.apply(this, other.toArray()); + } finally { + if (typeof this.allowAndFire === "function") { + this.allowAndFire('change', this, this); + } + } + }; + + SimpleSet.prototype.toArray = function() { + return this._storage.slice(); + }; + + SimpleSet.prototype.merge = function() { + var merged, others, set, _i, _len; + others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + merged = new this.constructor; + others.unshift(this); + for (_i = 0, _len = others.length; _i < _len; _i++) { + set = others[_i]; + set.forEach(function(v) { + return merged.add(v); + }); + } + return merged; + }; + + SimpleSet.prototype.indexedBy = function(key) { + this._indexes || (this._indexes = new Batman.SimpleHash); + return this._indexes.get(key) || this._indexes.set(key, new Batman.SetIndex(this, key)); + }; + + SimpleSet.prototype.indexedByUnique = function(key) { + this._uniqueIndexes || (this._uniqueIndexes = new Batman.SimpleHash); + return this._uniqueIndexes.get(key) || this._uniqueIndexes.set(key, new Batman.UniqueSetIndex(this, key)); + }; + + SimpleSet.prototype.sortedBy = function(key, order) { + var sortsForKey; + if (order == null) { + order = "asc"; + } + order = order.toLowerCase() === "desc" ? "desc" : "asc"; + this._sorts || (this._sorts = new Batman.SimpleHash); + sortsForKey = this._sorts.get(key) || this._sorts.set(key, new Batman.Object); + return sortsForKey.get(order) || sortsForKey.set(order, new Batman.SetSort(this, key, order)); + }; + + SimpleSet.prototype.equality = Batman.SimpleHash.prototype.equality; + + SimpleSet.prototype._indexOfItem = function(givenItem) { + var index, item, _i, _len, _ref; + _ref = this._storage; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + item = _ref[index]; + if (this.equality(givenItem, item)) { + return index; + } + } + return -1; + }; + + return SimpleSet; + + })(); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.Property = (function() { + + Batman.mixin(Property.prototype, Batman.EventEmitter); + + Property._sourceTrackerStack = []; + + Property.sourceTracker = function() { + var stack; + return (stack = this._sourceTrackerStack)[stack.length - 1]; + }; + + Property.defaultAccessor = { + get: function(key) { + return this[key]; + }, + set: function(key, val) { + return this[key] = val; + }, + unset: function(key) { + var x; + x = this[key]; + delete this[key]; + return x; + }, + cache: false + }; + + Property.defaultAccessorForBase = function(base) { + var _ref; + return ((_ref = base._batman) != null ? _ref.getFirst('defaultAccessor') : void 0) || Batman.Property.defaultAccessor; + }; + + Property.accessorForBaseAndKey = function(base, key) { + var accessor, _bm, _ref, + _this = this; + if ((_bm = base._batman) != null) { + accessor = (_ref = _bm.keyAccessors) != null ? _ref.get(key) : void 0; + if (!accessor) { + _bm.ancestors(function(ancestor) { + var _ref1, _ref2; + return accessor || (accessor = (_ref1 = ancestor._batman) != null ? (_ref2 = _ref1.keyAccessors) != null ? _ref2.get(key) : void 0 : void 0); + }); + } + } + return accessor || this.defaultAccessorForBase(base); + }; + + Property.forBaseAndKey = function(base, key) { + if (base.isObservable) { + return base.property(key); + } else { + return new Batman.Keypath(base, key); + } + }; + + Property.withoutTracking = function(block) { + return this.wrapTrackingPrevention(block)(); + }; + + Property.wrapTrackingPrevention = function(block) { + return function() { + Batman.Property.pushDummySourceTracker(); + try { + return block.apply(this, arguments); + } finally { + Batman.Property.popSourceTracker(); + } + }; + }; + + Property.registerSource = function(obj) { + var _ref; + if (!obj.isEventEmitter) { + return; + } + return (_ref = this.sourceTracker()) != null ? _ref.add(obj) : void 0; + }; + + Property.pushSourceTracker = function() { + return Batman.Property._sourceTrackerStack.push(new Batman.SimpleSet); + }; + + Property.pushDummySourceTracker = function() { + return Batman.Property._sourceTrackerStack.push(null); + }; + + Property.popSourceTracker = function() { + return Batman.Property._sourceTrackerStack.pop(); + }; + + function Property(base, key) { + this.base = base; + this.key = key; + } + + Property.prototype._isolationCount = 0; + + Property.prototype.cached = false; + + Property.prototype.value = null; + + Property.prototype.sources = null; + + Property.prototype.isProperty = true; + + Property.prototype.isDead = false; + + Property.prototype.eventClass = Batman.PropertyEvent; + + Property.prototype.isEqual = function(other) { + return this.constructor === other.constructor && this.base === other.base && this.key === other.key; + }; + + Property.prototype.hashKey = function() { + var key; + this.hashKey = function() { + return key; + }; + return key = ""; + }; + + Property.prototype.event = function(key) { + var eventClass, _base; + eventClass = this.eventClass || Batman.Event; + this.events || (this.events = {}); + (_base = this.events)[key] || (_base[key] = new eventClass(this, key)); + return this.events[key]; + }; + + Property.prototype.changeEvent = function() { + var event; + event = this.event('change'); + this.changeEvent = function() { + return event; + }; + return event; + }; + + Property.prototype.accessor = function() { + var accessor; + accessor = this.constructor.accessorForBaseAndKey(this.base, this.key); + this.accessor = function() { + return accessor; + }; + return accessor; + }; + + Property.prototype.eachObserver = function(iterator) { + var key; + key = this.key; + this.changeEvent().handlers.slice().forEach(iterator); + if (this.base.isObservable) { + return this.base._batman.ancestors(function(ancestor) { + var handlers, property; + if (ancestor.isObservable && ancestor.hasProperty(key)) { + property = ancestor.property(key); + handlers = property.changeEvent().handlers; + return handlers.slice().forEach(iterator); + } + }); + } + }; + + Property.prototype.observers = function() { + var results; + results = []; + this.eachObserver(function(observer) { + return results.push(observer); + }); + return results; + }; + + Property.prototype.hasObservers = function() { + return this.observers().length > 0; + }; + + Property.prototype.updateSourcesFromTracker = function() { + var handler, newSources; + newSources = this.constructor.popSourceTracker(); + handler = this.sourceChangeHandler(); + this._eachSourceChangeEvent(function(e) { + return e.removeHandler(handler); + }); + this.sources = newSources; + return this._eachSourceChangeEvent(function(e) { + return e.addHandler(handler); + }); + }; + + Property.prototype._eachSourceChangeEvent = function(iterator) { + if (this.sources == null) { + return; + } + return this.sources.forEach(function(source) { + return iterator(source.event('change')); + }); + }; + + Property.prototype.getValue = function() { + this.registerAsMutableSource(); + if (!this.isCached()) { + this.constructor.pushSourceTracker(); + try { + this.value = this.valueFromAccessor(); + this.cached = true; + } finally { + this.updateSourcesFromTracker(); + } + } + return this.value; + }; + + Property.prototype.isCachable = function() { + var cacheable; + if (this.isFinal()) { + return true; + } + cacheable = this.accessor().cache; + if (cacheable != null) { + return !!cacheable; + } else { + return true; + } + }; + + Property.prototype.isCached = function() { + return this.isCachable() && this.cached; + }; + + Property.prototype.isFinal = function() { + return !!this.accessor()['final']; + }; + + Property.prototype.refresh = function() { + var previousValue, value; + this.cached = false; + previousValue = this.value; + value = this.getValue(); + if (value !== previousValue && !this.isIsolated()) { + this.fire(value, previousValue); + } + if (this.value !== void 0 && this.isFinal()) { + return this.lockValue(); + } + }; + + Property.prototype.sourceChangeHandler = function() { + var handler, + _this = this; + handler = this._handleSourceChange.bind(this); + Batman.developer["do"](function() { + return handler.property = _this; + }); + this.sourceChangeHandler = function() { + return handler; + }; + return handler; + }; + + Property.prototype._handleSourceChange = function() { + if (this.isIsolated()) { + return this._needsRefresh = true; + } else if (!this.isFinal() && !this.hasObservers()) { + return this.cached = false; + } else { + return this.refresh(); + } + }; + + Property.prototype.valueFromAccessor = function() { + var _ref; + return (_ref = this.accessor().get) != null ? _ref.call(this.base, this.key) : void 0; + }; + + Property.prototype.setValue = function(val) { + var set; + if (!(set = this.accessor().set)) { + return; + } + return this._changeValue(function() { + return set.call(this.base, this.key, val); + }); + }; + + Property.prototype.unsetValue = function() { + var unset; + if (!(unset = this.accessor().unset)) { + return; + } + return this._changeValue(function() { + return unset.call(this.base, this.key); + }); + }; + + Property.prototype._changeValue = function(block) { + var result; + this.cached = false; + this.constructor.pushDummySourceTracker(); + try { + result = block.apply(this); + this.refresh(); + } finally { + this.constructor.popSourceTracker(); + } + if (!(this.isCached() || this.hasObservers())) { + this.die(); + } + return result; + }; + + Property.prototype.forget = function(handler) { + if (handler != null) { + return this.changeEvent().removeHandler(handler); + } else { + return this.changeEvent().clearHandlers(); + } + }; + + Property.prototype.observeAndFire = function(handler) { + this.observe(handler); + return handler.call(this.base, this.value, this.value, this.key); + }; + + Property.prototype.observe = function(handler) { + this.changeEvent().addHandler(handler); + if (this.sources == null) { + this.getValue(); + } + return this; + }; + + Property.prototype.observeOnce = function(originalHandler) { + var event, handler; + event = this.changeEvent(); + handler = function() { + originalHandler.apply(this, arguments); + return event.removeHandler(handler); + }; + event.addHandler(handler); + if (this.sources == null) { + this.getValue(); + } + return this; + }; + + Property.prototype._removeHandlers = function() { + var handler; + handler = this.sourceChangeHandler(); + this._eachSourceChangeEvent(function(e) { + return e.removeHandler(handler); + }); + delete this.sources; + return this.changeEvent().clearHandlers(); + }; + + Property.prototype.lockValue = function() { + this._removeHandlers(); + this.getValue = function() { + return this.value; + }; + return this.setValue = this.unsetValue = this.refresh = this.observe = function() {}; + }; + + Property.prototype.die = function() { + var _ref, _ref1; + this._removeHandlers(); + if ((_ref = this.base._batman) != null) { + if ((_ref1 = _ref.properties) != null) { + _ref1.unset(this.key); + } + } + return this.isDead = true; + }; + + Property.prototype.fire = function() { + var _ref; + return (_ref = this.changeEvent()).fire.apply(_ref, __slice.call(arguments).concat([this.key])); + }; + + Property.prototype.isolate = function() { + if (this._isolationCount === 0) { + this._preIsolationValue = this.getValue(); + } + return this._isolationCount++; + }; + + Property.prototype.expose = function() { + if (this._isolationCount === 1) { + this._isolationCount--; + if (this._needsRefresh) { + this.value = this._preIsolationValue; + this.refresh(); + } else if (this.value !== this._preIsolationValue) { + this.fire(this.value, this._preIsolationValue); + } + return this._preIsolationValue = null; + } else if (this._isolationCount > 0) { + return this._isolationCount--; + } + }; + + Property.prototype.isIsolated = function() { + return this._isolationCount > 0; + }; + + return Property; + + })(); + +}).call(this); + +(function() { + var __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; }; + + Batman.Keypath = (function(_super) { + + __extends(Keypath, _super); + + function Keypath(base, key) { + if (typeof key === 'string') { + this.segments = key.split('.'); + this.depth = this.segments.length; + } else { + this.segments = [key]; + this.depth = 1; + } + Keypath.__super__.constructor.apply(this, arguments); + } + + Keypath.prototype.isCachable = function() { + if (this.depth === 1) { + return Keypath.__super__.isCachable.apply(this, arguments); + } else { + return true; + } + }; + + Keypath.prototype.terminalProperty = function() { + var base; + base = Batman.getPath(this.base, this.segments.slice(0, -1)); + if (base == null) { + return; + } + return Batman.Keypath.forBaseAndKey(base, this.segments[this.depth - 1]); + }; + + Keypath.prototype.valueFromAccessor = function() { + if (this.depth === 1) { + return Keypath.__super__.valueFromAccessor.apply(this, arguments); + } else { + return Batman.getPath(this.base, this.segments); + } + }; + + Keypath.prototype.setValue = function(val) { + var _ref; + if (this.depth === 1) { + return Keypath.__super__.setValue.apply(this, arguments); + } else { + return (_ref = this.terminalProperty()) != null ? _ref.setValue(val) : void 0; + } + }; + + Keypath.prototype.unsetValue = function() { + var _ref; + if (this.depth === 1) { + return Keypath.__super__.unsetValue.apply(this, arguments); + } else { + return (_ref = this.terminalProperty()) != null ? _ref.unsetValue() : void 0; + } + }; + + return Keypath; + + })(Batman.Property); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.Observable = { + isObservable: true, + hasProperty: function(key) { + var _ref, _ref1; + return (_ref = this._batman) != null ? (_ref1 = _ref.properties) != null ? typeof _ref1.hasKey === "function" ? _ref1.hasKey(key) : void 0 : void 0 : void 0; + }, + property: function(key) { + var properties, propertyClass, _base; + Batman.initializeObject(this); + propertyClass = this.propertyClass || Batman.Keypath; + properties = (_base = this._batman).properties || (_base.properties = new Batman.SimpleHash); + return properties.get(key) || properties.set(key, new propertyClass(this, key)); + }, + get: function(key) { + return this.property(key).getValue(); + }, + set: function(key, val) { + return this.property(key).setValue(val); + }, + unset: function(key) { + return this.property(key).unsetValue(); + }, + getOrSet: Batman.SimpleHash.prototype.getOrSet, + forget: function(key, observer) { + var _ref; + if (key) { + this.property(key).forget(observer); + } else { + if ((_ref = this._batman.properties) != null) { + _ref.forEach(function(key, property) { + return property.forget(); + }); + } + } + return this; + }, + observe: function() { + var args, key, _ref; + key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + (_ref = this.property(key)).observe.apply(_ref, args); + return this; + }, + observeAndFire: function() { + var args, key, _ref; + key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + (_ref = this.property(key)).observeAndFire.apply(_ref, args); + return this; + }, + observeOnce: function() { + var args, key, _ref; + key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + (_ref = this.property(key)).observeOnce.apply(_ref, args); + return this; + } + }; + +}).call(this); + +(function() { + + Batman.DOM = { + textInputTypes: ['text', 'search', 'tel', 'url', 'email', 'password'], + scrollIntoView: function(elementID) { + var _ref; + return (_ref = document.getElementById(elementID)) != null ? typeof _ref.scrollIntoView === "function" ? _ref.scrollIntoView() : void 0 : void 0; + }, + querySelectorAll: (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) != null ? function(node, selector) { + return jQuery(selector, node); + } : (typeof document !== "undefined" && document !== null ? document.querySelectorAll : void 0) != null ? function(node, selector) { + return node.querySelectorAll(selector); + } : function() { + return Batman.developer.error("Please include either jQuery or a querySelectorAll polyfill, or set Batman.DOM.querySelectorAll to return an empty array."); + }, + querySelector: (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) != null ? function(node, selector) { + return jQuery(selector, node)[0]; + } : (typeof document !== "undefined" && document !== null ? document.querySelector : void 0) != null ? function(node, selector) { + return node.querySelector(selector); + } : function() { + return Batman.developer.error("Please include either jQuery or a querySelector polyfill, or set Batman.DOM.querySelector to an empty function."); + }, + partial: function(container, path, context, renderer) { + var view; + renderer.prevent('rendered'); + view = new Batman.View({ + source: path, + context: context + }); + return view.on('ready', function() { + Batman.setInnerHTML(container, ''); + Batman.appendChild(container, view.get('node')); + return renderer.allowAndFire('rendered'); + }); + }, + propagateBindingEvent: Batman.propagateBindingEvent = function(binding, node) { + var current, parentBinding, parentBindings, _i, _len; + while ((current = (current || node).parentNode)) { + parentBindings = Batman._data(current, 'bindings'); + if (parentBindings != null) { + for (_i = 0, _len = parentBindings.length; _i < _len; _i++) { + parentBinding = parentBindings[_i]; + if (typeof parentBinding.childBindingAdded === "function") { + parentBinding.childBindingAdded(binding); + } + } + } + } + }, + propagateBindingEvents: Batman.propagateBindingEvents = function(newNode) { + var binding, bindings, child, _i, _j, _len, _len1, _ref; + _ref = newNode.childNodes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + Batman.propagateBindingEvents(child); + } + if (bindings = Batman._data(newNode, 'bindings')) { + for (_j = 0, _len1 = bindings.length; _j < _len1; _j++) { + binding = bindings[_j]; + Batman.propagateBindingEvent(binding, newNode); + } + } + }, + trackBinding: Batman.trackBinding = function(binding, node) { + var bindings; + if (bindings = Batman._data(node, 'bindings')) { + bindings.push(binding); + } else { + Batman._data(node, 'bindings', [binding]); + } + Batman.DOM.fire('bindingAdded', binding); + Batman.propagateBindingEvent(binding, node); + return true; + }, + onParseExit: Batman.onParseExit = function(node, callback) { + var set; + set = Batman._data(node, 'onParseExit') || Batman._data(node, 'onParseExit', new Batman.SimpleSet); + if (callback != null) { + set.add(callback); + } + return set; + }, + forgetParseExit: Batman.forgetParseExit = function(node, callback) { + return Batman.removeData(node, 'onParseExit', true); + }, + defineView: function(name, node) { + var contents; + contents = node.innerHTML; + Batman.View.store.set(Batman.Navigator.normalizePath(name), contents); + return contents; + }, + setInnerHTML: Batman.setInnerHTML = function(node, html) { + var child, childNodes, result, _i, _j, _len, _len1; + childNodes = (function() { + var _i, _len, _ref, _results; + _ref = node.childNodes; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + _results.push(child); + } + return _results; + })(); + for (_i = 0, _len = childNodes.length; _i < _len; _i++) { + child = childNodes[_i]; + Batman.DOM.willRemoveNode(child); + } + result = node.innerHTML = html; + for (_j = 0, _len1 = childNodes.length; _j < _len1; _j++) { + child = childNodes[_j]; + Batman.DOM.didRemoveNode(child); + } + return result; + }, + setStyleProperty: Batman.setStyleProperty = function(node, property, value, importance) { + if (node.style.setAttribute) { + return node.style.setAttribute(property, value, importance); + } else { + return node.style.setProperty(property, value, importance); + } + }, + removeNode: Batman.removeNode = function(node) { + var _ref; + Batman.DOM.willRemoveNode(node); + if ((_ref = node.parentNode) != null) { + _ref.removeChild(node); + } + return Batman.DOM.didRemoveNode(node); + }, + destroyNode: Batman.destroyNode = function(node) { + Batman.DOM.willDestroyNode(node); + Batman.removeNode(node); + return Batman.DOM.didDestroyNode(node); + }, + appendChild: Batman.appendChild = function(parent, child) { + Batman.DOM.willInsertNode(child); + parent.appendChild(child); + return Batman.DOM.didInsertNode(child); + }, + removeOrDestroyNode: Batman.removeOrDestroyNode = function(node) { + var view; + view = Batman._data(node, 'view'); + view || (view = Batman._data(node, 'yielder')); + if ((view != null) && view.get('cached')) { + return Batman.DOM.removeNode(node); + } else { + return Batman.DOM.destroyNode(node); + } + }, + insertBefore: Batman.insertBefore = function(parentNode, newNode, referenceNode) { + if (referenceNode == null) { + referenceNode = null; + } + if (!referenceNode || parentNode.childNodes.length <= 0) { + return Batman.appendChild(parentNode, newNode); + } else { + Batman.DOM.willInsertNode(newNode); + parentNode.insertBefore(newNode, referenceNode); + return Batman.DOM.didInsertNode(newNode); + } + }, + valueForNode: function(node, value, escapeValue) { + var isSetting; + if (value == null) { + value = ''; + } + if (escapeValue == null) { + escapeValue = true; + } + isSetting = arguments.length > 1; + switch (node.nodeName.toUpperCase()) { + case 'INPUT': + case 'TEXTAREA': + if (isSetting) { + return node.value = value; + } else { + return node.value; + } + break; + case 'SELECT': + if (isSetting) { + return node.value = value; + } + break; + default: + if (isSetting) { + return Batman.setInnerHTML(node, escapeValue ? Batman.escapeHTML(value) : value); + } else { + return node.innerHTML; + } + } + }, + nodeIsEditable: function(node) { + var _ref; + return (_ref = node.nodeName.toUpperCase()) === 'INPUT' || _ref === 'TEXTAREA' || _ref === 'SELECT'; + }, + addEventListener: Batman.addEventListener = function(node, eventName, callback) { + var listeners; + if (!(listeners = Batman._data(node, 'listeners'))) { + listeners = Batman._data(node, 'listeners', {}); + } + if (!listeners[eventName]) { + listeners[eventName] = []; + } + listeners[eventName].push(callback); + if (Batman.hasAddEventListener) { + return node.addEventListener(eventName, callback, false); + } else { + return node.attachEvent("on" + eventName, callback); + } + }, + removeEventListener: Batman.removeEventListener = function(node, eventName, callback) { + var eventListeners, index, listeners; + if (listeners = Batman._data(node, 'listeners')) { + if (eventListeners = listeners[eventName]) { + index = eventListeners.indexOf(callback); + if (index !== -1) { + eventListeners.splice(index, 1); + } + } + } + if (Batman.hasAddEventListener) { + return node.removeEventListener(eventName, callback, false); + } else { + return node.detachEvent('on' + eventName, callback); + } + }, + hasAddEventListener: Batman.hasAddEventListener = !!(typeof window !== "undefined" && window !== null ? window.addEventListener : void 0), + preventDefault: Batman.preventDefault = function(e) { + if (typeof e.preventDefault === "function") { + return e.preventDefault(); + } else { + return e.returnValue = false; + } + }, + stopPropagation: Batman.stopPropagation = function(e) { + if (e.stopPropagation) { + return e.stopPropagation(); + } else { + return e.cancelBubble = true; + } + }, + willInsertNode: function(node) { + var child, view, _i, _len, _ref, _ref1; + view = Batman._data(node, 'view'); + if (view != null) { + view.fire('beforeAppear', node); + } + if ((_ref = Batman.data(node, 'show')) != null) { + _ref.call(node); + } + _ref1 = node.childNodes; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + child = _ref1[_i]; + Batman.DOM.willInsertNode(child); + } + return true; + }, + didInsertNode: function(node) { + var child, view, _i, _len, _ref; + view = Batman._data(node, 'view'); + if (view) { + view.fire('appear', node); + view.applyYields(); + } + _ref = node.childNodes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + Batman.DOM.didInsertNode(child); + } + return true; + }, + willRemoveNode: function(node) { + var child, view, _i, _len, _ref, _ref1; + view = Batman._data(node, 'view'); + if (view) { + view.fire('beforeDisappear', node); + } + if ((_ref = Batman.data(node, 'hide')) != null) { + _ref.call(node); + } + _ref1 = node.childNodes; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + child = _ref1[_i]; + Batman.DOM.willRemoveNode(child); + } + return true; + }, + didRemoveNode: function(node) { + var child, view, _i, _len, _ref; + view = Batman._data(node, 'view'); + if (view) { + view.retractYields(); + view.fire('disappear', node); + } + _ref = node.childNodes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + Batman.DOM.didRemoveNode(child); + } + return true; + }, + willDestroyNode: function(node) { + var child, view, _i, _len, _ref; + view = Batman._data(node, 'view'); + if (view) { + view.fire('beforeDestroy', node); + view.get('yields').forEach(function(name, actions) { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = actions.length; _i < _len; _i++) { + node = actions[_i].node; + _results.push(Batman.DOM.willDestroyNode(node)); + } + return _results; + }); + } + _ref = node.childNodes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + Batman.DOM.willDestroyNode(child); + } + return true; + }, + didDestroyNode: function(node) { + var bindings, child, eventListeners, eventName, listeners, view, _i, _len, _ref; + view = Batman._data(node, 'view'); + if (view) { + view.fire('destroy', node); + view.get('yields').forEach(function(name, actions) { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = actions.length; _i < _len; _i++) { + node = actions[_i].node; + _results.push(Batman.DOM.didDestroyNode(node)); + } + return _results; + }); + } + if (bindings = Batman._data(node, 'bindings')) { + bindings.forEach(function(binding) { + return binding.die(); + }); + } + if (listeners = Batman._data(node, 'listeners')) { + for (eventName in listeners) { + eventListeners = listeners[eventName]; + eventListeners.forEach(function(listener) { + return Batman.removeEventListener(node, eventName, listener); + }); + } + } + Batman.removeData(node); + Batman.removeData(node, void 0, true); + _ref = node.childNodes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + Batman.DOM.didDestroyNode(child); + } + return true; + } + }; + + Batman.mixin(Batman.DOM, Batman.EventEmitter, Batman.Observable); + + Batman.DOM.event('bindingAdded'); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.DOM.readers = { + target: function(node, key, context, renderer) { + Batman.DOM.readers.bind(node, key, context, renderer, 'nodeChange'); + return true; + }, + source: function(node, key, context, renderer) { + Batman.DOM.readers.bind(node, key, context, renderer, 'dataChange'); + return true; + }, + bind: function(node, key, context, renderer, only) { + var bindingClass; + bindingClass = false; + switch (node.nodeName.toLowerCase()) { + case 'input': + switch (node.getAttribute('type')) { + case 'checkbox': + Batman.DOM.attrReaders.bind(node, 'checked', key, context, renderer, only); + return true; + case 'radio': + bindingClass = Batman.DOM.RadioBinding; + break; + case 'file': + bindingClass = Batman.DOM.FileBinding; + } + break; + case 'select': + bindingClass = Batman.DOM.SelectBinding; + } + bindingClass || (bindingClass = Batman.DOM.Binding); + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(bindingClass, arguments, function(){}); + return true; + }, + context: function(node, key, context, renderer) { + return context.descendWithKey(key); + }, + mixin: function(node, key, context, renderer) { + new Batman.DOM.MixinBinding(node, key, context.descend(Batman.mixins), renderer); + return true; + }, + showif: function(node, key, context, parentRenderer, invert) { + new Batman.DOM.ShowHideBinding(node, key, context, parentRenderer, false, invert); + return true; + }, + hideif: function() { + var _ref; + return (_ref = Batman.DOM.readers).showif.apply(_ref, __slice.call(arguments).concat([true])); + }, + insertif: function(node, key, context, parentRenderer, invert) { + new Batman.DOM.InsertionBinding(node, key, context, parentRenderer, false, invert); + return true; + }, + removeif: function() { + var _ref; + return (_ref = Batman.DOM.readers).insertif.apply(_ref, __slice.call(arguments).concat([true])); + }, + route: function() { + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.DOM.RouteBinding, arguments, function(){}); + return true; + }, + view: function() { + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.DOM.ViewBinding, arguments, function(){}); + return false; + }, + partial: function(node, path, context, renderer) { + Batman.DOM.partial(node, path, context, renderer); + return true; + }, + defineview: function(node, name, context, renderer) { + Batman.onParseExit(node, function() { + var _ref; + return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; + }); + Batman.DOM.defineView(name, node); + return false; + }, + renderif: function(node, key, context, renderer) { + new Batman.DOM.DeferredRenderingBinding(node, key, context, renderer); + return false; + }, + "yield": function(node, key) { + Batman.onParseExit(node, function() { + return Batman.DOM.Yield.withName(key).set('containerNode', node); + }); + return true; + }, + contentfor: function(node, key, context, renderer, action) { + if (action == null) { + action = 'append'; + } + Batman.onParseExit(node, function() { + var _ref; + if ((_ref = node.parentNode) != null) { + _ref.removeChild(node); + } + return renderer.view.pushYieldAction(key, action, node); + }); + return true; + }, + replace: function(node, key, context, renderer) { + Batman.DOM.readers.contentfor(node, key, context, renderer, 'replace'); + return true; + } + }; + +}).call(this); + +(function() { + var __slice = [].slice, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Batman.DOM.events = { + click: function(node, callback, context, eventName) { + if (eventName == null) { + eventName = 'click'; + } + Batman.addEventListener(node, eventName, function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + callback.apply(null, [node].concat(__slice.call(args), [context])); + return Batman.preventDefault(args[0]); + }); + if (node.nodeName.toUpperCase() === 'A' && !node.href) { + node.href = '#'; + } + return node; + }, + doubleclick: function(node, callback, context) { + return Batman.DOM.events.click(node, callback, context, 'dblclick'); + }, + change: function(node, callback, context) { + var eventName, eventNames, oldCallback, _i, _len, _results; + eventNames = (function() { + var _ref; + switch (node.nodeName.toUpperCase()) { + case 'TEXTAREA': + return ['input', 'keyup', 'change']; + case 'INPUT': + if (_ref = node.type.toLowerCase(), __indexOf.call(Batman.DOM.textInputTypes, _ref) >= 0) { + oldCallback = callback; + callback = function(node, event) { + if (event.type === 'keyup' && Batman.DOM.events.isEnter(event)) { + return; + } + return oldCallback.apply(null, arguments); + }; + return ['input', 'keyup', 'change']; + } else { + return ['input', 'change']; + } + break; + default: + return ['change']; + } + })(); + _results = []; + for (_i = 0, _len = eventNames.length; _i < _len; _i++) { + eventName = eventNames[_i]; + _results.push(Batman.addEventListener(node, eventName, function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return callback.apply(null, [node].concat(__slice.call(args), [context])); + })); + } + return _results; + }, + isEnter: function(ev) { + var _ref, _ref1; + return ((13 <= (_ref = ev.keyCode) && _ref <= 14)) || ((13 <= (_ref1 = ev.which) && _ref1 <= 14)) || ev.keyIdentifier === 'Enter' || ev.key === 'Enter'; + }, + submit: function(node, callback, context) { + if (Batman.DOM.nodeIsEditable(node)) { + Batman.addEventListener(node, 'keydown', function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + if (Batman.DOM.events.isEnter(args[0])) { + return Batman.DOM._keyCapturingNode = node; + } + }); + Batman.addEventListener(node, 'keyup', function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + if (Batman.DOM.events.isEnter(args[0])) { + if (Batman.DOM._keyCapturingNode === node) { + Batman.preventDefault(args[0]); + callback.apply(null, [node].concat(__slice.call(args), [context])); + } + return Batman.DOM._keyCapturingNode = null; + } + }); + } else { + Batman.addEventListener(node, 'submit', function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + Batman.preventDefault(args[0]); + return callback.apply(null, [node].concat(__slice.call(args), [context])); + }); + } + return node; + }, + other: function(node, eventName, callback, context) { + return Batman.addEventListener(node, eventName, function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return callback.apply(null, [node].concat(__slice.call(args), [context])); + }); + } + }; + +}).call(this); + +(function() { + + Batman.DOM.attrReaders = { + _parseAttribute: function(value) { + if (value === 'false') { + value = false; + } + if (value === 'true') { + value = true; + } + return value; + }, + source: function(node, attr, key, context, renderer) { + return Batman.DOM.attrReaders.bind(node, attr, key, context, renderer, 'dataChange'); + }, + bind: function(node, attr, key, context, renderer, only) { + var bindingClass; + bindingClass = (function() { + switch (attr) { + case 'checked': + case 'disabled': + case 'selected': + return Batman.DOM.CheckedBinding; + case 'value': + case 'href': + case 'src': + case 'size': + return Batman.DOM.NodeAttributeBinding; + case 'class': + return Batman.DOM.ClassBinding; + case 'style': + return Batman.DOM.StyleBinding; + default: + return Batman.DOM.AttributeBinding; + } + })(); + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(bindingClass, arguments, function(){}); + return true; + }, + context: function(node, contextName, key, context) { + return context.descendWithKey(key, contextName); + }, + event: function(node, eventName, key, context) { + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.DOM.EventBinding, arguments, function(){}); + return true; + }, + addclass: function(node, className, key, context, parentRenderer, invert) { + new Batman.DOM.AddClassBinding(node, className, key, context, parentRenderer, false, invert); + return true; + }, + removeclass: function(node, className, key, context, parentRenderer) { + return Batman.DOM.attrReaders.addclass(node, className, key, context, parentRenderer, true); + }, + foreach: function(node, iteratorName, key, context, parentRenderer) { + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.DOM.IteratorBinding, arguments, function(){}); + return false; + }, + formfor: function(node, localName, key, context) { + (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.DOM.FormBinding, arguments, function(){}); + return context.descendWithKey(key, localName); + } + }; + +}).call(this); + +(function() { + var BatmanObject, + __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; }, + __slice = [].slice; + + BatmanObject = (function(_super) { + var counter, getAccessorObject, promiseWrapper, wrapSingleAccessor; + + __extends(BatmanObject, _super); + + Batman.initializeObject(BatmanObject); + + Batman.initializeObject(BatmanObject.prototype); + + BatmanObject.classMixin = function() { + return Batman.mixin.apply(Batman, [this].concat(__slice.call(arguments))); + }; + + BatmanObject.mixin = function() { + return this.classMixin.apply(this.prototype, arguments); + }; + + BatmanObject.prototype.mixin = BatmanObject.classMixin; + + counter = 0; + + BatmanObject.prototype._batmanID = function() { + var c; + this._batmanID = function() { + return c; + }; + return c = counter++; + }; + + BatmanObject.prototype.hashKey = function() { + var key; + if (typeof this.isEqual === 'function') { + return; + } + this.hashKey = function() { + return key; + }; + return key = ""; + }; + + BatmanObject.prototype.toJSON = function() { + var key, obj, value; + obj = {}; + for (key in this) { + if (!__hasProp.call(this, key)) continue; + value = this[key]; + if (key !== "_batman" && key !== "hashKey" && key !== "_batmanID") { + obj[key] = (value != null ? value.toJSON : void 0) ? value.toJSON() : value; + } + } + return obj; + }; + + getAccessorObject = function(base, accessor) { + var deprecated, _i, _len, _ref; + if (typeof accessor === 'function') { + accessor = { + get: accessor + }; + } + _ref = ['cachable', 'cacheable']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + deprecated = _ref[_i]; + if (deprecated in accessor) { + Batman.developer.warn("Property accessor option \"" + deprecated + "\" is deprecated. Use \"cache\" instead."); + if (!('cache' in accessor)) { + accessor.cache = accessor[deprecated]; + } + } + } + return accessor; + }; + + promiseWrapper = function(fetcher) { + return function(core) { + return { + get: function(key) { + var deliver, returned, val, + _this = this; + val = core.get.apply(this, arguments); + if (typeof val !== 'undefined') { + return val; + } + returned = false; + deliver = function(err, result) { + if (returned) { + _this.set(key, result); + } + return val = result; + }; + fetcher.call(this, deliver, key); + returned = true; + return val; + }, + cache: true + }; + }; + }; + + wrapSingleAccessor = function(core, wrapper) { + var k, v; + wrapper = (typeof wrapper === "function" ? wrapper(core) : void 0) || wrapper; + for (k in core) { + v = core[k]; + if (!(k in wrapper)) { + wrapper[k] = v; + } + } + return wrapper; + }; + + BatmanObject._defineAccessor = function() { + var accessor, key, keys, _base, _i, _j, _len, _ref, _results; + keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), accessor = arguments[_i++]; + if (!(accessor != null)) { + return Batman.Property.defaultAccessorForBase(this); + } else if (keys.length === 0 && ((_ref = Batman.typeOf(accessor)) !== 'Object' && _ref !== 'Function')) { + return Batman.Property.accessorForBaseAndKey(this, accessor); + } else if (typeof accessor.promise === 'function') { + return this._defineWrapAccessor.apply(this, __slice.call(keys).concat([promiseWrapper(accessor.promise)])); + } + Batman.initializeObject(this); + if (keys.length === 0) { + return this._batman.defaultAccessor = getAccessorObject(this, accessor); + } else { + (_base = this._batman).keyAccessors || (_base.keyAccessors = new Batman.SimpleHash); + _results = []; + for (_j = 0, _len = keys.length; _j < _len; _j++) { + key = keys[_j]; + _results.push(this._batman.keyAccessors.set(key, getAccessorObject(this, accessor))); + } + return _results; + } + }; + + BatmanObject.prototype._defineAccessor = BatmanObject._defineAccessor; + + BatmanObject._defineWrapAccessor = function() { + var key, keys, wrapper, _i, _j, _len, _results; + keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), wrapper = arguments[_i++]; + Batman.initializeObject(this); + if (keys.length === 0) { + return this._defineAccessor(wrapSingleAccessor(this._defineAccessor(), wrapper)); + } else { + _results = []; + for (_j = 0, _len = keys.length; _j < _len; _j++) { + key = keys[_j]; + _results.push(this._defineAccessor(key, wrapSingleAccessor(this._defineAccessor(key), wrapper))); + } + return _results; + } + }; + + BatmanObject.prototype._defineWrapAccessor = BatmanObject._defineWrapAccessor; + + BatmanObject.classAccessor = BatmanObject._defineAccessor; + + BatmanObject.accessor = function() { + var _ref; + return (_ref = this.prototype)._defineAccessor.apply(_ref, arguments); + }; + + BatmanObject.prototype.accessor = BatmanObject._defineAccessor; + + BatmanObject.wrapClassAccessor = BatmanObject._defineWrapAccessor; + + BatmanObject.wrapAccessor = function() { + var _ref; + return (_ref = this.prototype)._defineWrapAccessor.apply(_ref, arguments); + }; + + BatmanObject.prototype.wrapAccessor = BatmanObject._defineWrapAccessor; + + function BatmanObject() { + var mixins; + mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + this._batman = new Batman._Batman(this); + this.mixin.apply(this, mixins); + } + + BatmanObject.classMixin(Batman.EventEmitter, Batman.Observable); + + BatmanObject.mixin(Batman.EventEmitter, Batman.Observable); + + BatmanObject.observeAll = function() { + return this.prototype.observe.apply(this.prototype, arguments); + }; + + BatmanObject.singleton = function(singletonMethodName) { + if (singletonMethodName == null) { + singletonMethodName = "sharedInstance"; + } + return this.classAccessor(singletonMethodName, { + get: function() { + var _name; + return this[_name = "_" + singletonMethodName] || (this[_name] = new this); + } + }); + }; + + BatmanObject.accessor('_batmanID', function() { + return this._batmanID(); + }); + + return BatmanObject; + + })(Object); + + Batman.Object = BatmanObject; + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.Renderer = (function(_super) { + var bindingRegexp, bindingSortOrder, bindingSortPositions, k, name, pos, _i, _j, _len, _len1, _ref; + + __extends(Renderer, _super); + + Renderer.prototype.deferEvery = 50; + + function Renderer(node, context, view) { + this.node = node; + this.context = context; + this.view = view; + this.resume = __bind(this.resume, this); + + this.start = __bind(this.start, this); + + Renderer.__super__.constructor.call(this); + if (!(this.context instanceof Batman.RenderContext)) { + Batman.developer.error("Must pass a RenderContext to a renderer for rendering"); + } + this.immediate = Batman.setImmediate(this.start); + } + + Renderer.prototype.start = function() { + this.startTime = new Date; + return this.parseNode(this.node); + }; + + Renderer.prototype.resume = function() { + this.startTime = new Date; + return this.parseNode(this.resumeNode); + }; + + Renderer.prototype.finish = function() { + this.startTime = null; + this.prevent('stopped'); + this.fire('parsed'); + return this.fire('rendered'); + }; + + Renderer.prototype.stop = function() { + Batman.clearImmediate(this.immediate); + return this.fire('stopped'); + }; + + _ref = ['parsed', 'rendered', 'stopped']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + Renderer.prototype.event(k).oneShot = true; + } + + bindingRegexp = /^data\-(.*)/; + + bindingSortOrder = ["view", "renderif", "foreach", "formfor", "context", "bind", "source", "target"]; + + bindingSortPositions = {}; + + for (pos = _j = 0, _len1 = bindingSortOrder.length; _j < _len1; pos = ++_j) { + name = bindingSortOrder[pos]; + bindingSortPositions[name] = pos; + } + + Renderer.prototype._sortBindings = function(a, b) { + var aindex, bindex; + aindex = bindingSortPositions[a[0]]; + bindex = bindingSortPositions[b[0]]; + if (aindex == null) { + aindex = bindingSortOrder.length; + } + if (bindex == null) { + bindex = bindingSortOrder.length; + } + if (aindex > bindex) { + return 1; + } else if (bindex > aindex) { + return -1; + } else if (a[0] > b[0]) { + return 1; + } else if (b[0] > a[0]) { + return -1; + } else { + return 0; + } + }; + + Renderer.prototype.parseNode = function(node) { + var argument, attribute, bindings, keypath, names, nextNode, oldContext, result, skipChildren, _base, _base1, _k, _l, _len2, _len3, _ref1, _ref2, _ref3, _ref4, + _this = this; + if (this.deferEvery && (new Date - this.startTime) > this.deferEvery) { + this.resumeNode = node; + this.timeout = Batman.setImmediate(this.resume); + return; + } + if (node.getAttribute && node.attributes) { + bindings = []; + _ref1 = node.attributes; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + attribute = _ref1[_k]; + name = (_ref2 = attribute.nodeName.match(bindingRegexp)) != null ? _ref2[1] : void 0; + if (!name) { + continue; + } + bindings.push((names = name.split('-')).length > 1 ? [names[0], names.slice(1, names.length + 1 || 9e9).join('-'), attribute.value] : [name, void 0, attribute.value]); + } + _ref3 = bindings.sort(this._sortBindings); + for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { + _ref4 = _ref3[_l], name = _ref4[0], argument = _ref4[1], keypath = _ref4[2]; + result = argument ? typeof (_base = Batman.DOM.attrReaders)[name] === "function" ? _base[name](node, argument, keypath, this.context, this) : void 0 : typeof (_base1 = Batman.DOM.readers)[name] === "function" ? _base1[name](node, keypath, this.context, this) : void 0; + if (result === false) { + skipChildren = true; + break; + } else if (result instanceof Batman.RenderContext) { + oldContext = this.context; + this.context = result; + Batman.onParseExit(node, function() { + return _this.context = oldContext; + }); + } + } + } + if ((nextNode = this.nextNode(node, skipChildren))) { + return this.parseNode(nextNode); + } else { + return this.finish(); + } + }; + + Renderer.prototype.nextNode = function(node, skipChildren) { + var children, nextParent, parentSibling, sibling, _ref1, _ref2; + if (!skipChildren) { + children = node.childNodes; + if (children != null ? children.length : void 0) { + return children[0]; + } + } + sibling = node.nextSibling; + if ((_ref1 = Batman.onParseExit(node)) != null) { + _ref1.forEach(function(callback) { + return callback(); + }); + } + Batman.forgetParseExit(node); + if (this.node === node) { + return; + } + if (sibling) { + return sibling; + } + nextParent = node; + while (nextParent = nextParent.parentNode) { + parentSibling = nextParent.nextSibling; + if ((_ref2 = Batman.onParseExit(nextParent)) != null) { + _ref2.forEach(function(callback) { + return callback(); + }); + } + Batman.forgetParseExit(nextParent); + if (this.node === nextParent) { + return; + } + if (parentSibling) { + return parentSibling; + } + } + }; + + return Renderer; + + })(Batman.Object); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.DOM.AbstractBinding = (function(_super) { + var get_dot_rx, get_rx, keypath_rx; + + __extends(AbstractBinding, _super); + + keypath_rx = /(^|,)\s*(?:(true|false)|("[^"]*")|(\{[^\}]*\})|([a-zA-Z][\w\-\.]*[\?\!]?))\s*(?=$|,)/g; + + get_dot_rx = /(?:\]\.)(.+?)(?=[\[\.]|\s*\||$)/; + + get_rx = /(?!^\s*)\[(.*?)\]/g; + + AbstractBinding.accessor('filteredValue', { + get: function() { + var renderContext, result, self, unfilteredValue; + unfilteredValue = this.get('unfilteredValue'); + self = this; + renderContext = this.get('renderContext'); + if (this.filterFunctions.length > 0) { + Batman.developer.currentFilterStack = renderContext; + result = this.filterFunctions.reduce(function(value, fn, i) { + var args; + args = self.filterArguments[i].map(function(argument) { + if (argument._keypath) { + return self.renderContext.get(argument._keypath); + } else { + return argument; + } + }); + args.unshift(value); + while (args.length < (fn.length - 1)) { + args.push(void 0); + } + args.push(self); + return fn.apply(renderContext, args); + }, unfilteredValue); + Batman.developer.currentFilterStack = null; + return result; + } else { + return unfilteredValue; + } + }, + set: function(_, newValue) { + return this.set('unfilteredValue', newValue); + } + }); + + AbstractBinding.accessor('unfilteredValue', { + get: function() { + var k; + if (k = this.get('key')) { + return Batman.RenderContext.deProxy(Batman.getPath(this, ['keyContext', k])); + } else { + return this.get('value'); + } + }, + set: function(_, value) { + var k, keyContext, prop; + if (k = this.get('key')) { + keyContext = this.get('keyContext'); + if (keyContext && keyContext !== Batman.container) { + prop = Batman.Property.forBaseAndKey(keyContext, k); + return prop.setValue(value); + } + } else { + return this.set('value', value); + } + } + }); + + AbstractBinding.accessor('keyContext', function() { + return this.renderContext.contextForKey(this.key); + }); + + AbstractBinding.prototype.bindImmediately = true; + + AbstractBinding.prototype.shouldSet = true; + + AbstractBinding.prototype.isInputBinding = false; + + AbstractBinding.prototype.escapeValue = true; + + function AbstractBinding(node, keyPath, renderContext, renderer, only) { + this.node = node; + this.keyPath = keyPath; + this.renderContext = renderContext; + this.renderer = renderer; + this.only = only != null ? only : false; + this._fireDataChange = __bind(this._fireDataChange, this); + + this._fireNodeChange = __bind(this._fireNodeChange, this); + + this.parseFilter(); + if (this.bindImmediately) { + this.bind(); + } + } + + AbstractBinding.prototype.isTwoWay = function() { + return (this.key != null) && this.filterFunctions.length === 0; + }; + + AbstractBinding.prototype.bind = function() { + var _ref, _ref1; + if ((this.node != null) && ((_ref = this.only) === false || _ref === 'nodeChange') && Batman.DOM.nodeIsEditable(this.node)) { + Batman.DOM.events.change(this.node, this._fireNodeChange); + if (this.only === 'nodeChange') { + this._fireNodeChange(); + } + } + if ((_ref1 = this.only) === false || _ref1 === 'dataChange') { + this.observeAndFire('filteredValue', this._fireDataChange); + } + if (this.node != null) { + return Batman.DOM.trackBinding(this, this.node); + } + }; + + AbstractBinding.prototype._fireNodeChange = function(event) { + var val; + this.shouldSet = false; + val = this.value || this.get('keyContext'); + if (typeof this.nodeChange === "function") { + this.nodeChange(this.node, val, event); + } + this.fire('nodeChange', this.node, val); + return this.shouldSet = true; + }; + + AbstractBinding.prototype._fireDataChange = function(value) { + if (this.shouldSet) { + if (typeof this.dataChange === "function") { + this.dataChange(value, this.node); + } + return this.fire('dataChange', value, this.node); + } + }; + + AbstractBinding.prototype.die = function() { + var _ref; + this.forget(); + if ((_ref = this._batman.properties) != null) { + _ref.forEach(function(key, property) { + return property.die(); + }); + } + this.fire('die'); + this.dead = true; + return true; + }; + + AbstractBinding.prototype.parseFilter = function() { + var args, filter, filterName, filterString, filters, key, keyPath, orig, split; + this.filterFunctions = []; + this.filterArguments = []; + keyPath = this.keyPath; + while (get_dot_rx.test(keyPath)) { + keyPath = keyPath.replace(get_dot_rx, "]['$1']"); + } + filters = keyPath.replace(get_rx, " | get $1 ").replace(/'/g, '"').split(/(?!")\s+\|\s+(?!")/); + try { + key = this.parseSegment(orig = filters.shift())[0]; + } catch (e) { + Batman.developer.warn(e); + Batman.developer.error("Error! Couldn't parse keypath in \"" + orig + "\". Parsing error above."); + } + if (key && key._keypath) { + this.key = key._keypath; + } else { + this.value = key; + } + if (filters.length) { + while (filterString = filters.shift()) { + split = filterString.indexOf(' '); + if (split === -1) { + split = filterString.length; + } + filterName = filterString.substr(0, split); + args = filterString.substr(split); + if (!(filter = Batman.Filters[filterName])) { + return Batman.developer.error("Unrecognized filter '" + filterName + "' in key \"" + this.keyPath + "\"!"); + } + this.filterFunctions.push(filter); + try { + this.filterArguments.push(this.parseSegment(args)); + } catch (e) { + Batman.developer.error("Bad filter arguments \"" + args + "\"!"); + } + } + return true; + } + }; + + AbstractBinding.prototype.parseSegment = function(segment) { + segment = segment.replace(keypath_rx, function(match, start, bool, string, object, keypath, offset) { + var replacement; + if (start == null) { + start = ''; + } + replacement = keypath ? '{"_keypath": "' + keypath + '"}' : bool || string || object; + return start + replacement; + }); + return JSON.parse("[" + segment + "]"); + }; + + return AbstractBinding; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.ViewBinding = (function(_super) { + + __extends(ViewBinding, _super); + + function ViewBinding() { + ViewBinding.__super__.constructor.apply(this, arguments); + this.renderer.prevent('rendered'); + this.node.removeAttribute('data-view'); + } + + ViewBinding.prototype.dataChange = function(viewClassOrInstance) { + var _this = this; + if (viewClassOrInstance == null) { + return; + } + if (viewClassOrInstance.isView) { + this.view = viewClassOrInstance; + this.view.set('context', this.renderContext); + this.view.set('node', this.node); + } else { + this.view = new viewClassOrInstance({ + node: this.node, + context: this.renderContext, + parentView: this.renderer.view + }); + } + this.view.on('ready', function() { + return _this.renderer.allowAndFire('rendered'); + }); + return this.die(); + }; + + return ViewBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.ViewArgumentBinding = (function(_super) { + + __extends(ViewArgumentBinding, _super); + + function ViewArgumentBinding() { + return ViewArgumentBinding.__super__.constructor.apply(this, arguments); + } + + return ViewArgumentBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.ShowHideBinding = (function(_super) { + + __extends(ShowHideBinding, _super); + + function ShowHideBinding(node, className, key, context, parentRenderer, invert) { + var display; + this.invert = invert != null ? invert : false; + display = node.style.display; + if (!display || display === 'none') { + display = ''; + } + this.originalDisplay = display; + ShowHideBinding.__super__.constructor.apply(this, arguments); + } + + ShowHideBinding.prototype.dataChange = function(value) { + var hide, view, _ref; + view = Batman._data(this.node, 'view'); + if (!!value === !this.invert) { + if (view != null) { + view.fire('beforeAppear', this.node); + } + if ((_ref = Batman.data(this.node, 'show')) != null) { + _ref.call(this.node); + } + this.node.style.display = this.originalDisplay; + return view != null ? view.fire('appear', this.node) : void 0; + } else { + if (view != null) { + view.fire('beforeDisappear', this.node); + } + if (typeof (hide = Batman.data(this.node, 'hide')) === 'function') { + hide.call(this.node); + } else { + Batman.setStyleProperty(this.node, 'display', 'none', 'important'); + } + return view != null ? view.fire('disappear', this.node) : void 0; + } + }; + + return ShowHideBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.DOM.SelectBinding = (function(_super) { + + __extends(SelectBinding, _super); + + SelectBinding.prototype.isInputBinding = true; + + SelectBinding.prototype.firstBind = true; + + function SelectBinding() { + this.updateOptionBindings = __bind(this.updateOptionBindings, this); + + this.nodeChange = __bind(this.nodeChange, this); + + this.dataChange = __bind(this.dataChange, this); + + this.childBindingAdded = __bind(this.childBindingAdded, this); + this.selectedBindings = new Batman.SimpleSet; + SelectBinding.__super__.constructor.apply(this, arguments); + } + + SelectBinding.prototype.childBindingAdded = function(binding) { + var dataChangeHandler, + _this = this; + if (binding instanceof Batman.DOM.CheckedBinding) { + binding.on('dataChange', dataChangeHandler = function() { + return _this.nodeChange(); + }); + binding.on('die', function() { + binding.forget('dataChange', dataChangeHandler); + return _this.selectedBindings.remove(binding); + }); + this.selectedBindings.add(binding); + } else if (binding instanceof Batman.DOM.IteratorBinding) { + binding.on('nodeAdded', dataChangeHandler = function() { + return _this._fireDataChange(_this.get('filteredValue')); + }); + binding.on('nodeRemoved', dataChangeHandler); + binding.on('die', function() { + binding.forget('nodeAdded', dataChangeHandler); + return binding.forget('nodeRemoved', dataChangeHandler); + }); + } else { + return; + } + return this._fireDataChange(this.get('filteredValue')); + }; + + SelectBinding.prototype.dataChange = function(newValue) { + var child, matches, valueToChild, _i, _len, _name, _ref, + _this = this; + if (newValue != null ? newValue.forEach : void 0) { + valueToChild = {}; + _ref = this.node.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + child.selected = false; + matches = valueToChild[_name = child.value] || (valueToChild[_name] = []); + matches.push(child); + } + newValue.forEach(function(value) { + var children, node, _j, _len1, _results; + if (children = valueToChild[value]) { + _results = []; + for (_j = 0, _len1 = children.length; _j < _len1; _j++) { + node = children[_j]; + _results.push(node.selected = true); + } + return _results; + } + }); + } else { + if (typeof newValue === 'undefined' && this.firstBind) { + this.set('unfilteredValue', this.node.value); + } else { + Batman.DOM.valueForNode(this.node, newValue, this.escapeValue); + } + this.firstBind = false; + } + this.updateOptionBindings(); + }; + + SelectBinding.prototype.nodeChange = function() { + var c, selections; + if (this.isTwoWay()) { + selections = this.node.multiple ? (function() { + var _i, _len, _ref, _results; + _ref = this.node.children; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + c = _ref[_i]; + if (c.selected) { + _results.push(c.value); + } + } + return _results; + }).call(this) : this.node.value; + if (typeof selections === Array && selections.length === 1) { + selections = selections[0]; + } + this.set('unfilteredValue', selections); + this.updateOptionBindings(); + } + }; + + SelectBinding.prototype.updateOptionBindings = function() { + return this.selectedBindings.forEach(function(binding) { + return binding._fireNodeChange(); + }); + }; + + return SelectBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.RouteBinding = (function(_super) { + + __extends(RouteBinding, _super); + + function RouteBinding() { + return RouteBinding.__super__.constructor.apply(this, arguments); + } + + RouteBinding.prototype.onATag = false; + + RouteBinding.accessor('dispatcher', function() { + return this.renderContext.get('dispatcher') || Batman.App.get('current.dispatcher'); + }); + + RouteBinding.prototype.bind = function() { + var _this = this; + if (this.node.nodeName.toUpperCase() === 'A') { + this.onATag = true; + } + RouteBinding.__super__.bind.apply(this, arguments); + return Batman.DOM.events.click(this.node, function(node, event) { + var params; + if (event.__batmanActionTaken) { + return; + } + event.__batmanActionTaken = true; + params = _this.pathFromValue(_this.get('filteredValue')); + if (params != null) { + return Batman.redirect(params); + } + }); + }; + + RouteBinding.prototype.dataChange = function(value) { + var path; + if (value != null) { + path = this.pathFromValue(value); + } + if (this.onATag) { + if ((path != null) && (Batman.navigator != null)) { + path = Batman.navigator.linkTo(path); + } else { + path = "#"; + } + return this.node.href = path; + } + }; + + RouteBinding.prototype.pathFromValue = function(value) { + var _ref; + if (value != null) { + if (value.isNamedRouteQuery) { + return value.get('path'); + } else { + return (_ref = this.get('dispatcher')) != null ? _ref.pathFromParams(value) : void 0; + } + } + }; + + return RouteBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.RadioBinding = (function(_super) { + + __extends(RadioBinding, _super); + + function RadioBinding() { + return RadioBinding.__super__.constructor.apply(this, arguments); + } + + RadioBinding.accessor('parsedNodeValue', function() { + return Batman.DOM.attrReaders._parseAttribute(this.node.value); + }); + + RadioBinding.prototype.firstBind = true; + + RadioBinding.prototype.dataChange = function(value) { + var boundValue; + boundValue = this.get('filteredValue'); + if (boundValue != null) { + this.node.checked = boundValue === Batman.DOM.attrReaders._parseAttribute(this.node.value); + } else { + if (this.firstBind && this.node.checked) { + this.set('filteredValue', this.get('parsedNodeValue')); + } + } + return this.firstBind = false; + }; + + RadioBinding.prototype.nodeChange = function(node) { + if (this.isTwoWay()) { + return this.set('filteredValue', this.get('parsedNodeValue')); + } + }; + + return RadioBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.MixinBinding = (function(_super) { + + __extends(MixinBinding, _super); + + function MixinBinding() { + return MixinBinding.__super__.constructor.apply(this, arguments); + } + + MixinBinding.prototype.dataChange = function(value) { + if (value != null) { + return Batman.mixin(this.node, value); + } + }; + + return MixinBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.FileBinding = (function(_super) { + + __extends(FileBinding, _super); + + function FileBinding() { + return FileBinding.__super__.constructor.apply(this, arguments); + } + + FileBinding.prototype.isInputBinding = true; + + FileBinding.prototype.nodeChange = function(node, subContext) { + if (!this.isTwoWay()) { + return; + } + if (node.hasAttribute('multiple')) { + return this.set('filteredValue', Array.prototype.slice.call(node.files)); + } else { + return this.set('filteredValue', node.files[0]); + } + }; + + return FileBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.DeferredRenderingBinding = (function(_super) { + + __extends(DeferredRenderingBinding, _super); + + DeferredRenderingBinding.prototype.rendered = false; + + function DeferredRenderingBinding() { + DeferredRenderingBinding.__super__.constructor.apply(this, arguments); + this.node.removeAttribute("data-renderif"); + } + + DeferredRenderingBinding.prototype.nodeChange = function() {}; + + DeferredRenderingBinding.prototype.dataChange = function(value) { + if (value && !this.rendered) { + return this.render(); + } + }; + + DeferredRenderingBinding.prototype.render = function() { + new Batman.Renderer(this.node, this.renderContext, this.renderer.view); + return this.rendered = true; + }; + + return DeferredRenderingBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.Binding = (function(_super) { + + __extends(Binding, _super); + + function Binding(node) { + var _ref; + this.isInputBinding = (_ref = node.nodeName.toLowerCase()) === 'input' || _ref === 'textarea'; + Binding.__super__.constructor.apply(this, arguments); + } + + Binding.prototype.nodeChange = function(node, context) { + if (this.isTwoWay()) { + return this.set('filteredValue', this.node.value); + } + }; + + Binding.prototype.dataChange = function(value, node) { + return Batman.DOM.valueForNode(this.node, value, this.escapeValue); + }; + + return Binding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.DOM.AbstractAttributeBinding = (function(_super) { + + __extends(AbstractAttributeBinding, _super); + + function AbstractAttributeBinding() { + var args, attributeName, node; + node = arguments[0], attributeName = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + this.attributeName = attributeName; + AbstractAttributeBinding.__super__.constructor.apply(this, [node].concat(__slice.call(args))); + } + + return AbstractAttributeBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.DOM.FormBinding = (function(_super) { + + __extends(FormBinding, _super); + + FormBinding.current = null; + + FormBinding.prototype.errorClass = 'error'; + + FormBinding.prototype.defaultErrorsListSelector = 'div.errors'; + + FormBinding.accessor('errorsListSelector', function() { + return this.get('node').getAttribute('data-errors-list') || this.defaultErrorsListSelector; + }); + + function FormBinding(node, contextName, keyPath, renderContext, renderer, only) { + this.childBindingAdded = __bind(this.childBindingAdded, this); + FormBinding.__super__.constructor.apply(this, arguments); + this.contextName = contextName; + delete this.attributeName; + Batman.DOM.events.submit(this.get('node'), function(node, e) { + return Batman.preventDefault(e); + }); + this.setupErrorsList(); + } + + FormBinding.prototype.childBindingAdded = function(binding) { + var field, index, node; + if (binding.isInputBinding && Batman.isChildOf(this.get('node'), binding.get('node'))) { + if (~(index = binding.get('key').indexOf(this.contextName))) { + node = binding.get('node'); + field = binding.get('key').slice(index + this.contextName.length + 1); + return new Batman.DOM.AddClassBinding(node, this.errorClass, this.get('keyPath') + (" | get 'errors." + field + ".length'"), this.renderContext, this.renderer); + } + } + }; + + FormBinding.prototype.setupErrorsList = function() { + if (this.errorsListNode = Batman.DOM.querySelector(this.get('node'), this.get('errorsListSelector'))) { + Batman.setInnerHTML(this.errorsListNode, this.errorsListHTML()); + if (!this.errorsListNode.getAttribute('data-showif')) { + return this.errorsListNode.setAttribute('data-showif', "" + this.contextName + ".errors.length"); + } + } + }; + + FormBinding.prototype.errorsListHTML = function() { + return "
    \n
  • \n
"; + }; + + return FormBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.EventBinding = (function(_super) { + + __extends(EventBinding, _super); + + EventBinding.prototype.bindImmediately = false; + + function EventBinding(node, eventName, key, context) { + var attacher, callback, confirmText, + _this = this; + EventBinding.__super__.constructor.apply(this, arguments); + confirmText = this.node.getAttribute('data-confirm'); + callback = function() { + var _ref; + if (confirmText && !confirm(confirmText)) { + return; + } + return (_ref = _this.get('filteredValue')) != null ? _ref.apply(_this.get('callbackContext'), arguments) : void 0; + }; + if (attacher = Batman.DOM.events[this.attributeName]) { + attacher(this.node, callback, context); + } else { + Batman.DOM.events.other(this.node, this.attributeName, callback, context); + } + this.bind(); + } + + EventBinding.accessor('callbackContext', function() { + var contextKeySegments; + contextKeySegments = this.key.split('.'); + contextKeySegments.pop(); + if (contextKeySegments.length > 0) { + return this.get('keyContext').get(contextKeySegments.join('.')); + } else { + return this.get('keyContext'); + } + }); + + EventBinding.wrapAccessor('unfilteredValue', function(core) { + return { + get: function() { + var functionKey, k, keyContext, keys; + if (k = this.get('key')) { + keys = k.split('.'); + if (keys.length > 1) { + functionKey = keys.pop(); + keyContext = Batman.getPath(this, ['keyContext'].concat(keys)); + if (keyContext != null) { + keyContext = Batman.RenderContext.deProxy(keyContext); + return keyContext[functionKey]; + } + } + } + return core.get.apply(this, arguments); + } + }; + }); + + return EventBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.NodeAttributeBinding = (function(_super) { + + __extends(NodeAttributeBinding, _super); + + function NodeAttributeBinding() { + return NodeAttributeBinding.__super__.constructor.apply(this, arguments); + } + + NodeAttributeBinding.prototype.dataChange = function(value) { + if (value == null) { + value = ""; + } + return this.node[this.attributeName] = value; + }; + + NodeAttributeBinding.prototype.nodeChange = function(node) { + if (this.isTwoWay()) { + return this.set('filteredValue', Batman.DOM.attrReaders._parseAttribute(node[this.attributeName])); + } + }; + + return NodeAttributeBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.CheckedBinding = (function(_super) { + + __extends(CheckedBinding, _super); + + function CheckedBinding() { + return CheckedBinding.__super__.constructor.apply(this, arguments); + } + + CheckedBinding.prototype.isInputBinding = true; + + CheckedBinding.prototype.dataChange = function(value) { + return this.node[this.attributeName] = !!value; + }; + + return CheckedBinding; + + })(Batman.DOM.NodeAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.AttributeBinding = (function(_super) { + + __extends(AttributeBinding, _super); + + function AttributeBinding() { + return AttributeBinding.__super__.constructor.apply(this, arguments); + } + + AttributeBinding.prototype.dataChange = function(value) { + return this.node.setAttribute(this.attributeName, value); + }; + + AttributeBinding.prototype.nodeChange = function(node) { + if (this.isTwoWay()) { + return this.set('filteredValue', Batman.DOM.attrReaders._parseAttribute(node.getAttribute(this.attributeName))); + } + }; + + return AttributeBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.AddClassBinding = (function(_super) { + + __extends(AddClassBinding, _super); + + function AddClassBinding(node, className, keyPath, renderContext, renderer, only, invert) { + var name, names; + this.invert = invert != null ? invert : false; + names = className.split('|'); + this.classes = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = names.length; _i < _len; _i++) { + name = names[_i]; + _results.push({ + name: name, + pattern: new RegExp("(?:^|\\s)" + name + "(?:$|\\s)", 'i') + }); + } + return _results; + })(); + AddClassBinding.__super__.constructor.apply(this, arguments); + delete this.attributeName; + } + + AddClassBinding.prototype.dataChange = function(value) { + var currentName, includesClassName, name, pattern, _i, _len, _ref, _ref1; + currentName = this.node.className; + _ref = this.classes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + _ref1 = _ref[_i], name = _ref1.name, pattern = _ref1.pattern; + includesClassName = pattern.test(currentName); + if (!!value === !this.invert) { + if (!includesClassName) { + this.node.className = "" + currentName + " " + name; + } + } else { + if (includesClassName) { + this.node.className = currentName.replace(pattern, ' '); + } + } + } + return true; + }; + + return AddClassBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.AbstractCollectionBinding = (function(_super) { + + __extends(AbstractCollectionBinding, _super); + + function AbstractCollectionBinding() { + return AbstractCollectionBinding.__super__.constructor.apply(this, arguments); + } + + AbstractCollectionBinding.prototype.bindCollection = function(newCollection) { + var _ref; + if (newCollection instanceof Batman.Hash) { + newCollection = newCollection.meta; + } + if (newCollection === this.collection) { + return true; + } else { + this.unbindCollection(); + this.collection = newCollection; + if ((_ref = this.collection) != null ? _ref.isObservable : void 0) { + this.collection.observeAndFire('toArray', this.handleArrayChanged); + return true; + } + } + return false; + }; + + AbstractCollectionBinding.prototype.unbindCollection = function() { + var _ref; + if ((_ref = this.collection) != null ? _ref.isObservable : void 0) { + return this.collection.forget('toArray', this.handleArrayChanged); + } + }; + + AbstractCollectionBinding.prototype.handleArrayChanged = function() {}; + + AbstractCollectionBinding.prototype.die = function() { + this.unbindCollection(); + return AbstractCollectionBinding.__super__.die.apply(this, arguments); + }; + + return AbstractCollectionBinding; + + })(Batman.DOM.AbstractAttributeBinding); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }, + __slice = [].slice; + + Batman.DOM.StyleBinding = (function(_super) { + + __extends(StyleBinding, _super); + + StyleBinding.SingleStyleBinding = (function(_super1) { + + __extends(SingleStyleBinding, _super1); + + SingleStyleBinding.prototype.isTwoWay = function() { + return false; + }; + + function SingleStyleBinding() { + var args, parent, _i; + args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), parent = arguments[_i++]; + this.parent = parent; + SingleStyleBinding.__super__.constructor.apply(this, args); + } + + SingleStyleBinding.prototype.dataChange = function(value) { + return this.parent.setStyle(this.attributeName, value); + }; + + return SingleStyleBinding; + + })(Batman.DOM.AbstractAttributeBinding); + + function StyleBinding() { + this.setStyle = __bind(this.setStyle, this); + + this.handleArrayChanged = __bind(this.handleArrayChanged, this); + this.oldStyles = {}; + this.styleBindings = {}; + StyleBinding.__super__.constructor.apply(this, arguments); + } + + StyleBinding.prototype.dataChange = function(value) { + var colonSplitCSSValues, cssName, key, style, _i, _len, _ref, _ref1, _results; + if (!value) { + this.resetStyles(); + return; + } + this.unbindCollection(); + if (typeof value === 'string') { + this.resetStyles(); + _ref = value.split(';'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + style = _ref[_i]; + _ref1 = style.split(":"), cssName = _ref1[0], colonSplitCSSValues = 2 <= _ref1.length ? __slice.call(_ref1, 1) : []; + this.setStyle(cssName, colonSplitCSSValues.join(":")); + } + return; + } + if (value instanceof Batman.Hash) { + return this.bindCollection(value); + } else { + if (value instanceof Batman.Object) { + value = value.toJSON(); + } + this.resetStyles(); + _results = []; + for (key in value) { + if (!__hasProp.call(value, key)) continue; + _results.push(this.bindSingleAttribute(key, "" + this.keyPath + "." + key)); + } + return _results; + } + }; + + StyleBinding.prototype.handleArrayChanged = function(array) { + var _this = this; + return this.collection.forEach(function(key, value) { + return _this.bindSingleAttribute(key, "" + _this.keyPath + "." + key); + }); + }; + + StyleBinding.prototype.bindSingleAttribute = function(attr, keyPath) { + return this.styleBindings[attr] = new this.constructor.SingleStyleBinding(this.node, attr, keyPath, this.renderContext, this.renderer, this.only, this); + }; + + StyleBinding.prototype.setStyle = function(key, value) { + key = Batman.helpers.camelize(key.trim(), true); + if (this.oldStyles[key] == null) { + this.oldStyles[key] = this.node.style[key] || ""; + } + if (value != null ? value.trim : void 0) { + value = value.trim(); + } + if (value == null) { + value = ""; + } + return this.node.style[key] = value; + }; + + StyleBinding.prototype.resetStyles = function() { + var cssName, cssValue, _ref, _results; + _ref = this.oldStyles; + _results = []; + for (cssName in _ref) { + if (!__hasProp.call(_ref, cssName)) continue; + cssValue = _ref[cssName]; + _results.push(this.setStyle(cssName, cssValue)); + } + return _results; + }; + + StyleBinding.prototype.resetBindings = function() { + var attribute, binding, _ref; + _ref = this.styleBindings; + for (attribute in _ref) { + binding = _ref[attribute]; + binding._fireDataChange(''); + binding.die(); + } + return this.styleBindings = {}; + }; + + StyleBinding.prototype.unbindCollection = function() { + this.resetBindings(); + return StyleBinding.__super__.unbindCollection.apply(this, arguments); + }; + + return StyleBinding; + + })(Batman.DOM.AbstractCollectionBinding); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.DOM.IteratorBinding = (function(_super) { + + __extends(IteratorBinding, _super); + + IteratorBinding.prototype.currentActionNumber = 0; + + IteratorBinding.prototype.queuedActionNumber = 0; + + IteratorBinding.prototype.bindImmediately = false; + + function IteratorBinding(sourceNode, iteratorName, key, context, parentRenderer) { + var previousSiblingNode, + _this = this; + this.iteratorName = iteratorName; + this.key = key; + this.context = context; + this.parentRenderer = parentRenderer; + this.handleArrayChanged = __bind(this.handleArrayChanged, this); + + this.nodeMap = new Batman.SimpleHash; + this.rendererMap = new Batman.SimpleHash; + this.fragment = document.createDocumentFragment(); + this.prototypeNode = sourceNode.cloneNode(true); + this.prototypeNode.removeAttribute("data-foreach-" + this.iteratorName); + previousSiblingNode = sourceNode.nextSibling; + this.startNode = document.createComment("start " + this.iteratorName + "-" + (this.get('_batmanID'))); + this.endNode = document.createComment("end " + this.iteratorName + "-" + (this.get('_batmanID'))); + this.endNode[Batman.expando] = sourceNode[Batman.expando]; + if (Batman.canDeleteExpando) { + delete sourceNode[Batman.expando]; + } + Batman.insertBefore(sourceNode.parentNode, this.startNode, previousSiblingNode); + Batman.insertBefore(sourceNode.parentNode, this.endNode, previousSiblingNode); + this.parentRenderer.prevent('rendered'); + Batman.DOM.onParseExit(sourceNode.parentNode, function() { + Batman.destroyNode(sourceNode); + _this.bind(); + return _this.parentRenderer.allowAndFire('rendered'); + }); + IteratorBinding.__super__.constructor.call(this, this.endNode, this.iteratorName, this.key, this.context, this.parentRenderer); + } + + IteratorBinding.prototype.parentNode = function() { + return this.endNode.parentNode; + }; + + IteratorBinding.prototype.die = function() { + this.dead = true; + return IteratorBinding.__super__.die.apply(this, arguments); + }; + + IteratorBinding.prototype.dataChange = function(collection) { + var items, _items; + if (collection != null) { + if (!this.bindCollection(collection)) { + items = (collection != null ? collection.forEach : void 0) ? (_items = [], collection.forEach(function(item) { + return _items.push(item); + }), _items) : Object.keys(collection); + return this.handleArrayChanged(items); + } + } else { + return this.handleArrayChanged([]); + } + }; + + IteratorBinding.prototype.handleArrayChanged = function(newItems) { + var existingNode, index, newItem, node, nodeAtIndex, parentNode, startIndex, unseenNodeMap, _i, _len, + _this = this; + parentNode = this.parentNode(); + startIndex = this._getStartNodeIndex() + 1; + unseenNodeMap = this.nodeMap.merge(); + for (index = _i = 0, _len = newItems.length; _i < _len; index = ++_i) { + newItem = newItems[index]; + nodeAtIndex = parentNode.childNodes[startIndex + index]; + if ((nodeAtIndex != null) && this._itemForNode(nodeAtIndex) === newItem) { + unseenNodeMap.unset(newItem); + continue; + } else { + node = (existingNode = this.nodeMap.get(newItem)) ? (unseenNodeMap.unset(newItem), existingNode) : this._newNodeForItem(newItem); + Batman.insertBefore(this.parentNode(), node, nodeAtIndex); + } + } + unseenNodeMap.forEach(function(item, node) { + return _this._removeItem(item); + }); + }; + + IteratorBinding.prototype._itemForNode = function(node) { + return Batman._data(node, "" + this.iteratorName + "Item"); + }; + + IteratorBinding.prototype._newNodeForItem = function(newItem) { + var newNode, renderer, + _this = this; + newNode = this.prototypeNode.cloneNode(true); + Batman._data(newNode, "" + this.iteratorName + "Item", newItem); + this.nodeMap.set(newItem, newNode); + this.parentRenderer.prevent('rendered'); + renderer = new Batman.Renderer(newNode, this.renderContext.descend(newItem, this.iteratorName), this.parentRenderer.view); + renderer.on('rendered', function() { + Batman.propagateBindingEvents(newNode); + _this.fire('nodeAdded', newNode, newItem); + return _this.parentRenderer.allowAndFire('rendered'); + }); + return newNode; + }; + + IteratorBinding.prototype._getStartNodeIndex = function() { + var index, node, _i, _len, _ref; + _ref = this.parentNode().childNodes; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + node = _ref[index]; + if (node === this.startNode) { + return index; + } + } + return 0; + }; + + IteratorBinding.prototype._removeItem = function(item) { + var node; + node = this.nodeMap.unset(item); + Batman.destroyNode(node); + return this.fire('nodeRemoved', node, item); + }; + + return IteratorBinding; + + })(Batman.DOM.AbstractCollectionBinding); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.DOM.ClassBinding = (function(_super) { + + __extends(ClassBinding, _super); + + function ClassBinding() { + this.handleArrayChanged = __bind(this.handleArrayChanged, this); + return ClassBinding.__super__.constructor.apply(this, arguments); + } + + ClassBinding.prototype.dataChange = function(value) { + if (value != null) { + this.unbindCollection(); + if (typeof value === 'string') { + return this.node.className = value; + } else { + this.bindCollection(value); + return this.updateFromCollection(); + } + } + }; + + ClassBinding.prototype.updateFromCollection = function() { + var array, k, v; + if (this.collection) { + array = this.collection.map ? this.collection.map(function(x) { + return x; + }) : (function() { + var _ref, _results; + _ref = this.collection; + _results = []; + for (k in _ref) { + if (!__hasProp.call(_ref, k)) continue; + v = _ref[k]; + _results.push(k); + } + return _results; + }).call(this); + if (array.toArray != null) { + array = array.toArray(); + } + return this.node.className = array.join(' '); + } + }; + + ClassBinding.prototype.handleArrayChanged = function() { + return this.updateFromCollection(); + }; + + return ClassBinding; + + })(Batman.DOM.AbstractCollectionBinding); + +}).call(this); + +(function() { + var __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; }; + + Batman.ValidationError = (function(_super) { + + __extends(ValidationError, _super); + + ValidationError.accessor('fullMessage', function() { + return Batman.t('errors.format', { + attribute: Batman.helpers.humanize(this.attribute), + message: this.message + }); + }); + + function ValidationError(attribute, message) { + ValidationError.__super__.constructor.call(this, { + attribute: attribute, + message: message + }); + } + + return ValidationError; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.StorageAdapter = (function(_super) { + + __extends(StorageAdapter, _super); + + StorageAdapter.StorageError = (function(_super1) { + + __extends(StorageError, _super1); + + StorageError.prototype.name = "StorageError"; + + function StorageError(message) { + StorageError.__super__.constructor.apply(this, arguments); + this.message = message; + } + + return StorageError; + + })(Error); + + StorageAdapter.RecordExistsError = (function(_super1) { + + __extends(RecordExistsError, _super1); + + RecordExistsError.prototype.name = 'RecordExistsError'; + + function RecordExistsError(message) { + RecordExistsError.__super__.constructor.call(this, message || "Can't create this record because it already exists in the store!"); + } + + return RecordExistsError; + + })(StorageAdapter.StorageError); + + StorageAdapter.NotFoundError = (function(_super1) { + + __extends(NotFoundError, _super1); + + NotFoundError.prototype.name = 'NotFoundError'; + + function NotFoundError(message) { + NotFoundError.__super__.constructor.call(this, message || "Record couldn't be found in storage!"); + } + + return NotFoundError; + + })(StorageAdapter.StorageError); + + function StorageAdapter(model) { + var constructor; + StorageAdapter.__super__.constructor.call(this, { + model: model + }); + constructor = this.constructor; + if (constructor.ModelMixin) { + Batman.extend(model, constructor.ModelMixin); + } + if (constructor.RecordMixin) { + Batman.extend(model.prototype, constructor.RecordMixin); + } + } + + StorageAdapter.prototype.isStorageAdapter = true; + + StorageAdapter.prototype.storageKey = function(record) { + var model; + model = (record != null ? record.constructor : void 0) || this.model; + return model.get('storageKey') || Batman.helpers.pluralize(Batman.helpers.underscore(model.get('resourceName'))); + }; + + StorageAdapter.prototype.getRecordFromData = function(attributes, constructor) { + var record; + if (constructor == null) { + constructor = this.model; + } + record = new constructor(); + record._withoutDirtyTracking(function() { + return this.fromJSON(attributes); + }); + return record; + }; + + StorageAdapter.skipIfError = function(f) { + return function(env, next) { + if (env.error != null) { + return next(); + } else { + return f.call(this, env, next); + } + }; + }; + + StorageAdapter.prototype.before = function() { + return this._addFilter.apply(this, ['before'].concat(__slice.call(arguments))); + }; + + StorageAdapter.prototype.after = function() { + return this._addFilter.apply(this, ['after'].concat(__slice.call(arguments))); + }; + + StorageAdapter.prototype._inheritFilters = function() { + var filtersByKey, filtersList, key, oldFilters, position, _results; + if (!this._batman.check(this) || !this._batman.filters) { + oldFilters = this._batman.getFirst('filters'); + this._batman.filters = { + before: {}, + after: {} + }; + if (oldFilters != null) { + _results = []; + for (position in oldFilters) { + filtersByKey = oldFilters[position]; + _results.push((function() { + var _results1; + _results1 = []; + for (key in filtersByKey) { + filtersList = filtersByKey[key]; + _results1.push(this._batman.filters[position][key] = filtersList.slice(0)); + } + return _results1; + }).call(this)); + } + return _results; + } + } + }; + + StorageAdapter.prototype._addFilter = function() { + var filter, key, keys, position, _base, _i, _j, _len; + position = arguments[0], keys = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), filter = arguments[_i++]; + this._inheritFilters(); + for (_j = 0, _len = keys.length; _j < _len; _j++) { + key = keys[_j]; + (_base = this._batman.filters[position])[key] || (_base[key] = []); + this._batman.filters[position][key].push(filter); + } + return true; + }; + + StorageAdapter.prototype.runFilter = function(position, action, env, callback) { + var actionFilters, allFilters, filters, next, + _this = this; + this._inheritFilters(); + allFilters = this._batman.filters[position].all || []; + actionFilters = this._batman.filters[position][action] || []; + env.action = action; + filters = position === 'before' ? actionFilters.concat(allFilters) : allFilters.concat(actionFilters); + next = function(newEnv) { + var nextFilter; + if (newEnv != null) { + env = newEnv; + } + if ((nextFilter = filters.shift()) != null) { + return nextFilter.call(_this, env, next); + } else { + return callback.call(_this, env); + } + }; + return next(); + }; + + StorageAdapter.prototype.runBeforeFilter = function() { + return this.runFilter.apply(this, ['before'].concat(__slice.call(arguments))); + }; + + StorageAdapter.prototype.runAfterFilter = function(action, env, callback) { + return this.runFilter('after', action, env, this.exportResult(callback)); + }; + + StorageAdapter.prototype.exportResult = function(callback) { + return function(env) { + return callback(env.error, env.result, env); + }; + }; + + StorageAdapter.prototype._jsonToAttributes = function(json) { + return JSON.parse(json); + }; + + StorageAdapter.prototype.perform = function(key, subject, options, callback) { + var env, next, + _this = this; + options || (options = {}); + env = { + options: options, + subject: subject + }; + next = function(newEnv) { + if (newEnv != null) { + env = newEnv; + } + return _this.runAfterFilter(key, env, callback); + }; + return this.runBeforeFilter(key, env, function(env) { + return this[key](env, next); + }); + }; + + return StorageAdapter; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Batman.RestStorage = (function(_super) { + var key, _fn, _i, _len, _ref, + _this = this; + + __extends(RestStorage, _super); + + RestStorage.JSONContentType = 'application/json'; + + RestStorage.PostBodyContentType = 'application/x-www-form-urlencoded'; + + RestStorage.BaseMixin = { + request: function(action, options, callback) { + if (!callback) { + callback = options; + options = {}; + } + options.method || (options.method = 'GET'); + options.action = action; + return this._doStorageOperation(options.method.toLowerCase(), options, callback); + } + }; + + RestStorage.ModelMixin = Batman.extend({}, RestStorage.BaseMixin, { + urlNestsUnder: function() { + var key, keys, parents, _i, _len; + keys = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + parents = {}; + for (_i = 0, _len = keys.length; _i < _len; _i++) { + key = keys[_i]; + parents[key + '_id'] = Batman.helpers.pluralize(key); + } + this.url = function(options) { + var childSegment, parentID, plural; + childSegment = Batman.helpers.pluralize(this.get('resourceName').toLowerCase()); + for (key in parents) { + plural = parents[key]; + parentID = options.data[key]; + if (parentID) { + delete options.data[key]; + return "" + plural + "/" + parentID + "/" + childSegment; + } + } + return childSegment; + }; + return this.prototype.url = function() { + var childSegment, id, parentID, plural, url; + childSegment = Batman.helpers.pluralize(this.constructor.get('resourceName').toLowerCase()); + for (key in parents) { + plural = parents[key]; + parentID = this.get('dirtyKeys').get(key); + if (parentID === void 0) { + parentID = this.get(key); + } + if (parentID) { + url = "" + plural + "/" + parentID + "/" + childSegment; + break; + } + } + url || (url = childSegment); + if (id = this.get('id')) { + url += '/' + id; + } + return url; + }; + } + }); + + RestStorage.RecordMixin = Batman.extend({}, RestStorage.BaseMixin); + + RestStorage.prototype.defaultRequestOptions = { + type: 'json' + }; + + RestStorage.prototype._implicitActionNames = ['create', 'read', 'update', 'destroy', 'readAll']; + + RestStorage.prototype.serializeAsForm = true; + + function RestStorage() { + RestStorage.__super__.constructor.apply(this, arguments); + this.defaultRequestOptions = Batman.extend({}, this.defaultRequestOptions); + } + + RestStorage.prototype.recordJsonNamespace = function(record) { + return Batman.helpers.singularize(this.storageKey(record)); + }; + + RestStorage.prototype.collectionJsonNamespace = function(constructor) { + return Batman.helpers.pluralize(this.storageKey(constructor.prototype)); + }; + + RestStorage.prototype._execWithOptions = function(object, key, options) { + if (typeof object[key] === 'function') { + return object[key](options); + } else { + return object[key]; + } + }; + + RestStorage.prototype._defaultCollectionUrl = function(model) { + return "/" + (this.storageKey(model.prototype)); + }; + + RestStorage.prototype._addParams = function(url, options) { + var _ref; + if (options && options.action && !(_ref = options.action, __indexOf.call(this._implicitActionNames, _ref) >= 0)) { + url += '/' + options.action.toLowerCase(); + } + return url; + }; + + RestStorage.prototype.urlForRecord = function(record, env) { + var id, url; + if (record.url) { + url = this._execWithOptions(record, 'url', env.options); + } else { + url = record.constructor.url ? this._execWithOptions(record.constructor, 'url', env.options) : this._defaultCollectionUrl(record.constructor); + if (env.action !== 'create') { + if ((id = record.get('id')) != null) { + url = url + "/" + id; + } else { + throw new this.constructor.StorageError("Couldn't get/set record primary key on " + env.action + "!"); + } + } + } + url = this._addParams(url, env.options); + return this.urlPrefix(record, env) + url + this.urlSuffix(record, env); + }; + + RestStorage.prototype.urlForCollection = function(model, env) { + var url; + url = model.url ? this._execWithOptions(model, 'url', env.options) : this._defaultCollectionUrl(model, env.options); + url = this._addParams(url, env.options); + return this.urlPrefix(model, env) + url + this.urlSuffix(model, env); + }; + + RestStorage.prototype.urlPrefix = function(object, env) { + return this._execWithOptions(object, 'urlPrefix', env.options) || ''; + }; + + RestStorage.prototype.urlSuffix = function(object, env) { + return this._execWithOptions(object, 'urlSuffix', env.options) || ''; + }; + + RestStorage.prototype.request = function(env, next) { + var options; + options = Batman.extend(env.options, { + autosend: false, + success: function(data) { + return env.data = data; + }, + error: function(error) { + return env.error = error; + }, + loaded: function() { + env.response = env.request.get('response'); + return next(); + } + }); + env.request = new Batman.Request(options); + return env.request.send(); + }; + + RestStorage.prototype.perform = function(key, record, options, callback) { + options || (options = {}); + Batman.extend(options, this.defaultRequestOptions); + return RestStorage.__super__.perform.call(this, key, record, options, callback); + }; + + RestStorage.prototype.before('all', RestStorage.skipIfError(function(env, next) { + if (!env.options.url) { + try { + env.options.url = env.subject.prototype ? this.urlForCollection(env.subject, env) : this.urlForRecord(env.subject, env); + } catch (error) { + env.error = error; + } + } + return next(); + })); + + RestStorage.prototype.before('get', 'put', 'post', 'delete', RestStorage.skipIfError(function(env, next) { + env.options.method = env.action.toUpperCase(); + return next(); + })); + + RestStorage.prototype.before('create', 'update', RestStorage.skipIfError(function(env, next) { + var data, json, namespace; + json = env.subject.toJSON(); + if (namespace = this.recordJsonNamespace(env.subject)) { + data = {}; + data[namespace] = json; + } else { + data = json; + } + env.options.data = data; + return next(); + })); + + RestStorage.prototype.before('create', 'update', 'put', 'post', RestStorage.skipIfError(function(env, next) { + if (this.serializeAsForm) { + env.options.contentType = this.constructor.PostBodyContentType; + } else { + if (env.options.data != null) { + env.options.data = JSON.stringify(env.options.data); + env.options.contentType = this.constructor.JSONContentType; + } + } + return next(); + })); + + RestStorage.prototype.after('all', RestStorage.skipIfError(function(env, next) { + var json; + if (!(env.data != null)) { + return next(); + } + if (typeof env.data === 'string') { + if (env.data.length > 0) { + try { + json = this._jsonToAttributes(env.data); + } catch (error) { + env.error = error; + return next(); + } + } + } else if (typeof env.data === 'object') { + json = env.data; + } + if (json != null) { + env.json = json; + } + return next(); + })); + + RestStorage.prototype.extractFromNamespace = function(data, namespace) { + if (namespace && (data[namespace] != null)) { + return data[namespace]; + } else { + return data; + } + }; + + RestStorage.prototype.after('create', 'read', 'update', RestStorage.skipIfError(function(env, next) { + var json; + if (env.json != null) { + json = this.extractFromNamespace(env.json, this.recordJsonNamespace(env.subject)); + env.subject._withoutDirtyTracking(function() { + return this.fromJSON(json); + }); + } + env.result = env.subject; + return next(); + })); + + RestStorage.prototype.after('readAll', RestStorage.skipIfError(function(env, next) { + var jsonRecordAttributes, namespace; + namespace = this.collectionJsonNamespace(env.subject); + env.recordsAttributes = this.extractFromNamespace(env.json, namespace); + if (Batman.typeOf(env.recordsAttributes) !== 'Array') { + namespace = this.recordJsonNamespace(env.subject.prototype); + env.recordsAttributes = [this.extractFromNamespace(env.json, namespace)]; + } + env.result = env.records = (function() { + var _i, _len, _ref, _results; + _ref = env.recordsAttributes; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + jsonRecordAttributes = _ref[_i]; + _results.push(this.getRecordFromData(jsonRecordAttributes, env.subject)); + } + return _results; + }).call(this); + return next(); + })); + + RestStorage.prototype.after('get', 'put', 'post', 'delete', RestStorage.skipIfError(function(env, next) { + var json, namespace; + if (env.json != null) { + json = env.json; + namespace = env.subject.prototype ? this.collectionJsonNamespace(env.subject) : this.recordJsonNamespace(env.subject); + env.result = namespace && (env.json[namespace] != null) ? env.json[namespace] : env.json; + } + return next(); + })); + + RestStorage.HTTPMethods = { + create: 'POST', + update: 'PUT', + read: 'GET', + readAll: 'GET', + destroy: 'DELETE' + }; + + _ref = ['create', 'read', 'update', 'destroy', 'readAll', 'get', 'post', 'put', 'delete']; + _fn = function(key) { + return RestStorage.prototype[key] = RestStorage.skipIfError(function(env, next) { + var _base; + (_base = env.options).method || (_base.method = this.constructor.HTTPMethods[key]); + return this.request(env, next); + }); + }; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + _fn(key); + } + + return RestStorage; + + }).call(this, Batman.StorageAdapter); + +}).call(this); + +(function() { + var __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; }; + + Batman.LocalStorage = (function(_super) { + + __extends(LocalStorage, _super); + + function LocalStorage() { + if (typeof window.localStorage === 'undefined') { + return null; + } + LocalStorage.__super__.constructor.apply(this, arguments); + this.storage = localStorage; + } + + LocalStorage.prototype.storageRegExpForRecord = function(record) { + return new RegExp("^" + (this.storageKey(record)) + "(\\d+)$"); + }; + + LocalStorage.prototype.nextIdForRecord = function(record) { + var nextId, re; + re = this.storageRegExpForRecord(record); + nextId = 1; + this._forAllStorageEntries(function(k, v) { + var matches; + if (matches = re.exec(k)) { + return nextId = Math.max(nextId, parseInt(matches[1], 10) + 1); + } + }); + return nextId; + }; + + LocalStorage.prototype._forAllStorageEntries = function(iterator) { + var i, key, _i, _ref; + for (i = _i = 0, _ref = this.storage.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + key = this.storage.key(i); + iterator.call(this, key, this.storage.getItem(key)); + } + return true; + }; + + LocalStorage.prototype._storageEntriesMatching = function(constructor, options) { + var re, records; + re = this.storageRegExpForRecord(constructor.prototype); + records = []; + this._forAllStorageEntries(function(storageKey, storageString) { + var data, keyMatches; + if (keyMatches = re.exec(storageKey)) { + data = this._jsonToAttributes(storageString); + data[constructor.primaryKey] = keyMatches[1]; + if (this._dataMatches(options, data)) { + return records.push(data); + } + } + }); + return records; + }; + + LocalStorage.prototype._dataMatches = function(conditions, data) { + var k, match, v; + match = true; + for (k in conditions) { + v = conditions[k]; + if (data[k] !== v) { + match = false; + break; + } + } + return match; + }; + + LocalStorage.prototype.before('read', 'create', 'update', 'destroy', LocalStorage.skipIfError(function(env, next) { + var _this = this; + if (env.action === 'create') { + env.id = env.subject.get('id') || env.subject._withoutDirtyTracking(function() { + return env.subject.set('id', _this.nextIdForRecord(env.subject)); + }); + } else { + env.id = env.subject.get('id'); + } + if (env.id == null) { + env.error = new this.constructor.StorageError("Couldn't get/set record primary key on " + env.action + "!"); + } else { + env.key = this.storageKey(env.subject) + env.id; + } + return next(); + })); + + LocalStorage.prototype.before('create', 'update', LocalStorage.skipIfError(function(env, next) { + env.recordAttributes = JSON.stringify(env.subject); + return next(); + })); + + LocalStorage.prototype.after('read', LocalStorage.skipIfError(function(env, next) { + if (typeof env.recordAttributes === 'string') { + try { + env.recordAttributes = this._jsonToAttributes(env.recordAttributes); + } catch (error) { + env.error = error; + return next(); + } + } + env.subject._withoutDirtyTracking(function() { + return this.fromJSON(env.recordAttributes); + }); + return next(); + })); + + LocalStorage.prototype.after('read', 'create', 'update', 'destroy', LocalStorage.skipIfError(function(env, next) { + env.result = env.subject; + return next(); + })); + + LocalStorage.prototype.after('readAll', LocalStorage.skipIfError(function(env, next) { + var recordAttributes; + env.result = env.records = (function() { + var _i, _len, _ref, _results; + _ref = env.recordsAttributes; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + recordAttributes = _ref[_i]; + _results.push(this.getRecordFromData(recordAttributes, env.subject)); + } + return _results; + }).call(this); + return next(); + })); + + LocalStorage.prototype.read = LocalStorage.skipIfError(function(env, next) { + env.recordAttributes = this.storage.getItem(env.key); + if (!env.recordAttributes) { + env.error = new this.constructor.NotFoundError(); + } + return next(); + }); + + LocalStorage.prototype.create = LocalStorage.skipIfError(function(_arg, next) { + var key, recordAttributes; + key = _arg.key, recordAttributes = _arg.recordAttributes; + if (this.storage.getItem(key)) { + arguments[0].error = new this.constructor.RecordExistsError; + } else { + this.storage.setItem(key, recordAttributes); + } + return next(); + }); + + LocalStorage.prototype.update = LocalStorage.skipIfError(function(_arg, next) { + var key, recordAttributes; + key = _arg.key, recordAttributes = _arg.recordAttributes; + this.storage.setItem(key, recordAttributes); + return next(); + }); + + LocalStorage.prototype.destroy = LocalStorage.skipIfError(function(_arg, next) { + var key; + key = _arg.key; + this.storage.removeItem(key); + return next(); + }); + + LocalStorage.prototype.readAll = LocalStorage.skipIfError(function(env, next) { + try { + arguments[0].recordsAttributes = this._storageEntriesMatching(env.subject, env.options.data); + } catch (error) { + arguments[0].error = error; + } + return next(); + }); + + return LocalStorage; + + })(Batman.StorageAdapter); + +}).call(this); + +(function() { + var __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; }; + + Batman.SessionStorage = (function(_super) { + + __extends(SessionStorage, _super); + + function SessionStorage() { + if (typeof window.sessionStorage === 'undefined') { + return null; + } + SessionStorage.__super__.constructor.apply(this, arguments); + this.storage = sessionStorage; + } + + return SessionStorage; + + })(Batman.LocalStorage); + +}).call(this); + +(function() { + + Batman.Encoders = new Batman.Object; + +}).call(this); + +(function() { + var __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; }; + + Batman.AssociationProxy = (function(_super) { + + __extends(AssociationProxy, _super); + + AssociationProxy.prototype.isProxy = true; + + function AssociationProxy(association, model) { + this.association = association; + this.model = model; + } + + AssociationProxy.prototype.loaded = false; + + AssociationProxy.prototype.toJSON = function() { + var target; + target = this.get('target'); + if (target != null) { + return this.get('target').toJSON(); + } + }; + + AssociationProxy.prototype.load = function(callback) { + var _this = this; + this.fetch(function(err, proxiedRecord) { + if (!err) { + _this.set('loaded', true); + _this.set('target', proxiedRecord); + } + return typeof callback === "function" ? callback(err, proxiedRecord) : void 0; + }); + return this.get('target'); + }; + + AssociationProxy.prototype.fetch = function(callback) { + var record; + if ((this.get('foreignValue') || this.get('primaryValue')) == null) { + return callback(void 0, void 0); + } + record = this.fetchFromLocal(); + if (record) { + return callback(void 0, record); + } else { + return this.fetchFromRemote(callback); + } + }; + + AssociationProxy.accessor('loaded', Batman.Property.defaultAccessor); + + AssociationProxy.accessor('target', { + get: function() { + return this.fetchFromLocal(); + }, + set: function(_, v) { + return v; + } + }); + + AssociationProxy.accessor({ + get: function(k) { + var _ref; + return (_ref = this.get('target')) != null ? _ref.get(k) : void 0; + }, + set: function(k, v) { + var _ref; + return (_ref = this.get('target')) != null ? _ref.set(k, v) : void 0; + } + }); + + return AssociationProxy; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.HasOneProxy = (function(_super) { + + __extends(HasOneProxy, _super); + + function HasOneProxy() { + return HasOneProxy.__super__.constructor.apply(this, arguments); + } + + HasOneProxy.accessor('primaryValue', function() { + return this.model.get(this.association.primaryKey); + }); + + HasOneProxy.prototype.fetchFromLocal = function() { + return this.association.setIndex().get(this.get('primaryValue')); + }; + + HasOneProxy.prototype.fetchFromRemote = function(callback) { + var loadOptions, + _this = this; + loadOptions = {}; + loadOptions[this.association.foreignKey] = this.get('primaryValue'); + return this.association.getRelatedModel().load(loadOptions, function(error, loadedRecords) { + if (error) { + throw error; + } + if (!loadedRecords || loadedRecords.length <= 0) { + return callback(new Error("Couldn't find related record!"), void 0); + } else { + return callback(void 0, loadedRecords[0]); + } + }); + }; + + return HasOneProxy; + + })(Batman.AssociationProxy); + +}).call(this); + +(function() { + var __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; }; + + Batman.BelongsToProxy = (function(_super) { + + __extends(BelongsToProxy, _super); + + function BelongsToProxy() { + return BelongsToProxy.__super__.constructor.apply(this, arguments); + } + + BelongsToProxy.accessor('foreignValue', function() { + return this.model.get(this.association.foreignKey); + }); + + BelongsToProxy.prototype.fetchFromLocal = function() { + return this.association.setIndex().get(this.get('foreignValue')); + }; + + BelongsToProxy.prototype.fetchFromRemote = function(callback) { + var _this = this; + return this.association.getRelatedModel().find(this.get('foreignValue'), function(error, loadedRecord) { + if (error) { + throw error; + } + return callback(void 0, loadedRecord); + }); + }; + + return BelongsToProxy; + + })(Batman.AssociationProxy); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicBelongsToProxy = (function(_super) { + + __extends(PolymorphicBelongsToProxy, _super); + + function PolymorphicBelongsToProxy() { + return PolymorphicBelongsToProxy.__super__.constructor.apply(this, arguments); + } + + PolymorphicBelongsToProxy.accessor('foreignTypeValue', function() { + return this.model.get(this.association.foreignTypeKey); + }); + + PolymorphicBelongsToProxy.prototype.fetchFromLocal = function() { + return this.association.setIndexForType(this.get('foreignTypeValue')).get(this.get('foreignValue')); + }; + + PolymorphicBelongsToProxy.prototype.fetchFromRemote = function(callback) { + var _this = this; + return this.association.getRelatedModelForType(this.get('foreignTypeValue')).find(this.get('foreignValue'), function(error, loadedRecord) { + if (error) { + throw error; + } + return callback(void 0, loadedRecord); + }); + }; + + return PolymorphicBelongsToProxy; + + })(Batman.BelongsToProxy); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.StateMachine = (function(_super) { + + __extends(StateMachine, _super); + + StateMachine.InvalidTransitionError = function(message) { + this.message = message != null ? message : ""; + }; + + StateMachine.InvalidTransitionError.prototype = new Error; + + StateMachine.transitions = function(table) { + var definePredicate, fromState, k, object, predicateKeys, toState, transitions, v, _fn, _ref, + _this = this; + for (k in table) { + v = table[k]; + if (!(v.from && v.to)) { + continue; + } + object = {}; + if (v.from.forEach) { + v.from.forEach(function(fromKey) { + return object[fromKey] = v.to; + }); + } else { + object[v.from] = v.to; + } + table[k] = object; + } + this.prototype.transitionTable = Batman.extend({}, this.prototype.transitionTable, table); + predicateKeys = []; + definePredicate = function(state) { + var key; + key = "is" + (Batman.helpers.capitalize(state)); + if (_this.prototype[key] != null) { + return; + } + predicateKeys.push(key); + return _this.prototype[key] = function() { + return this.get('state') === state; + }; + }; + _ref = this.prototype.transitionTable; + _fn = function(k) { + return _this.prototype[k] = function() { + return this.startTransition(k); + }; + }; + for (k in _ref) { + transitions = _ref[k]; + if (!(!this.prototype[k])) { + continue; + } + _fn(k); + for (fromState in transitions) { + toState = transitions[fromState]; + definePredicate(fromState); + definePredicate(toState); + } + } + if (predicateKeys.length) { + this.accessor.apply(this, __slice.call(predicateKeys).concat([function(key) { + return this[key](); + }])); + } + return this; + }; + + function StateMachine(startState) { + this.nextEvents = []; + this.set('_state', startState); + } + + StateMachine.accessor('state', function() { + return this.get('_state'); + }); + + StateMachine.prototype.isTransitioning = false; + + StateMachine.prototype.transitionTable = {}; + + StateMachine.prototype.onTransition = function(from, into, callback) { + return this.on("" + from + "->" + into, callback); + }; + + StateMachine.prototype.onEnter = function(into, callback) { + return this.on("enter " + into, callback); + }; + + StateMachine.prototype.onExit = function(from, callback) { + return this.on("exit " + from, callback); + }; + + StateMachine.prototype.startTransition = Batman.Property.wrapTrackingPrevention(function(event) { + var nextState, previousState; + if (this.isTransitioning) { + this.nextEvents.push(event); + return; + } + previousState = this.get('state'); + nextState = this.nextStateForEvent(event); + if (!nextState) { + return false; + } + this.isTransitioning = true; + this.fire("exit " + previousState); + this.set('_state', nextState); + this.fire("" + previousState + "->" + nextState); + this.fire("enter " + nextState); + this.fire(event); + this.isTransitioning = false; + if (this.nextEvents.length > 0) { + this.startTransition(this.nextEvents.shift()); + } + return true; + }); + + StateMachine.prototype.canStartTransition = function(event, fromState) { + if (fromState == null) { + fromState = this.get('state'); + } + return !!this.nextStateForEvent(event, fromState); + }; + + StateMachine.prototype.nextStateForEvent = function(event, fromState) { + var _ref; + if (fromState == null) { + fromState = this.get('state'); + } + return (_ref = this.transitionTable[event]) != null ? _ref[fromState] : void 0; + }; + + return StateMachine; + + })(Batman.Object); + + Batman.DelegatingStateMachine = (function(_super) { + + __extends(DelegatingStateMachine, _super); + + function DelegatingStateMachine(startState, base) { + this.base = base; + DelegatingStateMachine.__super__.constructor.call(this, startState); + } + + DelegatingStateMachine.prototype.fire = function() { + var result, _ref; + result = DelegatingStateMachine.__super__.fire.apply(this, arguments); + (_ref = this.base).fire.apply(_ref, arguments); + return result; + }; + + return DelegatingStateMachine; + + })(Batman.StateMachine); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }, + __slice = [].slice; + + Batman.Model = (function(_super) { + var functionName, _i, _j, _len, _len1, _ref, _ref1; + + __extends(Model, _super); + + Model.primaryKey = 'id'; + + Model.storageKey = null; + + Model.persist = function(mechanism, options) { + Batman.initializeObject(this.prototype); + mechanism = mechanism.isStorageAdapter ? mechanism : new mechanism(this); + if (options) { + Batman.mixin(mechanism, options); + } + this.prototype._batman.storage = mechanism; + return mechanism; + }; + + Model.storageAdapter = function() { + Batman.initializeObject(this.prototype); + return this.prototype._batman.storage; + }; + + Model.encode = function() { + var encoder, encoderForKey, encoderOrLastKey, key, keys, _base, _i, _j, _len; + keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), encoderOrLastKey = arguments[_i++]; + Batman.initializeObject(this.prototype); + (_base = this.prototype._batman).encoders || (_base.encoders = new Batman.SimpleHash); + encoder = {}; + switch (Batman.typeOf(encoderOrLastKey)) { + case 'String': + keys.push(encoderOrLastKey); + break; + case 'Function': + encoder.encode = encoderOrLastKey; + break; + default: + encoder = encoderOrLastKey; + } + for (_j = 0, _len = keys.length; _j < _len; _j++) { + key = keys[_j]; + encoderForKey = Batman.extend({ + as: key + }, this.defaultEncoder, encoder); + this.prototype._batman.encoders.set(key, encoderForKey); + } + }; + + Model.defaultEncoder = { + encode: function(x) { + return x; + }, + decode: function(x) { + return x; + } + }; + + Model.observeAndFire('primaryKey', function(newPrimaryKey, oldPrimaryKey) { + this.encode(oldPrimaryKey, { + encode: false, + decode: false + }); + return this.encode(newPrimaryKey, { + encode: false, + decode: this.defaultEncoder.decode + }); + }); + + Model.validate = function() { + var keys, match, matches, options, optionsOrFunction, validator, validators, _base, _i, _j, _k, _len, _len1, _ref, _results; + keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), optionsOrFunction = arguments[_i++]; + Batman.initializeObject(this.prototype); + validators = (_base = this.prototype._batman).validators || (_base.validators = []); + if (typeof optionsOrFunction === 'function') { + return validators.push({ + keys: keys, + callback: optionsOrFunction + }); + } else { + options = optionsOrFunction; + _ref = Batman.Validators; + _results = []; + for (_j = 0, _len = _ref.length; _j < _len; _j++) { + validator = _ref[_j]; + if ((matches = validator.matches(options))) { + for (_k = 0, _len1 = matches.length; _k < _len1; _k++) { + match = matches[_k]; + delete options[match]; + } + _results.push(validators.push({ + keys: keys, + validator: new validator(matches) + })); + } else { + _results.push(void 0); + } + } + return _results; + } + }; + + Model.LifecycleStateMachine = (function(_super1) { + + __extends(LifecycleStateMachine, _super1); + + function LifecycleStateMachine() { + return LifecycleStateMachine.__super__.constructor.apply(this, arguments); + } + + LifecycleStateMachine.transitions({ + load: { + empty: 'loading', + loaded: 'loading', + loading: 'loading' + }, + loaded: { + loading: 'loaded' + }, + error: { + loading: 'error' + } + }); + + return LifecycleStateMachine; + + })(Batman.DelegatingStateMachine); + + Model.classAccessor('lifecycle', function() { + var _base; + this._batman.check(this); + return (_base = this._batman).lifecycle || (_base.lifecycle = new this.LifecycleStateMachine('empty', this)); + }); + + Model.classAccessor('resourceName', { + get: function() { + if (this.resourceName != null) { + return this.resourceName; + } else { + if (Batman.config.minificationErrors) { + Batman.developer.error("Please define " + (Batman.functionName(this)) + ".resourceName in order for your model to be minification safe."); + } + return Batman.helpers.underscore(Batman.functionName(this)); + } + } + }); + + Model.classAccessor('all', { + get: function() { + this._batman.check(this); + if (this.prototype.hasStorage() && !this._batman.allLoadTriggered) { + this.load(); + this._batman.allLoadTriggered = true; + } + return this.get('loaded'); + }, + set: function(k, v) { + return this.set('loaded', v); + } + }); + + Model.classAccessor('loaded', { + get: function() { + return this._loaded || (this._loaded = new Batman.Set); + }, + set: function(k, v) { + return this._loaded = v; + } + }); + + Model.classAccessor('first', function() { + return this.get('all').toArray()[0]; + }); + + Model.classAccessor('last', function() { + var x; + x = this.get('all').toArray(); + return x[x.length - 1]; + }); + + Model.clear = function() { + var result, _ref; + Batman.initializeObject(this); + result = this.get('loaded').clear(); + if ((_ref = this._batman.get('associations')) != null) { + _ref.reset(); + } + return result; + }; + + Model.find = function(id, callback) { + var record; + Batman.developer.assert(callback, "Must call find with a callback!"); + record = new this(); + record._withoutDirtyTracking(function() { + return this.set('id', id); + }); + record.load(callback); + return record; + }; + + Model.load = function(options, callback) { + var lifecycle, _ref, + _this = this; + if ((_ref = typeof options) === 'function' || _ref === 'undefined') { + callback = options; + options = {}; + } + lifecycle = this.get('lifecycle'); + if (lifecycle.load()) { + return this._doStorageOperation('readAll', { + data: options + }, function(err, records, env) { + var mappedRecords, record; + if (err != null) { + lifecycle.error(); + return typeof callback === "function" ? callback(err, []) : void 0; + } else { + mappedRecords = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = records.length; _i < _len; _i++) { + record = records[_i]; + _results.push(this._mapIdentity(record)); + } + return _results; + }).call(_this); + lifecycle.loaded(); + return typeof callback === "function" ? callback(err, mappedRecords, env) : void 0; + } + }); + } else { + return callback(new Batman.StateMachine.InvalidTransitionError("Can't load while in state " + (lifecycle.get('state')))); + } + }; + + Model.create = function(attrs, callback) { + var obj, _ref; + if (!callback) { + _ref = [{}, attrs], attrs = _ref[0], callback = _ref[1]; + } + obj = new this(attrs); + obj.save(callback); + return obj; + }; + + Model.findOrCreate = function(attrs, callback) { + var foundRecord, record; + record = new this(attrs); + if (record.isNew()) { + record.save(callback); + } else { + foundRecord = this._mapIdentity(record); + callback(void 0, foundRecord); + } + return record; + }; + + Model._mapIdentity = function(record) { + var existing, id, _ref; + if (typeof (id = record.get('id')) === 'undefined' || id === '') { + return record; + } else { + existing = (_ref = this.get("loaded.indexedBy.id").get(id)) != null ? _ref.toArray()[0] : void 0; + if (existing) { + existing._withoutDirtyTracking(function() { + var _ref1; + return this.updateAttributes(((_ref1 = record.get('attributes')) != null ? _ref1.toObject() : void 0) || {}); + }); + return existing; + } else { + this.get('loaded').add(record); + return record; + } + } + }; + + Model._doStorageOperation = function(operation, options, callback) { + var adapter; + Batman.developer.assert(this.prototype.hasStorage(), "Can't " + operation + " model " + (Batman.functionName(this.constructor)) + " without any storage adapters!"); + adapter = this.prototype._batman.get('storage'); + return adapter.perform(operation, this, options, callback); + }; + + _ref = ['find', 'load', 'create']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + functionName = _ref[_i]; + Model[functionName] = Batman.Property.wrapTrackingPrevention(Model[functionName]); + } + + Model.InstanceLifecycleStateMachine = (function(_super1) { + + __extends(InstanceLifecycleStateMachine, _super1); + + function InstanceLifecycleStateMachine() { + return InstanceLifecycleStateMachine.__super__.constructor.apply(this, arguments); + } + + InstanceLifecycleStateMachine.transitions({ + load: { + from: ['dirty', 'clean'], + to: 'loading' + }, + create: { + from: ['dirty', 'clean'], + to: 'creating' + }, + save: { + from: ['dirty', 'clean'], + to: 'saving' + }, + destroy: { + from: ['dirty', 'clean'], + to: 'destroying' + }, + failedValidation: { + from: ['saving', 'creating'], + to: 'dirty' + }, + loaded: { + loading: 'clean' + }, + created: { + creating: 'clean' + }, + saved: { + saving: 'clean' + }, + destroyed: { + destroying: 'destroyed' + }, + set: { + from: ['dirty', 'clean'], + to: 'dirty' + }, + error: { + from: ['saving', 'creating', 'loading', 'destroying'], + to: 'error' + } + }); + + return InstanceLifecycleStateMachine; + + })(Batman.DelegatingStateMachine); + + function Model(idOrAttributes) { + if (idOrAttributes == null) { + idOrAttributes = {}; + } + this.destroy = __bind(this.destroy, this); + + this.save = __bind(this.save, this); + + this.load = __bind(this.load, this); + + Batman.developer.assert(this instanceof Batman.Object, "constructors must be called with new"); + if (Batman.typeOf(idOrAttributes) === 'Object') { + Model.__super__.constructor.call(this, idOrAttributes); + } else { + Model.__super__.constructor.call(this); + this.set('id', idOrAttributes); + } + } + + Model.accessor('lifecycle', function() { + return this.lifecycle || (this.lifecycle = new Batman.Model.InstanceLifecycleStateMachine('clean', this)); + }); + + Model.accessor('attributes', function() { + return this.attributes || (this.attributes = new Batman.Hash); + }); + + Model.accessor('dirtyKeys', function() { + return this.dirtyKeys || (this.dirtyKeys = new Batman.Hash); + }); + + Model.accessor('_dirtiedKeys', function() { + return this._dirtiedKeys || (this._dirtiedKeys = new Batman.SimpleSet); + }); + + Model.accessor('errors', function() { + return this.errors || (this.errors = new Batman.ErrorsSet); + }); + + Model.accessor('isNew', function() { + return this.isNew(); + }); + + Model.accessor(Model.defaultAccessor = { + get: function(k) { + return Batman.getPath(this, ['attributes', k]); + }, + set: function(k, v) { + if (this._willSet(k)) { + return this.get('attributes').set(k, v); + } else { + return this.get(k); + } + }, + unset: function(k) { + return this.get('attributes').unset(k); + } + }); + + Model.wrapAccessor('id', function(core) { + return { + get: function() { + var primaryKey; + primaryKey = this.constructor.primaryKey; + if (primaryKey === 'id') { + return core.get.apply(this, arguments); + } else { + return this.get(primaryKey); + } + }, + set: function(key, value) { + var parsedValue, primaryKey; + if ((typeof value === "string") && (value.match(/[^0-9]/) === null) && (("" + (parsedValue = parseInt(value, 10))) === value)) { + value = parsedValue; + } + primaryKey = this.constructor.primaryKey; + if (primaryKey === 'id') { + this._willSet(key); + return core.set.apply(this, arguments); + } else { + return this.set(primaryKey, value); + } + } + }; + }); + + Model.prototype.isNew = function() { + return typeof this.get('id') === 'undefined'; + }; + + Model.prototype.updateAttributes = function(attrs) { + this.mixin(attrs); + return this; + }; + + Model.prototype.toString = function() { + return "" + (this.constructor.get('resourceName')) + ": " + (this.get('id')); + }; + + Model.prototype.toParam = function() { + return this.get('id'); + }; + + Model.prototype.toJSON = function() { + var encoders, obj, + _this = this; + obj = {}; + encoders = this._batman.get('encoders'); + if (!(!encoders || encoders.isEmpty())) { + encoders.forEach(function(key, encoder) { + var encodedVal, val; + if (encoder.encode) { + val = _this.get(key); + if (typeof val !== 'undefined') { + encodedVal = encoder.encode(val, key, obj, _this); + if (typeof encodedVal !== 'undefined') { + return obj[encoder.as] = encodedVal; + } + } + } + }); + } + return obj; + }; + + Model.prototype.fromJSON = function(data) { + var encoders, key, obj, value, + _this = this; + obj = {}; + encoders = this._batman.get('encoders'); + if (!encoders || encoders.isEmpty() || !encoders.some(function(key, encoder) { + return encoder.decode != null; + })) { + for (key in data) { + value = data[key]; + obj[key] = value; + } + } else { + encoders.forEach(function(key, encoder) { + if (encoder.decode && typeof data[encoder.as] !== 'undefined') { + return obj[key] = encoder.decode(data[encoder.as], encoder.as, data, obj, _this); + } + }); + } + if (this.constructor.primaryKey !== 'id') { + obj.id = data[this.constructor.primaryKey]; + } + Batman.developer["do"](function() { + if ((!encoders) || encoders.length <= 1) { + return Batman.developer.warn("Warning: Model " + (Batman.functionName(_this.constructor)) + " has suspiciously few decoders!"); + } + }); + return this.mixin(obj); + }; + + Model.prototype.hasStorage = function() { + return this._batman.get('storage') != null; + }; + + Model.prototype.load = function(options, callback) { + var callbackQueue, hasOptions, _ref1, _ref2, + _this = this; + if (!callback) { + _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + } + hasOptions = Object.keys(options).length !== 0; + if ((_ref2 = this.get('lifecycle.state')) === 'destroying' || _ref2 === 'destroyed') { + if (typeof callback === "function") { + callback(new Error("Can't load a destroyed record!")); + } + return; + } + if (this.get('lifecycle').load()) { + callbackQueue = []; + if (callback != null) { + callbackQueue.push(callback); + } + if (!hasOptions) { + this._currentLoad = callbackQueue; + } + return this._doStorageOperation('read', { + data: options + }, function(err, record, env) { + var _j, _len1; + if (!err) { + _this.get('lifecycle').loaded(); + record = _this.constructor._mapIdentity(record); + } else { + _this.get('lifecycle').error(); + } + if (!hasOptions) { + _this._currentLoad = null; + } + for (_j = 0, _len1 = callbackQueue.length; _j < _len1; _j++) { + callback = callbackQueue[_j]; + callback(err, record, env); + } + }); + } else { + if (this.get('lifecycle.state') === 'loading' && !hasOptions) { + if (callback != null) { + return this._currentLoad.push(callback); + } + } else { + return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't load while in state " + (this.get('lifecycle.state')))) : void 0; + } + } + }; + + Model.prototype.save = function(options, callback) { + var endState, isNew, startState, storageOperation, _ref1, _ref2, _ref3, + _this = this; + if (!callback) { + _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + } + if ((_ref2 = this.get('lifecycle').get('state')) === 'destroying' || _ref2 === 'destroyed') { + if (typeof callback === "function") { + callback(new Error("Can't save a destroyed record!")); + } + return; + } + isNew = this.isNew(); + _ref3 = isNew ? ['create', 'create', 'created'] : ['save', 'update', 'saved'], startState = _ref3[0], storageOperation = _ref3[1], endState = _ref3[2]; + return this.validate(function(error, errors) { + var associations, creating; + if (error || errors.length) { + _this.get('lifecycle').failedValidation(); + if (typeof callback === "function") { + callback(error || errors, _this); + } + return; + } + creating = _this.isNew(); + if (_this.get('lifecycle').startTransition(startState)) { + associations = _this.constructor._batman.get('associations'); + _this._withoutDirtyTracking(function() { + var _ref4, + _this = this; + return associations != null ? (_ref4 = associations.getByType('belongsTo')) != null ? _ref4.forEach(function(association, label) { + return association.apply(_this); + }) : void 0 : void 0; + }); + return _this._doStorageOperation(storageOperation, { + data: options + }, function(err, record, env) { + if (!err) { + _this.get('dirtyKeys').clear(); + _this.get('_dirtiedKeys').clear(); + if (associations) { + record._withoutDirtyTracking(function() { + var _ref4, _ref5; + if ((_ref4 = associations.getByType('hasOne')) != null) { + _ref4.forEach(function(association, label) { + return association.apply(err, record); + }); + } + return (_ref5 = associations.getByType('hasMany')) != null ? _ref5.forEach(function(association, label) { + return association.apply(err, record); + }) : void 0; + }); + } + record = _this.constructor._mapIdentity(record); + _this.get('lifecycle').startTransition(endState); + } else { + if (err instanceof Batman.ErrorsSet) { + _this.get('lifecycle').failedValidation(); + } else { + _this.get('lifecycle').error(); + } + } + return typeof callback === "function" ? callback(err, record || _this, env) : void 0; + }); + } else { + return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't save while in state " + (_this.get('lifecycle.state')))) : void 0; + } + }); + }; + + Model.prototype.destroy = function(options, callback) { + var _ref1, + _this = this; + if (!callback) { + _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + } + if (this.get('lifecycle').destroy()) { + return this._doStorageOperation('destroy', { + data: options + }, function(err, record, env) { + if (!err) { + _this.constructor.get('loaded').remove(_this); + _this.get('lifecycle').destroyed(); + } else { + _this.get('lifecycle').error(); + } + return typeof callback === "function" ? callback(err, record, env) : void 0; + }); + } else { + return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't destroy while in state " + (this.get('lifecycle.state')))) : void 0; + } + }; + + Model.prototype.validate = function(callback) { + var args, count, errors, finishedValidation, key, validator, validators, _j, _k, _len1, _len2, _ref1; + errors = this.get('errors'); + errors.clear(); + validators = this._batman.get('validators') || []; + if (!validators || validators.length === 0) { + if (typeof callback === "function") { + callback(void 0, errors); + } + return true; + } + count = validators.reduce((function(acc, validator) { + return acc + validator.keys.length; + }), 0); + finishedValidation = function() { + if (--count === 0) { + return typeof callback === "function" ? callback(void 0, errors) : void 0; + } + }; + for (_j = 0, _len1 = validators.length; _j < _len1; _j++) { + validator = validators[_j]; + _ref1 = validator.keys; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + key = _ref1[_k]; + args = [errors, this, key, finishedValidation]; + try { + if (validator.validator) { + validator.validator.validateEach.apply(validator.validator, args); + } else { + validator.callback.apply(validator, args); + } + } catch (e) { + if (typeof callback === "function") { + callback(e, errors); + } + } + } + } + }; + + Model.prototype.associationProxy = function(association) { + var proxies, _base, _name; + Batman.initializeObject(this); + proxies = (_base = this._batman).associationProxies || (_base.associationProxies = {}); + proxies[_name = association.label] || (proxies[_name] = new association.proxyClass(association, this)); + return proxies[association.label]; + }; + + Model.prototype._willSet = function(key) { + if (this._pauseDirtyTracking) { + return true; + } + if (this.get('lifecycle').startTransition('set')) { + if (!this.get('_dirtiedKeys').has(key)) { + this.set("dirtyKeys." + key, this.get(key)); + this.get('_dirtiedKeys').add(key); + } + return true; + } else { + return false; + } + }; + + Model.prototype._doStorageOperation = function(operation, options, callback) { + var adapter, + _this = this; + Batman.developer.assert(this.hasStorage(), "Can't " + operation + " model " + (Batman.functionName(this.constructor)) + " without any storage adapters!"); + adapter = this._batman.get('storage'); + return adapter.perform(operation, this, options, function() { + return callback.apply(null, arguments); + }); + }; + + Model.prototype._withoutDirtyTracking = function(block) { + var result; + this._pauseDirtyTracking = true; + result = block.call(this); + this._pauseDirtyTracking = false; + return result; + }; + + _ref1 = ['load', 'save', 'validate', 'destroy']; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + functionName = _ref1[_j]; + Model.prototype[functionName] = Batman.Property.wrapTrackingPrevention(Model.prototype[functionName]); + } + + return Model; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var k, _fn, _i, _len, _ref, + _this = this; + + _ref = Batman.AssociationCurator.availableAssociations; + _fn = function(k) { + return Batman.Model[k] = function(label, scope) { + var collection, _base; + Batman.initializeObject(this); + collection = (_base = this._batman).associations || (_base.associations = new Batman.AssociationCurator(this)); + return collection.add(new Batman["" + (Batman.helpers.capitalize(k)) + "Association"](this, label, scope)); + }; + }; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + _fn(k); + } + +}).call(this); + +(function() { + var __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; }; + + Batman.ParamsReplacer = (function(_super) { + + __extends(ParamsReplacer, _super); + + function ParamsReplacer(navigator, params) { + this.navigator = navigator; + this.params = params; + } + + ParamsReplacer.prototype.redirect = function() { + return this.navigator.replace(this.toObject()); + }; + + ParamsReplacer.prototype.replace = function(params) { + this.params.replace(params); + return this.redirect(); + }; + + ParamsReplacer.prototype.update = function(params) { + this.params.update(params); + return this.redirect(); + }; + + ParamsReplacer.prototype.clear = function() { + this.params.clear(); + return this.redirect(); + }; + + ParamsReplacer.prototype.toObject = function() { + return this.params.toObject(); + }; + + ParamsReplacer.accessor({ + get: function(k) { + return this.params.get(k); + }, + set: function(k, v) { + var oldValue, result; + oldValue = this.params.get(k); + result = this.params.set(k, v); + if (oldValue !== v) { + this.redirect(); + } + return result; + }, + unset: function(k) { + var hadKey, result; + hadKey = this.params.hasKey(k); + result = this.params.unset(k); + if (hadKey) { + this.redirect(); + } + return result; + } + }); + + return ParamsReplacer; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.ParamsPusher = (function(_super) { + + __extends(ParamsPusher, _super); + + function ParamsPusher() { + return ParamsPusher.__super__.constructor.apply(this, arguments); + } + + ParamsPusher.prototype.redirect = function() { + return this.navigator.push(this.toObject()); + }; + + return ParamsPusher; + + })(Batman.ParamsReplacer); + +}).call(this); + +(function() { + var __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; }; + + Batman.NamedRouteQuery = (function(_super) { + + __extends(NamedRouteQuery, _super); + + NamedRouteQuery.prototype.isNamedRouteQuery = true; + + function NamedRouteQuery(routeMap, args) { + var key; + if (args == null) { + args = []; + } + NamedRouteQuery.__super__.constructor.call(this, { + routeMap: routeMap, + args: args + }); + for (key in this.get('routeMap').childrenByName) { + this[key] = this._queryAccess.bind(this, key); + } + } + + NamedRouteQuery.accessor('route', function() { + var collectionRoute, memberRoute, route, _i, _len, _ref, _ref1; + _ref = this.get('routeMap'), memberRoute = _ref.memberRoute, collectionRoute = _ref.collectionRoute; + _ref1 = [memberRoute, collectionRoute]; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + route = _ref1[_i]; + if (route != null) { + if (route.namedArguments.length === this.get('args').length) { + return route; + } + } + } + return collectionRoute || memberRoute; + }); + + NamedRouteQuery.accessor('path', function() { + return this.path(); + }); + + NamedRouteQuery.accessor('routeMap', 'args', 'cardinality', 'hashValue', Batman.Property.defaultAccessor); + + NamedRouteQuery.accessor({ + get: function(key) { + if (key == null) { + return; + } + if (typeof key === 'string') { + return this.nextQueryForName(key); + } else { + return this.nextQueryWithArgument(key); + } + }, + cache: false + }); + + NamedRouteQuery.accessor('withHash', function() { + var _this = this; + return new Batman.Accessible(function(hashValue) { + return _this.withHash(hashValue); + }); + }); + + NamedRouteQuery.prototype.withHash = function(hashValue) { + var clone; + clone = this.clone(); + clone.set('hashValue', hashValue); + return clone; + }; + + NamedRouteQuery.prototype.nextQueryForName = function(key) { + var map; + if (map = this.get('routeMap').childrenByName[key]) { + return new Batman.NamedRouteQuery(map, this.args); + } else { + return Batman.developer.error("Couldn't find a route for the name " + key + "!"); + } + }; + + NamedRouteQuery.prototype.nextQueryWithArgument = function(arg) { + var args; + args = this.args.slice(0); + args.push(arg); + return this.clone(args); + }; + + NamedRouteQuery.prototype.path = function() { + var argumentName, argumentValue, index, namedArguments, params, _i, _len; + params = {}; + namedArguments = this.get('route.namedArguments'); + for (index = _i = 0, _len = namedArguments.length; _i < _len; index = ++_i) { + argumentName = namedArguments[index]; + if ((argumentValue = this.get('args')[index]) != null) { + params[argumentName] = this._toParam(argumentValue); + } + } + if (this.get('hashValue') != null) { + params['#'] = this.get('hashValue'); + } + return this.get('route').pathFromParams(params); + }; + + NamedRouteQuery.prototype.toString = function() { + return this.path(); + }; + + NamedRouteQuery.prototype.clone = function(args) { + if (args == null) { + args = this.args; + } + return new Batman.NamedRouteQuery(this.routeMap, args); + }; + + NamedRouteQuery.prototype._toParam = function(arg) { + if (arg instanceof Batman.AssociationProxy) { + arg = arg.get('target'); + } + if ((arg != null ? arg.toParam : void 0) != null) { + return arg.toParam(); + } else { + return arg; + } + }; + + NamedRouteQuery.prototype._queryAccess = function(key, arg) { + var query; + query = this.nextQueryForName(key); + if (arg != null) { + query = query.nextQueryWithArgument(arg); + } + return query; + }; + + return NamedRouteQuery; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.Dispatcher = (function(_super) { + var ControllerDirectory; + + __extends(Dispatcher, _super); + + Dispatcher.canInferRoute = function(argument) { + return argument instanceof Batman.Model || argument instanceof Batman.AssociationProxy || argument.prototype instanceof Batman.Model; + }; + + Dispatcher.paramsFromArgument = function(argument) { + var resourceNameFromModel; + resourceNameFromModel = function(model) { + return Batman.helpers.camelize(Batman.helpers.pluralize(model.get('resourceName')), true); + }; + if (!this.canInferRoute(argument)) { + return argument; + } + if (argument instanceof Batman.Model || argument instanceof Batman.AssociationProxy) { + if (argument.isProxy) { + argument = argument.get('target'); + } + if (argument != null) { + return { + controller: resourceNameFromModel(argument.constructor), + action: 'show', + id: argument.get('id') + }; + } else { + return {}; + } + } else if (argument.prototype instanceof Batman.Model) { + return { + controller: resourceNameFromModel(argument), + action: 'index' + }; + } else { + return argument; + } + }; + + ControllerDirectory = (function(_super1) { + + __extends(ControllerDirectory, _super1); + + function ControllerDirectory() { + return ControllerDirectory.__super__.constructor.apply(this, arguments); + } + + ControllerDirectory.accessor('__app', Batman.Property.defaultAccessor); + + ControllerDirectory.accessor(function(key) { + return this.get("__app." + (Batman.helpers.capitalize(key)) + "Controller.sharedController"); + }); + + return ControllerDirectory; + + })(Batman.Object); + + Dispatcher.accessor('controllers', function() { + return new ControllerDirectory({ + __app: this.get('app') + }); + }); + + function Dispatcher(app, routeMap) { + Dispatcher.__super__.constructor.call(this, { + app: app, + routeMap: routeMap + }); + } + + Dispatcher.prototype.routeForParams = function(params) { + params = this.constructor.paramsFromArgument(params); + return this.get('routeMap').routeForParams(params); + }; + + Dispatcher.prototype.pathFromParams = function(params) { + var _ref; + if (typeof params === 'string') { + return params; + } + params = this.constructor.paramsFromArgument(params); + return (_ref = this.routeForParams(params)) != null ? _ref.pathFromParams(params) : void 0; + }; + + Dispatcher.prototype.dispatch = function(params) { + var inferredParams, path, route, _ref; + inferredParams = this.constructor.paramsFromArgument(params); + route = this.routeForParams(inferredParams); + if (route) { + _ref = route.pathAndParamsFromArgument(inferredParams), path = _ref[0], params = _ref[1]; + this.set('app.currentRoute', route); + this.set('app.currentURL', path); + this.get('app.currentParams').replace(params || {}); + route.dispatch(params); + } else { + if (Batman.typeOf(params) === 'Object' && !this.constructor.canInferRoute(params)) { + return this.get('app.currentParams').replace(params); + } else { + this.get('app.currentParams').clear(); + } + if (params !== '/404') { + return Batman.redirect('/404'); + } + } + return path; + }; + + return Dispatcher; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.Route = (function(_super) { + + __extends(Route, _super); + + Route.regexps = { + namedParam: /:([\w\d]+)/g, + splatParam: /\*([\w\d]+)/g, + queryParam: '(?:\\?.+)?', + namedOrSplat: /[:|\*]([\w\d]+)/g, + namePrefix: '[:|\*]', + escapeRegExp: /[-[\]{}+?.,\\^$|#\s]/g, + openOptParam: /\(/g, + closeOptParam: /\)/g + }; + + Route.prototype.optionKeys = ['member', 'collection']; + + Route.prototype.testKeys = ['controller', 'action']; + + Route.prototype.isRoute = true; + + function Route(templatePath, baseParams) { + var k, matches, namedArguments, pattern, properties, regexp, regexps, _i, _len, _ref; + regexps = this.constructor.regexps; + if (templatePath.indexOf('/') !== 0) { + templatePath = "/" + templatePath; + } + pattern = templatePath.replace(regexps.escapeRegExp, '\\$&'); + regexp = RegExp("^" + (pattern.replace(regexps.openOptParam, '(?:').replace(regexps.closeOptParam, ')?').replace(regexps.namedParam, '([^\/]+)').replace(regexps.splatParam, '(.*?)')) + regexps.queryParam + "$"); + namedArguments = ((function() { + var _results; + _results = []; + while (matches = regexps.namedOrSplat.exec(pattern)) { + _results.push(matches[1]); + } + return _results; + })()); + properties = { + templatePath: templatePath, + pattern: pattern, + regexp: regexp, + namedArguments: namedArguments, + baseParams: baseParams + }; + _ref = this.optionKeys; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + properties[k] = baseParams[k]; + delete baseParams[k]; + } + Route.__super__.constructor.call(this, properties); + } + + Route.prototype.paramsFromPath = function(pathAndQuery) { + var index, match, matches, name, namedArguments, params, uri, _i, _len; + uri = new Batman.URI(pathAndQuery); + namedArguments = this.get('namedArguments'); + params = Batman.extend({ + path: uri.path + }, this.get('baseParams')); + matches = this.get('regexp').exec(uri.path).slice(1); + for (index = _i = 0, _len = matches.length; _i < _len; index = ++_i) { + match = matches[index]; + name = namedArguments[index]; + params[name] = match; + } + return Batman.extend(params, uri.queryParams); + }; + + Route.prototype.pathFromParams = function(argumentParams) { + var hash, key, name, newPath, params, path, query, regexp, regexps, _i, _j, _len, _len1, _ref, _ref1; + params = Batman.extend({}, argumentParams); + path = this.get('templatePath'); + regexps = this.constructor.regexps; + _ref = this.get('namedArguments'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + regexp = RegExp("" + regexps.namePrefix + name); + newPath = path.replace(regexp, (params[name] != null ? params[name] : '')); + if (newPath !== path) { + delete params[name]; + path = newPath; + } + } + path = path.replace(regexps.openOptParam, '').replace(regexps.closeOptParam, '').replace(/([^\/])\/+$/, '$1'); + _ref1 = this.testKeys; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + key = _ref1[_j]; + delete params[key]; + } + if (params['#']) { + hash = params['#']; + delete params['#']; + } + query = Batman.URI.queryFromParams(params); + if (query) { + path += "?" + query; + } + if (hash) { + path += "#" + hash; + } + return path; + }; + + Route.prototype.test = function(pathOrParams) { + var key, path, value, _i, _len, _ref; + if (typeof pathOrParams === 'string') { + path = pathOrParams; + } else if (pathOrParams.path != null) { + path = pathOrParams.path; + } else { + path = this.pathFromParams(pathOrParams); + _ref = this.testKeys; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + if ((value = this.get(key)) != null) { + if (pathOrParams[key] !== value) { + return false; + } + } + } + } + return this.get('regexp').test(path); + }; + + Route.prototype.pathAndParamsFromArgument = function(pathOrParams) { + var params, path; + if (typeof pathOrParams === 'string') { + params = this.paramsFromPath(pathOrParams); + path = pathOrParams; + } else { + params = pathOrParams; + path = this.pathFromParams(pathOrParams); + } + return [path, params]; + }; + + Route.prototype.dispatch = function(params) { + if (!this.test(params)) { + return false; + } + return this.get('callback')(params); + }; + + Route.prototype.callback = function() { + throw new Batman.DevelopmentError("Override callback in a Route subclass"); + }; + + return Route; + + })(Batman.Object); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }; + + Batman.ControllerActionRoute = (function(_super) { + + __extends(ControllerActionRoute, _super); + + ControllerActionRoute.prototype.optionKeys = ['member', 'collection', 'app', 'controller', 'action']; + + function ControllerActionRoute(templatePath, options) { + this.callback = __bind(this.callback, this); + + var action, controller, _ref; + if (options.signature) { + _ref = options.signature.split('#'), controller = _ref[0], action = _ref[1]; + action || (action = 'index'); + options.controller = controller; + options.action = action; + delete options.signature; + } + ControllerActionRoute.__super__.constructor.call(this, templatePath, options); + } + + ControllerActionRoute.prototype.callback = function(params) { + var controller; + controller = this.get("app.dispatcher.controllers." + (this.get('controller'))); + return controller.dispatch(this.get('action'), params); + }; + + return ControllerActionRoute; + + })(Batman.Route); + +}).call(this); + +(function() { + var __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; }; + + Batman.CallbackActionRoute = (function(_super) { + + __extends(CallbackActionRoute, _super); + + function CallbackActionRoute() { + return CallbackActionRoute.__super__.constructor.apply(this, arguments); + } + + CallbackActionRoute.prototype.optionKeys = ['member', 'collection', 'callback', 'app']; + + CallbackActionRoute.prototype.controller = false; + + CallbackActionRoute.prototype.action = false; + + return CallbackActionRoute; + + })(Batman.Route); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.Hash = (function(_super) { + var k, _fn, _i, _j, _len, _len1, _ref, _ref1, + _this = this; + + __extends(Hash, _super); + + Hash.Metadata = (function(_super1) { + + __extends(Metadata, _super1); + + Batman.extend(Metadata.prototype, Batman.Enumerable); + + function Metadata(hash) { + this.hash = hash; + } + + Metadata.accessor('length', function() { + this.hash.registerAsMutableSource(); + return this.hash.length; + }); + + Metadata.accessor('isEmpty', 'keys', 'toArray', function(key) { + this.hash.registerAsMutableSource(); + return this.hash[key](); + }); + + Metadata.prototype.forEach = function() { + var _ref; + return (_ref = this.hash).forEach.apply(_ref, arguments); + }; + + return Metadata; + + })(Batman.Object); + + function Hash() { + this.meta = new this.constructor.Metadata(this); + Batman.SimpleHash.apply(this, arguments); + Hash.__super__.constructor.apply(this, arguments); + } + + Batman.extend(Hash.prototype, Batman.Enumerable); + + Hash.prototype.propertyClass = Batman.Property; + + Hash.defaultAccessor = { + get: Batman.SimpleHash.prototype.get, + set: Hash.mutation(function(key, value) { + var result; + result = Batman.SimpleHash.prototype.set.call(this, key, value); + this.fire('itemsWereAdded', key); + return result; + }), + unset: Hash.mutation(function(key) { + var result; + result = Batman.SimpleHash.prototype.unset.call(this, key); + if (result != null) { + this.fire('itemsWereRemoved', key); + } + return result; + }), + cache: false + }; + + Hash.accessor(Hash.defaultAccessor); + + Hash.prototype._preventMutationEvents = function(block) { + this.prevent('change'); + this.prevent('itemsWereAdded'); + this.prevent('itemsWereRemoved'); + try { + return block.call(this); + } finally { + this.allow('change'); + this.allow('itemsWereAdded'); + this.allow('itemsWereRemoved'); + } + }; + + Hash.prototype.clear = Hash.mutation(function() { + var keys, result; + keys = this.keys(); + this._preventMutationEvents(function() { + var _this = this; + return this.forEach(function(k) { + return _this.unset(k); + }); + }); + result = Batman.SimpleHash.prototype.clear.call(this); + this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(keys))); + return result; + }); + + Hash.prototype.update = Hash.mutation(function(object) { + var addedKeys; + addedKeys = []; + this._preventMutationEvents(function() { + var _this = this; + return Batman.forEach(object, function(k, v) { + if (!_this.hasKey(k)) { + addedKeys.push(k); + } + return _this.set(k, v); + }); + }); + if (addedKeys.length > 0) { + return this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedKeys))); + } + }); + + Hash.prototype.replace = Hash.mutation(function(object) { + var addedKeys, removedKeys; + addedKeys = []; + removedKeys = []; + this._preventMutationEvents(function() { + var _this = this; + this.forEach(function(k, _) { + if (!Batman.objectHasKey(object, k)) { + _this.unset(k); + return removedKeys.push(k); + } + }); + return Batman.forEach(object, function(k, v) { + if (!_this.hasKey(k)) { + addedKeys.push(k); + } + return _this.set(k, v); + }); + }); + if (addedKeys.length > 0) { + this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedKeys))); + } + if (removedKeys.length > 0) { + return this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(removedKeys))); + } + }); + + _ref = ['equality', 'hashKeyFor', 'objectKey', 'prefixedKey', 'unprefixedKey']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + Hash.prototype[k] = Batman.SimpleHash.prototype[k]; + } + + _ref1 = ['hasKey', 'forEach', 'isEmpty', 'keys', 'toArray', 'merge', 'toJSON', 'toObject']; + _fn = function(k) { + return Hash.prototype[k] = function() { + this.registerAsMutableSource(); + return Batman.SimpleHash.prototype[k].apply(this, arguments); + }; + }; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + k = _ref1[_j]; + _fn(k); + } + + return Hash; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.RenderCache = (function(_super) { + + __extends(RenderCache, _super); + + RenderCache.prototype.maximumLength = 4; + + function RenderCache() { + RenderCache.__super__.constructor.apply(this, arguments); + this.keyQueue = []; + } + + RenderCache.prototype.viewForOptions = function(options) { + var _this = this; + if (options.cache === false || options.viewClass.prototype.cache === false) { + return this._newViewFromOptions(options); + } + return this.getOrSet(options, function() { + return _this._newViewFromOptions(Batman.extend({}, options)); + }); + }; + + RenderCache.prototype._newViewFromOptions = function(options) { + return new options.viewClass(options); + }; + + RenderCache.wrapAccessor(function(core) { + return { + cache: false, + get: function(key) { + var result; + result = core.get.call(this, key); + if (result) { + this._addOrBubbleKey(key); + } + return result; + }, + set: function(key, value) { + var result; + result = core.set.apply(this, arguments); + result.set('cached', true); + this._addOrBubbleKey(key); + this._evictExpiredKeys(); + return result; + }, + unset: function(key) { + var result; + result = core.unset.apply(this, arguments); + result.set('cached', false); + this._removeKeyFromQueue(key); + return result; + } + }; + }); + + RenderCache.prototype.equality = function(incomingOptions, storageOptions) { + var key; + if (Object.keys(incomingOptions).length !== Object.keys(storageOptions).length) { + return false; + } + for (key in incomingOptions) { + if (!(key === 'view')) { + if (incomingOptions[key] !== storageOptions[key]) { + return false; + } + } + } + return true; + }; + + RenderCache.prototype.reset = function() { + var key, _i, _len, _ref, _results; + _ref = this.keyQueue.slice(0); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + _results.push(this.unset(key)); + } + return _results; + }; + + RenderCache.prototype._addOrBubbleKey = function(key) { + this._removeKeyFromQueue(key); + return this.keyQueue.unshift(key); + }; + + RenderCache.prototype._removeKeyFromQueue = function(key) { + var index, queuedKey, _i, _len, _ref; + _ref = this.keyQueue; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + queuedKey = _ref[index]; + if (this.equality(queuedKey, key)) { + this.keyQueue.splice(index, 1); + break; + } + } + return key; + }; + + RenderCache.prototype._evictExpiredKeys = function() { + var currentKeys, i, key, _i, _ref, _ref1; + if (this.length > this.maximumLength) { + currentKeys = this.keyQueue.slice(0); + for (i = _i = _ref = this.maximumLength, _ref1 = currentKeys.length; _ref <= _ref1 ? _i < _ref1 : _i > _ref1; i = _ref <= _ref1 ? ++_i : --_i) { + key = currentKeys[i]; + if (!this.get(key).isInDOM()) { + this.unset(key); + } + } + } + }; + + return RenderCache; + + })(Batman.Hash); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Batman.Controller = (function(_super) { + var _optionsFromFilterArguments; + + __extends(Controller, _super); + + Controller.singleton('sharedController'); + + Controller.wrapAccessor('routingKey', function(core) { + return { + get: function() { + if (this.routingKey != null) { + return this.routingKey; + } else { + if (Batman.config.minificationErrors) { + Batman.developer.error("Please define `routingKey` on the prototype of " + (Batman.functionName(this.constructor)) + " in order for your controller to be minification safe."); + } + return Batman.functionName(this.constructor).replace(/Controller$/, ''); + } + } + }; + }); + + Controller.accessor('_renderContext', function() { + return Batman.RenderContext.root().descend(this); + }); + + _optionsFromFilterArguments = function(options, nameOrFunction) { + if (!nameOrFunction) { + nameOrFunction = options; + options = {}; + } else { + if (typeof options === 'string') { + options = { + only: [options] + }; + } else { + if (options.only && Batman.typeOf(options.only) !== 'Array') { + options.only = [options.only]; + } + if (options.except && Batman.typeOf(options.except) !== 'Array') { + options.except = [options.except]; + } + } + } + options.block = nameOrFunction; + return options; + }; + + Controller.beforeFilter = function() { + var filters, options, _base; + Batman.initializeObject(this); + options = _optionsFromFilterArguments.apply(null, arguments); + filters = (_base = this._batman).beforeFilters || (_base.beforeFilters = new Batman.SimpleHash); + return filters.set(options.block, options); + }; + + Controller.afterFilter = function() { + var filters, options, _base; + Batman.initializeObject(this); + options = _optionsFromFilterArguments.apply(null, arguments); + filters = (_base = this._batman).afterFilters || (_base.afterFilters = new Batman.SimpleHash); + return filters.set(options.block, options); + }; + + Controller.afterFilter(function(params) { + if (this.autoScrollToHash && (params['#'] != null)) { + return this.scrollToHash(params['#']); + } + }); + + function Controller() { + this.redirect = __bind(this.redirect, this); + Controller.__super__.constructor.apply(this, arguments); + this._resetActionFrames(); + } + + Controller.prototype.renderCache = new Batman.RenderCache; + + Controller.prototype.defaultRenderYield = 'main'; + + Controller.prototype.autoScrollToHash = true; + + Controller.prototype.dispatch = function(action, params) { + var redirectTo; + if (params == null) { + params = {}; + } + params.controller || (params.controller = this.get('routingKey')); + params.action || (params.action = action); + params.target || (params.target = this); + this._resetActionFrames(); + this.set('action', action); + this.set('params', params); + Batman.DOM.Yield.cycleAll(); + this.executeAction(action, params); + Batman.DOM.Yield.clearAllStale(); + redirectTo = this._afterFilterRedirect; + delete this._afterFilterRedirect; + if (redirectTo) { + return Batman.redirect(redirectTo); + } + }; + + Controller.prototype.executeAction = function(action, params) { + var frame, oldRedirect, parentFrame, result, _ref, _ref1, + _this = this; + if (params == null) { + params = this.get('params'); + } + Batman.developer.assert(this[action], "Error! Controller action " + (this.get('routingKey')) + "." + action + " couldn't be found!"); + parentFrame = this._actionFrames[this._actionFrames.length - 1]; + frame = new Batman.ControllerActionFrame({ + parentFrame: parentFrame, + action: action + }, function() { + var _ref; + _this._runFilters(action, params, 'afterFilters'); + _this._resetActionFrames(); + return (_ref = Batman.navigator) != null ? _ref.redirect = oldRedirect : void 0; + }); + this._actionFrames.push(frame); + frame.startOperation({ + internal: true + }); + oldRedirect = (_ref = Batman.navigator) != null ? _ref.redirect : void 0; + if ((_ref1 = Batman.navigator) != null) { + _ref1.redirect = this.redirect; + } + this._runFilters(action, params, 'beforeFilters'); + result = this[action](params); + if (!frame.operationOccurred) { + this.render(); + } + frame.finishOperation(); + return result; + }; + + Controller.prototype.redirect = function(url) { + var frame; + frame = this._actionFrames[this._actionFrames.length - 1]; + if (frame) { + if (frame.operationOccurred) { + Batman.developer.warn("Warning! Trying to redirect but an action has already been taken during " + (this.get('routingKey')) + "." + (frame.action || this.get('action'))); + } + frame.startAndFinishOperation(); + if (this._afterFilterRedirect != null) { + return Batman.developer.warn("Warning! Multiple actions trying to redirect!"); + } else { + return this._afterFilterRedirect = url; + } + } else { + if (Batman.typeOf(url) === 'Object') { + if (!url.controller) { + url.controller = this; + } + } + return Batman.redirect(url); + } + }; + + Controller.prototype.render = function(options) { + var action, frame, view, _ref, _ref1, + _this = this; + if (options == null) { + options = {}; + } + if (frame = (_ref = this._actionFrames) != null ? _ref[this._actionFrames.length - 1] : void 0) { + frame.startOperation(); + } + if (options === false) { + frame.finishOperation(); + return; + } + action = (frame != null ? frame.action : void 0) || this.get('action'); + if (options) { + options.into || (options.into = this.defaultRenderYield); + } + if (!options.view) { + options.viewClass || (options.viewClass = this._viewClassForAction(action)); + options.context || (options.context = this.get('_renderContext')); + options.source || (options.source = Batman.helpers.underscore(this.get('routingKey') + '/' + action)); + view = this.renderCache.viewForOptions(options); + } else { + view = options.view; + options.view = null; + } + if (view) { + if ((_ref1 = Batman.currentApp) != null) { + _ref1.prevent('ready'); + } + view.on('ready', function() { + var _ref2; + Batman.DOM.Yield.withName(options.into).replace(view.get('node')); + if ((_ref2 = Batman.currentApp) != null) { + _ref2.allowAndFire('ready'); + } + return frame != null ? frame.finishOperation() : void 0; + }); + } + return view; + }; + + Controller.prototype.scrollToHash = function(hash) { + if (hash == null) { + hash = this.get('params')['#']; + } + return Batman.DOM.scrollIntoView(hash); + }; + + Controller.prototype._resetActionFrames = function() { + return this._actionFrames = []; + }; + + Controller.prototype._viewClassForAction = function(action) { + var classPrefix, _ref; + classPrefix = this.get('routingKey').replace('/', '_'); + return ((_ref = Batman.currentApp) != null ? _ref[Batman.helpers.camelize("" + classPrefix + "_" + action + "_view")] : void 0) || Batman.View; + }; + + Controller.prototype._runFilters = function(action, params, filters) { + var _ref, + _this = this; + if (filters = (_ref = this.constructor._batman) != null ? _ref.get(filters) : void 0) { + return filters.forEach(function(_, options) { + var block; + if (options.only && __indexOf.call(options.only, action) < 0) { + return; + } + if (options.except && __indexOf.call(options.except, action) >= 0) { + return; + } + block = options.block; + if (typeof block === 'function') { + return block.call(_this, params); + } else { + return typeof _this[block] === "function" ? _this[block](params) : void 0; + } + }); + } + }; + + return Controller; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.Set = (function(_super) { + var k, _fn, _i, _j, _len, _len1, _ref, _ref1, + _this = this; + + __extends(Set, _super); + + function Set() { + Batman.SimpleSet.apply(this, arguments); + } + + Batman.extend(Set.prototype, Batman.Enumerable); + + Set._applySetAccessors = function(klass) { + var accessor, accessors, key, _results; + accessors = { + first: function() { + return this.toArray()[0]; + }, + last: function() { + return this.toArray()[this.length - 1]; + }, + isEmpty: function() { + return this.isEmpty(); + }, + toArray: function() { + return this.toArray(); + }, + length: function() { + this.registerAsMutableSource(); + return this.length; + }, + indexedBy: function() { + var _this = this; + return new Batman.TerminalAccessible(function(key) { + return _this.indexedBy(key); + }); + }, + indexedByUnique: function() { + var _this = this; + return new Batman.TerminalAccessible(function(key) { + return _this.indexedByUnique(key); + }); + }, + sortedBy: function() { + var _this = this; + return new Batman.TerminalAccessible(function(key) { + return _this.sortedBy(key); + }); + }, + sortedByDescending: function() { + var _this = this; + return new Batman.TerminalAccessible(function(key) { + return _this.sortedBy(key, 'desc'); + }); + } + }; + _results = []; + for (key in accessors) { + accessor = accessors[key]; + _results.push(klass.accessor(key, accessor)); + } + return _results; + }; + + Set._applySetAccessors(Set); + + _ref = ['add', 'remove', 'clear', 'replace', 'indexedBy', 'indexedByUnique', 'sortedBy', 'equality', '_indexOfItem']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + Set.prototype[k] = Batman.SimpleSet.prototype[k]; + } + + _ref1 = ['find', 'merge', 'forEach', 'toArray', 'isEmpty', 'has']; + _fn = function(k) { + return Set.prototype[k] = function() { + this.registerAsMutableSource(); + return Batman.SimpleSet.prototype[k].apply(this, arguments); + }; + }; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + k = _ref1[_j]; + _fn(k); + } + + Set.prototype.toJSON = Set.prototype.toArray; + + return Set; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.ErrorsSet = (function(_super) { + + __extends(ErrorsSet, _super); + + function ErrorsSet() { + return ErrorsSet.__super__.constructor.apply(this, arguments); + } + + ErrorsSet.accessor(function(key) { + return this.indexedBy('attribute').get(key); + }); + + ErrorsSet.prototype.add = function(key, error) { + return ErrorsSet.__super__.add.call(this, new Batman.ValidationError(key, error)); + }; + + return ErrorsSet; + + })(Batman.Set); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetProxy = (function(_super) { + var k, _fn, _i, _len, _ref, + _this = this; + + __extends(SetProxy, _super); + + function SetProxy(base) { + var _this = this; + this.base = base; + SetProxy.__super__.constructor.call(this); + this.length = this.base.length; + this.base.on('itemsWereAdded', function() { + var items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _this.set('length', _this.base.length); + return _this.fire.apply(_this, ['itemsWereAdded'].concat(__slice.call(items))); + }); + this.base.on('itemsWereRemoved', function() { + var items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _this.set('length', _this.base.length); + return _this.fire.apply(_this, ['itemsWereRemoved'].concat(__slice.call(items))); + }); + } + + Batman.extend(SetProxy.prototype, Batman.Enumerable); + + SetProxy.prototype.filter = function(f) { + var r; + r = new Batman.Set(); + return this.reduce((function(r, e) { + if (f(e)) { + r.add(e); + } + return r; + }), r); + }; + + SetProxy.prototype.replace = function() { + var length, result; + length = this.property('length'); + length.isolate(); + result = this.base.replace.apply(this, arguments); + length.expose(); + return result; + }; + + _ref = ['add', 'remove', 'find', 'clear', 'has', 'merge', 'toArray', 'isEmpty', 'indexedBy', 'indexedByUnique', 'sortedBy']; + _fn = function(k) { + return SetProxy.prototype[k] = function() { + var _ref1; + return (_ref1 = this.base)[k].apply(_ref1, arguments); + }; + }; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + _fn(k); + } + + Batman.Set._applySetAccessors(SetProxy); + + SetProxy.accessor('length', { + get: function() { + this.registerAsMutableSource(); + return this.length; + }, + set: function(_, v) { + return this.length = v; + } + }); + + return SetProxy; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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; }, + __slice = [].slice; + + Batman.BinarySetOperation = (function(_super) { + + __extends(BinarySetOperation, _super); + + function BinarySetOperation(left, right) { + this.left = left; + this.right = right; + this._setup = __bind(this._setup, this); + + BinarySetOperation.__super__.constructor.call(this); + this._setup(this.left, this.right); + this._setup(this.right, this.left); + } + + BinarySetOperation.prototype._setup = function(set, opposite) { + var _this = this; + set.on('itemsWereAdded', function() { + var items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return _this._itemsWereAddedToSource.apply(_this, [set, opposite].concat(__slice.call(items))); + }); + set.on('itemsWereRemoved', function() { + var items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return _this._itemsWereRemovedFromSource.apply(_this, [set, opposite].concat(__slice.call(items))); + }); + return this._itemsWereAddedToSource.apply(this, [set, opposite].concat(__slice.call(set.toArray()))); + }; + + BinarySetOperation.prototype.merge = function() { + var merged, others, set, _i, _len; + others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + merged = new Batman.Set; + others.unshift(this); + for (_i = 0, _len = others.length; _i < _len; _i++) { + set = others[_i]; + set.forEach(function(v) { + return merged.add(v); + }); + } + return merged; + }; + + BinarySetOperation.prototype.filter = Batman.SetProxy.prototype.filter; + + return BinarySetOperation; + + })(Batman.Set); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetUnion = (function(_super) { + + __extends(SetUnion, _super); + + function SetUnion() { + return SetUnion.__super__.constructor.apply(this, arguments); + } + + SetUnion.prototype._itemsWereAddedToSource = function() { + var items, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + return this.add.apply(this, items); + }; + + SetUnion.prototype._itemsWereRemovedFromSource = function() { + var item, items, itemsToRemove, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + itemsToRemove = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!opposite.has(item)) { + _results.push(item); + } + } + return _results; + })(); + return this.remove.apply(this, itemsToRemove); + }; + + return SetUnion; + + })(Batman.BinarySetOperation); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetIntersection = (function(_super) { + + __extends(SetIntersection, _super); + + function SetIntersection() { + return SetIntersection.__super__.constructor.apply(this, arguments); + } + + SetIntersection.prototype._itemsWereAddedToSource = function() { + var item, items, itemsToAdd, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + itemsToAdd = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (opposite.has(item)) { + _results.push(item); + } + } + return _results; + })(); + return this.add.apply(this, itemsToAdd); + }; + + SetIntersection.prototype._itemsWereRemovedFromSource = function() { + var items, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + return this.remove.apply(this, items); + }; + + return SetIntersection; + + })(Batman.BinarySetOperation); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetComplement = (function(_super) { + + __extends(SetComplement, _super); + + function SetComplement() { + return SetComplement.__super__.constructor.apply(this, arguments); + } + + SetComplement.prototype._itemsWereAddedToSource = function() { + var item, items, itemsToAdd, itemsToRemove, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + if (source === this.left) { + itemsToAdd = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!opposite.has(item)) { + _results.push(item); + } + } + return _results; + })(); + return this.add.apply(this, itemsToAdd); + } else { + itemsToRemove = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (opposite.has(item)) { + _results.push(item); + } + } + return _results; + })(); + return this.remove.apply(this, itemsToRemove); + } + }; + + SetComplement.prototype._itemsWereRemovedFromSource = function() { + var item, items, itemsToAdd, opposite, source; + source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + if (source === this.left) { + return this.remove.apply(this, items); + } else { + itemsToAdd = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (opposite.has(item)) { + _results.push(item); + } + } + return _results; + })(); + return this.add.apply(this, itemsToAdd); + } + }; + + SetComplement.prototype._addComplement = function(items, opposite) { + var item; + return this.add.apply(this, (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (opposite.has(item)) { + _results.push(item); + } + } + return _results; + })()); + }; + + return SetComplement; + + })(Batman.BinarySetOperation); + +}).call(this); + +(function() { + + Batman.mixins = new Batman.Object; + +}).call(this); + +(function() { + var __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; }; + + Batman.Accessible = (function(_super) { + + __extends(Accessible, _super); + + function Accessible() { + this.accessor.apply(this, arguments); + } + + return Accessible; + + })(Batman.Object); + + Batman.TerminalAccessible = (function(_super) { + + __extends(TerminalAccessible, _super); + + function TerminalAccessible() { + return TerminalAccessible.__super__.constructor.apply(this, arguments); + } + + TerminalAccessible.prototype.propertyClass = Batman.Property; + + return TerminalAccessible; + + })(Batman.Accessible); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetObserver = (function(_super) { + + __extends(SetObserver, _super); + + function SetObserver(base) { + var _this = this; + this.base = base; + this._itemObservers = new Batman.SimpleHash; + this._setObservers = new Batman.SimpleHash; + this._setObservers.set("itemsWereAdded", function() { + return _this.fire.apply(_this, ['itemsWereAdded'].concat(__slice.call(arguments))); + }); + this._setObservers.set("itemsWereRemoved", function() { + return _this.fire.apply(_this, ['itemsWereRemoved'].concat(__slice.call(arguments))); + }); + this.on('itemsWereAdded', this.startObservingItems.bind(this)); + this.on('itemsWereRemoved', this.stopObservingItems.bind(this)); + } + + SetObserver.prototype.observedItemKeys = []; + + SetObserver.prototype.observerForItemAndKey = function(item, key) {}; + + SetObserver.prototype._getOrSetObserverForItemAndKey = function(item, key) { + var _this = this; + return this._itemObservers.getOrSet(item, function() { + var observersByKey; + observersByKey = new Batman.SimpleHash; + return observersByKey.getOrSet(key, function() { + return _this.observerForItemAndKey(item, key); + }); + }); + }; + + SetObserver.prototype.startObserving = function() { + this._manageItemObservers("observe"); + return this._manageSetObservers("addHandler"); + }; + + SetObserver.prototype.stopObserving = function() { + this._manageItemObservers("forget"); + return this._manageSetObservers("removeHandler"); + }; + + SetObserver.prototype.startObservingItems = function() { + var item, items, _i, _len, _results; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(this._manageObserversForItem(item, "observe")); + } + return _results; + }; + + SetObserver.prototype.stopObservingItems = function() { + var item, items, _i, _len, _results; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(this._manageObserversForItem(item, "forget")); + } + return _results; + }; + + SetObserver.prototype._manageObserversForItem = function(item, method) { + var key, _i, _len, _ref; + if (!item.isObservable) { + return; + } + _ref = this.observedItemKeys; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + item[method](key, this._getOrSetObserverForItemAndKey(item, key)); + } + if (method === "forget") { + return this._itemObservers.unset(item); + } + }; + + SetObserver.prototype._manageItemObservers = function(method) { + var _this = this; + return this.base.forEach(function(item) { + return _this._manageObserversForItem(item, method); + }); + }; + + SetObserver.prototype._manageSetObservers = function(method) { + var _this = this; + if (!this.base.isObservable) { + return; + } + return this._setObservers.forEach(function(key, observer) { + return _this.base.event(key)[method](observer); + }); + }; + + return SetObserver; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.SetSort = (function(_super) { + + __extends(SetSort, _super); + + function SetSort(base, key, order) { + var boundReIndex; + this.key = key; + if (order == null) { + order = "asc"; + } + SetSort.__super__.constructor.call(this, base); + this.descending = order.toLowerCase() === "desc"; + if (this.base.isObservable) { + this._setObserver = new Batman.SetObserver(this.base); + this._setObserver.observedItemKeys = [this.key]; + boundReIndex = this._reIndex.bind(this); + this._setObserver.observerForItemAndKey = function() { + return boundReIndex; + }; + this._setObserver.on('itemsWereAdded', boundReIndex); + this._setObserver.on('itemsWereRemoved', boundReIndex); + this.startObserving(); + } + this._reIndex(); + } + + SetSort.prototype.startObserving = function() { + var _ref; + return (_ref = this._setObserver) != null ? _ref.startObserving() : void 0; + }; + + SetSort.prototype.stopObserving = function() { + var _ref; + return (_ref = this._setObserver) != null ? _ref.stopObserving() : void 0; + }; + + SetSort.prototype.toArray = function() { + return this.get('_storage'); + }; + + SetSort.prototype.forEach = function(iterator, ctx) { + var e, i, _i, _len, _ref, _results; + _ref = this.get('_storage'); + _results = []; + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + e = _ref[i]; + _results.push(iterator.call(ctx, e, i, this)); + } + return _results; + }; + + SetSort.prototype.compare = function(a, b) { + if (a === b) { + return 0; + } + if (a === void 0) { + return 1; + } + if (b === void 0) { + return -1; + } + if (a === null) { + return 1; + } + if (b === null) { + return -1; + } + if (a === false) { + return 1; + } + if (b === false) { + return -1; + } + if (a === true) { + return 1; + } + if (b === true) { + return -1; + } + if (a !== a) { + if (b !== b) { + return 0; + } else { + return 1; + } + } + if (b !== b) { + return -1; + } + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + return 0; + }; + + SetSort.prototype._reIndex = function() { + var newOrder, _ref, + _this = this; + newOrder = this.base.toArray().sort(function(a, b) { + var multiple, valueA, valueB; + valueA = Batman.get(a, _this.key); + if (typeof valueA === 'function') { + valueA = valueA.call(a); + } + if (valueA != null) { + valueA = valueA.valueOf(); + } + valueB = Batman.get(b, _this.key); + if (typeof valueB === 'function') { + valueB = valueB.call(b); + } + if (valueB != null) { + valueB = valueB.valueOf(); + } + multiple = _this.descending ? -1 : 1; + return _this.compare.call(_this, valueA, valueB) * multiple; + }); + if ((_ref = this._setObserver) != null) { + _ref.startObservingItems.apply(_ref, newOrder); + } + return this.set('_storage', newOrder); + }; + + return SetSort; + + })(Batman.SetProxy); + +}).call(this); + +(function() { + var __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; }; + + Batman.AssociationSet = (function(_super) { + + __extends(AssociationSet, _super); + + function AssociationSet(foreignKeyValue, association) { + var base; + this.foreignKeyValue = foreignKeyValue; + this.association = association; + base = new Batman.Set; + AssociationSet.__super__.constructor.call(this, base, '_batmanID'); + } + + AssociationSet.prototype.loaded = false; + + AssociationSet.prototype.load = function(callback) { + var _this = this; + if (this.foreignKeyValue == null) { + return callback(void 0, this); + } + return this.association.getRelatedModel().load(this._getLoadOptions(), function(err, records) { + if (!err) { + _this.markAsLoaded(); + } + return callback(err, _this); + }); + }; + + AssociationSet.prototype._getLoadOptions = function() { + var loadOptions; + loadOptions = {}; + loadOptions[this.association.foreignKey] = this.foreignKeyValue; + return loadOptions; + }; + + AssociationSet.accessor('loaded', Batman.Property.defaultAccessor); + + AssociationSet.prototype.markAsLoaded = function() { + this.set('loaded', true); + return this.fire('loaded'); + }; + + return AssociationSet; + + })(Batman.SetSort); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicAssociationSet = (function(_super) { + + __extends(PolymorphicAssociationSet, _super); + + function PolymorphicAssociationSet(foreignKeyValue, foreignTypeKeyValue, association) { + this.foreignKeyValue = foreignKeyValue; + this.foreignTypeKeyValue = foreignTypeKeyValue; + this.association = association; + PolymorphicAssociationSet.__super__.constructor.call(this, this.foreignKeyValue, this.association); + } + + PolymorphicAssociationSet.prototype._getLoadOptions = function() { + var loadOptions; + loadOptions = {}; + loadOptions[this.association.foreignKey] = this.foreignKeyValue; + loadOptions[this.association.foreignTypeKey] = this.foreignTypeKeyValue; + return loadOptions; + }; + + return PolymorphicAssociationSet; + + })(Batman.AssociationSet); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.SetIndex = (function(_super) { + + __extends(SetIndex, _super); + + SetIndex.accessor('toArray', function() { + return this.toArray(); + }); + + Batman.extend(SetIndex.prototype, Batman.Enumerable); + + SetIndex.prototype.propertyClass = Batman.Property; + + function SetIndex(base, key) { + var _this = this; + this.base = base; + this.key = key; + SetIndex.__super__.constructor.call(this); + this._storage = new Batman.Hash; + if (this.base.isEventEmitter) { + this._setObserver = new Batman.SetObserver(this.base); + this._setObserver.observedItemKeys = [this.key]; + this._setObserver.observerForItemAndKey = this.observerForItemAndKey.bind(this); + this._setObserver.on('itemsWereAdded', function() { + var item, items, _i, _len, _results; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(_this._addItem(item)); + } + return _results; + }); + this._setObserver.on('itemsWereRemoved', function() { + var item, items, _i, _len, _results; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(_this._removeItem(item)); + } + return _results; + }); + } + this.base.forEach(this._addItem.bind(this)); + this.startObserving(); + } + + SetIndex.accessor(function(key) { + return this._resultSetForKey(key); + }); + + SetIndex.prototype.startObserving = function() { + var _ref; + return (_ref = this._setObserver) != null ? _ref.startObserving() : void 0; + }; + + SetIndex.prototype.stopObserving = function() { + var _ref; + return (_ref = this._setObserver) != null ? _ref.stopObserving() : void 0; + }; + + SetIndex.prototype.observerForItemAndKey = function(item, key) { + var _this = this; + return function(newValue, oldValue) { + _this._removeItemFromKey(item, oldValue); + return _this._addItemToKey(item, newValue); + }; + }; + + SetIndex.prototype.forEach = function(iterator, ctx) { + var _this = this; + return this._storage.forEach(function(key, set) { + if (set.get('length') > 0) { + return iterator.call(ctx, key, set, _this); + } + }); + }; + + SetIndex.prototype.toArray = function() { + var results; + results = []; + this._storage.forEach(function(key, set) { + if (set.get('length') > 0) { + return results.push(key); + } + }); + return results; + }; + + SetIndex.prototype._addItem = function(item) { + return this._addItemToKey(item, this._keyForItem(item)); + }; + + SetIndex.prototype._addItemToKey = function(item, key) { + return this._resultSetForKey(key).add(item); + }; + + SetIndex.prototype._removeItem = function(item) { + return this._removeItemFromKey(item, this._keyForItem(item)); + }; + + SetIndex.prototype._removeItemFromKey = function(item, key) { + return this._resultSetForKey(key).remove(item); + }; + + SetIndex.prototype._resultSetForKey = function(key) { + return this._storage.getOrSet(key, function() { + return new Batman.Set; + }); + }; + + SetIndex.prototype._keyForItem = function(item) { + return Batman.Keypath.forBaseAndKey(item, this.key).getValue(); + }; + + return SetIndex; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicAssociationSetIndex = (function(_super) { + + __extends(PolymorphicAssociationSetIndex, _super); + + function PolymorphicAssociationSetIndex(association, type, key) { + this.association = association; + this.type = type; + PolymorphicAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModelForType(type).get('loaded'), key); + } + + PolymorphicAssociationSetIndex.prototype._resultSetForKey = function(key) { + var _this = this; + return this._storage.getOrSet(key, function() { + return new _this.association.proxyClass(key, _this.type, _this.association); + }); + }; + + return PolymorphicAssociationSetIndex; + + })(Batman.SetIndex); + +}).call(this); + +(function() { + var __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; }; + + Batman.AssociationSetIndex = (function(_super) { + + __extends(AssociationSetIndex, _super); + + function AssociationSetIndex(association, key) { + this.association = association; + AssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModel().get('loaded'), key); + } + + AssociationSetIndex.prototype._resultSetForKey = function(key) { + var _this = this; + return this._storage.getOrSet(key, function() { + return new _this.association.proxyClass(key, _this.association); + }); + }; + + AssociationSetIndex.prototype._setResultSet = function(key, set) { + return this._storage.set(key, set); + }; + + return AssociationSetIndex; + + })(Batman.SetIndex); + +}).call(this); + +(function() { + var __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; }; + + Batman.UniqueSetIndex = (function(_super) { + + __extends(UniqueSetIndex, _super); + + function UniqueSetIndex() { + this._uniqueIndex = new Batman.Hash; + UniqueSetIndex.__super__.constructor.apply(this, arguments); + } + + UniqueSetIndex.accessor(function(key) { + return this._uniqueIndex.get(key); + }); + + UniqueSetIndex.prototype._addItemToKey = function(item, key) { + this._resultSetForKey(key).add(item); + if (!this._uniqueIndex.hasKey(key)) { + return this._uniqueIndex.set(key, item); + } + }; + + UniqueSetIndex.prototype._removeItemFromKey = function(item, key) { + var resultSet; + resultSet = this._resultSetForKey(key); + UniqueSetIndex.__super__._removeItemFromKey.apply(this, arguments); + if (resultSet.isEmpty()) { + return this._uniqueIndex.unset(key); + } else { + return this._uniqueIndex.set(key, resultSet.toArray()[0]); + } + }; + + return UniqueSetIndex; + + })(Batman.SetIndex); + +}).call(this); + +(function() { + var __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; }; + + Batman.UniqueAssociationSetIndex = (function(_super) { + + __extends(UniqueAssociationSetIndex, _super); + + function UniqueAssociationSetIndex(association, key) { + this.association = association; + UniqueAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModel().get('loaded'), key); + } + + return UniqueAssociationSetIndex; + + })(Batman.UniqueSetIndex); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicUniqueAssociationSetIndex = (function(_super) { + + __extends(PolymorphicUniqueAssociationSetIndex, _super); + + function PolymorphicUniqueAssociationSetIndex(association, type, key) { + this.association = association; + this.type = type; + PolymorphicUniqueAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModelForType(type).get('loaded'), key); + } + + return PolymorphicUniqueAssociationSetIndex; + + })(Batman.UniqueSetIndex); + +}).call(this); + +(function() { + + Batman.URI = (function() { + /* + # URI parsing + */ + + var attributes, childKeyMatchers, decodeQueryComponent, encodeComponent, encodeQueryComponent, keyVal, nameParser, normalizeParams, plus, queryFromParams, r20, strictParser; + + strictParser = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/; + + attributes = ["source", "protocol", "authority", "userInfo", "user", "password", "hostname", "port", "relative", "path", "directory", "file", "query", "hash"]; + + function URI(str) { + var i, matches; + matches = strictParser.exec(str); + i = 14; + while (i--) { + this[attributes[i]] = matches[i] || ''; + } + this.queryParams = this.constructor.paramsFromQuery(this.query); + delete this.authority; + delete this.userInfo; + delete this.relative; + delete this.directory; + delete this.file; + delete this.query; + } + + URI.prototype.queryString = function() { + return this.constructor.queryFromParams(this.queryParams); + }; + + URI.prototype.toString = function() { + return [this.protocol ? "" + this.protocol + ":" : void 0, this.authority() ? "//" : void 0, this.authority(), this.relative()].join(""); + }; + + URI.prototype.userInfo = function() { + return [this.user, this.password ? ":" + this.password : void 0].join(""); + }; + + URI.prototype.authority = function() { + return [this.userInfo(), this.user || this.password ? "@" : void 0, this.hostname, this.port ? ":" + this.port : void 0].join(""); + }; + + URI.prototype.relative = function() { + var query; + query = this.queryString(); + return [this.path, query ? "?" + query : void 0, this.hash ? "#" + this.hash : void 0].join(""); + }; + + URI.prototype.directory = function() { + var splitPath; + splitPath = this.path.split('/'); + if (splitPath.length > 1) { + return splitPath.slice(0, splitPath.length - 1).join('/') + "/"; + } else { + return ""; + } + }; + + URI.prototype.file = function() { + var splitPath; + splitPath = this.path.split("/"); + return splitPath[splitPath.length - 1]; + }; + + /* + # query parsing + */ + + + URI.paramsFromQuery = function(query) { + var matches, params, segment, _i, _len, _ref; + params = {}; + _ref = query.split('&'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + segment = _ref[_i]; + if (matches = segment.match(keyVal)) { + normalizeParams(params, decodeQueryComponent(matches[1]), decodeQueryComponent(matches[2])); + } else { + normalizeParams(params, decodeQueryComponent(segment), null); + } + } + return params; + }; + + URI.decodeQueryComponent = decodeQueryComponent = function(str) { + return decodeURIComponent(str.replace(plus, '%20')); + }; + + nameParser = /^[\[\]]*([^\[\]]+)\]*(.*)/; + + childKeyMatchers = [/^\[\]\[([^\[\]]+)\]$/, /^\[\](.+)$/]; + + plus = /\+/g; + + r20 = /%20/g; + + keyVal = /^([^=]*)=(.*)/; + + normalizeParams = function(params, name, v) { + var after, childKey, k, last, matches, _ref, _ref1, _ref2; + if (matches = name.match(nameParser)) { + k = matches[1]; + after = matches[2]; + } else { + return; + } + if (after === '') { + params[k] = v; + } else if (after === '[]') { + if ((_ref = params[k]) == null) { + params[k] = []; + } + if (Batman.typeOf(params[k]) !== 'Array') { + throw new Error("expected Array (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); + } + params[k].push(v); + } else if (matches = after.match(childKeyMatchers[0]) || after.match(childKeyMatchers[1])) { + childKey = matches[1]; + if ((_ref1 = params[k]) == null) { + params[k] = []; + } + if (Batman.typeOf(params[k]) !== 'Array') { + throw new Error("expected Array (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); + } + last = params[k][params[k].length - 1]; + if (Batman.typeOf(last) === 'Object' && !(childKey in last)) { + normalizeParams(last, childKey, v); + } else { + params[k].push(normalizeParams({}, childKey, v)); + } + } else { + if ((_ref2 = params[k]) == null) { + params[k] = {}; + } + if (Batman.typeOf(params[k]) !== 'Object') { + throw new Error("expected Object (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); + } + params[k] = normalizeParams(params[k], after, v); + } + return params; + }; + + /* + # query building + */ + + + URI.queryFromParams = queryFromParams = function(value, prefix) { + var arrayResults, k, v, valueType; + if (value == null) { + return prefix; + } + valueType = Batman.typeOf(value); + if (!((prefix != null) || valueType === 'Object')) { + throw new Error("value must be an Object"); + } + switch (valueType) { + case 'Array': + return ((function() { + var _i, _len; + arrayResults = []; + if (value.length === 0) { + arrayResults.push(queryFromParams(null, "" + prefix + "[]")); + } else { + for (_i = 0, _len = value.length; _i < _len; _i++) { + v = value[_i]; + arrayResults.push(queryFromParams(v, "" + prefix + "[]")); + } + } + return arrayResults; + })()).join("&"); + case 'Object': + return ((function() { + var _results; + _results = []; + for (k in value) { + v = value[k]; + _results.push(queryFromParams(v, prefix ? "" + prefix + "[" + (encodeQueryComponent(k)) + "]" : encodeQueryComponent(k))); + } + return _results; + })()).join("&"); + default: + if (prefix != null) { + return "" + prefix + "=" + (encodeQueryComponent(value)); + } else { + return encodeQueryComponent(value); + } + } + }; + + URI.encodeComponent = encodeComponent = function(str) { + if (str != null) { + return encodeURIComponent(str); + } else { + return ''; + } + }; + + URI.encodeQueryComponent = encodeQueryComponent = function(str) { + return encodeComponent(str).replace(r20, '+'); + }; + + return URI; + + })(); + +}).call(this); + +(function() { + var __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; }; + + Batman.Request = (function(_super) { + var dataHasFileUploads; + + __extends(Request, _super); + + Request.objectToFormData = function(data) { + var formData, key, pairForList, val, _i, _len, _ref, _ref1; + pairForList = function(key, object, first) { + var k, list, v; + if (first == null) { + first = false; + } + return list = (function() { + switch (Batman.typeOf(object)) { + case 'Object': + list = (function() { + var _results; + _results = []; + for (k in object) { + v = object[k]; + _results.push(pairForList((first ? k : "" + key + "[" + k + "]"), v)); + } + return _results; + })(); + return list.reduce(function(acc, list) { + return acc.concat(list); + }, []); + case 'Array': + return object.reduce(function(acc, element) { + return acc.concat(pairForList("" + key + "[]", element)); + }, []); + default: + return [[key, object != null ? object : ""]]; + } + })(); + }; + formData = new Batman.container.FormData(); + _ref = pairForList("", data, true); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + _ref1 = _ref[_i], key = _ref1[0], val = _ref1[1]; + formData.append(key, val); + } + return formData; + }; + + Request.dataHasFileUploads = dataHasFileUploads = function(data) { + var k, type, v, _i, _len; + if ((typeof File !== "undefined" && File !== null) && data instanceof File) { + return true; + } + type = Batman.typeOf(data); + switch (type) { + case 'Object': + for (k in data) { + v = data[k]; + if (dataHasFileUploads(v)) { + return true; + } + } + break; + case 'Array': + for (_i = 0, _len = data.length; _i < _len; _i++) { + v = data[_i]; + if (dataHasFileUploads(v)) { + return true; + } + } + } + return false; + }; + + Request.wrapAccessor('method', function(core) { + return { + set: function(k, val) { + return core.set.call(this, k, val != null ? typeof val.toUpperCase === "function" ? val.toUpperCase() : void 0 : void 0); + } + }; + }); + + Request.prototype.method = 'GET'; + + Request.prototype.hasFileUploads = function() { + return dataHasFileUploads(this.data); + }; + + Request.prototype.contentType = 'application/x-www-form-urlencoded'; + + Request.prototype.autosend = true; + + function Request(options) { + var handler, handlers, k, _ref; + handlers = {}; + for (k in options) { + handler = options[k]; + if (!(k === 'success' || k === 'error' || k === 'loading' || k === 'loaded')) { + continue; + } + handlers[k] = handler; + delete options[k]; + } + Request.__super__.constructor.call(this, options); + for (k in handlers) { + handler = handlers[k]; + this.on(k, handler); + } + if (((_ref = this.get('url')) != null ? _ref.length : void 0) > 0) { + if (this.autosend) { + this.send(); + } + } else { + this.observe('url', function(url) { + if (url != null) { + return this.send(); + } + }); + } + } + + Request.prototype.send = function() { + return Batman.developer.error("Please source a dependency file for a request implementation"); + }; + + return Request; + + })(Batman.Object); + +}).call(this); + +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __slice = [].slice; + + Batman.Navigator = (function() { + + Navigator.defaultClass = function() { + if (Batman.config.usePushState && Batman.PushStateNavigator.isSupported()) { + return Batman.PushStateNavigator; + } else { + return Batman.HashbangNavigator; + } + }; + + Navigator.forApp = function(app) { + return new (this.defaultClass())(app); + }; + + function Navigator(app) { + this.app = app; + this.handleCurrentLocation = __bind(this.handleCurrentLocation, this); + + } + + Navigator.prototype.start = function() { + var _this = this; + if (typeof window === 'undefined') { + return; + } + if (this.started) { + return; + } + this.started = true; + this.startWatching(); + Batman.currentApp.prevent('ready'); + return Batman.setImmediate(function() { + if (_this.started && Batman.currentApp) { + _this.handleCurrentLocation(); + return Batman.currentApp.allowAndFire('ready'); + } + }); + }; + + Navigator.prototype.stop = function() { + this.stopWatching(); + return this.started = false; + }; + + Navigator.prototype.handleLocation = function(location) { + var path; + path = this.pathFromLocation(location); + if (path === this.cachedPath) { + return; + } + return this.dispatch(path); + }; + + Navigator.prototype.handleCurrentLocation = function() { + return this.handleLocation(window.location); + }; + + Navigator.prototype.dispatch = function(params) { + return this.cachedPath = this.app.get('dispatcher').dispatch(params); + }; + + Navigator.prototype.push = function(params) { + var path; + path = this.dispatch(params); + this.pushState(null, '', path); + return path; + }; + + Navigator.prototype.replace = function(params) { + var path; + path = this.dispatch(params); + this.replaceState(null, '', path); + return path; + }; + + Navigator.prototype.redirect = Navigator.prototype.push; + + Navigator.prototype.normalizePath = function() { + var i, seg, segments; + segments = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + segments = (function() { + var _i, _len, _results; + _results = []; + for (i = _i = 0, _len = segments.length; _i < _len; i = ++_i) { + seg = segments[i]; + _results.push(("" + seg).replace(/^(?!\/)/, '/').replace(/\/+$/, '')); + } + return _results; + })(); + return segments.join('') || '/'; + }; + + Navigator.normalizePath = Navigator.prototype.normalizePath; + + return Navigator; + + })(); + +}).call(this); + +(function() { + var __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; }; + + Batman.PushStateNavigator = (function(_super) { + + __extends(PushStateNavigator, _super); + + function PushStateNavigator() { + return PushStateNavigator.__super__.constructor.apply(this, arguments); + } + + PushStateNavigator.isSupported = function() { + var _ref; + return (typeof window !== "undefined" && window !== null ? (_ref = window.history) != null ? _ref.pushState : void 0 : void 0) != null; + }; + + PushStateNavigator.prototype.startWatching = function() { + return Batman.addEventListener(window, 'popstate', this.handleCurrentLocation); + }; + + PushStateNavigator.prototype.stopWatching = function() { + return Batman.removeEventListener(window, 'popstate', this.handleCurrentLocation); + }; + + PushStateNavigator.prototype.pushState = function(stateObject, title, path) { + return window.history.pushState(stateObject, title, this.linkTo(path)); + }; + + PushStateNavigator.prototype.replaceState = function(stateObject, title, path) { + return window.history.replaceState(stateObject, title, this.linkTo(path)); + }; + + PushStateNavigator.prototype.linkTo = function(url) { + return this.normalizePath(Batman.config.pathPrefix, url); + }; + + PushStateNavigator.prototype.pathFromLocation = function(location) { + var fullPath, prefixPattern; + fullPath = "" + (location.pathname || '') + (location.search || ''); + prefixPattern = new RegExp("^" + (this.normalizePath(Batman.config.pathPrefix))); + return this.normalizePath(fullPath.replace(prefixPattern, '')); + }; + + PushStateNavigator.prototype.handleLocation = function(location) { + var hashbangPath, path; + path = this.pathFromLocation(location); + if (path === '/' && (hashbangPath = Batman.HashbangNavigator.prototype.pathFromLocation(location)) !== '/') { + return this.replace(hashbangPath); + } else { + return PushStateNavigator.__super__.handleLocation.apply(this, arguments); + } + }; + + return PushStateNavigator; + + })(Batman.Navigator); + +}).call(this); + +(function() { + var __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; }; + + Batman.HashbangNavigator = (function(_super) { + + __extends(HashbangNavigator, _super); + + function HashbangNavigator() { + return HashbangNavigator.__super__.constructor.apply(this, arguments); + } + + HashbangNavigator.prototype.HASH_PREFIX = '#!'; + + if ((typeof window !== "undefined" && window !== null) && 'onhashchange' in window) { + HashbangNavigator.prototype.startWatching = function() { + return Batman.addEventListener(window, 'hashchange', this.handleCurrentLocation); + }; + HashbangNavigator.prototype.stopWatching = function() { + return Batman.removeEventListener(window, 'hashchange', this.handleCurrentLocation); + }; + } else { + HashbangNavigator.prototype.startWatching = function() { + return this.interval = setInterval(this.handleCurrentLocation, 100); + }; + HashbangNavigator.prototype.stopWatching = function() { + return this.interval = clearInterval(this.interval); + }; + } + + HashbangNavigator.prototype.pushState = function(stateObject, title, path) { + return window.location.hash = this.linkTo(path); + }; + + HashbangNavigator.prototype.replaceState = function(stateObject, title, path) { + var loc; + loc = window.location; + return loc.replace("" + loc.pathname + loc.search + (this.linkTo(path))); + }; + + HashbangNavigator.prototype.linkTo = function(url) { + return this.HASH_PREFIX + url; + }; + + HashbangNavigator.prototype.pathFromLocation = function(location) { + var hash; + hash = location.hash; + if ((hash != null ? hash.substr(0, 2) : void 0) === this.HASH_PREFIX) { + return this.normalizePath(hash.substr(2)); + } else { + return '/'; + } + }; + + HashbangNavigator.prototype.handleLocation = function(location) { + var realPath; + if (!Batman.config.usePushState) { + return HashbangNavigator.__super__.handleLocation.apply(this, arguments); + } + realPath = Batman.PushStateNavigator.prototype.pathFromLocation(location); + if (realPath === '/') { + return HashbangNavigator.__super__.handleLocation.apply(this, arguments); + } else { + return location.replace(this.normalizePath("" + Batman.config.pathPrefix + (this.linkTo(realPath)))); + } + }; + + return HashbangNavigator; + + })(Batman.Navigator); + +}).call(this); + +(function() { + + Batman.RouteMap = (function() { + + RouteMap.prototype.memberRoute = null; + + RouteMap.prototype.collectionRoute = null; + + function RouteMap() { + this.childrenByOrder = []; + this.childrenByName = {}; + } + + RouteMap.prototype.routeForParams = function(params) { + var route, _i, _len, _ref; + _ref = this.childrenByOrder; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + route = _ref[_i]; + if (route.test(params)) { + return route; + } + } + return void 0; + }; + + RouteMap.prototype.addRoute = function(name, route) { + var base, names, + _this = this; + this.childrenByOrder.push(route); + if (name.length > 0 && (names = name.split('.')).length > 0) { + base = names.shift(); + if (!this.childrenByName[base]) { + this.childrenByName[base] = new Batman.RouteMap; + } + this.childrenByName[base].addRoute(names.join('.'), route); + } else { + if (route.get('member')) { + Batman.developer["do"](function() { + if (_this.memberRoute) { + return Batman.developer.error("Member route with name " + name + " already exists!"); + } + }); + this.memberRoute = route; + } else { + Batman.developer["do"](function() { + if (_this.collectionRoute) { + return Batman.developer.error("Collection route with name " + name + " already exists!"); + } + }); + this.collectionRoute = route; + } + } + return true; + }; + + return RouteMap; + + })(); + +}).call(this); + +(function() { + var __slice = [].slice; + + Batman.RouteMapBuilder = (function() { + + RouteMapBuilder.BUILDER_FUNCTIONS = ['resources', 'member', 'collection', 'route', 'root']; + + RouteMapBuilder.ROUTES = { + index: { + cardinality: 'collection', + path: function(resource) { + return resource; + }, + name: function(resource) { + return resource; + } + }, + "new": { + cardinality: 'collection', + path: function(resource) { + return "" + resource + "/new"; + }, + name: function(resource) { + return "" + resource + ".new"; + } + }, + show: { + cardinality: 'member', + path: function(resource) { + return "" + resource + "/:id"; + }, + name: function(resource) { + return resource; + } + }, + edit: { + cardinality: 'member', + path: function(resource) { + return "" + resource + "/:id/edit"; + }, + name: function(resource) { + return "" + resource + ".edit"; + } + }, + collection: { + cardinality: 'collection', + path: function(resource, name) { + return "" + resource + "/" + name; + }, + name: function(resource, name) { + return "" + resource + "." + name; + } + }, + member: { + cardinality: 'member', + path: function(resource, name) { + return "" + resource + "/:id/" + name; + }, + name: function(resource, name) { + return "" + resource + "." + name; + } + } + }; + + function RouteMapBuilder(app, routeMap, parent, baseOptions) { + this.app = app; + this.routeMap = routeMap; + this.parent = parent; + this.baseOptions = baseOptions != null ? baseOptions : {}; + if (this.parent) { + this.rootPath = this.parent._nestingPath(); + this.rootName = this.parent._nestingName(); + } else { + this.rootPath = ''; + this.rootName = ''; + } + } + + RouteMapBuilder.prototype.resources = function() { + var action, actions, arg, args, as, callback, childBuilder, controller, included, k, options, path, resourceName, resourceNames, resourceRoot, routeOptions, routeTemplate, v, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + resourceNames = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + if (typeof arg === 'string') { + _results.push(arg); + } + } + return _results; + })(); + if (typeof args[args.length - 1] === 'function') { + callback = args.pop(); + } + if (typeof args[args.length - 1] === 'object') { + options = args.pop(); + } else { + options = {}; + } + actions = { + index: true, + "new": true, + show: true, + edit: true + }; + if (options.except) { + _ref = options.except; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + actions[k] = false; + } + delete options.except; + } else if (options.only) { + for (k in actions) { + v = actions[k]; + actions[k] = false; + } + _ref1 = options.only; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + k = _ref1[_j]; + actions[k] = true; + } + delete options.only; + } + for (_k = 0, _len2 = resourceNames.length; _k < _len2; _k++) { + resourceName = resourceNames[_k]; + resourceRoot = Batman.helpers.pluralize(resourceName); + controller = Batman.helpers.camelize(resourceRoot, true); + childBuilder = this._childBuilder({ + controller: controller + }); + if (callback != null) { + callback.call(childBuilder); + } + for (action in actions) { + included = actions[action]; + if (!(included)) { + continue; + } + routeTemplate = this.constructor.ROUTES[action]; + as = routeTemplate.name(resourceRoot); + path = routeTemplate.path(resourceRoot); + routeOptions = Batman.extend({ + controller: controller, + action: action, + path: path, + as: as + }, options); + childBuilder[routeTemplate.cardinality](action, routeOptions); + } + } + return true; + }; + + RouteMapBuilder.prototype.member = function() { + return this._addRoutesWithCardinality.apply(this, ['member'].concat(__slice.call(arguments))); + }; + + RouteMapBuilder.prototype.collection = function() { + return this._addRoutesWithCardinality.apply(this, ['collection'].concat(__slice.call(arguments))); + }; + + RouteMapBuilder.prototype.root = function(signature, options) { + return this.route('/', signature, options); + }; + + RouteMapBuilder.prototype.route = function(path, signature, options, callback) { + if (!callback) { + if (typeof options === 'function') { + callback = options; + options = void 0; + } else if (typeof signature === 'function') { + callback = signature; + signature = void 0; + } + } + if (!options) { + if (typeof signature === 'string') { + options = { + signature: signature + }; + } else { + options = signature; + } + options || (options = {}); + } else { + if (signature) { + options.signature = signature; + } + } + if (callback) { + options.callback = callback; + } + options.as || (options.as = this._nameFromPath(path)); + options.path = path; + return this._addRoute(options); + }; + + RouteMapBuilder.prototype._addRoutesWithCardinality = function() { + var cardinality, name, names, options, resourceRoot, routeOptions, routeTemplate, _i, _j, _len; + cardinality = arguments[0], names = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), options = arguments[_i++]; + if (typeof options === 'string') { + names.push(options); + options = {}; + } + options = Batman.extend({}, this.baseOptions, options); + options[cardinality] = true; + routeTemplate = this.constructor.ROUTES[cardinality]; + resourceRoot = options.controller; + for (_j = 0, _len = names.length; _j < _len; _j++) { + name = names[_j]; + routeOptions = Batman.extend({ + action: name + }, options); + if (routeOptions.path == null) { + routeOptions.path = routeTemplate.path(resourceRoot, name); + } + if (routeOptions.as == null) { + routeOptions.as = routeTemplate.name(resourceRoot, name); + } + this._addRoute(routeOptions); + } + return true; + }; + + RouteMapBuilder.prototype._addRoute = function(options) { + var klass, name, path, route; + if (options == null) { + options = {}; + } + path = this.rootPath + options.path; + name = this.rootName + Batman.helpers.camelize(options.as, true); + delete options.as; + delete options.path; + klass = options.callback ? Batman.CallbackActionRoute : Batman.ControllerActionRoute; + options.app = this.app; + route = new klass(path, options); + return this.routeMap.addRoute(name, route); + }; + + RouteMapBuilder.prototype._nameFromPath = function(path) { + path = path.replace(Batman.Route.regexps.namedOrSplat, '').replace(/\/+/g, '.').replace(/(^\.)|(\.$)/g, ''); + return path; + }; + + RouteMapBuilder.prototype._nestingPath = function() { + var nestingParam, nestingSegment; + if (!this.parent) { + return ""; + } else { + nestingParam = ":" + Batman.helpers.singularize(this.baseOptions.controller) + "Id"; + nestingSegment = Batman.helpers.underscore(this.baseOptions.controller); + return "" + (this.parent._nestingPath()) + "/" + nestingSegment + "/" + nestingParam + "/"; + } + }; + + RouteMapBuilder.prototype._nestingName = function() { + if (!this.parent) { + return ""; + } else { + return this.baseOptions.controller + "."; + } + }; + + RouteMapBuilder.prototype._childBuilder = function(baseOptions) { + if (baseOptions == null) { + baseOptions = {}; + } + return new Batman.RouteMapBuilder(this.app, this.routeMap, this, baseOptions); + }; + + return RouteMapBuilder; + + })(); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.App = (function(_super) { + var name, _fn, _i, _len, _ref, + _this = this; + + __extends(App, _super); + + function App() { + return App.__super__.constructor.apply(this, arguments); + } + + App.classAccessor('currentParams', { + get: function() { + return new Batman.Hash; + }, + 'final': true + }); + + App.classAccessor('paramsManager', { + get: function() { + var nav, params; + if (!(nav = this.get('navigator'))) { + return; + } + params = this.get('currentParams'); + return params.replacer = new Batman.ParamsReplacer(nav, params); + }, + 'final': true + }); + + App.classAccessor('paramsPusher', { + get: function() { + var nav, params; + if (!(nav = this.get('navigator'))) { + return; + } + params = this.get('currentParams'); + return params.pusher = new Batman.ParamsPusher(nav, params); + }, + 'final': true + }); + + App.classAccessor('routes', function() { + return new Batman.NamedRouteQuery(this.get('routeMap')); + }); + + App.classAccessor('routeMap', function() { + return new Batman.RouteMap; + }); + + App.classAccessor('routeMapBuilder', function() { + return new Batman.RouteMapBuilder(this, this.get('routeMap')); + }); + + App.classAccessor('dispatcher', function() { + return new Batman.Dispatcher(this, this.get('routeMap')); + }); + + App.classAccessor('controllers', function() { + return this.get('dispatcher.controllers'); + }); + + App.classAccessor('_renderContext', function() { + return Batman.RenderContext.base.descend(this); + }); + + App.requirePath = ''; + + Batman.developer["do"](function() { + App.require = function() { + var base, name, names, path, _i, _len, + _this = this; + path = arguments[0], names = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + base = this.requirePath + path; + for (_i = 0, _len = names.length; _i < _len; _i++) { + name = names[_i]; + this.prevent('run'); + path = base + '/' + name + '.coffee'; + new Batman.Request({ + url: path, + type: 'html', + success: function(response) { + CoffeeScript["eval"](response); + _this.allow('run'); + if (!_this.isPrevented('run')) { + _this.fire('loaded'); + } + if (_this.wantsToRun) { + return _this.run(); + } + } + }); + } + return this; + }; + App.controller = function() { + var names; + names = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + names = names.map(function(n) { + return n + '_controller'; + }); + return this.require.apply(this, ['controllers'].concat(__slice.call(names))); + }; + App.model = function() { + return this.require.apply(this, ['models'].concat(__slice.call(arguments))); + }; + return App.view = function() { + return this.require.apply(this, ['views'].concat(__slice.call(arguments))); + }; + }); + + App.layout = void 0; + + _ref = Batman.RouteMapBuilder.BUILDER_FUNCTIONS; + _fn = function(name) { + return App[name] = function() { + var _ref1; + return (_ref1 = this.get('routeMapBuilder'))[name].apply(_ref1, arguments); + }; + }; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + _fn(name); + } + + App.event('ready').oneShot = true; + + App.event('run').oneShot = true; + + App.run = function() { + var layout, layoutClass, + _this = this; + if (Batman.currentApp) { + if (Batman.currentApp === this) { + return; + } + Batman.currentApp.stop(); + } + if (this.hasRun) { + return false; + } + if (this.isPrevented('run')) { + this.wantsToRun = true; + return false; + } else { + delete this.wantsToRun; + } + Batman.currentApp = this; + Batman.App.set('current', this); + if (this.get('dispatcher') == null) { + this.set('dispatcher', new Batman.Dispatcher(this, this.get('routeMap'))); + this.set('controllers', this.get('dispatcher.controllers')); + } + if (this.get('navigator') == null) { + this.set('navigator', Batman.Navigator.forApp(this)); + this.on('run', function() { + Batman.navigator = _this.get('navigator'); + if (Object.keys(_this.get('dispatcher').routeMap).length > 0) { + return Batman.navigator.start(); + } + }); + } + this.observe('layout', function(layout) { + return layout != null ? layout.on('ready', function() { + return _this.fire('ready'); + }) : void 0; + }); + layout = this.get('layout'); + if (layout) { + if (typeof layout === 'string') { + layoutClass = this[Batman.helpers.camelize(layout) + 'View']; + } + } else { + if (layout !== null) { + layoutClass = Batman.View; + } + } + if (layoutClass) { + layout = this.set('layout', new layoutClass({ + context: this, + node: document + })); + } + this.hasRun = true; + this.fire('run'); + return this; + }; + + App.event('ready').oneShot = true; + + App.event('stop').oneShot = true; + + App.stop = function() { + var _ref1; + if ((_ref1 = this.navigator) != null) { + _ref1.stop(); + } + Batman.navigator = null; + this.hasRun = false; + this.fire('stop'); + return this; + }; + + return App; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + + Batman.Association = (function() { + + Association.prototype.associationType = ''; + + Association.prototype.isPolymorphic = false; + + Association.prototype.defaultOptions = { + saveInline: true, + autoload: true, + nestUrl: false + }; + + function Association(model, label, options) { + var defaultOptions, encoder, getAccessor, self; + this.model = model; + this.label = label; + if (options == null) { + options = {}; + } + defaultOptions = { + namespace: Batman.currentApp, + name: Batman.helpers.camelize(Batman.helpers.singularize(this.label)) + }; + this.options = Batman.extend(defaultOptions, this.defaultOptions, options); + if (this.options.nestUrl) { + if (!(this.model.urlNestsUnder != null)) { + developer.error("You must persist the the model " + this.model.constructor.name + " to use the url helpers on an association"); + } + this.model.urlNestsUnder(Batman.helpers.underscore(this.getRelatedModel().get('resourceName'))); + } + if (this.options.extend != null) { + Batman.extend(this, this.options.extend); + } + encoder = { + encode: this.options.saveInline ? this.encoder() : false, + decode: this.decoder() + }; + this.model.encode(this.label, encoder); + self = this; + getAccessor = function() { + return self.getAccessor.call(this, self, this.model, this.label); + }; + this.model.accessor(this.label, { + get: getAccessor, + set: model.defaultAccessor.set, + unset: model.defaultAccessor.unset + }); + } + + Association.prototype.getRelatedModel = function() { + var className, relatedModel, scope; + scope = this.options.namespace || Batman.currentApp; + className = this.options.name; + relatedModel = scope != null ? scope[className] : void 0; + Batman.developer["do"](function() { + if ((Batman.currentApp != null) && !relatedModel) { + return Batman.developer.warn("Related model " + className + " hasn't loaded yet."); + } + }); + return relatedModel; + }; + + Association.prototype.getFromAttributes = function(record) { + return record.get("attributes." + this.label); + }; + + Association.prototype.setIntoAttributes = function(record, value) { + return record.get('attributes').set(this.label, value); + }; + + Association.prototype.inverse = function() { + var inverse, relatedAssocs, + _this = this; + if (relatedAssocs = this.getRelatedModel()._batman.get('associations')) { + if (this.options.inverseOf) { + return relatedAssocs.getByLabel(this.options.inverseOf); + } + inverse = null; + relatedAssocs.forEach(function(label, assoc) { + if (assoc.getRelatedModel() === _this.model) { + return inverse = assoc; + } + }); + return inverse; + } + }; + + Association.prototype.reset = function() { + delete this.index; + return true; + }; + + return Association; + + })(); + +}).call(this); + +(function() { + var __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; }; + + Batman.PluralAssociation = (function(_super) { + + __extends(PluralAssociation, _super); + + function PluralAssociation() { + return PluralAssociation.__super__.constructor.apply(this, arguments); + } + + PluralAssociation.prototype.proxyClass = Batman.AssociationSet; + + PluralAssociation.prototype.isSingular = false; + + PluralAssociation.prototype.setForRecord = Batman.Property.wrapTrackingPrevention(function(record) { + var id; + if (id = record.get(this.primaryKey)) { + return this.setIndex().get(id); + } else { + return new this.proxyClass(void 0, this); + } + }); + + PluralAssociation.prototype.getAccessor = function(self, model, label) { + var relatedRecords, setInAttributes, + _this = this; + if (!self.getRelatedModel()) { + return; + } + if (setInAttributes = self.getFromAttributes(this)) { + return setInAttributes; + } else { + relatedRecords = self.setForRecord(this); + self.setIntoAttributes(this, relatedRecords); + Batman.Property.withoutTracking(function() { + if (self.options.autoload && !_this.isNew() && !relatedRecords.loaded) { + return relatedRecords.load(function(error, records) { + if (error) { + throw error; + } + }); + } + }); + return relatedRecords; + } + }; + + PluralAssociation.prototype.setIndex = function() { + this.index || (this.index = new Batman.AssociationSetIndex(this, this[this.indexRelatedModelOn])); + return this.index; + }; + + return PluralAssociation; + + })(Batman.Association); + +}).call(this); + +(function() { + var __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; }; + + Batman.HasManyAssociation = (function(_super) { + + __extends(HasManyAssociation, _super); + + HasManyAssociation.prototype.associationType = 'hasMany'; + + HasManyAssociation.prototype.indexRelatedModelOn = 'foreignKey'; + + function HasManyAssociation(model, label, options) { + if (options != null ? options.as : void 0) { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.PolymorphicHasManyAssociation, arguments, function(){}); + } + HasManyAssociation.__super__.constructor.apply(this, arguments); + this.primaryKey = this.options.primaryKey || "id"; + this.foreignKey = this.options.foreignKey || ("" + (Batman.helpers.underscore(model.get('resourceName'))) + "_id"); + } + + HasManyAssociation.prototype.apply = function(baseSaveError, base) { + var relations, set, + _this = this; + if (!baseSaveError) { + if (relations = this.getFromAttributes(base)) { + relations.forEach(function(model) { + return model.set(_this.foreignKey, base.get(_this.primaryKey)); + }); + } + base.set(this.label, set = this.setForRecord(base)); + if (base.lifecycle.get('state') === 'creating') { + return set.markAsLoaded(); + } + } + }; + + HasManyAssociation.prototype.encoder = function() { + var association; + association = this; + return function(relationSet, _, __, record) { + var jsonArray; + if (relationSet != null) { + jsonArray = []; + relationSet.forEach(function(relation) { + var relationJSON; + relationJSON = relation.toJSON(); + if (!association.inverse() || association.inverse().options.encodeForeignKey) { + relationJSON[association.foreignKey] = record.get(association.primaryKey); + } + return jsonArray.push(relationJSON); + }); + } + return jsonArray; + }; + }; + + HasManyAssociation.prototype.decoder = function() { + var association; + association = this; + return function(data, key, _, __, parentRecord) { + var existingRecord, existingRelations, jsonObject, newRelations, record, relatedModel, savedRecord, _i, _len; + if (relatedModel = association.getRelatedModel()) { + existingRelations = association.getFromAttributes(parentRecord) || association.setForRecord(parentRecord); + newRelations = existingRelations.filter(function(relation) { + return relation.isNew(); + }).toArray(); + for (_i = 0, _len = data.length; _i < _len; _i++) { + jsonObject = data[_i]; + record = new relatedModel(); + record._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + existingRecord = relatedModel.get('loaded').indexedByUnique('id').get(record.get('id')); + if (existingRecord != null) { + existingRecord._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + record = existingRecord; + } else { + if (newRelations.length > 0) { + savedRecord = newRelations.shift(); + savedRecord._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + record = savedRecord; + } + } + record = relatedModel._mapIdentity(record); + existingRelations.add(record); + if (association.options.inverseOf) { + record.set(association.options.inverseOf, parentRecord); + } + } + existingRelations.markAsLoaded(); + } else { + Batman.developer.error("Can't decode model " + association.options.name + " because it hasn't been loaded yet!"); + } + return existingRelations; + }; + }; + + return HasManyAssociation; + + })(Batman.PluralAssociation); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicHasManyAssociation = (function(_super) { + + __extends(PolymorphicHasManyAssociation, _super); + + PolymorphicHasManyAssociation.prototype.proxyClass = Batman.PolymorphicAssociationSet; + + PolymorphicHasManyAssociation.prototype.isPolymorphic = true; + + function PolymorphicHasManyAssociation(model, label, options) { + options.inverseOf = this.foreignLabel = options.as; + delete options.as; + options.foreignKey || (options.foreignKey = "" + this.foreignLabel + "_id"); + PolymorphicHasManyAssociation.__super__.constructor.call(this, model, label, options); + this.foreignTypeKey = options.foreignTypeKey || ("" + this.foreignLabel + "_type"); + this.model.encode(this.foreignTypeKey); + } + + PolymorphicHasManyAssociation.prototype.apply = function(baseSaveError, base) { + var relations, + _this = this; + if (!baseSaveError) { + if (relations = this.getFromAttributes(base)) { + PolymorphicHasManyAssociation.__super__.apply.apply(this, arguments); + relations.forEach(function(model) { + return model.set(_this.foreignTypeKey, _this.modelType()); + }); + } + } + return true; + }; + + PolymorphicHasManyAssociation.prototype.getRelatedModelForType = function() { + return this.getRelatedModel(); + }; + + PolymorphicHasManyAssociation.prototype.modelType = function() { + return this.model.get('resourceName'); + }; + + PolymorphicHasManyAssociation.prototype.setIndex = function() { + if (!this.typeIndex) { + this.typeIndex = new Batman.PolymorphicAssociationSetIndex(this, this.modelType(), this[this.indexRelatedModelOn]); + } + return this.typeIndex; + }; + + PolymorphicHasManyAssociation.prototype.encoder = function() { + var association; + association = this; + return function(relationSet, _, __, record) { + var jsonArray; + if (relationSet != null) { + jsonArray = []; + relationSet.forEach(function(relation) { + var relationJSON; + relationJSON = relation.toJSON(); + relationJSON[association.foreignKey] = record.get(association.primaryKey); + relationJSON[association.foreignTypeKey] = association.modelType(); + return jsonArray.push(relationJSON); + }); + } + return jsonArray; + }; + }; + + return PolymorphicHasManyAssociation; + + })(Batman.HasManyAssociation); + +}).call(this); + +(function() { + var __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; }; + + Batman.SingularAssociation = (function(_super) { + + __extends(SingularAssociation, _super); + + function SingularAssociation() { + return SingularAssociation.__super__.constructor.apply(this, arguments); + } + + SingularAssociation.prototype.isSingular = true; + + SingularAssociation.prototype.getAccessor = function(self, model, label) { + var proxy, recordInAttributes; + if (recordInAttributes = self.getFromAttributes(this)) { + return recordInAttributes; + } + if (self.getRelatedModel()) { + proxy = this.associationProxy(self); + Batman.Property.withoutTracking(function() { + if (!proxy.get('loaded') && self.options.autoload) { + return proxy.load(); + } + }); + return proxy; + } + }; + + SingularAssociation.prototype.setIndex = function() { + this.index || (this.index = new Batman.UniqueAssociationSetIndex(this, this[this.indexRelatedModelOn])); + return this.index; + }; + + return SingularAssociation; + + })(Batman.Association); + +}).call(this); + +(function() { + var __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; }; + + Batman.HasOneAssociation = (function(_super) { + + __extends(HasOneAssociation, _super); + + HasOneAssociation.prototype.associationType = 'hasOne'; + + HasOneAssociation.prototype.proxyClass = Batman.HasOneProxy; + + HasOneAssociation.prototype.indexRelatedModelOn = 'foreignKey'; + + function HasOneAssociation() { + HasOneAssociation.__super__.constructor.apply(this, arguments); + this.primaryKey = this.options.primaryKey || "id"; + this.foreignKey = this.options.foreignKey || ("" + (Batman.helpers.underscore(this.model.get('resourceName'))) + "_id"); + } + + HasOneAssociation.prototype.apply = function(baseSaveError, base) { + var relation; + if (relation = this.getFromAttributes(base)) { + return relation.set(this.foreignKey, base.get(this.primaryKey)); + } + }; + + HasOneAssociation.prototype.encoder = function() { + var association; + association = this; + return function(val, key, object, record) { + var json; + if (!association.options.saveInline) { + return; + } + if (json = val.toJSON()) { + json[association.foreignKey] = record.get(association.primaryKey); + } + return json; + }; + }; + + HasOneAssociation.prototype.decoder = function() { + var association; + association = this; + return function(data, _, __, ___, parentRecord) { + var record, relatedModel; + relatedModel = association.getRelatedModel(); + record = new relatedModel(); + record._withoutDirtyTracking(function() { + return this.fromJSON(data); + }); + if (association.options.inverseOf) { + record.set(association.options.inverseOf, parentRecord); + } + record = relatedModel._mapIdentity(record); + return record; + }; + }; + + return HasOneAssociation; + + })(Batman.SingularAssociation); + +}).call(this); + +(function() { + var __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; }; + + Batman.BelongsToAssociation = (function(_super) { + + __extends(BelongsToAssociation, _super); + + BelongsToAssociation.prototype.associationType = 'belongsTo'; + + BelongsToAssociation.prototype.proxyClass = Batman.BelongsToProxy; + + BelongsToAssociation.prototype.indexRelatedModelOn = 'primaryKey'; + + BelongsToAssociation.prototype.defaultOptions = { + saveInline: false, + autoload: true, + encodeForeignKey: true + }; + + function BelongsToAssociation(model, label, options) { + if (options != null ? options.polymorphic : void 0) { + delete options.polymorphic; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args), t = typeof result; + return t == "object" || t == "function" ? result || child : child; + })(Batman.PolymorphicBelongsToAssociation, arguments, function(){}); + } + BelongsToAssociation.__super__.constructor.apply(this, arguments); + this.foreignKey = this.options.foreignKey || ("" + this.label + "_id"); + this.primaryKey = this.options.primaryKey || "id"; + if (this.options.encodeForeignKey) { + this.model.encode(this.foreignKey); + } + } + + BelongsToAssociation.prototype.encoder = function() { + return function(val) { + return val.toJSON(); + }; + }; + + BelongsToAssociation.prototype.decoder = function() { + var association; + association = this; + return function(data, _, __, ___, childRecord) { + var inverse, record, relatedModel; + relatedModel = association.getRelatedModel(); + record = new relatedModel(); + record._withoutDirtyTracking(function() { + return this.fromJSON(data); + }); + record = relatedModel._mapIdentity(record); + if (association.options.inverseOf) { + if (inverse = association.inverse()) { + if (inverse instanceof Batman.HasManyAssociation) { + childRecord.set(association.foreignKey, record.get(association.primaryKey)); + } else { + record.set(inverse.label, childRecord); + } + } + } + childRecord.set(association.label, record); + return record; + }; + }; + + BelongsToAssociation.prototype.apply = function(base) { + var foreignValue, model; + if (model = base.get(this.label)) { + foreignValue = model.get(this.primaryKey); + if (foreignValue !== void 0) { + return base.set(this.foreignKey, foreignValue); + } + } + }; + + return BelongsToAssociation; + + })(Batman.SingularAssociation); + +}).call(this); + +(function() { + var __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; }; + + Batman.PolymorphicBelongsToAssociation = (function(_super) { + + __extends(PolymorphicBelongsToAssociation, _super); + + PolymorphicBelongsToAssociation.prototype.isPolymorphic = true; + + PolymorphicBelongsToAssociation.prototype.proxyClass = Batman.PolymorphicBelongsToProxy; + + PolymorphicBelongsToAssociation.prototype.defaultOptions = Batman.mixin({}, Batman.BelongsToAssociation.prototype.defaultOptions, { + encodeForeignTypeKey: true + }); + + function PolymorphicBelongsToAssociation() { + PolymorphicBelongsToAssociation.__super__.constructor.apply(this, arguments); + this.foreignTypeKey = this.options.foreignTypeKey || ("" + this.label + "_type"); + if (this.options.encodeForeignTypeKey) { + this.model.encode(this.foreignTypeKey); + } + this.typeIndicies = {}; + } + + PolymorphicBelongsToAssociation.prototype.getRelatedModel = false; + + PolymorphicBelongsToAssociation.prototype.setIndex = false; + + PolymorphicBelongsToAssociation.prototype.inverse = false; + + PolymorphicBelongsToAssociation.prototype.apply = function(base) { + var foreignTypeValue, instanceOrProxy, model; + PolymorphicBelongsToAssociation.__super__.apply.apply(this, arguments); + if (instanceOrProxy = base.get(this.label)) { + if (instanceOrProxy instanceof Batman.AssociationProxy) { + model = instanceOrProxy.association.model; + } else { + model = instanceOrProxy.constructor; + } + foreignTypeValue = model.get('resourceName'); + return base.set(this.foreignTypeKey, foreignTypeValue); + } + }; + + PolymorphicBelongsToAssociation.prototype.getAccessor = function(self, model, label) { + var proxy, recordInAttributes; + if (recordInAttributes = self.getFromAttributes(this)) { + return recordInAttributes; + } + if (self.getRelatedModelForType(this.get(self.foreignTypeKey))) { + proxy = this.associationProxy(self); + Batman.Property.withoutTracking(function() { + if (!proxy.get('loaded') && self.options.autoload) { + return proxy.load(); + } + }); + return proxy; + } + }; + + PolymorphicBelongsToAssociation.prototype.url = function(recordOptions) { + var ending, helper, id, inverse, root, type, _ref, _ref1; + type = (_ref = recordOptions.data) != null ? _ref[this.foreignTypeKey] : void 0; + if (type && (inverse = this.inverseForType(type))) { + root = Batman.helpers.pluralize(type).toLowerCase(); + id = (_ref1 = recordOptions.data) != null ? _ref1[this.foreignKey] : void 0; + helper = inverse.isSingular ? "singularize" : "pluralize"; + ending = Batman.helpers[helper](inverse.label); + return "/" + root + "/" + id + "/" + ending; + } + }; + + PolymorphicBelongsToAssociation.prototype.getRelatedModelForType = function(type) { + var relatedModel, scope; + scope = this.options.namespace || Batman.currentApp; + if (type) { + relatedModel = scope != null ? scope[type] : void 0; + relatedModel || (relatedModel = scope != null ? scope[Batman.helpers.camelize(type)] : void 0); + } + Batman.developer["do"](function() { + if ((Batman.currentApp != null) && !relatedModel) { + return Batman.developer.warn("Related model " + type + " for polymorphic association not found."); + } + }); + return relatedModel; + }; + + PolymorphicBelongsToAssociation.prototype.setIndexForType = function(type) { + var _base; + (_base = this.typeIndicies)[type] || (_base[type] = new Batman.PolymorphicUniqueAssociationSetIndex(this, type, this.primaryKey)); + return this.typeIndicies[type]; + }; + + PolymorphicBelongsToAssociation.prototype.inverseForType = function(type) { + var inverse, relatedAssocs, _ref, + _this = this; + if (relatedAssocs = (_ref = this.getRelatedModelForType(type)) != null ? _ref._batman.get('associations') : void 0) { + if (this.options.inverseOf) { + return relatedAssocs.getByLabel(this.options.inverseOf); + } + inverse = null; + relatedAssocs.forEach(function(label, assoc) { + if (assoc.getRelatedModel() === _this.model) { + return inverse = assoc; + } + }); + return inverse; + } + }; + + PolymorphicBelongsToAssociation.prototype.decoder = function() { + var association; + association = this; + return function(data, key, response, ___, childRecord) { + var foreignTypeValue, inverse, record, relatedModel; + foreignTypeValue = response[association.foreignTypeKey] || childRecord.get(association.foreignTypeKey); + relatedModel = association.getRelatedModelForType(foreignTypeValue); + record = new relatedModel(); + record._withoutDirtyTracking(function() { + return this.fromJSON(data); + }); + record = relatedModel._mapIdentity(record); + if (association.options.inverseOf) { + if (inverse = association.inverseForType(foreignTypeValue)) { + if (inverse instanceof Batman.PolymorphicHasManyAssociation) { + childRecord.set(association.foreignKey, record.get(association.primaryKey)); + childRecord.set(association.foreignTypeKey, foreignTypeValue); + } else { + record.set(inverse.label, childRecord); + } + } + } + childRecord.set(association.label, record); + return record; + }; + }; + + return PolymorphicBelongsToAssociation; + + })(Batman.BelongsToAssociation); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.Validator = (function(_super) { + + __extends(Validator, _super); + + function Validator() { + var mixins, options; + options = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + this.options = options; + Validator.__super__.constructor.apply(this, mixins); + } + + Validator.prototype.validate = function(record) { + return Batman.developer.error("You must override validate in Batman.Validator subclasses."); + }; + + Validator.prototype.format = function(key, messageKey, interpolations) { + return Batman.t("errors.messages." + messageKey, interpolations); + }; + + Validator.options = function() { + var options; + options = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + Batman.initializeObject(this); + if (this._batman.options) { + return this._batman.options.concat(options); + } else { + return this._batman.options = options; + } + }; + + Validator.matches = function(options) { + var key, results, shouldReturn, value, _ref, _ref1; + results = {}; + shouldReturn = false; + for (key in options) { + value = options[key]; + if (~((_ref = this._batman) != null ? (_ref1 = _ref.options) != null ? _ref1.indexOf(key) : void 0 : void 0)) { + results[key] = value; + shouldReturn = true; + } + } + if (shouldReturn) { + return results; + } + }; + + return Validator; + + })(Batman.Object); + +}).call(this); + +(function() { + + Batman.Validators = []; + + Batman.extend(Batman.translate.messages, { + errors: { + format: "%{attribute} %{message}", + messages: { + too_short: "must be at least %{count} characters", + too_long: "must be less than %{count} characters", + wrong_length: "must be %{count} characters", + blank: "can't be blank", + not_numeric: "must be a number", + not_matching: "is not valid" + } + } + }); + +}).call(this); + +(function() { + var __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; }; + + Batman.RegExpValidator = (function(_super) { + + __extends(RegExpValidator, _super); + + RegExpValidator.options('regexp', 'pattern'); + + function RegExpValidator(options) { + var _ref; + this.regexp = (_ref = options.regexp) != null ? _ref : options.pattern; + RegExpValidator.__super__.constructor.apply(this, arguments); + } + + RegExpValidator.prototype.validateEach = function(errors, record, key, callback) { + var value; + value = record.get(key); + if ((value != null) && value !== '') { + if (!this.regexp.test(value)) { + errors.add(key, this.format(key, 'not_matching')); + } + } + return callback(); + }; + + return RegExpValidator; + + })(Batman.Validator); + + Batman.Validators.push(Batman.RegExpValidator); + +}).call(this); + +(function() { + var __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; }; + + Batman.PresenceValidator = (function(_super) { + + __extends(PresenceValidator, _super); + + function PresenceValidator() { + return PresenceValidator.__super__.constructor.apply(this, arguments); + } + + PresenceValidator.options('presence'); + + PresenceValidator.prototype.validateEach = function(errors, record, key, callback) { + var value; + value = record.get(key); + if (this.options.presence && (!(value != null) || value === '')) { + errors.add(key, this.format(key, 'blank')); + } + return callback(); + }; + + return PresenceValidator; + + })(Batman.Validator); + + Batman.Validators.push(Batman.PresenceValidator); + +}).call(this); + +(function() { + var __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; }; + + Batman.NumericValidator = (function(_super) { + + __extends(NumericValidator, _super); + + function NumericValidator() { + return NumericValidator.__super__.constructor.apply(this, arguments); + } + + NumericValidator.options('numeric'); + + NumericValidator.prototype.validateEach = function(errors, record, key, callback) { + var value; + value = record.get(key); + if (this.options.numeric && isNaN(parseFloat(value))) { + errors.add(key, this.format(key, 'not_numeric')); + } + return callback(); + }; + + return NumericValidator; + + })(Batman.Validator); + + Batman.Validators.push(Batman.NumericValidator); + +}).call(this); + +(function() { + var __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; }; + + Batman.LengthValidator = (function(_super) { + + __extends(LengthValidator, _super); + + LengthValidator.options('minLength', 'maxLength', 'length', 'lengthWithin', 'lengthIn'); + + function LengthValidator(options) { + var range; + if (range = options.lengthIn || options.lengthWithin) { + options.minLength = range[0]; + options.maxLength = range[1] || -1; + delete options.lengthWithin; + delete options.lengthIn; + } + LengthValidator.__super__.constructor.apply(this, arguments); + } + + LengthValidator.prototype.validateEach = function(errors, record, key, callback) { + var options, value, _ref; + options = this.options; + value = (_ref = record.get(key)) != null ? _ref : []; + if (options.minLength && value.length < options.minLength) { + errors.add(key, this.format(key, 'too_short', { + count: options.minLength + })); + } + if (options.maxLength && value.length > options.maxLength) { + errors.add(key, this.format(key, 'too_long', { + count: options.maxLength + })); + } + if (options.length && value.length !== options.length) { + errors.add(key, this.format(key, 'wrong_length', { + count: options.length + })); + } + return callback(); + }; + + return LengthValidator; + + })(Batman.Validator); + + Batman.Validators.push(Batman.LengthValidator); + +}).call(this); + +(function() { + var __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; }; + + Batman.ControllerActionFrame = (function(_super) { + + __extends(ControllerActionFrame, _super); + + ControllerActionFrame.prototype.operationOccurred = false; + + ControllerActionFrame.prototype.remainingOperations = 0; + + ControllerActionFrame.prototype.event('complete').oneShot = true; + + function ControllerActionFrame(options, onComplete) { + ControllerActionFrame.__super__.constructor.call(this, options); + this.on('complete', onComplete); + } + + ControllerActionFrame.prototype.startOperation = function(options) { + if (options == null) { + options = {}; + } + if (!options.internal) { + this.operationOccurred = true; + } + this._changeOperationsCounter(1); + return true; + }; + + ControllerActionFrame.prototype.finishOperation = function() { + this._changeOperationsCounter(-1); + return true; + }; + + ControllerActionFrame.prototype.startAndFinishOperation = function(options) { + this.startOperation(options); + this.finishOperation(options); + return true; + }; + + ControllerActionFrame.prototype._changeOperationsCounter = function(delta) { + var _ref; + this.remainingOperations += delta; + if (this.remainingOperations === 0) { + this.fire('complete'); + } + if ((_ref = this.parentFrame) != null) { + _ref._changeOperationsCounter(delta); + } + }; + + return ControllerActionFrame; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }; + + Batman.DOM.InsertionBinding = (function(_super) { + + __extends(InsertionBinding, _super); + + InsertionBinding.prototype.isTwoWay = false; + + InsertionBinding.prototype.bindImmediately = false; + + function InsertionBinding(node, className, key, context, parentRenderer, invert) { + var result, + _this = this; + this.invert = invert != null ? invert : false; + this.placeholderNode = document.createComment("detached node " + (this.get('_batmanID'))); + result = InsertionBinding.__super__.constructor.apply(this, arguments); + Batman.DOM.onParseExit(this.node, function() { + _this.bind(); + if (_this.placeholderNode != null) { + return Batman.DOM.trackBinding(_this, _this.placeholderNode); + } + }); + result; + + } + + InsertionBinding.prototype.dataChange = function(value) { + var parentNode; + parentNode = this.placeholderNode.parentNode || this.node.parentNode; + if (!!value === !this.invert) { + if (!(this.node.parentNode != null)) { + Batman.DOM.insertBefore(parentNode, this.node, this.placeholderNode); + return parentNode.removeChild(this.placeholderNode); + } + } else { + parentNode.insertBefore(this.placeholderNode, this.node); + return Batman.DOM.removeNode(this.node); + } + }; + + InsertionBinding.prototype.die = function() { + if (this.dead) { + return; + } + InsertionBinding.__super__.die.apply(this, arguments); + if (!!this.get('filteredValue') === !this.invert) { + return Batman.DOM.destroyNode(this.placeholderNode); + } else { + return Batman.DOM.destroyNode(this.node); + } + }; + + return InsertionBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var isEmptyDataObject; + + isEmptyDataObject = function(obj) { + var name; + for (name in obj) { + return false; + } + return true; + }; + + Batman.extend(Batman, { + cache: {}, + uuid: 0, + expando: "batman" + Math.random().toString().replace(/\D/g, ''), + canDeleteExpando: (function() { + var div; + try { + div = document.createElement('div'); + return delete div.test; + } catch (e) { + return Batman.canDeleteExpando = false; + } + })(), + noData: { + "embed": true, + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + hasData: function(elem) { + elem = (elem.nodeType ? Batman.cache[elem[Batman.expando]] : elem[Batman.expando]); + return !!elem && !isEmptyDataObject(elem); + }, + data: function(elem, name, data, pvt) { + var cache, getByName, id, internalKey, ret, thisCache; + if (!Batman.acceptData(elem)) { + return; + } + internalKey = Batman.expando; + getByName = typeof name === "string"; + cache = Batman.cache; + id = elem[Batman.expando]; + if ((!id || (pvt && id && (cache[id] && !cache[id][internalKey]))) && getByName && data === void 0) { + return; + } + if (!id) { + if (elem.nodeType !== 3) { + elem[Batman.expando] = id = ++Batman.uuid; + } else { + id = Batman.expando; + } + } + if (!cache[id]) { + cache[id] = {}; + } + if (typeof name === "object" || typeof name === "function") { + if (pvt) { + cache[id][internalKey] = Batman.extend(cache[id][internalKey], name); + } else { + cache[id] = Batman.extend(cache[id], name); + } + } + thisCache = cache[id]; + if (pvt) { + thisCache[internalKey] || (thisCache[internalKey] = {}); + thisCache = thisCache[internalKey]; + } + if (data !== void 0) { + thisCache[name] = data; + } + if (getByName) { + ret = thisCache[name]; + } else { + ret = thisCache; + } + return ret; + }, + removeData: function(elem, name, pvt) { + var cache, id, internalCache, internalKey, isNode, thisCache; + if (!Batman.acceptData(elem)) { + return; + } + internalKey = Batman.expando; + isNode = elem.nodeType; + cache = Batman.cache; + id = elem[Batman.expando]; + if (!cache[id]) { + return; + } + if (name) { + thisCache = pvt ? cache[id][internalKey] : cache[id]; + if (thisCache) { + delete thisCache[name]; + if (!isEmptyDataObject(thisCache)) { + return; + } + } + } + if (pvt) { + delete cache[id][internalKey]; + if (!isEmptyDataObject(cache[id])) { + return; + } + } + internalCache = cache[id][internalKey]; + if (Batman.canDeleteExpando || !cache.setInterval) { + delete cache[id]; + } else { + cache[id] = null; + } + if (internalCache) { + cache[id] = {}; + return cache[id][internalKey] = internalCache; + } else { + if (Batman.canDeleteExpando) { + return delete elem[Batman.expando]; + } else if (elem.removeAttribute) { + return elem.removeAttribute(Batman.expando); + } else { + return elem[Batman.expando] = null; + } + } + }, + _data: function(elem, name, data) { + return Batman.data(elem, name, data, true); + }, + acceptData: function(elem) { + var match; + if (elem.nodeName) { + match = Batman.noData[elem.nodeName.toLowerCase()]; + if (match) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + return true; + } + }); + +}).call(this); + +(function() { + var buntUndefined, defaultAndOr, + __slice = [].slice; + + buntUndefined = function(f) { + return function(value) { + if (typeof value === 'undefined') { + return void 0; + } else { + return f.apply(this, arguments); + } + }; + }; + + defaultAndOr = function(lhs, rhs) { + return lhs || rhs; + }; + + Batman.Filters = { + raw: buntUndefined(function(value, binding) { + binding.escapeValue = false; + return value; + }), + get: buntUndefined(function(value, key) { + if (value.get != null) { + return value.get(key); + } else { + return value[key]; + } + }), + equals: buntUndefined(function(lhs, rhs, binding) { + return lhs === rhs; + }), + and: function(lhs, rhs) { + return lhs && rhs; + }, + or: function(lhs, rhs, binding) { + return lhs || rhs; + }, + not: function(value, binding) { + return !!!value; + }, + matches: buntUndefined(function(value, searchFor) { + return value.indexOf(searchFor) !== -1; + }), + truncate: buntUndefined(function(value, length, end, binding) { + if (end == null) { + end = "..."; + } + if (!binding) { + binding = end; + end = "..."; + } + if (value.length > length) { + value = value.substr(0, length - end.length) + end; + } + return value; + }), + "default": function(value, defaultValue, binding) { + if ((value != null) && value !== '') { + return value; + } else { + return defaultValue; + } + }, + prepend: function(value, string, binding) { + return string + value; + }, + append: function(value, string, binding) { + return value + string; + }, + replace: buntUndefined(function(value, searchFor, replaceWith, flags, binding) { + if (!binding) { + binding = flags; + flags = void 0; + } + if (flags === void 0) { + return value.replace(searchFor, replaceWith); + } else { + return value.replace(searchFor, replaceWith, flags); + } + }), + downcase: buntUndefined(function(value) { + return value.toLowerCase(); + }), + upcase: buntUndefined(function(value) { + return value.toUpperCase(); + }), + pluralize: buntUndefined(function(string, count, includeCount, binding) { + if (!binding) { + binding = includeCount; + includeCount = true; + if (!binding) { + binding = count; + count = void 0; + } + } + if (count) { + return Batman.helpers.pluralize(count, string, void 0, includeCount); + } else { + return Batman.helpers.pluralize(string); + } + }), + humanize: buntUndefined(function(string, binding) { + return Batman.helpers.humanize(string); + }), + join: buntUndefined(function(value, withWhat, binding) { + if (withWhat == null) { + withWhat = ''; + } + if (!binding) { + binding = withWhat; + withWhat = ''; + } + return value.join(withWhat); + }), + sort: buntUndefined(function(value) { + return value.sort(); + }), + map: buntUndefined(function(value, key) { + return value.map(function(x) { + return Batman.get(x, key); + }); + }), + has: function(set, item) { + if (set == null) { + return false; + } + return Batman.contains(set, item); + }, + first: buntUndefined(function(value) { + return value[0]; + }), + meta: buntUndefined(function(value, keypath) { + Batman.developer.assert(value.meta, "Error, value doesn't have a meta to filter on!"); + return value.meta.get(keypath); + }), + interpolate: function(string, interpolationKeypaths, binding) { + var k, v, values; + if (!binding) { + binding = interpolationKeypaths; + interpolationKeypaths = void 0; + } + if (!string) { + return; + } + values = {}; + for (k in interpolationKeypaths) { + v = interpolationKeypaths[k]; + values[k] = this.get(v); + if (!(values[k] != null)) { + Batman.developer.warn("Warning! Undefined interpolation key " + k + " for interpolation", string); + values[k] = ''; + } + } + return Batman.helpers.interpolate(string, values); + }, + withArguments: function() { + var binding, block, curryArgs, _i; + block = arguments[0], curryArgs = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), binding = arguments[_i++]; + if (!block) { + return; + } + return function() { + var regularArgs; + regularArgs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return block.call.apply(block, [this].concat(__slice.call(curryArgs), __slice.call(regularArgs))); + }; + }, + routeToAction: buntUndefined(function(model, action) { + var params; + params = Batman.Dispatcher.paramsFromArgument(model); + params.action = action; + return params; + }), + escape: buntUndefined(Batman.escapeHTML) + }; + + (function() { + var k, _i, _len, _ref, _results; + _ref = ['capitalize', 'singularize', 'underscore', 'camelize']; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + _results.push(Batman.Filters[k] = buntUndefined(Batman.helpers[k])); + } + return _results; + })(); + + Batman.developer.addFilters(); + +}).call(this); + +(function() { + var __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; }; + + Batman.RenderContext = (function() { + var ContextProxy; + + RenderContext.deProxy = function(object) { + if ((object != null) && object.isContextProxy) { + return object.get('proxiedObject'); + } else { + return object; + } + }; + + RenderContext.root = function() { + var root; + if (Batman.currentApp != null) { + root = Batman.currentApp.get('_renderContext'); + } + return root != null ? root : root = this.base; + }; + + RenderContext.prototype.windowWrapper = { + window: Batman.container + }; + + function RenderContext(object, parent) { + this.object = object; + this.parent = parent; + } + + RenderContext.prototype.findKey = function(key) { + var base, currentNode, val; + base = key.split('.')[0].split('|')[0].trim(); + currentNode = this; + while (currentNode) { + val = Batman.get(currentNode.object, base); + if (typeof val !== 'undefined') { + val = Batman.get(currentNode.object, key); + return [val, currentNode.object].map(this.constructor.deProxy); + } + currentNode = currentNode.parent; + } + return [Batman.get(this.windowWrapper, key), this.windowWrapper]; + }; + + RenderContext.prototype.get = function(key) { + return this.findKey(key)[0]; + }; + + RenderContext.prototype.contextForKey = function(key) { + return this.findKey(key)[1]; + }; + + RenderContext.prototype.descend = function(object, scopedKey) { + var oldObject; + if (scopedKey) { + oldObject = object; + object = new Batman.Object(); + object[scopedKey] = oldObject; + } + return new this.constructor(object, this); + }; + + RenderContext.prototype.descendWithKey = function(key, scopedKey) { + var proxy; + proxy = new ContextProxy(this, key); + return this.descend(proxy, scopedKey); + }; + + RenderContext.prototype.chain = function() { + var parent, x; + x = []; + parent = this; + while (parent) { + x.push(parent.object); + parent = parent.parent; + } + return x; + }; + + RenderContext.ContextProxy = ContextProxy = (function(_super) { + + __extends(ContextProxy, _super); + + ContextProxy.prototype.isContextProxy = true; + + ContextProxy.accessor('proxiedObject', function() { + return this.binding.get('filteredValue'); + }); + + ContextProxy.accessor({ + get: function(key) { + return this.get("proxiedObject." + key); + }, + set: function(key, value) { + return this.set("proxiedObject." + key, value); + }, + unset: function(key) { + return this.unset("proxiedObject." + key); + } + }); + + function ContextProxy(renderContext, keyPath, localKey) { + this.renderContext = renderContext; + this.keyPath = keyPath; + this.localKey = localKey; + this.binding = new Batman.DOM.AbstractBinding(void 0, this.keyPath, this.renderContext); + } + + return ContextProxy; + + })(Batman.Object); + + return RenderContext; + + }).call(this); + + Batman.RenderContext.base = new Batman.RenderContext(Batman.RenderContext.prototype.windowWrapper); + +}).call(this); + +(function() { + var __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; }; + + Batman.ViewStore = (function(_super) { + + __extends(ViewStore, _super); + + ViewStore.prefix = 'views'; + + ViewStore.fetchFromRemote = true; + + function ViewStore() { + ViewStore.__super__.constructor.apply(this, arguments); + this._viewContents = {}; + this._requestedPaths = new Batman.SimpleSet; + } + + ViewStore.prototype.propertyClass = Batman.Property; + + ViewStore.prototype.fetchView = function(path) { + var _this = this; + return new Batman.Request({ + url: Batman.Navigator.normalizePath(this.constructor.prefix, "" + path + ".html"), + type: 'html', + success: function(response) { + return _this.set(path, response); + }, + error: function(response) { + throw new Error("Could not load view from " + path); + } + }); + }; + + ViewStore.accessor({ + 'final': true, + get: function(path) { + var contents; + if (path[0] !== '/') { + return this.get("/" + path); + } + if (this._viewContents[path]) { + return this._viewContents[path]; + } + if (this._requestedPaths.has(path)) { + return; + } + if (contents = this._sourceFromDOM(path)) { + return contents; + } + if (this.constructor.fetchFromRemote) { + this.fetchView(path); + } else { + throw new Error("Couldn't find view source for \'" + path + "\'!"); + } + }, + set: function(path, content) { + if (path[0] !== '/') { + return this.set("/" + path, content); + } + this._requestedPaths.add(path); + return this._viewContents[path] = content; + } + }); + + ViewStore.prototype.prefetch = function(path) { + this.get(path); + return true; + }; + + ViewStore.prototype._sourceFromDOM = function(path) { + var node, relativePath; + relativePath = path.slice(1); + if (node = Batman.DOM.querySelector(document, "[data-defineview*='" + relativePath + "']")) { + Batman.setImmediate(function() { + var _ref; + return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; + }); + return Batman.DOM.defineView(path, node); + } + }; + + return ViewStore; + + })(Batman.Object); + +}).call(this); + +(function() { + var __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; }, + __slice = [].slice; + + Batman.View = (function(_super) { + + __extends(View, _super); + + View.YieldStorage = (function(_super1) { + + __extends(YieldStorage, _super1); + + function YieldStorage() { + return YieldStorage.__super__.constructor.apply(this, arguments); + } + + YieldStorage.wrapAccessor(function(core) { + return { + get: function(key) { + var val; + val = core.get.call(this, key); + if (!(val != null)) { + val = this.set(key, []); + } + return val; + } + }; + }); + + return YieldStorage; + + })(Batman.Hash); + + View.store = new Batman.ViewStore(); + + View.option = function() { + var keys, + _this = this; + keys = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + keys.forEach(function(key) { + return _this.accessor(_this.prototype._argumentBindingKey(key), function(bindingKey) { + var context, keyPath, node, _ref; + if (!((node = this.get('node')) && (context = this.get('context')))) { + return; + } + keyPath = node.getAttribute(("data-view-" + key).toLowerCase()); + if (keyPath == null) { + return; + } + if ((_ref = this[bindingKey]) != null) { + _ref.die(); + } + return this[bindingKey] = new Batman.DOM.ViewArgumentBinding(node, keyPath, context); + }); + }); + return this.accessor.apply(this, __slice.call(keys).concat([function(key) { + var _ref; + return (_ref = this.get(this._argumentBindingKey(key))) != null ? _ref.get('filteredValue') : void 0; + }])); + }; + + View.prototype.isView = true; + + View.prototype.cache = true; + + View.prototype._rendered = false; + + View.prototype.node = null; + + View.prototype.event('ready').oneShot = true; + + View.accessor('html', { + get: function() { + var source; + if (this.html && this.html.length > 0) { + return this.html; + } + if (!(source = this.get('source'))) { + return; + } + source = Batman.Navigator.normalizePath(source); + return this.html = this.constructor.store.get(source); + }, + set: function(_, html) { + return this.html = html; + } + }); + + View.accessor('node', { + get: function() { + var html; + if (this.node == null) { + html = this.get('html'); + if (!(html && html.length > 0)) { + return; + } + this.node = document.createElement('div'); + this._setNodeOwner(this.node); + Batman.setInnerHTML(this.node, html); + } + return this.node; + }, + set: function(_, node) { + var updateHTML, + _this = this; + this.node = node; + this._setNodeOwner(node); + updateHTML = function(html) { + if (html != null) { + Batman.setInnerHTML(_this.node, html); + return _this.forget('html', updateHTML); + } + }; + this.observeAndFire('html', updateHTML); + return node; + } + }); + + View.accessor('yields', function() { + return new this.constructor.YieldStorage; + }); + + View.accessor('fetched?', function() { + return this.get('source') != null; + }); + + View.accessor('readyToRender', function() { + var _ref; + return this.get('node') && (this.get('fetched?') ? ((_ref = this.get('html')) != null ? _ref.length : void 0) > 0 : true); + }); + + function View(options) { + var context, + _this = this; + if (options == null) { + options = {}; + } + context = options.context; + if (context) { + if (!(context instanceof Batman.RenderContext)) { + context = Batman.RenderContext.root().descend(context); + } + } else { + context = Batman.RenderContext.root(); + } + options.context = context.descend(this); + View.__super__.constructor.call(this, options); + Batman.Property.withoutTracking(function() { + return _this.observeAndFire('readyToRender', function(ready) { + if (ready) { + return _this.render(); + } + }); + }); + } + + View.prototype.render = function() { + var node, + _this = this; + if (this._rendered) { + return; + } + this._rendered = true; + this._renderer = new Batman.Renderer(node = this.get('node'), this.get('context'), this); + return this._renderer.on('rendered', function() { + return _this.fire('ready', node); + }); + }; + + View.prototype.isInDOM = function() { + var node; + if ((node = this.get('node'))) { + return (node.parentNode != null) || this.get('yields').some(function(name, nodes) { + var _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + node = nodes[_i].node; + if (node.parentNode != null) { + return true; + } + } + return false; + }); + } else { + return false; + } + }; + + View.prototype.applyYields = function() { + return this.get('yields').forEach(function(name, nodes) { + var action, node, yieldObject, _i, _len, _ref, _results; + yieldObject = Batman.DOM.Yield.withName(name); + _results = []; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + _ref = nodes[_i], node = _ref.node, action = _ref.action; + _results.push(yieldObject[action](node)); + } + return _results; + }); + }; + + View.prototype.retractYields = function() { + return this.get('yields').forEach(function(name, nodes) { + var node, _i, _len, _ref, _results; + _results = []; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + node = nodes[_i].node; + _results.push((_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0); + } + return _results; + }); + }; + + View.prototype.pushYieldAction = function(key, action, node) { + this._setNodeYielder(node); + return this.get("yields").get(key).push({ + node: node, + action: action + }); + }; + + View.prototype._argumentBindingKey = function(key) { + return "_" + key + "ArgumentBinding"; + }; + + View.prototype._setNodeOwner = function(node) { + return Batman._data(node, 'view', this); + }; + + View.prototype._setNodeYielder = function(node) { + return Batman._data(node, 'yielder', this); + }; + + View.prototype.on('ready', function() { + return typeof this.ready === "function" ? this.ready.apply(this, arguments) : void 0; + }); + + View.prototype.on('appear', function() { + return typeof this.viewDidAppear === "function" ? this.viewDidAppear.apply(this, arguments) : void 0; + }); + + View.prototype.on('disappear', function() { + return typeof this.viewDidDisappear === "function" ? this.viewDidDisappear.apply(this, arguments) : void 0; + }); + + View.prototype.on('beforeAppear', function() { + return typeof this.viewWillAppear === "function" ? this.viewWillAppear.apply(this, arguments) : void 0; + }); + + View.prototype.on('beforeDisappear', function() { + return typeof this.viewWillDisappear === "function" ? this.viewWillDisappear.apply(this, arguments) : void 0; + }); + + return View; + + }).call(this, Batman.Object); + +}).call(this); + +(function() { + var Yield, + __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; }, + __slice = [].slice; + + Batman.DOM.Yield = Yield = (function(_super) { + + __extends(Yield, _super); + + Yield.yields = {}; + + Yield.queued = function(fn) { + return function() { + var args, handler, + _this = this; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + if (this.containerNode != null) { + return fn.apply(this, args); + } else { + return handler = this.observe('containerNode', function() { + var result; + result = fn.apply(_this, args); + _this.forget('containerNode', handler); + return result; + }); + } + }; + }; + + Yield.reset = function() { + return this.yields = {}; + }; + + Yield.withName = function(name) { + var _base; + (_base = this.yields)[name] || (_base[name] = new this({ + name: name + })); + return this.yields[name]; + }; + + Yield.forEach = function(f) { + var name, yieldObject, _ref; + _ref = this.yields; + for (name in _ref) { + yieldObject = _ref[name]; + f(yieldObject); + } + }; + + Yield.clearAll = function() { + return this.forEach(function(yieldObject) { + return yieldObject.clear(); + }); + }; + + Yield.cycleAll = function() { + return this.forEach(function(yieldObject) { + return yieldObject.cycle(); + }); + }; + + Yield.clearAllStale = function() { + return this.forEach(function(yieldObject) { + return yieldObject.clearStale(); + }); + }; + + function Yield() { + this.cycle(); + } + + Yield.prototype.cycle = function() { + return this.currentVersionNodes = []; + }; + + Yield.prototype.clear = Yield.queued(function() { + var child, _i, _len, _ref, _results; + this.cycle(); + _ref = (function() { + var _j, _len, _ref, _results1; + _ref = this.containerNode.childNodes; + _results1 = []; + for (_j = 0, _len = _ref.length; _j < _len; _j++) { + child = _ref[_j]; + _results1.push(child); + } + return _results1; + }).call(this); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + _results.push(Batman.removeOrDestroyNode(child)); + } + return _results; + }); + + Yield.prototype.clearStale = Yield.queued(function() { + var child, _i, _len, _ref, _results; + _ref = (function() { + var _j, _len, _ref, _results1; + _ref = this.containerNode.childNodes; + _results1 = []; + for (_j = 0, _len = _ref.length; _j < _len; _j++) { + child = _ref[_j]; + _results1.push(child); + } + return _results1; + }).call(this); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (!~this.currentVersionNodes.indexOf(child)) { + _results.push(Batman.removeOrDestroyNode(child)); + } + } + return _results; + }); + + Yield.prototype.append = Yield.queued(function(node) { + this.currentVersionNodes.push(node); + return Batman.appendChild(this.containerNode, node, true); + }); + + Yield.prototype.replace = Yield.queued(function(node) { + this.clear(); + return this.append(node); + }); + + return Yield; + + })(Batman.Object); + +}).call(this); + +(function() { + + + +}).call(this); \ No newline at end of file diff --git a/javascripts/dashing.coffee b/javascripts/dashing.coffee new file mode 100644 index 0000000..2d9953d --- /dev/null +++ b/javascripts/dashing.coffee @@ -0,0 +1,96 @@ +#= require jquery +#= require es5-shim +#= require batman +#= require batman.jquery + + +Batman.Filters.prettyNumber = (num) -> + num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") unless isNaN(num) + +Batman.Filters.dashize = (str) -> + dashes_rx1 = /([A-Z]+)([A-Z][a-z])/g; + dashes_rx2 = /([a-z\d])([A-Z])/g; + + return str.replace(dashes_rx1, '$1_$2').replace(dashes_rx2, '$1_$2').replace('_', '-').toLowerCase() + +Batman.Filters.shortenedNumber = (num) -> + return if isNaN(num) + if num >= 1000000000 + (num / 1000000000).toFixed(1) + 'B' + else if num >= 1000000 + (num / 1000000).toFixed(1) + 'M' + else if num >= 1000 + (num / 1000).toFixed(1) + 'K' + else + num + +class window.Dashing extends Batman.App + @root -> + +class Dashing.Widget extends Batman.View + constructor: -> + # Set the view path + @constructor::source = Batman.Filters.underscore(@constructor.name) + super + + @mixin($(@node).data()) + Dashing.widgets[@id] ||= [] + Dashing.widgets[@id].push(@) + @mixin(Dashing.lastEvents[@id]) # in case the events from the server came before the widget was rendered + + type = Batman.Filters.dashize(@view) + $(@node).addClass("widget widget-#{type} #{@id}") + + + @::on 'ready', -> + Dashing.Widget.fire 'ready' + + onData: (data) => + @mixin(data) + + +Dashing.AnimatedValue = + get: Batman.Property.defaultAccessor.get + set: (k, to) -> + if isNaN(to) + @[k] = to + else + timer = "interval_#{k}" + num = if !isNaN(@[k]) then @[k] else 0 + unless @[timer] || num == to + up = to > num + num_interval = Math.abs(num - to) / 90 + @[timer] = + setInterval => + num = if up then Math.ceil(num+num_interval) else Math.floor(num-num_interval) + if (up && num > to) || (!up && num < to) + num = to + clearInterval(@[timer]) + @[timer] = null + delete @[timer] + @[k] = num + @set k, to + @[k] = num + +Dashing.widgets = widgets = {} +Dashing.lastEvents = lastEvents = {} + +source = new EventSource('/events') +source.addEventListener 'open', (e) -> + console.log("Connection opened") + +source.addEventListener 'error', (e)-> + console.log("Connection error") + if (e.readyState == EventSource.CLOSED) + console.log("Connection closed") + +source.addEventListener 'message', (e) => + data = JSON.parse(e.data) + lastEvents[data.id] = data + if widgets[data.id]?.length > 0 + for widget in widgets[data.id] + widget.onData(data) + + +$(document).ready -> + Dashing.run() diff --git a/javascripts/es5-shim.js b/javascripts/es5-shim.js new file mode 100644 index 0000000..ce79780 --- /dev/null +++ b/javascripts/es5-shim.js @@ -0,0 +1,1021 @@ +// vim: ts=4 sts=4 sw=4 expandtab +// -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License +// -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) +// -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA +// -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License +// -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License +// -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License +// -- kossnocorp Sasha Koss XXX TODO License or CLA +// -- bryanforbes Bryan Forbes XXX TODO License or CLA +// -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence +// -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License +// -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License +// -- bbqsrc Brendan Molloy XXX TODO License or CLA +// -- iwyg XXX TODO License or CLA +// -- DomenicDenicola Domenic Denicola XXX TODO License or CLA +// -- xavierm02 Montillet Xavier XXX TODO License or CLA +// -- Raynos Raynos XXX TODO License or CLA +// -- samsonjs Sami Samhuri XXX TODO License or CLA +// -- rwldrn Rick Waldron Copyright (C) 2011 MIT License +// -- lexer Alexey Zakharov XXX TODO License or CLA + +/*! + Copyright (c) 2009, 280 North Inc. http://280north.com/ + MIT License. http://github.com/280north/narwhal/blob/master/README.md +*/ + +// Module systems magic dance +(function (definition) { + // RequireJS + if (typeof define == "function") { + define(definition); + // CommonJS and + ") + + +$ -> + $('#save-gridster').leanModal() + + $('#save-gridster').click -> + $('#save-gridster').slideUp() \ No newline at end of file diff --git a/templates/project/assets/javascripts/gridster/jquery.collision.js b/templates/project/assets/javascripts/gridster/jquery.collision.js new file mode 100755 index 0000000..5d37c61 --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.collision.js @@ -0,0 +1,224 @@ +/* + * jquery.collision + * https://github.com/ducksboard/gridster.js + * + * Copyright (c) 2012 ducksboard + * Licensed under the MIT licenses. + */ + +;(function($, window, document, undefined){ + + var defaults = { + colliders_context: document.body + // ,on_overlap: function(collider_data){}, + // on_overlap_start : function(collider_data){}, + // on_overlap_stop : function(collider_data){} + }; + + + /** + * Detects collisions between a DOM element against other DOM elements or + * Coords objects. + * + * @class Collision + * @uses Coords + * @param {HTMLElement} el The jQuery wrapped HTMLElement. + * @param {HTMLElement|Array} colliders Can be a jQuery collection + * of HTMLElements or an Array of Coords instances. + * @param {Object} [options] An Object with all options you want to + * overwrite: + * @param {Function} [options.on_overlap_start] Executes a function the first + * time each `collider ` is overlapped. + * @param {Function} [options.on_overlap_stop] Executes a function when a + * `collider` is no longer collided. + * @param {Function} [options.on_overlap] Executes a function when the + * mouse is moved during the collision. + * @return {Object} Collision instance. + * @constructor + */ + function Collision(el, colliders, options) { + this.options = $.extend(defaults, options); + this.$element = el; + this.last_colliders = []; + this.last_colliders_coords = []; + if (typeof colliders === 'string' || colliders instanceof jQuery) { + this.$colliders = $(colliders, + this.options.colliders_context).not(this.$element); + }else{ + this.colliders = $(colliders); + } + + this.init(); + } + + + var fn = Collision.prototype; + + + fn.init = function() { + this.find_collisions(); + }; + + + fn.overlaps = function(a, b) { + var x = false; + var y = false; + + if ((b.x1 >= a.x1 && b.x1 <= a.x2) || + (b.x2 >= a.x1 && b.x2 <= a.x2) || + (a.x1 >= b.x1 && a.x2 <= b.x2) + ) { x = true; } + + if ((b.y1 >= a.y1 && b.y1 <= a.y2) || + (b.y2 >= a.y1 && b.y2 <= a.y2) || + (a.y1 >= b.y1 && a.y2 <= b.y2) + ) { y = true; } + + return (x && y); + }; + + + fn.detect_overlapping_region = function(a, b){ + var regionX = ''; + var regionY = ''; + + if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; } + if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; } + if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; } + if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; } + + return (regionX + regionY) || 'C'; + }; + + + fn.calculate_overlapped_area_coords = function(a, b){ + var x1 = Math.max(a.x1, b.x1); + var y1 = Math.max(a.y1, b.y1); + var x2 = Math.min(a.x2, b.x2); + var y2 = Math.min(a.y2, b.y2); + + return $({ + left: x1, + top: y1, + width : (x2 - x1), + height: (y2 - y1) + }).coords().get(); + }; + + + fn.calculate_overlapped_area = function(coords){ + return (coords.width * coords.height); + }; + + + fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){ + var last = this.last_colliders_coords; + + for (var i = 0, il = last.length; i < il; i++) { + if ($.inArray(last[i], new_colliders_coords) === -1) { + start_callback.call(this, last[i]); + } + } + + for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) { + if ($.inArray(new_colliders_coords[j], last) === -1) { + stop_callback.call(this, new_colliders_coords[j]); + } + + } + }; + + + fn.find_collisions = function(player_data_coords){ + var self = this; + var colliders_coords = []; + var colliders_data = []; + var $colliders = (this.colliders || this.$colliders); + var count = $colliders.length; + var player_coords = self.$element.coords() + .update(player_data_coords || false).get(); + + while(count--){ + var $collider = self.$colliders ? + $($colliders[count]) : $colliders[count]; + var $collider_coords_ins = ($collider.isCoords) ? + $collider : $collider.coords(); + var collider_coords = $collider_coords_ins.get(); + var overlaps = self.overlaps(player_coords, collider_coords); + + if (!overlaps) { + continue; + } + + var region = self.detect_overlapping_region( + player_coords, collider_coords); + + //todo: make this an option + if (region === 'C'){ + var area_coords = self.calculate_overlapped_area_coords( + player_coords, collider_coords); + var area = self.calculate_overlapped_area(area_coords); + var collider_data = { + area: area, + area_coords : area_coords, + region: region, + coords: collider_coords, + player_coords: player_coords, + el: $collider + }; + + if (self.options.on_overlap) { + self.options.on_overlap.call(this, collider_data); + } + colliders_coords.push($collider_coords_ins); + colliders_data.push(collider_data); + } + } + + if (self.options.on_overlap_stop || self.options.on_overlap_start) { + this.manage_colliders_start_stop(colliders_coords, + self.options.on_overlap_stop, self.options.on_overlap_start); + } + + this.last_colliders_coords = colliders_coords; + + return colliders_data; + }; + + + fn.get_closest_colliders = function(player_data_coords){ + var colliders = this.find_collisions(player_data_coords); + var min_area = 100; + colliders.sort(function(a, b){ + if (a.area <= min_area) { + return 1; + } + + /* if colliders are being overlapped by the "C" (center) region, + * we have to set a lower index in the array to which they are placed + * above in the grid. */ + if (a.region === 'C' && b.region === 'C') { + if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) { + return - 1; + }else{ + return 1; + } + } + + if (a.area < b.area){ + return 1; + } + + return 1; + }); + return colliders; + }; + + + //jQuery adapter + $.fn.collision = function(collider, options) { + return new Collision( this, collider, options ); + }; + + +}(jQuery, window, document)); diff --git a/templates/project/assets/javascripts/gridster/jquery.coords.js b/templates/project/assets/javascripts/gridster/jquery.coords.js new file mode 100755 index 0000000..e3bd5e6 --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.coords.js @@ -0,0 +1,108 @@ +/* + * jquery.coords + * https://github.com/ducksboard/gridster.js + * + * Copyright (c) 2012 ducksboard + * Licensed under the MIT licenses. + */ + +;(function($, window, document, undefined){ + /** + * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height) + * to simulate DOM elements on the screen. + * Coords is used by Gridster to create a faux grid with any DOM element can + * collide. + * + * @class Coords + * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left, + * top, width and height properties. + * @return {Object} Coords instance. + * @constructor + */ + function Coords(obj) { + if (obj[0] && $.isPlainObject(obj[0])) { + this.data = obj[0]; + }else { + this.el = obj; + } + + this.isCoords = true; + this.coords = {}; + this.init(); + return this; + } + + + var fn = Coords.prototype; + + + fn.init = function(){ + this.set(); + this.original_coords = this.get(); + }; + + + fn.set = function(update, not_update_offsets) { + var el = this.el; + + if (el && !update) { + this.data = el.offset(); + this.data.width = el.width(); + this.data.height = el.height(); + } + + if (el && update && !not_update_offsets) { + var offset = el.offset(); + this.data.top = offset.top; + this.data.left = offset.left; + } + + var d = this.data; + + this.coords.x1 = d.left; + this.coords.y1 = d.top; + this.coords.x2 = d.left + d.width; + this.coords.y2 = d.top + d.height; + this.coords.cx = d.left + (d.width / 2); + this.coords.cy = d.top + (d.height / 2); + this.coords.width = d.width; + this.coords.height = d.height; + this.coords.el = el || false ; + + return this; + }; + + + fn.update = function(data){ + if (!data && !this.el) { + return this; + } + + if (data) { + var new_data = $.extend({}, this.data, data); + this.data = new_data; + return this.set(true, true); + } + + this.set(true); + return this; + }; + + + fn.get = function(){ + return this.coords; + }; + + + //jQuery adapter + $.fn.coords = function() { + if (this.data('coords') ) { + return this.data('coords'); + } + + var ins = new Coords(this, arguments[0]); + this.data('coords', ins); + return ins; + }; + +}(jQuery, window, document)); diff --git a/templates/project/assets/javascripts/gridster/jquery.draggable.js b/templates/project/assets/javascripts/gridster/jquery.draggable.js new file mode 100755 index 0000000..52a18d4 --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.draggable.js @@ -0,0 +1,327 @@ +/* + * jquery.draggable + * https://github.com/ducksboard/gridster.js + * + * Copyright (c) 2012 ducksboard + * Licensed under the MIT licenses. + */ + +;(function($, window, document, undefined){ + + var defaults = { + items: '.gs_w', + distance: 1, + limit: true, + offset_left: 0, + autoscroll: true + // ,drag: function(e){}, + // start : function(e, ui){}, + // stop : function(e){} + }; + + var $window = $(window); + var isTouch = !!('ontouchstart' in window); + var pointer_events = { + start: isTouch ? 'touchstart' : 'mousedown.draggable', + move: isTouch ? 'touchmove' : 'mousemove.draggable', + end: isTouch ? 'touchend' : 'mouseup.draggable' + }; + + /** + * Basic drag implementation for DOM elements inside a container. + * Provide start/stop/drag callbacks. + * + * @class Draggable + * @param {HTMLElement} el The HTMLelement that contains all the widgets + * to be dragged. + * @param {Object} [options] An Object with all options you want to + * overwrite: + * @param {HTMLElement|String} [options.items] Define who will + * be the draggable items. Can be a CSS Selector String or a + * collection of HTMLElements. + * @param {Number} [options.distance] Distance in pixels after mousedown + * the mouse must move before dragging should start. + * @param {Boolean} [options.limit] Constrains dragging to the width of + * the container + * @param {offset_left} [options.offset_left] Offset added to the item + * that is being dragged. + * @param {Number} [options.drag] Executes a callback when the mouse is + * moved during the dragging. + * @param {Number} [options.start] Executes a callback when the drag + * starts. + * @param {Number} [options.stop] Executes a callback when the drag stops. + * @return {Object} Returns `el`. + * @constructor + */ + function Draggable(el, options) { + this.options = $.extend({}, defaults, options); + this.$body = $(document.body); + this.$container = $(el); + this.$dragitems = $(this.options.items, this.$container); + this.is_dragging = false; + this.player_min_left = 0 + this.options.offset_left; + this.init(); + } + + var fn = Draggable.prototype; + + fn.init = function() { + this.calculate_positions(); + this.$container.css('position', 'relative'); + this.enable(); + + $(window).bind('resize', + throttle($.proxy(this.calculate_positions, this), 200)); + }; + + + fn.get_actual_pos = function($el) { + var pos = $el.position(); + return pos; + }; + + + fn.get_mouse_pos = function(e) { + if (isTouch) { + var oe = e.originalEvent; + e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0]; + }; + + return { + left: e.clientX, + top: e.clientY + }; + }; + + + fn.get_offset = function(e) { + e.preventDefault(); + var mouse_actual_pos = this.get_mouse_pos(e); + var diff_x = Math.round( + mouse_actual_pos.left - this.mouse_init_pos.left); + var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top); + + var left = Math.round(this.el_init_offset.left + diff_x - this.baseX); + var top = Math.round( + this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset); + + if (this.options.limit) { + if (left > this.player_max_left) { + left = this.player_max_left; + }else if(left < this.player_min_left) { + left = this.player_min_left; + } + } + + return { + left: left, + top: top, + mouse_left: mouse_actual_pos.left, + mouse_top: mouse_actual_pos.top + }; + }; + + + fn.manage_scroll = function(offset) { + /* scroll document */ + var nextScrollTop; + var scrollTop = $window.scrollTop(); + var min_window_y = scrollTop; + var max_window_y = min_window_y + this.window_height; + + var mouse_down_zone = max_window_y - 50; + var mouse_up_zone = min_window_y + 50; + + var abs_mouse_left = offset.mouse_left; + var abs_mouse_top = min_window_y + offset.mouse_top; + + var max_player_y = (this.doc_height - this.window_height + + this.player_height); + + if (abs_mouse_top >= mouse_down_zone) { + nextScrollTop = scrollTop + 30; + if (nextScrollTop < max_player_y) { + $window.scrollTop(nextScrollTop); + this.scrollOffset = this.scrollOffset + 30; + } + }; + + if (abs_mouse_top <= mouse_up_zone) { + nextScrollTop = scrollTop - 30; + if (nextScrollTop > 0) { + $window.scrollTop(nextScrollTop); + this.scrollOffset = this.scrollOffset - 30; + } + }; + } + + + fn.calculate_positions = function(e) { + this.window_height = $window.height(); + } + + + fn.drag_handler = function(e) { + var node = e.target.nodeName; + + if (e.which !== 1 && !isTouch) { + return; + } + + if (node === 'INPUT' || node === 'TEXTAREA' || node === 'SELECT' || + node === 'BUTTON') { + return; + }; + + var self = this; + var first = true; + this.$player = $(e.currentTarget); + + this.el_init_pos = this.get_actual_pos(this.$player); + this.mouse_init_pos = this.get_mouse_pos(e); + this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; + + this.$body.on(pointer_events.move, function(mme){ + var mouse_actual_pos = self.get_mouse_pos(mme); + var diff_x = Math.abs( + mouse_actual_pos.left - self.mouse_init_pos.left); + var diff_y = Math.abs( + mouse_actual_pos.top - self.mouse_init_pos.top); + if (!(diff_x > self.options.distance || + diff_y > self.options.distance) + ) { + return false; + } + + if (first) { + first = false; + self.on_dragstart.call(self, mme); + return false; + } + + if (self.is_dragging == true) { + self.on_dragmove.call(self, mme); + } + + return false; + }); + }; + + + fn.on_dragstart = function(e) { + e.preventDefault(); + this.drag_start = true; + this.is_dragging = true; + var offset = this.$container.offset(); + this.baseX = Math.round(offset.left); + this.baseY = Math.round(offset.top); + this.doc_height = $(document).height(); + + if (this.options.helper === 'clone') { + this.$helper = this.$player.clone() + .appendTo(this.$container).addClass('helper'); + this.helper = true; + }else{ + this.helper = false; + } + this.scrollOffset = 0; + this.el_init_offset = this.$player.offset(); + this.player_width = this.$player.width(); + this.player_height = this.$player.height(); + this.player_max_left = (this.$container.width() - this.player_width + + this.options.offset_left); + + if (this.options.start) { + this.options.start.call(this.$player, e, { + helper: this.helper ? this.$helper : this.$player + }); + } + return false; + }; + + + fn.on_dragmove = function(e) { + var offset = this.get_offset(e); + + this.options.autoscroll && this.manage_scroll(offset); + + (this.helper ? this.$helper : this.$player).css({ + 'position': 'absolute', + 'left' : offset.left, + 'top' : offset.top + }); + + var ui = { + 'position': { + 'left': offset.left, + 'top': offset.top + } + }; + + if (this.options.drag) { + this.options.drag.call(this.$player, e, ui); + } + return false; + }; + + + fn.on_dragstop = function(e) { + var offset = this.get_offset(e); + this.drag_start = false; + + var ui = { + 'position': { + 'left': offset.left, + 'top': offset.top + } + }; + + if (this.options.stop) { + this.options.stop.call(this.$player, e, ui); + } + + if (this.helper) { + this.$helper.remove(); + } + + return false; + }; + + + fn.enable = function(){ + this.$container.on(pointer_events.start, this.options.items, $.proxy( + this.drag_handler, this)); + + this.$body.on(pointer_events.end, $.proxy(function(e) { + this.is_dragging = false; + this.$body.off(pointer_events.move); + if (this.drag_start) { + this.on_dragstop(e); + } + }, this)); + }; + + + fn.disable = function(){ + this.$container.off(pointer_events.start); + this.$body.off(pointer_events.end); + }; + + + fn.destroy = function(){ + this.disable(); + $.removeData(this.$container, 'draggable'); + }; + + + //jQuery adapter + $.fn.drag = function ( options ) { + return this.each(function () { + if (!$.data(this, 'drag')) { + $.data(this, 'drag', new Draggable( this, options )); + } + }); + }; + + +}(jQuery, window, document)); diff --git a/templates/project/assets/javascripts/gridster/jquery.gridster.js b/templates/project/assets/javascripts/gridster/jquery.gridster.js new file mode 100755 index 0000000..9099177 --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.gridster.js @@ -0,0 +1,2890 @@ +/*! gridster.js - v0.1.0 - 2012-08-14 +* http://gridster.net/ +* Copyright (c) 2012 ducksboard; Licensed MIT */ + +;(function($, window, document, undefined){ + /** + * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height) + * to simulate DOM elements on the screen. + * Coords is used by Gridster to create a faux grid with any DOM element can + * collide. + * + * @class Coords + * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left, + * top, width and height properties. + * @return {Object} Coords instance. + * @constructor + */ + function Coords(obj) { + if (obj[0] && $.isPlainObject(obj[0])) { + this.data = obj[0]; + }else { + this.el = obj; + } + + this.isCoords = true; + this.coords = {}; + this.init(); + return this; + } + + + var fn = Coords.prototype; + + + fn.init = function(){ + this.set(); + this.original_coords = this.get(); + }; + + + fn.set = function(update, not_update_offsets) { + var el = this.el; + + if (el && !update) { + this.data = el.offset(); + this.data.width = el.width(); + this.data.height = el.height(); + } + + if (el && update && !not_update_offsets) { + var offset = el.offset(); + this.data.top = offset.top; + this.data.left = offset.left; + } + + var d = this.data; + + this.coords.x1 = d.left; + this.coords.y1 = d.top; + this.coords.x2 = d.left + d.width; + this.coords.y2 = d.top + d.height; + this.coords.cx = d.left + (d.width / 2); + this.coords.cy = d.top + (d.height / 2); + this.coords.width = d.width; + this.coords.height = d.height; + this.coords.el = el || false ; + + return this; + }; + + + fn.update = function(data){ + if (!data && !this.el) { + return this; + } + + if (data) { + var new_data = $.extend({}, this.data, data); + this.data = new_data; + return this.set(true, true); + } + + this.set(true); + return this; + }; + + + fn.get = function(){ + return this.coords; + }; + + + //jQuery adapter + $.fn.coords = function() { + if (this.data('coords') ) { + return this.data('coords'); + } + + var ins = new Coords(this, arguments[0]); + this.data('coords', ins); + return ins; + }; + +}(jQuery, window, document)); + +;(function($, window, document, undefined){ + + var defaults = { + colliders_context: document.body + // ,on_overlap: function(collider_data){}, + // on_overlap_start : function(collider_data){}, + // on_overlap_stop : function(collider_data){} + }; + + + /** + * Detects collisions between a DOM element against other DOM elements or + * Coords objects. + * + * @class Collision + * @uses Coords + * @param {HTMLElement} el The jQuery wrapped HTMLElement. + * @param {HTMLElement|Array} colliders Can be a jQuery collection + * of HTMLElements or an Array of Coords instances. + * @param {Object} [options] An Object with all options you want to + * overwrite: + * @param {Function} [options.on_overlap_start] Executes a function the first + * time each `collider ` is overlapped. + * @param {Function} [options.on_overlap_stop] Executes a function when a + * `collider` is no longer collided. + * @param {Function} [options.on_overlap] Executes a function when the + * mouse is moved during the collision. + * @return {Object} Collision instance. + * @constructor + */ + function Collision(el, colliders, options) { + this.options = $.extend(defaults, options); + this.$element = el; + this.last_colliders = []; + this.last_colliders_coords = []; + if (typeof colliders === 'string' || colliders instanceof jQuery) { + this.$colliders = $(colliders, + this.options.colliders_context).not(this.$element); + }else{ + this.colliders = $(colliders); + } + + this.init(); + } + + + var fn = Collision.prototype; + + + fn.init = function() { + this.find_collisions(); + }; + + + fn.overlaps = function(a, b) { + var x = false; + var y = false; + + if ((b.x1 >= a.x1 && b.x1 <= a.x2) || + (b.x2 >= a.x1 && b.x2 <= a.x2) || + (a.x1 >= b.x1 && a.x2 <= b.x2) + ) { x = true; } + + if ((b.y1 >= a.y1 && b.y1 <= a.y2) || + (b.y2 >= a.y1 && b.y2 <= a.y2) || + (a.y1 >= b.y1 && a.y2 <= b.y2) + ) { y = true; } + + return (x && y); + }; + + + fn.detect_overlapping_region = function(a, b){ + var regionX = ''; + var regionY = ''; + + if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; } + if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; } + if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; } + if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; } + + return (regionX + regionY) || 'C'; + }; + + + fn.calculate_overlapped_area_coords = function(a, b){ + var x1 = Math.max(a.x1, b.x1); + var y1 = Math.max(a.y1, b.y1); + var x2 = Math.min(a.x2, b.x2); + var y2 = Math.min(a.y2, b.y2); + + return $({ + left: x1, + top: y1, + width : (x2 - x1), + height: (y2 - y1) + }).coords().get(); + }; + + + fn.calculate_overlapped_area = function(coords){ + return (coords.width * coords.height); + }; + + + fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){ + var last = this.last_colliders_coords; + + for (var i = 0, il = last.length; i < il; i++) { + if ($.inArray(last[i], new_colliders_coords) === -1) { + start_callback.call(this, last[i]); + } + } + + for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) { + if ($.inArray(new_colliders_coords[j], last) === -1) { + stop_callback.call(this, new_colliders_coords[j]); + } + + } + }; + + + fn.find_collisions = function(player_data_coords){ + var self = this; + var colliders_coords = []; + var colliders_data = []; + var $colliders = (this.colliders || this.$colliders); + var count = $colliders.length; + var player_coords = self.$element.coords() + .update(player_data_coords || false).get(); + + while(count--){ + var $collider = self.$colliders ? + $($colliders[count]) : $colliders[count]; + var $collider_coords_ins = ($collider.isCoords) ? + $collider : $collider.coords(); + var collider_coords = $collider_coords_ins.get(); + var overlaps = self.overlaps(player_coords, collider_coords); + + if (!overlaps) { + continue; + } + + var region = self.detect_overlapping_region( + player_coords, collider_coords); + + //todo: make this an option + if (region === 'C'){ + var area_coords = self.calculate_overlapped_area_coords( + player_coords, collider_coords); + var area = self.calculate_overlapped_area(area_coords); + var collider_data = { + area: area, + area_coords : area_coords, + region: region, + coords: collider_coords, + player_coords: player_coords, + el: $collider + }; + + if (self.options.on_overlap) { + self.options.on_overlap.call(this, collider_data); + } + colliders_coords.push($collider_coords_ins); + colliders_data.push(collider_data); + } + } + + if (self.options.on_overlap_stop || self.options.on_overlap_start) { + this.manage_colliders_start_stop(colliders_coords, + self.options.on_overlap_stop, self.options.on_overlap_start); + } + + this.last_colliders_coords = colliders_coords; + + return colliders_data; + }; + + + fn.get_closest_colliders = function(player_data_coords){ + var colliders = this.find_collisions(player_data_coords); + var min_area = 100; + colliders.sort(function(a, b){ + if (a.area <= min_area) { + return 1; + } + + /* if colliders are being overlapped by the "C" (center) region, + * we have to set a lower index in the array to which they are placed + * above in the grid. */ + if (a.region === 'C' && b.region === 'C') { + if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) { + return - 1; + }else{ + return 1; + } + } + + if (a.area < b.area){ + return 1; + } + + return 1; + }); + return colliders; + }; + + + //jQuery adapter + $.fn.collision = function(collider, options) { + return new Collision( this, collider, options ); + }; + + +}(jQuery, window, document)); + +;(function(window, undefined) { + /* Debounce and throttle functions taken from underscore.js */ + window.debounce = function(func, wait, immediate) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + if (immediate && !timeout) func.apply(context, args); + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + + window.throttle = function(func, wait) { + var context, args, timeout, throttling, more, result; + var whenDone = debounce( + function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + result = func.apply(context, args); + } + whenDone(); + throttling = true; + return result; + }; + }; + +})(window); + +;(function($, window, document, undefined){ + + var defaults = { + items: '.gs_w', + distance: 1, + limit: true, + offset_left: 0, + autoscroll: true + // ,drag: function(e){}, + // start : function(e, ui){}, + // stop : function(e){} + }; + + var $window = $(window); + var isTouch = !!('ontouchstart' in window); + var pointer_events = { + start: isTouch ? 'touchstart' : 'mousedown.draggable', + move: isTouch ? 'touchmove' : 'mousemove.draggable', + end: isTouch ? 'touchend' : 'mouseup.draggable' + }; + + /** + * Basic drag implementation for DOM elements inside a container. + * Provide start/stop/drag callbacks. + * + * @class Draggable + * @param {HTMLElement} el The HTMLelement that contains all the widgets + * to be dragged. + * @param {Object} [options] An Object with all options you want to + * overwrite: + * @param {HTMLElement|String} [options.items] Define who will + * be the draggable items. Can be a CSS Selector String or a + * collection of HTMLElements. + * @param {Number} [options.distance] Distance in pixels after mousedown + * the mouse must move before dragging should start. + * @param {Boolean} [options.limit] Constrains dragging to the width of + * the container + * @param {offset_left} [options.offset_left] Offset added to the item + * that is being dragged. + * @param {Number} [options.drag] Executes a callback when the mouse is + * moved during the dragging. + * @param {Number} [options.start] Executes a callback when the drag + * starts. + * @param {Number} [options.stop] Executes a callback when the drag stops. + * @return {Object} Returns `el`. + * @constructor + */ + function Draggable(el, options) { + this.options = $.extend({}, defaults, options); + this.$body = $(document.body); + this.$container = $(el); + this.$dragitems = $(this.options.items, this.$container); + this.is_dragging = false; + this.player_min_left = 0 + this.options.offset_left; + this.init(); + } + + var fn = Draggable.prototype; + + fn.init = function() { + this.calculate_positions(); + this.$container.css('position', 'relative'); + this.enable(); + + $(window).bind('resize', + throttle($.proxy(this.calculate_positions, this), 200)); + }; + + + fn.get_actual_pos = function($el) { + var pos = $el.position(); + return pos; + }; + + + fn.get_mouse_pos = function(e) { + if (isTouch) { + var oe = e.originalEvent; + e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0]; + }; + + return { + left: e.clientX, + top: e.clientY + }; + }; + + + fn.get_offset = function(e) { + e.preventDefault(); + var mouse_actual_pos = this.get_mouse_pos(e); + var diff_x = Math.round( + mouse_actual_pos.left - this.mouse_init_pos.left); + var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top); + + var left = Math.round(this.el_init_offset.left + diff_x - this.baseX); + var top = Math.round( + this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset); + + if (this.options.limit) { + if (left > this.player_max_left) { + left = this.player_max_left; + }else if(left < this.player_min_left) { + left = this.player_min_left; + } + } + + return { + left: left, + top: top, + mouse_left: mouse_actual_pos.left, + mouse_top: mouse_actual_pos.top + }; + }; + + + fn.manage_scroll = function(offset) { + /* scroll document */ + var nextScrollTop; + var scrollTop = $window.scrollTop(); + var min_window_y = scrollTop; + var max_window_y = min_window_y + this.window_height; + + var mouse_down_zone = max_window_y - 50; + var mouse_up_zone = min_window_y + 50; + + var abs_mouse_left = offset.mouse_left; + var abs_mouse_top = min_window_y + offset.mouse_top; + + var max_player_y = (this.doc_height - this.window_height + + this.player_height); + + if (abs_mouse_top >= mouse_down_zone) { + nextScrollTop = scrollTop + 30; + if (nextScrollTop < max_player_y) { + $window.scrollTop(nextScrollTop); + this.scrollOffset = this.scrollOffset + 30; + } + }; + + if (abs_mouse_top <= mouse_up_zone) { + nextScrollTop = scrollTop - 30; + if (nextScrollTop > 0) { + $window.scrollTop(nextScrollTop); + this.scrollOffset = this.scrollOffset - 30; + } + }; + } + + + fn.calculate_positions = function(e) { + this.window_height = $window.height(); + } + + + fn.drag_handler = function(e) { + var node = e.target.nodeName; + + if (e.which !== 1 && !isTouch) { + return; + } + + if (node === 'INPUT' || node === 'TEXTAREA' || node === 'SELECT' || + node === 'BUTTON') { + return; + }; + + var self = this; + var first = true; + this.$player = $(e.currentTarget); + + this.el_init_pos = this.get_actual_pos(this.$player); + this.mouse_init_pos = this.get_mouse_pos(e); + this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; + + this.$body.on(pointer_events.move, function(mme){ + var mouse_actual_pos = self.get_mouse_pos(mme); + var diff_x = Math.abs( + mouse_actual_pos.left - self.mouse_init_pos.left); + var diff_y = Math.abs( + mouse_actual_pos.top - self.mouse_init_pos.top); + if (!(diff_x > self.options.distance || + diff_y > self.options.distance) + ) { + return false; + } + + if (first) { + first = false; + self.on_dragstart.call(self, mme); + return false; + } + + if (self.is_dragging == true) { + self.on_dragmove.call(self, mme); + } + + return false; + }); + + return false; + }; + + + fn.on_dragstart = function(e) { + e.preventDefault(); + this.drag_start = true; + this.is_dragging = true; + var offset = this.$container.offset(); + this.baseX = Math.round(offset.left); + this.baseY = Math.round(offset.top); + this.doc_height = $(document).height(); + + if (this.options.helper === 'clone') { + this.$helper = this.$player.clone() + .appendTo(this.$container).addClass('helper'); + this.helper = true; + }else{ + this.helper = false; + } + this.scrollOffset = 0; + this.el_init_offset = this.$player.offset(); + this.player_width = this.$player.width(); + this.player_height = this.$player.height(); + this.player_max_left = (this.$container.width() - this.player_width + + this.options.offset_left); + + if (this.options.start) { + this.options.start.call(this.$player, e, { + helper: this.helper ? this.$helper : this.$player + }); + } + return false; + }; + + + fn.on_dragmove = function(e) { + var offset = this.get_offset(e); + + this.options.autoscroll && this.manage_scroll(offset); + + (this.helper ? this.$helper : this.$player).css({ + 'position': 'absolute', + 'left' : offset.left, + 'top' : offset.top + }); + + var ui = { + 'position': { + 'left': offset.left, + 'top': offset.top + } + }; + + if (this.options.drag) { + this.options.drag.call(this.$player, e, ui); + } + return false; + }; + + + fn.on_dragstop = function(e) { + var offset = this.get_offset(e); + this.drag_start = false; + + var ui = { + 'position': { + 'left': offset.left, + 'top': offset.top + } + }; + + if (this.options.stop) { + this.options.stop.call(this.$player, e, ui); + } + + if (this.helper) { + this.$helper.remove(); + } + + return false; + }; + + fn.on_select_start = function(e) { + return false; + } + + + fn.enable = function(){ + this.$container.on('selectstart', this.on_select_start); + + this.$container.on(pointer_events.start, this.options.items, $.proxy( + this.drag_handler, this)); + + this.$body.on(pointer_events.end, $.proxy(function(e) { + this.is_dragging = false; + this.$body.off(pointer_events.move); + if (this.drag_start) { + this.on_dragstop(e); + } + }, this)); + }; + + + fn.disable = function(){ + this.$container.off(pointer_events.start); + this.$body.off(pointer_events.end); + this.$container.off('selectstart', this.on_select_start); + }; + + + fn.destroy = function(){ + this.disable(); + $.removeData(this.$container, 'drag'); + }; + + + //jQuery adapter + $.fn.drag = function ( options ) { + return this.each(function () { + if (!$.data(this, 'drag')) { + $.data(this, 'drag', new Draggable( this, options )); + } + }); + }; + + +}(jQuery, window, document)); + +;(function($, window, document, undefined) { + + var defaults = { + widget_selector: '> li', + widget_margins: [10, 10], + widget_base_dimensions: [400, 225], + extra_rows: 0, + extra_cols: 0, + min_cols: 1, + min_rows: 15, + max_size_x: 6, + max_size_y: 6, + autogenerate_stylesheet: true, + avoid_overlapped_widgets: true, + serialize_params: function($w, wgd) { + return { + col: wgd.col, + row: wgd.row + }; + }, + collision: {}, + draggable: { + distance: 4 + } + }; + + + /** + * @class Gridster + * @uses Draggable + * @uses Collision + * @param {HTMLElement} el The HTMLelement that contains all the widgets. + * @param {Object} [options] An Object with all options you want to + * overwrite: + * @param {HTMLElement|String} [options.widget_selector] Define who will + * be the draggable widgets. Can be a CSS Selector String or a + * collection of HTMLElements + * @param {Array} [options.widget_margins] Margin between widgets. + * The first index for the horizontal margin (left, right) and + * the second for the vertical margin (top, bottom). + * @param {Array} [options.widget_base_dimensions] Base widget dimensions + * in pixels. The first index for the width and the second for the + * height. + * @param {Number} [options.extra_cols] Add more columns in addition to + * those that have been calculated. + * @param {Number} [options.extra_rows] Add more rows in addition to + * those that have been calculated. + * @param {Number} [options.min_cols] The minimum required columns. + * @param {Number} [options.min_rows] The minimum required rows. + * @param {Number} [options.max_size_x] The maximum number of columns + * that a widget can span. + * @param {Number} [options.max_size_y] The maximum number of rows + * that a widget can span. + * @param {Boolean} [options.autogenerate_stylesheet] If true, all the + * CSS required to position all widgets in their respective columns + * and rows will be generated automatically and injected to the + * `` of the document. You can set this to false, and write + * your own CSS targeting rows and cols via data-attributes like so: + * `[data-col="1"] { left: 10px; }` + * @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded + * from the DOM can be overlapped. It is helpful if the positions were + * bad stored in the database or if there was any conflict. + * @param {Function} [options.serialize_params] Return the data you want + * for each widget in the serialization. Two arguments are passed: + * `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid + * coords object (`col`, `row`, `size_x`, `size_y`). + * @param {Object} [options.collision] An Object with all options for + * Collision class you want to overwrite. See Collision docs for + * more info. + * @param {Object} [options.draggable] An Object with all options for + * Draggable class you want to overwrite. See Draggable docs for more + * info. + * + * @constructor + */ + function Gridster(el, options) { + this.options = $.extend(true, defaults, options); + this.$el = $(el); + this.$wrapper = this.$el.parent(); + this.$widgets = $(this.options.widget_selector, this.$el).addClass('gs_w'); + this.widgets = []; + this.$changed = $([]); + this.wrapper_width = this.$wrapper.width(); + this.min_widget_width = (this.options.widget_margins[0] * 2) + + this.options.widget_base_dimensions[0]; + this.min_widget_height = (this.options.widget_margins[1] * 2) + + this.options.widget_base_dimensions[1]; + this.init(); + } + + Gridster.generated_stylesheets = []; + + var fn = Gridster.prototype; + + fn.init = function() { + this.generate_grid_and_stylesheet(); + this.get_widgets_from_DOM(); + this.set_dom_grid_height(); + this.$wrapper.addClass('ready'); + this.draggable(); + + $(window).bind( + 'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200)); + }; + + + /** + * Disables dragging. + * + * @method disable + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.disable = function() { + this.$wrapper.find('.player-revert').removeClass('player-revert'); + this.drag_api.disable(); + return this; + }; + + + /** + * Enables dragging. + * + * @method enable + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.enable = function() { + this.drag_api.enable(); + return this; + }; + + + /** + * Add a new widget to the grid. + * + * @method add_widget + * @param {String} html The string representing the HTML of the widget. + * @param {Number} size_x The nº of rows the widget occupies horizontally. + * @param {Number} size_y The nº of columns the widget occupies vertically. + * @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing. + * the widget that was just created. + */ + fn.add_widget = function(html, size_x, size_y) { + var next_pos = this.next_position(size_x, size_y); + + var $w = $(html).attr({ + 'data-col': next_pos.col, + 'data-row': next_pos.row, + 'data-sizex' : next_pos.size_x, + 'data-sizey' : next_pos.size_y + }).addClass('gs_w').appendTo(this.$el).hide(); + + this.$widgets = this.$widgets.add($w); + + this.register_widget($w); + + this.set_dom_grid_height(); + + return $w.fadeIn(); + }; + + + /** + * Get the most left column below to add a new widget. + * + * @method next_position + * @param {Number} size_x The nº of rows the widget occupies horizontally. + * @param {Number} size_y The nº of columns the widget occupies vertically. + * @return {Object} Returns a grid coords object representing the future + * widget coords. + */ + fn.next_position = function(size_x, size_y) { + size_x || (size_x = 1); + size_y || (size_y = 1); + var ga = this.gridmap; + var cols_l = ga.length; + var valid_pos = []; + + for (var c = 1; c < cols_l; c++) { + var rows_l = ga[c].length; + for (var r = 1; r <= rows_l; r++) { + var can_move_to = this.can_move_to({ + size_x: size_x, + size_y: size_y + }, c, r); + + if (can_move_to) { + valid_pos.push({ + col: c, + row: r, + size_y: size_y, + size_x: size_x + }); + } + } + } + + if (valid_pos.length) { + return this.sort_by_row_and_col_asc(valid_pos)[0]; + } + return false; + }; + + + /** + * Remove a widget from the grid. + * + * @method remove_widget + * @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.remove_widget = function(el, callback) { + var $el = el instanceof jQuery ? el : $(el); + var wgd = $el.coords().grid; + + this.cells_occupied_by_placeholder = {}; + this.$widgets = this.$widgets.not($el); + + var $nexts = this.widgets_below($el); + + this.remove_from_gridmap(wgd); + + $el.fadeOut($.proxy(function() { + $el.remove(); + + $nexts.each($.proxy(function(i, widget) { + this.move_widget_up( $(widget), wgd.size_y ); + }, this)); + + this.set_dom_grid_height(); + + if (callback) { + callback.call(this, el); + } + }, this)); + }; + + + /** + * Returns a serialized array of the widgets in the grid. + * + * @method serialize + * @param {HTMLElement} [$widgets] The collection of jQuery wrapped + * HTMLElements you want to serialize. If no argument is passed all widgets + * will be serialized. + * @return {Array} Returns an Array of Objects with the data specified in + * the serialize_params option. + */ + fn.serialize = function($widgets) { + $widgets || ($widgets = this.$widgets); + var result = []; + $widgets.each($.proxy(function(i, widget) { + result.push(this.options.serialize_params( + $(widget), $(widget).coords().grid ) ); + }, this)); + + return result; + }; + + + /** + * Returns a serialized array of the widgets that have changed their + * position. + * + * @method serialize_changed + * @return {Array} Returns an Array of Objects with the data specified in + * the serialize_params option. + */ + fn.serialize_changed = function() { + return this.serialize(this.$changed); + }; + + + /** + * Creates the grid coords object representing the widget a add it to the + * mapped array of positions. + * + * @method register_widget + * @return {Array} Returns the instance of the Gridster class. + */ + fn.register_widget = function($el) { + + var wgd = { + 'col': parseInt($el.attr('data-col'), 10), + 'row': parseInt($el.attr('data-row'), 10), + 'size_x': parseInt($el.attr('data-sizex'), 10), + 'size_y': parseInt($el.attr('data-sizey'), 10), + 'el': $el + }; + + if (this.options.avoid_overlapped_widgets && + !this.can_move_to( + {size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row) + ) { + wgd = this.next_position(wgd.size_x, wgd.size_y); + wgd.el = $el; + $el.attr({ + 'data-col': wgd.col, + 'data-row': wgd.row, + 'data-sizex': wgd.size_x, + 'data-sizey': wgd.size_y + }); + } + + // attach Coord object to player data-coord attribute + $el.data('coords', $el.coords()); + + // Extend Coord object with grid position info + $el.data('coords').grid = wgd; + + this.add_to_gridmap(wgd, $el); + this.widgets.push($el); + return this; + }; + + + /** + * Update in the mapped array of positions the value of cells represented by + * the grid coords object passed in the `grid_data` param. + * + * @param {Object} grid_data The grid coords object representing the cells + * to update in the mapped array. + * @param {HTMLElement|Boolean} value Pass `false` or the jQuery wrapped + * HTMLElement, depends if you want to delete an existing position or add + * a new one. + * @method update_widget_position + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.update_widget_position = function(grid_data, value) { + this.for_each_cell_occupied(grid_data, function(col, row) { + if (!this.gridmap[col]) { return this; } + this.gridmap[col][row] = value; + }); + return this; + }; + + + /** + * Remove a widget from the mapped array of positions. + * + * @method remove_from_gridmap + * @param {Object} grid_data The grid coords object representing the cells + * to update in the mapped array. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.remove_from_gridmap = function(grid_data) { + return this.update_widget_position(grid_data, false); + }; + + + /** + * Add a widget to the mapped array of positions. + * + * @method add_to_gridmap + * @param {Object} grid_data The grid coords object representing the cells + * to update in the mapped array. + * @param {HTMLElement|Boolean} value The value to set in the specified + * position . + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.add_to_gridmap = function(grid_data, value) { + this.update_widget_position(grid_data, value || grid_data.el); + + if (grid_data.el) { + var $widgets = this.widgets_below(grid_data.el); + $widgets.each($.proxy(function(i, widget) { + this.move_widget_up( $(widget)); + }, this)); + } + }; + + + /** + * Make widgets draggable. + * + * @uses Draggable + * @method draggable + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.draggable = function() { + var self = this; + var draggable_options = $.extend(true, {}, this.options.draggable, { + offset_left: this.options.widget_margins[0], + items: '.gs_w', + start: function(event, ui) { + self.$widgets.filter('.player-revert') + .removeClass('player-revert'); + + self.$player = $(this); + self.$helper = self.options.draggable.helper === 'clone' ? + $(ui.helper) : self.$player; + self.helper = !self.$helper.is(self.$player); + + self.on_start_drag.call(self, event, ui); + self.$el.trigger('gridster:dragstart'); + }, + stop: function(event, ui) { + self.on_stop_drag.call(self, event, ui); + self.$el.trigger('gridster:dragstop'); + }, + drag: throttle(function(event, ui) { + self.on_drag.call(self, event, ui); + self.$el.trigger('gridster:drag'); + }, 60) + }); + + this.drag_api = this.$el.drag(draggable_options).data('drag'); + return this; + }; + + + /** + * This function is executed when the player begins to be dragged. + * + * @method on_start_drag + * @param {Event} The original browser event + * @param {Object} A prepared ui object. + */ + fn.on_start_drag = function(event, ui) { + + this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging'); + + this.$player.addClass('player'); + this.player_grid_data = this.$player.coords().grid; + this.placeholder_grid_data = $.extend({}, this.player_grid_data); + + //set new grid height along the dragging period + this.$el.css('height', this.$el.height() + + (this.player_grid_data.size_y * this.min_widget_height)); + + var colliders = this.faux_grid; + var coords = this.$player.data('coords').coords; + + this.cells_occupied_by_player = this.get_cells_occupied( + this.player_grid_data); + this.cells_occupied_by_placeholder = this.get_cells_occupied( + this.placeholder_grid_data); + + this.last_cols = []; + this.last_rows = []; + + + // see jquery.collision.js + this.collision_api = this.$helper.collision( + colliders, this.options.collision); + + this.$preview_holder = $('
  • ', { + 'class': 'preview-holder', + 'data-row': this.$player.attr('data-row'), + 'data-col': this.$player.attr('data-col'), + css: { + width: coords.width, + height: coords.height + } + }).appendTo(this.$el); + + if (this.options.draggable.start) { + this.options.draggable.start.call(this, event, ui); + } + }; + + + /** + * This function is executed when the player is being dragged. + * + * @method on_drag + * @param {Event} The original browser event + * @param {Object} A prepared ui object. + */ + fn.on_drag = function(event, ui) { + //break if dragstop has been fired + if (this.$player === null) { + return false; + }; + + var abs_offset = { + left: ui.position.left + this.baseX, + top: ui.position.top + this.baseY + }; + + this.colliders_data = this.collision_api.get_closest_colliders( + abs_offset); + + this.on_overlapped_column_change( + this.on_start_overlapping_column, + this.on_stop_overlapping_column + ); + + this.on_overlapped_row_change( + this.on_start_overlapping_row, + this.on_stop_overlapping_row + ); + + if (this.helper && this.$player) { + this.$player.css({ + 'left': ui.position.left, + 'top': ui.position.top + }); + } + + if (this.options.draggable.drag) { + this.options.draggable.drag.call(this, event, ui); + } + }; + + /** + * This function is executed when the player stops being dragged. + * + * @method on_stop_drag + * @param {Event} The original browser event + * @param {Object} A prepared ui object. + */ + fn.on_stop_drag = function(event, ui) { + this.$helper.add(this.$player).add(this.$wrapper) + .removeClass('dragging'); + + ui.position.left = ui.position.left + this.baseX; + ui.position.top = ui.position.top + this.baseY; + this.colliders_data = this.collision_api.get_closest_colliders(ui.position); + + this.on_overlapped_column_change( + this.on_start_overlapping_column, + this.on_stop_overlapping_column + ); + + this.on_overlapped_row_change( + this.on_start_overlapping_row, + this.on_stop_overlapping_row + ); + + this.$player.addClass('player-revert').removeClass('player') + .attr({ + 'data-col': this.placeholder_grid_data.col, + 'data-row': this.placeholder_grid_data.row + }).css({ + 'left': '', + 'top': '' + }); + + this.$changed = this.$changed.add(this.$player); + + this.cells_occupied_by_player = this.get_cells_occupied( + this.placeholder_grid_data); + this.set_cells_player_occupies( + this.placeholder_grid_data.col, this.placeholder_grid_data.row); + + this.$player.coords().grid.row = this.placeholder_grid_data.row; + this.$player.coords().grid.col = this.placeholder_grid_data.col; + + if (this.options.draggable.stop) { + this.options.draggable.stop.call(this, event, ui); + } + + this.$preview_holder.remove(); + this.$player = null; + + this.set_dom_grid_height(); + }; + + + /** + * Executes the callbacks passed as arguments when a column begins to be + * overlapped or stops being overlapped. + * + * @param {Function} start_callback Function executed when a new column + * begins to be overlapped. The column is passed as first argument. + * @param {Function} stop_callback Function executed when a column stops + * being overlapped. The column is passed as first argument. + * @method on_overlapped_column_change + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.on_overlapped_column_change = function(start_callback, stop_callback) { + if (!this.colliders_data.length) { + return; + } + var cols = this.get_targeted_columns( + this.colliders_data[0].el.data.col); + + var last_n_cols = this.last_cols.length; + var n_cols = cols.length; + var i; + + for (i = 0; i < n_cols; i++) { + if ($.inArray(cols[i], this.last_cols) === -1) { + (start_callback || $.noop).call(this, cols[i]); + } + } + + for (i = 0; i< last_n_cols; i++) { + if ($.inArray(this.last_cols[i], cols) === -1) { + (stop_callback || $.noop).call(this, this.last_cols[i]); + } + } + + this.last_cols = cols; + + return this; + }; + + + /** + * Executes the callbacks passed as arguments when a row starts to be + * overlapped or stops being overlapped. + * + * @param {Function} start_callback Function executed when a new row begins + * to be overlapped. The row is passed as first argument. + * @param {Function} stop_callback Function executed when a row stops being + * overlapped. The row is passed as first argument. + * @method on_overlapped_row_change + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.on_overlapped_row_change = function(start_callback, end_callback) { + if (!this.colliders_data.length) { + return; + } + var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); + var last_n_rows = this.last_rows.length; + var n_rows = rows.length; + var i; + + for (i = 0; i < n_rows; i++) { + if ($.inArray(rows[i], this.last_rows) === -1) { + (start_callback || $.noop).call(this, rows[i]); + } + } + + for (i = 0; i < last_n_rows; i++) { + if ($.inArray(this.last_rows[i], rows) === -1) { + (end_callback || $.noop).call(this, this.last_rows[i]); + } + } + + this.last_rows = rows; + }; + + + /** + * Sets the current position of the player + * + * @param {Function} start_callback Function executed when a new row begins + * to be overlapped. The row is passed as first argument. + * @param {Function} stop_callback Function executed when a row stops being + * overlapped. The row is passed as first argument. + * @method set_player + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.set_player = function(col, row) { + this.empty_cells_player_occupies(); + + var self = this; + var cell = self.colliders_data[0].el.data; + var to_col = cell.col; + var to_row = row || cell.row; + + this.player_grid_data = { + col: to_col, + row: to_row, + size_y : this.player_grid_data.size_y, + size_x : this.player_grid_data.size_x + }; + + this.cells_occupied_by_player = this.get_cells_occupied( + this.player_grid_data); + + var $overlapped_widgets = this.get_widgets_overlapped( + this.player_grid_data); + + var constraints = this.widgets_constraints($overlapped_widgets); + + this.manage_movements(constraints.can_go_up, to_col, to_row); + this.manage_movements(constraints.can_not_go_up, to_col, to_row); + + /* if there is not widgets overlapping in the new player position, + * update the new placeholder position. */ + if (!$overlapped_widgets.length) { + var pp = this.can_go_player_up(this.player_grid_data); + if (pp !== false) { + to_row = pp; + } + this.set_placeholder(to_col, to_row); + } + + return { + col: to_col, + row: to_row + }; + }; + + + /** + * See which of the widgets in the $widgets param collection can go to + * a upper row and which not. + * + * @method widgets_contraints + * @param {HTMLElements} $widgets A jQuery wrapped collection of + * HTMLElements. + * @return {Array} Returns a literal Object with two keys: `can_go_up` & + * `can_not_go_up`. Each contains a set of HTMLElements. + */ + fn.widgets_constraints = function($widgets) { + var $widgets_can_go_up = $([]); + var $widgets_can_not_go_up; + var wgd_can_go_up = []; + var wgd_can_not_go_up = []; + + $widgets.each($.proxy(function(i, w) { + var $w = $(w); + var wgd = $w.coords().grid; + if (this.can_go_widget_up(wgd)) { + $widgets_can_go_up = $widgets_can_go_up.add($w); + wgd_can_go_up.push(wgd); + }else{ + wgd_can_not_go_up.push(wgd); + } + }, this)); + + $widgets_can_not_go_up = $widgets.not($widgets_can_go_up); + + return { + can_go_up: this.sort_by_row_asc(wgd_can_go_up), + can_not_go_up: this.sort_by_row_desc(wgd_can_not_go_up) + }; + }; + + + /** + * Sorts an Array of grid coords objects (representing the grid coords of + * each widget) in ascending way. + * + * @method sort_by_row_asc + * @param {Array} widgets Array of grid coords objects + * @return {Array} Returns the array sorted. + */ + fn.sort_by_row_asc = function(widgets) { + widgets = widgets.sort(function(a, b) { + if (a.row > b.row) { + return 1; + } + return -1; + }); + + return widgets; + }; + + + /** + * Sorts an Array of grid coords objects (representing the grid coords of + * each widget) placing first the empty cells upper left. + * + * @method sort_by_row_and_col_asc + * @param {Array} widgets Array of grid coords objects + * @return {Array} Returns the array sorted. + */ + fn.sort_by_row_and_col_asc = function(widgets) { + widgets = widgets.sort(function(a, b) { + if (a.row > b.row || a.row == b.row && a.col > b.col) { + return 1; + } + return -1; + }); + + return widgets; + }; + + + /** + * Sorts an Array of grid coords objects by column (representing the grid + * coords of each widget) in ascending way. + * + * @method sort_by_col_asc + * @param {Array} widgets Array of grid coords objects + * @return {Array} Returns the array sorted. + */ + fn.sort_by_col_asc = function(widgets) { + widgets = widgets.sort(function(a, b) { + if (a.col > b.col) { + return 1; + } + return -1; + }); + + return widgets; + }; + + + /** + * Sorts an Array of grid coords objects (representing the grid coords of + * each widget) in descending way. + * + * @method sort_by_row_desc + * @param {Array} widgets Array of grid coords objects + * @return {Array} Returns the array sorted. + */ + fn.sort_by_row_desc = function(widgets) { + widgets = widgets.sort(function(a, b) { + if (a.row + a.size_y < b.row + b.size_y) { + return 1; + } + return -1; + }); + return widgets; + }; + + + /** + * Sorts an Array of grid coords objects (representing the grid coords of + * each widget) in descending way. + * + * @method manage_movements + * @param {HTMLElements} $widgets A jQuery collection of HTMLElements + * representing the widgets you want to move. + * @param {Number} to_col The column to which we want to move the widgets. + * @param {Number} to_row The row to which we want to move the widgets. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.manage_movements = function($widgets, to_col, to_row) { + $.each($widgets, $.proxy(function(i, w) { + var wgd = w; + var $w = wgd.el; + + var can_go_widget_up = this.can_go_widget_up(wgd); + + if (can_go_widget_up) { + //target CAN go up + //so move widget up + this.move_widget_to($w, can_go_widget_up); + this.set_placeholder(to_col, can_go_widget_up + wgd.size_y); + + } else { + //target can't go up + var can_go_player_up = this.can_go_player_up( + this.player_grid_data); + + if (!can_go_player_up) { + // target can't go up + // player cant't go up + // so we need to move widget down to a position that dont + // overlaps player + var y = (to_row + this.player_grid_data.size_y) - wgd.row; + + this.move_widget_down($w, y); + this.set_placeholder(to_col, to_row); + } + } + }, this)); + + return this; + }; + + /** + * Determines if there is a widget in the row and col given. Or if the + * HTMLElement passed as first argument is the player. + * + * @method is_player + * @param {Number|HTMLElement} col_or_el A jQuery wrapped collection of + * HTMLElements. + * @param {Number} [row] The column to which we want to move the widgets. + * @return {Boolean} Returns true or false. + */ + fn.is_player = function(col_or_el, row) { + if (row && !this.gridmap[col_or_el]) { return false; } + var $w = row ? this.gridmap[col_or_el][row] : col_or_el; + return $w && ($w.is(this.$player) || $w.is(this.$helper)); + }; + + + /** + * Determines if the widget that is being dragged is currently over the row + * and col given. + * + * @method is_player_in + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean} Returns true or false. + */ + fn.is_player_in = function(col, row) { + var c = this.cells_occupied_by_player || {}; + return $.inArray(col, c.cols) >= 0 && $.inArray(row, c.rows) >= 0; + }; + + + /** + * Determines if the placeholder is currently over the row and col given. + * + * @method is_placeholder_in + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean} Returns true or false. + */ + fn.is_placeholder_in = function(col, row) { + var c = this.cells_occupied_by_placeholder || {}; + return this.is_placeholder_in_col(col) && $.inArray(row, c.rows) >= 0; + }; + + + /** + * Determines if the placeholder is currently over the column given. + * + * @method is_placeholder_in_col + * @param {Number} col The column to check. + * @return {Boolean} Returns true or false. + */ + fn.is_placeholder_in_col = function(col) { + var c = this.cells_occupied_by_placeholder || []; + return $.inArray(col, c.cols) >= 0; + }; + + + /** + * Determines if the cell represented by col and row params is empty. + * + * @method is_empty + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean} Returns true or false. + */ + fn.is_empty = function(col, row) { + if (typeof this.gridmap[col] !== 'undefined' && + typeof this.gridmap[col][row] !== 'undefined' && + this.gridmap[col][row] === false + ) { + return true; + } + return false; + }; + + + /** + * Determines if the cell represented by col and row params is occupied. + * + * @method is_occupied + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean} Returns true or false. + */ + fn.is_occupied = function(col, row) { + if (!this.gridmap[col]) { + return false; + } + + if (this.gridmap[col][row]) { + return true; + } + return false; + }; + + + /** + * Determines if there is a widget in the cell represented by col/row params. + * + * @method is_widget + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean|HTMLElement} Returns false if there is no widget, + * else returns the jQuery HTMLElement + */ + fn.is_widget = function(col, row) { + var cell = this.gridmap[col]; + if (!cell) { + return false; + } + + cell = cell[row]; + + if (cell) { + return cell; + } + + return false; + }; + + + /** + * Determines if there is a widget in the cell represented by col/row + * params and if this is under the widget that is being dragged. + * + * @method is_widget_under_player + * @param {Number} col The column to check. + * @param {Number} row The row to check. + * @return {Boolean} Returns true or false. + */ + fn.is_widget_under_player = function(col, row) { + if (this.is_widget(col, row)) { + return this.is_player_in(col, row); + } + return false; + }; + + + /** + * Get widgets overlapping with the player. + * + * @method get_widgets_under_player + * @return {HTMLElement} Returns a jQuery collection of HTMLElements + */ + fn.get_widgets_under_player = function() { + var cells = this.cells_occupied_by_player; + var $widgets = $([]); + + $.each(cells.cols, $.proxy(function(i, col) { + $.each(cells.rows, $.proxy(function(i, row) { + if(this.is_widget(col, row)) { + $widgets = $widgets.add(this.gridmap[col][row]); + } + }, this)); + }, this)); + + return $widgets; + }; + + + /** + * Put placeholder at the row and column specified. + * + * @method set_placeholder + * @param {Number} col The column to which we want to move the + * placeholder. + * @param {Number} row The row to which we want to move the + * placeholder. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.set_placeholder = function(col, row) { + var phgd = $.extend({}, this.placeholder_grid_data); + var $nexts = this.widgets_below({ + col: phgd.col, + row: phgd.row, + size_y: phgd.size_y, + size_x: phgd.size_x + }); + + //Prevents widgets go out of the grid + var right_col = (col + phgd.size_x - 1); + if (right_col > this.cols) { + col = col - (right_col - col); + } + + var moved_down = this.placeholder_grid_data.row < row; + var changed_column = this.placeholder_grid_data.col !== col; + + this.placeholder_grid_data.col = col; + this.placeholder_grid_data.row = row; + + this.cells_occupied_by_placeholder = this.get_cells_occupied( + this.placeholder_grid_data); + + this.$preview_holder.attr({ + 'data-row' : row, + 'data-col' : col + }); + + if (moved_down || changed_column) { + $nexts.each($.proxy(function(i, widget) { + this.move_widget_up( + $(widget), this.placeholder_grid_data.col - col + phgd.size_y); + }, this)); + } + + }; + + + /** + * Determines whether the player can move to a position above. + * + * @method can_go_player_up + * @param {Object} widget_grid_data The actual grid coords object of the + * player. + * @return {Number|Boolean} If the player can be moved to an upper row + * returns the row number, else returns false. + */ + fn.can_go_player_up = function(widget_grid_data) { + var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; + var result = true; + var upper_rows = []; + var min_row = 10000; + var $widgets_under_player = this.get_widgets_under_player(); + + /* generate an array with columns as index and array with upper rows + * empty as value */ + this.for_each_column_occupied(widget_grid_data, function(tcol) { + var grid_col = this.gridmap[tcol]; + var r = p_bottom_row + 1; + upper_rows[tcol] = []; + + while (--r > 0) { + if (this.is_empty(tcol, r) || this.is_player(tcol, r) || + this.is_widget(tcol, r) && + grid_col[r].is($widgets_under_player) + ) { + upper_rows[tcol].push(r); + min_row = r < min_row ? r : min_row; + }else{ + break; + } + } + + if (upper_rows[tcol].length === 0) { + result = false; + return true; //break + } + + upper_rows[tcol].sort(); + }); + + if (!result) { return false; } + + return this.get_valid_rows(widget_grid_data, upper_rows, min_row); + }; + + + /** + * Determines whether a widget can move to a position above. + * + * @method can_go_widget_up + * @param {Object} widget_grid_data The actual grid coords object of the + * widget we want to check. + * @return {Number|Boolean} If the widget can be moved to an upper row + * returns the row number, else returns false. + */ + fn.can_go_widget_up = function(widget_grid_data) { + var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; + var result = true; + var upper_rows = []; + var min_row = 10000; + + if (widget_grid_data.col < this.player_grid_data.col && + (widget_grid_data.col + widget_grid_data.size_y - 1) > + (this.player_grid_data.col + this.player_grid_data.size_y - 1) + ) { + return false; + }; + + /* generate an array with columns as index and array with upper rows + * empty as value */ + this.for_each_column_occupied(widget_grid_data, function(tcol) { + var grid_col = this.gridmap[tcol]; + upper_rows[tcol] = []; + + var r = p_bottom_row + 1; + + while (--r > 0) { + if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) { + if (!grid_col[r].is(widget_grid_data.el)) { + break; + }; + } + + if (!this.is_player(tcol, r) && + !this.is_placeholder_in(tcol, r) && + !this.is_player_in(tcol, r)) { + upper_rows[tcol].push(r); + }; + + if (r < min_row) { + min_row = r; + } + } + + if (upper_rows[tcol].length === 0) { + result = false; + return true; //break + } + + upper_rows[tcol].sort(); + }); + + if (!result) { return false; } + + return this.get_valid_rows(widget_grid_data, upper_rows, min_row); + }; + + + /** + * Search a valid row for the widget represented by `widget_grid_data' in + * the `upper_rows` array. Iteration starts from row specified in `min_row`. + * + * @method get_valid_rows + * @param {Object} widget_grid_data The actual grid coords object of the + * player. + * @param {Array} upper_rows An array with columns as index and arrays + * of valid rows as values. + * @param {Number} min_row The upper row from which the iteration will start. + * @return {Number|Boolean} Returns the upper row valid from the `upper_rows` + * for the widget in question. + */ + fn.get_valid_rows = function(widget_grid_data, upper_rows, min_row) { + var p_top_row = widget_grid_data.row; + var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; + var size_y = widget_grid_data.size_y; + var r = min_row - 1; + var valid_rows = []; + + while (++r <= p_bottom_row ) { + var common = true; + $.each(upper_rows, function(col, rows) { + if ($.isArray(rows) && $.inArray(r, rows) === -1) { + common = false; + } + }); + + if (common === true) { + valid_rows.push(r); + if (valid_rows.length === size_y) { + break; + } + } + } + + var new_row = false; + if (size_y === 1) { + if (valid_rows[0] !== p_top_row) { + new_row = valid_rows[0] || false; + } + }else{ + if (valid_rows[0] !== p_top_row) { + new_row = this.get_consecutive_numbers_index( + valid_rows, size_y); + } + } + + return new_row; + }; + + + fn.get_consecutive_numbers_index = function(arr, size_y) { + var max = arr.length; + var result = []; + var first = true; + var prev = -1; // or null? + + for (var i=0; i < max; i++) { + if (first || arr[i] === prev + 1) { + result.push(i); + if (result.length === size_y) { + break; + } + first = false; + }else{ + result = []; + first = true; + } + + prev = arr[i]; + } + + return result.length >= size_y ? arr[result[0]] : false; + }; + + + /** + * Get widgets overlapping with the player. + * + * @method get_widgets_overlapped + * @return {HTMLElements} Returns a jQuery collection of HTMLElements. + */ + fn.get_widgets_overlapped = function() { + var $w; + var $widgets = $([]); + var used = []; + var rows_from_bottom = this.cells_occupied_by_player.rows.slice(0); + rows_from_bottom.reverse(); + + $.each(this.cells_occupied_by_player.cols, $.proxy(function(i, col) { + $.each(rows_from_bottom, $.proxy(function(i, row) { + // if there is a widget in the player position + if (!this.gridmap[col]) { return true; } //next iteration + var $w = this.gridmap[col][row]; + + if (this.is_occupied(col, row) && !this.is_player($w) && + $.inArray($w, used) === -1 + ) { + $widgets = $widgets.add($w); + used.push($w); + } + + }, this)); + }, this)); + + return $widgets; + }; + + + /** + * This callback is executed when the player begins to collide with a column. + * + * @method on_start_overlapping_column + * @param {Number} col The collided column. + * @return {HTMLElements} Returns a jQuery collection of HTMLElements. + */ + fn.on_start_overlapping_column = function(col) { + this.set_player(col, false); + }; + + + /** + * A callback executed when the player begins to collide with a row. + * + * @method on_start_overlapping_row + * @param {Number} col The collided row. + * @return {HTMLElements} Returns a jQuery collection of HTMLElements. + */ + fn.on_start_overlapping_row = function(row) { + this.set_player(false, row); + }; + + + /** + * A callback executed when the the player ends to collide with a column. + * + * @method on_stop_overlapping_column + * @param {Number} col The collided row. + * @return {HTMLElements} Returns a jQuery collection of HTMLElements. + */ + fn.on_stop_overlapping_column = function(col) { + this.set_player(col, false); + + var self = this; + this.for_each_widget_below(col, this.cells_occupied_by_player.rows[0], + function(tcol, trow) { + self.move_widget_up(this, self.player_grid_data.size_y); + }); + }; + + + /** + * This callback is executed when the player ends to collide with a row. + * + * @method on_stop_overlapping_row + * @param {Number} row The collided row. + * @return {HTMLElements} Returns a jQuery collection of HTMLElements. + */ + fn.on_stop_overlapping_row = function(row) { + this.set_player(false, row); + + var self = this; + var cols = this.cells_occupied_by_player.cols; + for (var c = 0, cl = cols.length; c < cl; c++) { + this.for_each_widget_below(cols[c], row, function(tcol, trow) { + self.move_widget_up(this, self.player_grid_data.size_y); + }); + } + }; + + + /** + * Move a widget to a specific row. The cell or cells must be empty. + * If the widget has widgets below, all of these widgets will be moved also + * if they can. + * + * @method move_widget_to + * @param {HTMLElement} $widget The jQuery wrapped HTMLElement of the + * widget is going to be moved. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.move_widget_to = function($widget, row) { + var self = this; + var widget_grid_data = $widget.coords().grid; + var diff = row - widget_grid_data.row; + var $next_widgets = this.widgets_below($widget); + + var can_move_to_new_cell = this.can_move_to( + widget_grid_data, widget_grid_data.col, row, $widget); + + if (can_move_to_new_cell === false) { + return false; + } + + this.remove_from_gridmap(widget_grid_data); + widget_grid_data.row = row; + this.add_to_gridmap(widget_grid_data); + $widget.attr('data-row', row); + this.$changed = this.$changed.add($widget); + + + $next_widgets.each(function(i, widget) { + var $w = $(widget); + var wgd = $w.coords().grid; + var can_go_up = self.can_go_widget_up(wgd); + if (can_go_up && can_go_up !== wgd.row) { + self.move_widget_to($w, can_go_up); + } + }); + + return this; + }; + + + /** + * Move up the specified widget and all below it. + * + * @method move_widget_up + * @param {HTMLElement} $widget The widget you want to move. + * @param {Number} [y_units] The number of cells that the widget has to move. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.move_widget_up = function($widget, y_units) { + var el_grid_data = $widget.coords().grid; + var actual_row = el_grid_data.row; + var moved = []; + var can_go_up = true; + y_units || (y_units = 1); + + if (!this.can_go_up($widget)) { return false; } //break; + + this.for_each_column_occupied(el_grid_data, function(col) { + // can_go_up + if ($.inArray($widget, moved) === -1) { + var widget_grid_data = $widget.coords().grid; + var next_row = actual_row - y_units; + next_row = this.can_go_up_to_row( + widget_grid_data, col, next_row); + + if (!next_row) { + return true; + } + + var $next_widgets = this.widgets_below($widget); + + this.remove_from_gridmap(widget_grid_data); + widget_grid_data.row = next_row; + this.add_to_gridmap(widget_grid_data); + $widget.attr('data-row', widget_grid_data.row); + this.$changed = this.$changed.add($widget); + + moved.push($widget); + + $next_widgets.each($.proxy(function(i, widget) { + this.move_widget_up($(widget), y_units); + }, this)); + } + }); + + }; + + + /** + * Move down the specified widget and all below it. + * + * @method move_widget_down + * @param {HTMLElement} $widget The jQuery object representing the widget + * you want to move. + * @param {Number} The number of cells that the widget has to move. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.move_widget_down = function($widget, y_units) { + var el_grid_data = $widget.coords().grid; + var actual_row = el_grid_data.row; + var moved = []; + var y_diff = y_units; + + if (!$widget) { return false; } + + if ($.inArray($widget, moved) === -1) { + + var widget_grid_data = $widget.coords().grid; + var next_row = actual_row + y_units; + var $next_widgets = this.widgets_below($widget); + + this.remove_from_gridmap(widget_grid_data); + + $next_widgets.each($.proxy(function(i, widget) { + var $w = $(widget); + var wd = $w.coords().grid; + var tmp_y = this.displacement_diff( + wd, widget_grid_data, y_diff); + + if (tmp_y > 0) { + this.move_widget_down($w, tmp_y); + } + }, this)); + + widget_grid_data.row = next_row; + this.update_widget_position(widget_grid_data, $widget); + $widget.attr('data-row', widget_grid_data.row); + this.$changed = this.$changed.add($widget); + + moved.push($widget); + } + }; + + + /** + * Check if the widget can move to the specified row, else returns the + * upper row possible. + * + * @method can_go_up_to_row + * @param {Number} widget_grid_data The current grid coords object of the + * widget. + * @param {Number} col The target column. + * @param {Number} row The target row. + * @return {Boolean|Number} Returns the row number if the widget can move + * to the target position, else returns false. + */ + fn.can_go_up_to_row = function(widget_grid_data, col, row) { + var ga = this.gridmap; + var result = true; + var urc = []; // upper_rows_in_columns + var actual_row = widget_grid_data.row; + var r; + + /* generate an array with columns as index and array with + * upper rows empty in the column */ + this.for_each_column_occupied(widget_grid_data, function(tcol) { + var grid_col = ga[tcol]; + urc[tcol] = []; + + r = actual_row; + while (r--) { + if (this.is_empty(tcol, r) && + !this.is_placeholder_in(tcol, r) + ) { + urc[tcol].push(r); + }else{ + break; + } + } + + if (!urc[tcol].length) { + result = false; + return true; + } + + }); + + if (!result) { return false; } + + /* get common rows starting from upper position in all the columns + * that widget occupies */ + r = row; + for (r = 1; r < actual_row; r++) { + var common = true; + + for (var uc = 0, ucl = urc.length; uc < ucl; uc++) { + if (urc[uc] && $.inArray(r, urc[uc]) === -1) { + common = false; + } + } + + if (common === true) { + result = r; + break; + } + } + + return result; + }; + + + fn.displacement_diff = function(widget_grid_data, parent_bgd, y_units) { + var actual_row = widget_grid_data.row; + var diffs = []; + var parent_max_y = parent_bgd.row + parent_bgd.size_y; + + this.for_each_column_occupied(widget_grid_data, function(col) { + var temp_y_units = 0; + + for (var r = parent_max_y; r < actual_row; r++) { + if (this.is_empty(col, r)) { + temp_y_units = temp_y_units + 1; + } + } + + diffs.push(temp_y_units); + }); + + var max_diff = Math.max.apply(Math, diffs); + y_units = (y_units - max_diff); + + return y_units > 0 ? y_units : 0; + }; + + + /** + * Get widgets below a widget. + * + * @method widgets_below + * @param {HTMLElement} $el The jQuery wrapped HTMLElement. + * @return {HTMLElements} A jQuery collection of HTMLElements. + */ + fn.widgets_below = function($el) { + var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; + var self = this; + var ga = this.gridmap; + var next_row = el_grid_data.row + el_grid_data.size_y - 1; + var $nexts = $([]); + + this.for_each_column_occupied(el_grid_data, function(col) { + self.for_each_widget_below(col, next_row, + function(tcol, trow) { + if (!self.is_player(this) && + $.inArray(this, $nexts) === -1) { + $nexts = $nexts.add(this); + return true; // break + } + }); + }); + + return this.sort_by_row_asc($nexts); + }; + + + /** + * Update the array of mapped positions with the new player position. + * + * @method set_cells_player_occupies + * @param {Number} col The new player col. + * @param {Number} col The new player row. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.set_cells_player_occupies = function(col, row) { + this.remove_from_gridmap(this.placeholder_grid_data); + this.placeholder_grid_data.col = col; + this.placeholder_grid_data.row = row; + this.add_to_gridmap(this.placeholder_grid_data, this.$player); + return this; + }; + + + /** + * Remove from the array of mapped positions the reference to the player. + * + * @method empty_cells_player_occupies + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.empty_cells_player_occupies = function() { + this.remove_from_gridmap(this.placeholder_grid_data); + return this; + }; + + + fn.can_go_up = function($el) { + var el_grid_data = $el.coords().grid; + var initial_row = el_grid_data.row; + var prev_row = initial_row - 1; + var ga = this.gridmap; + var upper_rows_by_column = []; + + var result = true; + if (initial_row === 1) { return false; } + + this.for_each_column_occupied(el_grid_data, function(col) { + var $w = this.is_widget(col, prev_row); + if (this.is_occupied(col, prev_row) || + this.is_player(col, prev_row) || + this.is_placeholder_in(col, prev_row) || + this.is_player_in(col, prev_row) + ) { + result = false; + return true; //break + } + }); + + return result; + }; + + + + /** + * Check if it's possible to move a widget to a specific col/row. It takes + * into account the dimensions (`size_y` and `size_x` attrs. of the grid + * coords object) the widget occupies. + * + * @method can_move_to + * @param {Object} widget_grid_data The grid coords object that represents + * the widget. + * @param {Object} col The col to check. + * @param {Object} row The row to check. + * @return {Boolean} Returns true if all cells are empty, else return false. + */ + fn.can_move_to = function(widget_grid_data, col, row) { + var ga = this.gridmap; + var $w = widget_grid_data.el; + var future_wd = { + size_y: widget_grid_data.size_y, + size_x: widget_grid_data.size_x, + col: col, + row: row + }; + var result = true; + + //Prevents widgets go out of the grid + var right_col = col + widget_grid_data.size_x - 1; + if (right_col > this.cols) { + return false; + }; + + this.for_each_cell_occupied(future_wd, function(tcol, trow) { + var $tw = this.is_widget(tcol, trow); + if ($tw && (!widget_grid_data.el || $tw.is($w))) { + result = false; + } + }); + + return result; + }; + + + /** + * Given the leftmost column returns all columns that are overlapping + * with the player. + * + * @method get_targeted_columns + * @param {Number} [from_col] The leftmost column. + * @return {Array} Returns an array with column numbers. + */ + fn.get_targeted_columns = function(from_col) { + var max = (from_col || this.player_grid_data.col) + + (this.player_grid_data.size_x - 1); + var cols = []; + for (var col = from_col; col <= max; col++) { + cols.push(col); + } + return cols; + }; + + + /** + * Given the upper row returns all rows that are overlapping with the player. + * + * @method get_targeted_rows + * @param {Number} [from_row] The upper row. + * @return {Array} Returns an array with row numbers. + */ + fn.get_targeted_rows = function(from_row) { + var max = (from_row || this.player_grid_data.row) + + (this.player_grid_data.size_y - 1); + var rows = []; + for (var row = from_row; row <= max; row++) { + rows.push(row); + } + return rows; + }; + + /** + * Get all columns and rows that a widget occupies. + * + * @method get_cells_occupied + * @param {Object} el_grid_data The grid coords object of the widget. + * @return {Object} Returns an object like `{ cols: [], rows: []}`. + */ + fn.get_cells_occupied = function(el_grid_data) { + var cells = { cols: [], rows: []}; + var i; + if (arguments[1] instanceof jQuery) { + el_grid_data = arguments[1].coords().grid; + } + + for (i = 0; i < el_grid_data.size_x; i++) { + var col = el_grid_data.col + i; + cells.cols.push(col); + } + + for (i = 0; i < el_grid_data.size_y; i++) { + var row = el_grid_data.row + i; + cells.rows.push(row); + } + + return cells; + }; + + + /** + * Iterate over the cells occupied by a widget executing a function for + * each one. + * + * @method for_each_cell_occupied + * @param {Object} el_grid_data The grid coords object that represents the + * widget. + * @param {Function} callback The function to execute on each column + * iteration. Column and row are passed as arguments. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.for_each_cell_occupied = function(grid_data, callback) { + this.for_each_column_occupied(grid_data, function(col) { + this.for_each_row_occupied(grid_data, function(row) { + callback.call(this, col, row); + }); + }); + return this; + }; + + + /** + * Iterate over the columns occupied by a widget executing a function for + * each one. + * + * @method for_each_column_occupied + * @param {Object} el_grid_data The grid coords object that represents + * the widget. + * @param {Function} callback The function to execute on each column + * iteration. The column number is passed as first argument. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.for_each_column_occupied = function(el_grid_data, callback) { + for (var i = 0; i < el_grid_data.size_x; i++) { + var col = el_grid_data.col + i; + callback.call(this, col, el_grid_data); + } + }; + + + /** + * Iterate over the rows occupied by a widget executing a function for + * each one. + * + * @method for_each_row_occupied + * @param {Object} el_grid_data The grid coords object that represents + * the widget. + * @param {Function} callback The function to execute on each column + * iteration. The row number is passed as first argument. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.for_each_row_occupied = function(el_grid_data, callback) { + for (var i = 0; i < el_grid_data.size_y; i++) { + var row = el_grid_data.row + i; + callback.call(this, row, el_grid_data); + } + }; + + + + fn._traversing_widgets = function(type, direction, col, row, callback) { + var ga = this.gridmap; + if (!ga[col]) { return; } + + var cr, max; + var action = type + '/' + direction; + if (arguments[2] instanceof jQuery) { + var el_grid_data = arguments[2].coords().grid; + col = el_grid_data.col; + row = el_grid_data.row; + callback = arguments[3]; + } + var matched = []; + var trow = row; + + + var methods = { + 'for_each/above': function() { + while (trow--) { + if (trow > 0 && this.is_widget(col, trow) && + $.inArray(ga[col][trow], matched) === -1 + ) { + cr = callback.call(ga[col][trow], col, trow); + matched.push(ga[col][trow]); + if (cr) { break; } + } + } + }, + 'for_each/below': function() { + for (trow = row + 1, max = ga[col].length; trow < max; trow++) { + if (this.is_widget(col, trow) && + $.inArray(ga[col][trow], matched) === -1 + ) { + cr = callback.call(ga[col][trow], col, trow); + matched.push(ga[col][trow]); + if (cr) { break; } + } + } + } + }; + + if (methods[action]) { + methods[action].call(this); + } + }; + + + /** + * Iterate over each widget above the column and row specified. + * + * @method for_each_widget_above + * @param {Number} col The column to start iterating. + * @param {Number} row The row to start iterating. + * @param {Function} callback The function to execute on each widget + * iteration. The value of `this` inside the function is the jQuery + * wrapped HTMLElement. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.for_each_widget_above = function(col, row, callback) { + this._traversing_widgets('for_each', 'above', col, row, callback); + return this; + }; + + + /** + * Iterate over each widget below the column and row specified. + * + * @method for_each_widget_below + * @param {Number} col The column to start iterating. + * @param {Number} row The row to start iterating. + * @param {Function} callback The function to execute on each widget + * iteration. The value of `this` inside the function is the jQuery wrapped + * HTMLElement. + * @return {Class} Returns the instance of the Gridster Class. + */ + fn.for_each_widget_below = function(col, row, callback) { + this._traversing_widgets('for_each', 'below', col, row, callback); + return this; + }; + + + /** + * Returns the highest occupied cell in the grid. + * + * @method get_highest_occupied_cell + * @return {Object} Returns an object with `col` and `row` numbers. + */ + fn.get_highest_occupied_cell = function() { + var r; + var gm = this.gridmap; + var rows = []; + var row_in_col = []; + for (var c = gm.length - 1; c >= 1; c--) { + for (r = gm[c].length - 1; r >= 1; r--) { + if (this.is_widget(c, r)) { + rows.push(r); + row_in_col[r] = c; + break; + } + } + } + + var highest_row = Math.max.apply(Math, rows); + + this.highest_occupied_cell = { + col: row_in_col[highest_row], + row: highest_row + }; + + return this.highest_occupied_cell; + }; + + + fn.get_widgets_from = function(col, row) { + var ga = this.gridmap; + var $widgets = $(); + + if (col) { + $widgets = $widgets.add( + this.$widgets.filter(function() { + var tcol = $(this).attr('data-col'); + return (tcol === col || tcol > col); + }) + ); + } + + if (row) { + $widgets = $widgets.add( + this.$widgets.filter(function() { + var trow = $(this).attr('data-row'); + return (trow === row || trow > row); + }) + ); + } + + return $widgets; + } + + + /** + * Set the current height of the parent grid. + * + * @method set_dom_grid_height + * @return {Object} Returns the instance of the Gridster class. + */ + fn.set_dom_grid_height = function() { + var r = this.get_highest_occupied_cell().row; + this.$el.css('height', r * this.min_widget_height); + return this; + }; + + + /** + * It generates the neccessary styles to position the widgets. + * + * @method generate_stylesheet + * @param {Number} rows Number of columns. + * @param {Number} cols Number of rows. + * @return {Object} Returns the instance of the Gridster class. + */ + fn.generate_stylesheet = function(opts) { + var styles = ''; + var extra_cells = 10; + var max_size_y = this.options.max_size_y; + var max_size_x = this.options.max_size_x; + var i; + var rules; + + opts || (opts = {}); + opts.cols || (opts.cols = this.cols); + opts.rows || (opts.rows = this.rows); + opts.namespace || (opts.namespace = ''); + opts.widget_base_dimensions || + (opts.widget_base_dimensions = this.options.widget_base_dimensions); + opts.widget_margins || + (opts.widget_margins = this.options.widget_margins); + opts.min_widget_width = (opts.widget_margins[0] * 2) + + opts.widget_base_dimensions[0]; + opts.min_widget_height = (opts.widget_margins[1] * 2) + + opts.widget_base_dimensions[1]; + + var serialized_opts = $.param(opts); + // don't duplicate stylesheets for the same configuration + if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) { + return false; + } + + Gridster.generated_stylesheets.push(serialized_opts); + + /* generate CSS styles for cols */ + for (i = opts.cols + extra_cells; i >= 0; i--) { + styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' + + ((i * opts.widget_base_dimensions[0]) + + (i * opts.widget_margins[0]) + + ((i + 1) * opts.widget_margins[0])) + 'px;} '); + } + + /* generate CSS styles for rows */ + for (i = opts.rows + extra_cells; i >= 0; i--) { + styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' + + ((i * opts.widget_base_dimensions[1]) + + (i * opts.widget_margins[1]) + + ((i + 1) * opts.widget_margins[1]) ) + 'px;} '); + } + + for (var y = 1; y <= max_size_y; y++) { + styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' + + (y * opts.widget_base_dimensions[1] + + (y - 1) * (opts.widget_margins[1] * 2)) + 'px;}'); + } + + for (var x = 1; x <= max_size_x; x++) { + styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' + + (x * opts.widget_base_dimensions[0] + + (x - 1) * (opts.widget_margins[0] * 2)) + 'px;}'); + } + + return this.add_style_tag(styles); + }; + + + /** + * Injects the given CSS as string to the head of the document. + * + * @method add_style_tag + * @param {String} css The styles to apply. + * @return {Object} Returns the instance of the Gridster class. + */ + fn.add_style_tag = function(css) { + var d = document; + var tag = d.createElement('style'); + + d.getElementsByTagName('head')[0].appendChild(tag); + tag.setAttribute('type', 'text/css'); + + if (tag.styleSheet) { + tag.styleSheet.cssText = css; + }else{ + tag.appendChild(document.createTextNode(css)); + } + return this; + }; + + + /** + * Generates a faux grid to collide with it when a widget is dragged and + * detect row or column that we want to go. + * + * @method generate_faux_grid + * @param {Number} rows Number of columns. + * @param {Number} cols Number of rows. + * @return {Object} Returns the instance of the Gridster class. + */ + fn.generate_faux_grid = function(rows, cols) { + this.faux_grid = []; + this.gridmap = []; + var col; + var row; + for (col = cols; col > 0; col--) { + this.gridmap[col] = []; + for (row = rows; row > 0; row--) { + var coords = $({ + left: this.baseX + ((col - 1) * this.min_widget_width), + top: this.baseY + (row -1) * this.min_widget_height, + width: this.min_widget_width, + height: this.min_widget_height, + col: col, + row: row, + original_col: col, + original_row: row + }).coords(); + + this.gridmap[col][row] = false; + this.faux_grid.push(coords); + } + } + return this; + }; + + + /** + * Recalculates the offsets for the faux grid. You need to use it when + * the browser is resized. + * + * @method recalculate_faux_grid + * @return {Object} Returns the instance of the Gridster class. + */ + fn.recalculate_faux_grid = function() { + var aw = this.$wrapper.width(); + this.baseX = ($(window).width() - aw) / 2; + this.baseY = this.$wrapper.offset().top; + + $.each(this.faux_grid, $.proxy(function(i, coords) { + this.faux_grid[i] = coords.update({ + left: this.baseX + (coords.data.col -1) * this.min_widget_width, + top: this.baseY + (coords.data.row -1) * this.min_widget_height + }); + + }, this)); + + return this; + }; + + + /** + * Get all widgets in the DOM and register them. + * + * @method get_widgets_from_DOM + * @return {Object} Returns the instance of the Gridster class. + */ + fn.get_widgets_from_DOM = function() { + this.$widgets.each($.proxy(function(i, widget) { + this.register_widget($(widget)); + }, this)); + return this; + }; + + + /** + * Calculate columns and rows to be set based on the configuration + * parameters, grid dimensions, etc ... + * + * @method generate_grid_and_stylesheet + * @return {Object} Returns the instance of the Gridster class. + */ + fn.generate_grid_and_stylesheet = function() { + var aw = this.$wrapper.width(); + var ah = this.$wrapper.height(); + + var cols = Math.floor(aw / this.min_widget_width) + + this.options.extra_cols; + var rows = Math.floor(ah / this.min_widget_height) + + this.options.extra_rows; + + var actual_cols = this.$widgets.map(function() { + return $(this).attr('data-col'); + }); + actual_cols = Array.prototype.slice.call(actual_cols, 0); + //needed to pass tests with phantomjs + actual_cols.length || (actual_cols = [0]); + + var actual_rows = this.$widgets.map(function() { + return $(this).attr('data-row'); + }); + actual_rows = Array.prototype.slice.call(actual_rows, 0); + //needed to pass tests with phantomjs + actual_rows.length || (actual_rows = [0]); + + var min_cols = Math.max.apply(Math, actual_cols); + var min_rows = Math.max.apply(Math, actual_rows); + + this.cols = Math.max(min_cols, cols, this.options.min_cols); + this.rows = Math.max(min_rows, rows, this.options.min_rows); + + this.baseX = ($(window).width() - aw) / 2; + this.baseY = this.$wrapper.offset().top; + + if (this.options.autogenerate_stylesheet) { + this.generate_stylesheet(); + } + + /* more faux rows that needed are created so that there are cells + * where drag beyond the limits */ + return this.generate_faux_grid(this.rows, this.cols); + }; + + + //jQuery adapter + $.fn.gridster = function(options) { + return this.each(function() { + if (!$(this).data('gridster')) { + $(this).data('gridster', new Gridster( this, options )); + } + }); + }; + + +}(jQuery, window, document)); \ No newline at end of file diff --git a/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js b/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js new file mode 100644 index 0000000..a5772dd --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js @@ -0,0 +1,5 @@ +// leanModal v1.1 by Ray Stone - http://finelysliced.com.au +// Dual licensed under the MIT and GPL + +(function($){$.fn.extend({leanModal:function(options){var defaults={top:100,overlay:0.5,closeButton:null};var overlay=$("
    ");$("body").append(overlay);options=$.extend(defaults,options);return this.each(function(){var o=options;$(this).click(function(e){var modal_id=$(this).attr("href");$("#lean_overlay").click(function(){close_modal(modal_id)});$(o.closeButton).click(function(){close_modal(modal_id)});var modal_height=$(modal_id).outerHeight();var modal_width=$(modal_id).outerWidth(); +$("#lean_overlay").css({"display":"block",opacity:0});$("#lean_overlay").fadeTo(200,o.overlay);$(modal_id).css({"display":"block","position":"fixed","opacity":0,"z-index":11000,"left":50+"%","margin-left":-(modal_width/2)+"px","top":o.top+"px"});$(modal_id).fadeTo(200,1);e.preventDefault()})});function close_modal(modal_id){$("#lean_overlay").fadeOut(200);$(modal_id).css({"display":"none"})}}})})(jQuery); diff --git a/templates/project/assets/javascripts/gridster/utils.js b/templates/project/assets/javascripts/gridster/utils.js new file mode 100755 index 0000000..5f340b3 --- /dev/null +++ b/templates/project/assets/javascripts/gridster/utils.js @@ -0,0 +1,41 @@ +;(function(window, undefined) { + /* Debounce and throttle functions taken from underscore.js */ + window.debounce = function(func, wait, immediate) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + if (immediate && !timeout) func.apply(context, args); + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + + window.throttle = function(func, wait) { + var context, args, timeout, throttling, more, result; + var whenDone = debounce( + function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + result = func.apply(context, args); + } + whenDone(); + throttling = true; + return result; + }; + }; + +})(window); diff --git a/templates/project/assets/javascripts/jquery.knob.js b/templates/project/assets/javascripts/jquery.knob.js new file mode 100644 index 0000000..3224638 --- /dev/null +++ b/templates/project/assets/javascripts/jquery.knob.js @@ -0,0 +1,646 @@ +/*!jQuery Knob*/ +/** + * Downward compatible, touchable dial + * + * Version: 1.2.0 (15/07/2012) + * Requires: jQuery v1.7+ + * + * Copyright (c) 2012 Anthony Terrien + * Under MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Thanks to vor, eskimoblood, spiffistan, FabrizioC + */ +$(function () { + + /** + * Kontrol library + */ + "use strict"; + + /** + * Definition of globals and core + */ + var k = {}, // kontrol + max = Math.max, + min = Math.min; + + k.c = {}; + k.c.d = $(document); + k.c.t = function (e) { + return e.originalEvent.touches.length - 1; + }; + + /** + * Kontrol Object + * + * Definition of an abstract UI control + * + * Each concrete component must call this one. + * + * k.o.call(this); + * + */ + k.o = function () { + var s = this; + + this.o = null; // array of options + this.$ = null; // jQuery wrapped element + this.i = null; // mixed HTMLInputElement or array of HTMLInputElement + this.g = null; // 2D graphics context for 'pre-rendering' + this.v = null; // value ; mixed array or integer + this.cv = null; // change value ; not commited value + this.x = 0; // canvas x position + this.y = 0; // canvas y position + this.$c = null; // jQuery canvas element + this.c = null; // rendered canvas context + this.t = 0; // touches index + this.isInit = false; + this.fgColor = null; // main color + this.pColor = null; // previous color + this.dH = null; // draw hook + this.cH = null; // change hook + this.eH = null; // cancel hook + this.rH = null; // release hook + + this.run = function () { + var cf = function (e, conf) { + var k; + for (k in conf) { + s.o[k] = conf[k]; + } + s.init(); + s._configure() + ._draw(); + }; + + if(this.$.data('kontroled')) return; + this.$.data('kontroled', true); + + this.extend(); + this.o = $.extend( + { + // Config + min : this.$.data('min') || 0, + max : this.$.data('max') || 100, + stopper : true, + readOnly : this.$.data('readonly'), + + // UI + cursor : (this.$.data('cursor') === true && 30) + || this.$.data('cursor') + || 0, + thickness : this.$.data('thickness') || 0.35, + width : this.$.data('width') || 200, + height : this.$.data('height') || 200, + displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'), + displayPrevious : this.$.data('displayprevious'), + fgColor : this.$.data('fgcolor') || '#87CEEB', + inline : false, + + // Hooks + draw : null, // function () {} + change : null, // function (value) {} + cancel : null, // function () {} + release : null // function (value) {} + }, this.o + ); + + // routing value + if(this.$.is('fieldset')) { + + // fieldset = array of integer + this.v = {}; + this.i = this.$.find('input') + this.i.each(function(k) { + var $this = $(this); + s.i[k] = $this; + s.v[k] = $this.val(); + + $this.bind( + 'change' + , function () { + var val = {}; + val[k] = $this.val(); + s.val(val); + } + ); + }); + this.$.find('legend').remove(); + + } else { + // input = integer + this.i = this.$; + this.v = this.$.val(); + (this.v == '') && (this.v = this.o.min); + + this.$.bind( + 'change' + , function () { + s.val(s.$.val()); + } + ); + } + + (!this.o.displayInput) && this.$.hide(); + + this.$c = $(''); + this.c = this.$c[0].getContext("2d"); + + this.$ + .wrap($('
    ')) + .before(this.$c); + + if (this.v instanceof Object) { + this.cv = {}; + this.copy(this.v, this.cv); + } else { + this.cv = this.v; + } + + this.$ + .bind("configure", cf) + .parent() + .bind("configure", cf); + + this._listen() + ._configure() + ._xy() + .init(); + + this.isInit = true; + + this._draw(); + + return this; + }; + + this._draw = function () { + + // canvas pre-rendering + var d = true, + c = document.createElement('canvas'); + + c.width = s.o.width; + c.height = s.o.height; + s.g = c.getContext('2d'); + + s.clear(); + + s.dH + && (d = s.dH()); + + (d !== false) && s.draw(); + + s.c.drawImage(c, 0, 0); + c = null; + }; + + this._touch = function (e) { + + var touchMove = function (e) { + + var v = s.xy2val( + e.originalEvent.touches[s.t].pageX, + e.originalEvent.touches[s.t].pageY + ); + + if (v == s.cv) return; + + if ( + s.cH + && (s.cH(v) === false) + ) return; + + + s.change(v); + s._draw(); + }; + + // get touches index + this.t = k.c.t(e); + + // First touch + touchMove(e); + + // Touch events listeners + k.c.d + .bind("touchmove.k", touchMove) + .bind( + "touchend.k" + , function () { + k.c.d.unbind('touchmove.k touchend.k'); + + if ( + s.rH + && (s.rH(s.cv) === false) + ) return; + + s.val(s.cv); + } + ); + + return this; + }; + + this._mouse = function (e) { + + var mouseMove = function (e) { + var v = s.xy2val(e.pageX, e.pageY); + if (v == s.cv) return; + + if ( + s.cH + && (s.cH(v) === false) + ) return; + + s.change(v); + s._draw(); + }; + + // First click + mouseMove(e); + + // Mouse events listeners + k.c.d + .bind("mousemove.k", mouseMove) + .bind( + // Escape key cancel current change + "keyup.k" + , function (e) { + if (e.keyCode === 27) { + k.c.d.unbind("mouseup.k mousemove.k keyup.k"); + + if ( + s.eH + && (s.eH() === false) + ) return; + + s.cancel(); + } + } + ) + .bind( + "mouseup.k" + , function (e) { + k.c.d.unbind('mousemove.k mouseup.k keyup.k'); + + if ( + s.rH + && (s.rH(s.cv) === false) + ) return; + + s.val(s.cv); + } + ); + + return this; + }; + + this._xy = function () { + var o = this.$c.offset(); + this.x = o.left; + this.y = o.top; + return this; + }; + + this._listen = function () { + + if (!this.o.readOnly) { + this.$c + .bind( + "mousedown" + , function (e) { + e.preventDefault(); + s._xy()._mouse(e); + } + ) + .bind( + "touchstart" + , function (e) { + e.preventDefault(); + s._xy()._touch(e); + } + ); + this.listen(); + } else { + this.$.attr('readonly', 'readonly'); + } + + return this; + }; + + this._configure = function () { + + // Hooks + if (this.o.draw) this.dH = this.o.draw; + if (this.o.change) this.cH = this.o.change; + if (this.o.cancel) this.eH = this.o.cancel; + if (this.o.release) this.rH = this.o.release; + + if (this.o.displayPrevious) { + this.pColor = this.h2rgba(this.o.fgColor, "0.4"); + this.fgColor = this.h2rgba(this.o.fgColor, "0.6"); + } else { + this.fgColor = this.o.fgColor; + } + + return this; + }; + + this._clear = function () { + this.$c[0].width = this.$c[0].width; + }; + + // Abstract methods + this.listen = function () {}; // on start, one time + this.extend = function () {}; // each time configure triggered + this.init = function () {}; // each time configure triggered + this.change = function (v) {}; // on change + this.val = function (v) {}; // on release + this.xy2val = function (x, y) {}; // + this.draw = function () {}; // on change / on release + this.clear = function () { this._clear(); }; + + // Utils + this.h2rgba = function (h, a) { + var rgb; + h = h.substring(1,7) + rgb = [parseInt(h.substring(0,2),16) + ,parseInt(h.substring(2,4),16) + ,parseInt(h.substring(4,6),16)]; + return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")"; + }; + + this.copy = function (f, t) { + for (var i in f) { t[i] = f[i]; } + }; + }; + + + /** + * k.Dial + */ + k.Dial = function () { + k.o.call(this); + + this.startAngle = null; + this.xy = null; + this.radius = null; + this.lineWidth = null; + this.cursorExt = null; + this.w2 = null; + this.PI2 = 2*Math.PI; + + this.extend = function () { + this.o = $.extend( + { + bgColor : this.$.data('bgcolor') || '#EEEEEE', + angleOffset : this.$.data('angleoffset') || 0, + angleArc : this.$.data('anglearc') || 360, + inline : true + }, this.o + ); + }; + + this.val = function (v) { + if (null != v) { + this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v; + this.v = this.cv; + this.$.val(this.v); + this._draw(); + } else { + return this.v; + } + }; + + this.xy2val = function (x, y) { + var a, ret; + + a = Math.atan2( + x - (this.x + this.w2) + , - (y - this.y - this.w2) + ) - this.angleOffset; + + if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) { + // if isset angleArc option, set to min if .5 under min + a = 0; + } else if (a < 0) { + a += this.PI2; + } + + ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc)) + + this.o.min; + + this.o.stopper + && (ret = max(min(ret, this.o.max), this.o.min)); + + return ret; + }; + + this.listen = function () { + // bind MouseWheel + var s = this, + mw = function (e) { + e.preventDefault(); + + var ori = e.originalEvent + ,deltaX = ori.detail || ori.wheelDeltaX + ,deltaY = ori.detail || ori.wheelDeltaY + ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0); + + if ( + s.cH + && (s.cH(v) === false) + ) return; + + s.val(v); + } + , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1}; + + this.$ + .bind( + "keydown" + ,function (e) { + var kc = e.keyCode; + kval = parseInt(String.fromCharCode(kc)); + + if (isNaN(kval)) { + + (kc !== 13) // enter + && (kc !== 8) // bs + && (kc !== 9) // tab + && (kc !== 189) // - + && e.preventDefault(); + + // arrows + if ($.inArray(kc,[37,38,39,40]) > -1) { + e.preventDefault(); + + var v = parseInt(s.$.val()) + kv[kc] * m; + + s.o.stopper + && (v = max(min(v, s.o.max), s.o.min)); + + s.change(v); + s._draw(); + + // long time keydown speed-up + to = window.setTimeout( + function () { m*=2; } + ,30 + ); + } + } + } + ) + .bind( + "keyup" + ,function (e) { + if (isNaN(kval)) { + if (to) { + window.clearTimeout(to); + to = null; + m = 1; + s.val(s.$.val()); + } + } else { + // kval postcond + (s.$.val() > s.o.max && s.$.val(s.o.max)) + || (s.$.val() < s.o.min && s.$.val(s.o.min)); + } + + } + ); + + this.$c.bind("mousewheel DOMMouseScroll", mw); + this.$.bind("mousewheel DOMMouseScroll", mw) + }; + + this.init = function () { + + if ( + this.v < this.o.min + || this.v > this.o.max + ) this.v = this.o.min; + + this.$.val(this.v); + this.w2 = this.o.width / 2; + this.cursorExt = this.o.cursor / 100; + this.xy = this.w2; + this.lineWidth = this.xy * this.o.thickness; + this.radius = this.xy - this.lineWidth / 2; + + this.o.angleOffset + && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset); + + this.o.angleArc + && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc); + + // deg to rad + this.angleOffset = this.o.angleOffset * Math.PI / 180; + this.angleArc = this.o.angleArc * Math.PI / 180; + + // compute start and end angles + this.startAngle = 1.5 * Math.PI + this.angleOffset; + this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc; + + var s = max( + String(Math.abs(this.o.max)).length + , String(Math.abs(this.o.min)).length + , 2 + ) + 2; + + this.o.displayInput + && this.i.css({ + 'width' : ((this.o.width / 2 + 4) >> 0) + 'px' + ,'height' : ((this.o.width / 3) >> 0) + 'px' + ,'position' : 'absolute' + ,'vertical-align' : 'middle' + ,'margin-top' : ((this.o.width / 3) >> 0) + 'px' + ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px' + ,'border' : 0 + ,'background' : 'none' + ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial' + ,'text-align' : 'center' + ,'color' : this.o.fgColor + ,'padding' : '0px' + ,'-webkit-appearance': 'none' + }) + || this.i.css({ + 'width' : '0px' + ,'visibility' : 'hidden' + }); + }; + + this.change = function (v) { + this.cv = v; + this.$.val(v); + }; + + this.angle = function (v) { + return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min); + }; + + this.draw = function () { + + var c = this.g, // context + a = this.angle(this.cv) // Angle + , sat = this.startAngle // Start angle + , eat = sat + a // End angle + , sa, ea // Previous angles + , r = 1; + + c.lineWidth = this.lineWidth; + + this.o.cursor + && (sat = eat - this.cursorExt) + && (eat = eat + this.cursorExt); + + c.beginPath(); + c.strokeStyle = this.o.bgColor; + c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true); + c.stroke(); + + if (this.o.displayPrevious) { + ea = this.startAngle + this.angle(this.v); + sa = this.startAngle; + this.o.cursor + && (sa = ea - this.cursorExt) + && (ea = ea + this.cursorExt); + + c.beginPath(); + c.strokeStyle = this.pColor; + c.arc(this.xy, this.xy, this.radius, sa, ea, false); + c.stroke(); + r = (this.cv == this.v); + } + + c.beginPath(); + c.strokeStyle = r ? this.o.fgColor : this.fgColor ; + c.arc(this.xy, this.xy, this.radius, sat, eat, false); + c.stroke(); + }; + + this.cancel = function () { + this.val(this.v); + }; + }; + + $.fn.dial = $.fn.knob = function (o) { + return this.each( + function () { + var d = new k.Dial(); + d.o = o; + d.$ = $(this); + d.run(); + } + ).parent(); + }; + +}); \ No newline at end of file diff --git a/templates/project/assets/stylesheets/application.scss b/templates/project/assets/stylesheets/application.scss new file mode 100644 index 0000000..c3b2a67 --- /dev/null +++ b/templates/project/assets/stylesheets/application.scss @@ -0,0 +1,227 @@ +/* + //=require_directory . + //=require_tree ../../widgets +*/ +// ---------------------------------------------------------------------------- +// Sass declarations +// ---------------------------------------------------------------------------- +$background-color: #222; +$text-color: #fff; + +$background-warning-color-1: #e82711; +$background-warning-color-2: #9b2d23; +$text-warning-color: #fff; + +$background-danger-color-1: #eeae32; +$background-danger-color-2: #ff9618; +$text-danger-color: #fff; + +@-webkit-keyframes status-warning-background { + 0% { background-color: $background-warning-color-1; } + 50% { background-color: $background-warning-color-2; } + 100% { background-color: $background-warning-color-1; } +} +@-webkit-keyframes status-danger-background { + 0% { background-color: $background-danger-color-1; } + 50% { background-color: $background-danger-color-2; } + 100% { background-color: $background-danger-color-1; } +} +@mixin animation($animation-name, $duration, $function, $animation-iteration-count:""){ + -webkit-animation: $animation-name $duration $function #{$animation-iteration-count}; + -moz-animation: $animation-name $duration $function #{$animation-iteration-count}; + -ms-animation: $animation-name $duration $function #{$animation-iteration-count}; +} + +// ---------------------------------------------------------------------------- +// Base styles +// ---------------------------------------------------------------------------- +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; + background-color: $background-color; + font-size: 20px; + color: $text-color; + font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +b, strong { + font-weight: bold; +} + +a { + text-decoration: none; + color: inherit; +} + +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; +} + +img, object { + max-width: 100%; +} + +iframe { + max-width: 100%; +} + +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; +} + +td { + vertical-align: middle; +} + +ul, ol { + padding: 0; + margin: 0; +} + +h1, h2, h3, h4, h5, p { + padding: 0; + margin: 0; +} +h1 { + margin-bottom: 12px; + text-align: center; + font-size: 30px; + font-weight: 300; +} +h2 { + text-transform: uppercase; + font-size: 80px; + font-weight: 700; + color: $text-color; +} +h3 { + font-size: 25px; + font-weight: 600; + color: $text-color; +} + +// ---------------------------------------------------------------------------- +// Base widget styles +// ---------------------------------------------------------------------------- +.gridster { + margin: 0px auto; +} + +.list-nostyle { + list-style: none; +} + +.gridster ul { + list-style: none; +} + +.gs_w { + width: 100%; + display: table; + cursor: pointer; +} + +.widget { + padding: 25px 12px; + text-align: center; + width: 100%; + display: table-cell; + vertical-align: middle; +} + +.widget.status-warning { + background-color: $background-warning-color-1; + @include animation(status-warning-background, 2s, ease, infinite); + + .icon-warning-sign { + display: inline-block; + } + + .title, .text-moreinfo { + color: $text-warning-color; + } +} + +.widget.status-danger { + color: $text-danger-color; + background-color: $background-danger-color-1; + @include animation(status-danger-background, 2s, ease, infinite); + + .icon-warning-sign { + display: inline-block; + } + + .title, .text-moreinfo { + color: $text-danger-color; + } +} + +.text-moreinfo { + margin-top: 12px; + font-size: 15px; +} + +#save-gridster { + display: none; + position: fixed; + top: 0; + margin: 0px auto; + left: 50%; + z-index: 1000; + background: black; + width: 190px; + text-align: center; + border: 1px solid white; + border-top: 0px; + margin-left: -95px; + padding: 15px; +} + +#save-gridster:hover { + padding-top: 25px; +} + +#saving-instructions { + display: none; + padding: 10px; + width: 500px; + height: 122px; + z-index: 1000; + background: white; + top: 100px; + color: black; + + textarea { + white-space: nowrap; + width: 494px; + height: 80px; + } +} + +#lean_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; + background: #000; + display: none; +} + + +// ---------------------------------------------------------------------------- +// Clearfix +// ---------------------------------------------------------------------------- +.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } +.clearfix:after { clear: both; } +.clearfix { zoom: 1; } \ No newline at end of file diff --git a/templates/project/assets/stylesheets/font-awesome.css b/templates/project/assets/stylesheets/font-awesome.css new file mode 100644 index 0000000..c642925 --- /dev/null +++ b/templates/project/assets/stylesheets/font-awesome.css @@ -0,0 +1,303 @@ +/* Font Awesome + the iconic font designed for use with Twitter Bootstrap + ------------------------------------------------------- + The full suite of pictographic icons, examples, and documentation + can be found at: http://fortawesome.github.com/Font-Awesome/ + + License + ------------------------------------------------------- + The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0: + http://creativecommons.org/licenses/by/3.0/ A mention of + 'Font Awesome - http://fortawesome.github.com/Font-Awesome' in human-readable + source code is considered acceptable attribution (most common on the web). + If human readable source code is not available to the end user, a mention in + an 'About' or 'Credits' screen is considered acceptable (most common in desktop + or mobile software). + + Contact + ------------------------------------------------------- + Email: dave@davegandy.com + Twitter: http://twitter.com/fortaweso_me + Work: http://lemonwi.se co-founder + + */ +@font-face { + font-family: "FontAwesome"; + src: url('/assets/fontawesome-webfont.eot'); + src: url('/assets/fontawesome-webfont.eot?#iefix') format('eot'), url('/assets/fontawesome-webfont.woff') format('woff'), url('/assets/fontawesome-webfont.ttf') format('truetype'), url('/assets/fontawesome-webfont.svg#FontAwesome') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* Font Awesome styles + ------------------------------------------------------- */ +[class^="icon-"]:before, [class*=" icon-"]:before { + font-family: FontAwesome; + font-weight: normal; + font-style: normal; + display: inline-block; + text-decoration: inherit; +} +a [class^="icon-"], a [class*=" icon-"] { + display: inline-block; + text-decoration: inherit; +} +/* makes the font 33% larger relative to the icon container */ +.icon-large:before { + vertical-align: top; + font-size: 1.3333333333333333em; +} +.btn [class^="icon-"], .btn [class*=" icon-"] { + /* keeps button heights with and without icons the same */ + + line-height: .9em; +} +li [class^="icon-"], li [class*=" icon-"] { + display: inline-block; + width: 1.25em; + text-align: center; +} +li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] { + /* 1.5 increased font size for icon-large * 1.25 width */ + + width: 1.875em; +} +li[class^="icon-"], li[class*=" icon-"] { + margin-left: 0; + list-style-type: none; +} +li[class^="icon-"]:before, li[class*=" icon-"]:before { + text-indent: -2em; + text-align: center; +} +li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before { + text-indent: -1.3333333333333333em; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.icon-glass:before { content: "\f000"; } +.icon-music:before { content: "\f001"; } +.icon-search:before { content: "\f002"; } +.icon-envelope:before { content: "\f003"; } +.icon-heart:before { content: "\f004"; } +.icon-star:before { content: "\f005"; } +.icon-star-empty:before { content: "\f006"; } +.icon-user:before { content: "\f007"; } +.icon-film:before { content: "\f008"; } +.icon-th-large:before { content: "\f009"; } +.icon-th:before { content: "\f00a"; } +.icon-th-list:before { content: "\f00b"; } +.icon-ok:before { content: "\f00c"; } +.icon-remove:before { content: "\f00d"; } +.icon-zoom-in:before { content: "\f00e"; } + +.icon-zoom-out:before { content: "\f010"; } +.icon-off:before { content: "\f011"; } +.icon-signal:before { content: "\f012"; } +.icon-cog:before { content: "\f013"; } +.icon-trash:before { content: "\f014"; } +.icon-home:before { content: "\f015"; } +.icon-file:before { content: "\f016"; } +.icon-time:before { content: "\f017"; } +.icon-road:before { content: "\f018"; } +.icon-download-alt:before { content: "\f019"; } +.icon-download:before { content: "\f01a"; } +.icon-upload:before { content: "\f01b"; } +.icon-inbox:before { content: "\f01c"; } +.icon-play-circle:before { content: "\f01d"; } +.icon-repeat:before { content: "\f01e"; } + +/* \f020 doesn't work in Safari. all shifted one down */ +.icon-refresh:before { content: "\f021"; } +.icon-list-alt:before { content: "\f022"; } +.icon-lock:before { content: "\f023"; } +.icon-flag:before { content: "\f024"; } +.icon-headphones:before { content: "\f025"; } +.icon-volume-off:before { content: "\f026"; } +.icon-volume-down:before { content: "\f027"; } +.icon-volume-up:before { content: "\f028"; } +.icon-qrcode:before { content: "\f029"; } +.icon-barcode:before { content: "\f02a"; } +.icon-tag:before { content: "\f02b"; } +.icon-tags:before { content: "\f02c"; } +.icon-book:before { content: "\f02d"; } +.icon-bookmark:before { content: "\f02e"; } +.icon-print:before { content: "\f02f"; } + +.icon-camera:before { content: "\f030"; } +.icon-font:before { content: "\f031"; } +.icon-bold:before { content: "\f032"; } +.icon-italic:before { content: "\f033"; } +.icon-text-height:before { content: "\f034"; } +.icon-text-width:before { content: "\f035"; } +.icon-align-left:before { content: "\f036"; } +.icon-align-center:before { content: "\f037"; } +.icon-align-right:before { content: "\f038"; } +.icon-align-justify:before { content: "\f039"; } +.icon-list:before { content: "\f03a"; } +.icon-indent-left:before { content: "\f03b"; } +.icon-indent-right:before { content: "\f03c"; } +.icon-facetime-video:before { content: "\f03d"; } +.icon-picture:before { content: "\f03e"; } + +.icon-pencil:before { content: "\f040"; } +.icon-map-marker:before { content: "\f041"; } +.icon-adjust:before { content: "\f042"; } +.icon-tint:before { content: "\f043"; } +.icon-edit:before { content: "\f044"; } +.icon-share:before { content: "\f045"; } +.icon-check:before { content: "\f046"; } +.icon-move:before { content: "\f047"; } +.icon-step-backward:before { content: "\f048"; } +.icon-fast-backward:before { content: "\f049"; } +.icon-backward:before { content: "\f04a"; } +.icon-play:before { content: "\f04b"; } +.icon-pause:before { content: "\f04c"; } +.icon-stop:before { content: "\f04d"; } +.icon-forward:before { content: "\f04e"; } + +.icon-fast-forward:before { content: "\f050"; } +.icon-step-forward:before { content: "\f051"; } +.icon-eject:before { content: "\f052"; } +.icon-chevron-left:before { content: "\f053"; } +.icon-chevron-right:before { content: "\f054"; } +.icon-plus-sign:before { content: "\f055"; } +.icon-minus-sign:before { content: "\f056"; } +.icon-remove-sign:before { content: "\f057"; } +.icon-ok-sign:before { content: "\f058"; } +.icon-question-sign:before { content: "\f059"; } +.icon-info-sign:before { content: "\f05a"; } +.icon-screenshot:before { content: "\f05b"; } +.icon-remove-circle:before { content: "\f05c"; } +.icon-ok-circle:before { content: "\f05d"; } +.icon-ban-circle:before { content: "\f05e"; } + +.icon-arrow-left:before { content: "\f060"; } +.icon-arrow-right:before { content: "\f061"; } +.icon-arrow-up:before { content: "\f062"; } +.icon-arrow-down:before { content: "\f063"; } +.icon-share-alt:before { content: "\f064"; } +.icon-resize-full:before { content: "\f065"; } +.icon-resize-small:before { content: "\f066"; } +.icon-plus:before { content: "\f067"; } +.icon-minus:before { content: "\f068"; } +.icon-asterisk:before { content: "\f069"; } +.icon-exclamation-sign:before { content: "\f06a"; } +.icon-gift:before { content: "\f06b"; } +.icon-leaf:before { content: "\f06c"; } +.icon-fire:before { content: "\f06d"; } +.icon-eye-open:before { content: "\f06e"; } + +.icon-eye-close:before { content: "\f070"; } +.icon-warning-sign:before { content: "\f071"; } +.icon-plane:before { content: "\f072"; } +.icon-calendar:before { content: "\f073"; } +.icon-random:before { content: "\f074"; } +.icon-comment:before { content: "\f075"; } +.icon-magnet:before { content: "\f076"; } +.icon-chevron-up:before { content: "\f077"; } +.icon-chevron-down:before { content: "\f078"; } +.icon-retweet:before { content: "\f079"; } +.icon-shopping-cart:before { content: "\f07a"; } +.icon-folder-close:before { content: "\f07b"; } +.icon-folder-open:before { content: "\f07c"; } +.icon-resize-vertical:before { content: "\f07d"; } +.icon-resize-horizontal:before { content: "\f07e"; } + +.icon-bar-chart:before { content: "\f080"; } +.icon-twitter-sign:before { content: "\f081"; } +.icon-facebook-sign:before { content: "\f082"; } +.icon-camera-retro:before { content: "\f083"; } +.icon-key:before { content: "\f084"; } +.icon-cogs:before { content: "\f085"; } +.icon-comments:before { content: "\f086"; } +.icon-thumbs-up:before { content: "\f087"; } +.icon-thumbs-down:before { content: "\f088"; } +.icon-star-half:before { content: "\f089"; } +.icon-heart-empty:before { content: "\f08a"; } +.icon-signout:before { content: "\f08b"; } +.icon-linkedin-sign:before { content: "\f08c"; } +.icon-pushpin:before { content: "\f08d"; } +.icon-external-link:before { content: "\f08e"; } + +.icon-signin:before { content: "\f090"; } +.icon-trophy:before { content: "\f091"; } +.icon-github-sign:before { content: "\f092"; } +.icon-upload-alt:before { content: "\f093"; } +.icon-lemon:before { content: "\f094"; } +.icon-phone:before { content: "\f095"; } +.icon-check-empty:before { content: "\f096"; } +.icon-bookmark-empty:before { content: "\f097"; } +.icon-phone-sign:before { content: "\f098"; } +.icon-twitter:before { content: "\f099"; } +.icon-facebook:before { content: "\f09a"; } +.icon-github:before { content: "\f09b"; } +.icon-unlock:before { content: "\f09c"; } +.icon-credit-card:before { content: "\f09d"; } +.icon-rss:before { content: "\f09e"; } + +.icon-hdd:before { content: "\f0a0"; } +.icon-bullhorn:before { content: "\f0a1"; } +.icon-bell:before { content: "\f0a2"; } +.icon-certificate:before { content: "\f0a3"; } +.icon-hand-right:before { content: "\f0a4"; } +.icon-hand-left:before { content: "\f0a5"; } +.icon-hand-up:before { content: "\f0a6"; } +.icon-hand-down:before { content: "\f0a7"; } +.icon-circle-arrow-left:before { content: "\f0a8"; } +.icon-circle-arrow-right:before { content: "\f0a9"; } +.icon-circle-arrow-up:before { content: "\f0aa"; } +.icon-circle-arrow-down:before { content: "\f0ab"; } +.icon-globe:before { content: "\f0ac"; } +.icon-wrench:before { content: "\f0ad"; } +.icon-tasks:before { content: "\f0ae"; } + +.icon-filter:before { content: "\f0b0"; } +.icon-briefcase:before { content: "\f0b1"; } +.icon-fullscreen:before { content: "\f0b2"; } + +.icon-group:before { content: "\f0c0"; } +.icon-link:before { content: "\f0c1"; } +.icon-cloud:before { content: "\f0c2"; } +.icon-beaker:before { content: "\f0c3"; } +.icon-cut:before { content: "\f0c4"; } +.icon-copy:before { content: "\f0c5"; } +.icon-paper-clip:before { content: "\f0c6"; } +.icon-save:before { content: "\f0c7"; } +.icon-sign-blank:before { content: "\f0c8"; } +.icon-reorder:before { content: "\f0c9"; } +.icon-list-ul:before { content: "\f0ca"; } +.icon-list-ol:before { content: "\f0cb"; } +.icon-strikethrough:before { content: "\f0cc"; } +.icon-underline:before { content: "\f0cd"; } +.icon-table:before { content: "\f0ce"; } + +.icon-magic:before { content: "\f0d0"; } +.icon-truck:before { content: "\f0d1"; } +.icon-pinterest:before { content: "\f0d2"; } +.icon-pinterest-sign:before { content: "\f0d3"; } +.icon-google-plus-sign:before { content: "\f0d4"; } +.icon-google-plus:before { content: "\f0d5"; } +.icon-money:before { content: "\f0d6"; } +.icon-caret-down:before { content: "\f0d7"; } +.icon-caret-up:before { content: "\f0d8"; } +.icon-caret-left:before { content: "\f0d9"; } +.icon-caret-right:before { content: "\f0da"; } +.icon-columns:before { content: "\f0db"; } +.icon-sort:before { content: "\f0dc"; } +.icon-sort-down:before { content: "\f0dd"; } +.icon-sort-up:before { content: "\f0de"; } + +.icon-envelope-alt:before { content: "\f0e0"; } +.icon-linkedin:before { content: "\f0e1"; } +.icon-undo:before { content: "\f0e2"; } +.icon-legal:before { content: "\f0e3"; } +.icon-dashboard:before { content: "\f0e4"; } +.icon-comment-alt:before { content: "\f0e5"; } +.icon-comments-alt:before { content: "\f0e6"; } +.icon-bolt:before { content: "\f0e7"; } +.icon-sitemap:before { content: "\f0e8"; } +.icon-umbrella:before { content: "\f0e9"; } +.icon-paste:before { content: "\f0ea"; } + +.icon-user-md:before { content: "\f200"; } diff --git a/templates/project/assets/stylesheets/jquery.gridster.css b/templates/project/assets/stylesheets/jquery.gridster.css new file mode 100755 index 0000000..d512484 --- /dev/null +++ b/templates/project/assets/stylesheets/jquery.gridster.css @@ -0,0 +1,57 @@ +/*! gridster.js - v0.1.0 - 2012-08-14 +* http://gridster.net/ +* Copyright (c) 2012 ducksboard; Licensed MIT */ + +.gridster { + position:relative; +} + +.gridster > * { + margin: 0 auto; + -webkit-transition: height .4s; + -moz-transition: height .4s; + -o-transition: height .4s; + -ms-transition: height .4s; + transition: height .4s; +} + +.gridster .gs_w{ + z-index: 2; + position: absolute; +} + +.ready .gs_w:not(.preview-holder) { + -webkit-transition: opacity .3s, left .3s, top .3s; + -moz-transition: opacity .3s, left .3s, top .3s; + -o-transition: opacity .3s, left .3s, top .3s; + transition: opacity .3s, left .3s, top .3s; +} + +.gridster .preview-holder { + z-index: 1; + position: absolute; + background-color: #fff; + border-color: #fff; + opacity: 0.3; +} + +.gridster .player-revert { + z-index: 10!important; + -webkit-transition: left .3s, top .3s!important; + -moz-transition: left .3s, top .3s!important; + -o-transition: left .3s, top .3s!important; + transition: left .3s, top .3s!important; +} + +.gridster .dragging { + z-index: 10!important; + -webkit-transition: all 0s !important; + -moz-transition: all 0s !important; + -o-transition: all 0s !important; + transition: all 0s !important; +} + +/* Uncomment this if you set helper : "clone" in draggable options */ +/*.gridster .player { + opacity:0; +}*/ \ No newline at end of file diff --git a/templates/project/config.ru b/templates/project/config.ru index a3a74de..6e1076a 100644 --- a/templates/project/config.ru +++ b/templates/project/config.ru @@ -2,6 +2,17 @@ require 'dashing' configure do set :auth_token, 'YOUR_AUTH_TOKEN' + + helpers do + def protected! + # Put any authentication code you want in here. + # This method is run before accessing any resource. + end + end +end + +map Sinatra::Application.assets_prefix do + run Sinatra::Application.sprockets end run Sinatra::Application \ No newline at end of file diff --git a/templates/project/dashboards/layout.erb b/templates/project/dashboards/layout.erb index 97cb96d..23d3c9a 100644 --- a/templates/project/dashboards/layout.erb +++ b/templates/project/dashboards/layout.erb @@ -8,34 +8,25 @@ <%= yield_content(:title) %> - - - + + + - - - + - - - -
    - <%= yield %> -
    - - + +
    + <%= yield %> +
    + + <% if development? %> +
    +

    Paste the following at the top of <%= params[:dashboard] %>.erb

    + +
    + Save this layout + <% end %> + \ No newline at end of file diff --git a/templates/project/public/.empty_directory b/templates/project/public/.empty_directory new file mode 100644 index 0000000..3da7f49 --- /dev/null +++ b/templates/project/public/.empty_directory @@ -0,0 +1 @@ +.empty_directory \ No newline at end of file diff --git a/templates/project/public/fonts/fontawesome-webfont.eot b/templates/project/public/fonts/fontawesome-webfont.eot deleted file mode 100755 index 89070c1..0000000 Binary files a/templates/project/public/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/templates/project/public/fonts/fontawesome-webfont.svg b/templates/project/public/fonts/fontawesome-webfont.svg deleted file mode 100755 index 1245f92..0000000 --- a/templates/project/public/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/templates/project/public/fonts/fontawesome-webfont.ttf b/templates/project/public/fonts/fontawesome-webfont.ttf deleted file mode 100755 index c17e9f8..0000000 Binary files a/templates/project/public/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/templates/project/public/fonts/fontawesome-webfont.woff b/templates/project/public/fonts/fontawesome-webfont.woff deleted file mode 100755 index 09f2469..0000000 Binary files a/templates/project/public/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/templates/project/public/images/.empty_directory b/templates/project/public/images/.empty_directory deleted file mode 100644 index 3da7f49..0000000 --- a/templates/project/public/images/.empty_directory +++ /dev/null @@ -1 +0,0 @@ -.empty_directory \ No newline at end of file diff --git a/templates/project/public/images/favicon.ico b/templates/project/public/images/favicon.ico deleted file mode 100644 index 29a408f..0000000 Binary files a/templates/project/public/images/favicon.ico and /dev/null differ diff --git a/templates/project/public/javascripts/.empty_directory b/templates/project/public/javascripts/.empty_directory deleted file mode 100644 index 3da7f49..0000000 --- a/templates/project/public/javascripts/.empty_directory +++ /dev/null @@ -1 +0,0 @@ -.empty_directory \ No newline at end of file diff --git a/templates/project/public/javascripts/jquery.knob.js b/templates/project/public/javascripts/jquery.knob.js deleted file mode 100644 index 0c5b8f1..0000000 --- a/templates/project/public/javascripts/jquery.knob.js +++ /dev/null @@ -1,28 +0,0 @@ -/*!jQuery Knob*/ -/** - * Downward compatible, touchable dial - * - * Version: 1.2.0 (15/07/2012) - * Requires: jQuery v1.7+ - * - * Copyright (c) 2012 Anthony Terrien - * Under MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Thanks to vor, eskimoblood, spiffistan, FabrizioC - */ -$(function(){"use strict";var k={},max=Math.max,min=Math.min;k.c={};k.c.d=$(document);k.c.t=function(e){return e.originalEvent.touches.length-1;};k.o=function(){var s=this;this.o=null;this.$=null;this.i=null;this.g=null;this.v=null;this.cv=null;this.x=0;this.y=0;this.$c=null;this.c=null;this.t=0;this.isInit=false;this.fgColor=null;this.pColor=null;this.dH=null;this.cH=null;this.eH=null;this.rH=null;this.run=function(){var cf=function(e,conf){var k;for(k in conf){s.o[k]=conf[k];} -s.init();s._configure()._draw();};if(this.$.data('kontroled'))return;this.$.data('kontroled',true);this.extend();this.o=$.extend({min:this.$.data('min')||0,max:this.$.data('max')||100,stopper:true,readOnly:this.$.data('readonly'),cursor:(this.$.data('cursor')===true&&30)||this.$.data('cursor')||0,thickness:this.$.data('thickness')||0.35,width:this.$.data('width')||200,height:this.$.data('height')||200,displayInput:this.$.data('displayinput')==null||this.$.data('displayinput'),displayPrevious:this.$.data('displayprevious'),fgColor:this.$.data('fgcolor')||'#87CEEB',inline:false,draw:null,change:null,cancel:null,release:null},this.o);if(this.$.is('fieldset')){this.v={};this.i=this.$.find('input') -this.i.each(function(k){var $this=$(this);s.i[k]=$this;s.v[k]=$this.val();$this.bind('change',function(){var val={};val[k]=$this.val();s.val(val);});});this.$.find('legend').remove();}else{this.i=this.$;this.v=this.$.val();(this.v=='')&&(this.v=this.o.min);this.$.bind('change',function(){s.val(s.$.val());});} -(!this.o.displayInput)&&this.$.hide();this.$c=$('');this.c=this.$c[0].getContext("2d");this.$.wrap($('
    ')).before(this.$c);if(this.v instanceof Object){this.cv={};this.copy(this.v,this.cv);}else{this.cv=this.v;} -this.$.bind("configure",cf).parent().bind("configure",cf);this._listen()._configure()._xy().init();this.isInit=true;this._draw();return this;};this._draw=function(){var d=true,c=document.createElement('canvas');c.width=s.o.width;c.height=s.o.height;s.g=c.getContext('2d');s.clear();s.dH&&(d=s.dH());(d!==false)&&s.draw();s.c.drawImage(c,0,0);c=null;};this._touch=function(e){var touchMove=function(e){var v=s.xy2val(e.originalEvent.touches[s.t].pageX,e.originalEvent.touches[s.t].pageY);if(v==s.cv)return;if(s.cH&&(s.cH(v)===false))return;s.change(v);s._draw();};this.t=k.c.t(e);touchMove(e);k.c.d.bind("touchmove.k",touchMove).bind("touchend.k",function(){k.c.d.unbind('touchmove.k touchend.k');if(s.rH&&(s.rH(s.cv)===false))return;s.val(s.cv);});return this;};this._mouse=function(e){var mouseMove=function(e){var v=s.xy2val(e.pageX,e.pageY);if(v==s.cv)return;if(s.cH&&(s.cH(v)===false))return;s.change(v);s._draw();};mouseMove(e);k.c.d.bind("mousemove.k",mouseMove).bind("keyup.k",function(e){if(e.keyCode===27){k.c.d.unbind("mouseup.k mousemove.k keyup.k");if(s.eH&&(s.eH()===false))return;s.cancel();}}).bind("mouseup.k",function(e){k.c.d.unbind('mousemove.k mouseup.k keyup.k');if(s.rH&&(s.rH(s.cv)===false))return;s.val(s.cv);});return this;};this._xy=function(){var o=this.$c.offset();this.x=o.left;this.y=o.top;return this;};this._listen=function(){if(!this.o.readOnly){this.$c.bind("mousedown",function(e){e.preventDefault();s._xy()._mouse(e);}).bind("touchstart",function(e){e.preventDefault();s._xy()._touch(e);});this.listen();}else{this.$.attr('readonly','readonly');} -return this;};this._configure=function(){if(this.o.draw)this.dH=this.o.draw;if(this.o.change)this.cH=this.o.change;if(this.o.cancel)this.eH=this.o.cancel;if(this.o.release)this.rH=this.o.release;if(this.o.displayPrevious){this.pColor=this.h2rgba(this.o.fgColor,"0.4");this.fgColor=this.h2rgba(this.o.fgColor,"0.6");}else{this.fgColor=this.o.fgColor;} -return this;};this._clear=function(){this.$c[0].width=this.$c[0].width;};this.listen=function(){};this.extend=function(){};this.init=function(){};this.change=function(v){};this.val=function(v){};this.xy2val=function(x,y){};this.draw=function(){};this.clear=function(){this._clear();};this.h2rgba=function(h,a){var rgb;h=h.substring(1,7) -rgb=[parseInt(h.substring(0,2),16),parseInt(h.substring(2,4),16),parseInt(h.substring(4,6),16)];return"rgba("+rgb[0]+","+rgb[1]+","+rgb[2]+","+a+")";};this.copy=function(f,t){for(var i in f){t[i]=f[i];}};};k.Dial=function(){k.o.call(this);this.startAngle=null;this.xy=null;this.radius=null;this.lineWidth=null;this.cursorExt=null;this.w2=null;this.PI2=2*Math.PI;this.extend=function(){this.o=$.extend({bgColor:this.$.data('bgcolor')||'#EEEEEE',angleOffset:this.$.data('angleoffset')||0,angleArc:this.$.data('anglearc')||360,inline:true},this.o);};this.val=function(v){if(null!=v){this.cv=this.o.stopper?max(min(v,this.o.max),this.o.min):v;this.v=this.cv;this.$.val(this.v);this._draw();}else{return this.v;}};this.xy2val=function(x,y){var a,ret;a=Math.atan2(x-(this.x+this.w2),-(y-this.y-this.w2))-this.angleOffset;if(this.angleArc!=this.PI2&&(a<0)&&(a>-0.5)){a=0;}else if(a<0){a+=this.PI2;} -ret=~~(0.5+(a*(this.o.max-this.o.min)/this.angleArc)) -+this.o.min;this.o.stopper&&(ret=max(min(ret,this.o.max),this.o.min));return ret;};this.listen=function(){var s=this,mw=function(e){e.preventDefault();var ori=e.originalEvent,deltaX=ori.detail||ori.wheelDeltaX,deltaY=ori.detail||ori.wheelDeltaY,v=parseInt(s.$.val())+(deltaX>0||deltaY>0?1:deltaX<0||deltaY<0?-1:0);if(s.cH&&(s.cH(v)===false))return;s.val(v);},kval,to,m=1,kv={37:-1,38:1,39:1,40:-1};this.$.bind("keydown",function(e){var kc=e.keyCode;kval=parseInt(String.fromCharCode(kc));if(isNaN(kval)){(kc!==13)&&(kc!==8)&&(kc!==9)&&(kc!==189)&&e.preventDefault();if($.inArray(kc,[37,38,39,40])>-1){e.preventDefault();var v=parseInt(s.$.val())+kv[kc]*m;s.o.stopper&&(v=max(min(v,s.o.max),s.o.min));s.change(v);s._draw();to=window.setTimeout(function(){m*=2;},30);}}}).bind("keyup",function(e){if(isNaN(kval)){if(to){window.clearTimeout(to);to=null;m=1;s.val(s.$.val());}}else{(s.$.val()>s.o.max&&s.$.val(s.o.max))||(s.$.val()this.o.max)this.v=this.o.min;this.$.val(this.v);this.w2=this.o.width/2;this.cursorExt=this.o.cursor/100;this.xy=this.w2;this.lineWidth=this.xy*this.o.thickness;this.radius=this.xy-this.lineWidth/2;this.o.angleOffset&&(this.o.angleOffset=isNaN(this.o.angleOffset)?0:this.o.angleOffset);this.o.angleArc&&(this.o.angleArc=isNaN(this.o.angleArc)?this.PI2:this.o.angleArc);this.angleOffset=this.o.angleOffset*Math.PI/180;this.angleArc=this.o.angleArc*Math.PI/180;this.startAngle=1.5*Math.PI+this.angleOffset;this.endAngle=1.5*Math.PI+this.angleOffset+this.angleArc;var s=max(String(Math.abs(this.o.max)).length,String(Math.abs(this.o.min)).length,2)+2;this.o.displayInput&&this.i.css({'width':((this.o.width/2+4)>>0)+'px','height':((this.o.width/3)>>0)+'px','position':'absolute','vertical-align':'middle','margin-top':((this.o.width/3)>>0)+'px','margin-left':'-'+((this.o.width*3/4+2)>>0)+'px','border':0,'background':'none','font':'bold '+((this.o.width/s)>>0)+'px Arial','text-align':'center','color':this.o.fgColor,'padding':'0px','-webkit-appearance':'none'})||this.i.css({'width':'0px','visibility':'hidden'});};this.change=function(v){this.cv=v;this.$.val(v);};this.angle=function(v){return(v-this.o.min)*this.angleArc/(this.o.max-this.o.min);};this.draw=function(){var c=this.g,a=this.angle(this.cv),sat=this.startAngle,eat=sat+a,sa,ea,r=1;c.lineWidth=this.lineWidth;this.o.cursor&&(sat=eat-this.cursorExt)&&(eat=eat+this.cursorExt);c.beginPath();c.strokeStyle=this.o.bgColor;c.arc(this.xy,this.xy,this.radius,this.endAngle,this.startAngle,true);c.stroke();if(this.o.displayPrevious){ea=this.startAngle+this.angle(this.v);sa=this.startAngle;this.o.cursor&&(sa=ea-this.cursorExt)&&(ea=ea+this.cursorExt);c.beginPath();c.strokeStyle=this.pColor;c.arc(this.xy,this.xy,this.radius,sa,ea,false);c.stroke();r=(this.cv==this.v);} -c.beginPath();c.strokeStyle=r?this.o.fgColor:this.fgColor;c.arc(this.xy,this.xy,this.radius,sat,eat,false);c.stroke();};this.cancel=function(){this.val(this.v);};};$.fn.dial=$.fn.knob=function(o){return this.each(function(){var d=new k.Dial();d.o=o;d.$=$(this);d.run();}).parent();};}); \ No newline at end of file diff --git a/templates/project/public/javascripts/jquery.masonry.min.js b/templates/project/public/javascripts/jquery.masonry.min.js deleted file mode 100644 index 67be988..0000000 --- a/templates/project/public/javascripts/jquery.masonry.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * jQuery Masonry v2.1.05 - * A dynamic layout plugin for jQuery - * The flip-side of CSS Floats - * http://masonry.desandro.com - * - * Licensed under the MIT license. - * Copyright 2012 David DeSandro - */ -(function(a,b,c){"use strict";var d=b.event,e;d.special.smartresize={setup:function(){b(this).bind("resize",d.special.smartresize.handler)},teardown:function(){b(this).unbind("resize",d.special.smartresize.handler)},handler:function(a,c){var d=this,f=arguments;a.type="smartresize",e&&clearTimeout(e),e=setTimeout(function(){b.event.handle.apply(d,f)},c==="execAsap"?0:100)}},b.fn.smartresize=function(a){return a?this.bind("smartresize",a):this.trigger("smartresize",["execAsap"])},b.Mason=function(a,c){this.element=b(c),this._create(a),this._init()},b.Mason.settings={isResizable:!0,isAnimated:!1,animationOptions:{queue:!1,duration:500},gutterWidth:0,isRTL:!1,isFitWidth:!1,containerStyle:{position:"relative"}},b.Mason.prototype={_filterFindBricks:function(a){var b=this.options.itemSelector;return b?a.filter(b).add(a.find(b)):a},_getBricks:function(a){var b=this._filterFindBricks(a).css({position:"absolute"}).addClass("masonry-brick");return b},_create:function(c){this.options=b.extend(!0,{},b.Mason.settings,c),this.styleQueue=[];var d=this.element[0].style;this.originalStyle={height:d.height||""};var e=this.options.containerStyle;for(var f in e)this.originalStyle[f]=d[f]||"";this.element.css(e),this.horizontalDirection=this.options.isRTL?"right":"left",this.offset={x:parseInt(this.element.css("padding-"+this.horizontalDirection),10),y:parseInt(this.element.css("padding-top"),10)},this.isFluid=this.options.columnWidth&&typeof this.options.columnWidth=="function";var g=this;setTimeout(function(){g.element.addClass("masonry")},0),this.options.isResizable&&b(a).bind("smartresize.masonry",function(){g.resize()}),this.reloadItems()},_init:function(a){this._getColumns(),this._reLayout(a)},option:function(a,c){b.isPlainObject(a)&&(this.options=b.extend(!0,this.options,a))},layout:function(a,b){for(var c=0,d=a.length;c - num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") unless isNaN(num) - -Batman.Filters.dashize = (str) -> - dashes_rx1 = /([A-Z]+)([A-Z][a-z])/g; - dashes_rx2 = /([a-z\d])([A-Z])/g; - - return str.replace(dashes_rx1, '$1_$2').replace(dashes_rx2, '$1_$2').replace('_', '-').toLowerCase() - -Batman.Filters.shortenedNumber = (num) -> - return if isNaN(num) - if num >= 1000000000 - (num / 1000000000).toFixed(1) + 'B' - else if num >= 1000000 - (num / 1000000).toFixed(1) + 'M' - else if num >= 1000 - (num / 1000).toFixed(1) + 'K' - else - num - -class window.Dashing extends Batman.App - @root -> - -Dashing.AnimatedValue = - get: Batman.Property.defaultAccessor.get - set: (k, to) -> - if isNaN(to) - @[k] = to - else - timer = "interval_#{k}" - num = if !isNaN(@[k]) then @[k] else 0 - unless @[timer] || num == to - up = to > num - num_interval = Math.abs(num - to) / 90 - @[timer] = - setInterval => - num = if up then Math.ceil(num+num_interval) else Math.floor(num-num_interval) - if (up && num > to) || (!up && num < to) - num = to - clearInterval(@[timer]) - @[timer] = null - delete @[timer] - @[k] = num - @set k, to - @[k] = num - -Dashing.widgets = widgets = {} -Dashing.lastEvents = lastEvents = {} - -source = new EventSource('/events') -source.addEventListener 'open', (e) -> - console.log("Connection opened") - -source.addEventListener 'error', (e)-> - console.log("Connection error") - if (e.readyState == EventSource.CLOSED) - console.log("Connection closed") - -source.addEventListener 'message', (e) => - data = JSON.parse(e.data) - lastEvents[data.id] = data - if widgets[data.id]?.length > 0 - for widget in widgets[data.id] - widget.onData(data) - - -$(document).ready -> - Dashing.run() \ No newline at end of file diff --git a/vendor/javascripts/batman.jquery.js b/vendor/javascripts/batman.jquery.js deleted file mode 100644 index 6407098..0000000 --- a/vendor/javascripts/batman.jquery.js +++ /dev/null @@ -1,109 +0,0 @@ -(function() { - - Batman.Request.prototype._parseResponseHeaders = function(xhr) { - var headers; - return headers = xhr.getAllResponseHeaders().split('\n').reduce(function(acc, header) { - var key, matches, value; - if (matches = header.match(/([^:]*):\s*(.*)/)) { - key = matches[1]; - value = matches[2]; - acc[key] = value; - } - return acc; - }, {}); - }; - - Batman.Request.prototype._prepareOptions = function(data) { - var options, _ref, - _this = this; - options = { - url: this.get('url'), - type: this.get('method'), - dataType: this.get('type'), - data: data || this.get('data'), - username: this.get('username'), - password: this.get('password'), - headers: this.get('headers'), - beforeSend: function() { - return _this.fire('loading'); - }, - success: function(response, textStatus, xhr) { - _this.mixin({ - xhr: xhr, - status: xhr.status, - response: response, - responseHeaders: _this._parseResponseHeaders(xhr) - }); - return _this.fire('success', response); - }, - error: function(xhr, status, error) { - _this.mixin({ - xhr: xhr, - status: xhr.status, - response: xhr.responseText, - responseHeaders: _this._parseResponseHeaders(xhr) - }); - xhr.request = _this; - return _this.fire('error', xhr); - }, - complete: function() { - return _this.fire('loaded'); - } - }; - if ((_ref = this.get('method')) === 'PUT' || _ref === 'POST') { - if (!this.hasFileUploads()) { - options.contentType = this.get('contentType'); - if (typeof options.data === 'object') { - options.processData = false; - options.data = Batman.URI.queryFromParams(options.data); - } - } else { - options.contentType = false; - options.processData = false; - options.data = this.constructor.objectToFormData(options.data); - } - } - return options; - }; - - Batman.Request.prototype.send = function(data) { - return jQuery.ajax(this._prepareOptions(data)); - }; - - Batman.mixins.animation = { - show: function(addToParent) { - var jq, show, _ref, _ref1; - jq = $(this); - show = function() { - return jq.show(600); - }; - if (addToParent) { - if ((_ref = addToParent.append) != null) { - _ref.appendChild(this); - } - if ((_ref1 = addToParent.before) != null) { - _ref1.parentNode.insertBefore(this, addToParent.before); - } - jq.hide(); - setTimeout(show, 0); - } else { - show(); - } - return this; - }, - hide: function(removeFromParent) { - var _this = this; - $(this).hide(600, function() { - var _ref; - if (removeFromParent) { - if ((_ref = _this.parentNode) != null) { - _ref.removeChild(_this); - } - } - return Batman.DOM.didRemoveNode(_this); - }); - return this; - } - }; - -}).call(this); \ No newline at end of file diff --git a/vendor/javascripts/batman.js b/vendor/javascripts/batman.js deleted file mode 100644 index 22c7b3a..0000000 --- a/vendor/javascripts/batman.js +++ /dev/null @@ -1,11811 +0,0 @@ -(function() { - var Batman, - __slice = [].slice; - - Batman = function() { - var mixins; - mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.Object, mixins, function(){}); - }; - - Batman.version = '0.10.0'; - - Batman.config = { - pathPrefix: '/', - usePushState: false, - minificationErrors: true - }; - - (Batman.container = (function() { - return this; - })()).Batman = Batman; - - if (typeof define === 'function') { - define('batman', [], function() { - return Batman; - }); - } - - Batman.exportHelpers = function(onto) { - var k, _i, _len, _ref; - _ref = ['mixin', 'extend', 'unmixin', 'redirect', 'typeOf', 'redirect', 'setImmediate', 'clearImmediate']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - onto["$" + k] = Batman[k]; - } - return onto; - }; - - Batman.exportGlobals = function() { - return Batman.exportHelpers(Batman.container); - }; - -}).call(this); - -(function() { - var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Batman.Inflector = (function() { - - Inflector.prototype.plural = function(regex, replacement) { - return this._plural.unshift([regex, replacement]); - }; - - Inflector.prototype.singular = function(regex, replacement) { - return this._singular.unshift([regex, replacement]); - }; - - Inflector.prototype.human = function(regex, replacement) { - return this._human.unshift([regex, replacement]); - }; - - Inflector.prototype.uncountable = function() { - var strings; - strings = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return this._uncountable = this._uncountable.concat(strings.map(function(x) { - return new RegExp("" + x + "$", 'i'); - })); - }; - - Inflector.prototype.irregular = function(singular, plural) { - if (singular.charAt(0) === plural.charAt(0)) { - this.plural(new RegExp("(" + (singular.charAt(0)) + ")" + (singular.slice(1)) + "$", "i"), "$1" + plural.slice(1)); - this.plural(new RegExp("(" + (singular.charAt(0)) + ")" + (plural.slice(1)) + "$", "i"), "$1" + plural.slice(1)); - return this.singular(new RegExp("(" + (plural.charAt(0)) + ")" + (plural.slice(1)) + "$", "i"), "$1" + singular.slice(1)); - } else { - this.plural(new RegExp("" + singular + "$", 'i'), plural); - this.plural(new RegExp("" + plural + "$", 'i'), plural); - return this.singular(new RegExp("" + plural + "$", 'i'), singular); - } - }; - - function Inflector() { - this._plural = []; - this._singular = []; - this._uncountable = []; - this._human = []; - } - - Inflector.prototype.ordinalize = function(number) { - var absNumber, _ref; - absNumber = Math.abs(parseInt(number)); - if (_ref = absNumber % 100, __indexOf.call([11, 12, 13], _ref) >= 0) { - return number + "th"; - } else { - switch (absNumber % 10) { - case 1: - return number + "st"; - case 2: - return number + "nd"; - case 3: - return number + "rd"; - default: - return number + "th"; - } - } - }; - - Inflector.prototype.pluralize = function(word) { - var regex, replace_string, uncountableRegex, _i, _j, _len, _len1, _ref, _ref1, _ref2; - _ref = this._uncountable; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - uncountableRegex = _ref[_i]; - if (uncountableRegex.test(word)) { - return word; - } - } - _ref1 = this._plural; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], regex = _ref2[0], replace_string = _ref2[1]; - if (regex.test(word)) { - return word.replace(regex, replace_string); - } - } - return word; - }; - - Inflector.prototype.singularize = function(word) { - var regex, replace_string, uncountableRegex, _i, _j, _len, _len1, _ref, _ref1, _ref2; - _ref = this._uncountable; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - uncountableRegex = _ref[_i]; - if (uncountableRegex.test(word)) { - return word; - } - } - _ref1 = this._singular; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], regex = _ref2[0], replace_string = _ref2[1]; - if (regex.test(word)) { - return word.replace(regex, replace_string); - } - } - return word; - }; - - Inflector.prototype.humanize = function(word) { - var regex, replace_string, _i, _len, _ref, _ref1; - _ref = this._human; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], regex = _ref1[0], replace_string = _ref1[1]; - if (regex.test(word)) { - return word.replace(regex, replace_string); - } - } - return word; - }; - - return Inflector; - - })(); - -}).call(this); - -(function() { - var Inflector, camelize_rx, capitalize_rx, humanize_rx1, humanize_rx2, humanize_rx3, underscore_rx1, underscore_rx2; - - camelize_rx = /(?:^|_|\-)(.)/g; - - capitalize_rx = /(^|\s)([a-z])/g; - - underscore_rx1 = /([A-Z]+)([A-Z][a-z])/g; - - underscore_rx2 = /([a-z\d])([A-Z])/g; - - humanize_rx1 = /_id$/; - - humanize_rx2 = /_|-/g; - - humanize_rx3 = /^\w/g; - - Batman.helpers = { - ordinalize: function() { - return Batman.helpers.inflector.ordinalize.apply(Batman.helpers.inflector, arguments); - }, - singularize: function() { - return Batman.helpers.inflector.singularize.apply(Batman.helpers.inflector, arguments); - }, - pluralize: function(count, singular, plural, includeCount) { - var result; - if (includeCount == null) { - includeCount = true; - } - if (arguments.length < 2) { - return Batman.helpers.inflector.pluralize(count); - } else { - result = +count === 1 ? singular : plural || Batman.helpers.inflector.pluralize(singular); - if (includeCount) { - result = ("" + (count || 0) + " ") + result; - } - return result; - } - }, - camelize: function(string, firstLetterLower) { - string = string.replace(camelize_rx, function(str, p1) { - return p1.toUpperCase(); - }); - if (firstLetterLower) { - return string.substr(0, 1).toLowerCase() + string.substr(1); - } else { - return string; - } - }, - underscore: function(string) { - return string.replace(underscore_rx1, '$1_$2').replace(underscore_rx2, '$1_$2').replace('-', '_').toLowerCase(); - }, - capitalize: function(string) { - return string.replace(capitalize_rx, function(m, p1, p2) { - return p1 + p2.toUpperCase(); - }); - }, - trim: function(string) { - if (string) { - return string.trim(); - } else { - return ""; - } - }, - interpolate: function(stringOrObject, keys) { - var key, string, value; - if (typeof stringOrObject === 'object') { - string = stringOrObject[keys.count]; - if (!string) { - string = stringOrObject['other']; - } - } else { - string = stringOrObject; - } - for (key in keys) { - value = keys[key]; - string = string.replace(new RegExp("%\\{" + key + "\\}", "g"), value); - } - return string; - }, - humanize: function(string) { - string = Batman.helpers.underscore(string); - string = Batman.helpers.inflector.humanize(string); - return string.replace(humanize_rx1, '').replace(humanize_rx2, ' ').replace(humanize_rx3, function(match) { - return match.toUpperCase(); - }); - } - }; - - Inflector = new Batman.Inflector; - - Batman.helpers.inflector = Inflector; - - Inflector.plural(/$/, 's'); - - Inflector.plural(/s$/i, 's'); - - Inflector.plural(/(ax|test)is$/i, '$1es'); - - Inflector.plural(/(octop|vir)us$/i, '$1i'); - - Inflector.plural(/(octop|vir)i$/i, '$1i'); - - Inflector.plural(/(alias|status)$/i, '$1es'); - - Inflector.plural(/(bu)s$/i, '$1ses'); - - Inflector.plural(/(buffal|tomat)o$/i, '$1oes'); - - Inflector.plural(/([ti])um$/i, '$1a'); - - Inflector.plural(/([ti])a$/i, '$1a'); - - Inflector.plural(/sis$/i, 'ses'); - - Inflector.plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves'); - - Inflector.plural(/(hive)$/i, '$1s'); - - Inflector.plural(/([^aeiouy]|qu)y$/i, '$1ies'); - - Inflector.plural(/(x|ch|ss|sh)$/i, '$1es'); - - Inflector.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'); - - Inflector.plural(/([m|l])ouse$/i, '$1ice'); - - Inflector.plural(/([m|l])ice$/i, '$1ice'); - - Inflector.plural(/^(ox)$/i, '$1en'); - - Inflector.plural(/^(oxen)$/i, '$1'); - - Inflector.plural(/(quiz)$/i, '$1zes'); - - Inflector.singular(/s$/i, ''); - - Inflector.singular(/(n)ews$/i, '$1ews'); - - Inflector.singular(/([ti])a$/i, '$1um'); - - Inflector.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '$1$2sis'); - - Inflector.singular(/(^analy)ses$/i, '$1sis'); - - Inflector.singular(/([^f])ves$/i, '$1fe'); - - Inflector.singular(/(hive)s$/i, '$1'); - - Inflector.singular(/(tive)s$/i, '$1'); - - Inflector.singular(/([lr])ves$/i, '$1f'); - - Inflector.singular(/([^aeiouy]|qu)ies$/i, '$1y'); - - Inflector.singular(/(s)eries$/i, '$1eries'); - - Inflector.singular(/(m)ovies$/i, '$1ovie'); - - Inflector.singular(/(x|ch|ss|sh)es$/i, '$1'); - - Inflector.singular(/([m|l])ice$/i, '$1ouse'); - - Inflector.singular(/(bus)es$/i, '$1'); - - Inflector.singular(/(o)es$/i, '$1'); - - Inflector.singular(/(shoe)s$/i, '$1'); - - Inflector.singular(/(cris|ax|test)es$/i, '$1is'); - - Inflector.singular(/(octop|vir)i$/i, '$1us'); - - Inflector.singular(/(alias|status)es$/i, '$1'); - - Inflector.singular(/^(ox)en/i, '$1'); - - Inflector.singular(/(vert|ind)ices$/i, '$1ex'); - - Inflector.singular(/(matr)ices$/i, '$1ix'); - - Inflector.singular(/(quiz)zes$/i, '$1'); - - Inflector.singular(/(database)s$/i, '$1'); - - Inflector.irregular('person', 'people'); - - Inflector.irregular('man', 'men'); - - Inflector.irregular('child', 'children'); - - Inflector.irregular('sex', 'sexes'); - - Inflector.irregular('move', 'moves'); - - Inflector.irregular('cow', 'kine'); - - Inflector.irregular('zombie', 'zombies'); - - Inflector.uncountable('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans'); - -}).call(this); - -(function() { - var _implementImmediates, _objectToString, - __slice = [].slice, - __hasProp = {}.hasOwnProperty, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Batman.typeOf = function(object) { - if (typeof object === 'undefined') { - return "Undefined"; - } - return _objectToString.call(object).slice(8, -1); - }; - - _objectToString = Object.prototype.toString; - - Batman.extend = function() { - var key, object, objects, to, value, _i, _len; - to = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - for (_i = 0, _len = objects.length; _i < _len; _i++) { - object = objects[_i]; - for (key in object) { - value = object[key]; - to[key] = value; - } - } - return to; - }; - - Batman.mixin = function() { - var hasSet, key, mixin, mixins, to, value, _i, _len; - to = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - hasSet = typeof to.set === 'function'; - for (_i = 0, _len = mixins.length; _i < _len; _i++) { - mixin = mixins[_i]; - if (Batman.typeOf(mixin) !== 'Object') { - continue; - } - for (key in mixin) { - if (!__hasProp.call(mixin, key)) continue; - value = mixin[key]; - if (key === 'initialize' || key === 'uninitialize' || key === 'prototype') { - continue; - } - if (hasSet) { - to.set(key, value); - } else if (to.nodeName != null) { - Batman.data(to, key, value); - } else { - to[key] = value; - } - } - if (typeof mixin.initialize === 'function') { - mixin.initialize.call(to); - } - } - return to; - }; - - Batman.unmixin = function() { - var from, key, mixin, mixins, _i, _len; - from = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - for (_i = 0, _len = mixins.length; _i < _len; _i++) { - mixin = mixins[_i]; - for (key in mixin) { - if (key === 'initialize' || key === 'uninitialize') { - continue; - } - delete from[key]; - } - if (typeof mixin.uninitialize === 'function') { - mixin.uninitialize.call(from); - } - } - return from; - }; - - Batman._functionName = Batman.functionName = function(f) { - var _ref; - if (f.__name__) { - return f.__name__; - } - if (f.name) { - return f.name; - } - return (_ref = f.toString().match(/\W*function\s+([\w\$]+)\(/)) != null ? _ref[1] : void 0; - }; - - Batman._isChildOf = Batman.isChildOf = function(parentNode, childNode) { - var node; - node = childNode.parentNode; - while (node) { - if (node === parentNode) { - return true; - } - node = node.parentNode; - } - return false; - }; - - Batman.setImmediate = Batman.clearImmediate = null; - - _implementImmediates = function(container) { - var canUsePostMessage, count, functions, getHandle, handler, prefix, tasks; - canUsePostMessage = function() { - var async, oldMessage; - if (!container.postMessage) { - return false; - } - async = true; - oldMessage = container.onmessage; - container.onmessage = function() { - return async = false; - }; - container.postMessage("", "*"); - container.onmessage = oldMessage; - return async; - }; - tasks = new Batman.SimpleHash; - count = 0; - getHandle = function() { - return "go" + (++count); - }; - if (container.setImmediate) { - Batman.setImmediate = container.setImmediate; - Batman.clearImmediate = container.clearImmediate; - } else if (container.msSetImmediate) { - Batman.setImmediate = msSetImmediate; - Batman.clearImmediate = msClearImmediate; - } else if (canUsePostMessage()) { - prefix = 'com.batman.'; - functions = new Batman.SimpleHash; - handler = function(e) { - var handle, _base; - if (!~e.data.search(prefix)) { - return; - } - handle = e.data.substring(prefix.length); - return typeof (_base = tasks.unset(handle)) === "function" ? _base() : void 0; - }; - if (container.addEventListener) { - container.addEventListener('message', handler, false); - } else { - container.attachEvent('onmessage', handler); - } - Batman.setImmediate = function(f) { - var handle; - tasks.set(handle = getHandle(), f); - container.postMessage(prefix + handle, "*"); - return handle; - }; - Batman.clearImmediate = function(handle) { - return tasks.unset(handle); - }; - } else if (typeof document !== 'undefined' && __indexOf.call(document.createElement("script"), "onreadystatechange") >= 0) { - Batman.setImmediate = function(f) { - var handle, script; - handle = getHandle(); - script = document.createElement("script"); - script.onreadystatechange = function() { - var _base; - if (typeof (_base = tasks.get(handle)) === "function") { - _base(); - } - script.onreadystatechange = null; - script.parentNode.removeChild(script); - return script = null; - }; - document.documentElement.appendChild(script); - return handle; - }; - Batman.clearImmediate = function(handle) { - return tasks.unset(handle); - }; - } else if (typeof process !== "undefined" && process !== null ? process.nextTick : void 0) { - functions = {}; - Batman.setImmediate = function(f) { - var handle; - handle = getHandle(); - functions[handle] = f; - process.nextTick(function() { - if (typeof functions[handle] === "function") { - functions[handle](); - } - return delete functions[handle]; - }); - return handle; - }; - Batman.clearImmediate = function(handle) { - return delete functions[handle]; - }; - } else { - Batman.setImmediate = function(f) { - return setTimeout(f, 0); - }; - Batman.clearImmediate = function(handle) { - return clearTimeout(handle); - }; - } - Batman.setImmediate = Batman.setImmediate; - return Batman.clearImmediate = Batman.clearImmediate; - }; - - Batman.setImmediate = function() { - _implementImmediates(Batman.container); - return Batman.setImmediate.apply(this, arguments); - }; - - Batman.clearImmediate = function() { - _implementImmediates(Batman.container); - return Batman.clearImmediate.apply(this, arguments); - }; - - Batman.forEach = function(container, iterator, ctx) { - var e, i, k, v, _i, _len, _results, _results1; - if (container.forEach) { - return container.forEach(iterator, ctx); - } else if (container.indexOf) { - _results = []; - for (i = _i = 0, _len = container.length; _i < _len; i = ++_i) { - e = container[i]; - _results.push(iterator.call(ctx, e, i, container)); - } - return _results; - } else { - _results1 = []; - for (k in container) { - v = container[k]; - _results1.push(iterator.call(ctx, k, v, container)); - } - return _results1; - } - }; - - Batman.objectHasKey = function(object, key) { - if (typeof object.hasKey === 'function') { - return object.hasKey(key); - } else { - return key in object; - } - }; - - Batman.contains = function(container, item) { - if (container.indexOf) { - return __indexOf.call(container, item) >= 0; - } else if (typeof container.has === 'function') { - return container.has(item); - } else { - return Batman.objectHasKey(container, item); - } - }; - - Batman.get = function(base, key) { - if (typeof base.get === 'function') { - return base.get(key); - } else { - return Batman.Property.forBaseAndKey(base, key).getValue(); - } - }; - - Batman.getPath = function(base, segments) { - var segment, _i, _len; - for (_i = 0, _len = segments.length; _i < _len; _i++) { - segment = segments[_i]; - if (base != null) { - base = Batman.get(base, segment); - if (base == null) { - return base; - } - } else { - return void 0; - } - } - return base; - }; - - Batman.escapeHTML = (function() { - var replacements; - replacements = { - "&": "&", - "<": "<", - ">": ">", - "\"": """, - "'": "'" - }; - return function(s) { - return ("" + s).replace(/[&<>'"]/g, function(c) { - return replacements[c]; - }); - }; - })(); - - Batman.translate = function(x, values) { - if (values == null) { - values = {}; - } - return Batman.helpers.interpolate(Batman.get(Batman.translate.messages, x), values); - }; - - Batman.translate.messages = {}; - - Batman.t = function() { - return Batman.translate.apply(Batman, arguments); - }; - - Batman.redirect = function(url) { - var _ref; - return (_ref = Batman.navigator) != null ? _ref.redirect(url) : void 0; - }; - - Batman.initializeObject = function(object) { - if (object._batman != null) { - return object._batman.check(object); - } else { - return object._batman = new Batman._Batman(object); - } - }; - -}).call(this); - -(function() { - var developer; - - Batman.developer = { - suppressed: false, - DevelopmentError: (function() { - var DevelopmentError; - DevelopmentError = function(message) { - this.message = message; - return this.name = "DevelopmentError"; - }; - DevelopmentError.prototype = Error.prototype; - return DevelopmentError; - })(), - _ie_console: function(f, args) { - var arg, _i, _len, _results; - if (args.length !== 1) { - if (typeof console !== "undefined" && console !== null) { - console[f]("..." + f + " of " + args.length + " items..."); - } - } - _results = []; - for (_i = 0, _len = args.length; _i < _len; _i++) { - arg = args[_i]; - _results.push(typeof console !== "undefined" && console !== null ? console[f](arg) : void 0); - } - return _results; - }, - suppress: function(f) { - developer.suppressed = true; - if (f) { - f(); - return developer.suppressed = false; - } - }, - unsuppress: function() { - return developer.suppressed = false; - }, - log: function() { - if (developer.suppressed || !((typeof console !== "undefined" && console !== null ? console.log : void 0) != null)) { - return; - } - if (console.log.apply) { - return console.log.apply(console, arguments); - } else { - return developer._ie_console("log", arguments); - } - }, - warn: function() { - if (developer.suppressed || !((typeof console !== "undefined" && console !== null ? console.warn : void 0) != null)) { - return; - } - if (console.warn.apply) { - return console.warn.apply(console, arguments); - } else { - return developer._ie_console("warn", arguments); - } - }, - error: function(message) { - throw new developer.DevelopmentError(message); - }, - assert: function(result, message) { - if (!result) { - return developer.error(message); - } - }, - "do": function(f) { - if (!developer.suppressed) { - return f(); - } - }, - addFilters: function() { - return Batman.extend(Batman.Filters, { - log: function(value, key) { - if (typeof console !== "undefined" && console !== null) { - if (typeof console.log === "function") { - console.log(arguments); - } - } - return value; - }, - logStack: function(value) { - if (typeof console !== "undefined" && console !== null) { - if (typeof console.log === "function") { - console.log(developer.currentFilterStack); - } - } - return value; - } - }); - } - }; - - developer = Batman.developer; - - Batman.developer.assert((function() {}).bind, "Error! Batman needs Function.bind to work! Please shim it using something like es5-shim or augmentjs!"); - -}).call(this); - -(function() { - var _Batman; - - Batman._Batman = _Batman = (function() { - - function _Batman(object) { - this.object = object; - } - - _Batman.prototype.check = function(object) { - if (object !== this.object) { - object._batman = new Batman._Batman(object); - return false; - } - return true; - }; - - _Batman.prototype.get = function(key) { - var reduction, results; - results = this.getAll(key); - switch (results.length) { - case 0: - return void 0; - case 1: - return results[0]; - default: - reduction = results[0].concat != null ? function(a, b) { - return a.concat(b); - } : results[0].merge != null ? function(a, b) { - return a.merge(b); - } : results.every(function(x) { - return typeof x === 'object'; - }) ? (results.unshift({}), function(a, b) { - return Batman.extend(a, b); - }) : void 0; - if (reduction) { - return results.reduceRight(reduction); - } else { - return results; - } - } - }; - - _Batman.prototype.getFirst = function(key) { - var results; - results = this.getAll(key); - return results[0]; - }; - - _Batman.prototype.getAll = function(keyOrGetter) { - var getter, results, val; - if (typeof keyOrGetter === 'function') { - getter = keyOrGetter; - } else { - getter = function(ancestor) { - var _ref; - return (_ref = ancestor._batman) != null ? _ref[keyOrGetter] : void 0; - }; - } - results = this.ancestors(getter); - if (val = getter(this.object)) { - results.unshift(val); - } - return results; - }; - - _Batman.prototype.ancestors = function(getter) { - var isClass, parent, proto, results, val, _ref, _ref1; - if (getter == null) { - getter = function(x) { - return x; - }; - } - results = []; - isClass = !!this.object.prototype; - parent = isClass ? (_ref = this.object.__super__) != null ? _ref.constructor : void 0 : (proto = Object.getPrototypeOf(this.object)) === this.object ? this.object.constructor.__super__ : proto; - if (parent != null) { - if ((_ref1 = parent._batman) != null) { - _ref1.check(parent); - } - val = getter(parent); - if (val != null) { - results.push(val); - } - if (parent._batman != null) { - results = results.concat(parent._batman.ancestors(getter)); - } - } - return results; - }; - - _Batman.prototype.set = function(key, value) { - return this[key] = value; - }; - - return _Batman; - - })(); - -}).call(this); - -(function() { - - Batman.Event = (function() { - - Event.forBaseAndKey = function(base, key) { - if (base.isEventEmitter) { - return base.event(key); - } else { - return new Batman.Event(base, key); - } - }; - - function Event(base, key) { - this.base = base; - this.key = key; - this.handlers = []; - this._preventCount = 0; - } - - Event.prototype.isEvent = true; - - Event.prototype.isEqual = function(other) { - return this.constructor === other.constructor && this.base === other.base && this.key === other.key; - }; - - Event.prototype.hashKey = function() { - var key; - this.hashKey = function() { - return key; - }; - return key = ""; - }; - - Event.prototype.addHandler = function(handler) { - if (this.handlers.indexOf(handler) === -1) { - this.handlers.push(handler); - } - if (this.oneShot) { - this.autofireHandler(handler); - } - return this; - }; - - Event.prototype.removeHandler = function(handler) { - var index; - if ((index = this.handlers.indexOf(handler)) !== -1) { - this.handlers.splice(index, 1); - } - return this; - }; - - Event.prototype.eachHandler = function(iterator) { - var key, _ref, _ref1; - this.handlers.slice().forEach(iterator); - if ((_ref = this.base) != null ? _ref.isEventEmitter : void 0) { - key = this.key; - return (_ref1 = this.base._batman) != null ? _ref1.ancestors(function(ancestor) { - var handlers, _ref2, _ref3; - if (ancestor.isEventEmitter && ((_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.events) != null ? _ref3.hasOwnProperty(key) : void 0 : void 0)) { - handlers = ancestor.event(key).handlers; - return handlers.slice().forEach(iterator); - } - }) : void 0; - } - }; - - Event.prototype.clearHandlers = function() { - return this.handlers = []; - }; - - Event.prototype.handlerContext = function() { - return this.base; - }; - - Event.prototype.prevent = function() { - return ++this._preventCount; - }; - - Event.prototype.allow = function() { - if (this._preventCount) { - --this._preventCount; - } - return this._preventCount; - }; - - Event.prototype.isPrevented = function() { - return this._preventCount > 0; - }; - - Event.prototype.autofireHandler = function(handler) { - if (this._oneShotFired && (this._oneShotArgs != null)) { - return handler.apply(this.handlerContext(), this._oneShotArgs); - } - }; - - Event.prototype.resetOneShot = function() { - this._oneShotFired = false; - return this._oneShotArgs = null; - }; - - Event.prototype.fire = function() { - var args, context; - if (this.isPrevented() || this._oneShotFired) { - return false; - } - context = this.handlerContext(); - args = arguments; - if (this.oneShot) { - this._oneShotFired = true; - this._oneShotArgs = arguments; - } - return this.eachHandler(function(handler) { - return handler.apply(context, args); - }); - }; - - Event.prototype.allowAndFire = function() { - this.allow(); - return this.fire.apply(this, arguments); - }; - - return Event; - - })(); - -}).call(this); - -(function() { - var __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; }; - - Batman.PropertyEvent = (function(_super) { - - __extends(PropertyEvent, _super); - - function PropertyEvent() { - return PropertyEvent.__super__.constructor.apply(this, arguments); - } - - PropertyEvent.prototype.eachHandler = function(iterator) { - return this.base.eachObserver(iterator); - }; - - PropertyEvent.prototype.handlerContext = function() { - return this.base.base; - }; - - return PropertyEvent; - - })(Batman.Event); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.EventEmitter = { - isEventEmitter: true, - hasEvent: function(key) { - var _ref, _ref1; - return (_ref = this._batman) != null ? typeof _ref.get === "function" ? (_ref1 = _ref.get('events')) != null ? _ref1.hasOwnProperty(key) : void 0 : void 0 : void 0; - }, - event: function(key) { - var eventClass, events, existingEvent, newEvent, _base; - Batman.initializeObject(this); - eventClass = this.eventClass || Batman.Event; - events = (_base = this._batman).events || (_base.events = {}); - if (events.hasOwnProperty(key)) { - return existingEvent = events[key]; - } else { - this._batman.ancestors(function(ancestor) { - var _ref, _ref1; - return existingEvent || (existingEvent = (_ref = ancestor._batman) != null ? (_ref1 = _ref.events) != null ? _ref1[key] : void 0 : void 0); - }); - newEvent = events[key] = new eventClass(this, key); - newEvent.oneShot = existingEvent != null ? existingEvent.oneShot : void 0; - return newEvent; - } - }, - on: function(key, handler) { - return this.event(key).addHandler(handler); - }, - once: function(key, originalHandler) { - var event, handler; - event = this.event(key); - handler = function() { - originalHandler.apply(this, arguments); - return event.removeHandler(handler); - }; - return event.addHandler(handler); - }, - registerAsMutableSource: function() { - return Batman.Property.registerSource(this); - }, - mutation: function(wrappedFunction) { - return function() { - var result; - result = wrappedFunction.apply(this, arguments); - this.event('change').fire(this, this); - return result; - }; - }, - prevent: function(key) { - this.event(key).prevent(); - return this; - }, - allow: function(key) { - this.event(key).allow(); - return this; - }, - isPrevented: function(key) { - return this.event(key).isPrevented(); - }, - fire: function() { - var args, key, _ref; - key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - return (_ref = this.event(key)).fire.apply(_ref, args); - }, - allowAndFire: function() { - var args, key, _ref; - key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - return (_ref = this.event(key)).allowAndFire.apply(_ref, args); - } - }; - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.Enumerable = { - isEnumerable: true, - map: function(f, ctx) { - var r; - if (ctx == null) { - ctx = Batman.container; - } - r = []; - this.forEach(function() { - return r.push(f.apply(ctx, arguments)); - }); - return r; - }, - mapToProperty: function(key) { - var r; - r = []; - this.forEach(function(item) { - return r.push(item.get(key)); - }); - return r; - }, - every: function(f, ctx) { - var r; - if (ctx == null) { - ctx = Batman.container; - } - r = true; - this.forEach(function() { - return r = r && f.apply(ctx, arguments); - }); - return r; - }, - some: function(f, ctx) { - var r; - if (ctx == null) { - ctx = Batman.container; - } - r = false; - this.forEach(function() { - return r = r || f.apply(ctx, arguments); - }); - return r; - }, - reduce: function(f, r) { - var count, self; - count = 0; - self = this; - this.forEach(function() { - if (r != null) { - return r = f.apply(null, [r].concat(__slice.call(arguments), [count], [self])); - } else { - return r = arguments[0]; - } - }); - return r; - }, - filter: function(f) { - var r, wrap; - r = new this.constructor; - if (r.add) { - wrap = function(r, e) { - if (f(e)) { - r.add(e); - } - return r; - }; - } else if (r.set) { - wrap = function(r, k, v) { - if (f(k, v)) { - r.set(k, v); - } - return r; - }; - } else { - if (!r.push) { - r = []; - } - wrap = function(r, e) { - if (f(e)) { - r.push(e); - } - return r; - }; - } - return this.reduce(wrap, r); - }, - inGroupsOf: function(n) { - var current, i, r; - r = []; - current = false; - i = 0; - this.forEach(function(x) { - if (i++ % n === 0) { - current = []; - r.push(current); - } - return current.push(x); - }); - return r; - } - }; - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.SimpleHash = (function() { - - function SimpleHash(obj) { - this._storage = {}; - this.length = 0; - if (obj != null) { - this.update(obj); - } - } - - Batman.extend(SimpleHash.prototype, Batman.Enumerable); - - SimpleHash.prototype.propertyClass = Batman.Property; - - SimpleHash.prototype.hasKey = function(key) { - var pair, pairs, _i, _len; - if (this.objectKey(key)) { - if (!this._objectStorage) { - return false; - } - if (pairs = this._objectStorage[this.hashKeyFor(key)]) { - for (_i = 0, _len = pairs.length; _i < _len; _i++) { - pair = pairs[_i]; - if (this.equality(pair[0], key)) { - return true; - } - } - } - return false; - } else { - key = this.prefixedKey(key); - return this._storage.hasOwnProperty(key); - } - }; - - SimpleHash.prototype.get = function(key) { - var pair, pairs, _i, _len; - if (this.objectKey(key)) { - if (!this._objectStorage) { - return void 0; - } - if (pairs = this._objectStorage[this.hashKeyFor(key)]) { - for (_i = 0, _len = pairs.length; _i < _len; _i++) { - pair = pairs[_i]; - if (this.equality(pair[0], key)) { - return pair[1]; - } - } - } - } else { - return this._storage[this.prefixedKey(key)]; - } - }; - - SimpleHash.prototype.set = function(key, val) { - var pair, pairs, _base, _i, _len, _name; - if (this.objectKey(key)) { - this._objectStorage || (this._objectStorage = {}); - pairs = (_base = this._objectStorage)[_name = this.hashKeyFor(key)] || (_base[_name] = []); - for (_i = 0, _len = pairs.length; _i < _len; _i++) { - pair = pairs[_i]; - if (this.equality(pair[0], key)) { - return pair[1] = val; - } - } - this.length++; - pairs.push([key, val]); - return val; - } else { - key = this.prefixedKey(key); - if (this._storage[key] == null) { - this.length++; - } - return this._storage[key] = val; - } - }; - - SimpleHash.prototype.unset = function(key) { - var hashKey, index, obj, pair, pairs, val, value, _i, _len, _ref; - if (this.objectKey(key)) { - if (!this._objectStorage) { - return void 0; - } - hashKey = this.hashKeyFor(key); - if (pairs = this._objectStorage[hashKey]) { - for (index = _i = 0, _len = pairs.length; _i < _len; index = ++_i) { - _ref = pairs[index], obj = _ref[0], value = _ref[1]; - if (this.equality(obj, key)) { - pair = pairs.splice(index, 1); - if (!pairs.length) { - delete this._objectStorage[hashKey]; - } - this.length--; - return pair[0][1]; - } - } - } - } else { - key = this.prefixedKey(key); - val = this._storage[key]; - if (this._storage[key] != null) { - this.length--; - delete this._storage[key]; - } - return val; - } - }; - - SimpleHash.prototype.getOrSet = function(key, valueFunction) { - var currentValue; - currentValue = this.get(key); - if (!currentValue) { - currentValue = valueFunction(); - this.set(key, currentValue); - } - return currentValue; - }; - - SimpleHash.prototype.prefixedKey = function(key) { - return "_" + key; - }; - - SimpleHash.prototype.unprefixedKey = function(key) { - return key.slice(1); - }; - - SimpleHash.prototype.hashKeyFor = function(obj) { - return (obj != null ? typeof obj.hashKey === "function" ? obj.hashKey() : void 0 : void 0) || obj; - }; - - SimpleHash.prototype.equality = function(lhs, rhs) { - if (lhs === rhs) { - return true; - } - if (lhs !== lhs && rhs !== rhs) { - return true; - } - if ((lhs != null ? typeof lhs.isEqual === "function" ? lhs.isEqual(rhs) : void 0 : void 0) && (rhs != null ? typeof rhs.isEqual === "function" ? rhs.isEqual(lhs) : void 0 : void 0)) { - return true; - } - return false; - }; - - SimpleHash.prototype.objectKey = function(key) { - return typeof key !== 'string'; - }; - - SimpleHash.prototype.forEach = function(iterator, ctx) { - var key, obj, results, value, values, _i, _len, _ref, _ref1, _ref2, _ref3; - results = []; - if (this._objectStorage) { - _ref = this._objectStorage; - for (key in _ref) { - values = _ref[key]; - _ref1 = values.slice(); - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - _ref2 = _ref1[_i], obj = _ref2[0], value = _ref2[1]; - results.push(iterator.call(ctx, obj, value, this)); - } - } - } - _ref3 = this._storage; - for (key in _ref3) { - value = _ref3[key]; - results.push(iterator.call(ctx, this.unprefixedKey(key), value, this)); - } - return results; - }; - - SimpleHash.prototype.keys = function() { - var result; - result = []; - Batman.SimpleHash.prototype.forEach.call(this, function(key) { - return result.push(key); - }); - return result; - }; - - SimpleHash.prototype.toArray = SimpleHash.prototype.keys; - - SimpleHash.prototype.clear = function() { - this._storage = {}; - delete this._objectStorage; - return this.length = 0; - }; - - SimpleHash.prototype.isEmpty = function() { - return this.length === 0; - }; - - SimpleHash.prototype.merge = function() { - var hash, merged, others, _i, _len; - others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - merged = new this.constructor; - others.unshift(this); - for (_i = 0, _len = others.length; _i < _len; _i++) { - hash = others[_i]; - hash.forEach(function(obj, value) { - return merged.set(obj, value); - }); - } - return merged; - }; - - SimpleHash.prototype.update = function(object) { - var k, v, _results; - _results = []; - for (k in object) { - v = object[k]; - _results.push(this.set(k, v)); - } - return _results; - }; - - SimpleHash.prototype.replace = function(object) { - var _this = this; - this.forEach(function(key, value) { - if (!(key in object)) { - return _this.unset(key); - } - }); - return this.update(object); - }; - - SimpleHash.prototype.toObject = function() { - var key, obj, pair, value, _ref, _ref1; - obj = {}; - _ref = this._storage; - for (key in _ref) { - value = _ref[key]; - obj[this.unprefixedKey(key)] = value; - } - if (this._objectStorage) { - _ref1 = this._objectStorage; - for (key in _ref1) { - pair = _ref1[key]; - obj[key] = pair[0][1]; - } - } - return obj; - }; - - SimpleHash.prototype.toJSON = SimpleHash.prototype.toObject; - - return SimpleHash; - - })(); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.AssociationCurator = (function(_super) { - - __extends(AssociationCurator, _super); - - AssociationCurator.availableAssociations = ['belongsTo', 'hasOne', 'hasMany']; - - function AssociationCurator(model) { - this.model = model; - AssociationCurator.__super__.constructor.call(this); - this._byTypeStorage = new Batman.SimpleHash; - } - - AssociationCurator.prototype.add = function(association) { - var associationTypeSet; - this.set(association.label, association); - if (!(associationTypeSet = this._byTypeStorage.get(association.associationType))) { - associationTypeSet = new Batman.SimpleSet; - this._byTypeStorage.set(association.associationType, associationTypeSet); - } - return associationTypeSet.add(association); - }; - - AssociationCurator.prototype.getByType = function(type) { - return this._byTypeStorage.get(type); - }; - - AssociationCurator.prototype.getByLabel = function(label) { - return this.get(label); - }; - - AssociationCurator.prototype.reset = function() { - this.forEach(function(label, association) { - return association.reset(); - }); - return true; - }; - - AssociationCurator.prototype.merge = function() { - var others, result; - others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - result = AssociationCurator.__super__.merge.apply(this, arguments); - result._byTypeStorage = this._byTypeStorage.merge(others.map(function(other) { - return other._byTypeStorage; - })); - return result; - }; - - AssociationCurator.prototype._markDirtyAttribute = function(key, oldValue) { - var _ref; - if ((_ref = this.lifecycle.get('state')) !== 'loading' && _ref !== 'creating' && _ref !== 'saving' && _ref !== 'saved') { - if (this.lifecycle.startTransition('set')) { - return this.dirtyKeys.set(key, oldValue); - } else { - throw new Batman.StateMachine.InvalidTransitionError("Can't set while in state " + (this.lifecycle.get('state'))); - } - } - }; - - return AssociationCurator; - - })(Batman.SimpleHash); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.SimpleSet = (function() { - - function SimpleSet() { - this._storage = []; - this.length = 0; - if (arguments.length > 0) { - this.add.apply(this, arguments); - } - } - - Batman.extend(SimpleSet.prototype, Batman.Enumerable); - - SimpleSet.prototype.has = function(item) { - return !!(~this._indexOfItem(item)); - }; - - SimpleSet.prototype.add = function() { - var addedItems, item, items, _i, _len; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - addedItems = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!(!~this._indexOfItem(item))) { - continue; - } - this._storage.push(item); - addedItems.push(item); - } - this.length = this._storage.length; - if (this.fire && addedItems.length !== 0) { - this.fire('change', this, this); - this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedItems))); - } - return addedItems; - }; - - SimpleSet.prototype.remove = function() { - var index, item, items, removedItems, _i, _len; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - removedItems = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!(~(index = this._indexOfItem(item)))) { - continue; - } - this._storage.splice(index, 1); - removedItems.push(item); - } - this.length = this._storage.length; - if (this.fire && removedItems.length !== 0) { - this.fire('change', this, this); - this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(removedItems))); - } - return removedItems; - }; - - SimpleSet.prototype.find = function(f) { - var item, _i, _len, _ref; - _ref = this._storage; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - item = _ref[_i]; - if (f(item)) { - return item; - } - } - }; - - SimpleSet.prototype.forEach = function(iterator, ctx) { - var container; - container = this; - return this._storage.slice().forEach(function(key) { - return iterator.call(ctx, key, null, container); - }); - }; - - SimpleSet.prototype.isEmpty = function() { - return this.length === 0; - }; - - SimpleSet.prototype.clear = function() { - var items; - items = this._storage; - this._storage = []; - this.length = 0; - if (this.fire && items.length !== 0) { - this.fire('change', this, this); - this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(items))); - } - return items; - }; - - SimpleSet.prototype.replace = function(other) { - try { - if (typeof this.prevent === "function") { - this.prevent('change'); - } - this.clear(); - return this.add.apply(this, other.toArray()); - } finally { - if (typeof this.allowAndFire === "function") { - this.allowAndFire('change', this, this); - } - } - }; - - SimpleSet.prototype.toArray = function() { - return this._storage.slice(); - }; - - SimpleSet.prototype.merge = function() { - var merged, others, set, _i, _len; - others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - merged = new this.constructor; - others.unshift(this); - for (_i = 0, _len = others.length; _i < _len; _i++) { - set = others[_i]; - set.forEach(function(v) { - return merged.add(v); - }); - } - return merged; - }; - - SimpleSet.prototype.indexedBy = function(key) { - this._indexes || (this._indexes = new Batman.SimpleHash); - return this._indexes.get(key) || this._indexes.set(key, new Batman.SetIndex(this, key)); - }; - - SimpleSet.prototype.indexedByUnique = function(key) { - this._uniqueIndexes || (this._uniqueIndexes = new Batman.SimpleHash); - return this._uniqueIndexes.get(key) || this._uniqueIndexes.set(key, new Batman.UniqueSetIndex(this, key)); - }; - - SimpleSet.prototype.sortedBy = function(key, order) { - var sortsForKey; - if (order == null) { - order = "asc"; - } - order = order.toLowerCase() === "desc" ? "desc" : "asc"; - this._sorts || (this._sorts = new Batman.SimpleHash); - sortsForKey = this._sorts.get(key) || this._sorts.set(key, new Batman.Object); - return sortsForKey.get(order) || sortsForKey.set(order, new Batman.SetSort(this, key, order)); - }; - - SimpleSet.prototype.equality = Batman.SimpleHash.prototype.equality; - - SimpleSet.prototype._indexOfItem = function(givenItem) { - var index, item, _i, _len, _ref; - _ref = this._storage; - for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { - item = _ref[index]; - if (this.equality(givenItem, item)) { - return index; - } - } - return -1; - }; - - return SimpleSet; - - })(); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.Property = (function() { - - Batman.mixin(Property.prototype, Batman.EventEmitter); - - Property._sourceTrackerStack = []; - - Property.sourceTracker = function() { - var stack; - return (stack = this._sourceTrackerStack)[stack.length - 1]; - }; - - Property.defaultAccessor = { - get: function(key) { - return this[key]; - }, - set: function(key, val) { - return this[key] = val; - }, - unset: function(key) { - var x; - x = this[key]; - delete this[key]; - return x; - }, - cache: false - }; - - Property.defaultAccessorForBase = function(base) { - var _ref; - return ((_ref = base._batman) != null ? _ref.getFirst('defaultAccessor') : void 0) || Batman.Property.defaultAccessor; - }; - - Property.accessorForBaseAndKey = function(base, key) { - var accessor, _bm, _ref, - _this = this; - if ((_bm = base._batman) != null) { - accessor = (_ref = _bm.keyAccessors) != null ? _ref.get(key) : void 0; - if (!accessor) { - _bm.ancestors(function(ancestor) { - var _ref1, _ref2; - return accessor || (accessor = (_ref1 = ancestor._batman) != null ? (_ref2 = _ref1.keyAccessors) != null ? _ref2.get(key) : void 0 : void 0); - }); - } - } - return accessor || this.defaultAccessorForBase(base); - }; - - Property.forBaseAndKey = function(base, key) { - if (base.isObservable) { - return base.property(key); - } else { - return new Batman.Keypath(base, key); - } - }; - - Property.withoutTracking = function(block) { - return this.wrapTrackingPrevention(block)(); - }; - - Property.wrapTrackingPrevention = function(block) { - return function() { - Batman.Property.pushDummySourceTracker(); - try { - return block.apply(this, arguments); - } finally { - Batman.Property.popSourceTracker(); - } - }; - }; - - Property.registerSource = function(obj) { - var _ref; - if (!obj.isEventEmitter) { - return; - } - return (_ref = this.sourceTracker()) != null ? _ref.add(obj) : void 0; - }; - - Property.pushSourceTracker = function() { - return Batman.Property._sourceTrackerStack.push(new Batman.SimpleSet); - }; - - Property.pushDummySourceTracker = function() { - return Batman.Property._sourceTrackerStack.push(null); - }; - - Property.popSourceTracker = function() { - return Batman.Property._sourceTrackerStack.pop(); - }; - - function Property(base, key) { - this.base = base; - this.key = key; - } - - Property.prototype._isolationCount = 0; - - Property.prototype.cached = false; - - Property.prototype.value = null; - - Property.prototype.sources = null; - - Property.prototype.isProperty = true; - - Property.prototype.isDead = false; - - Property.prototype.eventClass = Batman.PropertyEvent; - - Property.prototype.isEqual = function(other) { - return this.constructor === other.constructor && this.base === other.base && this.key === other.key; - }; - - Property.prototype.hashKey = function() { - var key; - this.hashKey = function() { - return key; - }; - return key = ""; - }; - - Property.prototype.event = function(key) { - var eventClass, _base; - eventClass = this.eventClass || Batman.Event; - this.events || (this.events = {}); - (_base = this.events)[key] || (_base[key] = new eventClass(this, key)); - return this.events[key]; - }; - - Property.prototype.changeEvent = function() { - var event; - event = this.event('change'); - this.changeEvent = function() { - return event; - }; - return event; - }; - - Property.prototype.accessor = function() { - var accessor; - accessor = this.constructor.accessorForBaseAndKey(this.base, this.key); - this.accessor = function() { - return accessor; - }; - return accessor; - }; - - Property.prototype.eachObserver = function(iterator) { - var key; - key = this.key; - this.changeEvent().handlers.slice().forEach(iterator); - if (this.base.isObservable) { - return this.base._batman.ancestors(function(ancestor) { - var handlers, property; - if (ancestor.isObservable && ancestor.hasProperty(key)) { - property = ancestor.property(key); - handlers = property.changeEvent().handlers; - return handlers.slice().forEach(iterator); - } - }); - } - }; - - Property.prototype.observers = function() { - var results; - results = []; - this.eachObserver(function(observer) { - return results.push(observer); - }); - return results; - }; - - Property.prototype.hasObservers = function() { - return this.observers().length > 0; - }; - - Property.prototype.updateSourcesFromTracker = function() { - var handler, newSources; - newSources = this.constructor.popSourceTracker(); - handler = this.sourceChangeHandler(); - this._eachSourceChangeEvent(function(e) { - return e.removeHandler(handler); - }); - this.sources = newSources; - return this._eachSourceChangeEvent(function(e) { - return e.addHandler(handler); - }); - }; - - Property.prototype._eachSourceChangeEvent = function(iterator) { - if (this.sources == null) { - return; - } - return this.sources.forEach(function(source) { - return iterator(source.event('change')); - }); - }; - - Property.prototype.getValue = function() { - this.registerAsMutableSource(); - if (!this.isCached()) { - this.constructor.pushSourceTracker(); - try { - this.value = this.valueFromAccessor(); - this.cached = true; - } finally { - this.updateSourcesFromTracker(); - } - } - return this.value; - }; - - Property.prototype.isCachable = function() { - var cacheable; - if (this.isFinal()) { - return true; - } - cacheable = this.accessor().cache; - if (cacheable != null) { - return !!cacheable; - } else { - return true; - } - }; - - Property.prototype.isCached = function() { - return this.isCachable() && this.cached; - }; - - Property.prototype.isFinal = function() { - return !!this.accessor()['final']; - }; - - Property.prototype.refresh = function() { - var previousValue, value; - this.cached = false; - previousValue = this.value; - value = this.getValue(); - if (value !== previousValue && !this.isIsolated()) { - this.fire(value, previousValue); - } - if (this.value !== void 0 && this.isFinal()) { - return this.lockValue(); - } - }; - - Property.prototype.sourceChangeHandler = function() { - var handler, - _this = this; - handler = this._handleSourceChange.bind(this); - Batman.developer["do"](function() { - return handler.property = _this; - }); - this.sourceChangeHandler = function() { - return handler; - }; - return handler; - }; - - Property.prototype._handleSourceChange = function() { - if (this.isIsolated()) { - return this._needsRefresh = true; - } else if (!this.isFinal() && !this.hasObservers()) { - return this.cached = false; - } else { - return this.refresh(); - } - }; - - Property.prototype.valueFromAccessor = function() { - var _ref; - return (_ref = this.accessor().get) != null ? _ref.call(this.base, this.key) : void 0; - }; - - Property.prototype.setValue = function(val) { - var set; - if (!(set = this.accessor().set)) { - return; - } - return this._changeValue(function() { - return set.call(this.base, this.key, val); - }); - }; - - Property.prototype.unsetValue = function() { - var unset; - if (!(unset = this.accessor().unset)) { - return; - } - return this._changeValue(function() { - return unset.call(this.base, this.key); - }); - }; - - Property.prototype._changeValue = function(block) { - var result; - this.cached = false; - this.constructor.pushDummySourceTracker(); - try { - result = block.apply(this); - this.refresh(); - } finally { - this.constructor.popSourceTracker(); - } - if (!(this.isCached() || this.hasObservers())) { - this.die(); - } - return result; - }; - - Property.prototype.forget = function(handler) { - if (handler != null) { - return this.changeEvent().removeHandler(handler); - } else { - return this.changeEvent().clearHandlers(); - } - }; - - Property.prototype.observeAndFire = function(handler) { - this.observe(handler); - return handler.call(this.base, this.value, this.value, this.key); - }; - - Property.prototype.observe = function(handler) { - this.changeEvent().addHandler(handler); - if (this.sources == null) { - this.getValue(); - } - return this; - }; - - Property.prototype.observeOnce = function(originalHandler) { - var event, handler; - event = this.changeEvent(); - handler = function() { - originalHandler.apply(this, arguments); - return event.removeHandler(handler); - }; - event.addHandler(handler); - if (this.sources == null) { - this.getValue(); - } - return this; - }; - - Property.prototype._removeHandlers = function() { - var handler; - handler = this.sourceChangeHandler(); - this._eachSourceChangeEvent(function(e) { - return e.removeHandler(handler); - }); - delete this.sources; - return this.changeEvent().clearHandlers(); - }; - - Property.prototype.lockValue = function() { - this._removeHandlers(); - this.getValue = function() { - return this.value; - }; - return this.setValue = this.unsetValue = this.refresh = this.observe = function() {}; - }; - - Property.prototype.die = function() { - var _ref, _ref1; - this._removeHandlers(); - if ((_ref = this.base._batman) != null) { - if ((_ref1 = _ref.properties) != null) { - _ref1.unset(this.key); - } - } - return this.isDead = true; - }; - - Property.prototype.fire = function() { - var _ref; - return (_ref = this.changeEvent()).fire.apply(_ref, __slice.call(arguments).concat([this.key])); - }; - - Property.prototype.isolate = function() { - if (this._isolationCount === 0) { - this._preIsolationValue = this.getValue(); - } - return this._isolationCount++; - }; - - Property.prototype.expose = function() { - if (this._isolationCount === 1) { - this._isolationCount--; - if (this._needsRefresh) { - this.value = this._preIsolationValue; - this.refresh(); - } else if (this.value !== this._preIsolationValue) { - this.fire(this.value, this._preIsolationValue); - } - return this._preIsolationValue = null; - } else if (this._isolationCount > 0) { - return this._isolationCount--; - } - }; - - Property.prototype.isIsolated = function() { - return this._isolationCount > 0; - }; - - return Property; - - })(); - -}).call(this); - -(function() { - var __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; }; - - Batman.Keypath = (function(_super) { - - __extends(Keypath, _super); - - function Keypath(base, key) { - if (typeof key === 'string') { - this.segments = key.split('.'); - this.depth = this.segments.length; - } else { - this.segments = [key]; - this.depth = 1; - } - Keypath.__super__.constructor.apply(this, arguments); - } - - Keypath.prototype.isCachable = function() { - if (this.depth === 1) { - return Keypath.__super__.isCachable.apply(this, arguments); - } else { - return true; - } - }; - - Keypath.prototype.terminalProperty = function() { - var base; - base = Batman.getPath(this.base, this.segments.slice(0, -1)); - if (base == null) { - return; - } - return Batman.Keypath.forBaseAndKey(base, this.segments[this.depth - 1]); - }; - - Keypath.prototype.valueFromAccessor = function() { - if (this.depth === 1) { - return Keypath.__super__.valueFromAccessor.apply(this, arguments); - } else { - return Batman.getPath(this.base, this.segments); - } - }; - - Keypath.prototype.setValue = function(val) { - var _ref; - if (this.depth === 1) { - return Keypath.__super__.setValue.apply(this, arguments); - } else { - return (_ref = this.terminalProperty()) != null ? _ref.setValue(val) : void 0; - } - }; - - Keypath.prototype.unsetValue = function() { - var _ref; - if (this.depth === 1) { - return Keypath.__super__.unsetValue.apply(this, arguments); - } else { - return (_ref = this.terminalProperty()) != null ? _ref.unsetValue() : void 0; - } - }; - - return Keypath; - - })(Batman.Property); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.Observable = { - isObservable: true, - hasProperty: function(key) { - var _ref, _ref1; - return (_ref = this._batman) != null ? (_ref1 = _ref.properties) != null ? typeof _ref1.hasKey === "function" ? _ref1.hasKey(key) : void 0 : void 0 : void 0; - }, - property: function(key) { - var properties, propertyClass, _base; - Batman.initializeObject(this); - propertyClass = this.propertyClass || Batman.Keypath; - properties = (_base = this._batman).properties || (_base.properties = new Batman.SimpleHash); - return properties.get(key) || properties.set(key, new propertyClass(this, key)); - }, - get: function(key) { - return this.property(key).getValue(); - }, - set: function(key, val) { - return this.property(key).setValue(val); - }, - unset: function(key) { - return this.property(key).unsetValue(); - }, - getOrSet: Batman.SimpleHash.prototype.getOrSet, - forget: function(key, observer) { - var _ref; - if (key) { - this.property(key).forget(observer); - } else { - if ((_ref = this._batman.properties) != null) { - _ref.forEach(function(key, property) { - return property.forget(); - }); - } - } - return this; - }, - observe: function() { - var args, key, _ref; - key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - (_ref = this.property(key)).observe.apply(_ref, args); - return this; - }, - observeAndFire: function() { - var args, key, _ref; - key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - (_ref = this.property(key)).observeAndFire.apply(_ref, args); - return this; - }, - observeOnce: function() { - var args, key, _ref; - key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - (_ref = this.property(key)).observeOnce.apply(_ref, args); - return this; - } - }; - -}).call(this); - -(function() { - - Batman.DOM = { - textInputTypes: ['text', 'search', 'tel', 'url', 'email', 'password'], - scrollIntoView: function(elementID) { - var _ref; - return (_ref = document.getElementById(elementID)) != null ? typeof _ref.scrollIntoView === "function" ? _ref.scrollIntoView() : void 0 : void 0; - }, - querySelectorAll: (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) != null ? function(node, selector) { - return jQuery(selector, node); - } : (typeof document !== "undefined" && document !== null ? document.querySelectorAll : void 0) != null ? function(node, selector) { - return node.querySelectorAll(selector); - } : function() { - return Batman.developer.error("Please include either jQuery or a querySelectorAll polyfill, or set Batman.DOM.querySelectorAll to return an empty array."); - }, - querySelector: (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) != null ? function(node, selector) { - return jQuery(selector, node)[0]; - } : (typeof document !== "undefined" && document !== null ? document.querySelector : void 0) != null ? function(node, selector) { - return node.querySelector(selector); - } : function() { - return Batman.developer.error("Please include either jQuery or a querySelector polyfill, or set Batman.DOM.querySelector to an empty function."); - }, - partial: function(container, path, context, renderer) { - var view; - renderer.prevent('rendered'); - view = new Batman.View({ - source: path, - context: context - }); - return view.on('ready', function() { - Batman.setInnerHTML(container, ''); - Batman.appendChild(container, view.get('node')); - return renderer.allowAndFire('rendered'); - }); - }, - propagateBindingEvent: Batman.propagateBindingEvent = function(binding, node) { - var current, parentBinding, parentBindings, _i, _len; - while ((current = (current || node).parentNode)) { - parentBindings = Batman._data(current, 'bindings'); - if (parentBindings != null) { - for (_i = 0, _len = parentBindings.length; _i < _len; _i++) { - parentBinding = parentBindings[_i]; - if (typeof parentBinding.childBindingAdded === "function") { - parentBinding.childBindingAdded(binding); - } - } - } - } - }, - propagateBindingEvents: Batman.propagateBindingEvents = function(newNode) { - var binding, bindings, child, _i, _j, _len, _len1, _ref; - _ref = newNode.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - Batman.propagateBindingEvents(child); - } - if (bindings = Batman._data(newNode, 'bindings')) { - for (_j = 0, _len1 = bindings.length; _j < _len1; _j++) { - binding = bindings[_j]; - Batman.propagateBindingEvent(binding, newNode); - } - } - }, - trackBinding: Batman.trackBinding = function(binding, node) { - var bindings; - if (bindings = Batman._data(node, 'bindings')) { - bindings.push(binding); - } else { - Batman._data(node, 'bindings', [binding]); - } - Batman.DOM.fire('bindingAdded', binding); - Batman.propagateBindingEvent(binding, node); - return true; - }, - onParseExit: Batman.onParseExit = function(node, callback) { - var set; - set = Batman._data(node, 'onParseExit') || Batman._data(node, 'onParseExit', new Batman.SimpleSet); - if (callback != null) { - set.add(callback); - } - return set; - }, - forgetParseExit: Batman.forgetParseExit = function(node, callback) { - return Batman.removeData(node, 'onParseExit', true); - }, - defineView: function(name, node) { - var contents; - contents = node.innerHTML; - Batman.View.store.set(Batman.Navigator.normalizePath(name), contents); - return contents; - }, - setInnerHTML: Batman.setInnerHTML = function(node, html) { - var child, childNodes, result, _i, _j, _len, _len1; - childNodes = (function() { - var _i, _len, _ref, _results; - _ref = node.childNodes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - _results.push(child); - } - return _results; - })(); - for (_i = 0, _len = childNodes.length; _i < _len; _i++) { - child = childNodes[_i]; - Batman.DOM.willRemoveNode(child); - } - result = node.innerHTML = html; - for (_j = 0, _len1 = childNodes.length; _j < _len1; _j++) { - child = childNodes[_j]; - Batman.DOM.didRemoveNode(child); - } - return result; - }, - setStyleProperty: Batman.setStyleProperty = function(node, property, value, importance) { - if (node.style.setAttribute) { - return node.style.setAttribute(property, value, importance); - } else { - return node.style.setProperty(property, value, importance); - } - }, - removeNode: Batman.removeNode = function(node) { - var _ref; - Batman.DOM.willRemoveNode(node); - if ((_ref = node.parentNode) != null) { - _ref.removeChild(node); - } - return Batman.DOM.didRemoveNode(node); - }, - destroyNode: Batman.destroyNode = function(node) { - Batman.DOM.willDestroyNode(node); - Batman.removeNode(node); - return Batman.DOM.didDestroyNode(node); - }, - appendChild: Batman.appendChild = function(parent, child) { - Batman.DOM.willInsertNode(child); - parent.appendChild(child); - return Batman.DOM.didInsertNode(child); - }, - removeOrDestroyNode: Batman.removeOrDestroyNode = function(node) { - var view; - view = Batman._data(node, 'view'); - view || (view = Batman._data(node, 'yielder')); - if ((view != null) && view.get('cached')) { - return Batman.DOM.removeNode(node); - } else { - return Batman.DOM.destroyNode(node); - } - }, - insertBefore: Batman.insertBefore = function(parentNode, newNode, referenceNode) { - if (referenceNode == null) { - referenceNode = null; - } - if (!referenceNode || parentNode.childNodes.length <= 0) { - return Batman.appendChild(parentNode, newNode); - } else { - Batman.DOM.willInsertNode(newNode); - parentNode.insertBefore(newNode, referenceNode); - return Batman.DOM.didInsertNode(newNode); - } - }, - valueForNode: function(node, value, escapeValue) { - var isSetting; - if (value == null) { - value = ''; - } - if (escapeValue == null) { - escapeValue = true; - } - isSetting = arguments.length > 1; - switch (node.nodeName.toUpperCase()) { - case 'INPUT': - case 'TEXTAREA': - if (isSetting) { - return node.value = value; - } else { - return node.value; - } - break; - case 'SELECT': - if (isSetting) { - return node.value = value; - } - break; - default: - if (isSetting) { - return Batman.setInnerHTML(node, escapeValue ? Batman.escapeHTML(value) : value); - } else { - return node.innerHTML; - } - } - }, - nodeIsEditable: function(node) { - var _ref; - return (_ref = node.nodeName.toUpperCase()) === 'INPUT' || _ref === 'TEXTAREA' || _ref === 'SELECT'; - }, - addEventListener: Batman.addEventListener = function(node, eventName, callback) { - var listeners; - if (!(listeners = Batman._data(node, 'listeners'))) { - listeners = Batman._data(node, 'listeners', {}); - } - if (!listeners[eventName]) { - listeners[eventName] = []; - } - listeners[eventName].push(callback); - if (Batman.hasAddEventListener) { - return node.addEventListener(eventName, callback, false); - } else { - return node.attachEvent("on" + eventName, callback); - } - }, - removeEventListener: Batman.removeEventListener = function(node, eventName, callback) { - var eventListeners, index, listeners; - if (listeners = Batman._data(node, 'listeners')) { - if (eventListeners = listeners[eventName]) { - index = eventListeners.indexOf(callback); - if (index !== -1) { - eventListeners.splice(index, 1); - } - } - } - if (Batman.hasAddEventListener) { - return node.removeEventListener(eventName, callback, false); - } else { - return node.detachEvent('on' + eventName, callback); - } - }, - hasAddEventListener: Batman.hasAddEventListener = !!(typeof window !== "undefined" && window !== null ? window.addEventListener : void 0), - preventDefault: Batman.preventDefault = function(e) { - if (typeof e.preventDefault === "function") { - return e.preventDefault(); - } else { - return e.returnValue = false; - } - }, - stopPropagation: Batman.stopPropagation = function(e) { - if (e.stopPropagation) { - return e.stopPropagation(); - } else { - return e.cancelBubble = true; - } - }, - willInsertNode: function(node) { - var child, view, _i, _len, _ref, _ref1; - view = Batman._data(node, 'view'); - if (view != null) { - view.fire('beforeAppear', node); - } - if ((_ref = Batman.data(node, 'show')) != null) { - _ref.call(node); - } - _ref1 = node.childNodes; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - child = _ref1[_i]; - Batman.DOM.willInsertNode(child); - } - return true; - }, - didInsertNode: function(node) { - var child, view, _i, _len, _ref; - view = Batman._data(node, 'view'); - if (view) { - view.fire('appear', node); - view.applyYields(); - } - _ref = node.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - Batman.DOM.didInsertNode(child); - } - return true; - }, - willRemoveNode: function(node) { - var child, view, _i, _len, _ref, _ref1; - view = Batman._data(node, 'view'); - if (view) { - view.fire('beforeDisappear', node); - } - if ((_ref = Batman.data(node, 'hide')) != null) { - _ref.call(node); - } - _ref1 = node.childNodes; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - child = _ref1[_i]; - Batman.DOM.willRemoveNode(child); - } - return true; - }, - didRemoveNode: function(node) { - var child, view, _i, _len, _ref; - view = Batman._data(node, 'view'); - if (view) { - view.retractYields(); - view.fire('disappear', node); - } - _ref = node.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - Batman.DOM.didRemoveNode(child); - } - return true; - }, - willDestroyNode: function(node) { - var child, view, _i, _len, _ref; - view = Batman._data(node, 'view'); - if (view) { - view.fire('beforeDestroy', node); - view.get('yields').forEach(function(name, actions) { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = actions.length; _i < _len; _i++) { - node = actions[_i].node; - _results.push(Batman.DOM.willDestroyNode(node)); - } - return _results; - }); - } - _ref = node.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - Batman.DOM.willDestroyNode(child); - } - return true; - }, - didDestroyNode: function(node) { - var bindings, child, eventListeners, eventName, listeners, view, _i, _len, _ref; - view = Batman._data(node, 'view'); - if (view) { - view.fire('destroy', node); - view.get('yields').forEach(function(name, actions) { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = actions.length; _i < _len; _i++) { - node = actions[_i].node; - _results.push(Batman.DOM.didDestroyNode(node)); - } - return _results; - }); - } - if (bindings = Batman._data(node, 'bindings')) { - bindings.forEach(function(binding) { - return binding.die(); - }); - } - if (listeners = Batman._data(node, 'listeners')) { - for (eventName in listeners) { - eventListeners = listeners[eventName]; - eventListeners.forEach(function(listener) { - return Batman.removeEventListener(node, eventName, listener); - }); - } - } - Batman.removeData(node); - Batman.removeData(node, void 0, true); - _ref = node.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - Batman.DOM.didDestroyNode(child); - } - return true; - } - }; - - Batman.mixin(Batman.DOM, Batman.EventEmitter, Batman.Observable); - - Batman.DOM.event('bindingAdded'); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.DOM.readers = { - target: function(node, key, context, renderer) { - Batman.DOM.readers.bind(node, key, context, renderer, 'nodeChange'); - return true; - }, - source: function(node, key, context, renderer) { - Batman.DOM.readers.bind(node, key, context, renderer, 'dataChange'); - return true; - }, - bind: function(node, key, context, renderer, only) { - var bindingClass; - bindingClass = false; - switch (node.nodeName.toLowerCase()) { - case 'input': - switch (node.getAttribute('type')) { - case 'checkbox': - Batman.DOM.attrReaders.bind(node, 'checked', key, context, renderer, only); - return true; - case 'radio': - bindingClass = Batman.DOM.RadioBinding; - break; - case 'file': - bindingClass = Batman.DOM.FileBinding; - } - break; - case 'select': - bindingClass = Batman.DOM.SelectBinding; - } - bindingClass || (bindingClass = Batman.DOM.Binding); - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(bindingClass, arguments, function(){}); - return true; - }, - context: function(node, key, context, renderer) { - return context.descendWithKey(key); - }, - mixin: function(node, key, context, renderer) { - new Batman.DOM.MixinBinding(node, key, context.descend(Batman.mixins), renderer); - return true; - }, - showif: function(node, key, context, parentRenderer, invert) { - new Batman.DOM.ShowHideBinding(node, key, context, parentRenderer, false, invert); - return true; - }, - hideif: function() { - var _ref; - return (_ref = Batman.DOM.readers).showif.apply(_ref, __slice.call(arguments).concat([true])); - }, - insertif: function(node, key, context, parentRenderer, invert) { - new Batman.DOM.InsertionBinding(node, key, context, parentRenderer, false, invert); - return true; - }, - removeif: function() { - var _ref; - return (_ref = Batman.DOM.readers).insertif.apply(_ref, __slice.call(arguments).concat([true])); - }, - route: function() { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.RouteBinding, arguments, function(){}); - return true; - }, - view: function() { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.ViewBinding, arguments, function(){}); - return false; - }, - partial: function(node, path, context, renderer) { - Batman.DOM.partial(node, path, context, renderer); - return true; - }, - defineview: function(node, name, context, renderer) { - Batman.onParseExit(node, function() { - var _ref; - return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; - }); - Batman.DOM.defineView(name, node); - return false; - }, - renderif: function(node, key, context, renderer) { - new Batman.DOM.DeferredRenderingBinding(node, key, context, renderer); - return false; - }, - "yield": function(node, key) { - Batman.onParseExit(node, function() { - return Batman.DOM.Yield.withName(key).set('containerNode', node); - }); - return true; - }, - contentfor: function(node, key, context, renderer, action) { - if (action == null) { - action = 'append'; - } - Batman.onParseExit(node, function() { - var _ref; - if ((_ref = node.parentNode) != null) { - _ref.removeChild(node); - } - return renderer.view.pushYieldAction(key, action, node); - }); - return true; - }, - replace: function(node, key, context, renderer) { - Batman.DOM.readers.contentfor(node, key, context, renderer, 'replace'); - return true; - } - }; - -}).call(this); - -(function() { - var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Batman.DOM.events = { - click: function(node, callback, context, eventName) { - if (eventName == null) { - eventName = 'click'; - } - Batman.addEventListener(node, eventName, function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - callback.apply(null, [node].concat(__slice.call(args), [context])); - return Batman.preventDefault(args[0]); - }); - if (node.nodeName.toUpperCase() === 'A' && !node.href) { - node.href = '#'; - } - return node; - }, - doubleclick: function(node, callback, context) { - return Batman.DOM.events.click(node, callback, context, 'dblclick'); - }, - change: function(node, callback, context) { - var eventName, eventNames, oldCallback, _i, _len, _results; - eventNames = (function() { - var _ref; - switch (node.nodeName.toUpperCase()) { - case 'TEXTAREA': - return ['input', 'keyup', 'change']; - case 'INPUT': - if (_ref = node.type.toLowerCase(), __indexOf.call(Batman.DOM.textInputTypes, _ref) >= 0) { - oldCallback = callback; - callback = function(node, event) { - if (event.type === 'keyup' && Batman.DOM.events.isEnter(event)) { - return; - } - return oldCallback.apply(null, arguments); - }; - return ['input', 'keyup', 'change']; - } else { - return ['input', 'change']; - } - break; - default: - return ['change']; - } - })(); - _results = []; - for (_i = 0, _len = eventNames.length; _i < _len; _i++) { - eventName = eventNames[_i]; - _results.push(Batman.addEventListener(node, eventName, function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return callback.apply(null, [node].concat(__slice.call(args), [context])); - })); - } - return _results; - }, - isEnter: function(ev) { - var _ref, _ref1; - return ((13 <= (_ref = ev.keyCode) && _ref <= 14)) || ((13 <= (_ref1 = ev.which) && _ref1 <= 14)) || ev.keyIdentifier === 'Enter' || ev.key === 'Enter'; - }, - submit: function(node, callback, context) { - if (Batman.DOM.nodeIsEditable(node)) { - Batman.addEventListener(node, 'keydown', function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (Batman.DOM.events.isEnter(args[0])) { - return Batman.DOM._keyCapturingNode = node; - } - }); - Batman.addEventListener(node, 'keyup', function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (Batman.DOM.events.isEnter(args[0])) { - if (Batman.DOM._keyCapturingNode === node) { - Batman.preventDefault(args[0]); - callback.apply(null, [node].concat(__slice.call(args), [context])); - } - return Batman.DOM._keyCapturingNode = null; - } - }); - } else { - Batman.addEventListener(node, 'submit', function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - Batman.preventDefault(args[0]); - return callback.apply(null, [node].concat(__slice.call(args), [context])); - }); - } - return node; - }, - other: function(node, eventName, callback, context) { - return Batman.addEventListener(node, eventName, function() { - var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return callback.apply(null, [node].concat(__slice.call(args), [context])); - }); - } - }; - -}).call(this); - -(function() { - - Batman.DOM.attrReaders = { - _parseAttribute: function(value) { - if (value === 'false') { - value = false; - } - if (value === 'true') { - value = true; - } - return value; - }, - source: function(node, attr, key, context, renderer) { - return Batman.DOM.attrReaders.bind(node, attr, key, context, renderer, 'dataChange'); - }, - bind: function(node, attr, key, context, renderer, only) { - var bindingClass; - bindingClass = (function() { - switch (attr) { - case 'checked': - case 'disabled': - case 'selected': - return Batman.DOM.CheckedBinding; - case 'value': - case 'href': - case 'src': - case 'size': - return Batman.DOM.NodeAttributeBinding; - case 'class': - return Batman.DOM.ClassBinding; - case 'style': - return Batman.DOM.StyleBinding; - default: - return Batman.DOM.AttributeBinding; - } - })(); - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(bindingClass, arguments, function(){}); - return true; - }, - context: function(node, contextName, key, context) { - return context.descendWithKey(key, contextName); - }, - event: function(node, eventName, key, context) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.EventBinding, arguments, function(){}); - return true; - }, - addclass: function(node, className, key, context, parentRenderer, invert) { - new Batman.DOM.AddClassBinding(node, className, key, context, parentRenderer, false, invert); - return true; - }, - removeclass: function(node, className, key, context, parentRenderer) { - return Batman.DOM.attrReaders.addclass(node, className, key, context, parentRenderer, true); - }, - foreach: function(node, iteratorName, key, context, parentRenderer) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.IteratorBinding, arguments, function(){}); - return false; - }, - formfor: function(node, localName, key, context) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.FormBinding, arguments, function(){}); - return context.descendWithKey(key, localName); - } - }; - -}).call(this); - -(function() { - var BatmanObject, - __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; }, - __slice = [].slice; - - BatmanObject = (function(_super) { - var counter, getAccessorObject, promiseWrapper, wrapSingleAccessor; - - __extends(BatmanObject, _super); - - Batman.initializeObject(BatmanObject); - - Batman.initializeObject(BatmanObject.prototype); - - BatmanObject.classMixin = function() { - return Batman.mixin.apply(Batman, [this].concat(__slice.call(arguments))); - }; - - BatmanObject.mixin = function() { - return this.classMixin.apply(this.prototype, arguments); - }; - - BatmanObject.prototype.mixin = BatmanObject.classMixin; - - counter = 0; - - BatmanObject.prototype._batmanID = function() { - var c; - this._batmanID = function() { - return c; - }; - return c = counter++; - }; - - BatmanObject.prototype.hashKey = function() { - var key; - if (typeof this.isEqual === 'function') { - return; - } - this.hashKey = function() { - return key; - }; - return key = ""; - }; - - BatmanObject.prototype.toJSON = function() { - var key, obj, value; - obj = {}; - for (key in this) { - if (!__hasProp.call(this, key)) continue; - value = this[key]; - if (key !== "_batman" && key !== "hashKey" && key !== "_batmanID") { - obj[key] = (value != null ? value.toJSON : void 0) ? value.toJSON() : value; - } - } - return obj; - }; - - getAccessorObject = function(base, accessor) { - var deprecated, _i, _len, _ref; - if (typeof accessor === 'function') { - accessor = { - get: accessor - }; - } - _ref = ['cachable', 'cacheable']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - deprecated = _ref[_i]; - if (deprecated in accessor) { - Batman.developer.warn("Property accessor option \"" + deprecated + "\" is deprecated. Use \"cache\" instead."); - if (!('cache' in accessor)) { - accessor.cache = accessor[deprecated]; - } - } - } - return accessor; - }; - - promiseWrapper = function(fetcher) { - return function(core) { - return { - get: function(key) { - var deliver, returned, val, - _this = this; - val = core.get.apply(this, arguments); - if (typeof val !== 'undefined') { - return val; - } - returned = false; - deliver = function(err, result) { - if (returned) { - _this.set(key, result); - } - return val = result; - }; - fetcher.call(this, deliver, key); - returned = true; - return val; - }, - cache: true - }; - }; - }; - - wrapSingleAccessor = function(core, wrapper) { - var k, v; - wrapper = (typeof wrapper === "function" ? wrapper(core) : void 0) || wrapper; - for (k in core) { - v = core[k]; - if (!(k in wrapper)) { - wrapper[k] = v; - } - } - return wrapper; - }; - - BatmanObject._defineAccessor = function() { - var accessor, key, keys, _base, _i, _j, _len, _ref, _results; - keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), accessor = arguments[_i++]; - if (!(accessor != null)) { - return Batman.Property.defaultAccessorForBase(this); - } else if (keys.length === 0 && ((_ref = Batman.typeOf(accessor)) !== 'Object' && _ref !== 'Function')) { - return Batman.Property.accessorForBaseAndKey(this, accessor); - } else if (typeof accessor.promise === 'function') { - return this._defineWrapAccessor.apply(this, __slice.call(keys).concat([promiseWrapper(accessor.promise)])); - } - Batman.initializeObject(this); - if (keys.length === 0) { - return this._batman.defaultAccessor = getAccessorObject(this, accessor); - } else { - (_base = this._batman).keyAccessors || (_base.keyAccessors = new Batman.SimpleHash); - _results = []; - for (_j = 0, _len = keys.length; _j < _len; _j++) { - key = keys[_j]; - _results.push(this._batman.keyAccessors.set(key, getAccessorObject(this, accessor))); - } - return _results; - } - }; - - BatmanObject.prototype._defineAccessor = BatmanObject._defineAccessor; - - BatmanObject._defineWrapAccessor = function() { - var key, keys, wrapper, _i, _j, _len, _results; - keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), wrapper = arguments[_i++]; - Batman.initializeObject(this); - if (keys.length === 0) { - return this._defineAccessor(wrapSingleAccessor(this._defineAccessor(), wrapper)); - } else { - _results = []; - for (_j = 0, _len = keys.length; _j < _len; _j++) { - key = keys[_j]; - _results.push(this._defineAccessor(key, wrapSingleAccessor(this._defineAccessor(key), wrapper))); - } - return _results; - } - }; - - BatmanObject.prototype._defineWrapAccessor = BatmanObject._defineWrapAccessor; - - BatmanObject.classAccessor = BatmanObject._defineAccessor; - - BatmanObject.accessor = function() { - var _ref; - return (_ref = this.prototype)._defineAccessor.apply(_ref, arguments); - }; - - BatmanObject.prototype.accessor = BatmanObject._defineAccessor; - - BatmanObject.wrapClassAccessor = BatmanObject._defineWrapAccessor; - - BatmanObject.wrapAccessor = function() { - var _ref; - return (_ref = this.prototype)._defineWrapAccessor.apply(_ref, arguments); - }; - - BatmanObject.prototype.wrapAccessor = BatmanObject._defineWrapAccessor; - - function BatmanObject() { - var mixins; - mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - this._batman = new Batman._Batman(this); - this.mixin.apply(this, mixins); - } - - BatmanObject.classMixin(Batman.EventEmitter, Batman.Observable); - - BatmanObject.mixin(Batman.EventEmitter, Batman.Observable); - - BatmanObject.observeAll = function() { - return this.prototype.observe.apply(this.prototype, arguments); - }; - - BatmanObject.singleton = function(singletonMethodName) { - if (singletonMethodName == null) { - singletonMethodName = "sharedInstance"; - } - return this.classAccessor(singletonMethodName, { - get: function() { - var _name; - return this[_name = "_" + singletonMethodName] || (this[_name] = new this); - } - }); - }; - - BatmanObject.accessor('_batmanID', function() { - return this._batmanID(); - }); - - return BatmanObject; - - })(Object); - - Batman.Object = BatmanObject; - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.Renderer = (function(_super) { - var bindingRegexp, bindingSortOrder, bindingSortPositions, k, name, pos, _i, _j, _len, _len1, _ref; - - __extends(Renderer, _super); - - Renderer.prototype.deferEvery = 50; - - function Renderer(node, context, view) { - this.node = node; - this.context = context; - this.view = view; - this.resume = __bind(this.resume, this); - - this.start = __bind(this.start, this); - - Renderer.__super__.constructor.call(this); - if (!(this.context instanceof Batman.RenderContext)) { - Batman.developer.error("Must pass a RenderContext to a renderer for rendering"); - } - this.immediate = Batman.setImmediate(this.start); - } - - Renderer.prototype.start = function() { - this.startTime = new Date; - return this.parseNode(this.node); - }; - - Renderer.prototype.resume = function() { - this.startTime = new Date; - return this.parseNode(this.resumeNode); - }; - - Renderer.prototype.finish = function() { - this.startTime = null; - this.prevent('stopped'); - this.fire('parsed'); - return this.fire('rendered'); - }; - - Renderer.prototype.stop = function() { - Batman.clearImmediate(this.immediate); - return this.fire('stopped'); - }; - - _ref = ['parsed', 'rendered', 'stopped']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - Renderer.prototype.event(k).oneShot = true; - } - - bindingRegexp = /^data\-(.*)/; - - bindingSortOrder = ["view", "renderif", "foreach", "formfor", "context", "bind", "source", "target"]; - - bindingSortPositions = {}; - - for (pos = _j = 0, _len1 = bindingSortOrder.length; _j < _len1; pos = ++_j) { - name = bindingSortOrder[pos]; - bindingSortPositions[name] = pos; - } - - Renderer.prototype._sortBindings = function(a, b) { - var aindex, bindex; - aindex = bindingSortPositions[a[0]]; - bindex = bindingSortPositions[b[0]]; - if (aindex == null) { - aindex = bindingSortOrder.length; - } - if (bindex == null) { - bindex = bindingSortOrder.length; - } - if (aindex > bindex) { - return 1; - } else if (bindex > aindex) { - return -1; - } else if (a[0] > b[0]) { - return 1; - } else if (b[0] > a[0]) { - return -1; - } else { - return 0; - } - }; - - Renderer.prototype.parseNode = function(node) { - var argument, attribute, bindings, keypath, names, nextNode, oldContext, result, skipChildren, _base, _base1, _k, _l, _len2, _len3, _ref1, _ref2, _ref3, _ref4, - _this = this; - if (this.deferEvery && (new Date - this.startTime) > this.deferEvery) { - this.resumeNode = node; - this.timeout = Batman.setImmediate(this.resume); - return; - } - if (node.getAttribute && node.attributes) { - bindings = []; - _ref1 = node.attributes; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - attribute = _ref1[_k]; - name = (_ref2 = attribute.nodeName.match(bindingRegexp)) != null ? _ref2[1] : void 0; - if (!name) { - continue; - } - bindings.push((names = name.split('-')).length > 1 ? [names[0], names.slice(1, names.length + 1 || 9e9).join('-'), attribute.value] : [name, void 0, attribute.value]); - } - _ref3 = bindings.sort(this._sortBindings); - for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { - _ref4 = _ref3[_l], name = _ref4[0], argument = _ref4[1], keypath = _ref4[2]; - result = argument ? typeof (_base = Batman.DOM.attrReaders)[name] === "function" ? _base[name](node, argument, keypath, this.context, this) : void 0 : typeof (_base1 = Batman.DOM.readers)[name] === "function" ? _base1[name](node, keypath, this.context, this) : void 0; - if (result === false) { - skipChildren = true; - break; - } else if (result instanceof Batman.RenderContext) { - oldContext = this.context; - this.context = result; - Batman.onParseExit(node, function() { - return _this.context = oldContext; - }); - } - } - } - if ((nextNode = this.nextNode(node, skipChildren))) { - return this.parseNode(nextNode); - } else { - return this.finish(); - } - }; - - Renderer.prototype.nextNode = function(node, skipChildren) { - var children, nextParent, parentSibling, sibling, _ref1, _ref2; - if (!skipChildren) { - children = node.childNodes; - if (children != null ? children.length : void 0) { - return children[0]; - } - } - sibling = node.nextSibling; - if ((_ref1 = Batman.onParseExit(node)) != null) { - _ref1.forEach(function(callback) { - return callback(); - }); - } - Batman.forgetParseExit(node); - if (this.node === node) { - return; - } - if (sibling) { - return sibling; - } - nextParent = node; - while (nextParent = nextParent.parentNode) { - parentSibling = nextParent.nextSibling; - if ((_ref2 = Batman.onParseExit(nextParent)) != null) { - _ref2.forEach(function(callback) { - return callback(); - }); - } - Batman.forgetParseExit(nextParent); - if (this.node === nextParent) { - return; - } - if (parentSibling) { - return parentSibling; - } - } - }; - - return Renderer; - - })(Batman.Object); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.DOM.AbstractBinding = (function(_super) { - var get_dot_rx, get_rx, keypath_rx; - - __extends(AbstractBinding, _super); - - keypath_rx = /(^|,)\s*(?:(true|false)|("[^"]*")|(\{[^\}]*\})|([a-zA-Z][\w\-\.]*[\?\!]?))\s*(?=$|,)/g; - - get_dot_rx = /(?:\]\.)(.+?)(?=[\[\.]|\s*\||$)/; - - get_rx = /(?!^\s*)\[(.*?)\]/g; - - AbstractBinding.accessor('filteredValue', { - get: function() { - var renderContext, result, self, unfilteredValue; - unfilteredValue = this.get('unfilteredValue'); - self = this; - renderContext = this.get('renderContext'); - if (this.filterFunctions.length > 0) { - Batman.developer.currentFilterStack = renderContext; - result = this.filterFunctions.reduce(function(value, fn, i) { - var args; - args = self.filterArguments[i].map(function(argument) { - if (argument._keypath) { - return self.renderContext.get(argument._keypath); - } else { - return argument; - } - }); - args.unshift(value); - while (args.length < (fn.length - 1)) { - args.push(void 0); - } - args.push(self); - return fn.apply(renderContext, args); - }, unfilteredValue); - Batman.developer.currentFilterStack = null; - return result; - } else { - return unfilteredValue; - } - }, - set: function(_, newValue) { - return this.set('unfilteredValue', newValue); - } - }); - - AbstractBinding.accessor('unfilteredValue', { - get: function() { - var k; - if (k = this.get('key')) { - return Batman.RenderContext.deProxy(Batman.getPath(this, ['keyContext', k])); - } else { - return this.get('value'); - } - }, - set: function(_, value) { - var k, keyContext, prop; - if (k = this.get('key')) { - keyContext = this.get('keyContext'); - if (keyContext && keyContext !== Batman.container) { - prop = Batman.Property.forBaseAndKey(keyContext, k); - return prop.setValue(value); - } - } else { - return this.set('value', value); - } - } - }); - - AbstractBinding.accessor('keyContext', function() { - return this.renderContext.contextForKey(this.key); - }); - - AbstractBinding.prototype.bindImmediately = true; - - AbstractBinding.prototype.shouldSet = true; - - AbstractBinding.prototype.isInputBinding = false; - - AbstractBinding.prototype.escapeValue = true; - - function AbstractBinding(node, keyPath, renderContext, renderer, only) { - this.node = node; - this.keyPath = keyPath; - this.renderContext = renderContext; - this.renderer = renderer; - this.only = only != null ? only : false; - this._fireDataChange = __bind(this._fireDataChange, this); - - this._fireNodeChange = __bind(this._fireNodeChange, this); - - this.parseFilter(); - if (this.bindImmediately) { - this.bind(); - } - } - - AbstractBinding.prototype.isTwoWay = function() { - return (this.key != null) && this.filterFunctions.length === 0; - }; - - AbstractBinding.prototype.bind = function() { - var _ref, _ref1; - if ((this.node != null) && ((_ref = this.only) === false || _ref === 'nodeChange') && Batman.DOM.nodeIsEditable(this.node)) { - Batman.DOM.events.change(this.node, this._fireNodeChange); - if (this.only === 'nodeChange') { - this._fireNodeChange(); - } - } - if ((_ref1 = this.only) === false || _ref1 === 'dataChange') { - this.observeAndFire('filteredValue', this._fireDataChange); - } - if (this.node != null) { - return Batman.DOM.trackBinding(this, this.node); - } - }; - - AbstractBinding.prototype._fireNodeChange = function(event) { - var val; - this.shouldSet = false; - val = this.value || this.get('keyContext'); - if (typeof this.nodeChange === "function") { - this.nodeChange(this.node, val, event); - } - this.fire('nodeChange', this.node, val); - return this.shouldSet = true; - }; - - AbstractBinding.prototype._fireDataChange = function(value) { - if (this.shouldSet) { - if (typeof this.dataChange === "function") { - this.dataChange(value, this.node); - } - return this.fire('dataChange', value, this.node); - } - }; - - AbstractBinding.prototype.die = function() { - var _ref; - this.forget(); - if ((_ref = this._batman.properties) != null) { - _ref.forEach(function(key, property) { - return property.die(); - }); - } - this.fire('die'); - this.dead = true; - return true; - }; - - AbstractBinding.prototype.parseFilter = function() { - var args, filter, filterName, filterString, filters, key, keyPath, orig, split; - this.filterFunctions = []; - this.filterArguments = []; - keyPath = this.keyPath; - while (get_dot_rx.test(keyPath)) { - keyPath = keyPath.replace(get_dot_rx, "]['$1']"); - } - filters = keyPath.replace(get_rx, " | get $1 ").replace(/'/g, '"').split(/(?!")\s+\|\s+(?!")/); - try { - key = this.parseSegment(orig = filters.shift())[0]; - } catch (e) { - Batman.developer.warn(e); - Batman.developer.error("Error! Couldn't parse keypath in \"" + orig + "\". Parsing error above."); - } - if (key && key._keypath) { - this.key = key._keypath; - } else { - this.value = key; - } - if (filters.length) { - while (filterString = filters.shift()) { - split = filterString.indexOf(' '); - if (split === -1) { - split = filterString.length; - } - filterName = filterString.substr(0, split); - args = filterString.substr(split); - if (!(filter = Batman.Filters[filterName])) { - return Batman.developer.error("Unrecognized filter '" + filterName + "' in key \"" + this.keyPath + "\"!"); - } - this.filterFunctions.push(filter); - try { - this.filterArguments.push(this.parseSegment(args)); - } catch (e) { - Batman.developer.error("Bad filter arguments \"" + args + "\"!"); - } - } - return true; - } - }; - - AbstractBinding.prototype.parseSegment = function(segment) { - segment = segment.replace(keypath_rx, function(match, start, bool, string, object, keypath, offset) { - var replacement; - if (start == null) { - start = ''; - } - replacement = keypath ? '{"_keypath": "' + keypath + '"}' : bool || string || object; - return start + replacement; - }); - return JSON.parse("[" + segment + "]"); - }; - - return AbstractBinding; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.ViewBinding = (function(_super) { - - __extends(ViewBinding, _super); - - function ViewBinding() { - ViewBinding.__super__.constructor.apply(this, arguments); - this.renderer.prevent('rendered'); - this.node.removeAttribute('data-view'); - } - - ViewBinding.prototype.dataChange = function(viewClassOrInstance) { - var _this = this; - if (viewClassOrInstance == null) { - return; - } - if (viewClassOrInstance.isView) { - this.view = viewClassOrInstance; - this.view.set('context', this.renderContext); - this.view.set('node', this.node); - } else { - this.view = new viewClassOrInstance({ - node: this.node, - context: this.renderContext, - parentView: this.renderer.view - }); - } - this.view.on('ready', function() { - return _this.renderer.allowAndFire('rendered'); - }); - return this.die(); - }; - - return ViewBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.ViewArgumentBinding = (function(_super) { - - __extends(ViewArgumentBinding, _super); - - function ViewArgumentBinding() { - return ViewArgumentBinding.__super__.constructor.apply(this, arguments); - } - - return ViewArgumentBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.ShowHideBinding = (function(_super) { - - __extends(ShowHideBinding, _super); - - function ShowHideBinding(node, className, key, context, parentRenderer, invert) { - var display; - this.invert = invert != null ? invert : false; - display = node.style.display; - if (!display || display === 'none') { - display = ''; - } - this.originalDisplay = display; - ShowHideBinding.__super__.constructor.apply(this, arguments); - } - - ShowHideBinding.prototype.dataChange = function(value) { - var hide, view, _ref; - view = Batman._data(this.node, 'view'); - if (!!value === !this.invert) { - if (view != null) { - view.fire('beforeAppear', this.node); - } - if ((_ref = Batman.data(this.node, 'show')) != null) { - _ref.call(this.node); - } - this.node.style.display = this.originalDisplay; - return view != null ? view.fire('appear', this.node) : void 0; - } else { - if (view != null) { - view.fire('beforeDisappear', this.node); - } - if (typeof (hide = Batman.data(this.node, 'hide')) === 'function') { - hide.call(this.node); - } else { - Batman.setStyleProperty(this.node, 'display', 'none', 'important'); - } - return view != null ? view.fire('disappear', this.node) : void 0; - } - }; - - return ShowHideBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.DOM.SelectBinding = (function(_super) { - - __extends(SelectBinding, _super); - - SelectBinding.prototype.isInputBinding = true; - - SelectBinding.prototype.firstBind = true; - - function SelectBinding() { - this.updateOptionBindings = __bind(this.updateOptionBindings, this); - - this.nodeChange = __bind(this.nodeChange, this); - - this.dataChange = __bind(this.dataChange, this); - - this.childBindingAdded = __bind(this.childBindingAdded, this); - this.selectedBindings = new Batman.SimpleSet; - SelectBinding.__super__.constructor.apply(this, arguments); - } - - SelectBinding.prototype.childBindingAdded = function(binding) { - var dataChangeHandler, - _this = this; - if (binding instanceof Batman.DOM.CheckedBinding) { - binding.on('dataChange', dataChangeHandler = function() { - return _this.nodeChange(); - }); - binding.on('die', function() { - binding.forget('dataChange', dataChangeHandler); - return _this.selectedBindings.remove(binding); - }); - this.selectedBindings.add(binding); - } else if (binding instanceof Batman.DOM.IteratorBinding) { - binding.on('nodeAdded', dataChangeHandler = function() { - return _this._fireDataChange(_this.get('filteredValue')); - }); - binding.on('nodeRemoved', dataChangeHandler); - binding.on('die', function() { - binding.forget('nodeAdded', dataChangeHandler); - return binding.forget('nodeRemoved', dataChangeHandler); - }); - } else { - return; - } - return this._fireDataChange(this.get('filteredValue')); - }; - - SelectBinding.prototype.dataChange = function(newValue) { - var child, matches, valueToChild, _i, _len, _name, _ref, - _this = this; - if (newValue != null ? newValue.forEach : void 0) { - valueToChild = {}; - _ref = this.node.children; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - child.selected = false; - matches = valueToChild[_name = child.value] || (valueToChild[_name] = []); - matches.push(child); - } - newValue.forEach(function(value) { - var children, node, _j, _len1, _results; - if (children = valueToChild[value]) { - _results = []; - for (_j = 0, _len1 = children.length; _j < _len1; _j++) { - node = children[_j]; - _results.push(node.selected = true); - } - return _results; - } - }); - } else { - if (typeof newValue === 'undefined' && this.firstBind) { - this.set('unfilteredValue', this.node.value); - } else { - Batman.DOM.valueForNode(this.node, newValue, this.escapeValue); - } - this.firstBind = false; - } - this.updateOptionBindings(); - }; - - SelectBinding.prototype.nodeChange = function() { - var c, selections; - if (this.isTwoWay()) { - selections = this.node.multiple ? (function() { - var _i, _len, _ref, _results; - _ref = this.node.children; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - c = _ref[_i]; - if (c.selected) { - _results.push(c.value); - } - } - return _results; - }).call(this) : this.node.value; - if (typeof selections === Array && selections.length === 1) { - selections = selections[0]; - } - this.set('unfilteredValue', selections); - this.updateOptionBindings(); - } - }; - - SelectBinding.prototype.updateOptionBindings = function() { - return this.selectedBindings.forEach(function(binding) { - return binding._fireNodeChange(); - }); - }; - - return SelectBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.RouteBinding = (function(_super) { - - __extends(RouteBinding, _super); - - function RouteBinding() { - return RouteBinding.__super__.constructor.apply(this, arguments); - } - - RouteBinding.prototype.onATag = false; - - RouteBinding.accessor('dispatcher', function() { - return this.renderContext.get('dispatcher') || Batman.App.get('current.dispatcher'); - }); - - RouteBinding.prototype.bind = function() { - var _this = this; - if (this.node.nodeName.toUpperCase() === 'A') { - this.onATag = true; - } - RouteBinding.__super__.bind.apply(this, arguments); - return Batman.DOM.events.click(this.node, function(node, event) { - var params; - if (event.__batmanActionTaken) { - return; - } - event.__batmanActionTaken = true; - params = _this.pathFromValue(_this.get('filteredValue')); - if (params != null) { - return Batman.redirect(params); - } - }); - }; - - RouteBinding.prototype.dataChange = function(value) { - var path; - if (value != null) { - path = this.pathFromValue(value); - } - if (this.onATag) { - if ((path != null) && (Batman.navigator != null)) { - path = Batman.navigator.linkTo(path); - } else { - path = "#"; - } - return this.node.href = path; - } - }; - - RouteBinding.prototype.pathFromValue = function(value) { - var _ref; - if (value != null) { - if (value.isNamedRouteQuery) { - return value.get('path'); - } else { - return (_ref = this.get('dispatcher')) != null ? _ref.pathFromParams(value) : void 0; - } - } - }; - - return RouteBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.RadioBinding = (function(_super) { - - __extends(RadioBinding, _super); - - function RadioBinding() { - return RadioBinding.__super__.constructor.apply(this, arguments); - } - - RadioBinding.accessor('parsedNodeValue', function() { - return Batman.DOM.attrReaders._parseAttribute(this.node.value); - }); - - RadioBinding.prototype.firstBind = true; - - RadioBinding.prototype.dataChange = function(value) { - var boundValue; - boundValue = this.get('filteredValue'); - if (boundValue != null) { - this.node.checked = boundValue === Batman.DOM.attrReaders._parseAttribute(this.node.value); - } else { - if (this.firstBind && this.node.checked) { - this.set('filteredValue', this.get('parsedNodeValue')); - } - } - return this.firstBind = false; - }; - - RadioBinding.prototype.nodeChange = function(node) { - if (this.isTwoWay()) { - return this.set('filteredValue', this.get('parsedNodeValue')); - } - }; - - return RadioBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.MixinBinding = (function(_super) { - - __extends(MixinBinding, _super); - - function MixinBinding() { - return MixinBinding.__super__.constructor.apply(this, arguments); - } - - MixinBinding.prototype.dataChange = function(value) { - if (value != null) { - return Batman.mixin(this.node, value); - } - }; - - return MixinBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.FileBinding = (function(_super) { - - __extends(FileBinding, _super); - - function FileBinding() { - return FileBinding.__super__.constructor.apply(this, arguments); - } - - FileBinding.prototype.isInputBinding = true; - - FileBinding.prototype.nodeChange = function(node, subContext) { - if (!this.isTwoWay()) { - return; - } - if (node.hasAttribute('multiple')) { - return this.set('filteredValue', Array.prototype.slice.call(node.files)); - } else { - return this.set('filteredValue', node.files[0]); - } - }; - - return FileBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.DeferredRenderingBinding = (function(_super) { - - __extends(DeferredRenderingBinding, _super); - - DeferredRenderingBinding.prototype.rendered = false; - - function DeferredRenderingBinding() { - DeferredRenderingBinding.__super__.constructor.apply(this, arguments); - this.node.removeAttribute("data-renderif"); - } - - DeferredRenderingBinding.prototype.nodeChange = function() {}; - - DeferredRenderingBinding.prototype.dataChange = function(value) { - if (value && !this.rendered) { - return this.render(); - } - }; - - DeferredRenderingBinding.prototype.render = function() { - new Batman.Renderer(this.node, this.renderContext, this.renderer.view); - return this.rendered = true; - }; - - return DeferredRenderingBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.Binding = (function(_super) { - - __extends(Binding, _super); - - function Binding(node) { - var _ref; - this.isInputBinding = (_ref = node.nodeName.toLowerCase()) === 'input' || _ref === 'textarea'; - Binding.__super__.constructor.apply(this, arguments); - } - - Binding.prototype.nodeChange = function(node, context) { - if (this.isTwoWay()) { - return this.set('filteredValue', this.node.value); - } - }; - - Binding.prototype.dataChange = function(value, node) { - return Batman.DOM.valueForNode(this.node, value, this.escapeValue); - }; - - return Binding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.DOM.AbstractAttributeBinding = (function(_super) { - - __extends(AbstractAttributeBinding, _super); - - function AbstractAttributeBinding() { - var args, attributeName, node; - node = arguments[0], attributeName = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - this.attributeName = attributeName; - AbstractAttributeBinding.__super__.constructor.apply(this, [node].concat(__slice.call(args))); - } - - return AbstractAttributeBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.DOM.FormBinding = (function(_super) { - - __extends(FormBinding, _super); - - FormBinding.current = null; - - FormBinding.prototype.errorClass = 'error'; - - FormBinding.prototype.defaultErrorsListSelector = 'div.errors'; - - FormBinding.accessor('errorsListSelector', function() { - return this.get('node').getAttribute('data-errors-list') || this.defaultErrorsListSelector; - }); - - function FormBinding(node, contextName, keyPath, renderContext, renderer, only) { - this.childBindingAdded = __bind(this.childBindingAdded, this); - FormBinding.__super__.constructor.apply(this, arguments); - this.contextName = contextName; - delete this.attributeName; - Batman.DOM.events.submit(this.get('node'), function(node, e) { - return Batman.preventDefault(e); - }); - this.setupErrorsList(); - } - - FormBinding.prototype.childBindingAdded = function(binding) { - var field, index, node; - if (binding.isInputBinding && Batman.isChildOf(this.get('node'), binding.get('node'))) { - if (~(index = binding.get('key').indexOf(this.contextName))) { - node = binding.get('node'); - field = binding.get('key').slice(index + this.contextName.length + 1); - return new Batman.DOM.AddClassBinding(node, this.errorClass, this.get('keyPath') + (" | get 'errors." + field + ".length'"), this.renderContext, this.renderer); - } - } - }; - - FormBinding.prototype.setupErrorsList = function() { - if (this.errorsListNode = Batman.DOM.querySelector(this.get('node'), this.get('errorsListSelector'))) { - Batman.setInnerHTML(this.errorsListNode, this.errorsListHTML()); - if (!this.errorsListNode.getAttribute('data-showif')) { - return this.errorsListNode.setAttribute('data-showif', "" + this.contextName + ".errors.length"); - } - } - }; - - FormBinding.prototype.errorsListHTML = function() { - return "
      \n
    • \n
    "; - }; - - return FormBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.EventBinding = (function(_super) { - - __extends(EventBinding, _super); - - EventBinding.prototype.bindImmediately = false; - - function EventBinding(node, eventName, key, context) { - var attacher, callback, confirmText, - _this = this; - EventBinding.__super__.constructor.apply(this, arguments); - confirmText = this.node.getAttribute('data-confirm'); - callback = function() { - var _ref; - if (confirmText && !confirm(confirmText)) { - return; - } - return (_ref = _this.get('filteredValue')) != null ? _ref.apply(_this.get('callbackContext'), arguments) : void 0; - }; - if (attacher = Batman.DOM.events[this.attributeName]) { - attacher(this.node, callback, context); - } else { - Batman.DOM.events.other(this.node, this.attributeName, callback, context); - } - this.bind(); - } - - EventBinding.accessor('callbackContext', function() { - var contextKeySegments; - contextKeySegments = this.key.split('.'); - contextKeySegments.pop(); - if (contextKeySegments.length > 0) { - return this.get('keyContext').get(contextKeySegments.join('.')); - } else { - return this.get('keyContext'); - } - }); - - EventBinding.wrapAccessor('unfilteredValue', function(core) { - return { - get: function() { - var functionKey, k, keyContext, keys; - if (k = this.get('key')) { - keys = k.split('.'); - if (keys.length > 1) { - functionKey = keys.pop(); - keyContext = Batman.getPath(this, ['keyContext'].concat(keys)); - if (keyContext != null) { - keyContext = Batman.RenderContext.deProxy(keyContext); - return keyContext[functionKey]; - } - } - } - return core.get.apply(this, arguments); - } - }; - }); - - return EventBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.NodeAttributeBinding = (function(_super) { - - __extends(NodeAttributeBinding, _super); - - function NodeAttributeBinding() { - return NodeAttributeBinding.__super__.constructor.apply(this, arguments); - } - - NodeAttributeBinding.prototype.dataChange = function(value) { - if (value == null) { - value = ""; - } - return this.node[this.attributeName] = value; - }; - - NodeAttributeBinding.prototype.nodeChange = function(node) { - if (this.isTwoWay()) { - return this.set('filteredValue', Batman.DOM.attrReaders._parseAttribute(node[this.attributeName])); - } - }; - - return NodeAttributeBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.CheckedBinding = (function(_super) { - - __extends(CheckedBinding, _super); - - function CheckedBinding() { - return CheckedBinding.__super__.constructor.apply(this, arguments); - } - - CheckedBinding.prototype.isInputBinding = true; - - CheckedBinding.prototype.dataChange = function(value) { - return this.node[this.attributeName] = !!value; - }; - - return CheckedBinding; - - })(Batman.DOM.NodeAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.AttributeBinding = (function(_super) { - - __extends(AttributeBinding, _super); - - function AttributeBinding() { - return AttributeBinding.__super__.constructor.apply(this, arguments); - } - - AttributeBinding.prototype.dataChange = function(value) { - return this.node.setAttribute(this.attributeName, value); - }; - - AttributeBinding.prototype.nodeChange = function(node) { - if (this.isTwoWay()) { - return this.set('filteredValue', Batman.DOM.attrReaders._parseAttribute(node.getAttribute(this.attributeName))); - } - }; - - return AttributeBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.AddClassBinding = (function(_super) { - - __extends(AddClassBinding, _super); - - function AddClassBinding(node, className, keyPath, renderContext, renderer, only, invert) { - var name, names; - this.invert = invert != null ? invert : false; - names = className.split('|'); - this.classes = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = names.length; _i < _len; _i++) { - name = names[_i]; - _results.push({ - name: name, - pattern: new RegExp("(?:^|\\s)" + name + "(?:$|\\s)", 'i') - }); - } - return _results; - })(); - AddClassBinding.__super__.constructor.apply(this, arguments); - delete this.attributeName; - } - - AddClassBinding.prototype.dataChange = function(value) { - var currentName, includesClassName, name, pattern, _i, _len, _ref, _ref1; - currentName = this.node.className; - _ref = this.classes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], name = _ref1.name, pattern = _ref1.pattern; - includesClassName = pattern.test(currentName); - if (!!value === !this.invert) { - if (!includesClassName) { - this.node.className = "" + currentName + " " + name; - } - } else { - if (includesClassName) { - this.node.className = currentName.replace(pattern, ' '); - } - } - } - return true; - }; - - return AddClassBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.AbstractCollectionBinding = (function(_super) { - - __extends(AbstractCollectionBinding, _super); - - function AbstractCollectionBinding() { - return AbstractCollectionBinding.__super__.constructor.apply(this, arguments); - } - - AbstractCollectionBinding.prototype.bindCollection = function(newCollection) { - var _ref; - if (newCollection instanceof Batman.Hash) { - newCollection = newCollection.meta; - } - if (newCollection === this.collection) { - return true; - } else { - this.unbindCollection(); - this.collection = newCollection; - if ((_ref = this.collection) != null ? _ref.isObservable : void 0) { - this.collection.observeAndFire('toArray', this.handleArrayChanged); - return true; - } - } - return false; - }; - - AbstractCollectionBinding.prototype.unbindCollection = function() { - var _ref; - if ((_ref = this.collection) != null ? _ref.isObservable : void 0) { - return this.collection.forget('toArray', this.handleArrayChanged); - } - }; - - AbstractCollectionBinding.prototype.handleArrayChanged = function() {}; - - AbstractCollectionBinding.prototype.die = function() { - this.unbindCollection(); - return AbstractCollectionBinding.__super__.die.apply(this, arguments); - }; - - return AbstractCollectionBinding; - - })(Batman.DOM.AbstractAttributeBinding); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }, - __slice = [].slice; - - Batman.DOM.StyleBinding = (function(_super) { - - __extends(StyleBinding, _super); - - StyleBinding.SingleStyleBinding = (function(_super1) { - - __extends(SingleStyleBinding, _super1); - - SingleStyleBinding.prototype.isTwoWay = function() { - return false; - }; - - function SingleStyleBinding() { - var args, parent, _i; - args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), parent = arguments[_i++]; - this.parent = parent; - SingleStyleBinding.__super__.constructor.apply(this, args); - } - - SingleStyleBinding.prototype.dataChange = function(value) { - return this.parent.setStyle(this.attributeName, value); - }; - - return SingleStyleBinding; - - })(Batman.DOM.AbstractAttributeBinding); - - function StyleBinding() { - this.setStyle = __bind(this.setStyle, this); - - this.handleArrayChanged = __bind(this.handleArrayChanged, this); - this.oldStyles = {}; - this.styleBindings = {}; - StyleBinding.__super__.constructor.apply(this, arguments); - } - - StyleBinding.prototype.dataChange = function(value) { - var colonSplitCSSValues, cssName, key, style, _i, _len, _ref, _ref1, _results; - if (!value) { - this.resetStyles(); - return; - } - this.unbindCollection(); - if (typeof value === 'string') { - this.resetStyles(); - _ref = value.split(';'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - style = _ref[_i]; - _ref1 = style.split(":"), cssName = _ref1[0], colonSplitCSSValues = 2 <= _ref1.length ? __slice.call(_ref1, 1) : []; - this.setStyle(cssName, colonSplitCSSValues.join(":")); - } - return; - } - if (value instanceof Batman.Hash) { - return this.bindCollection(value); - } else { - if (value instanceof Batman.Object) { - value = value.toJSON(); - } - this.resetStyles(); - _results = []; - for (key in value) { - if (!__hasProp.call(value, key)) continue; - _results.push(this.bindSingleAttribute(key, "" + this.keyPath + "." + key)); - } - return _results; - } - }; - - StyleBinding.prototype.handleArrayChanged = function(array) { - var _this = this; - return this.collection.forEach(function(key, value) { - return _this.bindSingleAttribute(key, "" + _this.keyPath + "." + key); - }); - }; - - StyleBinding.prototype.bindSingleAttribute = function(attr, keyPath) { - return this.styleBindings[attr] = new this.constructor.SingleStyleBinding(this.node, attr, keyPath, this.renderContext, this.renderer, this.only, this); - }; - - StyleBinding.prototype.setStyle = function(key, value) { - key = Batman.helpers.camelize(key.trim(), true); - if (this.oldStyles[key] == null) { - this.oldStyles[key] = this.node.style[key] || ""; - } - if (value != null ? value.trim : void 0) { - value = value.trim(); - } - if (value == null) { - value = ""; - } - return this.node.style[key] = value; - }; - - StyleBinding.prototype.resetStyles = function() { - var cssName, cssValue, _ref, _results; - _ref = this.oldStyles; - _results = []; - for (cssName in _ref) { - if (!__hasProp.call(_ref, cssName)) continue; - cssValue = _ref[cssName]; - _results.push(this.setStyle(cssName, cssValue)); - } - return _results; - }; - - StyleBinding.prototype.resetBindings = function() { - var attribute, binding, _ref; - _ref = this.styleBindings; - for (attribute in _ref) { - binding = _ref[attribute]; - binding._fireDataChange(''); - binding.die(); - } - return this.styleBindings = {}; - }; - - StyleBinding.prototype.unbindCollection = function() { - this.resetBindings(); - return StyleBinding.__super__.unbindCollection.apply(this, arguments); - }; - - return StyleBinding; - - })(Batman.DOM.AbstractCollectionBinding); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.DOM.IteratorBinding = (function(_super) { - - __extends(IteratorBinding, _super); - - IteratorBinding.prototype.currentActionNumber = 0; - - IteratorBinding.prototype.queuedActionNumber = 0; - - IteratorBinding.prototype.bindImmediately = false; - - function IteratorBinding(sourceNode, iteratorName, key, context, parentRenderer) { - var previousSiblingNode, - _this = this; - this.iteratorName = iteratorName; - this.key = key; - this.context = context; - this.parentRenderer = parentRenderer; - this.handleArrayChanged = __bind(this.handleArrayChanged, this); - - this.nodeMap = new Batman.SimpleHash; - this.rendererMap = new Batman.SimpleHash; - this.fragment = document.createDocumentFragment(); - this.prototypeNode = sourceNode.cloneNode(true); - this.prototypeNode.removeAttribute("data-foreach-" + this.iteratorName); - previousSiblingNode = sourceNode.nextSibling; - this.startNode = document.createComment("start " + this.iteratorName + "-" + (this.get('_batmanID'))); - this.endNode = document.createComment("end " + this.iteratorName + "-" + (this.get('_batmanID'))); - this.endNode[Batman.expando] = sourceNode[Batman.expando]; - if (Batman.canDeleteExpando) { - delete sourceNode[Batman.expando]; - } - Batman.insertBefore(sourceNode.parentNode, this.startNode, previousSiblingNode); - Batman.insertBefore(sourceNode.parentNode, this.endNode, previousSiblingNode); - this.parentRenderer.prevent('rendered'); - Batman.DOM.onParseExit(sourceNode.parentNode, function() { - Batman.destroyNode(sourceNode); - _this.bind(); - return _this.parentRenderer.allowAndFire('rendered'); - }); - IteratorBinding.__super__.constructor.call(this, this.endNode, this.iteratorName, this.key, this.context, this.parentRenderer); - } - - IteratorBinding.prototype.parentNode = function() { - return this.endNode.parentNode; - }; - - IteratorBinding.prototype.die = function() { - this.dead = true; - return IteratorBinding.__super__.die.apply(this, arguments); - }; - - IteratorBinding.prototype.dataChange = function(collection) { - var items, _items; - if (collection != null) { - if (!this.bindCollection(collection)) { - items = (collection != null ? collection.forEach : void 0) ? (_items = [], collection.forEach(function(item) { - return _items.push(item); - }), _items) : Object.keys(collection); - return this.handleArrayChanged(items); - } - } else { - return this.handleArrayChanged([]); - } - }; - - IteratorBinding.prototype.handleArrayChanged = function(newItems) { - var existingNode, index, newItem, node, nodeAtIndex, parentNode, startIndex, unseenNodeMap, _i, _len, - _this = this; - parentNode = this.parentNode(); - startIndex = this._getStartNodeIndex() + 1; - unseenNodeMap = this.nodeMap.merge(); - for (index = _i = 0, _len = newItems.length; _i < _len; index = ++_i) { - newItem = newItems[index]; - nodeAtIndex = parentNode.childNodes[startIndex + index]; - if ((nodeAtIndex != null) && this._itemForNode(nodeAtIndex) === newItem) { - unseenNodeMap.unset(newItem); - continue; - } else { - node = (existingNode = this.nodeMap.get(newItem)) ? (unseenNodeMap.unset(newItem), existingNode) : this._newNodeForItem(newItem); - Batman.insertBefore(this.parentNode(), node, nodeAtIndex); - } - } - unseenNodeMap.forEach(function(item, node) { - return _this._removeItem(item); - }); - }; - - IteratorBinding.prototype._itemForNode = function(node) { - return Batman._data(node, "" + this.iteratorName + "Item"); - }; - - IteratorBinding.prototype._newNodeForItem = function(newItem) { - var newNode, renderer, - _this = this; - newNode = this.prototypeNode.cloneNode(true); - Batman._data(newNode, "" + this.iteratorName + "Item", newItem); - this.nodeMap.set(newItem, newNode); - this.parentRenderer.prevent('rendered'); - renderer = new Batman.Renderer(newNode, this.renderContext.descend(newItem, this.iteratorName), this.parentRenderer.view); - renderer.on('rendered', function() { - Batman.propagateBindingEvents(newNode); - _this.fire('nodeAdded', newNode, newItem); - return _this.parentRenderer.allowAndFire('rendered'); - }); - return newNode; - }; - - IteratorBinding.prototype._getStartNodeIndex = function() { - var index, node, _i, _len, _ref; - _ref = this.parentNode().childNodes; - for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { - node = _ref[index]; - if (node === this.startNode) { - return index; - } - } - return 0; - }; - - IteratorBinding.prototype._removeItem = function(item) { - var node; - node = this.nodeMap.unset(item); - Batman.destroyNode(node); - return this.fire('nodeRemoved', node, item); - }; - - return IteratorBinding; - - })(Batman.DOM.AbstractCollectionBinding); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.DOM.ClassBinding = (function(_super) { - - __extends(ClassBinding, _super); - - function ClassBinding() { - this.handleArrayChanged = __bind(this.handleArrayChanged, this); - return ClassBinding.__super__.constructor.apply(this, arguments); - } - - ClassBinding.prototype.dataChange = function(value) { - if (value != null) { - this.unbindCollection(); - if (typeof value === 'string') { - return this.node.className = value; - } else { - this.bindCollection(value); - return this.updateFromCollection(); - } - } - }; - - ClassBinding.prototype.updateFromCollection = function() { - var array, k, v; - if (this.collection) { - array = this.collection.map ? this.collection.map(function(x) { - return x; - }) : (function() { - var _ref, _results; - _ref = this.collection; - _results = []; - for (k in _ref) { - if (!__hasProp.call(_ref, k)) continue; - v = _ref[k]; - _results.push(k); - } - return _results; - }).call(this); - if (array.toArray != null) { - array = array.toArray(); - } - return this.node.className = array.join(' '); - } - }; - - ClassBinding.prototype.handleArrayChanged = function() { - return this.updateFromCollection(); - }; - - return ClassBinding; - - })(Batman.DOM.AbstractCollectionBinding); - -}).call(this); - -(function() { - var __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; }; - - Batman.ValidationError = (function(_super) { - - __extends(ValidationError, _super); - - ValidationError.accessor('fullMessage', function() { - return Batman.t('errors.format', { - attribute: Batman.helpers.humanize(this.attribute), - message: this.message - }); - }); - - function ValidationError(attribute, message) { - ValidationError.__super__.constructor.call(this, { - attribute: attribute, - message: message - }); - } - - return ValidationError; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.StorageAdapter = (function(_super) { - - __extends(StorageAdapter, _super); - - StorageAdapter.StorageError = (function(_super1) { - - __extends(StorageError, _super1); - - StorageError.prototype.name = "StorageError"; - - function StorageError(message) { - StorageError.__super__.constructor.apply(this, arguments); - this.message = message; - } - - return StorageError; - - })(Error); - - StorageAdapter.RecordExistsError = (function(_super1) { - - __extends(RecordExistsError, _super1); - - RecordExistsError.prototype.name = 'RecordExistsError'; - - function RecordExistsError(message) { - RecordExistsError.__super__.constructor.call(this, message || "Can't create this record because it already exists in the store!"); - } - - return RecordExistsError; - - })(StorageAdapter.StorageError); - - StorageAdapter.NotFoundError = (function(_super1) { - - __extends(NotFoundError, _super1); - - NotFoundError.prototype.name = 'NotFoundError'; - - function NotFoundError(message) { - NotFoundError.__super__.constructor.call(this, message || "Record couldn't be found in storage!"); - } - - return NotFoundError; - - })(StorageAdapter.StorageError); - - function StorageAdapter(model) { - var constructor; - StorageAdapter.__super__.constructor.call(this, { - model: model - }); - constructor = this.constructor; - if (constructor.ModelMixin) { - Batman.extend(model, constructor.ModelMixin); - } - if (constructor.RecordMixin) { - Batman.extend(model.prototype, constructor.RecordMixin); - } - } - - StorageAdapter.prototype.isStorageAdapter = true; - - StorageAdapter.prototype.storageKey = function(record) { - var model; - model = (record != null ? record.constructor : void 0) || this.model; - return model.get('storageKey') || Batman.helpers.pluralize(Batman.helpers.underscore(model.get('resourceName'))); - }; - - StorageAdapter.prototype.getRecordFromData = function(attributes, constructor) { - var record; - if (constructor == null) { - constructor = this.model; - } - record = new constructor(); - record._withoutDirtyTracking(function() { - return this.fromJSON(attributes); - }); - return record; - }; - - StorageAdapter.skipIfError = function(f) { - return function(env, next) { - if (env.error != null) { - return next(); - } else { - return f.call(this, env, next); - } - }; - }; - - StorageAdapter.prototype.before = function() { - return this._addFilter.apply(this, ['before'].concat(__slice.call(arguments))); - }; - - StorageAdapter.prototype.after = function() { - return this._addFilter.apply(this, ['after'].concat(__slice.call(arguments))); - }; - - StorageAdapter.prototype._inheritFilters = function() { - var filtersByKey, filtersList, key, oldFilters, position, _results; - if (!this._batman.check(this) || !this._batman.filters) { - oldFilters = this._batman.getFirst('filters'); - this._batman.filters = { - before: {}, - after: {} - }; - if (oldFilters != null) { - _results = []; - for (position in oldFilters) { - filtersByKey = oldFilters[position]; - _results.push((function() { - var _results1; - _results1 = []; - for (key in filtersByKey) { - filtersList = filtersByKey[key]; - _results1.push(this._batman.filters[position][key] = filtersList.slice(0)); - } - return _results1; - }).call(this)); - } - return _results; - } - } - }; - - StorageAdapter.prototype._addFilter = function() { - var filter, key, keys, position, _base, _i, _j, _len; - position = arguments[0], keys = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), filter = arguments[_i++]; - this._inheritFilters(); - for (_j = 0, _len = keys.length; _j < _len; _j++) { - key = keys[_j]; - (_base = this._batman.filters[position])[key] || (_base[key] = []); - this._batman.filters[position][key].push(filter); - } - return true; - }; - - StorageAdapter.prototype.runFilter = function(position, action, env, callback) { - var actionFilters, allFilters, filters, next, - _this = this; - this._inheritFilters(); - allFilters = this._batman.filters[position].all || []; - actionFilters = this._batman.filters[position][action] || []; - env.action = action; - filters = position === 'before' ? actionFilters.concat(allFilters) : allFilters.concat(actionFilters); - next = function(newEnv) { - var nextFilter; - if (newEnv != null) { - env = newEnv; - } - if ((nextFilter = filters.shift()) != null) { - return nextFilter.call(_this, env, next); - } else { - return callback.call(_this, env); - } - }; - return next(); - }; - - StorageAdapter.prototype.runBeforeFilter = function() { - return this.runFilter.apply(this, ['before'].concat(__slice.call(arguments))); - }; - - StorageAdapter.prototype.runAfterFilter = function(action, env, callback) { - return this.runFilter('after', action, env, this.exportResult(callback)); - }; - - StorageAdapter.prototype.exportResult = function(callback) { - return function(env) { - return callback(env.error, env.result, env); - }; - }; - - StorageAdapter.prototype._jsonToAttributes = function(json) { - return JSON.parse(json); - }; - - StorageAdapter.prototype.perform = function(key, subject, options, callback) { - var env, next, - _this = this; - options || (options = {}); - env = { - options: options, - subject: subject - }; - next = function(newEnv) { - if (newEnv != null) { - env = newEnv; - } - return _this.runAfterFilter(key, env, callback); - }; - return this.runBeforeFilter(key, env, function(env) { - return this[key](env, next); - }); - }; - - return StorageAdapter; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Batman.RestStorage = (function(_super) { - var key, _fn, _i, _len, _ref, - _this = this; - - __extends(RestStorage, _super); - - RestStorage.JSONContentType = 'application/json'; - - RestStorage.PostBodyContentType = 'application/x-www-form-urlencoded'; - - RestStorage.BaseMixin = { - request: function(action, options, callback) { - if (!callback) { - callback = options; - options = {}; - } - options.method || (options.method = 'GET'); - options.action = action; - return this._doStorageOperation(options.method.toLowerCase(), options, callback); - } - }; - - RestStorage.ModelMixin = Batman.extend({}, RestStorage.BaseMixin, { - urlNestsUnder: function() { - var key, keys, parents, _i, _len; - keys = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - parents = {}; - for (_i = 0, _len = keys.length; _i < _len; _i++) { - key = keys[_i]; - parents[key + '_id'] = Batman.helpers.pluralize(key); - } - this.url = function(options) { - var childSegment, parentID, plural; - childSegment = Batman.helpers.pluralize(this.get('resourceName').toLowerCase()); - for (key in parents) { - plural = parents[key]; - parentID = options.data[key]; - if (parentID) { - delete options.data[key]; - return "" + plural + "/" + parentID + "/" + childSegment; - } - } - return childSegment; - }; - return this.prototype.url = function() { - var childSegment, id, parentID, plural, url; - childSegment = Batman.helpers.pluralize(this.constructor.get('resourceName').toLowerCase()); - for (key in parents) { - plural = parents[key]; - parentID = this.get('dirtyKeys').get(key); - if (parentID === void 0) { - parentID = this.get(key); - } - if (parentID) { - url = "" + plural + "/" + parentID + "/" + childSegment; - break; - } - } - url || (url = childSegment); - if (id = this.get('id')) { - url += '/' + id; - } - return url; - }; - } - }); - - RestStorage.RecordMixin = Batman.extend({}, RestStorage.BaseMixin); - - RestStorage.prototype.defaultRequestOptions = { - type: 'json' - }; - - RestStorage.prototype._implicitActionNames = ['create', 'read', 'update', 'destroy', 'readAll']; - - RestStorage.prototype.serializeAsForm = true; - - function RestStorage() { - RestStorage.__super__.constructor.apply(this, arguments); - this.defaultRequestOptions = Batman.extend({}, this.defaultRequestOptions); - } - - RestStorage.prototype.recordJsonNamespace = function(record) { - return Batman.helpers.singularize(this.storageKey(record)); - }; - - RestStorage.prototype.collectionJsonNamespace = function(constructor) { - return Batman.helpers.pluralize(this.storageKey(constructor.prototype)); - }; - - RestStorage.prototype._execWithOptions = function(object, key, options) { - if (typeof object[key] === 'function') { - return object[key](options); - } else { - return object[key]; - } - }; - - RestStorage.prototype._defaultCollectionUrl = function(model) { - return "/" + (this.storageKey(model.prototype)); - }; - - RestStorage.prototype._addParams = function(url, options) { - var _ref; - if (options && options.action && !(_ref = options.action, __indexOf.call(this._implicitActionNames, _ref) >= 0)) { - url += '/' + options.action.toLowerCase(); - } - return url; - }; - - RestStorage.prototype.urlForRecord = function(record, env) { - var id, url; - if (record.url) { - url = this._execWithOptions(record, 'url', env.options); - } else { - url = record.constructor.url ? this._execWithOptions(record.constructor, 'url', env.options) : this._defaultCollectionUrl(record.constructor); - if (env.action !== 'create') { - if ((id = record.get('id')) != null) { - url = url + "/" + id; - } else { - throw new this.constructor.StorageError("Couldn't get/set record primary key on " + env.action + "!"); - } - } - } - url = this._addParams(url, env.options); - return this.urlPrefix(record, env) + url + this.urlSuffix(record, env); - }; - - RestStorage.prototype.urlForCollection = function(model, env) { - var url; - url = model.url ? this._execWithOptions(model, 'url', env.options) : this._defaultCollectionUrl(model, env.options); - url = this._addParams(url, env.options); - return this.urlPrefix(model, env) + url + this.urlSuffix(model, env); - }; - - RestStorage.prototype.urlPrefix = function(object, env) { - return this._execWithOptions(object, 'urlPrefix', env.options) || ''; - }; - - RestStorage.prototype.urlSuffix = function(object, env) { - return this._execWithOptions(object, 'urlSuffix', env.options) || ''; - }; - - RestStorage.prototype.request = function(env, next) { - var options; - options = Batman.extend(env.options, { - autosend: false, - success: function(data) { - return env.data = data; - }, - error: function(error) { - return env.error = error; - }, - loaded: function() { - env.response = env.request.get('response'); - return next(); - } - }); - env.request = new Batman.Request(options); - return env.request.send(); - }; - - RestStorage.prototype.perform = function(key, record, options, callback) { - options || (options = {}); - Batman.extend(options, this.defaultRequestOptions); - return RestStorage.__super__.perform.call(this, key, record, options, callback); - }; - - RestStorage.prototype.before('all', RestStorage.skipIfError(function(env, next) { - if (!env.options.url) { - try { - env.options.url = env.subject.prototype ? this.urlForCollection(env.subject, env) : this.urlForRecord(env.subject, env); - } catch (error) { - env.error = error; - } - } - return next(); - })); - - RestStorage.prototype.before('get', 'put', 'post', 'delete', RestStorage.skipIfError(function(env, next) { - env.options.method = env.action.toUpperCase(); - return next(); - })); - - RestStorage.prototype.before('create', 'update', RestStorage.skipIfError(function(env, next) { - var data, json, namespace; - json = env.subject.toJSON(); - if (namespace = this.recordJsonNamespace(env.subject)) { - data = {}; - data[namespace] = json; - } else { - data = json; - } - env.options.data = data; - return next(); - })); - - RestStorage.prototype.before('create', 'update', 'put', 'post', RestStorage.skipIfError(function(env, next) { - if (this.serializeAsForm) { - env.options.contentType = this.constructor.PostBodyContentType; - } else { - if (env.options.data != null) { - env.options.data = JSON.stringify(env.options.data); - env.options.contentType = this.constructor.JSONContentType; - } - } - return next(); - })); - - RestStorage.prototype.after('all', RestStorage.skipIfError(function(env, next) { - var json; - if (!(env.data != null)) { - return next(); - } - if (typeof env.data === 'string') { - if (env.data.length > 0) { - try { - json = this._jsonToAttributes(env.data); - } catch (error) { - env.error = error; - return next(); - } - } - } else if (typeof env.data === 'object') { - json = env.data; - } - if (json != null) { - env.json = json; - } - return next(); - })); - - RestStorage.prototype.extractFromNamespace = function(data, namespace) { - if (namespace && (data[namespace] != null)) { - return data[namespace]; - } else { - return data; - } - }; - - RestStorage.prototype.after('create', 'read', 'update', RestStorage.skipIfError(function(env, next) { - var json; - if (env.json != null) { - json = this.extractFromNamespace(env.json, this.recordJsonNamespace(env.subject)); - env.subject._withoutDirtyTracking(function() { - return this.fromJSON(json); - }); - } - env.result = env.subject; - return next(); - })); - - RestStorage.prototype.after('readAll', RestStorage.skipIfError(function(env, next) { - var jsonRecordAttributes, namespace; - namespace = this.collectionJsonNamespace(env.subject); - env.recordsAttributes = this.extractFromNamespace(env.json, namespace); - if (Batman.typeOf(env.recordsAttributes) !== 'Array') { - namespace = this.recordJsonNamespace(env.subject.prototype); - env.recordsAttributes = [this.extractFromNamespace(env.json, namespace)]; - } - env.result = env.records = (function() { - var _i, _len, _ref, _results; - _ref = env.recordsAttributes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - jsonRecordAttributes = _ref[_i]; - _results.push(this.getRecordFromData(jsonRecordAttributes, env.subject)); - } - return _results; - }).call(this); - return next(); - })); - - RestStorage.prototype.after('get', 'put', 'post', 'delete', RestStorage.skipIfError(function(env, next) { - var json, namespace; - if (env.json != null) { - json = env.json; - namespace = env.subject.prototype ? this.collectionJsonNamespace(env.subject) : this.recordJsonNamespace(env.subject); - env.result = namespace && (env.json[namespace] != null) ? env.json[namespace] : env.json; - } - return next(); - })); - - RestStorage.HTTPMethods = { - create: 'POST', - update: 'PUT', - read: 'GET', - readAll: 'GET', - destroy: 'DELETE' - }; - - _ref = ['create', 'read', 'update', 'destroy', 'readAll', 'get', 'post', 'put', 'delete']; - _fn = function(key) { - return RestStorage.prototype[key] = RestStorage.skipIfError(function(env, next) { - var _base; - (_base = env.options).method || (_base.method = this.constructor.HTTPMethods[key]); - return this.request(env, next); - }); - }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - _fn(key); - } - - return RestStorage; - - }).call(this, Batman.StorageAdapter); - -}).call(this); - -(function() { - var __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; }; - - Batman.LocalStorage = (function(_super) { - - __extends(LocalStorage, _super); - - function LocalStorage() { - if (typeof window.localStorage === 'undefined') { - return null; - } - LocalStorage.__super__.constructor.apply(this, arguments); - this.storage = localStorage; - } - - LocalStorage.prototype.storageRegExpForRecord = function(record) { - return new RegExp("^" + (this.storageKey(record)) + "(\\d+)$"); - }; - - LocalStorage.prototype.nextIdForRecord = function(record) { - var nextId, re; - re = this.storageRegExpForRecord(record); - nextId = 1; - this._forAllStorageEntries(function(k, v) { - var matches; - if (matches = re.exec(k)) { - return nextId = Math.max(nextId, parseInt(matches[1], 10) + 1); - } - }); - return nextId; - }; - - LocalStorage.prototype._forAllStorageEntries = function(iterator) { - var i, key, _i, _ref; - for (i = _i = 0, _ref = this.storage.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - key = this.storage.key(i); - iterator.call(this, key, this.storage.getItem(key)); - } - return true; - }; - - LocalStorage.prototype._storageEntriesMatching = function(constructor, options) { - var re, records; - re = this.storageRegExpForRecord(constructor.prototype); - records = []; - this._forAllStorageEntries(function(storageKey, storageString) { - var data, keyMatches; - if (keyMatches = re.exec(storageKey)) { - data = this._jsonToAttributes(storageString); - data[constructor.primaryKey] = keyMatches[1]; - if (this._dataMatches(options, data)) { - return records.push(data); - } - } - }); - return records; - }; - - LocalStorage.prototype._dataMatches = function(conditions, data) { - var k, match, v; - match = true; - for (k in conditions) { - v = conditions[k]; - if (data[k] !== v) { - match = false; - break; - } - } - return match; - }; - - LocalStorage.prototype.before('read', 'create', 'update', 'destroy', LocalStorage.skipIfError(function(env, next) { - var _this = this; - if (env.action === 'create') { - env.id = env.subject.get('id') || env.subject._withoutDirtyTracking(function() { - return env.subject.set('id', _this.nextIdForRecord(env.subject)); - }); - } else { - env.id = env.subject.get('id'); - } - if (env.id == null) { - env.error = new this.constructor.StorageError("Couldn't get/set record primary key on " + env.action + "!"); - } else { - env.key = this.storageKey(env.subject) + env.id; - } - return next(); - })); - - LocalStorage.prototype.before('create', 'update', LocalStorage.skipIfError(function(env, next) { - env.recordAttributes = JSON.stringify(env.subject); - return next(); - })); - - LocalStorage.prototype.after('read', LocalStorage.skipIfError(function(env, next) { - if (typeof env.recordAttributes === 'string') { - try { - env.recordAttributes = this._jsonToAttributes(env.recordAttributes); - } catch (error) { - env.error = error; - return next(); - } - } - env.subject._withoutDirtyTracking(function() { - return this.fromJSON(env.recordAttributes); - }); - return next(); - })); - - LocalStorage.prototype.after('read', 'create', 'update', 'destroy', LocalStorage.skipIfError(function(env, next) { - env.result = env.subject; - return next(); - })); - - LocalStorage.prototype.after('readAll', LocalStorage.skipIfError(function(env, next) { - var recordAttributes; - env.result = env.records = (function() { - var _i, _len, _ref, _results; - _ref = env.recordsAttributes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - recordAttributes = _ref[_i]; - _results.push(this.getRecordFromData(recordAttributes, env.subject)); - } - return _results; - }).call(this); - return next(); - })); - - LocalStorage.prototype.read = LocalStorage.skipIfError(function(env, next) { - env.recordAttributes = this.storage.getItem(env.key); - if (!env.recordAttributes) { - env.error = new this.constructor.NotFoundError(); - } - return next(); - }); - - LocalStorage.prototype.create = LocalStorage.skipIfError(function(_arg, next) { - var key, recordAttributes; - key = _arg.key, recordAttributes = _arg.recordAttributes; - if (this.storage.getItem(key)) { - arguments[0].error = new this.constructor.RecordExistsError; - } else { - this.storage.setItem(key, recordAttributes); - } - return next(); - }); - - LocalStorage.prototype.update = LocalStorage.skipIfError(function(_arg, next) { - var key, recordAttributes; - key = _arg.key, recordAttributes = _arg.recordAttributes; - this.storage.setItem(key, recordAttributes); - return next(); - }); - - LocalStorage.prototype.destroy = LocalStorage.skipIfError(function(_arg, next) { - var key; - key = _arg.key; - this.storage.removeItem(key); - return next(); - }); - - LocalStorage.prototype.readAll = LocalStorage.skipIfError(function(env, next) { - try { - arguments[0].recordsAttributes = this._storageEntriesMatching(env.subject, env.options.data); - } catch (error) { - arguments[0].error = error; - } - return next(); - }); - - return LocalStorage; - - })(Batman.StorageAdapter); - -}).call(this); - -(function() { - var __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; }; - - Batman.SessionStorage = (function(_super) { - - __extends(SessionStorage, _super); - - function SessionStorage() { - if (typeof window.sessionStorage === 'undefined') { - return null; - } - SessionStorage.__super__.constructor.apply(this, arguments); - this.storage = sessionStorage; - } - - return SessionStorage; - - })(Batman.LocalStorage); - -}).call(this); - -(function() { - - Batman.Encoders = new Batman.Object; - -}).call(this); - -(function() { - var __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; }; - - Batman.AssociationProxy = (function(_super) { - - __extends(AssociationProxy, _super); - - AssociationProxy.prototype.isProxy = true; - - function AssociationProxy(association, model) { - this.association = association; - this.model = model; - } - - AssociationProxy.prototype.loaded = false; - - AssociationProxy.prototype.toJSON = function() { - var target; - target = this.get('target'); - if (target != null) { - return this.get('target').toJSON(); - } - }; - - AssociationProxy.prototype.load = function(callback) { - var _this = this; - this.fetch(function(err, proxiedRecord) { - if (!err) { - _this.set('loaded', true); - _this.set('target', proxiedRecord); - } - return typeof callback === "function" ? callback(err, proxiedRecord) : void 0; - }); - return this.get('target'); - }; - - AssociationProxy.prototype.fetch = function(callback) { - var record; - if ((this.get('foreignValue') || this.get('primaryValue')) == null) { - return callback(void 0, void 0); - } - record = this.fetchFromLocal(); - if (record) { - return callback(void 0, record); - } else { - return this.fetchFromRemote(callback); - } - }; - - AssociationProxy.accessor('loaded', Batman.Property.defaultAccessor); - - AssociationProxy.accessor('target', { - get: function() { - return this.fetchFromLocal(); - }, - set: function(_, v) { - return v; - } - }); - - AssociationProxy.accessor({ - get: function(k) { - var _ref; - return (_ref = this.get('target')) != null ? _ref.get(k) : void 0; - }, - set: function(k, v) { - var _ref; - return (_ref = this.get('target')) != null ? _ref.set(k, v) : void 0; - } - }); - - return AssociationProxy; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.HasOneProxy = (function(_super) { - - __extends(HasOneProxy, _super); - - function HasOneProxy() { - return HasOneProxy.__super__.constructor.apply(this, arguments); - } - - HasOneProxy.accessor('primaryValue', function() { - return this.model.get(this.association.primaryKey); - }); - - HasOneProxy.prototype.fetchFromLocal = function() { - return this.association.setIndex().get(this.get('primaryValue')); - }; - - HasOneProxy.prototype.fetchFromRemote = function(callback) { - var loadOptions, - _this = this; - loadOptions = {}; - loadOptions[this.association.foreignKey] = this.get('primaryValue'); - return this.association.getRelatedModel().load(loadOptions, function(error, loadedRecords) { - if (error) { - throw error; - } - if (!loadedRecords || loadedRecords.length <= 0) { - return callback(new Error("Couldn't find related record!"), void 0); - } else { - return callback(void 0, loadedRecords[0]); - } - }); - }; - - return HasOneProxy; - - })(Batman.AssociationProxy); - -}).call(this); - -(function() { - var __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; }; - - Batman.BelongsToProxy = (function(_super) { - - __extends(BelongsToProxy, _super); - - function BelongsToProxy() { - return BelongsToProxy.__super__.constructor.apply(this, arguments); - } - - BelongsToProxy.accessor('foreignValue', function() { - return this.model.get(this.association.foreignKey); - }); - - BelongsToProxy.prototype.fetchFromLocal = function() { - return this.association.setIndex().get(this.get('foreignValue')); - }; - - BelongsToProxy.prototype.fetchFromRemote = function(callback) { - var _this = this; - return this.association.getRelatedModel().find(this.get('foreignValue'), function(error, loadedRecord) { - if (error) { - throw error; - } - return callback(void 0, loadedRecord); - }); - }; - - return BelongsToProxy; - - })(Batman.AssociationProxy); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicBelongsToProxy = (function(_super) { - - __extends(PolymorphicBelongsToProxy, _super); - - function PolymorphicBelongsToProxy() { - return PolymorphicBelongsToProxy.__super__.constructor.apply(this, arguments); - } - - PolymorphicBelongsToProxy.accessor('foreignTypeValue', function() { - return this.model.get(this.association.foreignTypeKey); - }); - - PolymorphicBelongsToProxy.prototype.fetchFromLocal = function() { - return this.association.setIndexForType(this.get('foreignTypeValue')).get(this.get('foreignValue')); - }; - - PolymorphicBelongsToProxy.prototype.fetchFromRemote = function(callback) { - var _this = this; - return this.association.getRelatedModelForType(this.get('foreignTypeValue')).find(this.get('foreignValue'), function(error, loadedRecord) { - if (error) { - throw error; - } - return callback(void 0, loadedRecord); - }); - }; - - return PolymorphicBelongsToProxy; - - })(Batman.BelongsToProxy); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.StateMachine = (function(_super) { - - __extends(StateMachine, _super); - - StateMachine.InvalidTransitionError = function(message) { - this.message = message != null ? message : ""; - }; - - StateMachine.InvalidTransitionError.prototype = new Error; - - StateMachine.transitions = function(table) { - var definePredicate, fromState, k, object, predicateKeys, toState, transitions, v, _fn, _ref, - _this = this; - for (k in table) { - v = table[k]; - if (!(v.from && v.to)) { - continue; - } - object = {}; - if (v.from.forEach) { - v.from.forEach(function(fromKey) { - return object[fromKey] = v.to; - }); - } else { - object[v.from] = v.to; - } - table[k] = object; - } - this.prototype.transitionTable = Batman.extend({}, this.prototype.transitionTable, table); - predicateKeys = []; - definePredicate = function(state) { - var key; - key = "is" + (Batman.helpers.capitalize(state)); - if (_this.prototype[key] != null) { - return; - } - predicateKeys.push(key); - return _this.prototype[key] = function() { - return this.get('state') === state; - }; - }; - _ref = this.prototype.transitionTable; - _fn = function(k) { - return _this.prototype[k] = function() { - return this.startTransition(k); - }; - }; - for (k in _ref) { - transitions = _ref[k]; - if (!(!this.prototype[k])) { - continue; - } - _fn(k); - for (fromState in transitions) { - toState = transitions[fromState]; - definePredicate(fromState); - definePredicate(toState); - } - } - if (predicateKeys.length) { - this.accessor.apply(this, __slice.call(predicateKeys).concat([function(key) { - return this[key](); - }])); - } - return this; - }; - - function StateMachine(startState) { - this.nextEvents = []; - this.set('_state', startState); - } - - StateMachine.accessor('state', function() { - return this.get('_state'); - }); - - StateMachine.prototype.isTransitioning = false; - - StateMachine.prototype.transitionTable = {}; - - StateMachine.prototype.onTransition = function(from, into, callback) { - return this.on("" + from + "->" + into, callback); - }; - - StateMachine.prototype.onEnter = function(into, callback) { - return this.on("enter " + into, callback); - }; - - StateMachine.prototype.onExit = function(from, callback) { - return this.on("exit " + from, callback); - }; - - StateMachine.prototype.startTransition = Batman.Property.wrapTrackingPrevention(function(event) { - var nextState, previousState; - if (this.isTransitioning) { - this.nextEvents.push(event); - return; - } - previousState = this.get('state'); - nextState = this.nextStateForEvent(event); - if (!nextState) { - return false; - } - this.isTransitioning = true; - this.fire("exit " + previousState); - this.set('_state', nextState); - this.fire("" + previousState + "->" + nextState); - this.fire("enter " + nextState); - this.fire(event); - this.isTransitioning = false; - if (this.nextEvents.length > 0) { - this.startTransition(this.nextEvents.shift()); - } - return true; - }); - - StateMachine.prototype.canStartTransition = function(event, fromState) { - if (fromState == null) { - fromState = this.get('state'); - } - return !!this.nextStateForEvent(event, fromState); - }; - - StateMachine.prototype.nextStateForEvent = function(event, fromState) { - var _ref; - if (fromState == null) { - fromState = this.get('state'); - } - return (_ref = this.transitionTable[event]) != null ? _ref[fromState] : void 0; - }; - - return StateMachine; - - })(Batman.Object); - - Batman.DelegatingStateMachine = (function(_super) { - - __extends(DelegatingStateMachine, _super); - - function DelegatingStateMachine(startState, base) { - this.base = base; - DelegatingStateMachine.__super__.constructor.call(this, startState); - } - - DelegatingStateMachine.prototype.fire = function() { - var result, _ref; - result = DelegatingStateMachine.__super__.fire.apply(this, arguments); - (_ref = this.base).fire.apply(_ref, arguments); - return result; - }; - - return DelegatingStateMachine; - - })(Batman.StateMachine); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }, - __slice = [].slice; - - Batman.Model = (function(_super) { - var functionName, _i, _j, _len, _len1, _ref, _ref1; - - __extends(Model, _super); - - Model.primaryKey = 'id'; - - Model.storageKey = null; - - Model.persist = function(mechanism, options) { - Batman.initializeObject(this.prototype); - mechanism = mechanism.isStorageAdapter ? mechanism : new mechanism(this); - if (options) { - Batman.mixin(mechanism, options); - } - this.prototype._batman.storage = mechanism; - return mechanism; - }; - - Model.storageAdapter = function() { - Batman.initializeObject(this.prototype); - return this.prototype._batman.storage; - }; - - Model.encode = function() { - var encoder, encoderForKey, encoderOrLastKey, key, keys, _base, _i, _j, _len; - keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), encoderOrLastKey = arguments[_i++]; - Batman.initializeObject(this.prototype); - (_base = this.prototype._batman).encoders || (_base.encoders = new Batman.SimpleHash); - encoder = {}; - switch (Batman.typeOf(encoderOrLastKey)) { - case 'String': - keys.push(encoderOrLastKey); - break; - case 'Function': - encoder.encode = encoderOrLastKey; - break; - default: - encoder = encoderOrLastKey; - } - for (_j = 0, _len = keys.length; _j < _len; _j++) { - key = keys[_j]; - encoderForKey = Batman.extend({ - as: key - }, this.defaultEncoder, encoder); - this.prototype._batman.encoders.set(key, encoderForKey); - } - }; - - Model.defaultEncoder = { - encode: function(x) { - return x; - }, - decode: function(x) { - return x; - } - }; - - Model.observeAndFire('primaryKey', function(newPrimaryKey, oldPrimaryKey) { - this.encode(oldPrimaryKey, { - encode: false, - decode: false - }); - return this.encode(newPrimaryKey, { - encode: false, - decode: this.defaultEncoder.decode - }); - }); - - Model.validate = function() { - var keys, match, matches, options, optionsOrFunction, validator, validators, _base, _i, _j, _k, _len, _len1, _ref, _results; - keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), optionsOrFunction = arguments[_i++]; - Batman.initializeObject(this.prototype); - validators = (_base = this.prototype._batman).validators || (_base.validators = []); - if (typeof optionsOrFunction === 'function') { - return validators.push({ - keys: keys, - callback: optionsOrFunction - }); - } else { - options = optionsOrFunction; - _ref = Batman.Validators; - _results = []; - for (_j = 0, _len = _ref.length; _j < _len; _j++) { - validator = _ref[_j]; - if ((matches = validator.matches(options))) { - for (_k = 0, _len1 = matches.length; _k < _len1; _k++) { - match = matches[_k]; - delete options[match]; - } - _results.push(validators.push({ - keys: keys, - validator: new validator(matches) - })); - } else { - _results.push(void 0); - } - } - return _results; - } - }; - - Model.LifecycleStateMachine = (function(_super1) { - - __extends(LifecycleStateMachine, _super1); - - function LifecycleStateMachine() { - return LifecycleStateMachine.__super__.constructor.apply(this, arguments); - } - - LifecycleStateMachine.transitions({ - load: { - empty: 'loading', - loaded: 'loading', - loading: 'loading' - }, - loaded: { - loading: 'loaded' - }, - error: { - loading: 'error' - } - }); - - return LifecycleStateMachine; - - })(Batman.DelegatingStateMachine); - - Model.classAccessor('lifecycle', function() { - var _base; - this._batman.check(this); - return (_base = this._batman).lifecycle || (_base.lifecycle = new this.LifecycleStateMachine('empty', this)); - }); - - Model.classAccessor('resourceName', { - get: function() { - if (this.resourceName != null) { - return this.resourceName; - } else { - if (Batman.config.minificationErrors) { - Batman.developer.error("Please define " + (Batman.functionName(this)) + ".resourceName in order for your model to be minification safe."); - } - return Batman.helpers.underscore(Batman.functionName(this)); - } - } - }); - - Model.classAccessor('all', { - get: function() { - this._batman.check(this); - if (this.prototype.hasStorage() && !this._batman.allLoadTriggered) { - this.load(); - this._batman.allLoadTriggered = true; - } - return this.get('loaded'); - }, - set: function(k, v) { - return this.set('loaded', v); - } - }); - - Model.classAccessor('loaded', { - get: function() { - return this._loaded || (this._loaded = new Batman.Set); - }, - set: function(k, v) { - return this._loaded = v; - } - }); - - Model.classAccessor('first', function() { - return this.get('all').toArray()[0]; - }); - - Model.classAccessor('last', function() { - var x; - x = this.get('all').toArray(); - return x[x.length - 1]; - }); - - Model.clear = function() { - var result, _ref; - Batman.initializeObject(this); - result = this.get('loaded').clear(); - if ((_ref = this._batman.get('associations')) != null) { - _ref.reset(); - } - return result; - }; - - Model.find = function(id, callback) { - var record; - Batman.developer.assert(callback, "Must call find with a callback!"); - record = new this(); - record._withoutDirtyTracking(function() { - return this.set('id', id); - }); - record.load(callback); - return record; - }; - - Model.load = function(options, callback) { - var lifecycle, _ref, - _this = this; - if ((_ref = typeof options) === 'function' || _ref === 'undefined') { - callback = options; - options = {}; - } - lifecycle = this.get('lifecycle'); - if (lifecycle.load()) { - return this._doStorageOperation('readAll', { - data: options - }, function(err, records, env) { - var mappedRecords, record; - if (err != null) { - lifecycle.error(); - return typeof callback === "function" ? callback(err, []) : void 0; - } else { - mappedRecords = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = records.length; _i < _len; _i++) { - record = records[_i]; - _results.push(this._mapIdentity(record)); - } - return _results; - }).call(_this); - lifecycle.loaded(); - return typeof callback === "function" ? callback(err, mappedRecords, env) : void 0; - } - }); - } else { - return callback(new Batman.StateMachine.InvalidTransitionError("Can't load while in state " + (lifecycle.get('state')))); - } - }; - - Model.create = function(attrs, callback) { - var obj, _ref; - if (!callback) { - _ref = [{}, attrs], attrs = _ref[0], callback = _ref[1]; - } - obj = new this(attrs); - obj.save(callback); - return obj; - }; - - Model.findOrCreate = function(attrs, callback) { - var foundRecord, record; - record = new this(attrs); - if (record.isNew()) { - record.save(callback); - } else { - foundRecord = this._mapIdentity(record); - callback(void 0, foundRecord); - } - return record; - }; - - Model._mapIdentity = function(record) { - var existing, id, _ref; - if (typeof (id = record.get('id')) === 'undefined' || id === '') { - return record; - } else { - existing = (_ref = this.get("loaded.indexedBy.id").get(id)) != null ? _ref.toArray()[0] : void 0; - if (existing) { - existing._withoutDirtyTracking(function() { - var _ref1; - return this.updateAttributes(((_ref1 = record.get('attributes')) != null ? _ref1.toObject() : void 0) || {}); - }); - return existing; - } else { - this.get('loaded').add(record); - return record; - } - } - }; - - Model._doStorageOperation = function(operation, options, callback) { - var adapter; - Batman.developer.assert(this.prototype.hasStorage(), "Can't " + operation + " model " + (Batman.functionName(this.constructor)) + " without any storage adapters!"); - adapter = this.prototype._batman.get('storage'); - return adapter.perform(operation, this, options, callback); - }; - - _ref = ['find', 'load', 'create']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - functionName = _ref[_i]; - Model[functionName] = Batman.Property.wrapTrackingPrevention(Model[functionName]); - } - - Model.InstanceLifecycleStateMachine = (function(_super1) { - - __extends(InstanceLifecycleStateMachine, _super1); - - function InstanceLifecycleStateMachine() { - return InstanceLifecycleStateMachine.__super__.constructor.apply(this, arguments); - } - - InstanceLifecycleStateMachine.transitions({ - load: { - from: ['dirty', 'clean'], - to: 'loading' - }, - create: { - from: ['dirty', 'clean'], - to: 'creating' - }, - save: { - from: ['dirty', 'clean'], - to: 'saving' - }, - destroy: { - from: ['dirty', 'clean'], - to: 'destroying' - }, - failedValidation: { - from: ['saving', 'creating'], - to: 'dirty' - }, - loaded: { - loading: 'clean' - }, - created: { - creating: 'clean' - }, - saved: { - saving: 'clean' - }, - destroyed: { - destroying: 'destroyed' - }, - set: { - from: ['dirty', 'clean'], - to: 'dirty' - }, - error: { - from: ['saving', 'creating', 'loading', 'destroying'], - to: 'error' - } - }); - - return InstanceLifecycleStateMachine; - - })(Batman.DelegatingStateMachine); - - function Model(idOrAttributes) { - if (idOrAttributes == null) { - idOrAttributes = {}; - } - this.destroy = __bind(this.destroy, this); - - this.save = __bind(this.save, this); - - this.load = __bind(this.load, this); - - Batman.developer.assert(this instanceof Batman.Object, "constructors must be called with new"); - if (Batman.typeOf(idOrAttributes) === 'Object') { - Model.__super__.constructor.call(this, idOrAttributes); - } else { - Model.__super__.constructor.call(this); - this.set('id', idOrAttributes); - } - } - - Model.accessor('lifecycle', function() { - return this.lifecycle || (this.lifecycle = new Batman.Model.InstanceLifecycleStateMachine('clean', this)); - }); - - Model.accessor('attributes', function() { - return this.attributes || (this.attributes = new Batman.Hash); - }); - - Model.accessor('dirtyKeys', function() { - return this.dirtyKeys || (this.dirtyKeys = new Batman.Hash); - }); - - Model.accessor('_dirtiedKeys', function() { - return this._dirtiedKeys || (this._dirtiedKeys = new Batman.SimpleSet); - }); - - Model.accessor('errors', function() { - return this.errors || (this.errors = new Batman.ErrorsSet); - }); - - Model.accessor('isNew', function() { - return this.isNew(); - }); - - Model.accessor(Model.defaultAccessor = { - get: function(k) { - return Batman.getPath(this, ['attributes', k]); - }, - set: function(k, v) { - if (this._willSet(k)) { - return this.get('attributes').set(k, v); - } else { - return this.get(k); - } - }, - unset: function(k) { - return this.get('attributes').unset(k); - } - }); - - Model.wrapAccessor('id', function(core) { - return { - get: function() { - var primaryKey; - primaryKey = this.constructor.primaryKey; - if (primaryKey === 'id') { - return core.get.apply(this, arguments); - } else { - return this.get(primaryKey); - } - }, - set: function(key, value) { - var parsedValue, primaryKey; - if ((typeof value === "string") && (value.match(/[^0-9]/) === null) && (("" + (parsedValue = parseInt(value, 10))) === value)) { - value = parsedValue; - } - primaryKey = this.constructor.primaryKey; - if (primaryKey === 'id') { - this._willSet(key); - return core.set.apply(this, arguments); - } else { - return this.set(primaryKey, value); - } - } - }; - }); - - Model.prototype.isNew = function() { - return typeof this.get('id') === 'undefined'; - }; - - Model.prototype.updateAttributes = function(attrs) { - this.mixin(attrs); - return this; - }; - - Model.prototype.toString = function() { - return "" + (this.constructor.get('resourceName')) + ": " + (this.get('id')); - }; - - Model.prototype.toParam = function() { - return this.get('id'); - }; - - Model.prototype.toJSON = function() { - var encoders, obj, - _this = this; - obj = {}; - encoders = this._batman.get('encoders'); - if (!(!encoders || encoders.isEmpty())) { - encoders.forEach(function(key, encoder) { - var encodedVal, val; - if (encoder.encode) { - val = _this.get(key); - if (typeof val !== 'undefined') { - encodedVal = encoder.encode(val, key, obj, _this); - if (typeof encodedVal !== 'undefined') { - return obj[encoder.as] = encodedVal; - } - } - } - }); - } - return obj; - }; - - Model.prototype.fromJSON = function(data) { - var encoders, key, obj, value, - _this = this; - obj = {}; - encoders = this._batman.get('encoders'); - if (!encoders || encoders.isEmpty() || !encoders.some(function(key, encoder) { - return encoder.decode != null; - })) { - for (key in data) { - value = data[key]; - obj[key] = value; - } - } else { - encoders.forEach(function(key, encoder) { - if (encoder.decode && typeof data[encoder.as] !== 'undefined') { - return obj[key] = encoder.decode(data[encoder.as], encoder.as, data, obj, _this); - } - }); - } - if (this.constructor.primaryKey !== 'id') { - obj.id = data[this.constructor.primaryKey]; - } - Batman.developer["do"](function() { - if ((!encoders) || encoders.length <= 1) { - return Batman.developer.warn("Warning: Model " + (Batman.functionName(_this.constructor)) + " has suspiciously few decoders!"); - } - }); - return this.mixin(obj); - }; - - Model.prototype.hasStorage = function() { - return this._batman.get('storage') != null; - }; - - Model.prototype.load = function(options, callback) { - var callbackQueue, hasOptions, _ref1, _ref2, - _this = this; - if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; - } - hasOptions = Object.keys(options).length !== 0; - if ((_ref2 = this.get('lifecycle.state')) === 'destroying' || _ref2 === 'destroyed') { - if (typeof callback === "function") { - callback(new Error("Can't load a destroyed record!")); - } - return; - } - if (this.get('lifecycle').load()) { - callbackQueue = []; - if (callback != null) { - callbackQueue.push(callback); - } - if (!hasOptions) { - this._currentLoad = callbackQueue; - } - return this._doStorageOperation('read', { - data: options - }, function(err, record, env) { - var _j, _len1; - if (!err) { - _this.get('lifecycle').loaded(); - record = _this.constructor._mapIdentity(record); - } else { - _this.get('lifecycle').error(); - } - if (!hasOptions) { - _this._currentLoad = null; - } - for (_j = 0, _len1 = callbackQueue.length; _j < _len1; _j++) { - callback = callbackQueue[_j]; - callback(err, record, env); - } - }); - } else { - if (this.get('lifecycle.state') === 'loading' && !hasOptions) { - if (callback != null) { - return this._currentLoad.push(callback); - } - } else { - return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't load while in state " + (this.get('lifecycle.state')))) : void 0; - } - } - }; - - Model.prototype.save = function(options, callback) { - var endState, isNew, startState, storageOperation, _ref1, _ref2, _ref3, - _this = this; - if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; - } - if ((_ref2 = this.get('lifecycle').get('state')) === 'destroying' || _ref2 === 'destroyed') { - if (typeof callback === "function") { - callback(new Error("Can't save a destroyed record!")); - } - return; - } - isNew = this.isNew(); - _ref3 = isNew ? ['create', 'create', 'created'] : ['save', 'update', 'saved'], startState = _ref3[0], storageOperation = _ref3[1], endState = _ref3[2]; - return this.validate(function(error, errors) { - var associations, creating; - if (error || errors.length) { - _this.get('lifecycle').failedValidation(); - if (typeof callback === "function") { - callback(error || errors, _this); - } - return; - } - creating = _this.isNew(); - if (_this.get('lifecycle').startTransition(startState)) { - associations = _this.constructor._batman.get('associations'); - _this._withoutDirtyTracking(function() { - var _ref4, - _this = this; - return associations != null ? (_ref4 = associations.getByType('belongsTo')) != null ? _ref4.forEach(function(association, label) { - return association.apply(_this); - }) : void 0 : void 0; - }); - return _this._doStorageOperation(storageOperation, { - data: options - }, function(err, record, env) { - if (!err) { - _this.get('dirtyKeys').clear(); - _this.get('_dirtiedKeys').clear(); - if (associations) { - record._withoutDirtyTracking(function() { - var _ref4, _ref5; - if ((_ref4 = associations.getByType('hasOne')) != null) { - _ref4.forEach(function(association, label) { - return association.apply(err, record); - }); - } - return (_ref5 = associations.getByType('hasMany')) != null ? _ref5.forEach(function(association, label) { - return association.apply(err, record); - }) : void 0; - }); - } - record = _this.constructor._mapIdentity(record); - _this.get('lifecycle').startTransition(endState); - } else { - if (err instanceof Batman.ErrorsSet) { - _this.get('lifecycle').failedValidation(); - } else { - _this.get('lifecycle').error(); - } - } - return typeof callback === "function" ? callback(err, record || _this, env) : void 0; - }); - } else { - return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't save while in state " + (_this.get('lifecycle.state')))) : void 0; - } - }); - }; - - Model.prototype.destroy = function(options, callback) { - var _ref1, - _this = this; - if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; - } - if (this.get('lifecycle').destroy()) { - return this._doStorageOperation('destroy', { - data: options - }, function(err, record, env) { - if (!err) { - _this.constructor.get('loaded').remove(_this); - _this.get('lifecycle').destroyed(); - } else { - _this.get('lifecycle').error(); - } - return typeof callback === "function" ? callback(err, record, env) : void 0; - }); - } else { - return typeof callback === "function" ? callback(new Batman.StateMachine.InvalidTransitionError("Can't destroy while in state " + (this.get('lifecycle.state')))) : void 0; - } - }; - - Model.prototype.validate = function(callback) { - var args, count, errors, finishedValidation, key, validator, validators, _j, _k, _len1, _len2, _ref1; - errors = this.get('errors'); - errors.clear(); - validators = this._batman.get('validators') || []; - if (!validators || validators.length === 0) { - if (typeof callback === "function") { - callback(void 0, errors); - } - return true; - } - count = validators.reduce((function(acc, validator) { - return acc + validator.keys.length; - }), 0); - finishedValidation = function() { - if (--count === 0) { - return typeof callback === "function" ? callback(void 0, errors) : void 0; - } - }; - for (_j = 0, _len1 = validators.length; _j < _len1; _j++) { - validator = validators[_j]; - _ref1 = validator.keys; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - key = _ref1[_k]; - args = [errors, this, key, finishedValidation]; - try { - if (validator.validator) { - validator.validator.validateEach.apply(validator.validator, args); - } else { - validator.callback.apply(validator, args); - } - } catch (e) { - if (typeof callback === "function") { - callback(e, errors); - } - } - } - } - }; - - Model.prototype.associationProxy = function(association) { - var proxies, _base, _name; - Batman.initializeObject(this); - proxies = (_base = this._batman).associationProxies || (_base.associationProxies = {}); - proxies[_name = association.label] || (proxies[_name] = new association.proxyClass(association, this)); - return proxies[association.label]; - }; - - Model.prototype._willSet = function(key) { - if (this._pauseDirtyTracking) { - return true; - } - if (this.get('lifecycle').startTransition('set')) { - if (!this.get('_dirtiedKeys').has(key)) { - this.set("dirtyKeys." + key, this.get(key)); - this.get('_dirtiedKeys').add(key); - } - return true; - } else { - return false; - } - }; - - Model.prototype._doStorageOperation = function(operation, options, callback) { - var adapter, - _this = this; - Batman.developer.assert(this.hasStorage(), "Can't " + operation + " model " + (Batman.functionName(this.constructor)) + " without any storage adapters!"); - adapter = this._batman.get('storage'); - return adapter.perform(operation, this, options, function() { - return callback.apply(null, arguments); - }); - }; - - Model.prototype._withoutDirtyTracking = function(block) { - var result; - this._pauseDirtyTracking = true; - result = block.call(this); - this._pauseDirtyTracking = false; - return result; - }; - - _ref1 = ['load', 'save', 'validate', 'destroy']; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - functionName = _ref1[_j]; - Model.prototype[functionName] = Batman.Property.wrapTrackingPrevention(Model.prototype[functionName]); - } - - return Model; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var k, _fn, _i, _len, _ref, - _this = this; - - _ref = Batman.AssociationCurator.availableAssociations; - _fn = function(k) { - return Batman.Model[k] = function(label, scope) { - var collection, _base; - Batman.initializeObject(this); - collection = (_base = this._batman).associations || (_base.associations = new Batman.AssociationCurator(this)); - return collection.add(new Batman["" + (Batman.helpers.capitalize(k)) + "Association"](this, label, scope)); - }; - }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - _fn(k); - } - -}).call(this); - -(function() { - var __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; }; - - Batman.ParamsReplacer = (function(_super) { - - __extends(ParamsReplacer, _super); - - function ParamsReplacer(navigator, params) { - this.navigator = navigator; - this.params = params; - } - - ParamsReplacer.prototype.redirect = function() { - return this.navigator.replace(this.toObject()); - }; - - ParamsReplacer.prototype.replace = function(params) { - this.params.replace(params); - return this.redirect(); - }; - - ParamsReplacer.prototype.update = function(params) { - this.params.update(params); - return this.redirect(); - }; - - ParamsReplacer.prototype.clear = function() { - this.params.clear(); - return this.redirect(); - }; - - ParamsReplacer.prototype.toObject = function() { - return this.params.toObject(); - }; - - ParamsReplacer.accessor({ - get: function(k) { - return this.params.get(k); - }, - set: function(k, v) { - var oldValue, result; - oldValue = this.params.get(k); - result = this.params.set(k, v); - if (oldValue !== v) { - this.redirect(); - } - return result; - }, - unset: function(k) { - var hadKey, result; - hadKey = this.params.hasKey(k); - result = this.params.unset(k); - if (hadKey) { - this.redirect(); - } - return result; - } - }); - - return ParamsReplacer; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.ParamsPusher = (function(_super) { - - __extends(ParamsPusher, _super); - - function ParamsPusher() { - return ParamsPusher.__super__.constructor.apply(this, arguments); - } - - ParamsPusher.prototype.redirect = function() { - return this.navigator.push(this.toObject()); - }; - - return ParamsPusher; - - })(Batman.ParamsReplacer); - -}).call(this); - -(function() { - var __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; }; - - Batman.NamedRouteQuery = (function(_super) { - - __extends(NamedRouteQuery, _super); - - NamedRouteQuery.prototype.isNamedRouteQuery = true; - - function NamedRouteQuery(routeMap, args) { - var key; - if (args == null) { - args = []; - } - NamedRouteQuery.__super__.constructor.call(this, { - routeMap: routeMap, - args: args - }); - for (key in this.get('routeMap').childrenByName) { - this[key] = this._queryAccess.bind(this, key); - } - } - - NamedRouteQuery.accessor('route', function() { - var collectionRoute, memberRoute, route, _i, _len, _ref, _ref1; - _ref = this.get('routeMap'), memberRoute = _ref.memberRoute, collectionRoute = _ref.collectionRoute; - _ref1 = [memberRoute, collectionRoute]; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - route = _ref1[_i]; - if (route != null) { - if (route.namedArguments.length === this.get('args').length) { - return route; - } - } - } - return collectionRoute || memberRoute; - }); - - NamedRouteQuery.accessor('path', function() { - return this.path(); - }); - - NamedRouteQuery.accessor('routeMap', 'args', 'cardinality', 'hashValue', Batman.Property.defaultAccessor); - - NamedRouteQuery.accessor({ - get: function(key) { - if (key == null) { - return; - } - if (typeof key === 'string') { - return this.nextQueryForName(key); - } else { - return this.nextQueryWithArgument(key); - } - }, - cache: false - }); - - NamedRouteQuery.accessor('withHash', function() { - var _this = this; - return new Batman.Accessible(function(hashValue) { - return _this.withHash(hashValue); - }); - }); - - NamedRouteQuery.prototype.withHash = function(hashValue) { - var clone; - clone = this.clone(); - clone.set('hashValue', hashValue); - return clone; - }; - - NamedRouteQuery.prototype.nextQueryForName = function(key) { - var map; - if (map = this.get('routeMap').childrenByName[key]) { - return new Batman.NamedRouteQuery(map, this.args); - } else { - return Batman.developer.error("Couldn't find a route for the name " + key + "!"); - } - }; - - NamedRouteQuery.prototype.nextQueryWithArgument = function(arg) { - var args; - args = this.args.slice(0); - args.push(arg); - return this.clone(args); - }; - - NamedRouteQuery.prototype.path = function() { - var argumentName, argumentValue, index, namedArguments, params, _i, _len; - params = {}; - namedArguments = this.get('route.namedArguments'); - for (index = _i = 0, _len = namedArguments.length; _i < _len; index = ++_i) { - argumentName = namedArguments[index]; - if ((argumentValue = this.get('args')[index]) != null) { - params[argumentName] = this._toParam(argumentValue); - } - } - if (this.get('hashValue') != null) { - params['#'] = this.get('hashValue'); - } - return this.get('route').pathFromParams(params); - }; - - NamedRouteQuery.prototype.toString = function() { - return this.path(); - }; - - NamedRouteQuery.prototype.clone = function(args) { - if (args == null) { - args = this.args; - } - return new Batman.NamedRouteQuery(this.routeMap, args); - }; - - NamedRouteQuery.prototype._toParam = function(arg) { - if (arg instanceof Batman.AssociationProxy) { - arg = arg.get('target'); - } - if ((arg != null ? arg.toParam : void 0) != null) { - return arg.toParam(); - } else { - return arg; - } - }; - - NamedRouteQuery.prototype._queryAccess = function(key, arg) { - var query; - query = this.nextQueryForName(key); - if (arg != null) { - query = query.nextQueryWithArgument(arg); - } - return query; - }; - - return NamedRouteQuery; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.Dispatcher = (function(_super) { - var ControllerDirectory; - - __extends(Dispatcher, _super); - - Dispatcher.canInferRoute = function(argument) { - return argument instanceof Batman.Model || argument instanceof Batman.AssociationProxy || argument.prototype instanceof Batman.Model; - }; - - Dispatcher.paramsFromArgument = function(argument) { - var resourceNameFromModel; - resourceNameFromModel = function(model) { - return Batman.helpers.camelize(Batman.helpers.pluralize(model.get('resourceName')), true); - }; - if (!this.canInferRoute(argument)) { - return argument; - } - if (argument instanceof Batman.Model || argument instanceof Batman.AssociationProxy) { - if (argument.isProxy) { - argument = argument.get('target'); - } - if (argument != null) { - return { - controller: resourceNameFromModel(argument.constructor), - action: 'show', - id: argument.get('id') - }; - } else { - return {}; - } - } else if (argument.prototype instanceof Batman.Model) { - return { - controller: resourceNameFromModel(argument), - action: 'index' - }; - } else { - return argument; - } - }; - - ControllerDirectory = (function(_super1) { - - __extends(ControllerDirectory, _super1); - - function ControllerDirectory() { - return ControllerDirectory.__super__.constructor.apply(this, arguments); - } - - ControllerDirectory.accessor('__app', Batman.Property.defaultAccessor); - - ControllerDirectory.accessor(function(key) { - return this.get("__app." + (Batman.helpers.capitalize(key)) + "Controller.sharedController"); - }); - - return ControllerDirectory; - - })(Batman.Object); - - Dispatcher.accessor('controllers', function() { - return new ControllerDirectory({ - __app: this.get('app') - }); - }); - - function Dispatcher(app, routeMap) { - Dispatcher.__super__.constructor.call(this, { - app: app, - routeMap: routeMap - }); - } - - Dispatcher.prototype.routeForParams = function(params) { - params = this.constructor.paramsFromArgument(params); - return this.get('routeMap').routeForParams(params); - }; - - Dispatcher.prototype.pathFromParams = function(params) { - var _ref; - if (typeof params === 'string') { - return params; - } - params = this.constructor.paramsFromArgument(params); - return (_ref = this.routeForParams(params)) != null ? _ref.pathFromParams(params) : void 0; - }; - - Dispatcher.prototype.dispatch = function(params) { - var inferredParams, path, route, _ref; - inferredParams = this.constructor.paramsFromArgument(params); - route = this.routeForParams(inferredParams); - if (route) { - _ref = route.pathAndParamsFromArgument(inferredParams), path = _ref[0], params = _ref[1]; - this.set('app.currentRoute', route); - this.set('app.currentURL', path); - this.get('app.currentParams').replace(params || {}); - route.dispatch(params); - } else { - if (Batman.typeOf(params) === 'Object' && !this.constructor.canInferRoute(params)) { - return this.get('app.currentParams').replace(params); - } else { - this.get('app.currentParams').clear(); - } - if (params !== '/404') { - return Batman.redirect('/404'); - } - } - return path; - }; - - return Dispatcher; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.Route = (function(_super) { - - __extends(Route, _super); - - Route.regexps = { - namedParam: /:([\w\d]+)/g, - splatParam: /\*([\w\d]+)/g, - queryParam: '(?:\\?.+)?', - namedOrSplat: /[:|\*]([\w\d]+)/g, - namePrefix: '[:|\*]', - escapeRegExp: /[-[\]{}+?.,\\^$|#\s]/g, - openOptParam: /\(/g, - closeOptParam: /\)/g - }; - - Route.prototype.optionKeys = ['member', 'collection']; - - Route.prototype.testKeys = ['controller', 'action']; - - Route.prototype.isRoute = true; - - function Route(templatePath, baseParams) { - var k, matches, namedArguments, pattern, properties, regexp, regexps, _i, _len, _ref; - regexps = this.constructor.regexps; - if (templatePath.indexOf('/') !== 0) { - templatePath = "/" + templatePath; - } - pattern = templatePath.replace(regexps.escapeRegExp, '\\$&'); - regexp = RegExp("^" + (pattern.replace(regexps.openOptParam, '(?:').replace(regexps.closeOptParam, ')?').replace(regexps.namedParam, '([^\/]+)').replace(regexps.splatParam, '(.*?)')) + regexps.queryParam + "$"); - namedArguments = ((function() { - var _results; - _results = []; - while (matches = regexps.namedOrSplat.exec(pattern)) { - _results.push(matches[1]); - } - return _results; - })()); - properties = { - templatePath: templatePath, - pattern: pattern, - regexp: regexp, - namedArguments: namedArguments, - baseParams: baseParams - }; - _ref = this.optionKeys; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - properties[k] = baseParams[k]; - delete baseParams[k]; - } - Route.__super__.constructor.call(this, properties); - } - - Route.prototype.paramsFromPath = function(pathAndQuery) { - var index, match, matches, name, namedArguments, params, uri, _i, _len; - uri = new Batman.URI(pathAndQuery); - namedArguments = this.get('namedArguments'); - params = Batman.extend({ - path: uri.path - }, this.get('baseParams')); - matches = this.get('regexp').exec(uri.path).slice(1); - for (index = _i = 0, _len = matches.length; _i < _len; index = ++_i) { - match = matches[index]; - name = namedArguments[index]; - params[name] = match; - } - return Batman.extend(params, uri.queryParams); - }; - - Route.prototype.pathFromParams = function(argumentParams) { - var hash, key, name, newPath, params, path, query, regexp, regexps, _i, _j, _len, _len1, _ref, _ref1; - params = Batman.extend({}, argumentParams); - path = this.get('templatePath'); - regexps = this.constructor.regexps; - _ref = this.get('namedArguments'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - regexp = RegExp("" + regexps.namePrefix + name); - newPath = path.replace(regexp, (params[name] != null ? params[name] : '')); - if (newPath !== path) { - delete params[name]; - path = newPath; - } - } - path = path.replace(regexps.openOptParam, '').replace(regexps.closeOptParam, '').replace(/([^\/])\/+$/, '$1'); - _ref1 = this.testKeys; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - key = _ref1[_j]; - delete params[key]; - } - if (params['#']) { - hash = params['#']; - delete params['#']; - } - query = Batman.URI.queryFromParams(params); - if (query) { - path += "?" + query; - } - if (hash) { - path += "#" + hash; - } - return path; - }; - - Route.prototype.test = function(pathOrParams) { - var key, path, value, _i, _len, _ref; - if (typeof pathOrParams === 'string') { - path = pathOrParams; - } else if (pathOrParams.path != null) { - path = pathOrParams.path; - } else { - path = this.pathFromParams(pathOrParams); - _ref = this.testKeys; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - if ((value = this.get(key)) != null) { - if (pathOrParams[key] !== value) { - return false; - } - } - } - } - return this.get('regexp').test(path); - }; - - Route.prototype.pathAndParamsFromArgument = function(pathOrParams) { - var params, path; - if (typeof pathOrParams === 'string') { - params = this.paramsFromPath(pathOrParams); - path = pathOrParams; - } else { - params = pathOrParams; - path = this.pathFromParams(pathOrParams); - } - return [path, params]; - }; - - Route.prototype.dispatch = function(params) { - if (!this.test(params)) { - return false; - } - return this.get('callback')(params); - }; - - Route.prototype.callback = function() { - throw new Batman.DevelopmentError("Override callback in a Route subclass"); - }; - - return Route; - - })(Batman.Object); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Batman.ControllerActionRoute = (function(_super) { - - __extends(ControllerActionRoute, _super); - - ControllerActionRoute.prototype.optionKeys = ['member', 'collection', 'app', 'controller', 'action']; - - function ControllerActionRoute(templatePath, options) { - this.callback = __bind(this.callback, this); - - var action, controller, _ref; - if (options.signature) { - _ref = options.signature.split('#'), controller = _ref[0], action = _ref[1]; - action || (action = 'index'); - options.controller = controller; - options.action = action; - delete options.signature; - } - ControllerActionRoute.__super__.constructor.call(this, templatePath, options); - } - - ControllerActionRoute.prototype.callback = function(params) { - var controller; - controller = this.get("app.dispatcher.controllers." + (this.get('controller'))); - return controller.dispatch(this.get('action'), params); - }; - - return ControllerActionRoute; - - })(Batman.Route); - -}).call(this); - -(function() { - var __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; }; - - Batman.CallbackActionRoute = (function(_super) { - - __extends(CallbackActionRoute, _super); - - function CallbackActionRoute() { - return CallbackActionRoute.__super__.constructor.apply(this, arguments); - } - - CallbackActionRoute.prototype.optionKeys = ['member', 'collection', 'callback', 'app']; - - CallbackActionRoute.prototype.controller = false; - - CallbackActionRoute.prototype.action = false; - - return CallbackActionRoute; - - })(Batman.Route); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.Hash = (function(_super) { - var k, _fn, _i, _j, _len, _len1, _ref, _ref1, - _this = this; - - __extends(Hash, _super); - - Hash.Metadata = (function(_super1) { - - __extends(Metadata, _super1); - - Batman.extend(Metadata.prototype, Batman.Enumerable); - - function Metadata(hash) { - this.hash = hash; - } - - Metadata.accessor('length', function() { - this.hash.registerAsMutableSource(); - return this.hash.length; - }); - - Metadata.accessor('isEmpty', 'keys', 'toArray', function(key) { - this.hash.registerAsMutableSource(); - return this.hash[key](); - }); - - Metadata.prototype.forEach = function() { - var _ref; - return (_ref = this.hash).forEach.apply(_ref, arguments); - }; - - return Metadata; - - })(Batman.Object); - - function Hash() { - this.meta = new this.constructor.Metadata(this); - Batman.SimpleHash.apply(this, arguments); - Hash.__super__.constructor.apply(this, arguments); - } - - Batman.extend(Hash.prototype, Batman.Enumerable); - - Hash.prototype.propertyClass = Batman.Property; - - Hash.defaultAccessor = { - get: Batman.SimpleHash.prototype.get, - set: Hash.mutation(function(key, value) { - var result; - result = Batman.SimpleHash.prototype.set.call(this, key, value); - this.fire('itemsWereAdded', key); - return result; - }), - unset: Hash.mutation(function(key) { - var result; - result = Batman.SimpleHash.prototype.unset.call(this, key); - if (result != null) { - this.fire('itemsWereRemoved', key); - } - return result; - }), - cache: false - }; - - Hash.accessor(Hash.defaultAccessor); - - Hash.prototype._preventMutationEvents = function(block) { - this.prevent('change'); - this.prevent('itemsWereAdded'); - this.prevent('itemsWereRemoved'); - try { - return block.call(this); - } finally { - this.allow('change'); - this.allow('itemsWereAdded'); - this.allow('itemsWereRemoved'); - } - }; - - Hash.prototype.clear = Hash.mutation(function() { - var keys, result; - keys = this.keys(); - this._preventMutationEvents(function() { - var _this = this; - return this.forEach(function(k) { - return _this.unset(k); - }); - }); - result = Batman.SimpleHash.prototype.clear.call(this); - this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(keys))); - return result; - }); - - Hash.prototype.update = Hash.mutation(function(object) { - var addedKeys; - addedKeys = []; - this._preventMutationEvents(function() { - var _this = this; - return Batman.forEach(object, function(k, v) { - if (!_this.hasKey(k)) { - addedKeys.push(k); - } - return _this.set(k, v); - }); - }); - if (addedKeys.length > 0) { - return this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedKeys))); - } - }); - - Hash.prototype.replace = Hash.mutation(function(object) { - var addedKeys, removedKeys; - addedKeys = []; - removedKeys = []; - this._preventMutationEvents(function() { - var _this = this; - this.forEach(function(k, _) { - if (!Batman.objectHasKey(object, k)) { - _this.unset(k); - return removedKeys.push(k); - } - }); - return Batman.forEach(object, function(k, v) { - if (!_this.hasKey(k)) { - addedKeys.push(k); - } - return _this.set(k, v); - }); - }); - if (addedKeys.length > 0) { - this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(addedKeys))); - } - if (removedKeys.length > 0) { - return this.fire.apply(this, ['itemsWereRemoved'].concat(__slice.call(removedKeys))); - } - }); - - _ref = ['equality', 'hashKeyFor', 'objectKey', 'prefixedKey', 'unprefixedKey']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - Hash.prototype[k] = Batman.SimpleHash.prototype[k]; - } - - _ref1 = ['hasKey', 'forEach', 'isEmpty', 'keys', 'toArray', 'merge', 'toJSON', 'toObject']; - _fn = function(k) { - return Hash.prototype[k] = function() { - this.registerAsMutableSource(); - return Batman.SimpleHash.prototype[k].apply(this, arguments); - }; - }; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - k = _ref1[_j]; - _fn(k); - } - - return Hash; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.RenderCache = (function(_super) { - - __extends(RenderCache, _super); - - RenderCache.prototype.maximumLength = 4; - - function RenderCache() { - RenderCache.__super__.constructor.apply(this, arguments); - this.keyQueue = []; - } - - RenderCache.prototype.viewForOptions = function(options) { - var _this = this; - if (options.cache === false || options.viewClass.prototype.cache === false) { - return this._newViewFromOptions(options); - } - return this.getOrSet(options, function() { - return _this._newViewFromOptions(Batman.extend({}, options)); - }); - }; - - RenderCache.prototype._newViewFromOptions = function(options) { - return new options.viewClass(options); - }; - - RenderCache.wrapAccessor(function(core) { - return { - cache: false, - get: function(key) { - var result; - result = core.get.call(this, key); - if (result) { - this._addOrBubbleKey(key); - } - return result; - }, - set: function(key, value) { - var result; - result = core.set.apply(this, arguments); - result.set('cached', true); - this._addOrBubbleKey(key); - this._evictExpiredKeys(); - return result; - }, - unset: function(key) { - var result; - result = core.unset.apply(this, arguments); - result.set('cached', false); - this._removeKeyFromQueue(key); - return result; - } - }; - }); - - RenderCache.prototype.equality = function(incomingOptions, storageOptions) { - var key; - if (Object.keys(incomingOptions).length !== Object.keys(storageOptions).length) { - return false; - } - for (key in incomingOptions) { - if (!(key === 'view')) { - if (incomingOptions[key] !== storageOptions[key]) { - return false; - } - } - } - return true; - }; - - RenderCache.prototype.reset = function() { - var key, _i, _len, _ref, _results; - _ref = this.keyQueue.slice(0); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - _results.push(this.unset(key)); - } - return _results; - }; - - RenderCache.prototype._addOrBubbleKey = function(key) { - this._removeKeyFromQueue(key); - return this.keyQueue.unshift(key); - }; - - RenderCache.prototype._removeKeyFromQueue = function(key) { - var index, queuedKey, _i, _len, _ref; - _ref = this.keyQueue; - for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { - queuedKey = _ref[index]; - if (this.equality(queuedKey, key)) { - this.keyQueue.splice(index, 1); - break; - } - } - return key; - }; - - RenderCache.prototype._evictExpiredKeys = function() { - var currentKeys, i, key, _i, _ref, _ref1; - if (this.length > this.maximumLength) { - currentKeys = this.keyQueue.slice(0); - for (i = _i = _ref = this.maximumLength, _ref1 = currentKeys.length; _ref <= _ref1 ? _i < _ref1 : _i > _ref1; i = _ref <= _ref1 ? ++_i : --_i) { - key = currentKeys[i]; - if (!this.get(key).isInDOM()) { - this.unset(key); - } - } - } - }; - - return RenderCache; - - })(Batman.Hash); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Batman.Controller = (function(_super) { - var _optionsFromFilterArguments; - - __extends(Controller, _super); - - Controller.singleton('sharedController'); - - Controller.wrapAccessor('routingKey', function(core) { - return { - get: function() { - if (this.routingKey != null) { - return this.routingKey; - } else { - if (Batman.config.minificationErrors) { - Batman.developer.error("Please define `routingKey` on the prototype of " + (Batman.functionName(this.constructor)) + " in order for your controller to be minification safe."); - } - return Batman.functionName(this.constructor).replace(/Controller$/, ''); - } - } - }; - }); - - Controller.accessor('_renderContext', function() { - return Batman.RenderContext.root().descend(this); - }); - - _optionsFromFilterArguments = function(options, nameOrFunction) { - if (!nameOrFunction) { - nameOrFunction = options; - options = {}; - } else { - if (typeof options === 'string') { - options = { - only: [options] - }; - } else { - if (options.only && Batman.typeOf(options.only) !== 'Array') { - options.only = [options.only]; - } - if (options.except && Batman.typeOf(options.except) !== 'Array') { - options.except = [options.except]; - } - } - } - options.block = nameOrFunction; - return options; - }; - - Controller.beforeFilter = function() { - var filters, options, _base; - Batman.initializeObject(this); - options = _optionsFromFilterArguments.apply(null, arguments); - filters = (_base = this._batman).beforeFilters || (_base.beforeFilters = new Batman.SimpleHash); - return filters.set(options.block, options); - }; - - Controller.afterFilter = function() { - var filters, options, _base; - Batman.initializeObject(this); - options = _optionsFromFilterArguments.apply(null, arguments); - filters = (_base = this._batman).afterFilters || (_base.afterFilters = new Batman.SimpleHash); - return filters.set(options.block, options); - }; - - Controller.afterFilter(function(params) { - if (this.autoScrollToHash && (params['#'] != null)) { - return this.scrollToHash(params['#']); - } - }); - - function Controller() { - this.redirect = __bind(this.redirect, this); - Controller.__super__.constructor.apply(this, arguments); - this._resetActionFrames(); - } - - Controller.prototype.renderCache = new Batman.RenderCache; - - Controller.prototype.defaultRenderYield = 'main'; - - Controller.prototype.autoScrollToHash = true; - - Controller.prototype.dispatch = function(action, params) { - var redirectTo; - if (params == null) { - params = {}; - } - params.controller || (params.controller = this.get('routingKey')); - params.action || (params.action = action); - params.target || (params.target = this); - this._resetActionFrames(); - this.set('action', action); - this.set('params', params); - Batman.DOM.Yield.cycleAll(); - this.executeAction(action, params); - Batman.DOM.Yield.clearAllStale(); - redirectTo = this._afterFilterRedirect; - delete this._afterFilterRedirect; - if (redirectTo) { - return Batman.redirect(redirectTo); - } - }; - - Controller.prototype.executeAction = function(action, params) { - var frame, oldRedirect, parentFrame, result, _ref, _ref1, - _this = this; - if (params == null) { - params = this.get('params'); - } - Batman.developer.assert(this[action], "Error! Controller action " + (this.get('routingKey')) + "." + action + " couldn't be found!"); - parentFrame = this._actionFrames[this._actionFrames.length - 1]; - frame = new Batman.ControllerActionFrame({ - parentFrame: parentFrame, - action: action - }, function() { - var _ref; - _this._runFilters(action, params, 'afterFilters'); - _this._resetActionFrames(); - return (_ref = Batman.navigator) != null ? _ref.redirect = oldRedirect : void 0; - }); - this._actionFrames.push(frame); - frame.startOperation({ - internal: true - }); - oldRedirect = (_ref = Batman.navigator) != null ? _ref.redirect : void 0; - if ((_ref1 = Batman.navigator) != null) { - _ref1.redirect = this.redirect; - } - this._runFilters(action, params, 'beforeFilters'); - result = this[action](params); - if (!frame.operationOccurred) { - this.render(); - } - frame.finishOperation(); - return result; - }; - - Controller.prototype.redirect = function(url) { - var frame; - frame = this._actionFrames[this._actionFrames.length - 1]; - if (frame) { - if (frame.operationOccurred) { - Batman.developer.warn("Warning! Trying to redirect but an action has already been taken during " + (this.get('routingKey')) + "." + (frame.action || this.get('action'))); - } - frame.startAndFinishOperation(); - if (this._afterFilterRedirect != null) { - return Batman.developer.warn("Warning! Multiple actions trying to redirect!"); - } else { - return this._afterFilterRedirect = url; - } - } else { - if (Batman.typeOf(url) === 'Object') { - if (!url.controller) { - url.controller = this; - } - } - return Batman.redirect(url); - } - }; - - Controller.prototype.render = function(options) { - var action, frame, view, _ref, _ref1, - _this = this; - if (options == null) { - options = {}; - } - if (frame = (_ref = this._actionFrames) != null ? _ref[this._actionFrames.length - 1] : void 0) { - frame.startOperation(); - } - if (options === false) { - frame.finishOperation(); - return; - } - action = (frame != null ? frame.action : void 0) || this.get('action'); - if (options) { - options.into || (options.into = this.defaultRenderYield); - } - if (!options.view) { - options.viewClass || (options.viewClass = this._viewClassForAction(action)); - options.context || (options.context = this.get('_renderContext')); - options.source || (options.source = Batman.helpers.underscore(this.get('routingKey') + '/' + action)); - view = this.renderCache.viewForOptions(options); - } else { - view = options.view; - options.view = null; - } - if (view) { - if ((_ref1 = Batman.currentApp) != null) { - _ref1.prevent('ready'); - } - view.on('ready', function() { - var _ref2; - Batman.DOM.Yield.withName(options.into).replace(view.get('node')); - if ((_ref2 = Batman.currentApp) != null) { - _ref2.allowAndFire('ready'); - } - return frame != null ? frame.finishOperation() : void 0; - }); - } - return view; - }; - - Controller.prototype.scrollToHash = function(hash) { - if (hash == null) { - hash = this.get('params')['#']; - } - return Batman.DOM.scrollIntoView(hash); - }; - - Controller.prototype._resetActionFrames = function() { - return this._actionFrames = []; - }; - - Controller.prototype._viewClassForAction = function(action) { - var classPrefix, _ref; - classPrefix = this.get('routingKey').replace('/', '_'); - return ((_ref = Batman.currentApp) != null ? _ref[Batman.helpers.camelize("" + classPrefix + "_" + action + "_view")] : void 0) || Batman.View; - }; - - Controller.prototype._runFilters = function(action, params, filters) { - var _ref, - _this = this; - if (filters = (_ref = this.constructor._batman) != null ? _ref.get(filters) : void 0) { - return filters.forEach(function(_, options) { - var block; - if (options.only && __indexOf.call(options.only, action) < 0) { - return; - } - if (options.except && __indexOf.call(options.except, action) >= 0) { - return; - } - block = options.block; - if (typeof block === 'function') { - return block.call(_this, params); - } else { - return typeof _this[block] === "function" ? _this[block](params) : void 0; - } - }); - } - }; - - return Controller; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.Set = (function(_super) { - var k, _fn, _i, _j, _len, _len1, _ref, _ref1, - _this = this; - - __extends(Set, _super); - - function Set() { - Batman.SimpleSet.apply(this, arguments); - } - - Batman.extend(Set.prototype, Batman.Enumerable); - - Set._applySetAccessors = function(klass) { - var accessor, accessors, key, _results; - accessors = { - first: function() { - return this.toArray()[0]; - }, - last: function() { - return this.toArray()[this.length - 1]; - }, - isEmpty: function() { - return this.isEmpty(); - }, - toArray: function() { - return this.toArray(); - }, - length: function() { - this.registerAsMutableSource(); - return this.length; - }, - indexedBy: function() { - var _this = this; - return new Batman.TerminalAccessible(function(key) { - return _this.indexedBy(key); - }); - }, - indexedByUnique: function() { - var _this = this; - return new Batman.TerminalAccessible(function(key) { - return _this.indexedByUnique(key); - }); - }, - sortedBy: function() { - var _this = this; - return new Batman.TerminalAccessible(function(key) { - return _this.sortedBy(key); - }); - }, - sortedByDescending: function() { - var _this = this; - return new Batman.TerminalAccessible(function(key) { - return _this.sortedBy(key, 'desc'); - }); - } - }; - _results = []; - for (key in accessors) { - accessor = accessors[key]; - _results.push(klass.accessor(key, accessor)); - } - return _results; - }; - - Set._applySetAccessors(Set); - - _ref = ['add', 'remove', 'clear', 'replace', 'indexedBy', 'indexedByUnique', 'sortedBy', 'equality', '_indexOfItem']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - Set.prototype[k] = Batman.SimpleSet.prototype[k]; - } - - _ref1 = ['find', 'merge', 'forEach', 'toArray', 'isEmpty', 'has']; - _fn = function(k) { - return Set.prototype[k] = function() { - this.registerAsMutableSource(); - return Batman.SimpleSet.prototype[k].apply(this, arguments); - }; - }; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - k = _ref1[_j]; - _fn(k); - } - - Set.prototype.toJSON = Set.prototype.toArray; - - return Set; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.ErrorsSet = (function(_super) { - - __extends(ErrorsSet, _super); - - function ErrorsSet() { - return ErrorsSet.__super__.constructor.apply(this, arguments); - } - - ErrorsSet.accessor(function(key) { - return this.indexedBy('attribute').get(key); - }); - - ErrorsSet.prototype.add = function(key, error) { - return ErrorsSet.__super__.add.call(this, new Batman.ValidationError(key, error)); - }; - - return ErrorsSet; - - })(Batman.Set); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetProxy = (function(_super) { - var k, _fn, _i, _len, _ref, - _this = this; - - __extends(SetProxy, _super); - - function SetProxy(base) { - var _this = this; - this.base = base; - SetProxy.__super__.constructor.call(this); - this.length = this.base.length; - this.base.on('itemsWereAdded', function() { - var items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _this.set('length', _this.base.length); - return _this.fire.apply(_this, ['itemsWereAdded'].concat(__slice.call(items))); - }); - this.base.on('itemsWereRemoved', function() { - var items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _this.set('length', _this.base.length); - return _this.fire.apply(_this, ['itemsWereRemoved'].concat(__slice.call(items))); - }); - } - - Batman.extend(SetProxy.prototype, Batman.Enumerable); - - SetProxy.prototype.filter = function(f) { - var r; - r = new Batman.Set(); - return this.reduce((function(r, e) { - if (f(e)) { - r.add(e); - } - return r; - }), r); - }; - - SetProxy.prototype.replace = function() { - var length, result; - length = this.property('length'); - length.isolate(); - result = this.base.replace.apply(this, arguments); - length.expose(); - return result; - }; - - _ref = ['add', 'remove', 'find', 'clear', 'has', 'merge', 'toArray', 'isEmpty', 'indexedBy', 'indexedByUnique', 'sortedBy']; - _fn = function(k) { - return SetProxy.prototype[k] = function() { - var _ref1; - return (_ref1 = this.base)[k].apply(_ref1, arguments); - }; - }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - _fn(k); - } - - Batman.Set._applySetAccessors(SetProxy); - - SetProxy.accessor('length', { - get: function() { - this.registerAsMutableSource(); - return this.length; - }, - set: function(_, v) { - return this.length = v; - } - }); - - return SetProxy; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }, - __slice = [].slice; - - Batman.BinarySetOperation = (function(_super) { - - __extends(BinarySetOperation, _super); - - function BinarySetOperation(left, right) { - this.left = left; - this.right = right; - this._setup = __bind(this._setup, this); - - BinarySetOperation.__super__.constructor.call(this); - this._setup(this.left, this.right); - this._setup(this.right, this.left); - } - - BinarySetOperation.prototype._setup = function(set, opposite) { - var _this = this; - set.on('itemsWereAdded', function() { - var items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _this._itemsWereAddedToSource.apply(_this, [set, opposite].concat(__slice.call(items))); - }); - set.on('itemsWereRemoved', function() { - var items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _this._itemsWereRemovedFromSource.apply(_this, [set, opposite].concat(__slice.call(items))); - }); - return this._itemsWereAddedToSource.apply(this, [set, opposite].concat(__slice.call(set.toArray()))); - }; - - BinarySetOperation.prototype.merge = function() { - var merged, others, set, _i, _len; - others = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - merged = new Batman.Set; - others.unshift(this); - for (_i = 0, _len = others.length; _i < _len; _i++) { - set = others[_i]; - set.forEach(function(v) { - return merged.add(v); - }); - } - return merged; - }; - - BinarySetOperation.prototype.filter = Batman.SetProxy.prototype.filter; - - return BinarySetOperation; - - })(Batman.Set); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetUnion = (function(_super) { - - __extends(SetUnion, _super); - - function SetUnion() { - return SetUnion.__super__.constructor.apply(this, arguments); - } - - SetUnion.prototype._itemsWereAddedToSource = function() { - var items, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - return this.add.apply(this, items); - }; - - SetUnion.prototype._itemsWereRemovedFromSource = function() { - var item, items, itemsToRemove, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - itemsToRemove = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!opposite.has(item)) { - _results.push(item); - } - } - return _results; - })(); - return this.remove.apply(this, itemsToRemove); - }; - - return SetUnion; - - })(Batman.BinarySetOperation); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetIntersection = (function(_super) { - - __extends(SetIntersection, _super); - - function SetIntersection() { - return SetIntersection.__super__.constructor.apply(this, arguments); - } - - SetIntersection.prototype._itemsWereAddedToSource = function() { - var item, items, itemsToAdd, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - itemsToAdd = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (opposite.has(item)) { - _results.push(item); - } - } - return _results; - })(); - return this.add.apply(this, itemsToAdd); - }; - - SetIntersection.prototype._itemsWereRemovedFromSource = function() { - var items, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - return this.remove.apply(this, items); - }; - - return SetIntersection; - - })(Batman.BinarySetOperation); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetComplement = (function(_super) { - - __extends(SetComplement, _super); - - function SetComplement() { - return SetComplement.__super__.constructor.apply(this, arguments); - } - - SetComplement.prototype._itemsWereAddedToSource = function() { - var item, items, itemsToAdd, itemsToRemove, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - if (source === this.left) { - itemsToAdd = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!opposite.has(item)) { - _results.push(item); - } - } - return _results; - })(); - return this.add.apply(this, itemsToAdd); - } else { - itemsToRemove = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (opposite.has(item)) { - _results.push(item); - } - } - return _results; - })(); - return this.remove.apply(this, itemsToRemove); - } - }; - - SetComplement.prototype._itemsWereRemovedFromSource = function() { - var item, items, itemsToAdd, opposite, source; - source = arguments[0], opposite = arguments[1], items = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - if (source === this.left) { - return this.remove.apply(this, items); - } else { - itemsToAdd = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (opposite.has(item)) { - _results.push(item); - } - } - return _results; - })(); - return this.add.apply(this, itemsToAdd); - } - }; - - SetComplement.prototype._addComplement = function(items, opposite) { - var item; - return this.add.apply(this, (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (opposite.has(item)) { - _results.push(item); - } - } - return _results; - })()); - }; - - return SetComplement; - - })(Batman.BinarySetOperation); - -}).call(this); - -(function() { - - Batman.mixins = new Batman.Object; - -}).call(this); - -(function() { - var __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; }; - - Batman.Accessible = (function(_super) { - - __extends(Accessible, _super); - - function Accessible() { - this.accessor.apply(this, arguments); - } - - return Accessible; - - })(Batman.Object); - - Batman.TerminalAccessible = (function(_super) { - - __extends(TerminalAccessible, _super); - - function TerminalAccessible() { - return TerminalAccessible.__super__.constructor.apply(this, arguments); - } - - TerminalAccessible.prototype.propertyClass = Batman.Property; - - return TerminalAccessible; - - })(Batman.Accessible); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetObserver = (function(_super) { - - __extends(SetObserver, _super); - - function SetObserver(base) { - var _this = this; - this.base = base; - this._itemObservers = new Batman.SimpleHash; - this._setObservers = new Batman.SimpleHash; - this._setObservers.set("itemsWereAdded", function() { - return _this.fire.apply(_this, ['itemsWereAdded'].concat(__slice.call(arguments))); - }); - this._setObservers.set("itemsWereRemoved", function() { - return _this.fire.apply(_this, ['itemsWereRemoved'].concat(__slice.call(arguments))); - }); - this.on('itemsWereAdded', this.startObservingItems.bind(this)); - this.on('itemsWereRemoved', this.stopObservingItems.bind(this)); - } - - SetObserver.prototype.observedItemKeys = []; - - SetObserver.prototype.observerForItemAndKey = function(item, key) {}; - - SetObserver.prototype._getOrSetObserverForItemAndKey = function(item, key) { - var _this = this; - return this._itemObservers.getOrSet(item, function() { - var observersByKey; - observersByKey = new Batman.SimpleHash; - return observersByKey.getOrSet(key, function() { - return _this.observerForItemAndKey(item, key); - }); - }); - }; - - SetObserver.prototype.startObserving = function() { - this._manageItemObservers("observe"); - return this._manageSetObservers("addHandler"); - }; - - SetObserver.prototype.stopObserving = function() { - this._manageItemObservers("forget"); - return this._manageSetObservers("removeHandler"); - }; - - SetObserver.prototype.startObservingItems = function() { - var item, items, _i, _len, _results; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - _results.push(this._manageObserversForItem(item, "observe")); - } - return _results; - }; - - SetObserver.prototype.stopObservingItems = function() { - var item, items, _i, _len, _results; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - _results.push(this._manageObserversForItem(item, "forget")); - } - return _results; - }; - - SetObserver.prototype._manageObserversForItem = function(item, method) { - var key, _i, _len, _ref; - if (!item.isObservable) { - return; - } - _ref = this.observedItemKeys; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - item[method](key, this._getOrSetObserverForItemAndKey(item, key)); - } - if (method === "forget") { - return this._itemObservers.unset(item); - } - }; - - SetObserver.prototype._manageItemObservers = function(method) { - var _this = this; - return this.base.forEach(function(item) { - return _this._manageObserversForItem(item, method); - }); - }; - - SetObserver.prototype._manageSetObservers = function(method) { - var _this = this; - if (!this.base.isObservable) { - return; - } - return this._setObservers.forEach(function(key, observer) { - return _this.base.event(key)[method](observer); - }); - }; - - return SetObserver; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.SetSort = (function(_super) { - - __extends(SetSort, _super); - - function SetSort(base, key, order) { - var boundReIndex; - this.key = key; - if (order == null) { - order = "asc"; - } - SetSort.__super__.constructor.call(this, base); - this.descending = order.toLowerCase() === "desc"; - if (this.base.isObservable) { - this._setObserver = new Batman.SetObserver(this.base); - this._setObserver.observedItemKeys = [this.key]; - boundReIndex = this._reIndex.bind(this); - this._setObserver.observerForItemAndKey = function() { - return boundReIndex; - }; - this._setObserver.on('itemsWereAdded', boundReIndex); - this._setObserver.on('itemsWereRemoved', boundReIndex); - this.startObserving(); - } - this._reIndex(); - } - - SetSort.prototype.startObserving = function() { - var _ref; - return (_ref = this._setObserver) != null ? _ref.startObserving() : void 0; - }; - - SetSort.prototype.stopObserving = function() { - var _ref; - return (_ref = this._setObserver) != null ? _ref.stopObserving() : void 0; - }; - - SetSort.prototype.toArray = function() { - return this.get('_storage'); - }; - - SetSort.prototype.forEach = function(iterator, ctx) { - var e, i, _i, _len, _ref, _results; - _ref = this.get('_storage'); - _results = []; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - e = _ref[i]; - _results.push(iterator.call(ctx, e, i, this)); - } - return _results; - }; - - SetSort.prototype.compare = function(a, b) { - if (a === b) { - return 0; - } - if (a === void 0) { - return 1; - } - if (b === void 0) { - return -1; - } - if (a === null) { - return 1; - } - if (b === null) { - return -1; - } - if (a === false) { - return 1; - } - if (b === false) { - return -1; - } - if (a === true) { - return 1; - } - if (b === true) { - return -1; - } - if (a !== a) { - if (b !== b) { - return 0; - } else { - return 1; - } - } - if (b !== b) { - return -1; - } - if (a > b) { - return 1; - } - if (a < b) { - return -1; - } - return 0; - }; - - SetSort.prototype._reIndex = function() { - var newOrder, _ref, - _this = this; - newOrder = this.base.toArray().sort(function(a, b) { - var multiple, valueA, valueB; - valueA = Batman.get(a, _this.key); - if (typeof valueA === 'function') { - valueA = valueA.call(a); - } - if (valueA != null) { - valueA = valueA.valueOf(); - } - valueB = Batman.get(b, _this.key); - if (typeof valueB === 'function') { - valueB = valueB.call(b); - } - if (valueB != null) { - valueB = valueB.valueOf(); - } - multiple = _this.descending ? -1 : 1; - return _this.compare.call(_this, valueA, valueB) * multiple; - }); - if ((_ref = this._setObserver) != null) { - _ref.startObservingItems.apply(_ref, newOrder); - } - return this.set('_storage', newOrder); - }; - - return SetSort; - - })(Batman.SetProxy); - -}).call(this); - -(function() { - var __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; }; - - Batman.AssociationSet = (function(_super) { - - __extends(AssociationSet, _super); - - function AssociationSet(foreignKeyValue, association) { - var base; - this.foreignKeyValue = foreignKeyValue; - this.association = association; - base = new Batman.Set; - AssociationSet.__super__.constructor.call(this, base, '_batmanID'); - } - - AssociationSet.prototype.loaded = false; - - AssociationSet.prototype.load = function(callback) { - var _this = this; - if (this.foreignKeyValue == null) { - return callback(void 0, this); - } - return this.association.getRelatedModel().load(this._getLoadOptions(), function(err, records) { - if (!err) { - _this.markAsLoaded(); - } - return callback(err, _this); - }); - }; - - AssociationSet.prototype._getLoadOptions = function() { - var loadOptions; - loadOptions = {}; - loadOptions[this.association.foreignKey] = this.foreignKeyValue; - return loadOptions; - }; - - AssociationSet.accessor('loaded', Batman.Property.defaultAccessor); - - AssociationSet.prototype.markAsLoaded = function() { - this.set('loaded', true); - return this.fire('loaded'); - }; - - return AssociationSet; - - })(Batman.SetSort); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicAssociationSet = (function(_super) { - - __extends(PolymorphicAssociationSet, _super); - - function PolymorphicAssociationSet(foreignKeyValue, foreignTypeKeyValue, association) { - this.foreignKeyValue = foreignKeyValue; - this.foreignTypeKeyValue = foreignTypeKeyValue; - this.association = association; - PolymorphicAssociationSet.__super__.constructor.call(this, this.foreignKeyValue, this.association); - } - - PolymorphicAssociationSet.prototype._getLoadOptions = function() { - var loadOptions; - loadOptions = {}; - loadOptions[this.association.foreignKey] = this.foreignKeyValue; - loadOptions[this.association.foreignTypeKey] = this.foreignTypeKeyValue; - return loadOptions; - }; - - return PolymorphicAssociationSet; - - })(Batman.AssociationSet); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.SetIndex = (function(_super) { - - __extends(SetIndex, _super); - - SetIndex.accessor('toArray', function() { - return this.toArray(); - }); - - Batman.extend(SetIndex.prototype, Batman.Enumerable); - - SetIndex.prototype.propertyClass = Batman.Property; - - function SetIndex(base, key) { - var _this = this; - this.base = base; - this.key = key; - SetIndex.__super__.constructor.call(this); - this._storage = new Batman.Hash; - if (this.base.isEventEmitter) { - this._setObserver = new Batman.SetObserver(this.base); - this._setObserver.observedItemKeys = [this.key]; - this._setObserver.observerForItemAndKey = this.observerForItemAndKey.bind(this); - this._setObserver.on('itemsWereAdded', function() { - var item, items, _i, _len, _results; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - _results.push(_this._addItem(item)); - } - return _results; - }); - this._setObserver.on('itemsWereRemoved', function() { - var item, items, _i, _len, _results; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - _results.push(_this._removeItem(item)); - } - return _results; - }); - } - this.base.forEach(this._addItem.bind(this)); - this.startObserving(); - } - - SetIndex.accessor(function(key) { - return this._resultSetForKey(key); - }); - - SetIndex.prototype.startObserving = function() { - var _ref; - return (_ref = this._setObserver) != null ? _ref.startObserving() : void 0; - }; - - SetIndex.prototype.stopObserving = function() { - var _ref; - return (_ref = this._setObserver) != null ? _ref.stopObserving() : void 0; - }; - - SetIndex.prototype.observerForItemAndKey = function(item, key) { - var _this = this; - return function(newValue, oldValue) { - _this._removeItemFromKey(item, oldValue); - return _this._addItemToKey(item, newValue); - }; - }; - - SetIndex.prototype.forEach = function(iterator, ctx) { - var _this = this; - return this._storage.forEach(function(key, set) { - if (set.get('length') > 0) { - return iterator.call(ctx, key, set, _this); - } - }); - }; - - SetIndex.prototype.toArray = function() { - var results; - results = []; - this._storage.forEach(function(key, set) { - if (set.get('length') > 0) { - return results.push(key); - } - }); - return results; - }; - - SetIndex.prototype._addItem = function(item) { - return this._addItemToKey(item, this._keyForItem(item)); - }; - - SetIndex.prototype._addItemToKey = function(item, key) { - return this._resultSetForKey(key).add(item); - }; - - SetIndex.prototype._removeItem = function(item) { - return this._removeItemFromKey(item, this._keyForItem(item)); - }; - - SetIndex.prototype._removeItemFromKey = function(item, key) { - return this._resultSetForKey(key).remove(item); - }; - - SetIndex.prototype._resultSetForKey = function(key) { - return this._storage.getOrSet(key, function() { - return new Batman.Set; - }); - }; - - SetIndex.prototype._keyForItem = function(item) { - return Batman.Keypath.forBaseAndKey(item, this.key).getValue(); - }; - - return SetIndex; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicAssociationSetIndex = (function(_super) { - - __extends(PolymorphicAssociationSetIndex, _super); - - function PolymorphicAssociationSetIndex(association, type, key) { - this.association = association; - this.type = type; - PolymorphicAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModelForType(type).get('loaded'), key); - } - - PolymorphicAssociationSetIndex.prototype._resultSetForKey = function(key) { - var _this = this; - return this._storage.getOrSet(key, function() { - return new _this.association.proxyClass(key, _this.type, _this.association); - }); - }; - - return PolymorphicAssociationSetIndex; - - })(Batman.SetIndex); - -}).call(this); - -(function() { - var __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; }; - - Batman.AssociationSetIndex = (function(_super) { - - __extends(AssociationSetIndex, _super); - - function AssociationSetIndex(association, key) { - this.association = association; - AssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModel().get('loaded'), key); - } - - AssociationSetIndex.prototype._resultSetForKey = function(key) { - var _this = this; - return this._storage.getOrSet(key, function() { - return new _this.association.proxyClass(key, _this.association); - }); - }; - - AssociationSetIndex.prototype._setResultSet = function(key, set) { - return this._storage.set(key, set); - }; - - return AssociationSetIndex; - - })(Batman.SetIndex); - -}).call(this); - -(function() { - var __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; }; - - Batman.UniqueSetIndex = (function(_super) { - - __extends(UniqueSetIndex, _super); - - function UniqueSetIndex() { - this._uniqueIndex = new Batman.Hash; - UniqueSetIndex.__super__.constructor.apply(this, arguments); - } - - UniqueSetIndex.accessor(function(key) { - return this._uniqueIndex.get(key); - }); - - UniqueSetIndex.prototype._addItemToKey = function(item, key) { - this._resultSetForKey(key).add(item); - if (!this._uniqueIndex.hasKey(key)) { - return this._uniqueIndex.set(key, item); - } - }; - - UniqueSetIndex.prototype._removeItemFromKey = function(item, key) { - var resultSet; - resultSet = this._resultSetForKey(key); - UniqueSetIndex.__super__._removeItemFromKey.apply(this, arguments); - if (resultSet.isEmpty()) { - return this._uniqueIndex.unset(key); - } else { - return this._uniqueIndex.set(key, resultSet.toArray()[0]); - } - }; - - return UniqueSetIndex; - - })(Batman.SetIndex); - -}).call(this); - -(function() { - var __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; }; - - Batman.UniqueAssociationSetIndex = (function(_super) { - - __extends(UniqueAssociationSetIndex, _super); - - function UniqueAssociationSetIndex(association, key) { - this.association = association; - UniqueAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModel().get('loaded'), key); - } - - return UniqueAssociationSetIndex; - - })(Batman.UniqueSetIndex); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicUniqueAssociationSetIndex = (function(_super) { - - __extends(PolymorphicUniqueAssociationSetIndex, _super); - - function PolymorphicUniqueAssociationSetIndex(association, type, key) { - this.association = association; - this.type = type; - PolymorphicUniqueAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModelForType(type).get('loaded'), key); - } - - return PolymorphicUniqueAssociationSetIndex; - - })(Batman.UniqueSetIndex); - -}).call(this); - -(function() { - - Batman.URI = (function() { - /* - # URI parsing - */ - - var attributes, childKeyMatchers, decodeQueryComponent, encodeComponent, encodeQueryComponent, keyVal, nameParser, normalizeParams, plus, queryFromParams, r20, strictParser; - - strictParser = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/; - - attributes = ["source", "protocol", "authority", "userInfo", "user", "password", "hostname", "port", "relative", "path", "directory", "file", "query", "hash"]; - - function URI(str) { - var i, matches; - matches = strictParser.exec(str); - i = 14; - while (i--) { - this[attributes[i]] = matches[i] || ''; - } - this.queryParams = this.constructor.paramsFromQuery(this.query); - delete this.authority; - delete this.userInfo; - delete this.relative; - delete this.directory; - delete this.file; - delete this.query; - } - - URI.prototype.queryString = function() { - return this.constructor.queryFromParams(this.queryParams); - }; - - URI.prototype.toString = function() { - return [this.protocol ? "" + this.protocol + ":" : void 0, this.authority() ? "//" : void 0, this.authority(), this.relative()].join(""); - }; - - URI.prototype.userInfo = function() { - return [this.user, this.password ? ":" + this.password : void 0].join(""); - }; - - URI.prototype.authority = function() { - return [this.userInfo(), this.user || this.password ? "@" : void 0, this.hostname, this.port ? ":" + this.port : void 0].join(""); - }; - - URI.prototype.relative = function() { - var query; - query = this.queryString(); - return [this.path, query ? "?" + query : void 0, this.hash ? "#" + this.hash : void 0].join(""); - }; - - URI.prototype.directory = function() { - var splitPath; - splitPath = this.path.split('/'); - if (splitPath.length > 1) { - return splitPath.slice(0, splitPath.length - 1).join('/') + "/"; - } else { - return ""; - } - }; - - URI.prototype.file = function() { - var splitPath; - splitPath = this.path.split("/"); - return splitPath[splitPath.length - 1]; - }; - - /* - # query parsing - */ - - - URI.paramsFromQuery = function(query) { - var matches, params, segment, _i, _len, _ref; - params = {}; - _ref = query.split('&'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - segment = _ref[_i]; - if (matches = segment.match(keyVal)) { - normalizeParams(params, decodeQueryComponent(matches[1]), decodeQueryComponent(matches[2])); - } else { - normalizeParams(params, decodeQueryComponent(segment), null); - } - } - return params; - }; - - URI.decodeQueryComponent = decodeQueryComponent = function(str) { - return decodeURIComponent(str.replace(plus, '%20')); - }; - - nameParser = /^[\[\]]*([^\[\]]+)\]*(.*)/; - - childKeyMatchers = [/^\[\]\[([^\[\]]+)\]$/, /^\[\](.+)$/]; - - plus = /\+/g; - - r20 = /%20/g; - - keyVal = /^([^=]*)=(.*)/; - - normalizeParams = function(params, name, v) { - var after, childKey, k, last, matches, _ref, _ref1, _ref2; - if (matches = name.match(nameParser)) { - k = matches[1]; - after = matches[2]; - } else { - return; - } - if (after === '') { - params[k] = v; - } else if (after === '[]') { - if ((_ref = params[k]) == null) { - params[k] = []; - } - if (Batman.typeOf(params[k]) !== 'Array') { - throw new Error("expected Array (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); - } - params[k].push(v); - } else if (matches = after.match(childKeyMatchers[0]) || after.match(childKeyMatchers[1])) { - childKey = matches[1]; - if ((_ref1 = params[k]) == null) { - params[k] = []; - } - if (Batman.typeOf(params[k]) !== 'Array') { - throw new Error("expected Array (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); - } - last = params[k][params[k].length - 1]; - if (Batman.typeOf(last) === 'Object' && !(childKey in last)) { - normalizeParams(last, childKey, v); - } else { - params[k].push(normalizeParams({}, childKey, v)); - } - } else { - if ((_ref2 = params[k]) == null) { - params[k] = {}; - } - if (Batman.typeOf(params[k]) !== 'Object') { - throw new Error("expected Object (got " + (Batman.typeOf(params[k])) + ") for param \"" + k + "\""); - } - params[k] = normalizeParams(params[k], after, v); - } - return params; - }; - - /* - # query building - */ - - - URI.queryFromParams = queryFromParams = function(value, prefix) { - var arrayResults, k, v, valueType; - if (value == null) { - return prefix; - } - valueType = Batman.typeOf(value); - if (!((prefix != null) || valueType === 'Object')) { - throw new Error("value must be an Object"); - } - switch (valueType) { - case 'Array': - return ((function() { - var _i, _len; - arrayResults = []; - if (value.length === 0) { - arrayResults.push(queryFromParams(null, "" + prefix + "[]")); - } else { - for (_i = 0, _len = value.length; _i < _len; _i++) { - v = value[_i]; - arrayResults.push(queryFromParams(v, "" + prefix + "[]")); - } - } - return arrayResults; - })()).join("&"); - case 'Object': - return ((function() { - var _results; - _results = []; - for (k in value) { - v = value[k]; - _results.push(queryFromParams(v, prefix ? "" + prefix + "[" + (encodeQueryComponent(k)) + "]" : encodeQueryComponent(k))); - } - return _results; - })()).join("&"); - default: - if (prefix != null) { - return "" + prefix + "=" + (encodeQueryComponent(value)); - } else { - return encodeQueryComponent(value); - } - } - }; - - URI.encodeComponent = encodeComponent = function(str) { - if (str != null) { - return encodeURIComponent(str); - } else { - return ''; - } - }; - - URI.encodeQueryComponent = encodeQueryComponent = function(str) { - return encodeComponent(str).replace(r20, '+'); - }; - - return URI; - - })(); - -}).call(this); - -(function() { - var __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; }; - - Batman.Request = (function(_super) { - var dataHasFileUploads; - - __extends(Request, _super); - - Request.objectToFormData = function(data) { - var formData, key, pairForList, val, _i, _len, _ref, _ref1; - pairForList = function(key, object, first) { - var k, list, v; - if (first == null) { - first = false; - } - return list = (function() { - switch (Batman.typeOf(object)) { - case 'Object': - list = (function() { - var _results; - _results = []; - for (k in object) { - v = object[k]; - _results.push(pairForList((first ? k : "" + key + "[" + k + "]"), v)); - } - return _results; - })(); - return list.reduce(function(acc, list) { - return acc.concat(list); - }, []); - case 'Array': - return object.reduce(function(acc, element) { - return acc.concat(pairForList("" + key + "[]", element)); - }, []); - default: - return [[key, object != null ? object : ""]]; - } - })(); - }; - formData = new Batman.container.FormData(); - _ref = pairForList("", data, true); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], key = _ref1[0], val = _ref1[1]; - formData.append(key, val); - } - return formData; - }; - - Request.dataHasFileUploads = dataHasFileUploads = function(data) { - var k, type, v, _i, _len; - if ((typeof File !== "undefined" && File !== null) && data instanceof File) { - return true; - } - type = Batman.typeOf(data); - switch (type) { - case 'Object': - for (k in data) { - v = data[k]; - if (dataHasFileUploads(v)) { - return true; - } - } - break; - case 'Array': - for (_i = 0, _len = data.length; _i < _len; _i++) { - v = data[_i]; - if (dataHasFileUploads(v)) { - return true; - } - } - } - return false; - }; - - Request.wrapAccessor('method', function(core) { - return { - set: function(k, val) { - return core.set.call(this, k, val != null ? typeof val.toUpperCase === "function" ? val.toUpperCase() : void 0 : void 0); - } - }; - }); - - Request.prototype.method = 'GET'; - - Request.prototype.hasFileUploads = function() { - return dataHasFileUploads(this.data); - }; - - Request.prototype.contentType = 'application/x-www-form-urlencoded'; - - Request.prototype.autosend = true; - - function Request(options) { - var handler, handlers, k, _ref; - handlers = {}; - for (k in options) { - handler = options[k]; - if (!(k === 'success' || k === 'error' || k === 'loading' || k === 'loaded')) { - continue; - } - handlers[k] = handler; - delete options[k]; - } - Request.__super__.constructor.call(this, options); - for (k in handlers) { - handler = handlers[k]; - this.on(k, handler); - } - if (((_ref = this.get('url')) != null ? _ref.length : void 0) > 0) { - if (this.autosend) { - this.send(); - } - } else { - this.observe('url', function(url) { - if (url != null) { - return this.send(); - } - }); - } - } - - Request.prototype.send = function() { - return Batman.developer.error("Please source a dependency file for a request implementation"); - }; - - return Request; - - })(Batman.Object); - -}).call(this); - -(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __slice = [].slice; - - Batman.Navigator = (function() { - - Navigator.defaultClass = function() { - if (Batman.config.usePushState && Batman.PushStateNavigator.isSupported()) { - return Batman.PushStateNavigator; - } else { - return Batman.HashbangNavigator; - } - }; - - Navigator.forApp = function(app) { - return new (this.defaultClass())(app); - }; - - function Navigator(app) { - this.app = app; - this.handleCurrentLocation = __bind(this.handleCurrentLocation, this); - - } - - Navigator.prototype.start = function() { - var _this = this; - if (typeof window === 'undefined') { - return; - } - if (this.started) { - return; - } - this.started = true; - this.startWatching(); - Batman.currentApp.prevent('ready'); - return Batman.setImmediate(function() { - if (_this.started && Batman.currentApp) { - _this.handleCurrentLocation(); - return Batman.currentApp.allowAndFire('ready'); - } - }); - }; - - Navigator.prototype.stop = function() { - this.stopWatching(); - return this.started = false; - }; - - Navigator.prototype.handleLocation = function(location) { - var path; - path = this.pathFromLocation(location); - if (path === this.cachedPath) { - return; - } - return this.dispatch(path); - }; - - Navigator.prototype.handleCurrentLocation = function() { - return this.handleLocation(window.location); - }; - - Navigator.prototype.dispatch = function(params) { - return this.cachedPath = this.app.get('dispatcher').dispatch(params); - }; - - Navigator.prototype.push = function(params) { - var path; - path = this.dispatch(params); - this.pushState(null, '', path); - return path; - }; - - Navigator.prototype.replace = function(params) { - var path; - path = this.dispatch(params); - this.replaceState(null, '', path); - return path; - }; - - Navigator.prototype.redirect = Navigator.prototype.push; - - Navigator.prototype.normalizePath = function() { - var i, seg, segments; - segments = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - segments = (function() { - var _i, _len, _results; - _results = []; - for (i = _i = 0, _len = segments.length; _i < _len; i = ++_i) { - seg = segments[i]; - _results.push(("" + seg).replace(/^(?!\/)/, '/').replace(/\/+$/, '')); - } - return _results; - })(); - return segments.join('') || '/'; - }; - - Navigator.normalizePath = Navigator.prototype.normalizePath; - - return Navigator; - - })(); - -}).call(this); - -(function() { - var __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; }; - - Batman.PushStateNavigator = (function(_super) { - - __extends(PushStateNavigator, _super); - - function PushStateNavigator() { - return PushStateNavigator.__super__.constructor.apply(this, arguments); - } - - PushStateNavigator.isSupported = function() { - var _ref; - return (typeof window !== "undefined" && window !== null ? (_ref = window.history) != null ? _ref.pushState : void 0 : void 0) != null; - }; - - PushStateNavigator.prototype.startWatching = function() { - return Batman.addEventListener(window, 'popstate', this.handleCurrentLocation); - }; - - PushStateNavigator.prototype.stopWatching = function() { - return Batman.removeEventListener(window, 'popstate', this.handleCurrentLocation); - }; - - PushStateNavigator.prototype.pushState = function(stateObject, title, path) { - return window.history.pushState(stateObject, title, this.linkTo(path)); - }; - - PushStateNavigator.prototype.replaceState = function(stateObject, title, path) { - return window.history.replaceState(stateObject, title, this.linkTo(path)); - }; - - PushStateNavigator.prototype.linkTo = function(url) { - return this.normalizePath(Batman.config.pathPrefix, url); - }; - - PushStateNavigator.prototype.pathFromLocation = function(location) { - var fullPath, prefixPattern; - fullPath = "" + (location.pathname || '') + (location.search || ''); - prefixPattern = new RegExp("^" + (this.normalizePath(Batman.config.pathPrefix))); - return this.normalizePath(fullPath.replace(prefixPattern, '')); - }; - - PushStateNavigator.prototype.handleLocation = function(location) { - var hashbangPath, path; - path = this.pathFromLocation(location); - if (path === '/' && (hashbangPath = Batman.HashbangNavigator.prototype.pathFromLocation(location)) !== '/') { - return this.replace(hashbangPath); - } else { - return PushStateNavigator.__super__.handleLocation.apply(this, arguments); - } - }; - - return PushStateNavigator; - - })(Batman.Navigator); - -}).call(this); - -(function() { - var __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; }; - - Batman.HashbangNavigator = (function(_super) { - - __extends(HashbangNavigator, _super); - - function HashbangNavigator() { - return HashbangNavigator.__super__.constructor.apply(this, arguments); - } - - HashbangNavigator.prototype.HASH_PREFIX = '#!'; - - if ((typeof window !== "undefined" && window !== null) && 'onhashchange' in window) { - HashbangNavigator.prototype.startWatching = function() { - return Batman.addEventListener(window, 'hashchange', this.handleCurrentLocation); - }; - HashbangNavigator.prototype.stopWatching = function() { - return Batman.removeEventListener(window, 'hashchange', this.handleCurrentLocation); - }; - } else { - HashbangNavigator.prototype.startWatching = function() { - return this.interval = setInterval(this.handleCurrentLocation, 100); - }; - HashbangNavigator.prototype.stopWatching = function() { - return this.interval = clearInterval(this.interval); - }; - } - - HashbangNavigator.prototype.pushState = function(stateObject, title, path) { - return window.location.hash = this.linkTo(path); - }; - - HashbangNavigator.prototype.replaceState = function(stateObject, title, path) { - var loc; - loc = window.location; - return loc.replace("" + loc.pathname + loc.search + (this.linkTo(path))); - }; - - HashbangNavigator.prototype.linkTo = function(url) { - return this.HASH_PREFIX + url; - }; - - HashbangNavigator.prototype.pathFromLocation = function(location) { - var hash; - hash = location.hash; - if ((hash != null ? hash.substr(0, 2) : void 0) === this.HASH_PREFIX) { - return this.normalizePath(hash.substr(2)); - } else { - return '/'; - } - }; - - HashbangNavigator.prototype.handleLocation = function(location) { - var realPath; - if (!Batman.config.usePushState) { - return HashbangNavigator.__super__.handleLocation.apply(this, arguments); - } - realPath = Batman.PushStateNavigator.prototype.pathFromLocation(location); - if (realPath === '/') { - return HashbangNavigator.__super__.handleLocation.apply(this, arguments); - } else { - return location.replace(this.normalizePath("" + Batman.config.pathPrefix + (this.linkTo(realPath)))); - } - }; - - return HashbangNavigator; - - })(Batman.Navigator); - -}).call(this); - -(function() { - - Batman.RouteMap = (function() { - - RouteMap.prototype.memberRoute = null; - - RouteMap.prototype.collectionRoute = null; - - function RouteMap() { - this.childrenByOrder = []; - this.childrenByName = {}; - } - - RouteMap.prototype.routeForParams = function(params) { - var route, _i, _len, _ref; - _ref = this.childrenByOrder; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - route = _ref[_i]; - if (route.test(params)) { - return route; - } - } - return void 0; - }; - - RouteMap.prototype.addRoute = function(name, route) { - var base, names, - _this = this; - this.childrenByOrder.push(route); - if (name.length > 0 && (names = name.split('.')).length > 0) { - base = names.shift(); - if (!this.childrenByName[base]) { - this.childrenByName[base] = new Batman.RouteMap; - } - this.childrenByName[base].addRoute(names.join('.'), route); - } else { - if (route.get('member')) { - Batman.developer["do"](function() { - if (_this.memberRoute) { - return Batman.developer.error("Member route with name " + name + " already exists!"); - } - }); - this.memberRoute = route; - } else { - Batman.developer["do"](function() { - if (_this.collectionRoute) { - return Batman.developer.error("Collection route with name " + name + " already exists!"); - } - }); - this.collectionRoute = route; - } - } - return true; - }; - - return RouteMap; - - })(); - -}).call(this); - -(function() { - var __slice = [].slice; - - Batman.RouteMapBuilder = (function() { - - RouteMapBuilder.BUILDER_FUNCTIONS = ['resources', 'member', 'collection', 'route', 'root']; - - RouteMapBuilder.ROUTES = { - index: { - cardinality: 'collection', - path: function(resource) { - return resource; - }, - name: function(resource) { - return resource; - } - }, - "new": { - cardinality: 'collection', - path: function(resource) { - return "" + resource + "/new"; - }, - name: function(resource) { - return "" + resource + ".new"; - } - }, - show: { - cardinality: 'member', - path: function(resource) { - return "" + resource + "/:id"; - }, - name: function(resource) { - return resource; - } - }, - edit: { - cardinality: 'member', - path: function(resource) { - return "" + resource + "/:id/edit"; - }, - name: function(resource) { - return "" + resource + ".edit"; - } - }, - collection: { - cardinality: 'collection', - path: function(resource, name) { - return "" + resource + "/" + name; - }, - name: function(resource, name) { - return "" + resource + "." + name; - } - }, - member: { - cardinality: 'member', - path: function(resource, name) { - return "" + resource + "/:id/" + name; - }, - name: function(resource, name) { - return "" + resource + "." + name; - } - } - }; - - function RouteMapBuilder(app, routeMap, parent, baseOptions) { - this.app = app; - this.routeMap = routeMap; - this.parent = parent; - this.baseOptions = baseOptions != null ? baseOptions : {}; - if (this.parent) { - this.rootPath = this.parent._nestingPath(); - this.rootName = this.parent._nestingName(); - } else { - this.rootPath = ''; - this.rootName = ''; - } - } - - RouteMapBuilder.prototype.resources = function() { - var action, actions, arg, args, as, callback, childBuilder, controller, included, k, options, path, resourceName, resourceNames, resourceRoot, routeOptions, routeTemplate, v, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - resourceNames = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = args.length; _i < _len; _i++) { - arg = args[_i]; - if (typeof arg === 'string') { - _results.push(arg); - } - } - return _results; - })(); - if (typeof args[args.length - 1] === 'function') { - callback = args.pop(); - } - if (typeof args[args.length - 1] === 'object') { - options = args.pop(); - } else { - options = {}; - } - actions = { - index: true, - "new": true, - show: true, - edit: true - }; - if (options.except) { - _ref = options.except; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - actions[k] = false; - } - delete options.except; - } else if (options.only) { - for (k in actions) { - v = actions[k]; - actions[k] = false; - } - _ref1 = options.only; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - k = _ref1[_j]; - actions[k] = true; - } - delete options.only; - } - for (_k = 0, _len2 = resourceNames.length; _k < _len2; _k++) { - resourceName = resourceNames[_k]; - resourceRoot = Batman.helpers.pluralize(resourceName); - controller = Batman.helpers.camelize(resourceRoot, true); - childBuilder = this._childBuilder({ - controller: controller - }); - if (callback != null) { - callback.call(childBuilder); - } - for (action in actions) { - included = actions[action]; - if (!(included)) { - continue; - } - routeTemplate = this.constructor.ROUTES[action]; - as = routeTemplate.name(resourceRoot); - path = routeTemplate.path(resourceRoot); - routeOptions = Batman.extend({ - controller: controller, - action: action, - path: path, - as: as - }, options); - childBuilder[routeTemplate.cardinality](action, routeOptions); - } - } - return true; - }; - - RouteMapBuilder.prototype.member = function() { - return this._addRoutesWithCardinality.apply(this, ['member'].concat(__slice.call(arguments))); - }; - - RouteMapBuilder.prototype.collection = function() { - return this._addRoutesWithCardinality.apply(this, ['collection'].concat(__slice.call(arguments))); - }; - - RouteMapBuilder.prototype.root = function(signature, options) { - return this.route('/', signature, options); - }; - - RouteMapBuilder.prototype.route = function(path, signature, options, callback) { - if (!callback) { - if (typeof options === 'function') { - callback = options; - options = void 0; - } else if (typeof signature === 'function') { - callback = signature; - signature = void 0; - } - } - if (!options) { - if (typeof signature === 'string') { - options = { - signature: signature - }; - } else { - options = signature; - } - options || (options = {}); - } else { - if (signature) { - options.signature = signature; - } - } - if (callback) { - options.callback = callback; - } - options.as || (options.as = this._nameFromPath(path)); - options.path = path; - return this._addRoute(options); - }; - - RouteMapBuilder.prototype._addRoutesWithCardinality = function() { - var cardinality, name, names, options, resourceRoot, routeOptions, routeTemplate, _i, _j, _len; - cardinality = arguments[0], names = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), options = arguments[_i++]; - if (typeof options === 'string') { - names.push(options); - options = {}; - } - options = Batman.extend({}, this.baseOptions, options); - options[cardinality] = true; - routeTemplate = this.constructor.ROUTES[cardinality]; - resourceRoot = options.controller; - for (_j = 0, _len = names.length; _j < _len; _j++) { - name = names[_j]; - routeOptions = Batman.extend({ - action: name - }, options); - if (routeOptions.path == null) { - routeOptions.path = routeTemplate.path(resourceRoot, name); - } - if (routeOptions.as == null) { - routeOptions.as = routeTemplate.name(resourceRoot, name); - } - this._addRoute(routeOptions); - } - return true; - }; - - RouteMapBuilder.prototype._addRoute = function(options) { - var klass, name, path, route; - if (options == null) { - options = {}; - } - path = this.rootPath + options.path; - name = this.rootName + Batman.helpers.camelize(options.as, true); - delete options.as; - delete options.path; - klass = options.callback ? Batman.CallbackActionRoute : Batman.ControllerActionRoute; - options.app = this.app; - route = new klass(path, options); - return this.routeMap.addRoute(name, route); - }; - - RouteMapBuilder.prototype._nameFromPath = function(path) { - path = path.replace(Batman.Route.regexps.namedOrSplat, '').replace(/\/+/g, '.').replace(/(^\.)|(\.$)/g, ''); - return path; - }; - - RouteMapBuilder.prototype._nestingPath = function() { - var nestingParam, nestingSegment; - if (!this.parent) { - return ""; - } else { - nestingParam = ":" + Batman.helpers.singularize(this.baseOptions.controller) + "Id"; - nestingSegment = Batman.helpers.underscore(this.baseOptions.controller); - return "" + (this.parent._nestingPath()) + "/" + nestingSegment + "/" + nestingParam + "/"; - } - }; - - RouteMapBuilder.prototype._nestingName = function() { - if (!this.parent) { - return ""; - } else { - return this.baseOptions.controller + "."; - } - }; - - RouteMapBuilder.prototype._childBuilder = function(baseOptions) { - if (baseOptions == null) { - baseOptions = {}; - } - return new Batman.RouteMapBuilder(this.app, this.routeMap, this, baseOptions); - }; - - return RouteMapBuilder; - - })(); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.App = (function(_super) { - var name, _fn, _i, _len, _ref, - _this = this; - - __extends(App, _super); - - function App() { - return App.__super__.constructor.apply(this, arguments); - } - - App.classAccessor('currentParams', { - get: function() { - return new Batman.Hash; - }, - 'final': true - }); - - App.classAccessor('paramsManager', { - get: function() { - var nav, params; - if (!(nav = this.get('navigator'))) { - return; - } - params = this.get('currentParams'); - return params.replacer = new Batman.ParamsReplacer(nav, params); - }, - 'final': true - }); - - App.classAccessor('paramsPusher', { - get: function() { - var nav, params; - if (!(nav = this.get('navigator'))) { - return; - } - params = this.get('currentParams'); - return params.pusher = new Batman.ParamsPusher(nav, params); - }, - 'final': true - }); - - App.classAccessor('routes', function() { - return new Batman.NamedRouteQuery(this.get('routeMap')); - }); - - App.classAccessor('routeMap', function() { - return new Batman.RouteMap; - }); - - App.classAccessor('routeMapBuilder', function() { - return new Batman.RouteMapBuilder(this, this.get('routeMap')); - }); - - App.classAccessor('dispatcher', function() { - return new Batman.Dispatcher(this, this.get('routeMap')); - }); - - App.classAccessor('controllers', function() { - return this.get('dispatcher.controllers'); - }); - - App.classAccessor('_renderContext', function() { - return Batman.RenderContext.base.descend(this); - }); - - App.requirePath = ''; - - Batman.developer["do"](function() { - App.require = function() { - var base, name, names, path, _i, _len, - _this = this; - path = arguments[0], names = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - base = this.requirePath + path; - for (_i = 0, _len = names.length; _i < _len; _i++) { - name = names[_i]; - this.prevent('run'); - path = base + '/' + name + '.coffee'; - new Batman.Request({ - url: path, - type: 'html', - success: function(response) { - CoffeeScript["eval"](response); - _this.allow('run'); - if (!_this.isPrevented('run')) { - _this.fire('loaded'); - } - if (_this.wantsToRun) { - return _this.run(); - } - } - }); - } - return this; - }; - App.controller = function() { - var names; - names = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - names = names.map(function(n) { - return n + '_controller'; - }); - return this.require.apply(this, ['controllers'].concat(__slice.call(names))); - }; - App.model = function() { - return this.require.apply(this, ['models'].concat(__slice.call(arguments))); - }; - return App.view = function() { - return this.require.apply(this, ['views'].concat(__slice.call(arguments))); - }; - }); - - App.layout = void 0; - - _ref = Batman.RouteMapBuilder.BUILDER_FUNCTIONS; - _fn = function(name) { - return App[name] = function() { - var _ref1; - return (_ref1 = this.get('routeMapBuilder'))[name].apply(_ref1, arguments); - }; - }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - _fn(name); - } - - App.event('ready').oneShot = true; - - App.event('run').oneShot = true; - - App.run = function() { - var layout, layoutClass, - _this = this; - if (Batman.currentApp) { - if (Batman.currentApp === this) { - return; - } - Batman.currentApp.stop(); - } - if (this.hasRun) { - return false; - } - if (this.isPrevented('run')) { - this.wantsToRun = true; - return false; - } else { - delete this.wantsToRun; - } - Batman.currentApp = this; - Batman.App.set('current', this); - if (this.get('dispatcher') == null) { - this.set('dispatcher', new Batman.Dispatcher(this, this.get('routeMap'))); - this.set('controllers', this.get('dispatcher.controllers')); - } - if (this.get('navigator') == null) { - this.set('navigator', Batman.Navigator.forApp(this)); - this.on('run', function() { - Batman.navigator = _this.get('navigator'); - if (Object.keys(_this.get('dispatcher').routeMap).length > 0) { - return Batman.navigator.start(); - } - }); - } - this.observe('layout', function(layout) { - return layout != null ? layout.on('ready', function() { - return _this.fire('ready'); - }) : void 0; - }); - layout = this.get('layout'); - if (layout) { - if (typeof layout === 'string') { - layoutClass = this[Batman.helpers.camelize(layout) + 'View']; - } - } else { - if (layout !== null) { - layoutClass = Batman.View; - } - } - if (layoutClass) { - layout = this.set('layout', new layoutClass({ - context: this, - node: document - })); - } - this.hasRun = true; - this.fire('run'); - return this; - }; - - App.event('ready').oneShot = true; - - App.event('stop').oneShot = true; - - App.stop = function() { - var _ref1; - if ((_ref1 = this.navigator) != null) { - _ref1.stop(); - } - Batman.navigator = null; - this.hasRun = false; - this.fire('stop'); - return this; - }; - - return App; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - - Batman.Association = (function() { - - Association.prototype.associationType = ''; - - Association.prototype.isPolymorphic = false; - - Association.prototype.defaultOptions = { - saveInline: true, - autoload: true, - nestUrl: false - }; - - function Association(model, label, options) { - var defaultOptions, encoder, getAccessor, self; - this.model = model; - this.label = label; - if (options == null) { - options = {}; - } - defaultOptions = { - namespace: Batman.currentApp, - name: Batman.helpers.camelize(Batman.helpers.singularize(this.label)) - }; - this.options = Batman.extend(defaultOptions, this.defaultOptions, options); - if (this.options.nestUrl) { - if (!(this.model.urlNestsUnder != null)) { - developer.error("You must persist the the model " + this.model.constructor.name + " to use the url helpers on an association"); - } - this.model.urlNestsUnder(Batman.helpers.underscore(this.getRelatedModel().get('resourceName'))); - } - if (this.options.extend != null) { - Batman.extend(this, this.options.extend); - } - encoder = { - encode: this.options.saveInline ? this.encoder() : false, - decode: this.decoder() - }; - this.model.encode(this.label, encoder); - self = this; - getAccessor = function() { - return self.getAccessor.call(this, self, this.model, this.label); - }; - this.model.accessor(this.label, { - get: getAccessor, - set: model.defaultAccessor.set, - unset: model.defaultAccessor.unset - }); - } - - Association.prototype.getRelatedModel = function() { - var className, relatedModel, scope; - scope = this.options.namespace || Batman.currentApp; - className = this.options.name; - relatedModel = scope != null ? scope[className] : void 0; - Batman.developer["do"](function() { - if ((Batman.currentApp != null) && !relatedModel) { - return Batman.developer.warn("Related model " + className + " hasn't loaded yet."); - } - }); - return relatedModel; - }; - - Association.prototype.getFromAttributes = function(record) { - return record.get("attributes." + this.label); - }; - - Association.prototype.setIntoAttributes = function(record, value) { - return record.get('attributes').set(this.label, value); - }; - - Association.prototype.inverse = function() { - var inverse, relatedAssocs, - _this = this; - if (relatedAssocs = this.getRelatedModel()._batman.get('associations')) { - if (this.options.inverseOf) { - return relatedAssocs.getByLabel(this.options.inverseOf); - } - inverse = null; - relatedAssocs.forEach(function(label, assoc) { - if (assoc.getRelatedModel() === _this.model) { - return inverse = assoc; - } - }); - return inverse; - } - }; - - Association.prototype.reset = function() { - delete this.index; - return true; - }; - - return Association; - - })(); - -}).call(this); - -(function() { - var __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; }; - - Batman.PluralAssociation = (function(_super) { - - __extends(PluralAssociation, _super); - - function PluralAssociation() { - return PluralAssociation.__super__.constructor.apply(this, arguments); - } - - PluralAssociation.prototype.proxyClass = Batman.AssociationSet; - - PluralAssociation.prototype.isSingular = false; - - PluralAssociation.prototype.setForRecord = Batman.Property.wrapTrackingPrevention(function(record) { - var id; - if (id = record.get(this.primaryKey)) { - return this.setIndex().get(id); - } else { - return new this.proxyClass(void 0, this); - } - }); - - PluralAssociation.prototype.getAccessor = function(self, model, label) { - var relatedRecords, setInAttributes, - _this = this; - if (!self.getRelatedModel()) { - return; - } - if (setInAttributes = self.getFromAttributes(this)) { - return setInAttributes; - } else { - relatedRecords = self.setForRecord(this); - self.setIntoAttributes(this, relatedRecords); - Batman.Property.withoutTracking(function() { - if (self.options.autoload && !_this.isNew() && !relatedRecords.loaded) { - return relatedRecords.load(function(error, records) { - if (error) { - throw error; - } - }); - } - }); - return relatedRecords; - } - }; - - PluralAssociation.prototype.setIndex = function() { - this.index || (this.index = new Batman.AssociationSetIndex(this, this[this.indexRelatedModelOn])); - return this.index; - }; - - return PluralAssociation; - - })(Batman.Association); - -}).call(this); - -(function() { - var __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; }; - - Batman.HasManyAssociation = (function(_super) { - - __extends(HasManyAssociation, _super); - - HasManyAssociation.prototype.associationType = 'hasMany'; - - HasManyAssociation.prototype.indexRelatedModelOn = 'foreignKey'; - - function HasManyAssociation(model, label, options) { - if (options != null ? options.as : void 0) { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.PolymorphicHasManyAssociation, arguments, function(){}); - } - HasManyAssociation.__super__.constructor.apply(this, arguments); - this.primaryKey = this.options.primaryKey || "id"; - this.foreignKey = this.options.foreignKey || ("" + (Batman.helpers.underscore(model.get('resourceName'))) + "_id"); - } - - HasManyAssociation.prototype.apply = function(baseSaveError, base) { - var relations, set, - _this = this; - if (!baseSaveError) { - if (relations = this.getFromAttributes(base)) { - relations.forEach(function(model) { - return model.set(_this.foreignKey, base.get(_this.primaryKey)); - }); - } - base.set(this.label, set = this.setForRecord(base)); - if (base.lifecycle.get('state') === 'creating') { - return set.markAsLoaded(); - } - } - }; - - HasManyAssociation.prototype.encoder = function() { - var association; - association = this; - return function(relationSet, _, __, record) { - var jsonArray; - if (relationSet != null) { - jsonArray = []; - relationSet.forEach(function(relation) { - var relationJSON; - relationJSON = relation.toJSON(); - if (!association.inverse() || association.inverse().options.encodeForeignKey) { - relationJSON[association.foreignKey] = record.get(association.primaryKey); - } - return jsonArray.push(relationJSON); - }); - } - return jsonArray; - }; - }; - - HasManyAssociation.prototype.decoder = function() { - var association; - association = this; - return function(data, key, _, __, parentRecord) { - var existingRecord, existingRelations, jsonObject, newRelations, record, relatedModel, savedRecord, _i, _len; - if (relatedModel = association.getRelatedModel()) { - existingRelations = association.getFromAttributes(parentRecord) || association.setForRecord(parentRecord); - newRelations = existingRelations.filter(function(relation) { - return relation.isNew(); - }).toArray(); - for (_i = 0, _len = data.length; _i < _len; _i++) { - jsonObject = data[_i]; - record = new relatedModel(); - record._withoutDirtyTracking(function() { - return this.fromJSON(jsonObject); - }); - existingRecord = relatedModel.get('loaded').indexedByUnique('id').get(record.get('id')); - if (existingRecord != null) { - existingRecord._withoutDirtyTracking(function() { - return this.fromJSON(jsonObject); - }); - record = existingRecord; - } else { - if (newRelations.length > 0) { - savedRecord = newRelations.shift(); - savedRecord._withoutDirtyTracking(function() { - return this.fromJSON(jsonObject); - }); - record = savedRecord; - } - } - record = relatedModel._mapIdentity(record); - existingRelations.add(record); - if (association.options.inverseOf) { - record.set(association.options.inverseOf, parentRecord); - } - } - existingRelations.markAsLoaded(); - } else { - Batman.developer.error("Can't decode model " + association.options.name + " because it hasn't been loaded yet!"); - } - return existingRelations; - }; - }; - - return HasManyAssociation; - - })(Batman.PluralAssociation); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicHasManyAssociation = (function(_super) { - - __extends(PolymorphicHasManyAssociation, _super); - - PolymorphicHasManyAssociation.prototype.proxyClass = Batman.PolymorphicAssociationSet; - - PolymorphicHasManyAssociation.prototype.isPolymorphic = true; - - function PolymorphicHasManyAssociation(model, label, options) { - options.inverseOf = this.foreignLabel = options.as; - delete options.as; - options.foreignKey || (options.foreignKey = "" + this.foreignLabel + "_id"); - PolymorphicHasManyAssociation.__super__.constructor.call(this, model, label, options); - this.foreignTypeKey = options.foreignTypeKey || ("" + this.foreignLabel + "_type"); - this.model.encode(this.foreignTypeKey); - } - - PolymorphicHasManyAssociation.prototype.apply = function(baseSaveError, base) { - var relations, - _this = this; - if (!baseSaveError) { - if (relations = this.getFromAttributes(base)) { - PolymorphicHasManyAssociation.__super__.apply.apply(this, arguments); - relations.forEach(function(model) { - return model.set(_this.foreignTypeKey, _this.modelType()); - }); - } - } - return true; - }; - - PolymorphicHasManyAssociation.prototype.getRelatedModelForType = function() { - return this.getRelatedModel(); - }; - - PolymorphicHasManyAssociation.prototype.modelType = function() { - return this.model.get('resourceName'); - }; - - PolymorphicHasManyAssociation.prototype.setIndex = function() { - if (!this.typeIndex) { - this.typeIndex = new Batman.PolymorphicAssociationSetIndex(this, this.modelType(), this[this.indexRelatedModelOn]); - } - return this.typeIndex; - }; - - PolymorphicHasManyAssociation.prototype.encoder = function() { - var association; - association = this; - return function(relationSet, _, __, record) { - var jsonArray; - if (relationSet != null) { - jsonArray = []; - relationSet.forEach(function(relation) { - var relationJSON; - relationJSON = relation.toJSON(); - relationJSON[association.foreignKey] = record.get(association.primaryKey); - relationJSON[association.foreignTypeKey] = association.modelType(); - return jsonArray.push(relationJSON); - }); - } - return jsonArray; - }; - }; - - return PolymorphicHasManyAssociation; - - })(Batman.HasManyAssociation); - -}).call(this); - -(function() { - var __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; }; - - Batman.SingularAssociation = (function(_super) { - - __extends(SingularAssociation, _super); - - function SingularAssociation() { - return SingularAssociation.__super__.constructor.apply(this, arguments); - } - - SingularAssociation.prototype.isSingular = true; - - SingularAssociation.prototype.getAccessor = function(self, model, label) { - var proxy, recordInAttributes; - if (recordInAttributes = self.getFromAttributes(this)) { - return recordInAttributes; - } - if (self.getRelatedModel()) { - proxy = this.associationProxy(self); - Batman.Property.withoutTracking(function() { - if (!proxy.get('loaded') && self.options.autoload) { - return proxy.load(); - } - }); - return proxy; - } - }; - - SingularAssociation.prototype.setIndex = function() { - this.index || (this.index = new Batman.UniqueAssociationSetIndex(this, this[this.indexRelatedModelOn])); - return this.index; - }; - - return SingularAssociation; - - })(Batman.Association); - -}).call(this); - -(function() { - var __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; }; - - Batman.HasOneAssociation = (function(_super) { - - __extends(HasOneAssociation, _super); - - HasOneAssociation.prototype.associationType = 'hasOne'; - - HasOneAssociation.prototype.proxyClass = Batman.HasOneProxy; - - HasOneAssociation.prototype.indexRelatedModelOn = 'foreignKey'; - - function HasOneAssociation() { - HasOneAssociation.__super__.constructor.apply(this, arguments); - this.primaryKey = this.options.primaryKey || "id"; - this.foreignKey = this.options.foreignKey || ("" + (Batman.helpers.underscore(this.model.get('resourceName'))) + "_id"); - } - - HasOneAssociation.prototype.apply = function(baseSaveError, base) { - var relation; - if (relation = this.getFromAttributes(base)) { - return relation.set(this.foreignKey, base.get(this.primaryKey)); - } - }; - - HasOneAssociation.prototype.encoder = function() { - var association; - association = this; - return function(val, key, object, record) { - var json; - if (!association.options.saveInline) { - return; - } - if (json = val.toJSON()) { - json[association.foreignKey] = record.get(association.primaryKey); - } - return json; - }; - }; - - HasOneAssociation.prototype.decoder = function() { - var association; - association = this; - return function(data, _, __, ___, parentRecord) { - var record, relatedModel; - relatedModel = association.getRelatedModel(); - record = new relatedModel(); - record._withoutDirtyTracking(function() { - return this.fromJSON(data); - }); - if (association.options.inverseOf) { - record.set(association.options.inverseOf, parentRecord); - } - record = relatedModel._mapIdentity(record); - return record; - }; - }; - - return HasOneAssociation; - - })(Batman.SingularAssociation); - -}).call(this); - -(function() { - var __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; }; - - Batman.BelongsToAssociation = (function(_super) { - - __extends(BelongsToAssociation, _super); - - BelongsToAssociation.prototype.associationType = 'belongsTo'; - - BelongsToAssociation.prototype.proxyClass = Batman.BelongsToProxy; - - BelongsToAssociation.prototype.indexRelatedModelOn = 'primaryKey'; - - BelongsToAssociation.prototype.defaultOptions = { - saveInline: false, - autoload: true, - encodeForeignKey: true - }; - - function BelongsToAssociation(model, label, options) { - if (options != null ? options.polymorphic : void 0) { - delete options.polymorphic; - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.PolymorphicBelongsToAssociation, arguments, function(){}); - } - BelongsToAssociation.__super__.constructor.apply(this, arguments); - this.foreignKey = this.options.foreignKey || ("" + this.label + "_id"); - this.primaryKey = this.options.primaryKey || "id"; - if (this.options.encodeForeignKey) { - this.model.encode(this.foreignKey); - } - } - - BelongsToAssociation.prototype.encoder = function() { - return function(val) { - return val.toJSON(); - }; - }; - - BelongsToAssociation.prototype.decoder = function() { - var association; - association = this; - return function(data, _, __, ___, childRecord) { - var inverse, record, relatedModel; - relatedModel = association.getRelatedModel(); - record = new relatedModel(); - record._withoutDirtyTracking(function() { - return this.fromJSON(data); - }); - record = relatedModel._mapIdentity(record); - if (association.options.inverseOf) { - if (inverse = association.inverse()) { - if (inverse instanceof Batman.HasManyAssociation) { - childRecord.set(association.foreignKey, record.get(association.primaryKey)); - } else { - record.set(inverse.label, childRecord); - } - } - } - childRecord.set(association.label, record); - return record; - }; - }; - - BelongsToAssociation.prototype.apply = function(base) { - var foreignValue, model; - if (model = base.get(this.label)) { - foreignValue = model.get(this.primaryKey); - if (foreignValue !== void 0) { - return base.set(this.foreignKey, foreignValue); - } - } - }; - - return BelongsToAssociation; - - })(Batman.SingularAssociation); - -}).call(this); - -(function() { - var __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; }; - - Batman.PolymorphicBelongsToAssociation = (function(_super) { - - __extends(PolymorphicBelongsToAssociation, _super); - - PolymorphicBelongsToAssociation.prototype.isPolymorphic = true; - - PolymorphicBelongsToAssociation.prototype.proxyClass = Batman.PolymorphicBelongsToProxy; - - PolymorphicBelongsToAssociation.prototype.defaultOptions = Batman.mixin({}, Batman.BelongsToAssociation.prototype.defaultOptions, { - encodeForeignTypeKey: true - }); - - function PolymorphicBelongsToAssociation() { - PolymorphicBelongsToAssociation.__super__.constructor.apply(this, arguments); - this.foreignTypeKey = this.options.foreignTypeKey || ("" + this.label + "_type"); - if (this.options.encodeForeignTypeKey) { - this.model.encode(this.foreignTypeKey); - } - this.typeIndicies = {}; - } - - PolymorphicBelongsToAssociation.prototype.getRelatedModel = false; - - PolymorphicBelongsToAssociation.prototype.setIndex = false; - - PolymorphicBelongsToAssociation.prototype.inverse = false; - - PolymorphicBelongsToAssociation.prototype.apply = function(base) { - var foreignTypeValue, instanceOrProxy, model; - PolymorphicBelongsToAssociation.__super__.apply.apply(this, arguments); - if (instanceOrProxy = base.get(this.label)) { - if (instanceOrProxy instanceof Batman.AssociationProxy) { - model = instanceOrProxy.association.model; - } else { - model = instanceOrProxy.constructor; - } - foreignTypeValue = model.get('resourceName'); - return base.set(this.foreignTypeKey, foreignTypeValue); - } - }; - - PolymorphicBelongsToAssociation.prototype.getAccessor = function(self, model, label) { - var proxy, recordInAttributes; - if (recordInAttributes = self.getFromAttributes(this)) { - return recordInAttributes; - } - if (self.getRelatedModelForType(this.get(self.foreignTypeKey))) { - proxy = this.associationProxy(self); - Batman.Property.withoutTracking(function() { - if (!proxy.get('loaded') && self.options.autoload) { - return proxy.load(); - } - }); - return proxy; - } - }; - - PolymorphicBelongsToAssociation.prototype.url = function(recordOptions) { - var ending, helper, id, inverse, root, type, _ref, _ref1; - type = (_ref = recordOptions.data) != null ? _ref[this.foreignTypeKey] : void 0; - if (type && (inverse = this.inverseForType(type))) { - root = Batman.helpers.pluralize(type).toLowerCase(); - id = (_ref1 = recordOptions.data) != null ? _ref1[this.foreignKey] : void 0; - helper = inverse.isSingular ? "singularize" : "pluralize"; - ending = Batman.helpers[helper](inverse.label); - return "/" + root + "/" + id + "/" + ending; - } - }; - - PolymorphicBelongsToAssociation.prototype.getRelatedModelForType = function(type) { - var relatedModel, scope; - scope = this.options.namespace || Batman.currentApp; - if (type) { - relatedModel = scope != null ? scope[type] : void 0; - relatedModel || (relatedModel = scope != null ? scope[Batman.helpers.camelize(type)] : void 0); - } - Batman.developer["do"](function() { - if ((Batman.currentApp != null) && !relatedModel) { - return Batman.developer.warn("Related model " + type + " for polymorphic association not found."); - } - }); - return relatedModel; - }; - - PolymorphicBelongsToAssociation.prototype.setIndexForType = function(type) { - var _base; - (_base = this.typeIndicies)[type] || (_base[type] = new Batman.PolymorphicUniqueAssociationSetIndex(this, type, this.primaryKey)); - return this.typeIndicies[type]; - }; - - PolymorphicBelongsToAssociation.prototype.inverseForType = function(type) { - var inverse, relatedAssocs, _ref, - _this = this; - if (relatedAssocs = (_ref = this.getRelatedModelForType(type)) != null ? _ref._batman.get('associations') : void 0) { - if (this.options.inverseOf) { - return relatedAssocs.getByLabel(this.options.inverseOf); - } - inverse = null; - relatedAssocs.forEach(function(label, assoc) { - if (assoc.getRelatedModel() === _this.model) { - return inverse = assoc; - } - }); - return inverse; - } - }; - - PolymorphicBelongsToAssociation.prototype.decoder = function() { - var association; - association = this; - return function(data, key, response, ___, childRecord) { - var foreignTypeValue, inverse, record, relatedModel; - foreignTypeValue = response[association.foreignTypeKey] || childRecord.get(association.foreignTypeKey); - relatedModel = association.getRelatedModelForType(foreignTypeValue); - record = new relatedModel(); - record._withoutDirtyTracking(function() { - return this.fromJSON(data); - }); - record = relatedModel._mapIdentity(record); - if (association.options.inverseOf) { - if (inverse = association.inverseForType(foreignTypeValue)) { - if (inverse instanceof Batman.PolymorphicHasManyAssociation) { - childRecord.set(association.foreignKey, record.get(association.primaryKey)); - childRecord.set(association.foreignTypeKey, foreignTypeValue); - } else { - record.set(inverse.label, childRecord); - } - } - } - childRecord.set(association.label, record); - return record; - }; - }; - - return PolymorphicBelongsToAssociation; - - })(Batman.BelongsToAssociation); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.Validator = (function(_super) { - - __extends(Validator, _super); - - function Validator() { - var mixins, options; - options = arguments[0], mixins = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - this.options = options; - Validator.__super__.constructor.apply(this, mixins); - } - - Validator.prototype.validate = function(record) { - return Batman.developer.error("You must override validate in Batman.Validator subclasses."); - }; - - Validator.prototype.format = function(key, messageKey, interpolations) { - return Batman.t("errors.messages." + messageKey, interpolations); - }; - - Validator.options = function() { - var options; - options = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - Batman.initializeObject(this); - if (this._batman.options) { - return this._batman.options.concat(options); - } else { - return this._batman.options = options; - } - }; - - Validator.matches = function(options) { - var key, results, shouldReturn, value, _ref, _ref1; - results = {}; - shouldReturn = false; - for (key in options) { - value = options[key]; - if (~((_ref = this._batman) != null ? (_ref1 = _ref.options) != null ? _ref1.indexOf(key) : void 0 : void 0)) { - results[key] = value; - shouldReturn = true; - } - } - if (shouldReturn) { - return results; - } - }; - - return Validator; - - })(Batman.Object); - -}).call(this); - -(function() { - - Batman.Validators = []; - - Batman.extend(Batman.translate.messages, { - errors: { - format: "%{attribute} %{message}", - messages: { - too_short: "must be at least %{count} characters", - too_long: "must be less than %{count} characters", - wrong_length: "must be %{count} characters", - blank: "can't be blank", - not_numeric: "must be a number", - not_matching: "is not valid" - } - } - }); - -}).call(this); - -(function() { - var __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; }; - - Batman.RegExpValidator = (function(_super) { - - __extends(RegExpValidator, _super); - - RegExpValidator.options('regexp', 'pattern'); - - function RegExpValidator(options) { - var _ref; - this.regexp = (_ref = options.regexp) != null ? _ref : options.pattern; - RegExpValidator.__super__.constructor.apply(this, arguments); - } - - RegExpValidator.prototype.validateEach = function(errors, record, key, callback) { - var value; - value = record.get(key); - if ((value != null) && value !== '') { - if (!this.regexp.test(value)) { - errors.add(key, this.format(key, 'not_matching')); - } - } - return callback(); - }; - - return RegExpValidator; - - })(Batman.Validator); - - Batman.Validators.push(Batman.RegExpValidator); - -}).call(this); - -(function() { - var __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; }; - - Batman.PresenceValidator = (function(_super) { - - __extends(PresenceValidator, _super); - - function PresenceValidator() { - return PresenceValidator.__super__.constructor.apply(this, arguments); - } - - PresenceValidator.options('presence'); - - PresenceValidator.prototype.validateEach = function(errors, record, key, callback) { - var value; - value = record.get(key); - if (this.options.presence && (!(value != null) || value === '')) { - errors.add(key, this.format(key, 'blank')); - } - return callback(); - }; - - return PresenceValidator; - - })(Batman.Validator); - - Batman.Validators.push(Batman.PresenceValidator); - -}).call(this); - -(function() { - var __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; }; - - Batman.NumericValidator = (function(_super) { - - __extends(NumericValidator, _super); - - function NumericValidator() { - return NumericValidator.__super__.constructor.apply(this, arguments); - } - - NumericValidator.options('numeric'); - - NumericValidator.prototype.validateEach = function(errors, record, key, callback) { - var value; - value = record.get(key); - if (this.options.numeric && isNaN(parseFloat(value))) { - errors.add(key, this.format(key, 'not_numeric')); - } - return callback(); - }; - - return NumericValidator; - - })(Batman.Validator); - - Batman.Validators.push(Batman.NumericValidator); - -}).call(this); - -(function() { - var __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; }; - - Batman.LengthValidator = (function(_super) { - - __extends(LengthValidator, _super); - - LengthValidator.options('minLength', 'maxLength', 'length', 'lengthWithin', 'lengthIn'); - - function LengthValidator(options) { - var range; - if (range = options.lengthIn || options.lengthWithin) { - options.minLength = range[0]; - options.maxLength = range[1] || -1; - delete options.lengthWithin; - delete options.lengthIn; - } - LengthValidator.__super__.constructor.apply(this, arguments); - } - - LengthValidator.prototype.validateEach = function(errors, record, key, callback) { - var options, value, _ref; - options = this.options; - value = (_ref = record.get(key)) != null ? _ref : []; - if (options.minLength && value.length < options.minLength) { - errors.add(key, this.format(key, 'too_short', { - count: options.minLength - })); - } - if (options.maxLength && value.length > options.maxLength) { - errors.add(key, this.format(key, 'too_long', { - count: options.maxLength - })); - } - if (options.length && value.length !== options.length) { - errors.add(key, this.format(key, 'wrong_length', { - count: options.length - })); - } - return callback(); - }; - - return LengthValidator; - - })(Batman.Validator); - - Batman.Validators.push(Batman.LengthValidator); - -}).call(this); - -(function() { - var __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; }; - - Batman.ControllerActionFrame = (function(_super) { - - __extends(ControllerActionFrame, _super); - - ControllerActionFrame.prototype.operationOccurred = false; - - ControllerActionFrame.prototype.remainingOperations = 0; - - ControllerActionFrame.prototype.event('complete').oneShot = true; - - function ControllerActionFrame(options, onComplete) { - ControllerActionFrame.__super__.constructor.call(this, options); - this.on('complete', onComplete); - } - - ControllerActionFrame.prototype.startOperation = function(options) { - if (options == null) { - options = {}; - } - if (!options.internal) { - this.operationOccurred = true; - } - this._changeOperationsCounter(1); - return true; - }; - - ControllerActionFrame.prototype.finishOperation = function() { - this._changeOperationsCounter(-1); - return true; - }; - - ControllerActionFrame.prototype.startAndFinishOperation = function(options) { - this.startOperation(options); - this.finishOperation(options); - return true; - }; - - ControllerActionFrame.prototype._changeOperationsCounter = function(delta) { - var _ref; - this.remainingOperations += delta; - if (this.remainingOperations === 0) { - this.fire('complete'); - } - if ((_ref = this.parentFrame) != null) { - _ref._changeOperationsCounter(delta); - } - }; - - return ControllerActionFrame; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }; - - Batman.DOM.InsertionBinding = (function(_super) { - - __extends(InsertionBinding, _super); - - InsertionBinding.prototype.isTwoWay = false; - - InsertionBinding.prototype.bindImmediately = false; - - function InsertionBinding(node, className, key, context, parentRenderer, invert) { - var result, - _this = this; - this.invert = invert != null ? invert : false; - this.placeholderNode = document.createComment("detached node " + (this.get('_batmanID'))); - result = InsertionBinding.__super__.constructor.apply(this, arguments); - Batman.DOM.onParseExit(this.node, function() { - _this.bind(); - if (_this.placeholderNode != null) { - return Batman.DOM.trackBinding(_this, _this.placeholderNode); - } - }); - result; - - } - - InsertionBinding.prototype.dataChange = function(value) { - var parentNode; - parentNode = this.placeholderNode.parentNode || this.node.parentNode; - if (!!value === !this.invert) { - if (!(this.node.parentNode != null)) { - Batman.DOM.insertBefore(parentNode, this.node, this.placeholderNode); - return parentNode.removeChild(this.placeholderNode); - } - } else { - parentNode.insertBefore(this.placeholderNode, this.node); - return Batman.DOM.removeNode(this.node); - } - }; - - InsertionBinding.prototype.die = function() { - if (this.dead) { - return; - } - InsertionBinding.__super__.die.apply(this, arguments); - if (!!this.get('filteredValue') === !this.invert) { - return Batman.DOM.destroyNode(this.placeholderNode); - } else { - return Batman.DOM.destroyNode(this.node); - } - }; - - return InsertionBinding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var isEmptyDataObject; - - isEmptyDataObject = function(obj) { - var name; - for (name in obj) { - return false; - } - return true; - }; - - Batman.extend(Batman, { - cache: {}, - uuid: 0, - expando: "batman" + Math.random().toString().replace(/\D/g, ''), - canDeleteExpando: (function() { - var div; - try { - div = document.createElement('div'); - return delete div.test; - } catch (e) { - return Batman.canDeleteExpando = false; - } - })(), - noData: { - "embed": true, - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - hasData: function(elem) { - elem = (elem.nodeType ? Batman.cache[elem[Batman.expando]] : elem[Batman.expando]); - return !!elem && !isEmptyDataObject(elem); - }, - data: function(elem, name, data, pvt) { - var cache, getByName, id, internalKey, ret, thisCache; - if (!Batman.acceptData(elem)) { - return; - } - internalKey = Batman.expando; - getByName = typeof name === "string"; - cache = Batman.cache; - id = elem[Batman.expando]; - if ((!id || (pvt && id && (cache[id] && !cache[id][internalKey]))) && getByName && data === void 0) { - return; - } - if (!id) { - if (elem.nodeType !== 3) { - elem[Batman.expando] = id = ++Batman.uuid; - } else { - id = Batman.expando; - } - } - if (!cache[id]) { - cache[id] = {}; - } - if (typeof name === "object" || typeof name === "function") { - if (pvt) { - cache[id][internalKey] = Batman.extend(cache[id][internalKey], name); - } else { - cache[id] = Batman.extend(cache[id], name); - } - } - thisCache = cache[id]; - if (pvt) { - thisCache[internalKey] || (thisCache[internalKey] = {}); - thisCache = thisCache[internalKey]; - } - if (data !== void 0) { - thisCache[name] = data; - } - if (getByName) { - ret = thisCache[name]; - } else { - ret = thisCache; - } - return ret; - }, - removeData: function(elem, name, pvt) { - var cache, id, internalCache, internalKey, isNode, thisCache; - if (!Batman.acceptData(elem)) { - return; - } - internalKey = Batman.expando; - isNode = elem.nodeType; - cache = Batman.cache; - id = elem[Batman.expando]; - if (!cache[id]) { - return; - } - if (name) { - thisCache = pvt ? cache[id][internalKey] : cache[id]; - if (thisCache) { - delete thisCache[name]; - if (!isEmptyDataObject(thisCache)) { - return; - } - } - } - if (pvt) { - delete cache[id][internalKey]; - if (!isEmptyDataObject(cache[id])) { - return; - } - } - internalCache = cache[id][internalKey]; - if (Batman.canDeleteExpando || !cache.setInterval) { - delete cache[id]; - } else { - cache[id] = null; - } - if (internalCache) { - cache[id] = {}; - return cache[id][internalKey] = internalCache; - } else { - if (Batman.canDeleteExpando) { - return delete elem[Batman.expando]; - } else if (elem.removeAttribute) { - return elem.removeAttribute(Batman.expando); - } else { - return elem[Batman.expando] = null; - } - } - }, - _data: function(elem, name, data) { - return Batman.data(elem, name, data, true); - }, - acceptData: function(elem) { - var match; - if (elem.nodeName) { - match = Batman.noData[elem.nodeName.toLowerCase()]; - if (match) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - return true; - } - }); - -}).call(this); - -(function() { - var buntUndefined, defaultAndOr, - __slice = [].slice; - - buntUndefined = function(f) { - return function(value) { - if (typeof value === 'undefined') { - return void 0; - } else { - return f.apply(this, arguments); - } - }; - }; - - defaultAndOr = function(lhs, rhs) { - return lhs || rhs; - }; - - Batman.Filters = { - raw: buntUndefined(function(value, binding) { - binding.escapeValue = false; - return value; - }), - get: buntUndefined(function(value, key) { - if (value.get != null) { - return value.get(key); - } else { - return value[key]; - } - }), - equals: buntUndefined(function(lhs, rhs, binding) { - return lhs === rhs; - }), - and: function(lhs, rhs) { - return lhs && rhs; - }, - or: function(lhs, rhs, binding) { - return lhs || rhs; - }, - not: function(value, binding) { - return !!!value; - }, - matches: buntUndefined(function(value, searchFor) { - return value.indexOf(searchFor) !== -1; - }), - truncate: buntUndefined(function(value, length, end, binding) { - if (end == null) { - end = "..."; - } - if (!binding) { - binding = end; - end = "..."; - } - if (value.length > length) { - value = value.substr(0, length - end.length) + end; - } - return value; - }), - "default": function(value, defaultValue, binding) { - if ((value != null) && value !== '') { - return value; - } else { - return defaultValue; - } - }, - prepend: function(value, string, binding) { - return string + value; - }, - append: function(value, string, binding) { - return value + string; - }, - replace: buntUndefined(function(value, searchFor, replaceWith, flags, binding) { - if (!binding) { - binding = flags; - flags = void 0; - } - if (flags === void 0) { - return value.replace(searchFor, replaceWith); - } else { - return value.replace(searchFor, replaceWith, flags); - } - }), - downcase: buntUndefined(function(value) { - return value.toLowerCase(); - }), - upcase: buntUndefined(function(value) { - return value.toUpperCase(); - }), - pluralize: buntUndefined(function(string, count, includeCount, binding) { - if (!binding) { - binding = includeCount; - includeCount = true; - if (!binding) { - binding = count; - count = void 0; - } - } - if (count) { - return Batman.helpers.pluralize(count, string, void 0, includeCount); - } else { - return Batman.helpers.pluralize(string); - } - }), - humanize: buntUndefined(function(string, binding) { - return Batman.helpers.humanize(string); - }), - join: buntUndefined(function(value, withWhat, binding) { - if (withWhat == null) { - withWhat = ''; - } - if (!binding) { - binding = withWhat; - withWhat = ''; - } - return value.join(withWhat); - }), - sort: buntUndefined(function(value) { - return value.sort(); - }), - map: buntUndefined(function(value, key) { - return value.map(function(x) { - return Batman.get(x, key); - }); - }), - has: function(set, item) { - if (set == null) { - return false; - } - return Batman.contains(set, item); - }, - first: buntUndefined(function(value) { - return value[0]; - }), - meta: buntUndefined(function(value, keypath) { - Batman.developer.assert(value.meta, "Error, value doesn't have a meta to filter on!"); - return value.meta.get(keypath); - }), - interpolate: function(string, interpolationKeypaths, binding) { - var k, v, values; - if (!binding) { - binding = interpolationKeypaths; - interpolationKeypaths = void 0; - } - if (!string) { - return; - } - values = {}; - for (k in interpolationKeypaths) { - v = interpolationKeypaths[k]; - values[k] = this.get(v); - if (!(values[k] != null)) { - Batman.developer.warn("Warning! Undefined interpolation key " + k + " for interpolation", string); - values[k] = ''; - } - } - return Batman.helpers.interpolate(string, values); - }, - withArguments: function() { - var binding, block, curryArgs, _i; - block = arguments[0], curryArgs = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), binding = arguments[_i++]; - if (!block) { - return; - } - return function() { - var regularArgs; - regularArgs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return block.call.apply(block, [this].concat(__slice.call(curryArgs), __slice.call(regularArgs))); - }; - }, - routeToAction: buntUndefined(function(model, action) { - var params; - params = Batman.Dispatcher.paramsFromArgument(model); - params.action = action; - return params; - }), - escape: buntUndefined(Batman.escapeHTML) - }; - - (function() { - var k, _i, _len, _ref, _results; - _ref = ['capitalize', 'singularize', 'underscore', 'camelize']; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - k = _ref[_i]; - _results.push(Batman.Filters[k] = buntUndefined(Batman.helpers[k])); - } - return _results; - })(); - - Batman.developer.addFilters(); - -}).call(this); - -(function() { - var __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; }; - - Batman.RenderContext = (function() { - var ContextProxy; - - RenderContext.deProxy = function(object) { - if ((object != null) && object.isContextProxy) { - return object.get('proxiedObject'); - } else { - return object; - } - }; - - RenderContext.root = function() { - var root; - if (Batman.currentApp != null) { - root = Batman.currentApp.get('_renderContext'); - } - return root != null ? root : root = this.base; - }; - - RenderContext.prototype.windowWrapper = { - window: Batman.container - }; - - function RenderContext(object, parent) { - this.object = object; - this.parent = parent; - } - - RenderContext.prototype.findKey = function(key) { - var base, currentNode, val; - base = key.split('.')[0].split('|')[0].trim(); - currentNode = this; - while (currentNode) { - val = Batman.get(currentNode.object, base); - if (typeof val !== 'undefined') { - val = Batman.get(currentNode.object, key); - return [val, currentNode.object].map(this.constructor.deProxy); - } - currentNode = currentNode.parent; - } - return [Batman.get(this.windowWrapper, key), this.windowWrapper]; - }; - - RenderContext.prototype.get = function(key) { - return this.findKey(key)[0]; - }; - - RenderContext.prototype.contextForKey = function(key) { - return this.findKey(key)[1]; - }; - - RenderContext.prototype.descend = function(object, scopedKey) { - var oldObject; - if (scopedKey) { - oldObject = object; - object = new Batman.Object(); - object[scopedKey] = oldObject; - } - return new this.constructor(object, this); - }; - - RenderContext.prototype.descendWithKey = function(key, scopedKey) { - var proxy; - proxy = new ContextProxy(this, key); - return this.descend(proxy, scopedKey); - }; - - RenderContext.prototype.chain = function() { - var parent, x; - x = []; - parent = this; - while (parent) { - x.push(parent.object); - parent = parent.parent; - } - return x; - }; - - RenderContext.ContextProxy = ContextProxy = (function(_super) { - - __extends(ContextProxy, _super); - - ContextProxy.prototype.isContextProxy = true; - - ContextProxy.accessor('proxiedObject', function() { - return this.binding.get('filteredValue'); - }); - - ContextProxy.accessor({ - get: function(key) { - return this.get("proxiedObject." + key); - }, - set: function(key, value) { - return this.set("proxiedObject." + key, value); - }, - unset: function(key) { - return this.unset("proxiedObject." + key); - } - }); - - function ContextProxy(renderContext, keyPath, localKey) { - this.renderContext = renderContext; - this.keyPath = keyPath; - this.localKey = localKey; - this.binding = new Batman.DOM.AbstractBinding(void 0, this.keyPath, this.renderContext); - } - - return ContextProxy; - - })(Batman.Object); - - return RenderContext; - - }).call(this); - - Batman.RenderContext.base = new Batman.RenderContext(Batman.RenderContext.prototype.windowWrapper); - -}).call(this); - -(function() { - var __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; }; - - Batman.ViewStore = (function(_super) { - - __extends(ViewStore, _super); - - ViewStore.prefix = 'views'; - - ViewStore.fetchFromRemote = true; - - function ViewStore() { - ViewStore.__super__.constructor.apply(this, arguments); - this._viewContents = {}; - this._requestedPaths = new Batman.SimpleSet; - } - - ViewStore.prototype.propertyClass = Batman.Property; - - ViewStore.prototype.fetchView = function(path) { - var _this = this; - return new Batman.Request({ - url: Batman.Navigator.normalizePath(this.constructor.prefix, "" + path + ".html"), - type: 'html', - success: function(response) { - return _this.set(path, response); - }, - error: function(response) { - throw new Error("Could not load view from " + path); - } - }); - }; - - ViewStore.accessor({ - 'final': true, - get: function(path) { - var contents; - if (path[0] !== '/') { - return this.get("/" + path); - } - if (this._viewContents[path]) { - return this._viewContents[path]; - } - if (this._requestedPaths.has(path)) { - return; - } - if (contents = this._sourceFromDOM(path)) { - return contents; - } - if (this.constructor.fetchFromRemote) { - this.fetchView(path); - } else { - throw new Error("Couldn't find view source for \'" + path + "\'!"); - } - }, - set: function(path, content) { - if (path[0] !== '/') { - return this.set("/" + path, content); - } - this._requestedPaths.add(path); - return this._viewContents[path] = content; - } - }); - - ViewStore.prototype.prefetch = function(path) { - this.get(path); - return true; - }; - - ViewStore.prototype._sourceFromDOM = function(path) { - var node, relativePath; - relativePath = path.slice(1); - if (node = Batman.DOM.querySelector(document, "[data-defineview*='" + relativePath + "']")) { - Batman.setImmediate(function() { - var _ref; - return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; - }); - return Batman.DOM.defineView(path, node); - } - }; - - return ViewStore; - - })(Batman.Object); - -}).call(this); - -(function() { - var __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; }, - __slice = [].slice; - - Batman.View = (function(_super) { - - __extends(View, _super); - - View.YieldStorage = (function(_super1) { - - __extends(YieldStorage, _super1); - - function YieldStorage() { - return YieldStorage.__super__.constructor.apply(this, arguments); - } - - YieldStorage.wrapAccessor(function(core) { - return { - get: function(key) { - var val; - val = core.get.call(this, key); - if (!(val != null)) { - val = this.set(key, []); - } - return val; - } - }; - }); - - return YieldStorage; - - })(Batman.Hash); - - View.store = new Batman.ViewStore(); - - View.option = function() { - var keys, - _this = this; - keys = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - keys.forEach(function(key) { - return _this.accessor(_this.prototype._argumentBindingKey(key), function(bindingKey) { - var context, keyPath, node, _ref; - if (!((node = this.get('node')) && (context = this.get('context')))) { - return; - } - keyPath = node.getAttribute(("data-view-" + key).toLowerCase()); - if (keyPath == null) { - return; - } - if ((_ref = this[bindingKey]) != null) { - _ref.die(); - } - return this[bindingKey] = new Batman.DOM.ViewArgumentBinding(node, keyPath, context); - }); - }); - return this.accessor.apply(this, __slice.call(keys).concat([function(key) { - var _ref; - return (_ref = this.get(this._argumentBindingKey(key))) != null ? _ref.get('filteredValue') : void 0; - }])); - }; - - View.prototype.isView = true; - - View.prototype.cache = true; - - View.prototype._rendered = false; - - View.prototype.node = null; - - View.prototype.event('ready').oneShot = true; - - View.accessor('html', { - get: function() { - var source; - if (this.html && this.html.length > 0) { - return this.html; - } - if (!(source = this.get('source'))) { - return; - } - source = Batman.Navigator.normalizePath(source); - return this.html = this.constructor.store.get(source); - }, - set: function(_, html) { - return this.html = html; - } - }); - - View.accessor('node', { - get: function() { - var html; - if (this.node == null) { - html = this.get('html'); - if (!(html && html.length > 0)) { - return; - } - this.node = document.createElement('div'); - this._setNodeOwner(this.node); - Batman.setInnerHTML(this.node, html); - } - return this.node; - }, - set: function(_, node) { - var updateHTML, - _this = this; - this.node = node; - this._setNodeOwner(node); - updateHTML = function(html) { - if (html != null) { - Batman.setInnerHTML(_this.node, html); - return _this.forget('html', updateHTML); - } - }; - this.observeAndFire('html', updateHTML); - return node; - } - }); - - View.accessor('yields', function() { - return new this.constructor.YieldStorage; - }); - - View.accessor('fetched?', function() { - return this.get('source') != null; - }); - - View.accessor('readyToRender', function() { - var _ref; - return this.get('node') && (this.get('fetched?') ? ((_ref = this.get('html')) != null ? _ref.length : void 0) > 0 : true); - }); - - function View(options) { - var context, - _this = this; - if (options == null) { - options = {}; - } - context = options.context; - if (context) { - if (!(context instanceof Batman.RenderContext)) { - context = Batman.RenderContext.root().descend(context); - } - } else { - context = Batman.RenderContext.root(); - } - options.context = context.descend(this); - View.__super__.constructor.call(this, options); - Batman.Property.withoutTracking(function() { - return _this.observeAndFire('readyToRender', function(ready) { - if (ready) { - return _this.render(); - } - }); - }); - } - - View.prototype.render = function() { - var node, - _this = this; - if (this._rendered) { - return; - } - this._rendered = true; - this._renderer = new Batman.Renderer(node = this.get('node'), this.get('context'), this); - return this._renderer.on('rendered', function() { - return _this.fire('ready', node); - }); - }; - - View.prototype.isInDOM = function() { - var node; - if ((node = this.get('node'))) { - return (node.parentNode != null) || this.get('yields').some(function(name, nodes) { - var _i, _len; - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i].node; - if (node.parentNode != null) { - return true; - } - } - return false; - }); - } else { - return false; - } - }; - - View.prototype.applyYields = function() { - return this.get('yields').forEach(function(name, nodes) { - var action, node, yieldObject, _i, _len, _ref, _results; - yieldObject = Batman.DOM.Yield.withName(name); - _results = []; - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - _ref = nodes[_i], node = _ref.node, action = _ref.action; - _results.push(yieldObject[action](node)); - } - return _results; - }); - }; - - View.prototype.retractYields = function() { - return this.get('yields').forEach(function(name, nodes) { - var node, _i, _len, _ref, _results; - _results = []; - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i].node; - _results.push((_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0); - } - return _results; - }); - }; - - View.prototype.pushYieldAction = function(key, action, node) { - this._setNodeYielder(node); - return this.get("yields").get(key).push({ - node: node, - action: action - }); - }; - - View.prototype._argumentBindingKey = function(key) { - return "_" + key + "ArgumentBinding"; - }; - - View.prototype._setNodeOwner = function(node) { - return Batman._data(node, 'view', this); - }; - - View.prototype._setNodeYielder = function(node) { - return Batman._data(node, 'yielder', this); - }; - - View.prototype.on('ready', function() { - return typeof this.ready === "function" ? this.ready.apply(this, arguments) : void 0; - }); - - View.prototype.on('appear', function() { - return typeof this.viewDidAppear === "function" ? this.viewDidAppear.apply(this, arguments) : void 0; - }); - - View.prototype.on('disappear', function() { - return typeof this.viewDidDisappear === "function" ? this.viewDidDisappear.apply(this, arguments) : void 0; - }); - - View.prototype.on('beforeAppear', function() { - return typeof this.viewWillAppear === "function" ? this.viewWillAppear.apply(this, arguments) : void 0; - }); - - View.prototype.on('beforeDisappear', function() { - return typeof this.viewWillDisappear === "function" ? this.viewWillDisappear.apply(this, arguments) : void 0; - }); - - return View; - - }).call(this, Batman.Object); - -}).call(this); - -(function() { - var Yield, - __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; }, - __slice = [].slice; - - Batman.DOM.Yield = Yield = (function(_super) { - - __extends(Yield, _super); - - Yield.yields = {}; - - Yield.queued = function(fn) { - return function() { - var args, handler, - _this = this; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (this.containerNode != null) { - return fn.apply(this, args); - } else { - return handler = this.observe('containerNode', function() { - var result; - result = fn.apply(_this, args); - _this.forget('containerNode', handler); - return result; - }); - } - }; - }; - - Yield.reset = function() { - return this.yields = {}; - }; - - Yield.withName = function(name) { - var _base; - (_base = this.yields)[name] || (_base[name] = new this({ - name: name - })); - return this.yields[name]; - }; - - Yield.forEach = function(f) { - var name, yieldObject, _ref; - _ref = this.yields; - for (name in _ref) { - yieldObject = _ref[name]; - f(yieldObject); - } - }; - - Yield.clearAll = function() { - return this.forEach(function(yieldObject) { - return yieldObject.clear(); - }); - }; - - Yield.cycleAll = function() { - return this.forEach(function(yieldObject) { - return yieldObject.cycle(); - }); - }; - - Yield.clearAllStale = function() { - return this.forEach(function(yieldObject) { - return yieldObject.clearStale(); - }); - }; - - function Yield() { - this.cycle(); - } - - Yield.prototype.cycle = function() { - return this.currentVersionNodes = []; - }; - - Yield.prototype.clear = Yield.queued(function() { - var child, _i, _len, _ref, _results; - this.cycle(); - _ref = (function() { - var _j, _len, _ref, _results1; - _ref = this.containerNode.childNodes; - _results1 = []; - for (_j = 0, _len = _ref.length; _j < _len; _j++) { - child = _ref[_j]; - _results1.push(child); - } - return _results1; - }).call(this); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - _results.push(Batman.removeOrDestroyNode(child)); - } - return _results; - }); - - Yield.prototype.clearStale = Yield.queued(function() { - var child, _i, _len, _ref, _results; - _ref = (function() { - var _j, _len, _ref, _results1; - _ref = this.containerNode.childNodes; - _results1 = []; - for (_j = 0, _len = _ref.length; _j < _len; _j++) { - child = _ref[_j]; - _results1.push(child); - } - return _results1; - }).call(this); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - if (!~this.currentVersionNodes.indexOf(child)) { - _results.push(Batman.removeOrDestroyNode(child)); - } - } - return _results; - }); - - Yield.prototype.append = Yield.queued(function(node) { - this.currentVersionNodes.push(node); - return Batman.appendChild(this.containerNode, node, true); - }); - - Yield.prototype.replace = Yield.queued(function(node) { - this.clear(); - return this.append(node); - }); - - return Yield; - - })(Batman.Object); - -}).call(this); - -(function() { - - - -}).call(this); \ No newline at end of file diff --git a/vendor/javascripts/es5-shim.js b/vendor/javascripts/es5-shim.js deleted file mode 100644 index ce79780..0000000 --- a/vendor/javascripts/es5-shim.js +++ /dev/null @@ -1,1021 +0,0 @@ -// vim: ts=4 sts=4 sw=4 expandtab -// -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License -// -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) -// -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA -// -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License -// -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License -// -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License -// -- kossnocorp Sasha Koss XXX TODO License or CLA -// -- bryanforbes Bryan Forbes XXX TODO License or CLA -// -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence -// -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License -// -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License -// -- bbqsrc Brendan Molloy XXX TODO License or CLA -// -- iwyg XXX TODO License or CLA -// -- DomenicDenicola Domenic Denicola XXX TODO License or CLA -// -- xavierm02 Montillet Xavier XXX TODO License or CLA -// -- Raynos Raynos XXX TODO License or CLA -// -- samsonjs Sami Samhuri XXX TODO License or CLA -// -- rwldrn Rick Waldron Copyright (C) 2011 MIT License -// -- lexer Alexey Zakharov XXX TODO License or CLA - -/*! - Copyright (c) 2009, 280 North Inc. http://280north.com/ - MIT License. http://github.com/280north/narwhal/blob/master/README.md -*/ - -// Module systems magic dance -(function (definition) { - // RequireJS - if (typeof define == "function") { - define(definition); - // CommonJS and