(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.14.1'; Batman.config = { pathPrefix: '/', viewPrefix: 'views', fetchRemoteViews: true, 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 _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 ancestor, results, val, _i, _len, _ref; this._allAncestors || (this._allAncestors = this.allAncestors()); if (getter) { results = []; _ref = this._allAncestors; for (_i = 0, _len = _ref.length; _i < _len; _i++) { ancestor = _ref[_i]; val = getter(ancestor); if (val != null) { results.push(val); } } return results; } else { return this._allAncestors; } }; _Batman.prototype.allAncestors = function() { var isClass, parent, proto, results, _ref, _ref1; 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); } results.push(parent); if (parent._batman != null) { results = results.concat(parent._batman.allAncestors()); } } return results; }; _Batman.prototype.set = function(key, value) { return this[key] = value; }; return _Batman; })(); }).call(this); (function() { var chr, _encodedChars, _encodedCharsPattern, _entityMap, _implementImmediates, _objectToString, _unsafeChars, _unsafeCharsPattern, __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; }; _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 && container.clearImmediate) { Batman.setImmediate = container.setImmediate; return Batman.clearImmediate = container.clearImmediate; } 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; }; return 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; }; return 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; }; return Batman.clearImmediate = function(handle) { return delete functions[handle]; }; } else { Batman.setImmediate = function(f) { return setTimeout(f, 0); }; return Batman.clearImmediate = function(handle) { return clearTimeout(handle); }; } }; 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; }; _entityMap = { "&": "&", "<": "<", ">": ">", "\"": """, "'": "'" }; _unsafeChars = []; _encodedChars = []; for (chr in _entityMap) { _unsafeChars.push(chr); _encodedChars.push(_entityMap[chr]); } _unsafeCharsPattern = new RegExp("[" + (_unsafeChars.join('')) + "]", "g"); _encodedCharsPattern = new RegExp("(" + (_encodedChars.join('|')) + ")", "g"); Batman.escapeHTML = (function() { return function(s) { return ("" + s).replace(_unsafeCharsPattern, function(c) { return _entityMap[c]; }); }; })(); Batman.unescapeHTML = (function() { return function(s) { var node; if (s == null) { return; } node = Batman._unescapeHTMLNode || (Batman._unescapeHTMLNode = document.createElement('DIV')); node.innerHTML = s; return Batman.DOM.innerText(node); }; })(); 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 __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 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; } }); }, deprecated: function(deprecatedName, upgradeString) { return Batman.developer.warn("" + deprecatedName + " has been deprecated.", upgradeString || ''); } }; 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() { 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._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) { this.handlers || (this.handlers = []); 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 (this.handlers && (index = this.handlers.indexOf(handler)) !== -1) { this.handlers.splice(index, 1); } return this; }; Event.prototype.eachHandler = function(iterator) { var ancestor, key, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _results; if ((_ref = this.handlers) != null) { _ref.slice().forEach(iterator); } if ((_ref1 = this.base) != null ? _ref1.isEventEmitter : void 0) { key = this.key; _ref3 = (_ref2 = this.base._batman) != null ? _ref2.ancestors() : void 0; _results = []; for (_i = 0, _len = _ref3.length; _i < _len; _i++) { ancestor = _ref3[_i]; if (ancestor.isEventEmitter && ((_ref4 = ancestor._batman) != null ? (_ref5 = _ref4.events) != null ? _ref5.hasOwnProperty(key) : void 0 : void 0)) { _results.push((_ref6 = ancestor.event(key, false)) != null ? (_ref7 = _ref6.handlers) != null ? _ref7.slice().forEach(iterator) : void 0 : void 0); } else { _results.push(void 0); } } return _results; } }; Event.prototype.clearHandlers = function() { return this.handlers = void 0; }; 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() { return this.fireWithContext(this.handlerContext(), arguments); }; Event.prototype.fireWithContext = function(context, args) { if (this.isPrevented() || this._oneShotFired) { return false; } if (this.oneShot) { this._oneShotFired = true; this._oneShotArgs = args; } return this.eachHandler(function(handler) { return handler.apply(context, args); }); }; Event.prototype.allowAndFire = function() { return this.allowAndFireWithContext(this.handlerContext, arguments); }; Event.prototype.allowAndFireWithContext = function(context, args) { this.allow(); return this.fireWithContext(context, args); }; 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, createEvent) { var ancestor, eventClass, events, existingEvent, newEvent, _base, _i, _len, _ref, _ref1, _ref2, _ref3; if (createEvent == null) { createEvent = true; } Batman.initializeObject(this); eventClass = this.eventClass || Batman.Event; if ((_ref = this._batman.events) != null ? _ref.hasOwnProperty(key) : void 0) { return existingEvent = this._batman.events[key]; } else { _ref1 = this._batman.ancestors(); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { ancestor = _ref1[_i]; existingEvent = (_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.events) != null ? _ref3[key] : void 0 : void 0; if (existingEvent) { break; } } if (createEvent || (existingEvent != null ? existingEvent.oneShot : void 0)) { events = (_base = this._batman).events || (_base.events = {}); newEvent = events[key] = new eventClass(this, key); newEvent.oneShot = existingEvent != null ? existingEvent.oneShot : void 0; return newEvent; } else { return existingEvent; } } }, on: function() { var handler, key, keys, _i, _j, _len, _results; keys = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), handler = arguments[_i++]; _results = []; for (_j = 0, _len = keys.length; _j < _len; _j++) { key = keys[_j]; _results.push(this.event(key).addHandler(handler)); } return _results; }, once: function(key, handler) { var event, handlerWrapper; event = this.event(key); handlerWrapper = function() { handler.apply(this, arguments); return event.removeHandler(handlerWrapper); }; return event.addHandler(handlerWrapper); }, registerAsMutableSource: function() { return Batman.Property.registerSource(this); }, mutation: function(wrappedFunction) { return function() { var result, _ref; result = wrappedFunction.apply(this, arguments); if ((_ref = this.event('change', false)) != null) { _ref.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) { var _ref; return (_ref = this.event(key, false)) != null ? _ref.isPrevented() : void 0; }, fire: function() { var args, key, _ref; key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return (_ref = this.event(key, false)) != null ? _ref.fireWithContext(this, args) : void 0; }, allowAndFire: function() { var args, key, _ref; key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return (_ref = this.event(key, false)) != null ? _ref.allowAndFireWithContext(this, args) : void 0; } }; }).call(this); (function() { var __slice = [].slice; Batman.Enumerable = { isEnumerable: true, map: function(f, ctx) { var result; if (ctx == null) { ctx = Batman.container; } result = []; this.forEach(function() { return result.push(f.apply(ctx, arguments)); }); return result; }, mapToProperty: function(key) { var result; result = []; this.forEach(function(item) { return result.push(item.get(key)); }); return result; }, every: function(f, ctx) { var result; if (ctx == null) { ctx = Batman.container; } result = true; this.forEach(function() { return result = result && f.apply(ctx, arguments); }); return result; }, some: function(f, ctx) { var result; if (ctx == null) { ctx = Batman.container; } result = false; this.forEach(function() { return result = result || f.apply(ctx, arguments); }); return result; }, reduce: function(f, accumulator) { var count, initialValuePassed, self; count = 0; self = this; if (accumulator != null) { initialValuePassed = true; } else { initialValuePassed = false; } this.forEach(function() { if (!initialValuePassed) { accumulator = arguments[0]; initialValuePassed = true; return; } return accumulator = f.apply(null, [accumulator].concat(__slice.call(arguments), [count], [self])); }); return accumulator; }, filter: function(f) { var result, wrap; result = new this.constructor; if (result.add) { wrap = function(result, element) { if (f(element)) { result.add(element); } return result; }; } else if (result.set) { wrap = function(result, key, value) { if (f(key, value)) { result.set(key, value); } return result; }; } else { if (!result.push) { result = []; } wrap = function(result, element) { if (f(element)) { result.push(element); } return result; }; } return this.reduce(wrap, result); }, inGroupsOf: function(groupSize) { var current, i, result; result = []; current = false; i = 0; this.forEach(function(element) { if (i++ % groupSize === 0) { current = []; result.push(current); } return current.push(element); }); return result; } }; }).call(this); (function() { var _objectToString, __slice = [].slice; _objectToString = Object.prototype.toString; 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.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) { var hashKey, typeString; if (hashKey = obj != null ? typeof obj.hashKey === "function" ? obj.hashKey() : void 0 : void 0) { return hashKey; } else { typeString = _objectToString.call(obj); if (typeString === "[object Array]") { return typeString; } else { return 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() { var item, itemsToAdd; this._storage = []; this.length = 0; itemsToAdd = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = arguments.length; _i < _len; _i++) { item = arguments[_i]; if (item != null) { _results.push(item); } } return _results; }).apply(this, arguments); if (itemsToAdd.length > 0) { this.add.apply(this, itemsToAdd); } } 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 key, _i, _len, _ref, _results; _ref = this._storage; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; _results.push(iterator.call(ctx, key, null, this)); } return _results; }; 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 SOURCE_TRACKER_STACK, SOURCE_TRACKER_STACK_VALID, __slice = [].slice; SOURCE_TRACKER_STACK = []; SOURCE_TRACKER_STACK_VALID = true; Batman.Property = (function() { Batman.mixin(Property.prototype, Batman.EventEmitter); Property._sourceTrackerStack = SOURCE_TRACKER_STACK; Property._sourceTrackerStackValid = SOURCE_TRACKER_STACK_VALID; 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, ancestor, _bm, _i, _len, _ref, _ref1, _ref2, _ref3; if ((_bm = base._batman) != null) { accessor = (_ref = _bm.keyAccessors) != null ? _ref.get(key) : void 0; if (!accessor) { _ref1 = _bm.ancestors(); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { ancestor = _ref1[_i]; accessor = (_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.keyAccessors) != null ? _ref3.get(key) : void 0 : void 0; if (accessor) { break; } } } } 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 set; if (!obj.isEventEmitter) { return; } if (SOURCE_TRACKER_STACK_VALID) { set = SOURCE_TRACKER_STACK[SOURCE_TRACKER_STACK.length - 1]; } else { set = []; SOURCE_TRACKER_STACK.push(set); SOURCE_TRACKER_STACK_VALID = true; } if (set != null) { set.push(obj); } return void 0; }; Property.pushSourceTracker = function() { if (SOURCE_TRACKER_STACK_VALID) { return SOURCE_TRACKER_STACK_VALID = false; } else { return SOURCE_TRACKER_STACK.push([]); } }; Property.popSourceTracker = function() { if (SOURCE_TRACKER_STACK_VALID) { return SOURCE_TRACKER_STACK.pop(); } else { SOURCE_TRACKER_STACK_VALID = true; return void 0; } }; Property.pushDummySourceTracker = function() { if (!SOURCE_TRACKER_STACK_VALID) { SOURCE_TRACKER_STACK.push([]); SOURCE_TRACKER_STACK_VALID = true; } return SOURCE_TRACKER_STACK.push(null); }; 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() { return this._hashKey || (this._hashKey = ""); }; 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() { return this._changeEvent || (this._changeEvent = this.event('change')); }; Property.prototype.accessor = function() { return this._accessor || (this._accessor = this.constructor.accessorForBaseAndKey(this.base, this.key)); }; Property.prototype.eachObserver = function(iterator) { var ancestor, handlers, key, object, property, _i, _j, _len, _len1, _ref, _ref1, _ref2, _results; key = this.key; handlers = (_ref = this.changeEvent().handlers) != null ? _ref.slice() : void 0; if (handlers) { for (_i = 0, _len = handlers.length; _i < _len; _i++) { object = handlers[_i]; iterator(object); } } if (this.base.isObservable) { _ref1 = this.base._batman.ancestors(); _results = []; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { ancestor = _ref1[_j]; if (ancestor.isObservable && ancestor.hasProperty(key)) { property = ancestor.property(key); handlers = (_ref2 = property.changeEvent().handlers) != null ? _ref2.slice() : void 0; if (handlers) { _results.push((function() { var _k, _len2, _results1; _results1 = []; for (_k = 0, _len2 = handlers.length; _k < _len2; _k++) { object = handlers[_k]; _results1.push(iterator(object)); } return _results1; })()); } else { _results.push(void 0); } } else { _results.push(void 0); } } return _results; } }; 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, source, _i, _j, _len, _len1, _ref, _ref1, _results; newSources = this.constructor.popSourceTracker(); handler = this.sourceChangeHandler(); if (this.sources) { _ref = this.sources; for (_i = 0, _len = _ref.length; _i < _len; _i++) { source = _ref[_i]; if (source != null) { source.event('change').removeHandler(handler); } } } this.sources = newSources; if (this.sources) { _ref1 = this.sources; _results = []; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { source = _ref1[_j]; _results.push(source != null ? source.event('change').addHandler(handler) : void 0); } return _results; } }; 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 _this = this; this._sourceChangeHandler || (this._sourceChangeHandler = this._handleSourceChange.bind(this)); Batman.developer["do"](function() { return _this._sourceChangeHandler.property = _this; }); return this._sourceChangeHandler; }; 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, source, _i, _len, _ref; handler = this.sourceChangeHandler(); if (this.sources) { _ref = this.sources; for (_i = 0, _len = _ref.length; _i < _len; _i++) { source = _ref[_i]; source.event('change').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; }, 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.DOM.setInnerHTML(container, ''); Batman.DOM.appendChild(container, view.get('node')); return renderer.allowAndFire('rendered'); }); }, 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: 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.DOM.propagateBindingEvents(child); } if (bindings = Batman._data(newNode, 'bindings')) { for (_j = 0, _len1 = bindings.length; _j < _len1; _j++) { binding = bindings[_j]; Batman.DOM.propagateBindingEvent(binding, newNode); } } }, 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.DOM.propagateBindingEvent(binding, node); return true; }, 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: 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; }, setStyleProperty: function(node, property, value, importance) { if (node.style.setProperty) { return node.style.setProperty(property, value, importance); } else { return node.style.setAttribute(property, value, importance); } }, 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: function(parentNode, newNode, referenceNode) { if (referenceNode == null) { referenceNode = null; } if (!referenceNode || parentNode.childNodes.length <= 0) { return Batman.DOM.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.DOM.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: 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.DOM.hasAddEventListener) { return node.addEventListener(eventName, callback, false); } else { return node.attachEvent("on" + eventName, callback); } }, 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.DOM.hasAddEventListener) { return node.removeEventListener(eventName, callback, false); } else { return node.detachEvent('on' + eventName, callback); } }, hasAddEventListener: !! (typeof window !== "undefined" && window !== null ? window.addEventListener : void 0), preventDefault: function(e) { if (typeof e.preventDefault === "function") { return e.preventDefault(); } else { return e.returnValue = false; } }, 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.die(); } 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.DOM.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() { Batman.DOM.ReaderBindingDefinition = (function() { function ReaderBindingDefinition(node, keyPath, context, renderer) { this.node = node; this.keyPath = keyPath; this.context = context; this.renderer = renderer; } return ReaderBindingDefinition; })(); Batman.BindingDefinitionOnlyObserve = { Data: 'data', Node: 'node', All: 'all', None: 'none' }; Batman.DOM.readers = { target: function(definition) { definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Node; return Batman.DOM.readers.bind(definition); }, source: function(definition) { definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; return Batman.DOM.readers.bind(definition); }, bind: function(definition) { var bindingClass, node; node = definition.node; switch (node.nodeName.toLowerCase()) { case 'input': switch (node.getAttribute('type')) { case 'checkbox': definition.attr = 'checked'; Batman.DOM.attrReaders.bind(definition); 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.ValueBinding); return new bindingClass(definition); }, context: function(definition) { return definition.context.descendWithDefinition(definition); }, mixin: function(definition) { definition.context = definition.context.descend(Batman.mixins); return new Batman.DOM.MixinBinding(definition); }, showif: function(definition) { return new Batman.DOM.ShowHideBinding(definition); }, hideif: function(definition) { definition.invert = true; return new Batman.DOM.ShowHideBinding(definition); }, insertif: function(definition) { return new Batman.DOM.InsertionBinding(definition); }, removeif: function(definition) { definition.invert = true; return new Batman.DOM.InsertionBinding(definition); }, route: function(definition) { return new Batman.DOM.RouteBinding(definition); }, view: function(definition) { return new Batman.DOM.ViewBinding(definition); }, partial: function(definition) { return Batman.DOM.partial(definition.node, definition.keyPath, definition.context, definition.renderer); }, defineview: function(definition) { var node; node = definition.node; Batman.DOM.onParseExit(node, function() { var _ref; return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; }); Batman.DOM.defineView(definition.keyPath, node); return { skipChildren: true }; }, renderif: function(definition) { return new Batman.DOM.DeferredRenderingBinding(definition); }, "yield": function(definition) { var keyPath, node; node = definition.node, keyPath = definition.keyPath; return Batman.DOM.onParseExit(node, function() { return Batman.DOM.Yield.withName(keyPath).set('containerNode', node); }); }, contentfor: function(definition) { var keyPath, node, renderer, swapMethod, value; node = definition.node, value = definition.value, swapMethod = definition.swapMethod, renderer = definition.renderer, keyPath = definition.keyPath; swapMethod || (swapMethod = 'append'); return Batman.DOM.onParseExit(node, function() { var _ref; if ((_ref = node.parentNode) != null) { _ref.removeChild(node); } return renderer.view.pushYieldAction(keyPath, swapMethod, node); }); }, replace: function(definition) { definition.swapMethod = 'replace'; return Batman.DOM.readers.contentfor(definition); } }; }).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.DOM.addEventListener(node, eventName, function() { var args, event; event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; if (event.metaKey || event.ctrlKey || event.button === 1) { return; } Batman.DOM.preventDefault(event); if (!Batman.DOM.eventIsAllowed(eventName, event)) { return; } return callback.apply(null, [node, event].concat(__slice.call(args), [context])); }); 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(node, event); }; 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.DOM.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.DOM.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.DOM.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.DOM.preventDefault(args[0]); callback.apply(null, [node].concat(__slice.call(args), [context])); } return Batman.DOM._keyCapturingNode = null; } }); } else { Batman.DOM.addEventListener(node, 'submit', function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; Batman.DOM.preventDefault(args[0]); return callback.apply(null, [node].concat(__slice.call(args), [context])); }); } return node; }, other: function(node, eventName, callback, context) { return Batman.DOM.addEventListener(node, eventName, function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return callback.apply(null, [node].concat(__slice.call(args), [context])); }); } }; Batman.DOM.eventIsAllowed = function(eventName, event) { var delegate, _ref, _ref1; if (delegate = (_ref = Batman.currentApp) != null ? (_ref1 = _ref.shouldAllowEvent) != null ? _ref1[eventName] : void 0 : void 0) { if (delegate(event) === false) { return false; } } return true; }; }).call(this); (function() { Batman.DOM.AttrReaderBindingDefinition = (function() { function AttrReaderBindingDefinition(node, attr, keyPath, context, renderer) { this.node = node; this.attr = attr; this.keyPath = keyPath; this.context = context; this.renderer = renderer; } return AttrReaderBindingDefinition; })(); Batman.DOM.attrReaders = { _parseAttribute: function(value) { if (value === 'false') { value = false; } if (value === 'true') { value = true; } return value; }, source: function(definition) { definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; return Batman.DOM.attrReaders.bind(definition); }, bind: function(definition) { var bindingClass; bindingClass = (function() { switch (definition.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; } })(); return new bindingClass(definition); }, context: function(definition) { return definition.context.descendWithDefinition(definition); }, event: function(definition) { return new Batman.DOM.EventBinding(definition); }, addclass: function(definition) { return new Batman.DOM.AddClassBinding(definition); }, removeclass: function(definition) { definition.invert = true; return new Batman.DOM.AddClassBinding(definition); }, foreach: function(definition) { return new Batman.DOM.IteratorBinding(definition); }, formfor: function(definition) { new Batman.DOM.FormBinding(definition); return definition.context.descendWithDefinition(definition); } }; }).call(this); (function() { var BatmanObject, ObjectFunctions, getAccessorObject, promiseWrapper, wrapSingleAccessor, __slice = [].slice, __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; }; 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(defaultAccessor) { return { get: function(key) { var asyncDeliver, existingValue, newValue, _base, _base1, _ref, _ref1, _this = this; if ((existingValue = defaultAccessor.get.apply(this, arguments)) != null) { return existingValue; } asyncDeliver = false; newValue = void 0; if ((_ref = (_base = this._batman).promises) == null) { _base.promises = {}; } if ((_ref1 = (_base1 = this._batman.promises)[key]) == null) { _base1[key] = (function() { var deliver, returnValue; deliver = function(err, result) { if (asyncDeliver) { _this.set(key, result); } return newValue = result; }; returnValue = fetcher.call(_this, deliver, key); if (newValue == null) { newValue = returnValue; } return true; })(); } asyncDeliver = true; return newValue; }, 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; }; ObjectFunctions = { _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; } }, _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; } }, _resetPromises: function() { var key; if (this._batman.promises == null) { return; } for (key in this._batman.promises) { this._resetPromise(key); } }, _resetPromise: function(key) { this.unset(key); this.property(key).cached = false; delete this._batman.promises[key]; } }; BatmanObject = (function(_super) { var counter; __extends(BatmanObject, _super); Batman.initializeObject(BatmanObject); Batman.initializeObject(BatmanObject.prototype); Batman.mixin(BatmanObject.prototype, ObjectFunctions, Batman.EventEmitter, Batman.Observable); Batman.mixin(BatmanObject, ObjectFunctions, Batman.EventEmitter, Batman.Observable); 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; 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; 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(); }); function BatmanObject() { var mixins; mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; this._batman = new Batman._Batman(this); this.mixin.apply(this, mixins); } counter = 0; BatmanObject.prototype._batmanID = function() { var _base, _ref; this._batman.check(this); if ((_ref = (_base = this._batman).id) == null) { _base.id = counter++; } return this._batman.id; }; BatmanObject.prototype.hashKey = function() { var _base; if (typeof this.isEqual === 'function') { return; } return (_base = this._batman).hashKey || (_base.hashKey = ""); }; 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; }; 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; this.prevent('parsed'); this.prevent('rendered'); 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.allowAndFire('parsed'); return this.allowAndFire('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 attr, attribute, binding, bindingDefinition, bindings, names, nextNode, oldContext, reader, skipChildren, value, _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], attr = _ref4[1], value = _ref4[2]; binding = attr ? (reader = Batman.DOM.attrReaders[name]) ? (bindingDefinition = new Batman.DOM.AttrReaderBindingDefinition(node, attr, value, this.context, this), reader(bindingDefinition)) : void 0 : (reader = Batman.DOM.readers[name]) ? (bindingDefinition = new Batman.DOM.ReaderBindingDefinition(node, value, this.context, this), reader(bindingDefinition)) : void 0; if (binding instanceof Batman.RenderContext) { oldContext = this.context; this.context = binding; Batman.DOM.onParseExit(node, function() { return _this.context = oldContext; }); } else if (binding != null ? binding.skipChildren : void 0) { skipChildren = true; break; } } } 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.DOM.onParseExit(node)) != null) { _ref1.forEach(function(callback) { return callback(); }); } Batman.DOM.forgetParseExit(node); if (this.node === node) { return; } if (sibling) { return sibling; } nextParent = node; while (nextParent = nextParent.parentNode) { parentSibling = nextParent.nextSibling; if ((_ref2 = Batman.DOM.onParseExit(nextParent)) != null) { _ref2.forEach(function(callback) { return callback(); }); } Batman.DOM.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, onlyAll, onlyData, onlyNode; __extends(AbstractBinding, _super); keypath_rx = /(^|,)\s*(?:(true|false)|("[^"]*")|(\{[^\}]*\})|(([0-9]+[a-zA-Z\_]|[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); }); onlyAll = Batman.BindingDefinitionOnlyObserve.All; onlyData = Batman.BindingDefinitionOnlyObserve.Data; onlyNode = Batman.BindingDefinitionOnlyObserve.Node; AbstractBinding.prototype.bindImmediately = true; AbstractBinding.prototype.shouldSet = true; AbstractBinding.prototype.isInputBinding = false; AbstractBinding.prototype.escapeValue = true; AbstractBinding.prototype.onlyObserve = onlyAll; AbstractBinding.prototype.skipParseFilter = false; function AbstractBinding(definition) { this._fireDataChange = __bind(this._fireDataChange, this); this.node = definition.node, this.keyPath = definition.keyPath, this.renderContext = definition.context, this.renderer = definition.renderer; if (definition.onlyObserve) { this.onlyObserve = definition.onlyObserve; } if (definition.skipParseFilter != null) { this.skipParseFilter = definition.skipParseFilter; } if (!this.skipParseFilter) { 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 && ((_ref = this.onlyObserve) === onlyAll || _ref === onlyNode) && Batman.DOM.nodeIsEditable(this.node)) { Batman.DOM.events.change(this.node, this._fireNodeChange.bind(this)); if (this.onlyObserve === onlyNode) { this._fireNodeChange(); } } if ((_ref1 = this.onlyObserve) === onlyAll || _ref1 === onlyData) { this.observeAndFire('filteredValue', this._fireDataChange); } if (this.node) { 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.node = null; this.keyPath = null; this.renderContext = null; this.renderer = null; 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); ViewBinding.prototype.skipChildren = true; ViewBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function ViewBinding() { ViewBinding.__super__.constructor.apply(this, arguments); this.renderer.prevent('rendered'); this.node.removeAttribute('data-view'); } ViewBinding.prototype.dataChange = function(viewClassOrInstance) { var _ref, _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'); }); this.forget(); return (_ref = this._batman.properties) != null ? _ref.forEach(function(key, property) { return property.die(); }) : void 0; }; ViewBinding.prototype.die = function() { this.view = null; return ViewBinding.__super__.die.apply(this, arguments); }; 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); } ViewArgumentBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; 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.ValueBinding = (function(_super) { __extends(ValueBinding, _super); function ValueBinding(definition) { var _ref; this.isInputBinding = (_ref = definition.node.nodeName.toLowerCase()) === 'input' || _ref === 'textarea'; ValueBinding.__super__.constructor.apply(this, arguments); } ValueBinding.prototype.nodeChange = function(node, context) { if (this.isTwoWay()) { return this.set('filteredValue', this.node.value); } }; ValueBinding.prototype.dataChange = function(value, node) { return Batman.DOM.valueForNode(this.node, value, this.escapeValue); }; return ValueBinding; })(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); ShowHideBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function ShowHideBinding(definition) { var display; display = definition.node.style.display; if (!display || display === 'none') { display = ''; } this.originalDisplay = display; this.invert = definition.invert; 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.DOM.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.canSetImplicitly = 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.lastKeyContext = null; SelectBinding.prototype.dataChange = function(newValue) { var child, matches, valueToChild, _i, _len, _name, _ref, _this = this; this.lastKeyContext || (this.lastKeyContext = this.get('keyContext')); if (this.lastKeyContext !== this.get('keyContext')) { this.canSetImplicitly = true; this.lastKeyContext = this.get('keyContext'); } 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 (!(newValue != null) && this.canSetImplicitly) { if (this.node.value) { this.canSetImplicitly = false; this.set('unfilteredValue', this.node.value); } } else { this.canSetImplicitly = false; Batman.DOM.valueForNode(this.node, newValue, this.escapeValue); } } 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.onAnchorTag = false; RouteBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; 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.onAnchorTag = 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) { path = this.pathFromValue(value); } if (this.onAnchorTag) { if (path && Batman.navigator) { path = Batman.navigator.linkTo(path); } else { path = "#"; } return this.node.href = path; } }; RouteBinding.prototype.pathFromValue = function(value) { var _ref; if (value) { 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.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; 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; DeferredRenderingBinding.prototype.skipChildren = true; 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.AbstractAttributeBinding = (function(_super) { __extends(AbstractAttributeBinding, _super); function AbstractAttributeBinding(definition) { this.attributeName = definition.attr; AbstractAttributeBinding.__super__.constructor.apply(this, arguments); } 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.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; FormBinding.accessor('errorsListSelector', function() { return this.get('node').getAttribute('data-errors-list') || this.defaultErrorsListSelector; }); function FormBinding() { this.childBindingAdded = __bind(this.childBindingAdded, this); FormBinding.__super__.constructor.apply(this, arguments); this.contextName = this.attributeName; delete this.attributeName; Batman.DOM.events.submit(this.get('node'), function(node, e) { return Batman.DOM.preventDefault(e); }); this.setupErrorsList(); } FormBinding.prototype.childBindingAdded = function(binding) { var definition, 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); definition = new Batman.DOM.AttrReaderBindingDefinition(node, this.errorClass, this.get('keyPath') + (" | get 'errors." + field + ".length'"), this.renderContext, this.renderer); return new Batman.DOM.AddClassBinding(definition); } } }; FormBinding.prototype.setupErrorsList = function() { if (this.errorsListNode = Batman.DOM.querySelector(this.get('node'), this.get('errorsListSelector'))) { Batman.DOM.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.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; function EventBinding() { var attacher, callback, confirmText, _this = this; EventBinding.__super__.constructor.apply(this, arguments); if (confirmText = this.node.getAttribute('data-confirm')) { Batman.developer.deprecated("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, this.renderContext); } else { Batman.DOM.events.other(this.node, this.attributeName, callback, this.renderContext); } } 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)); keyContext = Batman.RenderContext.deProxy(keyContext); if (keyContext != null) { 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.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; 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); AddClassBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function AddClassBinding(definition) { var name; this.invert = definition.invert; this.classes = (function() { var _i, _len, _ref, _results; _ref = definition.attr.split('|'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; _results.push({ name: name, pattern: new RegExp("(?:^|\\s)" + name + "(?:$|\\s)", 'i') }); } return _results; })(); AddClassBinding.__super__.constructor.apply(this, arguments); } 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.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; 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) { var definition; definition = new Batman.DOM.AttrReaderBindingDefinition(this.node, attr, keyPath, this.renderContext, this.renderer); return this.styleBindings[attr] = new Batman.DOM.StyleBinding.SingleStyleBinding(definition, 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); }; StyleBinding.SingleStyleBinding = (function(_super1) { __extends(SingleStyleBinding, _super1); SingleStyleBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; SingleStyleBinding.prototype.isTwoWay = function() { return false; }; function SingleStyleBinding(definition, parent) { this.parent = parent; SingleStyleBinding.__super__.constructor.call(this, definition); } SingleStyleBinding.prototype.dataChange = function(value) { return this.parent.setStyle(this.attributeName, value); }; return SingleStyleBinding; })(Batman.DOM.AbstractAttributeBinding); 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; IteratorBinding.prototype.skipChildren = true; IteratorBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function IteratorBinding(definition) { this.handleArrayChanged = __bind(this.handleArrayChanged, this); var previousSiblingNode, sourceNode, _this = this; sourceNode = definition.node, this.iteratorName = definition.attr, this.key = definition.keyPath, this.parentRenderer = definition.renderer; this.nodeMap = new Batman.SimpleHash; this.rendererMap = new Batman.SimpleHash; 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.DOM.insertBefore(sourceNode.parentNode, this.startNode, previousSiblingNode); Batman.DOM.insertBefore(sourceNode.parentNode, this.endNode, previousSiblingNode); this.parentRenderer.prevent('rendered'); Batman.DOM.onParseExit(sourceNode.parentNode, function() { Batman.DOM.destroyNode(sourceNode); _this.bind(); return _this.parentRenderer.allowAndFire('rendered'); }); definition.node = this.endNode; IteratorBinding.__super__.constructor.apply(this, arguments); } IteratorBinding.prototype.parentNode = function() { return this.endNode.parentNode; }; 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(); if (newItems) { 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.DOM.insertBefore(this.parentNode(), node, nodeAtIndex); } } } unseenNodeMap.forEach(function(item, node) { if (_this._nodesToBeRendered.has(node)) { _this._nodesToBeRemoved || (_this._nodesToBeRemoved = new Batman.SimpleSet); return _this._nodesToBeRemoved.add(node); } else { 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); this._nodesToBeRendered || (this._nodesToBeRendered = new Batman.SimpleSet); this._nodesToBeRendered.add(newNode); 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.once('rendered', function() { var _ref; _this._nodesToBeRendered.remove(newNode); if ((_ref = _this._nodesToBeRemoved) != null ? _ref.has(newNode) : void 0) { _this._nodesToBeRemoved.remove(newNode); _this._removeItem(newItem); } else { Batman.DOM.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.DOM.destroyNode(node); return this.fire('nodeRemoved', node, item); }; IteratorBinding.prototype.die = function() { var _ref; if (this._nodesToBeRendered && !this._nodesToBeRendered.isEmpty()) { this._nodesToBeRemoved || (this._nodesToBeRemoved = new Batman.SimpleSet); (_ref = this._nodesToBeRemoved).add.apply(_ref, this._nodesToBeRendered.toArray()); } return IteratorBinding.__super__.die.apply(this, arguments); }; 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.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; 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); StorageAdapter.NotAllowedError = (function(_super1) { __extends(NotAllowedError, _super1); NotAllowedError.prototype.name = "NotAllowedError"; function NotAllowedError(message) { NotAllowedError.__super__.constructor.call(this, message || "Storage operation denied access to the operation!"); } return NotAllowedError; })(StorageAdapter.StorageError); StorageAdapter.NotAcceptableError = (function(_super1) { __extends(NotAcceptableError, _super1); NotAcceptableError.prototype.name = "NotAcceptableError"; function NotAcceptableError(message) { NotAcceptableError.__super__.constructor.call(this, message || "Storage operation permitted but the request was malformed!"); } return NotAcceptableError; })(StorageAdapter.StorageError); StorageAdapter.UnprocessableRecordError = (function(_super1) { __extends(UnprocessableRecordError, _super1); UnprocessableRecordError.prototype.name = "UnprocessableRecordError"; function UnprocessableRecordError(message) { UnprocessableRecordError.__super__.constructor.call(this, message || "Storage adapter could not process the record!"); } return UnprocessableRecordError; })(StorageAdapter.StorageError); StorageAdapter.InternalStorageError = (function(_super1) { __extends(InternalStorageError, _super1); InternalStorageError.prototype.name = "InternalStorageError"; function InternalStorageError(message) { InternalStorageError.__super__.constructor.call(this, message || "An error occured during the storage operation!"); } return InternalStorageError; })(StorageAdapter.StorageError); StorageAdapter.NotImplementedError = (function(_super1) { __extends(NotImplementedError, _super1); NotImplementedError.prototype.name = "NotImplementedError"; function NotImplementedError(message) { NotImplementedError.__super__.constructor.call(this, message || "This operation is not implemented by the storage adpater!"); } return NotImplementedError; })(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); }; this.runBeforeFilter(key, env, function(env) { return this[key](env, next); }); return void 0; }; 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.CommunicationError = (function(_super1) { __extends(CommunicationError, _super1); CommunicationError.prototype.name = 'CommunicationError'; function CommunicationError(message) { CommunicationError.__super__.constructor.call(this, message || "A communication error has occurred!"); } return CommunicationError; })(RestStorage.StorageError); 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, context) { if (context == null) { context = object; } if (typeof object[key] === 'function') { return object[key].call(context, 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._addUrlAffixes = function(url, subject, env) { var prefix, segments; segments = [url, this.urlSuffix(subject, env)]; if (url.charAt(0) !== '/') { prefix = this.urlPrefix(subject, env); if (prefix.charAt(prefix.length - 1) !== '/') { segments.unshift('/'); } segments.unshift(prefix); } return segments.join(''); }; 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.urlForRecord = function(record, env) { var id, url, _ref; if ((_ref = env.options) != null ? _ref.recordUrl : void 0) { url = this._execWithOptions(env.options, 'recordUrl', env.options, record); } else 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 + "!"); } } } return this._addUrlAffixes(this._addParams(url, env.options), record, env); }; RestStorage.prototype.urlForCollection = function(model, env) { var url, _ref; url = ((_ref = env.options) != null ? _ref.collectionUrl : void 0) ? this._execWithOptions(env.options, 'collectionUrl', env.options, env.options.urlContext) : model.url ? this._execWithOptions(model, 'url', env.options) : this._defaultCollectionUrl(model, env.options); return this._addUrlAffixes(this._addParams(url, env.options), model, env); }; 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); } RestStorage.prototype.after('all', function(env, next) { if (env.error) { env.error = this._errorFor(env.error, env); } return next(); }); RestStorage._statusCodeErrors = { '0': RestStorage.CommunicationError, '403': RestStorage.NotAllowedError, '404': RestStorage.NotFoundError, '406': RestStorage.NotAcceptableError, '409': RestStorage.RecordExistsError, '422': RestStorage.UnprocessableRecordError, '500': RestStorage.InternalStorageError, '501': RestStorage.NotImplementedError }; RestStorage.prototype._errorFor = function(error, env) { var errorClass, request; if (error instanceof Error || !(error.request != null)) { return error; } if (errorClass = this.constructor._statusCodeErrors[error.request.status]) { request = error.request; error = new errorClass; error.request = request; error.env = env; } return error; }; 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.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 error, inferredParams, path, route, _ref, _ref1; 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(); } error = { type: '404', isPrevented: false, preventDefault: function() { return this.isPrevented = true; } }; if ((_ref1 = Batman.currentApp) != null) { _ref1.fire('error', error); } if (error.isPrevented) { return params; } 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 + "$"); regexps.namedOrSplat.lastIndex = 0; 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; }, __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.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 = []); return filters.push(options); }; Controller.afterFilter = function() { var filters, options, _base; Batman.initializeObject(this); options = _optionsFromFilterArguments.apply(null, arguments); filters = (_base = this._batman).afterFilters || (_base.afterFilters = []); return filters.push(options); }; Controller.afterFilter(function(params) { if (this.autoScrollToHash && (params['#'] != null)) { return this.scrollToHash(params['#']); } }); Controller.catchError = function() { var currentHandlers, error, errors, handlers, options, _base, _i, _j, _len, _results; errors = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), options = arguments[_i++]; Batman.initializeObject(this); (_base = this._batman).errorHandlers || (_base.errorHandlers = new Batman.SimpleHash); handlers = Batman.typeOf(options["with"]) === 'Array' ? options["with"] : [options["with"]]; _results = []; for (_j = 0, _len = errors.length; _j < _len; _j++) { error = errors[_j]; currentHandlers = this._batman.errorHandlers.get(error) || []; _results.push(this._batman.errorHandlers.set(error, currentHandlers.concat(handlers))); } return _results; }; Controller.prototype.errorHandler = function(callback) { var errorFrame, _ref, _this = this; errorFrame = (_ref = this._actionFrames) != null ? _ref[this._actionFrames.length - 1] : void 0; return function(err, result, env) { if (err) { if (errorFrame != null ? errorFrame.error : void 0) { return; } if (errorFrame != null) { errorFrame.error = err; } if (!_this.handleError(err)) { throw err; } } else { return typeof callback === "function" ? callback(result, env) : void 0; } }; }; Controller.prototype.handleError = function(error) { var handled, _ref, _this = this; handled = false; if ((_ref = this.constructor._batman.getAll('errorHandlers')) != null) { _ref.forEach(function(hash) { return hash.forEach(function(key, value) { var handler, _i, _len, _results; if (error instanceof key) { handled = true; _results = []; for (_i = 0, _len = value.length; _i < _len; _i++) { handler = value[_i]; _results.push(handler.call(_this, error)); } return _results; } }); }); } return handled; }; function Controller() { this.redirect = __bind(this.redirect, this); this.handleError = __bind(this.handleError, this); this.errorHandler = __bind(this.errorHandler, 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; if (!_this._afterFilterRedirect) { _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'); if (!this._afterFilterRedirect) { 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.once('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 block, options, _i, _len, _ref; if (filters = (_ref = this.constructor._batman) != null ? _ref.get(filters) : void 0) { for (_i = 0, _len = filters.length; _i < _len; _i++) { options = filters[_i]; if (options.only && __indexOf.call(options.only, action) < 0) { continue; } if (options.except && __indexOf.call(options.except, action) >= 0) { continue; } if (this._afterFilterRedirect) { return; } block = options.block; if (typeof block === 'function') { block.call(this, params); } else { if (typeof this[block] === "function") { this[block](params); } } } } }; 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) { return this.reduce(function(accumulator, element) { if (f(element)) { accumulator.add(element); } return accumulator; }, new Batman.Set()); }; SetProxy.prototype.replace = function() { var length, result; length = this.property('length'); length.isolate(); result = this.base.replace.apply(this, arguments); length.expose(); return result; }; Batman.Set._applySetAccessors(SetProxy); _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); } 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; })(); if (itemsToAdd.length > 0) { 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; })(); if (itemsToAdd.length > 0) { 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; })(); if (itemsToRemove.length > 0) { 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; })(); if (itemsToAdd.length > 0) { return this.add.apply(this, itemsToAdd); } } }; SetComplement.prototype._addComplement = function(items, opposite) { var item, itemsToAdd; 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; })(); if (itemsToAdd.length > 0) { return this.add.apply(this, itemsToAdd); } }; return SetComplement; })(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.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 __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.storageKey = null; Model.primaryKey = 'id'; Model.persist = function() { var mechanism, options; mechanism = arguments[0], options = 2 <= arguments.length ? __slice.call(arguments, 1) : []; Batman.initializeObject(this.prototype); mechanism = mechanism.isStorageAdapter ? mechanism : new mechanism(this); if (options.length > 0) { Batman.mixin.apply(Batman, [mechanism].concat(__slice.call(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, matches, optionsOrFunction, validatorClass, validators, _base, _i, _j, _len, _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 { _ref = Batman.Validators; _results = []; for (_j = 0, _len = _ref.length; _j < _len; _j++) { validatorClass = _ref[_j]; if ((matches = validatorClass.matches(optionsOrFunction))) { _results.push(validators.push({ keys: keys, validator: new validatorClass(matches) })); } else { _results.push(void 0); } } return _results; } }; 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(); } this._resetPromises(); return result; }; Model.find = function(id, callback) { return this.findWithOptions(id, void 0, callback); }; Model.findWithOptions = function(id, options, callback) { var record; if (options == null) { options = {}; } Batman.developer.assert(callback, "Must call find with a callback!"); record = new this(); record._withoutDirtyTracking(function() { return this.set('id', id); }); record.loadWithOptions(options, callback); return record; }; Model.load = function(options, callback) { var _ref; if ((_ref = typeof options) === 'function' || _ref === 'undefined') { callback = options; options = {}; } else { options = { data: options }; } return this.loadWithOptions(options, callback); }; Model.loadWithOptions = function(options, callback) { var _this = this; this.fire('loading', options); return this._doStorageOperation('readAll', options, function(err, records, env) { var mappedRecords; if (err != null) { _this.fire('error', err); return typeof callback === "function" ? callback(err, []) : void 0; } else { mappedRecords = _this._mapIdentities(records); _this.fire('loaded', mappedRecords, env); return typeof callback === "function" ? callback(err, mappedRecords, env) : void 0; } }); }; 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.createFromJSON = function(json) { var record; record = new this; record._withoutDirtyTracking(function() { return this.fromJSON(json); }); return this._mapIdentity(record); }; Model._mapIdentity = function(record) { return this._mapIdentities([record])[0]; }; Model._mapIdentities = function(records) { var existing, id, index, newRecords, record, _i, _len, _ref, _ref1; newRecords = []; for (index = _i = 0, _len = records.length; _i < _len; index = ++_i) { record = records[index]; if (!((id = record.get('id')) != null)) { continue; } else if (existing = (_ref = this.get('loaded.indexedBy.id').get(id)) != null ? _ref.toArray()[0] : void 0) { existing._withoutDirtyTracking(function() { var _ref1; return this.updateAttributes(((_ref1 = record.get('attributes')) != null ? _ref1.toObject() : void 0) || {}); }); records[index] = existing; } else { newRecords.push(record); } } if (newRecords.length) { (_ref1 = this.get('loaded')).add.apply(_ref1, newRecords); } return records; }; 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 = {}; } 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('isDirty', function() { return this.isDirty(); }); 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.isDirty = function() { return this.get('lifecycle.state') === 'dirty'; }; 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 _ref1; if (!callback) { _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; } else { options = { data: options }; } return this.loadWithOptions(options, callback); }; Model.prototype.loadWithOptions = function(options, callback) { var callbackQueue, hasOptions, _ref1, _this = this; hasOptions = Object.keys(options).length !== 0; if ((_ref1 = this.get('lifecycle.state')) === 'destroying' || _ref1 === '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', 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, _this = this; if (!callback) { _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; } isNew = this.isNew(); _ref2 = isNew ? ['create', 'create', 'created'] : ['save', 'update', 'saved'], startState = _ref2[0], storageOperation = _ref2[1], endState = _ref2[2]; if (this.get('lifecycle').startTransition(startState)) { return this.validate(function(error, errors) { var associations; if (error || errors.length) { _this.get('lifecycle').failedValidation(); return typeof callback === "function" ? callback(error || errors, _this) : void 0; } associations = _this.constructor._batman.get('associations'); _this._withoutDirtyTracking(function() { var _ref3, _this = this; return associations != null ? (_ref3 = associations.getByType('belongsTo')) != null ? _ref3.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 _ref3, _ref4; if ((_ref3 = associations.getByType('hasOne')) != null) { _ref3.forEach(function(association, label) { return association.apply(err, record); }); } return (_ref4 = associations.getByType('hasMany')) != null ? _ref4.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.Proxy = (function(_super) { __extends(Proxy, _super); Proxy.prototype.isProxy = true; function Proxy(target) { Proxy.__super__.constructor.call(this); if (target != null) { this.set('target', target); } } Proxy.accessor('target', Batman.Property.defaultAccessor); Proxy.accessor({ get: function(key) { var _ref; return (_ref = this.get('target')) != null ? _ref.get(key) : void 0; }, set: function(key, value) { var _ref; return (_ref = this.get('target')) != null ? _ref.set(key, value) : void 0; }, unset: function(key) { var _ref; return (_ref = this.get('target')) != null ? _ref.unset(key) : void 0; } }); return Proxy; })(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.loaded = false; function AssociationProxy(association, model) { this.association = association; this.model = model; AssociationProxy.__super__.constructor.call(this); } 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._setTarget(proxiedRecord); } return typeof callback === "function" ? callback(err, proxiedRecord) : void 0; }); return this.get('target'); }; AssociationProxy.prototype.loadFromLocal = function() { var target; if (!this._canLoad()) { return; } if (target = this.fetchFromLocal()) { this._setTarget(target); } return target; }; AssociationProxy.prototype.fetch = function(callback) { var record; if (!this._canLoad()) { 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.prototype._canLoad = function() { return (this.get('foreignValue') || this.get('primaryValue')) != null; }; AssociationProxy.prototype._setTarget = function(target) { this.set('target', target); this.set('loaded', true); return this.fire('loaded', target); }; return AssociationProxy; })(Batman.Proxy); }).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 = { data: {} }; loadOptions.data[this.association.foreignKey] = this.get('primaryValue'); if (this.association.options.url) { loadOptions.collectionUrl = this.association.options.url; loadOptions.urlContext = this.model; } return this.association.getRelatedModel().loadWithOptions(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 loadOptions, _this = this; loadOptions = {}; if (this.association.options.url) { loadOptions.recordUrl = this.association.options.url; } return this.association.getRelatedModel().findWithOptions(this.get('foreignValue'), loadOptions, 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 loadOptions, _this = this; loadOptions = {}; if (this.association.options.url) { loadOptions.recordUrl = this.association.options.url; } return this.association.getRelatedModelForType(this.get('foreignTypeValue')).findWithOptions(this.get('foreignValue'), loadOptions, 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; }; 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() { Batman.mixins = new Batman.Object; }).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; } if (object instanceof Batman.container.File) { return [[key, object]]; } 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 __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 = this; 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 = function() { return _this._reIndex(); }; 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.find = function(block) { var item, _i, _len, _ref; this.base.registerAsMutableSource(); _ref = this.get('_storage'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { item = _ref[_i]; if (block(item)) { return item; } } }; SetSort.prototype.merge = function(other) { this.base.registerAsMutableSource(); 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.Set, this._storage, function() {}).merge(other).sortedBy(this.key, this.order); }; 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().loadWithOptions(this._getLoadOptions(), function(err, records) { if (!err) { _this.markAsLoaded(); } return callback(err, _this); }); }; AssociationSet.prototype._getLoadOptions = function() { var loadOptions; loadOptions = { data: {} }; loadOptions.data[this.association.foreignKey] = this.foreignKeyValue; if (this.association.options.url) { loadOptions.collectionUrl = this.association.options.url; loadOptions.urlContext = this.association.parentSetIndex().get(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 = { data: {} }; loadOptions.data[this.association.foreignKey] = this.foreignKeyValue; loadOptions.data[this.association.foreignTypeKey] = this.foreignTypeKeyValue; if (this.association.options.url) { loadOptions.collectionUrl = this.association.options.url; loadOptions.urlContext = this.association.parentSetIndex().get(this.foreignKeyValue); } 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.getRelatedModel().get('loaded'), key); } PolymorphicAssociationSetIndex.prototype._resultSetForKey = function(key) { return this.association.setForKey(key); }; PolymorphicAssociationSetIndex.prototype._addItem = function(item) { if (this.association.modelType() !== item.get(this.association.foreignTypeKey)) { return; } return PolymorphicAssociationSetIndex.__super__._addItem.apply(this, arguments); }; PolymorphicAssociationSetIndex.prototype._removeItem = function(item) { if (this.association.modelType() !== item.get(this.association.foreignTypeKey)) { return; } return PolymorphicAssociationSetIndex.__super__._removeItem.apply(this, arguments); }; 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) { return this.association.setForKey(key); }; AssociationSetIndex.prototype.forEach = function(iterator, ctx) { var _this = this; return this.association.proxies.forEach(function(record, set) { var key; key = _this.association.indexValueForRecord(record); if (set.get('length') > 0) { return iterator.call(ctx, key, set, _this); } }); }; AssociationSetIndex.prototype.toArray = function() { var results; results = []; this.forEach(function(key) { return results.push(key); }); return results; }; 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() { 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) { this.cachedPath = this.app.get('dispatcher').dispatch(params); if (this._lastRedirect) { this.cachedPath = this._lastRedirect; } return this.cachedPath; }; Navigator.prototype.push = function(params) { var path, pathFromParams, _base; pathFromParams = typeof(_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; if (pathFromParams) { this._lastRedirect = pathFromParams; } path = this.dispatch(params); if (!this._lastRedirect || this._lastRedirect === path) { this.pushState(null, '', path); } return path; }; Navigator.prototype.replace = function(params) { var path, pathFromParams, _base; pathFromParams = typeof(_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; if (pathFromParams) { this._lastRedirect = pathFromParams; } path = this.dispatch(params); if (!this._lastRedirect || this._lastRedirect === path) { 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.DOM.addEventListener(window, 'popstate', this.handleCurrentLocation); }; PushStateNavigator.prototype.stopWatching = function() { return Batman.DOM.removeEventListener(window, 'popstate', this.handleCurrentLocation); }; PushStateNavigator.prototype.pushState = function(stateObject, title, path) { if (path !== this.pathFromLocation(window.location)) { return window.history.pushState(stateObject, title, this.linkTo(path)); } }; PushStateNavigator.prototype.replaceState = function(stateObject, title, path) { if (path !== this.pathFromLocation(window.location)) { 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.DOM.addEventListener(window, 'hashchange', this.handleCurrentLocation); }; HashbangNavigator.prototype.stopWatching = function() { return Batman.DOM.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 = Batman.helpers.underscore(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.parent._nestingName() + 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() { var requireDeprecated; requireDeprecated = "Please use whatever means you'd like to load your code before calling App.run."; App.require = function() { var base, name, names, path, _i, _len, _this = this; path = arguments[0], names = 2 <= arguments.length ? __slice.call(arguments, 1) : []; Batman.developer.deprecated("App.require", requireDeprecated); 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) : []; Batman.developer.deprecated("App.controller", requireDeprecated); names = names.map(function(n) { return n + '_controller'; }); return this.require.apply(this, ['controllers'].concat(__slice.call(names))); }; App.model = function() { Batman.developer.deprecated("App.model", requireDeprecated); return this.require.apply(this, ['models'].concat(__slice.call(arguments))); }; return App.view = function() { Batman.developer.deprecated("App.view", requireDeprecated); return this.require.apply(this, ['views'].concat(__slice.call(arguments))); }; }); App.layout = void 0; App.shouldAllowEvent = {}; _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)) { Batman.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); PluralAssociation.prototype.proxyClass = Batman.AssociationSet; PluralAssociation.prototype.isSingular = false; function PluralAssociation() { PluralAssociation.__super__.constructor.apply(this, arguments); this._resetSetHashes(); } PluralAssociation.prototype.setForRecord = function(record) { var childModelSetIndex, indexValue, _this = this; indexValue = this.indexValueForRecord(record); childModelSetIndex = this.setIndex(); Batman.Property.withoutTracking(function() { return _this._setsByRecord.getOrSet(record, function() { var existingValueSet, newSet; if (indexValue != null) { existingValueSet = _this._setsByValue.get(indexValue); if (existingValueSet != null) { return existingValueSet; } } newSet = _this.proxyClassInstanceForKey(indexValue); if (indexValue != null) { _this._setsByValue.set(indexValue, newSet); } return newSet; }); }); if (indexValue != null) { return childModelSetIndex.get(indexValue); } else { return this._setsByRecord.get(record); } }; PluralAssociation.prototype.setForKey = Batman.Property.wrapTrackingPrevention(function(indexValue) { var foundSet, _this = this; foundSet = void 0; this._setsByRecord.forEach(function(record, set) { if (foundSet != null) { return; } if (_this.indexValueForRecord(record) === indexValue) { return foundSet = set; } }); if (foundSet != null) { foundSet.foreignKeyValue = indexValue; return foundSet; } return this._setsByValue.getOrSet(indexValue, function() { return _this.proxyClassInstanceForKey(indexValue); }); }); PluralAssociation.prototype.proxyClassInstanceForKey = function(indexValue) { return new this.proxyClass(indexValue, 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.parentSetIndex = function() { this.parentIndex || (this.parentIndex = this.model.get('loaded').indexedByUnique(this.primaryKey)); return this.parentIndex; }; PluralAssociation.prototype.setIndex = function() { this.index || (this.index = new Batman.AssociationSetIndex(this, this[this.indexRelatedModelOn])); return this.index; }; PluralAssociation.prototype.indexValueForRecord = function(record) { return record.get(this.primaryKey); }; PluralAssociation.prototype.reset = function() { PluralAssociation.__super__.reset.apply(this, arguments); return this._resetSetHashes(); }; PluralAssociation.prototype._resetSetHashes = function() { this._setsByRecord = new Batman.SimpleHash; return this._setsByValue = new Batman.SimpleHash; }; 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.proxyClassInstanceForKey = function(indexValue) { return new this.proxyClass(indexValue, this.modelType(), this); }; PolymorphicHasManyAssociation.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); } else { relatedModel = this.getRelatedModel(); } Batman.developer["do"](function() { if ((Batman.currentApp != null) && !relatedModel) { return Batman.developer.warn("Related model " + type + " for polymorphic association not found."); } }); return relatedModel; }; PolymorphicHasManyAssociation.prototype.modelType = function() { return this.model.get('resourceName'); }; PolymorphicHasManyAssociation.prototype.setIndex = function() { 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; }; }; PolymorphicHasManyAssociation.prototype.decoder = function() { var association; association = this; return function(data, key, _, __, parentRecord) { var existingRecord, existingRelations, jsonObject, newRelations, record, relatedModel, savedRecord, subType, type, _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]; type = jsonObject[association.options.foreignTypeKey]; subType = association.getRelatedModelForType(type); record = new subType(); 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 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 parent, proxy, record, recordInAttributes, _ref; if (recordInAttributes = self.getFromAttributes(this)) { return recordInAttributes; } if (self.getRelatedModel()) { proxy = this.associationProxy(self); record = false; parent = this; if ((_ref = proxy._loadSetter) == null) { proxy._loadSetter = proxy.once('loaded', function(child) { return parent._withoutDirtyTracking(function() { return this.set(self.label, child); }); }); } if (!Batman.Property.withoutTracking(function() { return proxy.get('loaded'); })) { if (self.options.autoload) { Batman.Property.withoutTracking(function() { return proxy.load(); }); } else { record = proxy.loadFromLocal(); } } return record || 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; if (!data) { return; } relatedModel = association.getRelatedModel(); record = relatedModel.createFromJSON(data); if (association.options.inverseOf) { record.set(association.options.inverseOf, parentRecord); } 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 = relatedModel.createFromJSON(data); 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; PolymorphicBelongsToAssociation.__super__.apply.apply(this, arguments); if (instanceOrProxy = base.get(this.label)) { foreignTypeValue = instanceOrProxy instanceof Batman.PolymorphicBelongsToProxy ? instanceOrProxy.get('foreignTypeValue') : instanceOrProxy.constructor.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 = relatedModel.createFromJSON(data); 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); Validator.triggers = function() { var triggers; triggers = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (this._triggers != null) { return this._triggers.concat(triggers); } else { return this._triggers = triggers; } }; Validator.options = function() { var options; options = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (this._options != null) { return this._options.concat(options); } else { return this._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._options) != null ? _ref.indexOf(key) : void 0)) { results[key] = value; } if (~ ((_ref1 = this._triggers) != null ? _ref1.indexOf(key) : void 0)) { results[key] = value; shouldReturn = true; } } if (shouldReturn) { return results; } }; 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.prototype.handleBlank = function(value) { if (this.options.allowBlank && !Batman.PresenceValidator.prototype.isPresent(value)) { return true; } }; 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", greater_than: "must be greater than %{count}", greater_than_or_equal_to: "must be greater than or equal to %{count}", equal_to: "must be equal to %{count}", less_than: "must be less than %{count}", less_than_or_equal_to: "must be less than or equal to %{count}", not_matching: "is not valid", invalid_association: "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.triggers('regexp', 'pattern'); RegExpValidator.options('allowBlank'); 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 (this.handleBlank(value)) { return callback(); } if (!(value != null) || value === '' || !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.triggers('presence'); PresenceValidator.prototype.validateEach = function(errors, record, key, callback) { var value; value = record.get(key); if (!this.isPresent(value)) { errors.add(key, this.format(key, 'blank')); } return callback(); }; PresenceValidator.prototype.isPresent = function(value) { return (value != null) && value !== ''; }; 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.triggers('numeric', 'greaterThan', 'greaterThanOrEqualTo', 'equalTo', 'lessThan', 'lessThanOrEqualTo'); NumericValidator.options('allowBlank'); NumericValidator.prototype.validateEach = function(errors, record, key, callback) { var options, value; options = this.options; value = record.get(key); if (this.handleBlank(value)) { return callback(); } if (!(value != null) || !(this.isNumeric(value) || this.canCoerceToNumeric(value))) { errors.add(key, this.format(key, 'not_numeric')); } else { if (options.greaterThan && value <= options.greaterThan) { errors.add(key, this.format(key, 'greater_than', { count: options.greaterThan })); } if (options.greaterThanOrEqualTo && value < options.greaterThanOrEqualTo) { errors.add(key, this.format(key, 'greater_than_or_equal_to', { count: options.greaterThanOrEqualTo })); } if (options.equalTo && value !== options.equalTo) { errors.add(key, this.format(key, 'equal_to', { count: options.equalTo })); } if (options.lessThan && value >= options.lessThan) { errors.add(key, this.format(key, 'less_than', { count: options.lessThan })); } if (options.lessThanOrEqualTo && value > options.lessThanOrEqualTo) { errors.add(key, this.format(key, 'less_than_or_equal_to', { count: options.lessThanOrEqualTo })); } } return callback(); }; NumericValidator.prototype.isNumeric = function(value) { return !isNaN(parseFloat(value)) && isFinite(value); }; NumericValidator.prototype.canCoerceToNumeric = function(value) { return (value - 0) == value && value.length > 0; }; 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.triggers('minLength', 'maxLength', 'length', 'lengthWithin', 'lengthIn'); LengthValidator.options('allowBlank'); 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; options = this.options; value = record.get(key); if (value !== '' && this.handleBlank(value)) { return callback(); } if (value == null) { value = []; } 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.AssociatedValidator = (function(_super) { __extends(AssociatedValidator, _super); function AssociatedValidator() { return AssociatedValidator.__super__.constructor.apply(this, arguments); } AssociatedValidator.triggers('associated'); AssociatedValidator.prototype.validateEach = function(errors, record, key, callback) { var childFinished, count, value, _this = this; value = record.get(key); if (value != null) { if (value instanceof Batman.AssociationProxy) { value = typeof value.get === "function" ? value.get('target') : void 0; } count = 1; childFinished = function(err, childErrors) { if (childErrors.length > 0) { errors.add(key, _this.format(key, 'invalid_association')); } if (--count === 0) { return callback(); } }; if ((value != null ? value.forEach : void 0) != null) { value.forEach(function(record) { count += 1; return record.validate(childFinished); }); } else if ((value != null ? value.validate : void 0) != null) { count += 1; value.validate(childFinished); } return childFinished(null, []); } else { return callback(); } }; return AssociatedValidator; })(Batman.Validator); Batman.Validators.push(Batman.AssociatedValidator); }).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.once('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; InsertionBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function InsertionBinding(definition) { var _this = this; this.invert = definition.invert; this.placeholderNode = document.createComment("detached node " + (this.get('_batmanID'))); 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); } }); } 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 { if (this.node.parentNode != null) { parentNode.insertBefore(this.placeholderNode, this.node); return Batman.DOM.removeNode(this.node); } } }; InsertionBinding.prototype.die = function() { var filteredValue, node, placeholderNode; if (this.dead) { return; } node = this.node, placeholderNode = this.placeholderNode; filteredValue = this.get('filteredValue'); InsertionBinding.__super__.die.apply(this, arguments); if ( !! filteredValue === !this.invert) { return Batman.DOM.destroyNode(placeholderNode); } else { return Batman.DOM.destroyNode(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 (value == null) { 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; }, trim: buntUndefined(function(value, binding) { return value.trim(); }), 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 != null ? string : '') + (value != null ? value : ''); }, append: function(value, string, binding) { return (value != null ? value : '') + (string != null ? 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 != null) { 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.descendWithDefinition = function(definition) { var proxy; proxy = new ContextProxy(definition); return this.descend(proxy, definition.attr); }; 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(definition) { this.binding = new Batman.DOM.AbstractBinding(definition); } 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); 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(Batman.config.viewPrefix, "" + 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.charAt(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 (Batman.config.fetchRemoteViews) { this.fetchView(path); } else { throw new Error("Couldn't find view source for \'" + path + "\'!"); } }, set: function(path, content) { if (path.charAt(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; keys = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.accessor.apply(this, __slice.call(keys).concat([{ get: function(key) { var _ref; return (_ref = this.get("argumentBindings." + key)) != null ? _ref.get('filteredValue') : void 0; }, set: function(key, value) { var _ref; return (_ref = this.get("argumentBindings." + key)) != null ? _ref.set('filteredValue', value) : void 0; }, unset: function(key) { var _ref; return (_ref = this.get("argumentBindings." + key)) != null ? _ref.unset('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('argumentBindings', function() { var _this = this; return new Batman.TerminalAccessible(function(key) { var bindingKey, context, definition, keyPath, node, _ref; if (!((node = _this.get('node')) && (context = _this.get('context')))) { return; } keyPath = node.getAttribute(("data-view-" + key).toLowerCase()); if (keyPath == null) { return; } bindingKey = "_argumentBinding" + key; if ((_ref = _this[bindingKey]) != null) { _ref.die(); } definition = new Batman.DOM.ReaderBindingDefinition(node, keyPath, context); return _this[bindingKey] = new Batman.DOM.ViewArgumentBinding(definition); }); }); 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.DOM.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.DOM.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.once('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.die = function() { var _ref; this.fire('destroy', this.node); this.forget(); if ((_ref = this._batman.properties) != null) { _ref.forEach(function(key, property) { return property.die(); }); } return this.get('yields').forEach(function(name, actions) { var node, _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; }); }; 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._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.DOM.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.DOM.removeOrDestroyNode(child)); } } return _results; }); Yield.prototype.append = Yield.queued(function(node) { this.currentVersionNodes.push(node); return Batman.DOM.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);