diff --git a/assets/javascripts/vendor/ember.js b/assets/javascripts/vendor/ember.js index b0a279e8..3f8b4624 100644 --- a/assets/javascripts/vendor/ember.js +++ b/assets/javascripts/vendor/ember.js @@ -1,5 +1,5 @@ -// Version: v0.9.8.1-675-g417213d -// Last commit: 417213d (2012-07-30 13:06:36 +0200) +// Version: v1.0.pre +// Last commit: 7955b85 (2012-08-03 14:50:17 -0700) (function() { @@ -142,8 +142,8 @@ window.ember_deprecateFunc = Ember.deprecateFunc("ember_deprecateFunc is deprec })(); -// Version: v0.9.8.1-675-g417213d -// Last commit: 417213d (2012-07-30 13:06:36 +0200) +// Version: v1.0.pre-5-gf1ec52a +// Last commit: f1ec52a (2012-08-06 17:23:55 -0700) (function() { @@ -1011,6 +1011,8 @@ function canInvoke(obj, methodName) { /** Checks to see if the `methodName` exists on the `obj`. + @function + @param {Object} obj The object to check for the method @param {String} methodName The method name to check for */ @@ -1700,8 +1702,22 @@ var Descriptor = Ember.Descriptor = function() {}; return this.firstName+' '+this.lastName; }).property('firstName', 'lastName').cacheable()); */ -Ember.defineProperty = function(obj, keyName, desc, val, meta) { - var descs, existingDesc, watching; +Ember.defineProperty = function(obj, keyName, desc, data, meta) { + // The first two parameters to defineProperty are mandatory: + // + // * obj: the object to define this property on. This may be + // a prototype. + // * keyName: the name of the property + // + // One and only one of the following two parameters must be + // provided: + // + // * desc: an instance of Ember.Descriptor (typically a + // computed property) or an ES5 descriptor. + // * data: something other than a descriptor, that will + // become the explicit value of this property. + + var descs, existingDesc, watching, value; if (!meta) meta = metaFor(obj); descs = meta.descs; @@ -1713,6 +1729,8 @@ Ember.defineProperty = function(obj, keyName, desc, val, meta) { } if (desc instanceof Ember.Descriptor) { + value = desc; + descs[keyName] = desc; if (MANDATORY_SETTER && watching) { objectDefineProperty(obj, keyName, { @@ -1728,8 +1746,10 @@ Ember.defineProperty = function(obj, keyName, desc, val, meta) { } else { descs[keyName] = undefined; // shadow descriptor in proto if (desc == null) { + value = data; + if (MANDATORY_SETTER && watching) { - meta.values[keyName] = val; + meta.values[keyName] = data; objectDefineProperty(obj, keyName, { configurable: true, enumerable: true, @@ -1742,9 +1762,11 @@ Ember.defineProperty = function(obj, keyName, desc, val, meta) { } }); } else { - obj[keyName] = val; + obj[keyName] = data; } } else { + value = desc; + // compatibility with ES5 objectDefineProperty(obj, keyName, desc); } @@ -1754,6 +1776,10 @@ Ember.defineProperty = function(obj, keyName, desc, val, meta) { // were initialized with the prototype if (watching) { Ember.overrideChains(obj, keyName, meta); } + // The `value` passed to the `didDefineProperty` hook is + // either the descriptor or data, whichever was passed. + if (obj.didDefineProperty) { obj.didDefineProperty(obj, keyName, value); } + return this; }; @@ -2102,8 +2128,6 @@ function flushPendingChains() { forEach.call(queue, function(q) { q[0].add(q[1]); }); Ember.warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); - if(pendingQueue.length > 0) - console.log(pendingQueue) } /** @private */ @@ -2789,7 +2813,9 @@ var ComputedPropertyPrototype = ComputedProperty.prototype; Properties are cacheable by default. - @name Ember.ComputedProperty.cacheable + @memberOf Ember.ComputedProperty.prototype + @name cacheable + @function @param {Boolean} aFlag optional set to false to disable caching @returns {Ember.ComputedProperty} receiver */ @@ -2808,7 +2834,9 @@ ComputedPropertyPrototype.cacheable = function(aFlag) { }.property().volatile() }); - @name Ember.ComputedProperty.volatile + @memberOf Ember.ComputedProperty.prototype + @name volatile + @function @returns {Ember.ComputedProperty} receiver */ ComputedPropertyPrototype.volatile = function() { @@ -2828,7 +2856,9 @@ ComputedPropertyPrototype.volatile = function() { }).property('firstName', 'lastName') }); - @name Ember.ComputedProperty.property + @memberOf Ember.ComputedProperty.prototype + @name property + @function @param {String} path... zero or more property paths @returns {Ember.ComputedProperty} receiver */ @@ -2859,14 +2889,20 @@ ComputedPropertyPrototype.property = function() { exposes a public API for retrieving these values from classes, via the `metaForProperty()` function. - @name Ember.ComputedProperty.meta - @param {Hash} metadata + @memberOf Ember.ComputedProperty.prototype + @name meta + @function + @param {Hash} meta @returns {Ember.ComputedProperty} property descriptor instance */ ComputedPropertyPrototype.meta = function(meta) { - this._meta = meta; - return this; + if (arguments.length === 0) { + return this._meta || {}; + } else { + this._meta = meta; + return this; + } }; /** @private - impl descriptor API */ @@ -3487,7 +3523,7 @@ Ember.RunLoop = RunLoop; call. Ember.run(function(){ - // code to be execute within a RunLoop + // code to be execute within a RunLoop }); @name run @@ -3525,7 +3561,7 @@ var run = Ember.run; an lower-level way to use a RunLoop instead of using Ember.run(). Ember.run.begin(); - // code to be execute within a RunLoop + // code to be execute within a RunLoop Ember.run.end(); @@ -3541,7 +3577,7 @@ Ember.run.begin = function() { instead of using Ember.run(). Ember.run.begin(); - // code to be execute within a RunLoop + // code to be execute within a RunLoop Ember.run.end(); @returns {void} @@ -4914,6 +4950,17 @@ Ember.observer = function(func) { return func; }; +// If observers ever become asynchronous, Ember.immediateObserver +// must remain synchronous. +Ember.immediateObserver = function() { + for (var i=0, l=arguments.length; i true @@ -5457,7 +5504,7 @@ Ember.String = { > beta > gamma - @param {String} str + @param {String} str The string to split @returns {String} split string @@ -5466,7 +5513,7 @@ Ember.String = { /** Converts a camelized string into all lower case separated by underscores. - + 'innerHTML'.decamelize() => 'inner_html' 'action_name'.decamelize() => 'action_name' 'css-class-name'.decamelize() => 'css-class-name' @@ -5483,7 +5530,7 @@ Ember.String = { /** Replaces underscores or spaces with dashes. - + 'innerHTML'.dasherize() => 'inner-html' 'action_name'.dasherize() => 'action-name' 'css-class-name'.dasherize() => 'css-class-name' @@ -5650,7 +5697,7 @@ if (Ember.EXTEND_PROTOTYPES) { /** The `property` extension of Javascript's Function prototype is available - when Ember.EXTEND_PROTOTYPES is true, which is the default. + when Ember.EXTEND_PROTOTYPES is true, which is the default. Computed properties allow you to treat a function like a property: @@ -5705,7 +5752,7 @@ if (Ember.EXTEND_PROTOTYPES) { /** The `observes` extension of Javascript's Function prototype is available - when Ember.EXTEND_PROTOTYPES is true, which is the default. + when Ember.EXTEND_PROTOTYPES is true, which is the default. You can observe property changes simply by adding the `observes` call to the end of your method declarations in classes that you write. @@ -5716,7 +5763,7 @@ if (Ember.EXTEND_PROTOTYPES) { // Executes whenever the "value" property changes }.observes('value') }); - + @see Ember.Observable */ Function.prototype.observes = function() { @@ -5726,7 +5773,7 @@ if (Ember.EXTEND_PROTOTYPES) { /** The `observesBefore` extension of Javascript's Function prototype is - available when Ember.EXTEND_PROTOTYPES is true, which is the default. + available when Ember.EXTEND_PROTOTYPES is true, which is the default. You can get notified when a property changes is about to happen by by adding the `observesBefore` call to the end of your method @@ -5737,7 +5784,7 @@ if (Ember.EXTEND_PROTOTYPES) { // Executes whenever the "value" property is about to change }.observesBefore('value') }); - + @see Ember.Observable */ Function.prototype.observesBefore = function() { @@ -7012,6 +7059,7 @@ Ember.Copyable = Ember.Mixin.create( Override to return a copy of the receiver. Default implementation raises an exception. + @function @param deep {Boolean} if true, a deep copy of the object should be made @returns {Object} copy of receiver */ @@ -7208,6 +7256,8 @@ Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable, If the passed object is of a type not supported by the receiver then this method should raise an exception. + @function + @param {Object} object The object to add to the enumerable. @@ -7238,6 +7288,8 @@ Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable, If the passed object is of a type not supported by the receiver then this method should raise an exception. + @function + @param {Object} object The object to remove from the enumerable. @@ -7308,6 +7360,8 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable, should replace amt objects started at idx with the objects in the passed array. You should also call this.enumerableContentDidChange() ; + @function + @param {Number} idx Starting index in the array to replace. If idx >= length, then append to the end of the array. @@ -7331,7 +7385,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable, colors.clear(); => [] colors.length(); => 0 - @returns {Ember.Array} An empty Array. + @returns {Ember.Array} An empty Array. */ clear: function () { var len = get(this, 'length'); @@ -7539,15 +7593,15 @@ var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty; @class ## Overview - + This mixin provides properties and property observing functionality, core features of the Ember object model. - + Properties and observers allow one object to observe changes to a property on another object. This is one of the fundamental ways that models, controllers and views communicate with each other in an Ember application. - + Any object that has this mixin applied can be used in observer operations. That includes Ember.Object and most objects you will interact with as you write your Ember application. @@ -7555,16 +7609,16 @@ var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty; Note that you will not generally apply this mixin to classes yourself, but you will use the features provided by this module frequently, so it is important to understand how to use it. - + ## Using get() and set() - + Because of Ember's support for bindings and observers, you will always access properties using the get method, and set properties using the set method. This allows the observing objects to be notified and computed properties to be handled properly. - + More documentation about `get` and `set` are below. - + ## Observing Property Changes You typically observe property changes simply by adding the `observes` @@ -7576,7 +7630,7 @@ var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty; // Executes whenever the "value" property changes }.observes('value') }); - + Although this is the most common way to add an observer, this capability is actually built into the Ember.Object class on top of two methods defined in this mixin: `addObserver` and `removeObserver`. You can use @@ -7589,12 +7643,12 @@ var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty; This will call the `targetAction` method on the `targetObject` to be called whenever the value of the `propertyKey` changes. - - Note that if `propertyKey` is a computed property, the observer will be - called when any of the property dependencies are changed, even if the + + Note that if `propertyKey` is a computed property, the observer will be + called when any of the property dependencies are changed, even if the resulting value of the computed property is unchanged. This is necessary because computed properties are not computed until `get` is called. - + @extends Ember.Mixin */ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { @@ -7608,7 +7662,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { This method is usually similar to using object[keyName] or object.keyName, however it supports both computed properties and the unknownProperty handler. - + Because `get` unifies the syntax for accessing all these kinds of properties, it can make many refactorings easier, such as replacing a simple property with a computed property, or vice versa. @@ -7804,11 +7858,11 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { Ember.propertyDidChange(this, keyName); return this; }, - + /** Convenience method to call `propertyWillChange` and `propertyDidChange` in succession. - + @param {String} keyName The property key to be notified about. @returns {Ember.Observable} */ @@ -7900,7 +7954,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { This method will be called when a client attempts to get the value of a property that has not been defined in one of the typical ways. Override this method to create "virtual" properties. - + @param {String} key The name of the unknown property that was requested. @returns {Object} The property value or undefined. Default is undefined. */ @@ -7912,7 +7966,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { This method will be called when a client attempts to set the value of a property that has not been defined in one of the typical ways. Override this method to create "virtual" properties. - + @param {String} key The name of the unknown property to be set. @param {Object} value The value the unknown property is to be set to. */ @@ -7945,9 +7999,9 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { /** Retrieves the value of a property, or a default value in the case that the property returns undefined. - + person.getWithDefault('lastName', 'Doe'); - + @param {String} keyName The name of the property to retrieve @param {Object} defaultValue The value to return if the property value is undefined @returns {Object} The property value or the defaultValue. @@ -7958,10 +8012,10 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { /** Set the value of a property to the current value plus some amount. - + person.incrementProperty('age'); team.incrementProperty('score', 2); - + @param {String} keyName The name of the property to increment @param {Object} increment The amount to increment by. Defaults to 1 @returns {Object} The new property value @@ -7971,13 +8025,13 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { set(this, keyName, (get(this, keyName) || 0)+increment); return get(this, keyName); }, - + /** Set the value of a property to the current value minus some amount. - + player.decrementProperty('lives'); orc.decrementProperty('health', 5); - + @param {String} keyName The name of the property to decrement @param {Object} increment The amount to decrement by. Defaults to 1 @returns {Object} The new property value @@ -7991,9 +8045,9 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ { /** Set the value of a boolean property to the opposite of it's current value. - + starship.toggleProperty('warpDriveEnaged'); - + @param {String} keyName The name of the property to toggle @returns {Object} The new property value */ @@ -10316,6 +10370,8 @@ var get = Ember.get, set = Ember.set; perhaps be moved so that it's visible in the JsDoc output. */ /** + @class + Ember.Location returns an instance of the correct implementation of the `location` API. @@ -10348,11 +10404,18 @@ Ember.Location = { var get = Ember.get, set = Ember.set; /** + @class + Ember.HashLocation implements the location API using the browser's hash. At present, it relies on a hashchange event existing in the browser. + + @extends Ember.Object */ -Ember.HashLocation = Ember.Object.extend({ +Ember.HashLocation = Ember.Object.extend( +/** @scope Ember.HashLocation.prototype */ { + + /** @private */ init: function() { set(this, 'location', get(this, 'location') || window.location); }, @@ -10412,6 +10475,7 @@ Ember.HashLocation = Ember.Object.extend({ return '#'+url; }, + /** @private */ willDestroy: function() { var guid = Ember.guidFor(this); @@ -10429,10 +10493,17 @@ Ember.Location.registerImplementation('hash', Ember.HashLocation); var get = Ember.get, set = Ember.set; /** + @class + Ember.HistoryLocation implements the location API using the browser's history.pushState API. + + @extends Ember.Object */ -Ember.HistoryLocation = Ember.Object.extend({ +Ember.HistoryLocation = Ember.Object.extend( +/** @scope Ember.HistoryLocation.prototype */ { + + /** @private */ init: function() { set(this, 'location', get(this, 'location') || window.location); set(this, '_initialURL', get(this, 'location').pathname); @@ -10470,8 +10541,7 @@ Ember.HistoryLocation = Ember.Object.extend({ path = this.formatPath(path); - if ((initialURL && initialURL !== path) || (state && state.path !== path)) { - set(this, '_initialURL', null); + if ((initialURL !== path && !state) || (state && state.path !== path)) { window.history.pushState({ path: path }, null, path); } }, @@ -10515,6 +10585,7 @@ Ember.HistoryLocation = Ember.Object.extend({ return url; }, + /** @private */ willDestroy: function() { var guid = Ember.guidFor(this); @@ -10532,12 +10603,17 @@ Ember.Location.registerImplementation('history', Ember.HistoryLocation); var get = Ember.get, set = Ember.set; /** + @class + Ember.NoneLocation does not interact with the browser. It is useful for testing, or when you need to manage state with your Router, but temporarily don't want it to muck with the URL (for example when you embed your application in a larger page). + + @extends Ember.Object */ -Ember.NoneLocation = Ember.Object.extend({ +Ember.NoneLocation = Ember.Object.extend( +/** @scope Ember.NoneLocation.prototype */ { path: '', getURL: function() { @@ -11481,7 +11557,7 @@ var invokeForState = { `Ember.View` is the class in Ember responsible for encapsulating templates of HTML content, combining templates with data to render as sections of a page's DOM, and registering and responding to user-initiated events. - + ## HTML Tag The default HTML tag name used for a view's DOM representation is `div`. This can be customized by setting the `tagName` property. The following view class: @@ -11507,7 +11583,7 @@ var invokeForState = {
`class` attribute values can also be set by providing a `classNameBindings` property - set to an array of properties names for the view. The return value of these properties + set to an array of properties names for the view. The return value of these properties will be added as part of the value for the view's `class` attribute. These properties can be computed properties: @@ -11536,7 +11612,7 @@ var invokeForState = {
- When using boolean class name bindings you can supply a string value other than the + When using boolean class name bindings you can supply a string value other than the property name for use as the `class` HTML attribute by appending the preferred value after a ":" character when defining the binding: @@ -11614,11 +11690,11 @@ var invokeForState = {
- Updates to the the value of a class name binding will result in automatic update + Updates to the the value of a class name binding will result in automatic update of the HTML `class` attribute in the view's rendered HTML representation. If the value becomes `false` or `undefined` the class name will be removed. - Both `classNames` and `classNameBindings` are concatenated properties. + Both `classNames` and `classNameBindings` are concatenated properties. See `Ember.Object` documentation for more information about concatenated properties. ## HTML Attributes @@ -11664,7 +11740,7 @@ var invokeForState = { }.property() }) - Updates to the the property of an attribute binding will result in automatic update + Updates to the the property of an attribute binding will result in automatic update of the HTML attribute in the view's rendered HTML representation. `attributeBindings` is a concatenated property. See `Ember.Object` documentation @@ -11755,7 +11831,7 @@ var invokeForState = { primary templates, layouts can be any function that accepts an optional context parameter and returns a string of HTML that will be inserted inside view's tag. Views whose HTML element is self closing (e.g. ``) cannot have a layout and this property will be ignored. - + Most typically in Ember a layout will be a compiled Ember.Handlebars template. A view's layout can be set directly with the `layout` property or reference an @@ -11780,7 +11856,7 @@ var invokeForState = { See `Handlebars.helpers.yield` for more information. ## Responding to Browser Events - Views can respond to user-initiated events in one of three ways: method implementation, + Views can respond to user-initiated events in one of three ways: method implementation, through an event manager, and through `{{action}}` helper use in their template or layout. ### Method Implementation @@ -11797,8 +11873,8 @@ var invokeForState = { ### Event Managers Views can define an object as their `eventManager` property. This object can then implement methods that match the desired event names. Matching events that occur - on the view's rendered HTML or the rendered HTML of any of its DOM descendants - will trigger this method. A `jQuery.Event` object will be passed as the first + on the view's rendered HTML or the rendered HTML of any of its DOM descendants + will trigger this method. A `jQuery.Event` object will be passed as the first argument to the method and an `Ember.View` object as the second. The `Ember.View` will be the view whose rendered HTML was interacted with. This may be the view with the `eventManager` property or one of its descendent views. @@ -11832,7 +11908,7 @@ var invokeForState = { Similarly a view's event manager will take precedence for events of any views rendered as a descendent. A method name that matches an event name will not be called - if the view instance was rendered inside the HTML representation of a view that has + if the view instance was rendered inside the HTML representation of a view that has an `eventManager` property defined that handles events of the name. Events not handled by the event manager will still trigger method calls on the descendent. @@ -11854,7 +11930,7 @@ var invokeForState = { // eventManager doesn't handle click events }, mouseEnter: function(event){ - // will never be called if rendered inside + // will never be called if rendered inside // an OuterView. } }) @@ -11875,7 +11951,7 @@ var invokeForState = { Form events: 'submit', 'change', 'focusIn', 'focusOut', 'input' HTML5 drag and drop events: 'dragStart', 'drag', 'dragEnter', 'dragLeave', 'drop', 'dragEnd' - + ## Handlebars `{{view}}` Helper Other `Ember.View` instances can be included as part of a view's template by using the `{{view}}` Handlebars helper. See `Handlebars.helpers.view` for additional information. @@ -12092,10 +12168,6 @@ Ember.View = Ember.Object.extend(Ember.Evented, _parentView: null, - // allow navigation between the next and previous views - prevView: null, - nextView: null, - // return the current view, not including virtual views concreteView: Ember.computed(function() { if (!this.isVirtual) { return this; } @@ -12461,6 +12533,8 @@ Ember.View = Ember.Object.extend(Ember.Evented, // JavaScript property changes. var observer = function() { elem = this.$(); + if (!elem) { return; } + attributeValue = get(this, property); Ember.View.applyAttributeBindings(elem, attributeName, attributeValue); @@ -13272,9 +13346,12 @@ Ember.View = Ember.Object.extend(Ember.Evented, element of the actual DOM element. */ _isVisibleDidChange: Ember.observer(function() { + var $el = this.$(); + if (!$el) { return; } + var isVisible = get(this, 'isVisible'); - this.$().toggle(isVisible); + $el.toggle(isVisible); if (this._isAncestorHidden()) { return; } @@ -13407,22 +13484,10 @@ var DOMManager = { }); }, - after: function(parentView, view, newView) { - newView._insertElementLater(function() { - var nextView; - var prevView = view; - while (prevView !== null && prevView.get('state') !== 'inDOM') { - prevView=prevView.get('prevView'); - } - var element; - if (prevView === null) { - element = parentView.$(); - element.prepend(newView.$()); - } else { - element = prevView.$(); - element.after(newView.$()); - } - + after: function(view, nextView) { + nextView._insertElementLater(function() { + var element = view.$(); + element.after(nextView.$()); }); }, @@ -13590,7 +13655,7 @@ Ember.View.states = { }, $: function() { - return Ember.$(); + return undefined; }, getElement: function() { @@ -13695,13 +13760,7 @@ Ember.View.states.inBuffer = { var buffer = view.buffer; childView = this.createChildView(childView, options); - var childViews = get(view, '_childViews'); - - if (childViews.length > 0) { - childViews[childViews.length-1].nextView = childView; - childView.prevView = childViews[childViews.length-1]; - } - childViews.push(childView); + view._childViews.push(childView); childView.renderToBuffer(buffer); @@ -14120,10 +14179,6 @@ Ember.ContainerView = Ember.View.extend({ view = this.createChildView(viewName); } - if (idx>0) { - _childViews[idx-1].nextView = view; - view.prevView = _childViews[idx-1]; - } _childViews[idx] = view; }, this); @@ -14239,7 +14294,7 @@ Ember.ContainerView = Ember.View.extend({ */ _scheduleInsertion: function(view, prev) { if (prev) { - prev.domManager.after(this, prev, view); + prev.domManager.after(prev, view); } else { this.domManager.prepend(this, view); } @@ -14349,7 +14404,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt; @class `Ember.CollectionView` is an `Ember.View` descendent responsible for managing a - collection (an array or array-like object) by maintaing a child view object and + collection (an array or array-like object) by maintaing a child view object and associated DOM representation for each item in the array and ensuring that child views and their associated rendered HTML are updated when items in the array are added, removed, or replaced. @@ -14393,7 +14448,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt; ## Automatic matching of parent/child tagNames - Setting the `tagName` property of a `CollectionView` to any of + Setting the `tagName` property of a `CollectionView` to any of "ul", "ol", "table", "thead", "tbody", "tfoot", "tr", or "select" will result in the item views receiving an appropriately matched `tagName` property. @@ -14560,15 +14615,6 @@ Ember.CollectionView = Ember.ContainerView.extend( if (removingAll) { childView.removedFromDOM = true; } childView.destroy(); } - - // If there is an element before the ones we deleted - if (start>0) { - childViews[start-1].set('nextView', start0 ? childViews[start-1] : null); - } }, /** @@ -14609,11 +14655,6 @@ Ember.CollectionView = Ember.ContainerView.extend( contentIndex: idx }); - // link together the chain of addedViews - if (addedViews.length>0) { - view.set('prevView', addedViews[addedViews.length-1]); - addedViews[addedViews.length-1].set('nextView', view); - } addedViews.push(view); } } else { @@ -14624,20 +14665,6 @@ Ember.CollectionView = Ember.ContainerView.extend( addedViews.push(emptyView); set(this, 'emptyView', emptyView); } - - if (added>0) { - // if there is a childview before the ones we're adding - if (start>0) { - childViews.objectAt(start-1).set('nextView', addedViews[0]); - addedViews[0].set('prevView', childViews.objectAt(start-1)); - } - // if there is a childview after the ones we're adding - if (start - @@ -18873,7 +18912,7 @@ EmberHandlebars.ViewHelper = Ember.Object.create({ }) aView.appendTo('body') - + Will result in HTML structure:
@@ -18947,7 +18986,7 @@ EmberHandlebars.ViewHelper = Ember.Object.create({ Will result in the following HTML:
-
+
hi
@@ -19107,7 +19146,7 @@ var get = Ember.get, getPath = Ember.Handlebars.getPath, fmt = Ember.String.fmt;

Howdy Mary

Howdy Sara

- + @name Handlebars.helpers.collection @param {String} path @param {Hash} options @@ -19405,6 +19444,10 @@ ActionHelper.registerAction = function(actionName, options) { event.context = options.context; } + if (options.hasOwnProperty('contexts')) { + event.contexts = options.contexts; + } + var target = options.target; // Check for StateManager (or compatible object) @@ -19428,7 +19471,7 @@ ActionHelper.registerAction = function(actionName, options) { The `{{action}}` helper registers an HTML element within a template for DOM event handling and forwards that interaction to the Application's router, the template's `Ember.View` instance, or supplied `target` option (see 'Specifiying a Target'). - + User interaction with that element will invoke the supplied action name on the appropriate target. @@ -19473,7 +19516,7 @@ ActionHelper.registerAction = function(actionName, options) { If you need the default handler to trigger you should either register your own event handler, or use event methods on your view class. See Ember.View 'Responding to Browser Events' for more information. - + ### Specifying DOM event type By default the `{{action}}` helper registers for DOM `click` events. You can @@ -19493,23 +19536,23 @@ ActionHelper.registerAction = function(actionName, options) { `Ember.EventDispatcher` instance will be created when a new `Ember.Application` is created. Having an instance of `Ember.Application` will satisfy this requirement. - - + + ### Specifying a Target There are several possible target objects for `{{action}}` helpers: - + In a typical `Ember.Router`-backed Application where views are managed through use of the `{{outlet}}` helper, actions will be forwarded to the current state of the Applications's Router. See Ember.Router 'Responding to User-initiated Events' for more information. - + If you manaully set the `target` property on the controller of a template's `Ember.View` instance, the specifed `controller.target` will become the target for any actions. Likely custom values for a controller's `target` are the controller itself or a StateManager other than the Application's Router. - + If the templates's view lacks a controller property the view itself is the target. - + Finally, a `target` option can be provided to the helper to change which object will receive the method call. This option must be a string representing a path to an object: @@ -19564,7 +19607,7 @@ ActionHelper.registerAction = function(actionName, options) { Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when "click me" is clicked. - + ### Specifying a context By default the `{{action}}` helper passes the current Handlebars context @@ -19590,7 +19633,7 @@ EmberHandlebars.registerHelper('action', function(actionName) { var hash = options.hash, view = options.data.view, - target, context, controller, link; + target, controller, link; // create a hash to pass along to registerAction var action = { @@ -19607,15 +19650,17 @@ EmberHandlebars.registerHelper('action', function(actionName) { action.target = target = target || view; - // TODO: Support multiple contexts if (contexts.length) { - action.context = context = getPath(this, contexts[0], options); + action.contexts = contexts = Ember.EnumerableUtils.map(contexts, function(context) { + return getPath(this, context, options); + }, this); + action.context = contexts[0]; } var output = [], url; if (hash.href && target.urlForEvent) { - url = target.urlForEvent(actionName, context); + url = target.urlForEvent.apply(target, [actionName].concat(contexts)); output.push('href="' + url + '"'); action.link = true; } @@ -19772,7 +19817,7 @@ var set = Ember.set, get = Ember.get; /** @class - Creates an HTML input of type 'checkbox' with HTML related properties + Creates an HTML input of type 'checkbox' with HTML related properties applied directly to the input. {{view Ember.Checkbox classNames="applicaton-specific-checkbox"}} @@ -19796,6 +19841,7 @@ var set = Ember.set, get = Ember.get; Because HTML `input` elements are self closing `layout` and `layoutName` properties will not be applied. See `Ember.View`'s layout section for more information. + @extends Ember.View */ Ember.Checkbox = Ember.View.extend({ classNames: ['ember-checkbox'], @@ -19847,6 +19893,7 @@ Ember.TextSupport = Ember.Mixin.create( insertNewline: Ember.K, cancel: Ember.K, + /** @private */ init: function() { this._super(); this.on("focusOut", this, this._elementValueDidChange); @@ -19904,6 +19951,7 @@ var get = Ember.get, set = Ember.set; Because HTML `input` elements are self closing `layout` and `layoutName` properties will not be applied. See `Ember.View`'s layout section for more information. + @extends Ember.View @extends Ember.TextSupport */ Ember.TextField = Ember.View.extend(Ember.TextSupport, @@ -20080,9 +20128,10 @@ var get = Ember.get, set = Ember.set; ## Layout and LayoutName properties - Because HTML `textarea` elements do not contain inner HTML the `layout` and `layoutName` + Because HTML `textarea` elements do not contain inner HTML the `layout` and `layoutName` properties will not be applied. See `Ember.View`'s layout section for more information. + @extends Ember.View @extends Ember.TextSupport */ Ember.TextArea = Ember.View.extend(Ember.TextSupport, @@ -20097,12 +20146,14 @@ Ember.TextArea = Ember.View.extend(Ember.TextSupport, _updateElementValue: Ember.observer(function() { // We do this check so cursor position doesn't get affected in IE - var value = get(this, 'value'); - if (value !== this.$().val()) { - this.$().val(value); + var value = get(this, 'value'), + $el = this.$(); + if ($el && value !== $el.val()) { + $el.val(value); } }, 'value'), + /** @private */ init: function() { this._super(); this.on("didInsertElement", this, this._updateElementValue); @@ -20434,8 +20485,10 @@ Ember.Select = Ember.View.extend( }, _selectionDidChangeSingle: function() { - var el = this.$()[0], - content = get(this, 'content'), + var el = this.get('element'); + if (!el) { return; } + + var content = get(this, 'content'), selection = get(this, 'selection'), selectionIndex = content ? indexOf(content, selection) : -1, prompt = get(this, 'prompt'); @@ -20609,6 +20662,7 @@ Ember.Handlebars.bootstrap = function(ctx) { }); }; +/** @private */ function bootstrap() { Ember.Handlebars.bootstrap( Ember.$(document) ); } @@ -20640,8 +20694,8 @@ Ember.onLoad('application', bootstrap); })(); -// Version: v0.9.8.1-675-g417213d -// Last commit: 417213d (2012-07-30 13:06:36 +0200) +// Version: v1.0.pre-5-gf1ec52a +// Last commit: f1ec52a (2012-08-06 17:23:55 -0700) (function() { diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 3481edfe..d1549650 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1 +1 @@ -minispade.register('templates', "(function() {Ember.TEMPLATES['auth/show']=Ember.Handlebars.compile(\"

Sign in

\\n\\n

\\n \\n Sign in with GitHub\\n \\n

\\n\\n\");Ember.TEMPLATES['builds/list']=Ember.Handlebars.compile(\"\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n\\n \\n {{#each build in builds}}\\n {{#view Travis.BuildsItemView contextBinding=\\\"build\\\"}}\\n \\n \\n \\n \\n \\n \\n \\n {{/view}}\\n {{/each}}\\n \\n
{{t builds.name}}{{t builds.commit}}{{t builds.message}}{{t builds.duration}}{{t builds.finished_at}}
\\n \\n {{number}}\\n \\n \\n \\n {{formatCommit commit}}\\n \\n \\n {{{formatMessage commit.message short=\\\"true\\\"}}}\\n \\n {{formatDuration duration}}\\n \\n {{formatTime finishedAt}}\\n
\\n\\n

\\n \\n

\\n\");Ember.TEMPLATES['builds/show']=Ember.Handlebars.compile(\"{{#with view}}\\n {{#if build.isLoaded}}\\n
\\n
\\n
\\n
{{t builds.name}}
\\n
{{build.number}}
\\n
{{t builds.finished_at}}
\\n
{{formatTime build.finishedAt}}
\\n
{{t builds.duration}}
\\n
{{formatDuration build.duration}}
\\n
\\n\\n
\\n
{{t builds.commit}}
\\n
{{formatCommit build.commit}}
\\n {{#if commit.compareUrl}}\\n
{{t builds.compare}}
\\n
{{pathFrom build.commit.compareUrl}}
\\n {{/if}}\\n {{#if commit.authorName}}\\n
{{t builds.author}}
\\n
{{build.commit.authorName}}
\\n {{/if}}\\n {{#if commit.committerName}}\\n
{{t builds.committer}}
\\n
{{build.commit.committerName}}
\\n {{/if}}\\n
\\n\\n
{{t builds.message}}
\\n
{{{formatMessage build.commit.message}}}
\\n\\n {{#unless isMatrix}}\\n
{{t builds.config}}
\\n
{{formatConfig build.config}}
\\n {{/unless}}\\n
\\n\\n {{#if build.isMatrix}}\\n {{view Travis.JobsView jobsBinding=\\\"build.requiredJobs\\\" required=\\\"true\\\"}}\\n {{view Travis.JobsView jobsBinding=\\\"build.allowedFailureJobs\\\"}}\\n {{else}}\\n {{view Travis.LogView contextBinding=\\\"build.jobs.firstObject\\\"}}\\n {{/if}}\\n
\\n {{else}}\\n
\\n Loading\\n
\\n {{/if}}\\n{{/with}}\\n\");Ember.TEMPLATES['jobs/list']=Ember.Handlebars.compile(\"{{#if view.jobs.length}}\\n {{#if view.required}}\\n \\n \\n {{else}}\\n
\\n {{t jobs.build_matrix}}\\n
\\n \\n {{/if}}\\n \\n \\n {{#each key in view.build.configKeys}}\\n \\n {{/each}}\\n \\n \\n \\n {{#each job in view.jobs}}\\n {{#view Travis.JobsItemView contextBinding=\\\"job\\\"}}\\n \\n \\n \\n {{#each value in configValues}}\\n \\n {{/each}}\\n {{/view}}\\n {{/each}}\\n \\n
\\n {{t jobs.allowed_failures}}\\n \\n
{{key}}
{{number}}{{formatDuration duration}}{{formatTime finishedAt}}{{value}}
\\n\\n {{#unless required}}\\n
\\n
{{t \\\"jobs.allowed_failures\\\"}}
\\n
\\n

\\n Allowed Failures are items in your build matrix that are allowed to\\n fail without causing the entire build to be shown as failed. This lets you add\\n in experimental and preparatory builds to test against versions or\\n configurations that you are not ready to officially support.\\n

\\n

\\n You can define allowed failures in the build matrix as follows:\\n

\\n
 matrix:\\n  allow_failures:\\n    - rvm: ruby-head 
\\n
\\n
\\n {{/unless}}\\n{{/if}}\\n\");Ember.TEMPLATES['jobs/log']=Ember.Handlebars.compile(\"{{view.logSubscriber}}\\n\\n{{#if log.isLoaded}}\\n
{{{formatLog log.body}}}
\\n\\n {{#if sponsor.name}}\\n

\\n {{t builds.messages.sponsored_by}}\\n {{sponsor.name}}\\n

\\n {{/if}}\\n{{else}}\\n
\\n Loading\\n
\\n{{/if}}\\n\");Ember.TEMPLATES['jobs/show']=Ember.Handlebars.compile(\"{{#with view}}\\n {{#if job.isLoaded}}\\n
\\n
\\n
\\n
Job
\\n
{{job.number}}
\\n
{{t jobs.finished_at}}
\\n
{{formatTime job.finishedAt}}
\\n
{{t jobs.duration}}
\\n
{{formatDuration job.duration}}
\\n
\\n\\n
\\n
{{t jobs.commit}}
\\n
{{formatCommit commit}}
\\n {{#if commit.compareUrl}}\\n
{{t jobs.compare}}
\\n
{{pathFrom commit.compareUrl}}
\\n {{/if}}\\n {{#if commit.authorName}}\\n
{{t jobs.author}}
\\n
{{commit.authorName}}
\\n {{/if}}\\n {{#if commit.committerName}}\\n
{{t jobs.committer}}
\\n
{{commit.committerName}}
\\n {{/if}}\\n
\\n\\n
{{t jobs.message}}
\\n
{{formatMessage commit.message}}
\\n
{{t jobs.config}}
\\n
{{formatConfig job.config}}
\\n
\\n\\n {{view Travis.LogView contextBinding=\\\"job\\\"}}}\\n
\\n {{else}}\\n
\\n Loading\\n
\\n {{/if}}\\n{{/with}}\\n\");Ember.TEMPLATES['layouts/home']=Ember.Handlebars.compile(\"
\\n {{outlet top}}\\n
\\n\\n
\\n {{outlet left}}\\n
\\n\\n
\\n {{outlet main}}\\n\\n
\\n {{outlet right}}\\n
\\n
\\n\\n\");Ember.TEMPLATES['layouts/profile']=Ember.Handlebars.compile(\"
\\n {{outlet top}}\\n
\\n\\n
\\n {{outlet left}}\\n
\\n\\n
\\n {{outlet main}}\\n\\n
\\n
\\n
 \\n
\\n\\n
\\n

Getting started?

\\n

\\n Please read our guide.\\n It will only take a few minutes :)\\n

\\n

\\n You can find detailled docs on our about site.\\n

\\n

\\n If you need help please don't hesitate to join\\n #travis on irc.freenode.net\\n or our mailinglist.\\n

\\n
\\n
\\n
\\n\\n\");Ember.TEMPLATES['layouts/sidebar']=Ember.Handlebars.compile(\"\\n {{t layouts.application.fork_me}}\\n\\n\\n
\\n
 \\n
\\n\\n{{outlet decks}}\\n{{outlet workers}}\\n{{outlet queues}}\\n{{outlet links}}\\n\\n
\\n

{{t layouts.about.alpha}}

\\n

{{{t layouts.about.messages.alpha}}}

\\n
\\n\\n
\\n

{{t layouts.about.join}}

\\n \\n
\\n\");Ember.TEMPLATES['layouts/simple']=Ember.Handlebars.compile(\"
\\n {{outlet top}}\\n
\\n\\n
\\n {{outlet main}}\\n
\\n\\n\");Ember.TEMPLATES['layouts/top']=Ember.Handlebars.compile(\"\\n

Travis

\\n
\\n\\n\\n\");Ember.TEMPLATES['profile/owners']=Ember.Handlebars.compile(\"
\\n
\\n\\n\\n\\n
\\n {{#collection Travis.OwnersListView contentBinding=\\\"controller\\\"}}\\n {{view.name}}\\n

\\n Repositories:\\n {{view.content.reposCount}}\\n

\\n {{/collection}}\\n
\\n\");Ember.TEMPLATES['profile/show']=Ember.Handlebars.compile(\"

{{owner.name}}

\\n\\n{{view Travis.ProfileTabsView}}\\n\\n
\\n {{outlet pane}}\\n
\\n\\n\\n\");Ember.TEMPLATES['profile/tabs']=Ember.Handlebars.compile(\"\\n\");Ember.TEMPLATES['profile/tabs/hooks']=Ember.Handlebars.compile(\"

\\n {{{t profiles.show.message.your_repos}}}\\n

\\n\\n{{#if hooks.length}}\\n
    \\n {{#each hook in hooks}}\\n
  • \\n {{hook.slug}}\\n

    {{hook.description}}

    \\n\\n
    \\n \\n \\n
    \\n
  • \\n {{/each}}\\n
\\n{{else}}\\n

Please wait while we sync with GitHub

\\n{{/if}}\\n\\n\\n\");Ember.TEMPLATES['profile/tabs/user']=Ember.Handlebars.compile(\"\\n\\n
\\n
\\n {{t profiles.show.github}}:\\n
\\n
\\n {{user.login}}\\n
\\n
\\n {{t profiles.show.email}}:\\n
\\n
\\n {{user.email}}\\n
\\n
\\n {{t profiles.show.token}}:\\n
\\n
\\n {{user.token}}\\n
\\n
\\n\\n
\\n {{view Ember.Select\\n contentBinding=\\\"view.locales\\\"\\n selectionBinding=\\\"user.locale\\\"\\n optionLabelPath=\\\"content.name\\\"\\n optionValuePath=\\\"content.key\\\"}}\\n\\n \\n
\\n\\n\\n\");Ember.TEMPLATES['queues/list']=Ember.Handlebars.compile(\"{{#each queue in controller}}\\n

{{t queue}}: {{queue.name}}

\\n
    \\n {{#each queue}}\\n
  • \\n {{repository.slug}}\\n {{#if number}}\\n #{{number}}\\n {{/if}}\\n
  • \\n {{else}}\\n {{t no_job}}\\n {{/each}}\\n
\\n{{/each}}\\n\");Ember.TEMPLATES['repos/list']=Ember.Handlebars.compile(\"
\\n {{view Ember.TextField valueBinding=\\\"controller.search\\\"}}\\n
\\n\\n{{view Travis.ReposListTabsView}}\\n\\n
\\n {{#collection Travis.RepositoriesListView contentBinding=\\\"controller\\\"}}\\n {{#with view.repository}}\\n {{slug}}\\n #{{lastBuildNumber}}\\n\\n

\\n {{t repositories.duration}}:\\n {{formatDuration lastBuildDuration}},\\n {{t repositories.finished_at}}:\\n {{formatTime lastBuildFinishedAt}}\\n

\\n {{#if description}}\\n

{{description}}

\\n {{/if}}\\n \\n {{/with}}\\n {{/collection}}\\n
\\n\");Ember.TEMPLATES['repos/list/tabs']=Ember.Handlebars.compile(\"\\n\\n\");Ember.TEMPLATES['repos/show']=Ember.Handlebars.compile(\"
\\n {{#if view.repository.isLoaded}}\\n {{#with view.repository}}\\n

\\n {{slug}}\\n

\\n\\n

{{description}}

\\n\\n \\n\\n {{view Travis.RepoShowTabsView}}\\n {{/with}}\\n\\n {{else}}\\n Loading\\n {{/if}}\\n\\n
\\n {{outlet pane}}\\n
\\n
\\n\\n\");Ember.TEMPLATES['repos/show/tabs']=Ember.Handlebars.compile(\"\\n\\n
\\n \\n
\\n

\\n \\n {{view Ember.Select contentBinding=\\\"view.branches\\\" selectionBinding=\\\"view.branch\\\" optionLabelPath=\\\"content.commit.branch\\\" optionValuePath=\\\"content.commit.branch\\\"}}\\n

\\n

\\n \\n \\n

\\n

\\n \\n \\n

\\n

\\n \\n \\n

\\n

\\n \\n \\n

\\n
\\n
\\n\");Ember.TEMPLATES['sponsors/decks']=Ember.Handlebars.compile(\"

{{t layouts.application.sponsers}}

\\n\\n
    \\n {{#each deck in controller}}\\n {{#each deck}}\\n
  • \\n \\n \\n \\n
  • \\n {{/each}}\\n {{/each}}\\n
\\n\\n

\\n \\n {{{t layouts.application.sponsors_link}}}\\n \\n

\\n\");Ember.TEMPLATES['sponsors/links']=Ember.Handlebars.compile(\"
\\n

{{t layouts.application.sponsers}}

\\n\\n
    \\n {{#each controller}}\\n
  • \\n {{{link}}}\\n
  • \\n {{/each}}\\n
\\n\\n

\\n \\n {{{t layouts.application.sponsors_link}}}\\n \\n

\\n
\\n\\n\");Ember.TEMPLATES['stats/show']=Ember.Handlebars.compile(\"
\\n
\\n\");Ember.TEMPLATES['workers/list']=Ember.Handlebars.compile(\"

{{t workers}}

\\n
    \\n {{#each group in controller.groups}}\\n {{#view Travis.WorkersView contextBinding=\\\"repository\\\"}}\\n
  • \\n
    \\n {{group.firstObject.host}}\\n
    \\n \\n
  • \\n {{/view}}\\n {{else}}\\n No workers\\n {{/each}}\\n
\\n\\n\");\n})();\n//@ sourceURL=templates");minispade.register('app', "(function() {(function() {\nminispade.require('travis');\nminispade.require('controllers');\nminispade.require('helpers');\nminispade.require('models');\nminispade.require('pusher');\nminispade.require('routes');\nminispade.require('store');\nminispade.require('templates');\nminispade.require('views');\nminispade.require('config/locales');\nminispade.require('data/sponsors');\n\n Ember.ENV.RAISE_ON_DEPRECATION = true;\n\n Travis.reopen({\n App: Em.Application.extend({\n init: function() {\n this._super();\n this.connect();\n this.store = Travis.Store.create();\n this.store.loadMany(Travis.Sponsor, Travis.SPONSORS);\n this.routes = new Travis.Routes();\n this.pusher = new Travis.Pusher();\n return this.setCurrentUser(JSON.parse($.cookie('user')));\n },\n signIn: function() {\n this.setCurrentUser({\n id: 1,\n login: 'svenfuchs',\n name: 'Sven Fuchs',\n email: 'me@svenfuchs.com',\n token: '1234567890',\n gravatar: '402602a60e500e85f2f5dc1ff3648ecb',\n locale: 'en'\n });\n return this.render.apply(this, this.get('returnTo') || ['home', 'index']);\n },\n signOut: function() {\n return this.setCurrentUser();\n },\n setCurrentUser: function(user) {\n if (typeof user === 'string') {\n user = JSON.parse(user);\n }\n $.cookie('user', JSON.stringify(user));\n if (user) {\n this.store.load(Travis.User, user);\n }\n return this.set('currentUser', user ? Travis.User.find(user.id) : void 0);\n },\n render: function(name, action, params) {\n var layout;\n layout = this.connectLayout(name);\n layout.activate(action, params || {});\n return $('body').attr('id', name);\n },\n receive: function() {\n return this.store.receive.apply(this.store, arguments);\n },\n connectLayout: function(name) {\n var viewClass;\n if (this.get('layout.name') !== name) {\n name = $.camelize(name);\n viewClass = Travis[\"\" + name + \"Layout\"];\n this.layout = Travis[\"\" + name + \"Controller\"].create({\n parent: this.controller\n });\n this.controller.connectOutlet({\n outletName: 'layout',\n controller: this.layout,\n viewClass: viewClass\n });\n }\n return this.layout;\n },\n connect: function() {\n var view;\n this.controller = Em.Controller.create();\n view = Em.View.create({\n template: Em.Handlebars.compile('{{outlet layout}}'),\n controller: this.controller\n });\n return view.appendTo(this.get('rootElement') || 'body');\n },\n toggleSidebar: function() {\n var element;\n $('body').toggleClass('maximized');\n element = $('');\n $('#top .profile').append(element);\n Em.run.later((function() {\n return element.remove();\n }), 10);\n element = $('');\n $('#repository').append(element);\n return Em.run.later((function() {\n return element.remove();\n }), 10);\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=app");minispade.register('controllers', "(function() {(function() {\nminispade.require('helpers');\nminispade.require('travis/ticker');\n\n Travis.reopen({\n Controller: Em.Controller.extend({\n init: function() {\n var klass, name, _i, _len, _ref, _results;\n _ref = Array.prototype.slice.apply(arguments);\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n name = _ref[_i];\n name = \"\" + ($.camelize(name, false)) + \"Controller\";\n klass = Travis[$.camelize(name)] || Em.Controller;\n _results.push(this[name] = klass.create({\n parent: this,\n namespace: Travis,\n controllers: this\n }));\n }\n return _results;\n },\n connectTop: function() {\n this.connectOutlet({\n outletName: 'top',\n controller: this.topController,\n viewClass: Travis.TopView\n });\n return this.topController.set('tab', this.get('name'));\n },\n connectOutlet: function() {\n var view, _connectedOutletViews;\n view = this._super.apply(this, arguments);\n if (view) {\n _connectedOutletViews = Travis.app.get('_connectedOutletViews');\n if (!_connectedOutletViews) {\n _connectedOutletViews = [];\n }\n _connectedOutletViews.pushObject(view);\n Travis.app.set('_connectedOutletViews', _connectedOutletViews);\n }\n return view;\n }\n }),\n TopController: Em.Controller.extend({\n userBinding: 'Travis.app.currentUser'\n })\n });\nminispade.require('controllers/auth');\nminispade.require('controllers/builds');\nminispade.require('controllers/home');\nminispade.require('controllers/owners');\nminispade.require('controllers/profile');\nminispade.require('controllers/repositories');\nminispade.require('controllers/repository');\nminispade.require('controllers/sidebar');\nminispade.require('controllers/stats');\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers");minispade.register('controllers/auth', "(function() {(function() {\nminispade.require('controllers');\n\n this.Travis.AuthController = Travis.Controller.extend({\n name: 'auth',\n init: function() {\n this._super('top');\n this.connectTop();\n return this.connectOutlet({\n outletName: 'main',\n controller: this,\n viewClass: Travis.AuthView\n });\n },\n activate: function(action, params) {}\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/auth");minispade.register('controllers/builds', "(function() {(function() {\n\n Travis.BuildsController = Em.ArrayController.extend({\n repositoryBinding: 'parent.repository',\n contentBinding: 'parent.builds'\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/builds");minispade.register('controllers/home', "(function() {(function() {\n\n Travis.HomeController = Travis.Controller.extend({\n name: 'home',\n init: function() {\n this._super('top', 'repositories', 'repository', 'sidebar');\n this.connectTop();\n this.connectOutlet({\n outletName: 'left',\n controller: this.repositoriesController,\n viewClass: Travis.RepositoriesView\n });\n this.connectOutlet({\n outletName: 'main',\n controller: this.repositoryController,\n viewClass: Travis.RepositoryView\n });\n return this.connectOutlet({\n outletName: 'right',\n controller: this.sidebarController,\n viewClass: Travis.SidebarView\n });\n },\n activate: function(action, params) {\n return this.repositoryController.activate(action, params);\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/home");minispade.register('controllers/owners', "(function() {(function() {\n\n Travis.OwnersController = Ember.ArrayController.extend({\n defaultTab: 'accounts',\n init: function() {\n return this.activate(this.defaultTab);\n },\n activate: function(tab, params) {\n this.set('tab', tab);\n return this[\"view\" + ($.camelize(tab))](params);\n },\n viewAccounts: function() {\n return this.set('content', Travis.Owner.find());\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/owners");minispade.register('controllers/profile', "(function() {(function() {\n\n Travis.ProfileController = Travis.Controller.extend({\n name: 'profile',\n userBinding: 'Travis.app.currentUser',\n init: function() {\n this._super('top', 'owners');\n this.connectTop();\n this.connectOutlet({\n outletName: 'left',\n controller: this.ownersController,\n viewClass: Travis.OwnersView\n });\n this.connectOutlet({\n outletName: 'main',\n controller: this,\n viewClass: Travis.ProfileView\n });\n return this.owners = this.ownersController.get('content');\n },\n owner: (function() {\n var login;\n login = this.get('params.login') || Travis.app.get('currentUser.login');\n return this.owners.toArray().filter(function(owner) {\n if (owner.get('login') === login) {\n return owner;\n }\n })[0];\n }).property('owners.length', 'params.login'),\n activate: function(action, params) {\n this.setParams(params || this.get('params'));\n return this[\"view\" + ($.camelize(action))]();\n },\n viewHooks: function() {\n this.connectTab('hooks');\n return this.set('hooks', Travis.Hook.find({\n login: this.get('params.login') || Travis.app.get('currentUser.login')\n }));\n },\n viewUser: function() {\n return this.connectTab('user');\n },\n connectTab: function(tab) {\n var viewClass;\n viewClass = Travis[\"\" + ($.camelize(tab)) + \"View\"];\n this.set('tab', tab);\n return this.connectOutlet({\n outletName: 'pane',\n controller: this,\n viewClass: viewClass\n });\n },\n setParams: function(params) {\n var key, value, _results;\n this.set('params', {});\n _results = [];\n for (key in params) {\n value = params[key];\n _results.push(this.set(\"params.\" + key, params[key]));\n }\n return _results;\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/profile");minispade.register('controllers/repositories', "(function() {(function() {\n\n Travis.RepositoriesController = Ember.ArrayController.extend({\n defaultTab: 'recent',\n sortProperties: ['sortOrder'],\n init: function() {\n this.activate(this.defaultTab);\n return Ember.run.later(this.updateTimes.bind(this), Travis.INTERVALS.updateTimes);\n },\n updateTimes: function() {\n var content;\n if (content = this.get('content')) {\n content.forEach(function(r) {\n return r.updateTimes();\n });\n }\n return Ember.run.later(this.updateTimes.bind(this), Travis.INTERVALS.updateTimes);\n },\n activate: function(tab, params) {\n this.set('tab', tab);\n return this[\"view\" + ($.camelize(tab))](params);\n },\n viewRecent: function() {\n return this.set('content', Travis.Repository.find());\n },\n viewOwned: function() {\n return this.set('content', Travis.Repository.ownedBy(Travis.get('currentUser.login')));\n },\n viewSearch: function(params) {\n return this.set('content', Travis.Repository.search(params.search));\n },\n searchObserver: (function() {\n var search, tab;\n search = this.get('search');\n tab = search ? 'search' : 'recent';\n return this.activate(tab, {\n search: search\n });\n }).observes('search')\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/repositories");minispade.register('controllers/repository', "(function() {(function() {\n\n Travis.RepositoryController = Travis.Controller.extend({\n bindings: [],\n params: {},\n init: function() {\n this._super('builds', 'build', 'job');\n return Ember.run.later(this.updateTimes.bind(this), Travis.INTERVALS.updateTimes);\n },\n updateTimes: function() {\n var build, builds;\n if (builds = this.get('builds')) {\n builds.forEach(function(b) {\n return b.updateTimes();\n });\n }\n if (build = this.get('build')) {\n build.updateTimes();\n build.get('jobs').forEach(function(j) {\n return j.updateTimes();\n });\n }\n return Ember.run.later(this.updateTimes.bind(this), Travis.INTERVALS.updateTimes);\n },\n activate: function(action, params) {\n this._unbind();\n this.setParams(params);\n return this[\"view\" + ($.camelize(action))]();\n },\n viewIndex: function() {\n this._bind('repository', 'controllers.repositoriesController.firstObject');\n this._bind('build', 'repository.lastBuild');\n return this.connectTab('current');\n },\n viewCurrent: function() {\n this.connectTab('current');\n this._bind('repository', 'repositoriesByParams.firstObject');\n return this._bind('build', 'repository.lastBuild');\n },\n viewBuilds: function() {\n this.connectTab('builds');\n this._bind('repository', 'repositoriesByParams.firstObject');\n return this._bind('builds', 'repository.builds');\n },\n viewPullRequests: function() {\n this.connectTab('pull_requests');\n this._bind('repository', 'repositoriesByParams.firstObject');\n return this._bind('builds', 'repository.pullRequests');\n },\n viewBranches: function() {\n this.connectTab('branches');\n this._bind('repository', 'repositoriesByParams.firstObject');\n return this._bind('builds', 'repository.branches');\n },\n viewBuild: function() {\n this._bind('repository', 'repositoriesByParams.firstObject');\n this._bind('build', 'buildById');\n return this.connectTab('build');\n },\n viewJob: function() {\n this._bind('repository', 'repositoriesByParams.firstObject');\n this._bind('build', 'job.build');\n this._bind('job', 'jobById');\n return this.connectTab('job');\n },\n repositoriesByParams: (function() {\n return Travis.Repository.bySlug(\"\" + (this.get('params.owner')) + \"/\" + (this.get('params.name')));\n }).property('params.owner', 'params.name'),\n buildById: (function() {\n var id;\n if (id = this.get('params.id')) {\n return Travis.Build.find(id);\n }\n }).property('params.id'),\n jobById: (function() {\n var id;\n if (id = this.get('params.id')) {\n return Travis.Job.find(id);\n }\n }).property('params.id'),\n connectTab: function(tab) {\n var name, viewClass;\n name = tab === 'current' ? 'build' : tab;\n viewClass = name === 'builds' || name === 'branches' || name === 'pull_requests' ? Travis.BuildsView : Travis[\"\" + ($.camelize(name)) + \"View\"];\n this.set('tab', tab);\n return this.connectOutlet({\n outletName: 'pane',\n controller: this,\n viewClass: viewClass\n });\n },\n setParams: function(params) {\n var key, value, _results;\n _results = [];\n for (key in params) {\n value = params[key];\n _results.push(this.set(\"params.\" + key, params[key]));\n }\n return _results;\n },\n _bind: function(to, from) {\n return this.bindings.push(Ember.oneWay(this, to, from));\n },\n _unbind: function() {\n var binding, _i, _len, _ref;\n _ref = this.bindings;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n binding = _ref[_i];\n binding.disconnect(this);\n }\n return this.bindings.length = 0;\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/repository");minispade.register('controllers/sidebar', "(function() {(function() {\n\n Travis.reopen({\n SidebarController: Em.ArrayController.extend({\n init: function() {\n this.tickables = [];\n Travis.Ticker.create({\n target: this,\n interval: Travis.INTERVALS.sponsors\n });\n this.connectWorkers(Travis.Worker.find());\n this.connectQueues(Travis.QUEUES);\n this.connectSponsors('decks', Travis.Sponsor.decks(), 1);\n return this.connectSponsors('links', Travis.Sponsor.links(), 6);\n },\n connectSponsors: function(name, sponsors, perPage) {\n var controller, viewClass;\n controller = Travis.SponsorsController.create({\n perPage: perPage,\n content: sponsors\n });\n viewClass = Em.View.extend({\n templateName: \"sponsors/\" + name\n });\n this.connectOutlet({\n outletName: name,\n controller: controller,\n viewClass: viewClass\n });\n return this.tickables.push(controller);\n },\n connectWorkers: function(workers) {\n var controller, viewClass;\n controller = Travis.WorkersController.create({\n content: workers\n });\n viewClass = Em.View.extend({\n templateName: 'workers/list'\n });\n return this.connectOutlet({\n outletName: 'workers',\n controller: controller,\n viewClass: viewClass\n });\n },\n connectQueues: function(queues) {\n var controller, queue, viewClass;\n queues = (function() {\n var _i, _len, _results;\n _results = [];\n for (_i = 0, _len = queues.length; _i < _len; _i++) {\n queue = queues[_i];\n _results.push(Em.ArrayController.create({\n content: Travis.Job.queued(queue.name),\n id: \"queue_\" + queue.name,\n name: queue.display\n }));\n }\n return _results;\n })();\n controller = Travis.QueuesController.create({\n content: queues\n });\n viewClass = Em.View.extend({\n templateName: 'queues/list'\n });\n return this.connectOutlet({\n outletName: 'queues',\n controller: controller,\n viewClass: viewClass\n });\n },\n tick: function() {\n var tickable, _i, _len, _ref, _results;\n _ref = this.tickables;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n tickable = _ref[_i];\n _results.push(tickable.tick());\n }\n return _results;\n }\n }),\n QueuesController: Em.ArrayController.extend(),\n WorkersController: Em.ArrayController.extend({\n groups: (function() {\n var groups, host, worker, _i, _len, _ref;\n groups = {};\n _ref = this.get('content').toArray();\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n worker = _ref[_i];\n host = worker.get('host');\n if (!groups[host]) {\n groups[host] = Em.ArrayProxy.create({\n content: []\n });\n }\n groups[host].pushObject(worker);\n }\n return $.values(groups);\n }).property('content.length')\n }),\n SponsorsController: Em.ArrayController.extend({\n page: 0,\n arrangedContent: (function() {\n return this.get('shuffled').slice(this.start(), this.end());\n }).property('shuffled.length', 'page'),\n shuffled: (function() {\n var content;\n if (content = this.get('content')) {\n return $.shuffle(content);\n } else {\n return [];\n }\n }).property('content.length'),\n tick: function() {\n return this.set('page', this.isLast() ? 0 : this.get('page') + 1);\n },\n pages: (function() {\n var length;\n length = this.get('content.length');\n if (length) {\n return parseInt(length / this.get('perPage') + 1);\n } else {\n return 1;\n }\n }).property('length'),\n isLast: function() {\n return this.get('page') === this.get('pages') - 1;\n },\n start: function() {\n return this.get('page') * this.get('perPage');\n },\n end: function() {\n return this.start() + this.get('perPage');\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/sidebar");minispade.register('controllers/stats', "(function() {(function() {\n\n Travis.StatsController = Travis.Controller.extend({\n name: 'stats',\n init: function() {\n this._super('top');\n this.connectTop();\n return this.connectOutlet({\n outletName: 'main',\n controller: this,\n viewClass: Travis.StatsView\n });\n },\n activate: function(action, params) {}\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/stats");minispade.register('helpers', "(function() {(function() {\nminispade.require('helpers/handlebars');\nminispade.require('helpers/helpers');\nminispade.require('helpers/urls');\n\n}).call(this);\n\n})();\n//@ sourceURL=helpers");minispade.register('helpers/handlebars', "(function() {(function() {\n var safe;\nminispade.require('ext/ember/bound_helper');\n\n safe = function(string) {\n return new Handlebars.SafeString(string);\n };\n\n Handlebars.registerHelper('tipsy', function(text, tip) {\n return safe('' + text + '');\n });\n\n Handlebars.registerHelper('t', function(key) {\n return safe(I18n.t(key));\n });\n\n Ember.registerBoundHelper('formatTime', function(value, options) {\n return safe(Travis.Helpers.timeAgoInWords(value) || '-');\n });\n\n Ember.registerBoundHelper('formatDuration', function(duration, options) {\n return safe(Travis.Helpers.timeInWords(duration));\n });\n\n Ember.registerBoundHelper('formatCommit', function(commit, options) {\n if (commit) {\n return safe(Travis.Helpers.formatCommit(commit.get('sha'), commit.get('branch')));\n }\n });\n\n Ember.registerBoundHelper('formatSha', function(sha, options) {\n return safe(Travis.Helpers.formatSha(sha));\n });\n\n Ember.registerBoundHelper('pathFrom', function(url, options) {\n return safe(Travis.Helpers.pathFrom(url));\n });\n\n Ember.registerBoundHelper('formatMessage', function(message, options) {\n return safe(Travis.Helpers.formatMessage(message, options));\n });\n\n Ember.registerBoundHelper('formatConfig', function(config, options) {\n return safe(Travis.Helpers.formatConfig(config));\n });\n\n Ember.registerBoundHelper('formatLog', function(log, options) {\n return Travis.Helpers.formatLog(log) || '';\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=helpers/handlebars");minispade.register('helpers/helpers', "(function() {(function() {\nminispade.require('travis/log');\nminispade.require('emoij');\n\n this.Travis.Helpers = {\n compact: function(object) {\n var key, result, value, _ref;\n result = {};\n _ref = object || {};\n for (key in _ref) {\n value = _ref[key];\n if (!$.isEmpty(value)) {\n result[key] = value;\n }\n }\n return result;\n },\n safe: function(string) {\n return new Handlebars.SafeString(string);\n },\n colorForResult: function(result) {\n if (result === 0) {\n return 'green';\n } else {\n if (result === 1) {\n return 'red';\n } else {\n return null;\n }\n }\n },\n formatCommit: function(sha, branch) {\n return Travis.Helpers.formatSha(sha) + (branch ? \" (\" + branch + \")\" : '');\n },\n formatSha: function(sha) {\n return (sha || '').substr(0, 7);\n },\n formatConfig: function(config) {\n var values;\n config = $.only(config, 'rvm', 'gemfile', 'env', 'otp_release', 'php', 'node_js', 'scala', 'jdk', 'python', 'perl');\n values = $.map(config, function(value, key) {\n value = (value && value.join ? value.join(', ') : value) || '';\n return '%@: %@'.fmt($.camelize(key), value);\n });\n if (values.length === 0) {\n return '-';\n } else {\n return values.join(', ');\n }\n },\n formatMessage: function(message, options) {\n message = message || '';\n if (options.short) {\n message = message.split(/\\n/)[0];\n }\n return this._emojize(this._escape(message)).replace(/\\n/g, '
');\n },\n formatLog: function(log) {\n return Travis.Log.filter(log);\n },\n pathFrom: function(url) {\n return (url || '').split('/').pop();\n },\n timeAgoInWords: function(date) {\n return $.timeago.distanceInWords(date);\n },\n durationFrom: function(started, finished) {\n started = started && this._toUtc(new Date(this._normalizeDateString(started)));\n finished = finished ? this._toUtc(new Date(this._normalizeDateString(finished))) : this._nowUtc();\n if (started && finished) {\n return Math.round((finished - started) / 1000);\n } else {\n return 0;\n }\n },\n timeInWords: function(duration) {\n var days, hours, minutes, result, seconds;\n days = Math.floor(duration / 86400);\n hours = Math.floor(duration % 86400 / 3600);\n minutes = Math.floor(duration % 3600 / 60);\n seconds = duration % 60;\n if (days > 0) {\n return 'more than 24 hrs';\n } else {\n result = [];\n if (hours === 1) {\n result.push(hours + ' hr');\n }\n if (hours > 1) {\n result.push(hours + ' hrs');\n }\n if (minutes > 0) {\n result.push(minutes + ' min');\n }\n if (seconds > 0) {\n result.push(seconds + ' sec');\n }\n if (result.length > 0) {\n return result.join(' ');\n } else {\n return '-';\n }\n }\n },\n _normalizeDateString: function(string) {\n if (window.JHW) {\n string = string.replace('T', ' ').replace(/-/g, '/');\n string = string.replace('Z', '').replace(/\\..*$/, '');\n }\n return string;\n },\n _nowUtc: function() {\n return this._toUtc(new Date());\n },\n _toUtc: function(date) {\n return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());\n },\n _emojize: function(text) {\n var emojis;\n emojis = text.match(/:\\S+?:/g);\n if (emojis !== null) {\n $.each(emojis.uniq(), function(ix, emoji) {\n var image, strippedEmoji;\n strippedEmoji = emoji.substring(1, emoji.length - 1);\n if (EmojiDictionary.indexOf(strippedEmoji) !== -1) {\n image = '\\''';\n return text = text.replace(new RegExp(emoji, 'g'), image);\n }\n });\n }\n return text;\n },\n _escape: function(text) {\n return text.replace(/&/g, '&').replace(//g, '>');\n }\n };\n\n}).call(this);\n\n})();\n//@ sourceURL=helpers/helpers");minispade.register('helpers/urls', "(function() {(function() {\n\n this.Travis.Urls = {\n repository: function(slug) {\n return \"/\" + slug;\n },\n builds: function(slug) {\n return \"/\" + slug + \"/builds\";\n },\n pullRequests: function(slug) {\n return \"/\" + slug + \"/pull_requests\";\n },\n branches: function(slug) {\n return \"/\" + slug + \"/branches\";\n },\n build: function(slug, id) {\n return \"/\" + slug + \"/builds/\" + id;\n },\n job: function(slug, id) {\n return \"/\" + slug + \"/jobs/\" + id;\n },\n githubCommit: function(slug, sha) {\n return \"http://github.com/\" + slug + \"/commit/\" + sha;\n },\n githubRepository: function(slug) {\n return \"http://github.com/\" + slug;\n },\n githubWatchers: function(slug) {\n return \"http://github.com/\" + slug + \"/watchers\";\n },\n githubNetwork: function(slug) {\n return \"http://github.com/\" + slug + \"/network\";\n },\n githubAdmin: function(slug) {\n return \"http://github.com/\" + slug + \"/admin/hooks#travis_minibucket\";\n },\n statusImage: function(slug, branch) {\n return (\"https://secure.travis-ci.org/\" + slug + \".png\") + (branch ? \"?branch=\" + branch : '');\n },\n email: function(email) {\n return \"mailto:\" + email;\n },\n owner: function(login) {\n return \"/profile/\" + login;\n }\n };\n\n}).call(this);\n\n})();\n//@ sourceURL=helpers/urls");minispade.register('models', "(function() {(function() {\nminispade.require('models/extensions');\nminispade.require('models/artifact');\nminispade.require('models/branch');\nminispade.require('models/build');\nminispade.require('models/commit');\nminispade.require('models/hook');\nminispade.require('models/job');\nminispade.require('models/owner');\nminispade.require('models/repository');\nminispade.require('models/sponsor');\nminispade.require('models/user');\nminispade.require('models/worker');\n\n}).call(this);\n\n})();\n//@ sourceURL=models");minispade.register('models/artifact', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Artifact = Travis.Model.extend({\n body: DS.attr('string'),\n append: function(body) {\n return this.set('body', this.get('body') + body);\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/artifact");minispade.register('models/branch', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Branch = Travis.Model.extend(Travis.Helpers, {\n repositoryId: DS.attr('number'),\n commitId: DS.attr('number'),\n number: DS.attr('number'),\n branch: DS.attr('string'),\n message: DS.attr('string'),\n result: DS.attr('number'),\n duration: DS.attr('number'),\n started_at: DS.attr('string'),\n finished_at: DS.attr('string'),\n commit: DS.belongsTo('Travis.Commit'),\n repository: (function() {\n if (this.get('repositoryId')) {\n return Travis.Repository.find(this.get('repositoryId'));\n }\n }).property('repositoryId'),\n tick: function() {\n this.notifyPropertyChange('started_at');\n return this.notifyPropertyChange('finished_at');\n }\n });\n\n this.Travis.Branch.reopenClass({\n byRepositoryId: function(id) {\n return this.find({\n repository_id: id\n });\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/branch");minispade.register('models/build', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Build = Travis.Model.extend(Travis.DurationCalculations, {\n eventType: DS.attr('string'),\n repositoryId: DS.attr('number'),\n commitId: DS.attr('number'),\n state: DS.attr('string'),\n number: DS.attr('number'),\n branch: DS.attr('string'),\n message: DS.attr('string'),\n result: DS.attr('number'),\n _duration: DS.attr('number', {\n key: 'duration'\n }),\n startedAt: DS.attr('string', {\n key: 'started_at'\n }),\n finishedAt: DS.attr('string', {\n key: 'finished_at'\n }),\n repository: DS.belongsTo('Travis.Repository'),\n commit: DS.belongsTo('Travis.Commit'),\n jobs: DS.hasMany('Travis.Job', {\n key: 'job_ids'\n }),\n config: (function() {\n return Travis.Helpers.compact(this.get('data.config'));\n }).property('data.config'),\n isMatrix: (function() {\n return this.get('data.job_ids.length') > 1;\n }).property('data.job_ids.length'),\n requiredJobs: (function() {\n return this.get('jobs').filter(function(data) {\n return !data.get('allowFailure');\n });\n }).property('jobs.@each.allowFailure'),\n allowedFailureJobs: (function() {\n return this.get('jobs').filter(function(data) {\n return data.get('allowFailure');\n });\n }).property('jobs.@each.allowFailure'),\n configKeys: (function() {\n var config, headers, key, keys;\n if (!(config = this.get('config'))) {\n return [];\n }\n keys = $.intersect($.keys(config), Travis.CONFIG_KEYS);\n headers = (function() {\n var _i, _len, _ref, _results;\n _ref = ['build.job', 'build.duration', 'build.finished_at'];\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n key = _ref[_i];\n _results.push(I18n.t(key));\n }\n return _results;\n })();\n return $.map(headers.concat(keys), function(key) {\n return $.camelize(key);\n });\n }).property('config')\n });\n\n this.Travis.Build.reopenClass({\n byRepositoryId: function(id, parameters) {\n return this.find($.extend(parameters || {}, {\n repository_id: id,\n orderBy: 'number DESC'\n }));\n },\n olderThanNumber: function(id, build_number) {\n return this.find({\n url: \"/builds\",\n repository_id: id,\n after: build_number\n });\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/build");minispade.register('models/commit', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Commit = Travis.Model.extend({\n buildId: DS.attr('number'),\n sha: DS.attr('string'),\n branch: DS.attr('string'),\n message: DS.attr('string'),\n compareUrl: DS.attr('string'),\n authorName: DS.attr('string'),\n authorEmail: DS.attr('string'),\n committerName: DS.attr('string'),\n committerEmail: DS.attr('string'),\n build: DS.belongsTo('Travis.Build', {\n key: 'buildId'\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/commit");minispade.register('models/extensions', "(function() {(function() {\n\n Travis.DurationCalculations = Ember.Mixin.create({\n duration: (function() {\n var duration;\n if (duration = this.get('_duration')) {\n return duration;\n } else {\n return Travis.Helpers.durationFrom(this.get('startedAt'), this.get('finishedAt'));\n }\n }).property('_duration', 'finishedAt', 'startedAt'),\n updateTimes: function() {\n this.notifyPropertyChange('_duration');\n return this.notifyPropertyChange('finished_at');\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/extensions");minispade.register('models/hook', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Hook = Travis.Model.extend({\n slug: DS.attr('string'),\n description: DS.attr('string'),\n active: DS.attr('boolean'),\n owner: (function() {\n return this.get('slug').split('/')[0];\n }).property('slug'),\n name: (function() {\n if (this.get('isLoaded')) {\n return this.get('slug').split('/')[1];\n }\n }).property('slug'),\n urlGithub: (function() {\n return \"http://github.com/\" + (this.get('slug'));\n }).property(),\n urlGithubAdmin: (function() {\n return \"http://github.com/\" + (this.get('slug')) + \"/admin/hooks#travis_minibucket\";\n }).property(),\n toggle: function() {\n this.set('active', !this.get('active'));\n return Travis.app.store.commit();\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/hook");minispade.register('models/job', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Job = Travis.Model.extend(Travis.DurationCalculations, {\n repositoryId: DS.attr('number'),\n buildId: DS.attr('number'),\n commitId: DS.attr('number'),\n logId: DS.attr('number'),\n queue: DS.attr('string'),\n state: DS.attr('string'),\n number: DS.attr('string'),\n result: DS.attr('number'),\n _duration: DS.attr('number', {\n key: 'duration'\n }),\n startedAt: DS.attr('string'),\n finishedAt: DS.attr('string'),\n allowFailure: DS.attr('boolean', {\n key: 'allow_failure'\n }),\n repository: DS.belongsTo('Travis.Repository', {\n key: 'repository_id'\n }),\n build: DS.belongsTo('Travis.Build', {\n key: 'build_id'\n }),\n commit: DS.belongsTo('Travis.Commit', {\n key: 'commit_id'\n }),\n log: DS.belongsTo('Travis.Artifact', {\n key: 'log_id'\n }),\n config: (function() {\n return Travis.Helpers.compact(this.get('data.config'));\n }).property('data.config'),\n sponsor: (function() {\n return this.get('data.sponsor');\n }).property('data.sponsor'),\n configValues: (function() {\n var config;\n if (config = this.get('config')) {\n return $.values($.only.apply(config, Travis.CONFIG_KEYS));\n } else {\n return [];\n }\n }).property('config'),\n appendLog: function(text) {\n var log;\n if (log = this.get('log')) {\n return log.append(text);\n }\n },\n subscribe: function() {\n var id;\n if (id = this.get('id')) {\n return Travis.app.pusher.subscribe(\"job-\" + id);\n }\n },\n onStateChange: (function() {\n if (this.get('state') === 'finished') {\n return Travis.app.pusher.unsubscribe(\"job-\" + (this.get('id')));\n }\n }).observes('state')\n });\n\n this.Travis.Job.reopenClass({\n queued: function(queue) {\n this.find();\n return Travis.app.store.filter(this, function(job) {\n return job.get('queue') === queue;\n });\n },\n findMany: function(ids) {\n return Travis.app.store.findMany(this, ids);\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/job");minispade.register('models/owner', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Owner = Travis.Model.extend({\n primaryKey: 'login',\n login: DS.attr('string'),\n name: DS.attr('string'),\n type: DS.attr('string'),\n reposCount: DS.attr('number'),\n urlGithub: (function() {\n return \"http://github.com/\" + (this.get('login'));\n }).property()\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/owner");minispade.register('models/repository', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Repository = Travis.Model.extend({\n slug: DS.attr('string'),\n description: DS.attr('string'),\n lastBuildId: DS.attr('number'),\n lastBuildNumber: DS.attr('string'),\n lastBuildResult: DS.attr('number'),\n lastBuildStartedAt: DS.attr('string'),\n lastBuildFinishedAt: DS.attr('string'),\n lastBuild: DS.belongsTo('Travis.Build'),\n builds: (function() {\n var id;\n id = this.get('id');\n Travis.Build.byRepositoryId(id, {\n event_type: 'push'\n });\n return Travis.Build.filter(function(data) {\n return parseInt(data.get('repository_id')) === id && !data.get('pull_request');\n });\n }).property(),\n pullRequests: (function() {\n var id;\n id = this.get('id');\n Travis.Build.byRepositoryId(id, {\n event_type: 'pull_request'\n });\n return Travis.Build.filter(function(data) {\n return parseInt(data.get('repository_id')) === id && data.get('pull_request');\n });\n }).property(),\n branches: (function() {\n return Travis.Branch.byRepositoryId(this.get('id'));\n }).property(),\n owner: (function() {\n return (this.get('slug') || '').split('/')[0];\n }).property('slug'),\n name: (function() {\n return (this.get('slug') || '').split('/')[1];\n }).property('slug'),\n lastBuildDuration: (function() {\n var duration;\n duration = this.get('data.last_build_duration');\n if (!duration) {\n duration = Travis.Helpers.durationFrom(this.get('lastBuildStartedAt'), this.get('lastBuildFinishedAt'));\n }\n return duration;\n }).property('data.last_build_duration', 'lastBuildStartedAt', 'lastBuildFinishedAt'),\n sortOrder: (function() {\n var lastBuildFinishedAt;\n if (lastBuildFinishedAt = this.get('lastBuildFinishedAt')) {\n return -new Date(lastBuildFinishedAt).getTime();\n } else {\n return -new Date('9999').getTime() - parseInt(this.get('id'));\n }\n }).property('lastBuildFinishedAt'),\n stats: (function() {\n var _this = this;\n return this.get('_stats') || $.get(\"https://api.github.com/repos/\" + (this.get('slug')), function(data) {\n _this.set('_stats', data);\n return _this.notifyPropertyChange('stats');\n }) && {};\n }).property(),\n select: function() {\n return Travis.Repository.select(self.get('id'));\n },\n updateTimes: function() {\n return this.notifyPropertyChange('lastBuildDuration');\n }\n });\n\n this.Travis.Repository.reopenClass({\n recent: function() {\n return this.find();\n },\n ownedBy: function(login) {\n return this.find({\n owner: login,\n orderBy: 'name'\n });\n },\n search: function(query) {\n return this.find({\n search: query,\n orderBy: 'name'\n });\n },\n bySlug: function(slug) {\n return this.find({\n slug: slug\n });\n },\n select: function(id) {\n return this.find().forEach(function(repository) {\n return repository.set('selected', repository.get('id') === id);\n });\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/repository");minispade.register('models/sponsor', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Sponsor = Travis.Model.extend({\n type: DS.attr('string'),\n url: DS.attr('string'),\n link: DS.attr('string'),\n image: (function() {\n return \"/images/sponsors/\" + (this.get('data.image'));\n }).property('data.image')\n });\n\n Travis.Sponsor.reopenClass({\n decks: function() {\n return this.platinum().concat(this.gold());\n },\n platinum: function() {\n var platinum, sponsor, _i, _len, _results;\n platinum = this.byType('platinum').toArray();\n _results = [];\n for (_i = 0, _len = platinum.length; _i < _len; _i++) {\n sponsor = platinum[_i];\n _results.push([sponsor]);\n }\n return _results;\n },\n gold: function() {\n var gold, _results;\n gold = this.byType('gold').toArray();\n _results = [];\n while (gold.length > 0) {\n _results.push(gold.splice(0, 2));\n }\n return _results;\n },\n links: function() {\n return this.byType('silver');\n },\n byType: function() {\n var types;\n types = Array.prototype.slice.apply(arguments);\n return Travis.Sponsor.filter(function(sponsor) {\n return types.indexOf(sponsor.get('type')) !== -1;\n });\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/sponsor");minispade.register('models/user', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.User = Travis.Model.extend({\n name: DS.attr('string'),\n email: DS.attr('string'),\n login: DS.attr('string'),\n token: DS.attr('string'),\n locale: DS.attr('string'),\n gravatar: DS.attr('string'),\n urlGithub: (function() {\n return \"http://github.com/\" + (this.get('login'));\n }).property(),\n updateLocale: function(locale) {\n this.set('locale', locale);\n return Travis.app.store.commit();\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/user");minispade.register('models/worker', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Worker = Travis.Model.extend({\n state: DS.attr('string'),\n name: DS.attr('string'),\n host: DS.attr('string'),\n lastSeenAt: DS.attr('string'),\n payload: (function() {\n return this.get('data.payload');\n }).property('data.payload'),\n number: (function() {\n return this.get('name').match(/\\d+$/)[0];\n }).property('name'),\n display: (function() {\n var name, number, payload, repo, state;\n name = this.get('name');\n state = this.get('state');\n payload = this.get('payload');\n if (name) {\n name = name.replace('travis-', '');\n if (state === 'working' && payload !== void 0) {\n repo = payload.repository ? $.truncate(payload.repository.slug, 18) : void 0;\n number = payload.build && payload.build.number ? ' #' + payload.build.number : '';\n state = repo ? repo + number : state;\n }\n return name + ': ' + state;\n }\n }).property('state', 'name', 'payload'),\n urlJob: (function() {\n if (this.get('state') === 'working') {\n return \"/\" + (this.get('repository')) + \"/jobs/\" + (this.get('job_id'));\n }\n }).property('repository', 'job_id', 'state'),\n repository: (function() {\n return this.get('payload.repository.slug');\n }).property('payload.repository.slug'),\n job_id: (function() {\n return this.get('payload.job.id');\n }).property('payload.job.id')\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=models/worker");minispade.register('pusher', "(function() {(function() {\n\n Travis.Pusher = function() {\n this.active_channels = [];\n if (Travis.Pusher.KEY) {\n this.pusher = new Pusher(Travis.Pusher.KEY);\n }\n return this;\n };\n\n $.extend(Travis.Pusher, {\n CHANNELS: ['common'],\n CHANNEL_PREFIX: '',\n KEY: ''\n });\n\n $.extend(Travis.Pusher.prototype, {\n subscribe: function(channel) {\n var _this = this;\n if (this.pusher && this.active_channels.indexOf(channel) === -1) {\n this.active_channels.push(channel);\n return this.pusher.subscribe(this.prefix(channel)).bind_all(function(event, data) {\n return _this.receive(event, data);\n });\n }\n },\n unsubscribe: function(channel) {\n var ix;\n ix = this.active_channels.indexOf(channel);\n if (this.pusher && ix === -1) {\n this.active_channels.splice(ix, 1);\n return this.pusher.unsubscribe(this.prefix(channel));\n }\n },\n prefix: function(channel) {\n return \"\" + Travis.Pusher.CHANNEL_PREFIX + channel;\n },\n receive: function(event, data) {\n if (data.id) {\n data = this.normalize(event, data);\n }\n return Travis.app.store.receive(event, data);\n },\n normalize: function(event, data) {\n switch (event) {\n case 'build:started':\n case 'build:finished':\n return data;\n case 'job:created':\n case 'job:started':\n case 'job:finished':\n case 'job:log':\n if (data.queue) {\n data.queue = data.queue.replace('builds.', '');\n }\n return {\n job: data\n };\n case 'worker:added':\n case 'worker:updated':\n case 'worker:removed':\n return {\n worker: data\n };\n }\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=pusher");minispade.register('routes', "(function() {(function() {\n\n Travis.Routes = function() {\n var route, target, _ref;\n if (!Travis.Routes.initialized) {\n Em.routes.set('usesHistory', true);\n Em.routes.set('wantsHistory', true);\n Em.routes.set('baseURI', this.base_uri);\n _ref = Travis.ROUTES;\n for (route in _ref) {\n target = _ref[route];\n this.add(route, target[0], target[1]);\n }\n return Travis.Routes.initialized = true;\n }\n };\n\n $.extend(Travis.Routes.prototype, {\n base_uri: \"\" + document.location.protocol + \"//\" + document.location.host,\n add: function(route, layout, action) {\n var _this = this;\n return Em.routes.add(route, function(params) {\n return _this.action(layout, action, params);\n });\n },\n route: function(event) {\n return Em.routes.set('location', event.target.href.replace(\"\" + this.base_uri + \"/\", ''));\n },\n action: function(name, action, params) {\n if (this.before(name, action, params)) {\n return Travis.app.render(name, action, params);\n }\n },\n before: function(name, action, params) {\n if (this.requiresAuth(name, action, params)) {\n return true;\n } else {\n return this.requireAuth(name, action, params);\n }\n },\n signedIn: function() {\n return !!Travis.app.get('currentUser');\n },\n requiresAuth: function(name, action, params) {\n return name !== 'profile' || this.signedIn();\n },\n requireAuth: function(name, action, params) {\n Travis.app.set('returnTo', [name, action, params]);\n Travis.app.render('auth', 'show');\n return false;\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=routes");minispade.register('store', "(function() {(function() {\n var DATA_PROXY,\n __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; };\nminispade.require('store/rest_adapter');\n\n DATA_PROXY = {\n get: function(name) {\n return this.savedData[name];\n }\n };\n\n Travis.Store = DS.Store.extend({\n revision: 4,\n adapter: Travis.RestAdapter.create(),\n merge: function(type, id, hash) {\n var clientId, data, dataCache, primaryKey, record, recordCache, typeMap;\n if (hash === void 0) {\n hash = id;\n primaryKey = type.proto().primaryKey;\n Ember.assert(\"A data hash was loaded for a record of type \" + type.toString() + \" but no primary key '\" + primaryKey + \"' was provided.\", hash[primaryKey]);\n id = hash[primaryKey];\n }\n typeMap = this.typeMapFor(type);\n dataCache = typeMap.cidToHash;\n clientId = typeMap.idToCid[id];\n recordCache = this.get('recordCache');\n if (clientId !== void 0) {\n if (data = dataCache[clientId]) {\n $.extend(data, hash);\n } else {\n dataCache[clientId] = hash;\n }\n if (record = recordCache[clientId]) {\n record.send('didChangeData');\n }\n } else {\n clientId = this.find(type, id).get('clientId');\n }\n if (clientId) {\n DATA_PROXY.savedData = hash;\n this.updateRecordArrays(type, clientId, DATA_PROXY);\n return {\n id: id,\n clientId: clientId\n };\n }\n },\n receive: function(event, data) {\n var job, mappings, name, type, _ref;\n _ref = event.split(':'), name = _ref[0], type = _ref[1];\n mappings = this.adapter.get('mappings');\n type = mappings[name];\n if (event === 'job:log') {\n if (job = this.find(Travis.Job, data['job']['id'])) {\n return job.appendLog(data['job']['_log']);\n }\n } else if (data[type.singularName()]) {\n return this._loadOne(this, type, data);\n } else if (data[type.pluralName()]) {\n return this._loadMany(this, type, data);\n } else {\n if (!type) {\n throw \"can't load data for \" + name;\n }\n }\n },\n _loadOne: function(store, type, json) {\n var root;\n root = type.singularName();\n this.adapter.sideload(store, type, json, root);\n this.merge(type, json[root]);\n return this._updateAssociations(type, root, json[root]);\n },\n _loadMany: function(store, type, json) {\n var root;\n console.log('loadMany');\n root = type.pluralName();\n this.adapter.sideload(store, type, json, root);\n return this.loadMany(type, json[root]);\n },\n _updateAssociations: function(type, name, data) {\n var _this = this;\n return Em.get(type, 'associationsByName').forEach(function(key, meta) {\n var clientId, dataProxy, id, ids, parent, _ref;\n if (meta.kind === 'belongsTo') {\n id = data[\"\" + key + \"_id\"];\n if (clientId = _this.typeMapFor(meta.type).idToCid[id]) {\n if (parent = _this.findByClientId(meta.type, clientId, id)) {\n dataProxy = parent.get('data');\n if (ids = dataProxy.get(\"\" + name + \"_ids\")) {\n if (_ref = data.id, __indexOf.call(ids, _ref) < 0) {\n ids.pushObject(data.id);\n }\n return parent.send('didChangeData');\n }\n }\n }\n }\n });\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=store");minispade.register('store/fixture_adapter', "(function() {(function() {\n\n this.Travis.FixtureAdapter = DS.Adapter.extend({\n find: function(store, type, id) {\n var fixtures;\n fixtures = type.FIXTURES;\n Ember.assert(\"Unable to find fixtures for model type \" + type.toString(), !!fixtures);\n if (fixtures.hasLoaded) {\n return;\n }\n return setTimeout((function() {\n store.loadMany(type, fixtures);\n return fixtures.hasLoaded = true;\n }), 300);\n },\n findMany: function() {\n return this.find.apply(this, arguments);\n },\n findAll: function(store, type) {\n var fixtures, ids;\n fixtures = type.FIXTURES;\n Ember.assert(\"Unable to find fixtures for model type \" + type.toString(), !!fixtures);\n ids = fixtures.map(function(item, index, self) {\n return item.id;\n });\n return store.loadMany(type, ids, fixtures);\n },\n findQuery: function(store, type, params, array) {\n var fixture, fixtures, hashes, key, matches, value;\n fixtures = type.FIXTURES;\n Ember.assert(\"Unable to find fixtures for model type \" + type.toString(), !!fixtures);\n hashes = (function() {\n var _i, _len, _results;\n _results = [];\n for (_i = 0, _len = fixtures.length; _i < _len; _i++) {\n fixture = fixtures[_i];\n matches = (function() {\n var _results1;\n _results1 = [];\n for (key in params) {\n value = params[key];\n _results1.push(key === 'orderBy' || fixture[key] === value);\n }\n return _results1;\n })();\n if (matches.reduce(function(a, b) {\n return a && b;\n })) {\n _results.push(fixture);\n } else {\n _results.push(null);\n }\n }\n return _results;\n })();\n return array.load(hashes.compact());\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=store/fixture_adapter");minispade.register('store/rest_adapter', "(function() {(function() {\nminispade.require('models');\n\n jQuery.support.cors = true;\n\n this.Travis.RestAdapter = DS.RESTAdapter.extend({\n DEFAULT_OPTIONS: {\n accepts: {\n json: 'application/vnd.travis-ci.2+json'\n }\n },\n mappings: {\n repositories: Travis.Repository,\n repository: Travis.Repository,\n builds: Travis.Build,\n build: Travis.Build,\n commits: Travis.Commit,\n commit: Travis.Commit,\n jobs: Travis.Job,\n job: Travis.Job,\n owner: Travis.Owner,\n owners: Travis.Owner,\n worker: Travis.Worker,\n workers: Travis.Worker\n },\n plurals: {\n repository: 'repositories',\n build: 'builds',\n branch: 'branches',\n job: 'jobs',\n worker: 'workers'\n },\n ajax: function(url, method, options) {\n var endpoint;\n endpoint = Travis.config.api_endpoint || '';\n return this._super(\"\" + endpoint + url, method, $.extend(options, this.DEFAULT_OPTIONS));\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=store/rest_adapter");minispade.register('views', "(function() {(function() {\nminispade.require('ext/ember/namespace');\n\n this.Travis.reopen({\n View: Em.View.extend({\n route: function(event) {\n return Travis.app.routes.route(event);\n }\n })\n });\n\n this.Travis.reopen({\n HomeLayout: Travis.View.extend({\n templateName: 'layouts/home'\n }),\n ProfileLayout: Travis.View.extend({\n templateName: 'layouts/profile'\n }),\n StatsLayout: Travis.View.extend({\n templateName: 'layouts/simple'\n }),\n AuthLayout: Travis.View.extend({\n templateName: 'layouts/simple'\n }),\n AuthView: Travis.View.extend({\n templateName: 'auth/show'\n })\n });\nminispade.require('views/build');\nminispade.require('views/job');\nminispade.require('views/repo');\nminispade.require('views/profile');\nminispade.require('views/sidebar');\nminispade.require('views/stats');\nminispade.require('views/top');\n\n}).call(this);\n\n})();\n//@ sourceURL=views");minispade.register('views/build', "(function() {(function() {\n\n this.Travis.reopen({\n BuildsView: Travis.View.extend({\n templateName: 'builds/list',\n buildsBinding: 'controller',\n showMore: function() {\n var id, number;\n id = this.get('controller.repository.id');\n number = this.get('controller.builds.lastObject.number');\n return Travis.Build.olderThanNumber(id, number);\n }\n }),\n BuildsItemView: Travis.View.extend({\n repositoryBinding: 'controller.repository',\n buildBinding: 'context',\n commitBinding: 'build.commit',\n color: (function() {\n return Travis.Helpers.colorForResult(this.get('build.result'));\n }).property('build.result'),\n urlBuild: (function() {\n return Travis.Urls.build(this.get('repository.slug'), this.get('build.id'));\n }).property('repository.slug', 'build.id'),\n urlGithubCommit: (function() {\n return Travis.Urls.githubCommit(this.get('repository.slug'), this.get('commit.sha'));\n }).property('repository.slug', 'commit.sha')\n }),\n BuildView: Travis.View.extend({\n templateName: 'builds/show',\n repositoryBinding: 'controller.repository',\n buildBinding: 'controller.build',\n commitBinding: 'build.commit',\n color: (function() {\n return Travis.Helpers.colorForResult(this.get('build.result'));\n }).property('build.result'),\n urlBuild: (function() {\n return Travis.Urls.build(this.get('repository.slug'), this.get('build.id'));\n }).property('repository.slug', 'build.id'),\n urlGithubCommit: (function() {\n return Travis.Urls.githubCommit(this.get('repository.slug'), this.get('commit.sha'));\n }).property('repository.slug', 'commit.sha'),\n urlAuthor: (function() {\n return Travis.Urls.email(this.get('commit.authorEmail'));\n }).property('commit.authorEmail'),\n urlCommitter: (function() {\n return Travis.Urls.email(this.get('commit.committerEmail'));\n }).property('commit.committerEmail')\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/build");minispade.register('views/job', "(function() {(function() {\n\n this.Travis.reopen({\n JobsView: Travis.View.extend({\n templateName: 'jobs/list',\n buildBinding: 'controller.build',\n toggleHelp: function() {\n return $.facebox({\n div: '#allow_failure_help'\n });\n }\n }),\n JobsItemView: Travis.View.extend({\n tagName: 'tr',\n classNameBindings: ['color'],\n repositoryBinding: 'context.repository',\n jobBinding: 'context',\n color: (function() {\n return Travis.Helpers.colorForResult(this.get('job.result'));\n }).property('job.result'),\n urlJob: (function() {\n return Travis.Urls.job(this.get('repository.slug'), this.get('job.id'));\n }).property('repository.slug', 'job.id')\n }),\n JobView: Travis.View.extend({\n templateName: 'jobs/show',\n repositoryBinding: 'controller.repository',\n jobBinding: 'controller.job',\n commitBinding: 'job.commit',\n color: (function() {\n return Travis.Helpers.colorForResult(this.get('job.result'));\n }).property('job.result'),\n urlJob: (function() {\n return Travis.Urls.job(this.get('repository.slug'), this.get('job.id'));\n }).property('repository.slug', 'job.id'),\n urlGithubCommit: (function() {\n return Travis.Urls.githubCommit(this.get('repository.slug'), this.get('commit.sha'));\n }).property('repository.slug', 'commit.sha'),\n urlAuthor: (function() {\n return Travis.Urls.email(this.get('commit.authorEmail'));\n }).property('commit.authorEmail'),\n urlCommitter: (function() {\n return Travis.Urls.email(this.get('commit.committerEmail'));\n }).property('commit.committerEmail')\n }),\n LogView: Travis.View.extend({\n templateName: 'jobs/log',\n logBinding: 'job.log',\n click: function(event) {\n return $(event.target).closest('.fold').toggleClass('open');\n },\n jobBinding: 'context',\n logSubscriber: (function() {\n var job, state;\n job = this.get('job');\n state = this.get('job.state');\n if (job && state !== 'finished') {\n job.subscribe();\n }\n return null;\n }).property('job', 'job.state')\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/job");minispade.register('views/left', "(function() {(function() {\n\n this.Travis.reopen({\n ReposView: Travis.View.extend({\n templateName: 'repos/list',\n tabBinding: 'controller.tab',\n classRecent: (function() {\n if (this.get('tab') === 'recent') {\n return 'active';\n }\n }).property('tab'),\n classOwned: (function() {\n var classes;\n classes = [];\n if (this.get('tab') === 'owned') {\n classes.push('active');\n }\n if (Em.get('Travis.currentUser')) {\n classes.push('display');\n }\n return classes.join(' ');\n }).property('tab', 'Travis.currentUser'),\n classSearch: (function() {\n if (this.get('tab') === 'search') {\n return 'active';\n }\n }).property('tab')\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/left");minispade.register('views/profile', "(function() {(function() {\n\n this.Travis.reopen({\n OwnersView: Travis.View.extend({\n tabBinding: 'controller.tab',\n templateName: 'profile/owners',\n classAccounts: (function() {\n if (this.get('tab') === 'accounts') {\n return 'active';\n }\n }).property('tab')\n }),\n OwnersListView: Em.CollectionView.extend({\n elementId: 'owners',\n ownerBinding: 'content',\n tagName: 'ul',\n emptyView: Ember.View.extend({\n template: Ember.Handlebars.compile('
Loading
')\n }),\n itemViewClass: Travis.View.extend({\n ownerBinding: 'content',\n typeBinding: 'content.type',\n selectedBinding: 'owner.selected',\n classNames: ['owner'],\n classNameBindings: ['type', 'selected'],\n name: (function() {\n return this.get('content.name') || this.get('content.login');\n }).property('content.login', 'content.name'),\n urlOwner: (function() {\n return Travis.Urls.owner(this.get('owner.login'));\n }).property('owner.login')\n })\n }),\n ProfileView: Travis.View.extend({\n templateName: 'profile/show'\n }),\n ProfileTabsView: Travis.View.extend({\n templateName: 'profile/tabs',\n tabBinding: 'controller.tab',\n activate: function(event) {\n return this.get('controller').activate(event.target.name);\n },\n classHooks: (function() {\n if (this.get('tab') === 'hooks') {\n return 'active';\n }\n }).property('tab'),\n classUser: (function() {\n if (this.get('tab') === 'user') {\n return 'active';\n }\n }).property('tab'),\n displayUser: (function() {\n return this.get('controller.owner.login') === this.get('controller.user.login');\n }).property('controller.owner.login', 'controller.user.login')\n }),\n HooksView: Travis.View.extend({\n templateName: 'profile/tabs/hooks',\n urlGithubAdmin: (function() {\n return Travis.Urls.githubAdmin(this.get('hook.slug'));\n }).property('hook.slug')\n }),\n UserView: Travis.View.extend({\n templateName: 'profile/tabs/user',\n userBinding: 'controller.user',\n gravatarUrl: (function() {\n return \"http://www.gravatar.com/avatar/\" + (this.get('user.gravatar')) + \"?s=48&d=mm\";\n }).property('user.gravatar'),\n locales: (function() {\n return [\n {\n key: 'en',\n name: 'English'\n }, {\n key: 'ca',\n name: 'Catalan'\n }, {\n key: 'cs',\n name: '\u010ce\u0161tina'\n }, {\n key: 'es',\n name: 'Espa\u00f1ol'\n }, {\n key: 'fr',\n name: 'Fran\u00e7ais'\n }, {\n key: 'ja',\n name: '\u65e5\u672c\u8a9e'\n }, {\n key: 'nl',\n name: 'Nederlands'\n }, {\n key: 'nb',\n name: 'Norsk Bokm\u00e5l'\n }, {\n key: 'pl',\n name: 'Polski'\n }, {\n key: {\n 'pt-BR': {\n name: 'Portugu\u00eas brasileiro'\n }\n }\n }, {\n key: 'ru',\n name: '\u0420\u0443\u0441\u0441\u043a\u0438\u0439'\n }\n ];\n }).property(),\n saveLocale: function(event) {\n return this.get('user').updateLocale($('#locale').val());\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/profile");minispade.register('views/repo', "(function() {(function() {\nminispade.require('views/repo/list');\nminispade.require('views/repo/show');\n\n}).call(this);\n\n})();\n//@ sourceURL=views/repo");minispade.register('views/repo/list', "(function() {(function() {\n\n this.Travis.reopen({\n RepositoriesView: Travis.View.extend({\n templateName: 'repos/list'\n }),\n RepositoriesListView: Em.CollectionView.extend({\n elementId: 'repositories',\n repositoryBinding: 'content',\n tagName: 'ul',\n emptyView: Ember.View.extend({\n template: Ember.Handlebars.compile('
Loading
')\n }),\n itemViewClass: Travis.View.extend({\n repositoryBinding: 'content',\n classNames: ['repository'],\n classNameBindings: ['color', 'selected'],\n selectedBinding: 'repository.selected',\n color: (function() {\n return Travis.Helpers.colorForResult(this.get('repository.lastBuildResult'));\n }).property('repository.lastBuildResult'),\n urlRepository: (function() {\n return Travis.Urls.repository(this.get('repository.slug'));\n }).property('repository.slug'),\n urlLastBuild: (function() {\n return Travis.Urls.build(this.get('repository.slug'), this.get('repository.lastBuildId'));\n }).property('repository.slug', 'repository.lastBuildId')\n })\n }),\n ReposListTabsView: Travis.View.extend({\n templateName: 'repos/list/tabs',\n tabBinding: 'controller.tab',\n activate: function(event) {\n return this.get('controller').activate(event.target.name);\n },\n classRecent: (function() {\n if (this.get('tab') === 'recent') {\n return 'active';\n }\n }).property('tab'),\n classOwned: (function() {\n var classes;\n classes = [];\n if (this.get('tab') === 'owned') {\n classes.push('active');\n }\n if (Em.get('Travis.currentUser')) {\n classes.push('display');\n }\n return classes.join(' ');\n }).property('tab', 'Travis.currentUser'),\n classSearch: (function() {\n if (this.get('tab') === 'search') {\n return 'active';\n }\n }).property('tab')\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/repo/list");minispade.register('views/repo/show', "(function() {(function() {\n\n this.Travis.reopen({\n RepositoryView: Travis.View.extend({\n templateName: 'repos/show',\n repositoryBinding: 'controller.repository',\n \"class\": (function() {\n if (!this.get('repository.isLoaded')) {\n return 'loading';\n }\n }).property('repository.isLoaded'),\n urlGithub: (function() {\n return Travis.Urls.githubRepository(this.get('repository.slug'));\n }).property('repository.slug'),\n urlGithubWatchers: (function() {\n return Travis.Urls.githubWatchers(this.get('repository.slug'));\n }).property('repository.slug'),\n urlGithubNetwork: (function() {\n return Travis.Urls.githubNetwork(this.get('repository.slug'));\n }).property('repository.slug')\n }),\n RepoShowTabsView: Travis.View.extend({\n templateName: 'repos/show/tabs',\n repositoryBinding: 'controller.repository',\n buildBinding: 'controller.build',\n jobBinding: 'controller.job',\n tabBinding: 'controller.tab',\n toggleTools: function() {\n return $('#tools .pane').toggle();\n },\n classCurrent: (function() {\n if (this.get('tab') === 'current') {\n return 'active';\n }\n }).property('tab'),\n classBuilds: (function() {\n if (this.get('tab') === 'builds') {\n return 'active';\n }\n }).property('tab'),\n classPullRequests: (function() {\n if (this.get('tab') === 'pull_requests') {\n return 'active';\n }\n }).property('tab'),\n classBranches: (function() {\n if (this.get('tab') === 'branches') {\n return 'active';\n }\n }).property('tab'),\n classBuild: (function() {\n var classes, tab;\n tab = this.get('tab');\n classes = [];\n if (tab === 'build') {\n classes.push('active');\n }\n if (tab === 'build' || tab === 'job') {\n classes.push('display');\n }\n return classes.join(' ');\n }).property('tab'),\n classJob: (function() {\n if (this.get('tab') === 'job') {\n return 'active display';\n }\n }).property('tab'),\n urlRepository: (function() {\n return Travis.Urls.repository(this.get('repository.slug'));\n }).property('repository.slug'),\n urlBuilds: (function() {\n return Travis.Urls.builds(this.get('repository.slug'));\n }).property('repository.slug'),\n urlPullRequests: (function() {\n return Travis.Urls.pullRequests(this.get('repository.slug'));\n }).property('repository.slug'),\n urlBranches: (function() {\n return Travis.Urls.branches(this.get('repository.slug'));\n }).property('repository.slug'),\n urlBuild: (function() {\n return Travis.Urls.build(this.get('repository.slug'), this.get('build.id'));\n }).property('repository.slug', 'build.id'),\n urlJob: (function() {\n return Travis.Urls.job(this.get('repository.slug'), this.get('job.id'));\n }).property('repository.slug', 'job.id'),\n urlStatusImage: (function() {\n return Travis.Urls.statusImage(this.get('repository.slug'), this.get('branch.commit.branch'));\n }).property('repository.slug', 'branch'),\n markdownStatusImage: (function() {\n return \"[![Build Status](\" + (this.get('urlStatusImage')) + \")](\" + (this.get('urlRepository')) + \")\";\n }).property('urlStatusImage'),\n textileStatusImage: (function() {\n return \"!\" + (this.get('urlStatusImage')) + \"!:\" + (this.get('urlRepository'));\n }).property('urlStatusImage'),\n rdocStatusImage: (function() {\n return \"{\\\"Build}[\" + (this.get('urlRepository')) + \"]\";\n }).property('urlStatusImage')\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/repo/show");minispade.register('views/sidebar', "(function() {(function() {\n\n this.Travis.reopen({\n SidebarView: Travis.View.extend({\n templateName: 'layouts/sidebar'\n }),\n WorkersView: Travis.View.extend({\n toggle: function(event) {\n return $(event.target).closest('li').toggleClass('open');\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/sidebar");minispade.register('views/stats', "(function() {(function() {\n\n this.Travis.reopen({\n StatsView: Travis.View.extend({\n templateName: 'stats/show',\n didInsertElement: function() {\n var config, name, _ref, _results;\n _ref = this.CHARTS;\n _results = [];\n for (name in _ref) {\n config = _ref[name];\n _results.push(this.renderChart(config));\n }\n return _results;\n },\n renderChart: function(config) {\n var chart;\n chart = new Highcharts.Chart(config);\n return this.fetch(config.source, function(data) {\n var stats;\n stats = (function() {\n var _i, _len, _ref, _results;\n _ref = data.stats;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n stats = _ref[_i];\n _results.push(config.map(stats));\n }\n return _results;\n })();\n return chart.series[0].setData(stats);\n });\n },\n fetch: function(url, callback) {\n return $.ajax({\n type: 'GET',\n url: url,\n accepts: {\n json: 'application/vnd.travis-ci.2+json'\n },\n success: callback\n });\n },\n CHARTS: {\n repos: {\n source: '/stats/repos',\n map: function(data) {\n return [Date.parse(data.date), data.total_growth];\n },\n chart: {\n renderTo: \"repos_stats\"\n },\n title: {\n text: \"Total Projects/Repositories\"\n },\n xAxis: {\n type: \"datetime\",\n dateTimeLabelFormats: {\n month: \"%e. %b\",\n year: \"%b\"\n }\n },\n yAxis: {\n title: {\n text: \"Count\"\n },\n min: 0\n },\n tooltip: {\n formatter: function() {\n return Highcharts.dateFormat(\"%e. %b\", this.x) + \": \" + this.y + \" repos\";\n }\n },\n series: [\n {\n name: \"Repository Growth\",\n data: []\n }\n ]\n },\n builds: {\n source: '/stats/tests',\n map: function(data) {\n return [Date.parse(data.date), data.run_on_date];\n },\n chart: {\n renderTo: \"tests_stats\",\n type: \"column\"\n },\n title: {\n text: \"Build Count\"\n },\n subtitle: {\n text: \"last month\"\n },\n xAxis: {\n type: \"datetime\",\n dateTimeLabelFormats: {\n month: \"%e. %b\",\n year: \"%b\"\n }\n },\n yAxis: {\n title: {\n text: \"Count\"\n },\n min: 0\n },\n tooltip: {\n formatter: function() {\n return Highcharts.dateFormat(\"%e. %b\", this.x) + \": \" + this.y + \" builds\";\n }\n },\n series: [\n {\n name: \"Total Builds\",\n data: []\n }\n ]\n }\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/stats");minispade.register('views/top', "(function() {(function() {\nminispade.require('travis/auth');\n\n this.Travis.reopen({\n TopView: Travis.View.extend({\n templateName: 'layouts/top',\n tabBinding: 'controller.tab',\n userBinding: 'controller.user',\n gravatarUrl: (function() {\n return \"http://www.gravatar.com/avatar/\" + (this.get('user.gravatar')) + \"?s=24&d=mm\";\n }).property('user.gravatar'),\n classHome: (function() {\n if (this.get('tab') === 'home') {\n return 'active';\n }\n }).property('tab'),\n classStats: (function() {\n if (this.get('tab') === 'stats') {\n return 'active';\n }\n }).property('tab'),\n classProfile: (function() {\n if (this.get('tab') === 'profile') {\n return 'profile active';\n } else {\n return 'profile';\n }\n }).property('tab'),\n showProfile: function() {\n return $('#top .profile ul').show();\n },\n hideProfile: function() {\n return $('#top .profile ul').hide();\n }\n })\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=views/top");minispade.register('data/sponsors', "(function() {(function() {\n\n this.Travis.SPONSORS = [\n {\n type: 'platinum',\n url: \"http://www.wooga.com\",\n image: \"wooga-205x130.png\"\n }, {\n type: 'platinum',\n url: \"http://bendyworks.com\",\n image: \"bendyworks-205x130.png\"\n }, {\n type: 'platinum',\n url: \"http://cloudcontrol.com\",\n image: \"cloudcontrol-205x130.png\"\n }, {\n type: 'platinum',\n url: \"http://xing.de\",\n image: \"xing-205x130.png\"\n }, {\n type: 'gold',\n url: \"http://heroku.com\",\n image: \"heroku-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://soundcloud.com\",\n image: \"soundcloud-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://nedap.com\",\n image: \"nedap-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://mongohq.com\",\n image: \"mongohq-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://zweitag.de\",\n image: \"zweitag-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://kanbanery.com\",\n image: \"kanbanery-205x60.png\"\n }, {\n type: 'gold',\n url: \"http://ticketevolution.com\",\n image: \"ticketevolution-205x60.jpg\"\n }, {\n type: 'gold',\n url: \"http://plan.io/travis\",\n image: \"planio-205x60.png\"\n }, {\n type: 'silver',\n link: \"Cobot: The one tool to run your coworking space\"\n }, {\n type: 'silver',\n link: \"JumpstartLab: We build developers\"\n }, {\n type: 'silver',\n link: \"Evil Martians: Agile Ruby on Rails development\"\n }, {\n type: 'silver',\n link: \"Zendesk: Love your helpdesk\"\n }, {\n type: 'silver',\n link: \"Stripe: Payments for developers\"\n }, {\n type: 'silver',\n link: \"Basho: We make Riak!\"\n }, {\n type: 'silver',\n link: \"Relevance: We deliver software solutions\"\n }, {\n type: 'silver',\n link: \"Mindmatters: Software f\u00fcr Menschen\"\n }, {\n type: 'silver',\n link: \"Amen: The best and worst of everything\"\n }, {\n type: 'silver',\n link: \"Site5: Premium Web Hosting Solutions\"\n }, {\n type: 'silver',\n link: \"Crowd Interactive: Leading Rails consultancy in Mexico\"\n }, {\n type: 'silver',\n link: \"Atomic Object: Work with really smart people\"\n }, {\n type: 'silver',\n link: \"Codeminer: smart services for your startup\"\n }, {\n type: 'silver',\n link: \"Cloudant: grow into your data layer, not out of it\"\n }, {\n type: 'silver',\n link: \"Gidsy: Explore, organize & book unique things to do!\"\n }, {\n type: 'silver',\n link: \"5apps: Package & deploy HTML5 apps automatically\"\n }, {\n type: 'silver',\n link: \"Meltmedia: We are Interactive Superheroes\"\n }, {\n type: 'silver',\n link: \"Fingertips offers design and development services\"\n }, {\n type: 'silver',\n link: \"Engine Yard: Build epic apps, let us handle the rest\"\n }, {\n type: 'silver',\n link: \"Malwarebytes: Defeat Malware once and for all.\"\n }, {\n type: 'silver',\n link: \"Readmill: The best reading app on the iPad.\"\n }, {\n type: 'silver',\n link: \"Medidata: clinical tech improving quality of life\"\n }, {\n type: 'silver',\n link: \"ESM: Japan's best agile Ruby/Rails consultancy\"\n }, {\n type: 'silver',\n link: \"Twitter: instantly connects people everywhere\"\n }, {\n type: 'silver',\n link: \"AGiLE ANiMAL: we <3 Travis CI.\"\n }, {\n type: 'silver',\n link: \"Tupalo: Discover, review & share local businesses.\"\n }\n ];\n\n}).call(this);\n\n})();\n//@ sourceURL=data/sponsors");minispade.register('emoij', "(function() {(function() {\n\n this.EmojiDictionary = ['-1', '0', '1', '109', '2', '3', '4', '5', '6', '7', '8', '8ball', '9', 'a', 'ab', 'airplane', 'alien', 'ambulance', 'angel', 'anger', 'angry', 'apple', 'aquarius', 'aries', 'arrow_backward', 'arrow_down', 'arrow_forward', 'arrow_left', 'arrow_lower_left', 'arrow_lower_right', 'arrow_right', 'arrow_up', 'arrow_upper_left', 'arrow_upper_right', 'art', 'astonished', 'atm', 'b', 'baby', 'baby_chick', 'baby_symbol', 'balloon', 'bamboo', 'bank', 'barber', 'baseball', 'basketball', 'bath', 'bear', 'beer', 'beers', 'beginner', 'bell', 'bento', 'bike', 'bikini', 'bird', 'birthday', 'black_square', 'blue_car', 'blue_heart', 'blush', 'boar', 'boat', 'bomb', 'book', 'boot', 'bouquet', 'bow', 'bowtie', 'boy', 'bread', 'briefcase', 'broken_heart', 'bug', 'bulb', 'bullettrain_front', 'bullettrain_side', 'bus', 'busstop', 'cactus', 'cake', 'calling', 'camel', 'camera', 'cancer', 'capricorn', 'car', 'cat', 'cd', 'chart', 'checkered_flag', 'cherry_blossom', 'chicken', 'christmas_tree', 'church', 'cinema', 'city_sunrise', 'city_sunset', 'clap', 'clapper', 'clock1', 'clock10', 'clock11', 'clock12', 'clock2', 'clock3', 'clock4', 'clock5', 'clock6', 'clock7', 'clock8', 'clock9', 'closed_umbrella', 'cloud', 'clubs', 'cn', 'cocktail', 'coffee', 'cold_sweat', 'computer', 'confounded', 'congratulations', 'construction', 'construction_worker', 'convenience_store', 'cool', 'cop', 'copyright', 'couple', 'couple_with_heart', 'couplekiss', 'cow', 'crossed_flags', 'crown', 'cry', 'cupid', 'currency_exchange', 'curry', 'cyclone', 'dancer', 'dancers', 'dango', 'dart', 'dash', 'de', 'department_store', 'diamonds', 'disappointed', 'dog', 'dolls', 'dolphin', 'dress', 'dvd', 'ear', 'ear_of_rice', 'egg', 'eggplant', 'egplant', 'eight_pointed_black_star', 'eight_spoked_asterisk', 'elephant', 'email', 'es', 'european_castle', 'exclamation', 'eyes', 'factory', 'fallen_leaf', 'fast_forward', 'fax', 'fearful', 'feelsgood', 'feet', 'ferris_wheel', 'finnadie', 'fire', 'fire_engine', 'fireworks', 'fish', 'fist', 'flags', 'flushed', 'football', 'fork_and_knife', 'fountain', 'four_leaf_clover', 'fr', 'fries', 'frog', 'fuelpump', 'gb', 'gem', 'gemini', 'ghost', 'gift', 'gift_heart', 'girl', 'goberserk', 'godmode', 'golf', 'green_heart', 'grey_exclamation', 'grey_question', 'grin', 'guardsman', 'guitar', 'gun', 'haircut', 'hamburger', 'hammer', 'hamster', 'hand', 'handbag', 'hankey', 'hash', 'headphones', 'heart', 'heart_decoration', 'heart_eyes', 'heartbeat', 'heartpulse', 'hearts', 'hibiscus', 'high_heel', 'horse', 'hospital', 'hotel', 'hotsprings', 'house', 'hurtrealbad', 'icecream', 'id', 'ideograph_advantage', 'imp', 'information_desk_person', 'iphone', 'it', 'jack_o_lantern', 'japanese_castle', 'joy', 'jp', 'key', 'kimono', 'kiss', 'kissing_face', 'kissing_heart', 'koala', 'koko', 'kr', 'leaves', 'leo', 'libra', 'lips', 'lipstick', 'lock', 'loop', 'loudspeaker', 'love_hotel', 'mag', 'mahjong', 'mailbox', 'man', 'man_with_gua_pi_mao', 'man_with_turban', 'maple_leaf', 'mask', 'massage', 'mega', 'memo', 'mens', 'metal', 'metro', 'microphone', 'minidisc', 'mobile_phone_off', 'moneybag', 'monkey', 'monkey_face', 'moon', 'mortar_board', 'mount_fuji', 'mouse', 'movie_camera', 'muscle', 'musical_note', 'nail_care', 'necktie', 'new', 'no_good', 'no_smoking', 'nose', 'notes', 'o', 'o2', 'ocean', 'octocat', 'octopus', 'oden', 'office', 'ok', 'ok_hand', 'ok_woman', 'older_man', 'older_woman', 'open_hands', 'ophiuchus', 'palm_tree', 'parking', 'part_alternation_mark', 'pencil', 'penguin', 'pensive', 'persevere', 'person_with_blond_hair', 'phone', 'pig', 'pill', 'pisces', 'plus1', 'point_down', 'point_left', 'point_right', 'point_up', 'point_up_2', 'police_car', 'poop', 'post_office', 'postbox', 'pray', 'princess', 'punch', 'purple_heart', 'question', 'rabbit', 'racehorse', 'radio', 'rage', 'rage1', 'rage2', 'rage3', 'rage4', 'rainbow', 'raised_hands', 'ramen', 'red_car', 'red_circle', 'registered', 'relaxed', 'relieved', 'restroom', 'rewind', 'ribbon', 'rice', 'rice_ball', 'rice_cracker', 'rice_scene', 'ring', 'rocket', 'roller_coaster', 'rose', 'ru', 'runner', 'sa', 'sagittarius', 'sailboat', 'sake', 'sandal', 'santa', 'satellite', 'satisfied', 'saxophone', 'school', 'school_satchel', 'scissors', 'scorpius', 'scream', 'seat', 'secret', 'shaved_ice', 'sheep', 'shell', 'ship', 'shipit', 'shirt', 'shit', 'shoe', 'signal_strength', 'six_pointed_star', 'ski', 'skull', 'sleepy', 'slot_machine', 'smile', 'smiley', 'smirk', 'smoking', 'snake', 'snowman', 'sob', 'soccer', 'space_invader', 'spades', 'spaghetti', 'sparkler', 'sparkles', 'speaker', 'speedboat', 'squirrel', 'star', 'star2', 'stars', 'station', 'statue_of_liberty', 'stew', 'strawberry', 'sunflower', 'sunny', 'sunrise', 'sunrise_over_mountains', 'surfer', 'sushi', 'suspect', 'sweat', 'sweat_drops', 'swimmer', 'syringe', 'tada', 'tangerine', 'taurus', 'taxi', 'tea', 'telephone', 'tennis', 'tent', 'thumbsdown', 'thumbsup', 'ticket', 'tiger', 'tm', 'toilet', 'tokyo_tower', 'tomato', 'tongue', 'top', 'tophat', 'traffic_light', 'train', 'trident', 'trophy', 'tropical_fish', 'truck', 'trumpet', 'tshirt', 'tulip', 'tv', 'u5272', 'u55b6', 'u6307', 'u6708', 'u6709', 'u6e80', 'u7121', 'u7533', 'u7a7a', 'umbrella', 'unamused', 'underage', 'unlock', 'up', 'us', 'v', 'vhs', 'vibration_mode', 'virgo', 'vs', 'walking', 'warning', 'watermelon', 'wave', 'wc', 'wedding', 'whale', 'wheelchair', 'white_square', 'wind_chime', 'wink', 'wink2', 'wolf', 'woman', 'womans_hat', 'womens', 'x', 'yellow_heart', 'zap', 'zzz'];\n\n}).call(this);\n\n})();\n//@ sourceURL=emoij");minispade.register('ext/jquery', "(function() {(function() {\n\n $.fn.extend({\n outerHtml: function() {\n return $(this).wrap('
').parent().html();\n },\n outerElement: function() {\n return $($(this).outerHtml()).empty();\n },\n flash: function() {\n return Utils.flash(this);\n },\n unflash: function() {\n return Utils.unflash(this);\n },\n filterLog: function() {\n this.deansi();\n return this.foldLog();\n },\n deansi: function() {\n return this.html(Utils.deansi(this.html()));\n },\n foldLog: function() {\n return this.html(Utils.foldLog(this.html()));\n },\n unfoldLog: function() {\n return this.html(Utils.unfoldLog(this.html()));\n },\n updateTimes: function() {\n return Utils.updateTimes(this);\n },\n activateTab: function(tab) {\n return Utils.activateTab(this, tab);\n },\n timeInWords: function() {\n return $(this).each(function() {\n return $(this).text(Utils.timeInWords(parseInt($(this).attr('title'))));\n });\n },\n updateGithubStats: function(repository) {\n return Utils.updateGithubStats(repository, $(this));\n }\n });\n\n $.extend({\n isEmpty: function(obj) {\n if ($.isArray(obj)) {\n return !obj.length;\n } else if ($.isObject(obj)) {\n return !$.keys(obj).length;\n } else {\n return !obj;\n }\n },\n isObject: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Object]';\n },\n keys: function(obj) {\n var keys;\n keys = [];\n $.each(obj, function(key) {\n return keys.push(key);\n });\n return keys;\n },\n values: function(obj) {\n var values;\n values = [];\n $.each(obj, function(key, value) {\n return values.push(value);\n });\n return values;\n },\n underscore: function(string) {\n return string[0].toLowerCase() + string.substring(1).replace(/([A-Z])?/g, function(match, chr) {\n if (chr) {\n return \"_\" + (chr.toUpperCase());\n } else {\n return '';\n }\n });\n },\n camelize: function(string, uppercase) {\n string = uppercase === false ? $.underscore(string) : $.capitalize(string);\n return string.replace(/_(.)?/g, function(match, chr) {\n if (chr) {\n return chr.toUpperCase();\n } else {\n return '';\n }\n });\n },\n capitalize: function(string) {\n return string[0].toUpperCase() + string.substring(1);\n },\n compact: function(object) {\n return $.grep(object, function(value) {\n return !!value;\n });\n },\n all: function(array, callback) {\n var args, i;\n args = Array.prototype.slice.apply(arguments);\n callback = args.pop();\n array = args.pop() || this;\n i = 0;\n while (i < array.length) {\n if (callback(array[i])) {\n return false;\n }\n i++;\n }\n return true;\n },\n detect: function(array, callback) {\n var args, i;\n args = Array.prototype.slice.apply(arguments);\n callback = args.pop();\n array = args.pop() || this;\n i = 0;\n while (i < array.length) {\n if (callback(array[i])) {\n return array[i];\n }\n i++;\n }\n },\n select: function(array, callback) {\n var args, i, result;\n args = Array.prototype.slice.apply(arguments);\n callback = args.pop();\n array = args.pop() || this;\n result = [];\n i = 0;\n while (i < array.length) {\n if (callback(array[i])) {\n result.push(array[i]);\n }\n i++;\n }\n return result;\n },\n slice: function(object, key) {\n var keys, result;\n keys = Array.prototype.slice.apply(arguments);\n object = (typeof keys[0] === 'object' ? keys.shift() : this);\n result = {};\n for (key in object) {\n if (keys.indexOf(key) > -1) {\n result[key] = object[key];\n }\n }\n return result;\n },\n only: function(object) {\n var key, keys, result;\n keys = Array.prototype.slice.apply(arguments);\n object = (typeof keys[0] === 'object' ? keys.shift() : this);\n result = {};\n for (key in object) {\n if (keys.indexOf(key) !== -1) {\n result[key] = object[key];\n }\n }\n return result;\n },\n except: function(object) {\n var key, keys, result;\n keys = Array.prototype.slice.apply(arguments);\n object = (typeof keys[0] === 'object' ? keys.shift() : this);\n result = {};\n for (key in object) {\n if (keys.indexOf(key) === -1) {\n result[key] = object[key];\n }\n }\n return result;\n },\n intersect: function(array, other) {\n return array.filter(function(element) {\n return other.indexOf(element) !== -1;\n });\n },\n map: function(elems, callback, arg) {\n var i, isArray, key, length, ret, value;\n value = void 0;\n key = void 0;\n ret = [];\n i = 0;\n length = elems.length;\n isArray = elems instanceof jQuery || length !== void 0 && typeof length === 'number' && (length > 0 && elems[0] && elems[length - 1]) || length === 0 || jQuery.isArray(elems);\n if (isArray) {\n while (i < length) {\n value = callback(elems[i], i, arg);\n if (value != null) {\n ret[ret.length] = value;\n }\n i++;\n }\n } else {\n for (key in elems) {\n value = callback(elems[key], key, arg);\n if (value != null) {\n ret[ret.length] = value;\n }\n }\n }\n return ret.concat.apply([], ret);\n },\n shuffle: function(array) {\n var current, tmp, top;\n array = array.slice();\n top = array.length;\n while (top && --top) {\n current = Math.floor(Math.random() * (top + 1));\n tmp = array[current];\n array[current] = array[top];\n array[top] = tmp;\n }\n return array;\n },\n truncate: function(string, length) {\n if (string.length > length) {\n return string.trim().substring(0, length) + '...';\n } else {\n return string;\n }\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=ext/jquery");minispade.register('hax0rs', "(function() {(function() {\n\n\n\n}).call(this);\n\n})();\n//@ sourceURL=hax0rs");minispade.register('mocks', "(function() {(function() {\n var artifact, artifacts, branches, build, builds, commits, data, hooks, id, job, jobs, repositories, repository, responseTime, workers, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m;\nminispade.require('ext/jquery');\n\n responseTime = 0;\n\n repositories = [\n {\n id: 1,\n owner: 'travis-ci',\n name: 'travis-core',\n slug: 'travis-ci/travis-core',\n build_ids: [1, 2],\n last_build_id: 1,\n last_build_number: 1,\n last_build_result: 0,\n last_build_duration: 30,\n last_build_started_at: '2012-07-02T00:00:00Z',\n last_build_finished_at: '2012-07-02T00:00:30Z',\n description: 'Description of travis-core'\n }, {\n id: 2,\n owner: 'travis-ci',\n name: 'travis-assets',\n slug: 'travis-ci/travis-assets',\n build_ids: [3],\n last_build_id: 3,\n last_build_number: 3,\n last_build_result: 1,\n last_build_duration: 30,\n last_build_started_at: '2012-07-02T00:01:00Z',\n last_build_finished_at: '2012-07-01T00:01:30Z',\n description: 'Description of travis-assets'\n }, {\n id: 3,\n owner: 'travis-ci',\n name: 'travis-hub',\n slug: 'travis-ci/travis-hub',\n build_ids: [4],\n last_build_id: 4,\n last_build_number: 4,\n last_build_result: void 0,\n last_build_duration: void 0,\n last_build_started_at: '2012-07-02T00:02:00Z',\n last_build_finished_at: void 0,\n description: 'Description of travis-hub'\n }\n ];\n\n builds = [\n {\n id: 1,\n repository_id: '1',\n commit_id: 1,\n job_ids: [1, 2, 3],\n number: 1,\n pull_request: false,\n config: {\n rvm: ['rbx', '1.9.3', 'jruby']\n },\n duration: 30,\n started_at: '2012-07-02T00:00:00Z',\n finished_at: '2012-07-02T00:00:30Z',\n result: 0\n }, {\n id: 2,\n repository_id: '1',\n commit_id: 2,\n job_ids: [4],\n number: 2,\n pull_request: false,\n config: {\n rvm: ['rbx']\n }\n }, {\n id: 3,\n repository_id: '2',\n commit_id: 3,\n job_ids: [5],\n number: 3,\n pull_request: false,\n config: {\n rvm: ['rbx']\n },\n duration: 30,\n started_at: '2012-07-02T00:01:00Z',\n finished_at: '2012-07-01T00:01:30Z',\n result: 1\n }, {\n id: 4,\n repository_id: '3',\n commit_id: 4,\n job_ids: [6],\n number: 4,\n pull_request: false,\n config: {\n rvm: ['rbx']\n },\n started_at: '2012-07-02T00:02:00Z'\n }\n ];\n\n commits = [\n {\n id: 1,\n sha: '1234567',\n branch: 'master',\n message: 'commit message 1',\n author_name: 'author name',\n author_email: 'author@email.com',\n committer_name: 'committer name',\n committer_email: 'committer@email.com',\n compare_url: 'http://github.com/compare/0123456..1234567'\n }, {\n id: 2,\n sha: '2345678',\n branch: 'feature',\n message: 'commit message 2',\n author_name: 'author name',\n author_email: 'author@email.com',\n committer_name: 'committer name',\n committer_email: 'committer@email.com',\n compare_url: 'http://github.com/compare/0123456..2345678'\n }, {\n id: 3,\n sha: '3456789',\n branch: 'master',\n message: 'commit message 3',\n author_name: 'author name',\n author_email: 'author@email.com',\n committer_name: 'committer name',\n committer_email: 'committer@email.com',\n compare_url: 'http://github.com/compare/0123456..3456789'\n }, {\n id: 4,\n sha: '4567890',\n branch: 'master',\n message: 'commit message 4',\n author_name: 'author name',\n author_email: 'author@email.com',\n committer_name: 'committer name',\n committer_email: 'committer@email.com',\n compare_url: 'http://github.com/compare/0123456..4567890'\n }\n ];\n\n jobs = [\n {\n id: 1,\n repository_id: 1,\n build_id: 1,\n commit_id: 1,\n log_id: 1,\n number: '1.1',\n config: {\n rvm: 'rbx'\n },\n duration: 30,\n started_at: '2012-07-02T00:00:00Z',\n finished_at: '2012-07-02T00:00:30Z',\n result: 0\n }, {\n id: 2,\n repository_id: 1,\n build_id: 1,\n commit_id: 1,\n log_id: 2,\n number: '1.2',\n config: {\n rvm: '1.9.3'\n },\n duration: 40,\n started_at: '2012-07-02T00:00:00Z',\n finished_at: '2012-07-02T00:00:40Z',\n result: 1\n }, {\n id: 3,\n repository_id: 1,\n build_id: 1,\n commit_id: 1,\n log_id: 3,\n number: '1.3',\n config: {\n rvm: 'jruby'\n },\n allow_failure: true\n }, {\n id: 4,\n repository_id: 1,\n build_id: 2,\n commit_id: 2,\n log_id: 4,\n number: '2.1',\n config: {\n rvm: 'rbx'\n }\n }, {\n id: 5,\n repository_id: 2,\n build_id: 3,\n commit_id: 3,\n log_id: 5,\n number: '3.1',\n config: {\n rvm: 'rbx'\n },\n duration: 30,\n started_at: '2012-07-02T00:01:00Z',\n finished_at: '2012-07-02T00:01:30Z',\n result: 1\n }, {\n id: 6,\n repository_id: 3,\n build_id: 4,\n commit_id: 4,\n log_id: 6,\n number: '4.1',\n config: {\n rvm: 'rbx'\n },\n started_at: '2012-07-02T00:02:00Z'\n }, {\n id: 7,\n repository_id: 1,\n build_id: 5,\n commit_id: 5,\n log_id: 7,\n number: '5.1',\n config: {\n rvm: 'rbx'\n },\n state: 'created',\n queue: 'common'\n }, {\n id: 8,\n repository_id: 1,\n build_id: 5,\n commit_id: 5,\n log_id: 8,\n number: '5.2',\n config: {\n rvm: 'rbx'\n },\n state: 'created',\n queue: 'common'\n }\n ];\n\n artifacts = [\n {\n id: 1,\n body: 'log 1'\n }, {\n id: 2,\n body: 'log 2'\n }, {\n id: 3,\n body: 'log 3'\n }, {\n id: 4,\n body: 'log 4'\n }, {\n id: 5,\n body: 'log 5'\n }, {\n id: 6,\n body: 'log 6'\n }, {\n id: 7,\n body: 'log 7'\n }, {\n id: 8,\n body: 'log 8'\n }\n ];\n\n branches = [\n {\n branches: [builds[0], builds[1]],\n commits: [commits[0], commits[1]]\n }, {\n branches: [builds[2]],\n commits: [commits[2]]\n }, {\n branches: [builds[3]],\n commits: [commits[3]]\n }\n ];\n\n workers = [\n {\n id: 1,\n name: 'ruby-1',\n host: 'worker.travis-ci.org',\n state: 'ready'\n }, {\n id: 2,\n name: 'ruby-2',\n host: 'worker.travis-ci.org',\n state: 'ready'\n }\n ];\n\n hooks = [\n {\n slug: 'travis-ci/travis-core',\n description: 'description of travis-core',\n active: true,\n \"private\": false\n }, {\n slug: 'travis-ci/travis-assets',\n description: 'description of travis-assets',\n active: false,\n \"private\": false\n }, {\n slug: 'svenfuchs/minimal',\n description: 'description of minimal',\n active: true,\n \"private\": false\n }\n ];\n\n $.mockjax({\n url: '/repositories',\n responseTime: responseTime,\n response: function(settings) {\n var search, slug;\n if (!settings.data) {\n return this.responseText = {\n repositories: repositories\n };\n } else if (slug = settings.data.slug) {\n return this.responseText = {\n repositories: [\n $.detect(repositories, function(repository) {\n return repository.slug === slug;\n })\n ]\n };\n } else if (search = settings.data.search) {\n return this.responseText = {\n repositories: $.select(repositories, function(repository) {\n return repository.slug.indexOf(search) > -1;\n }).toArray()\n };\n } else {\n return raise(\"don't know this ditty\");\n }\n }\n });\n\n for (_i = 0, _len = repositories.length; _i < _len; _i++) {\n repository = repositories[_i];\n $.mockjax({\n url: '/' + repository.slug,\n responseTime: responseTime,\n responseText: {\n repository: repository\n }\n });\n $.mockjax({\n url: '/repositories',\n data: {\n slug: repository.slug\n },\n responseTime: responseTime,\n responseText: {\n repositories: [repository]\n }\n });\n $.mockjax({\n url: '/builds',\n data: {\n ids: repository.build_ids\n },\n responseTime: responseTime,\n responseText: {\n builds: $.select(builds, function(build) {\n return repository.build_ids.indexOf(build.id) !== -1;\n })\n }\n });\n $.mockjax({\n url: '/builds',\n data: {\n repository_id: repository.id,\n event_type: 'push',\n orderBy: 'number DESC'\n },\n responseTime: responseTime,\n responseText: {\n builds: (function() {\n var _j, _len1, _ref, _results;\n _ref = repository.build_ids;\n _results = [];\n for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {\n id = _ref[_j];\n _results.push(builds[id - 1]);\n }\n return _results;\n })(),\n commits: (function() {\n var _j, _len1, _ref, _results;\n _ref = repository.build_ids;\n _results = [];\n for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {\n id = _ref[_j];\n _results.push(commits[builds[id - 1].commit_id - 1]);\n }\n return _results;\n })()\n }\n });\n }\n\n for (_j = 0, _len1 = builds.length; _j < _len1; _j++) {\n build = builds[_j];\n $.mockjax({\n url: '/builds/' + build.id,\n responseTime: responseTime,\n responseText: {\n build: build,\n commit: commits[build.commit_id - 1],\n jobs: (function() {\n var _k, _len2, _ref, _results;\n _ref = build.job_ids;\n _results = [];\n for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {\n id = _ref[_k];\n _results.push(jobs[id - 1]);\n }\n return _results;\n })()\n }\n });\n }\n\n for (_k = 0, _len2 = jobs.length; _k < _len2; _k++) {\n job = jobs[_k];\n $.mockjax({\n url: '/jobs/' + job.id,\n responseTime: responseTime,\n responseText: {\n job: job,\n commit: commits[job.commit_id - 1]\n }\n });\n }\n\n $.mockjax({\n url: '/jobs',\n responseTime: responseTime,\n responseText: {\n jobs: $.select(jobs, function(job) {\n return job.state === 'created';\n })\n }\n });\n\n for (_l = 0, _len3 = branches.length; _l < _len3; _l++) {\n data = branches[_l];\n $.mockjax({\n url: '/branches',\n data: {\n repository_id: data.branches[0].repository_id\n },\n responseTime: responseTime,\n responseText: data\n });\n }\n\n for (_m = 0, _len4 = artifacts.length; _m < _len4; _m++) {\n artifact = artifacts[_m];\n $.mockjax({\n url: '/artifacts/' + artifact.id,\n responseTime: responseTime,\n responseText: {\n artifact: artifact\n }\n });\n }\n\n $.mockjax({\n url: '/workers',\n responseTime: responseTime,\n responseText: {\n workers: workers\n }\n });\n\n $.mockjax({\n url: '/profile/hooks',\n responseTime: responseTime,\n responseText: {\n hooks: hooks\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=mocks");minispade.register('travis/auth', "(function() {(function() {\n\n this.Travis.Auth = (function() {\n\n function Auth() {\n this.iframe = $('