From f2c72926bd20ff0a179dc2fb8790f5cacbe70422 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Tue, 18 Sep 2012 10:57:35 +0200 Subject: [PATCH] clean up styles --- AssetFile | 1 - assets/javascripts/app/app.coffee | 8 +- .../javascripts/app/templates/jobs/list.hbs | 34 +- assets/javascripts/app/templates/jobs/log.hbs | 2 +- .../app/templates/layouts/sidebar.hbs | 5 - assets/javascripts/app/views.coffee | 3 + assets/javascripts/app/views/job.coffee | 3 - assets/javascripts/vendor/facebox.js | 310 -- assets/stylesheets/_common.sass | 2 - assets/stylesheets/_mixins/all.sass | 20 + assets/stylesheets/_mixins/ansi.sass | 43 + assets/stylesheets/_mixins/colors.sass | 81 + assets/stylesheets/_mixins/fonts.sass | 13 + assets/stylesheets/application.sass | 123 +- assets/stylesheets/application/auth.sass | 10 + assets/stylesheets/application/flash.sass | 9 + assets/stylesheets/application/loading.sass | 19 + assets/stylesheets/application/misc.sass | 7 + assets/stylesheets/application/popup.sass | 34 + assets/stylesheets/left.sass | 12 +- assets/stylesheets/left/list.sass | 28 +- assets/stylesheets/main.sass | 11 +- assets/stylesheets/main/list.sass | 14 +- assets/stylesheets/main/log.sass | 104 +- assets/stylesheets/main/repository.sass | 19 +- assets/stylesheets/main/summary.sass | 4 +- assets/stylesheets/main/tools.sass | 10 +- assets/stylesheets/profile.sass | 26 +- assets/stylesheets/profile/hooks.sass | 26 +- assets/stylesheets/right.sass | 24 +- assets/stylesheets/right/github.sass | 2 +- assets/stylesheets/right/lists.sass | 5 +- assets/stylesheets/right/slider.sass | 22 +- assets/stylesheets/right/sponsors.sass | 9 +- assets/stylesheets/stats.sass | 2 +- assets/stylesheets/status.sass | 24 +- assets/stylesheets/tabs.sass | 24 +- assets/stylesheets/top.sass | 91 +- assets/stylesheets/vendor/facebox.css | 81 - public/javascripts/application.js | 2 +- public/javascripts/vendor.js | 310 -- public/stylesheets/application.css | 2807 ++++++++++++++--- 42 files changed, 2793 insertions(+), 1591 deletions(-) delete mode 100644 assets/javascripts/vendor/facebox.js delete mode 100644 assets/stylesheets/_common.sass create mode 100644 assets/stylesheets/_mixins/all.sass create mode 100644 assets/stylesheets/_mixins/ansi.sass create mode 100644 assets/stylesheets/_mixins/colors.sass create mode 100644 assets/stylesheets/_mixins/fonts.sass create mode 100644 assets/stylesheets/application/auth.sass create mode 100644 assets/stylesheets/application/flash.sass create mode 100644 assets/stylesheets/application/loading.sass create mode 100644 assets/stylesheets/application/misc.sass create mode 100644 assets/stylesheets/application/popup.sass delete mode 100644 assets/stylesheets/vendor/facebox.css diff --git a/AssetFile b/AssetFile index 30c6763b..ab0468ae 100644 --- a/AssetFile +++ b/AssetFile @@ -19,7 +19,6 @@ input 'assets/javascripts' do vendor/ember-data.js vendor/ansiparse.js vendor/i18n.js - vendor/facebox.js vendor/pusher.js vendor/jquery.cookie.js vendor/jquery.timeago.js diff --git a/assets/javascripts/app/app.coffee b/assets/javascripts/app/app.coffee index 171125ab..beb3183a 100644 --- a/assets/javascripts/app/app.coffee +++ b/assets/javascripts/app/app.coffee @@ -38,10 +38,10 @@ Travis.reopen @setCurrentUser(JSON.parse($.cookie('user'))) signIn: -> - user = Travis.Auth.signIn() - console.log(user) - # @setCurrentUser(@USER_PAYLOAD) - # @render.apply(this, @get('returnTo') || ['home', 'index']) + # user = Travis.Auth.signIn() + # console.log(user) + @setCurrentUser(@USER_PAYLOAD) + @render.apply(this, @get('returnTo') || ['home', 'index']) signOut: -> @setCurrentUser() diff --git a/assets/javascripts/app/templates/jobs/list.hbs b/assets/javascripts/app/templates/jobs/list.hbs index cd6d5ed7..3f4f3285 100644 --- a/assets/javascripts/app/templates/jobs/list.hbs +++ b/assets/javascripts/app/templates/jobs/list.hbs @@ -8,7 +8,7 @@ {{/if}} @@ -32,23 +32,23 @@
{{t jobs.allowed_failures}} - +
- {{#unless required}} -
-
{{t "jobs.allowed_failures"}}
-
-

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

-

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

-
 matrix:
+  {{#unless view.required}}
+    
+    - rvm: ruby-head
+

+ This lets you add in experimental and preparatory builds to test against versions or + configurations that you are not ready to officially support. +

{{/unless}} {{/if}} diff --git a/assets/javascripts/app/templates/jobs/log.hbs b/assets/javascripts/app/templates/jobs/log.hbs index 53cf0e80..58141802 100644 --- a/assets/javascripts/app/templates/jobs/log.hbs +++ b/assets/javascripts/app/templates/jobs/log.hbs @@ -1,7 +1,7 @@ {{view.logSubscriber}} {{#if log.isLoaded}} -

+  

     
     
   {{{formatLog log.body}}}
diff --git a/assets/javascripts/app/templates/layouts/sidebar.hbs b/assets/javascripts/app/templates/layouts/sidebar.hbs index 9a631602..8ac8421a 100644 --- a/assets/javascripts/app/templates/layouts/sidebar.hbs +++ b/assets/javascripts/app/templates/layouts/sidebar.hbs @@ -11,11 +11,6 @@ {{outlet queues}} {{outlet links}} -
-

{{t layouts.about.alpha}}

-

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

-
-

{{t layouts.about.join}}

    diff --git a/assets/javascripts/app/views.coffee b/assets/javascripts/app/views.coffee index f2fe9a01..1d5a4137 100644 --- a/assets/javascripts/app/views.coffee +++ b/assets/javascripts/app/views.coffee @@ -5,6 +5,9 @@ require 'ext/ember/namespace' route: (event) -> Travis.app.routes.route(event) + popup: (event) -> + $("##{event.target.name}").remove().appendTo('body').toggle() + @Travis.reopen HomeLayout: Travis.View.extend(templateName: 'layouts/home') ProfileLayout: Travis.View.extend(templateName: 'layouts/profile') diff --git a/assets/javascripts/app/views/job.coffee b/assets/javascripts/app/views/job.coffee index 16fd3b4e..3cf72bd9 100644 --- a/assets/javascripts/app/views/job.coffee +++ b/assets/javascripts/app/views/job.coffee @@ -3,9 +3,6 @@ templateName: 'jobs/list' buildBinding: 'controller.build' - toggleHelp: -> - $.facebox(div: '#allow_failure_help') - JobsItemView: Travis.View.extend tagName: 'tr' classNameBindings: ['color'] diff --git a/assets/javascripts/vendor/facebox.js b/assets/javascripts/vendor/facebox.js deleted file mode 100644 index a36acb0f..00000000 --- a/assets/javascripts/vendor/facebox.js +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Facebox (for jQuery) - * version: 1.2 (05/05/2008) - * @requires jQuery v1.2 or later - * - * Examples at http://famspam.com/facebox/ - * - * Licensed under the MIT: - * http://www.opensource.org/licenses/mit-license.php - * - * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ] - * - * Usage: - * - * jQuery(document).ready(function() { - * jQuery('a[rel*=facebox]').facebox() - * }) - * - * Terms - * Loads the #terms div in the box - * - * Terms - * Loads the terms.html page in the box - * - * Terms - * Loads the terms.png image in the box - * - * - * You can also use it programmatically: - * - * jQuery.facebox('some html') - * jQuery.facebox('some html', 'my-groovy-style') - * - * The above will open a facebox with "some html" as the content. - * - * jQuery.facebox(function($) { - * $.get('blah.html', function(data) { $.facebox(data) }) - * }) - * - * The above will show a loading screen before the passed function is called, - * allowing for a better ajaxy experience. - * - * The facebox function can also display an ajax page, an image, or the contents of a div: - * - * jQuery.facebox({ ajax: 'remote.html' }) - * jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style') - * jQuery.facebox({ image: 'stairs.jpg' }) - * jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style') - * jQuery.facebox({ div: '#box' }) - * jQuery.facebox({ div: '#box' }, 'my-groovy-style') - * - * Want to close the facebox? Trigger the 'close.facebox' document event: - * - * jQuery(document).trigger('close.facebox') - * - * Facebox also has a bunch of other hooks: - * - * loading.facebox - * beforeReveal.facebox - * reveal.facebox (aliased as 'afterReveal.facebox') - * init.facebox - * afterClose.facebox - * - * Simply bind a function to any of these hooks: - * - * $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... }) - * - */ -(function($) { - $.facebox = function(data, klass) { - $.facebox.loading() - - if (data.ajax) fillFaceboxFromAjax(data.ajax, klass) - else if (data.image) fillFaceboxFromImage(data.image, klass) - else if (data.div) fillFaceboxFromHref(data.div, klass) - else if ($.isFunction(data)) data.call($) - else $.facebox.reveal(data, klass) - } - - /* - * Public, $.facebox methods - */ - - $.extend($.facebox, { - settings: { - opacity : 0.2, - overlay : true, - loadingImage : '/facebox/loading.gif', - closeImage : '/facebox/closelabel.png', - imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ], - faceboxHtml : '\ - ' - }, - - loading: function() { - init() - if ($('#facebox .loading').length == 1) return true - showOverlay() - - $('#facebox .content').empty() - $('#facebox .body').children().hide().end(). - append('
    ') - - $('#facebox').css({ - top: getPageScroll()[1] + (getPageHeight() / 10), - left: $(window).width() / 2 - 205 - }).show() - - $(document).bind('keydown.facebox', function(e) { - if (e.keyCode == 27) $.facebox.close() - return true - }) - $(document).trigger('loading.facebox') - }, - - reveal: function(data, klass) { - $(document).trigger('beforeReveal.facebox') - if (klass) $('#facebox .content').addClass(klass) - $('#facebox .content').append(data) - $('#facebox .loading').remove() - $('#facebox .body').children().fadeIn('normal') - $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2)) - $(document).trigger('reveal.facebox').trigger('afterReveal.facebox') - }, - - close: function() { - $(document).trigger('close.facebox') - return false - } - }) - - /* - * Public, $.fn methods - */ - - $.fn.facebox = function(settings) { - if ($(this).length == 0) return - - init(settings) - - function clickHandler() { - $.facebox.loading(true) - - // support for rel="facebox.inline_popup" syntax, to add a class - // also supports deprecated "facebox[.inline_popup]" syntax - var klass = this.rel.match(/facebox\[?\.(\w+)\]?/) - if (klass) klass = klass[1] - - fillFaceboxFromHref(this.href, klass) - return false - } - - return this.bind('click.facebox', clickHandler) - } - - /* - * Private methods - */ - - // called one time to setup facebox on this page - function init(settings) { - if ($.facebox.settings.inited) return true - else $.facebox.settings.inited = true - - $(document).trigger('init.facebox') - makeCompatible() - - var imageTypes = $.facebox.settings.imageTypes.join('|') - $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i') - - if (settings) $.extend($.facebox.settings, settings) - $('body').append($.facebox.settings.faceboxHtml) - - var preload = [ new Image(), new Image() ] - preload[0].src = $.facebox.settings.closeImage - preload[1].src = $.facebox.settings.loadingImage - - $('#facebox').find('.b:first, .bl').each(function() { - preload.push(new Image()) - preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1') - }) - - $('#facebox .close').click($.facebox.close) - $('#facebox .close_image').attr('src', $.facebox.settings.closeImage) - } - - // getPageScroll() by quirksmode.com - function getPageScroll() { - var xScroll, yScroll; - if (self.pageYOffset) { - yScroll = self.pageYOffset; - xScroll = self.pageXOffset; - } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict - yScroll = document.documentElement.scrollTop; - xScroll = document.documentElement.scrollLeft; - } else if (document.body) {// all other Explorers - yScroll = document.body.scrollTop; - xScroll = document.body.scrollLeft; - } - return new Array(xScroll,yScroll) - } - - // Adapted from getPageSize() by quirksmode.com - function getPageHeight() { - var windowHeight - if (self.innerHeight) { // all except Explorer - windowHeight = self.innerHeight; - } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode - windowHeight = document.documentElement.clientHeight; - } else if (document.body) { // other Explorers - windowHeight = document.body.clientHeight; - } - return windowHeight - } - - // Backwards compatibility - function makeCompatible() { - var $s = $.facebox.settings - - $s.loadingImage = $s.loading_image || $s.loadingImage - $s.closeImage = $s.close_image || $s.closeImage - $s.imageTypes = $s.image_types || $s.imageTypes - $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml - } - - // Figures out what you want to display and displays it - // formats are: - // div: #id - // image: blah.extension - // ajax: anything else - function fillFaceboxFromHref(href, klass) { - // div - if (href.match(/#/)) { - var url = window.location.href.split('#')[0] - var target = href.replace(url,'') - if (target == '#') return - $.facebox.reveal($(target).html(), klass) - - // image - } else if (href.match($.facebox.settings.imageTypesRegexp)) { - fillFaceboxFromImage(href, klass) - // ajax - } else { - fillFaceboxFromAjax(href, klass) - } - } - - function fillFaceboxFromImage(href, klass) { - var image = new Image() - image.onload = function() { - $.facebox.reveal('
    ', klass) - } - image.src = href - } - - function fillFaceboxFromAjax(href, klass) { - $.get(href, function(data) { $.facebox.reveal(data, klass) }) - } - - function skipOverlay() { - return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null - } - - function showOverlay() { - if (skipOverlay()) return - - if ($('#facebox_overlay').length == 0) - $("body").append('
    ') - - $('#facebox_overlay').hide().addClass("facebox_overlayBG") - .css('opacity', $.facebox.settings.opacity) - .click(function() { $(document).trigger('close.facebox') }) - .fadeIn(200) - return false - } - - function hideOverlay() { - if (skipOverlay()) return - - $('#facebox_overlay').fadeOut(200, function(){ - $("#facebox_overlay").removeClass("facebox_overlayBG") - $("#facebox_overlay").addClass("facebox_hide") - $("#facebox_overlay").remove() - }) - - return false - } - - /* - * Bindings - */ - - $(document).bind('close.facebox', function() { - $(document).unbind('keydown.facebox') - $('#facebox').fadeOut(function() { - $('#facebox .content').removeClass().addClass('content') - $('#facebox .loading').remove() - $(document).trigger('afterClose.facebox') - }) - hideOverlay() - }) - -})(jQuery); - diff --git a/assets/stylesheets/_common.sass b/assets/stylesheets/_common.sass deleted file mode 100644 index f0ec68d7..00000000 --- a/assets/stylesheets/_common.sass +++ /dev/null @@ -1,2 +0,0 @@ -@import "compass" - diff --git a/assets/stylesheets/_mixins/all.sass b/assets/stylesheets/_mixins/all.sass new file mode 100644 index 00000000..7067b2dd --- /dev/null +++ b/assets/stylesheets/_mixins/all.sass @@ -0,0 +1,20 @@ +@import "compass" +@import "_mixins/ansi" +@import "_mixins/colors" +@import "_mixins/fonts" + +@mixin popup + display: none + position: absolute + z-index: 100 + background-color: #fff + border: 10px solid rgba(0, 0, 0, .5) + @include background-clip(padding-box) + @include border-radius(10px) + + + + + + + diff --git a/assets/stylesheets/_mixins/ansi.sass b/assets/stylesheets/_mixins/ansi.sass new file mode 100644 index 00000000..f11db162 --- /dev/null +++ b/assets/stylesheets/_mixins/ansi.sass @@ -0,0 +1,43 @@ +// ansi styles, see javascripts/lib/deansi.js +.ansi + .bold + font-weight: bold + .italic + font-style: italic + .underscore + // monochrome displays only according to http://ascii-table.com/ansi-escape-sequences.php + .black + color: black + .red + color: red + .green + color: lime + .yellow + color: yellow + .blue + color: blue + .magenta + color: magenta + .cyan + color: cyan + .white + color: white + .black.bright + color: #999 + .bg-black + background-color: black + .bg-red + background-color: red + .bg-green + background-color: lime + .bg-yellow + background-color: yellow + .bg-blue + background-color: blue + .bg-magenta + background-color: magenta + .bg-cyan + background-color: cyan + .bg-white + background-color: white + diff --git a/assets/stylesheets/_mixins/colors.sass b/assets/stylesheets/_mixins/colors.sass new file mode 100644 index 00000000..8a528928 --- /dev/null +++ b/assets/stylesheets/_mixins/colors.sass @@ -0,0 +1,81 @@ +$black: #000 +$white: #fff + +$green: green +$green-light-1: #dcffdc +$green-light-3: #fafffa +$red: #c00 +$red-light-1: #ffdcdc +$red-light-3: #fffafa +$yellow-light-1: #ffffe1 +$yellow-light-3: #fffffa + +$gray-dark-1: #333 +$gray-dark-2: #444 +$gray-dark-3: #666 +$gray-medium-1: #999 +$gray-medium-2: #aaa +$gray-medium-3: #ccc +$gray-light-1: #ddd +$gray-light-2: #efefef +$gray-light-3: #f6f6f6 + +$slate-blue-1: #e5e8ee +$slate-blue-2: #f2f4f9 +$slate-blue-3: #fafbfc +$slate-gray-1: #e1e2e6 + +$color-text: $gray-dark-3 +$color-text-light: $gray-medium-1 +$color-text-lighter: $gray-medium-2 +$color-text-log: $white +$color-text-status-passed: $green +$color-text-status-failed: $red + +$color-link: $gray-dark-3 +$color-link-highlight: #c7371a +$color-link-sponsor: #575c7c +$color-link-top: $gray-medium-3 +$color-link-top-highlight: $white + +$color-bg-dark: $slate-blue-1 +$color-bg-light: $gray-light-1 +$color-bg-input: $white +$color-bg-link-top: $black +$color-bg-dropdown: $gray-dark-2 +$color-bg-dropdown-highlight: $gray-dark-3 +$color-bg-pre: $gray-light-2 +$color-bg-tab: $gray-light-3 +$color-bg-tab-hover: $white +$color-bg-tab-active: $white +$color-bg-log: $gray-dark-1 +$color-bg-log-fold: $gray-dark-2 +$color-bg-log-highlight: rgba(255, 255, 255, 0.05) +$color-bg-slider: $slate-blue-2 +$color-bg-list-odd: $white +$color-bg-list-even: $gray-light-3 +$color-bg-hooks-odd: $slate-blue-3 +$color-bg-hooks-even: $white +$color-bg-tools-pane: $slate-blue-2 +$color-bg-sidebar: $slate-blue-2 +$color-bg-sidebar-box: $white + +$color-bg-job: $yellow-light-3 +$color-bg-job-highlight: $yellow-light-1 +$color-bg-job-passed: $green-light-3 +$color-bg-job-passed-highlight: $green-light-1 +$color-bg-job-failed: $red-light-3 +$color-bg-job-failed-highlight: $red-light-1 + +$color-border-normal: $gray-medium-3 +$color-border-light: $gray-light-1 +$color-border-log: $gray-light-1 +$color-border-slider-normal: $slate-blue-2 +$color-border-slider-light: $gray-medium-1 +$color-border-slider-hover: $slate-gray-1 + +$color-bg-list-info: #fffcf4 +$color-text-list-info: #7f7f75 +$color-shadow-list-info: #bab9a7 + + diff --git a/assets/stylesheets/_mixins/fonts.sass b/assets/stylesheets/_mixins/fonts.sass new file mode 100644 index 00000000..558a4365 --- /dev/null +++ b/assets/stylesheets/_mixins/fonts.sass @@ -0,0 +1,13 @@ +$font-size-huge: 24px +$font-size-big: 16px +$font-size-normal: 14px +$font-size-small: 13px +$font-size-log: 12px +$font-size-smaller: 12px +$font-size-tiny: 11px +$font-size-tiniest: 10px + +$line-height: 19px +$line-height-log: 18px + + diff --git a/assets/stylesheets/application.sass b/assets/stylesheets/application.sass index 828d5e61..337ba772 100644 --- a/assets/stylesheets/application.sass +++ b/assets/stylesheets/application.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" html margin: 0 @@ -7,13 +7,15 @@ html body overflow-x: hidden font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif - line-height: 120% + font-size: $font-size-small + line-height: $line-height margin: 0 padding: 0 width: 100% + color: $color-text a - color: #333 + color: $color-link text-decoration: none ul @@ -24,118 +26,3 @@ ul li padding: 0 -td, th - text-align: left - font-size: 80% - padding: 5px 10px - vertical-align: top - -caption - text-align: left - font-size: 16px - font-weight: bold - color: #666 - -pre - background: none repeat scroll 0 0 #FAFAFA - border: 1px solid #DDDDDD - border-radius: 8px 8px 8px 8px - font-family: monospace - font-size: 13px - line-height: 1.5em - margin-top: 1em - overflow-x: scroll - padding: 1em 1.5em - -pre::-webkit-scrollbar - height: 10px - width: 10px - -pre::-webkit-scrollbar-button:start:decrement, -pre::-webkit-scrollbar-button:end:increment - display: none - -pre::-webkit-scrollbar-track-piece - background: #444 - -webkit-border-radius: 4px - -pre::-webkit-scrollbar-thumb:horizontal - background: -webkit-gradient(linear, left top, left bottom, from(#85888E), to(#55585E)) - -webkit-border-radius: 4px - width: 25px - -#auth-frame - position: absolute - z-index: 10 - top: 50% - left: 50% - width: 400px - height: 300px - margin: -200px 0 0 -150px - background-color: #fff - border: 10px solid rgba(0, 0, 0, .5) - @include background-clip(padding-box) - @include border-radius(10px) - - -#flash-messages - position: absolute - left: 400px - top: 10px - font-size: 25px - color: #FFFFFF - -.loading - padding: 15px 25px 0 0 - span - padding-right: 25px - font-size: 13px - color: #aaa - background: inline-image('spinner.gif') no-repeat right 4px - - .loading - display: none - -span.loading - padding: 0 25px 0 0 - font-size: 13px - color: #aaa - background: inline-image('spinner.gif') no-repeat right 4px - -.emoji - vertical-align: middle - width: 20px - height: 20px - -.help - display: inline-block - height: 19px - width: 16px - margin: -9px 0 0 4px - vertical-align: middle - background: inline-image('icons/help.png') no-repeat scroll 0 3px transparent - cursor: pointer - -.context_help_caption - text-align: left - font-size: 16px - font-weight: bold - color: #666 - border-bottom: 1px solid #CCCCCC - -.context_help - display: none - -.context_help_body - font-size: 1em - line-height: 1.4286 - margin: 1.4286em 0 - -#facebox - .content - display: block !important - .close - display: none - pre::-webkit-scrollbar - height: 0 - width: 0 diff --git a/assets/stylesheets/application/auth.sass b/assets/stylesheets/application/auth.sass new file mode 100644 index 00000000..b9383137 --- /dev/null +++ b/assets/stylesheets/application/auth.sass @@ -0,0 +1,10 @@ +@import "_mixins/all" + +#auth-frame + top: 50% + left: 50% + width: 400px + height: 300px + margin: -200px 0 0 -150px + @include popup + diff --git a/assets/stylesheets/application/flash.sass b/assets/stylesheets/application/flash.sass new file mode 100644 index 00000000..b4c2648b --- /dev/null +++ b/assets/stylesheets/application/flash.sass @@ -0,0 +1,9 @@ +@import "_mixins/all" + +#flash-messages + position: absolute + left: 400px + top: 10px + font-size: 25px + color: #FFFFFF + diff --git a/assets/stylesheets/application/loading.sass b/assets/stylesheets/application/loading.sass new file mode 100644 index 00000000..b078abc0 --- /dev/null +++ b/assets/stylesheets/application/loading.sass @@ -0,0 +1,19 @@ +@import "_mixins/all" + +.loading + padding: 15px 25px 0 0 + span + padding-right: 25px + font-size: $font-size-small + color: $color-text-lighter + background: inline-image('spinner.gif') no-repeat right 4px + + .loading + display: none + +span.loading + padding: 0 25px 0 0 + font-size: $font-size-small + color: $color-text-lighter + background: inline-image('spinner.gif') no-repeat right 4px + diff --git a/assets/stylesheets/application/misc.sass b/assets/stylesheets/application/misc.sass new file mode 100644 index 00000000..f5cfbc34 --- /dev/null +++ b/assets/stylesheets/application/misc.sass @@ -0,0 +1,7 @@ +@import "_mixins/all" + +.emoji + vertical-align: middle + width: 20px + height: 20px + diff --git a/assets/stylesheets/application/popup.sass b/assets/stylesheets/application/popup.sass new file mode 100644 index 00000000..64084430 --- /dev/null +++ b/assets/stylesheets/application/popup.sass @@ -0,0 +1,34 @@ +@import "_mixins/all" + +.help + display: inline-block + height: 19px + width: 16px + margin: -9px 0 0 4px + vertical-align: middle + background: inline-image('icons/help.png') no-repeat scroll 0 3px transparent + cursor: pointer + +.popup + top: 50% + left: 50% + width: 400px + margin: -230px 0 0 -200px + padding: 20px + @include popup + + h4 + margin-top: 0 + font-size: 18px + font-weight: bold + color: $color-text + + p + font-size: $font-size-normal + + pre + background-color: $color-bg-pre + margin: 0 + padding: 10px 20px + @include border-radius(4px) + diff --git a/assets/stylesheets/left.sass b/assets/stylesheets/left.sass index 3d1503f4..2900ec49 100644 --- a/assets/stylesheets/left.sass +++ b/assets/stylesheets/left.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all.sass" body#home, body#profile @@ -12,17 +12,17 @@ body#profile #search_box height: 90px padding: 30px 20px 0 20px - background-color: #e5e8ee + background-color: $color-bg-dark input[type=text] height: 28px width: 97% padding: 0 0 0 10px - font-size: 10pt - color: #666 - border: 1px solid #ddd + color: $color-text + font-size: $font-size-small + border: 1px solid $color-border-light @include border-radius(4px) - background: #fff inline-image('icons/search.png') no-repeat 335px 8px + background: $color-bg-input inline-image('icons/search.png') no-repeat 335px 8px .tabs #tab_owned diff --git a/assets/stylesheets/left/list.sass b/assets/stylesheets/left/list.sass index 878976ab..fd415fdc 100644 --- a/assets/stylesheets/left/list.sass +++ b/assets/stylesheets/left/list.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #accounts, #repositories @@ -7,25 +7,25 @@ li position: relative - font-size: 16px + font-size: $font-size-big padding: 15px 25px 15px 45px - border-bottom: 1px solid #ccc + border-bottom: 1px solid $color-border-light background-position: 24px 16px background-repeat: no-repeat &:nth-child(odd) - background-color: #fff + background-color: $color-bg-list-odd .indicator background-image: inline-image('ui/current-repository-indicator-odd.png') &:nth-child(even) - background-color: #f6f6f6 + background-color: $color-bg-list-even .indicator background-image: inline-image('ui/current-repository-indicator-even.png') &.green a - color: green + color: $color-text-status-passed &.red a - color: #c00 + color: $color-text-status-failed .current display: inline-block @@ -39,20 +39,20 @@ .summary margin: 5px -5px 0 0 - font-size: 13px - color: #666 + color: $color-text-light + font-size: $font-size-small .info overflow: hidden margin: 12px -25px -15px -45px - font-size: 13px - background-color: #fffcf4 - color: #7f7f75 + font-size: $font-size-small + background-color: $color-bg-list-info + color: $color-text-list-info display: none p margin: 0 -10px 0 -10px padding: 12px 35px 12px 55px - @include box-shadow(#bab9a7 0 1px 8px 0 inset) + @include box-shadow($color-shadow-list-info 0 1px 8px 0 inset) .indicator display: none @@ -69,7 +69,7 @@ .loading padding: 15px 25px 15px 30px - background-color: #fff + background-color: $color-bg-list-odd background-image: none #accounts diff --git a/assets/stylesheets/main.sass b/assets/stylesheets/main.sass index c1cda499..6a7a69df 100644 --- a/assets/stylesheets/main.sass +++ b/assets/stylesheets/main.sass @@ -1,17 +1,20 @@ -@import "_common" +@import "_mixins/all" #main position: relative + h3 + margin: 15px 60px 0 0 + font-size: $font-size-huge + a + text-decoration: underline + #home, #profile #main min-height: 1000px padding: 20px 280px 30px 450px - &.loading - opacity: .1 - &.maximized padding: 60px 100px 30px 440px diff --git a/assets/stylesheets/main/list.sass b/assets/stylesheets/main/list.sass index a703b98d..4982a99d 100644 --- a/assets/stylesheets/main/list.sass +++ b/assets/stylesheets/main/list.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" table.list width: 100% @@ -11,13 +11,23 @@ table.list caption margin-left: 12px margin-bottom: 8px + text-align: left + color: $color-text + font-size: $font-size-big + font-weight: bold + + td, th + text-align: left + font-size: $font-size-small + padding: 5px 10px + vertical-align: top tr max-height: 20px th font-size: 13px - color: #666 + color: $color-text white-space: nowrap border-bottom: 2px solid white diff --git a/assets/stylesheets/main/log.sass b/assets/stylesheets/main/log.sass index d7eb1dd8..8cdfe989 100644 --- a/assets/stylesheets/main/log.sass +++ b/assets/stylesheets/main/log.sass @@ -1,36 +1,32 @@ -@import "_common" - -#main - .sponsor - float: left - margin-top: 1px - font-size: 13px - color: #999 +@import "_mixins/all" pre#log position: relative clear: left min-height: 12px + margin-top: 25px + margin-top: 1em + padding: 15px 0 + color: $color-text-log + font-family: monospace + font-size: $font-size-log + line-height: $line-height-log white-space: pre-wrap word-wrap: break-word - line-height: 140% - font-size: 90% - margin-top: 25px - padding: 15px 0 - color: white - background-color: #333 + background-color: $color-bg-log + border: 1px solid $color-border-log @include border-radius(4px) + overflow-x: scroll - // deansi styles, see javascripts/lib/deansi.js p position: relative padding: 0 15px 0 50px margin: 0 min-height: 16px &:hover - background-color: rgba(255, 255, 255, 0.05) + background-color: $color-bg-log-highlight &.highlight - background-color: rgba(255, 255, 255, 0.5) + background-color: $color-bg-log-highlight a position: absolute margin-left: -40px @@ -39,70 +35,44 @@ pre#log .fold height: 16px overflow: hidden - background: #444 inline-image('icons/log.fold.closed.2.png') no-repeat 99.5% 2px + background: $color-bg-log-fold inline-image('icons/log.fold.closed.2.png') no-repeat 99.5% 2px cursor: pointer &.open height: auto background-image: inline-image('icons/log.fold.open.2.png') - .bold - font-weight: bold - .italic - font-style: italic - .underscore - /* monochrome displays only according to http://ascii-table.com/ansi-escape-sequences.php - - .black - color: black - .red - color: red - .green - color: lime - .yellow - color: yellow - .blue - color: blue - .magenta - color: magenta - .cyan - color: cyan - .white - color: white - .black.bright - color: #999 - - .bg-black - background-color: black - .bg-red - background-color: red - .bg-green - background-color: lime - .bg-yellow - background-color: yellow - .bg-blue - background-color: blue - .bg-magenta - background-color: magenta - .bg-cyan - background-color: cyan - .bg-white - background-color: white - #log.loading padding: 25px 0 0 10px +#log::-webkit-scrollbar + height: 10px + width: 10px + +#log::-webkit-scrollbar-button:start:decrement, +#log::-webkit-scrollbar-button:end:increment + display: none + +#log::-webkit-scrollbar-track-piece + background: #444 + -webkit-border-radius: 4px + +#log::-webkit-scrollbar-thumb:horizontal + background: -webkit-gradient(linear, left top, left bottom, from(#85888E), to(#55585E)) + -webkit-border-radius: 4px + width: 25px + #log #tail z-index: 99 position: absolute display: block top: 0 - right: 0 - margin: 10px 10px 0 0 + right: 2px + margin: 13px 10px 0 0 padding: 0 2px 0 3px color: #666 text-shadow: 1px 1px 0px #fff font-family: "Helvetica Neue", Helvetica, Arial, sans-serif - font-size: 11px + font-size: $font-size-tiny line-height: 14px text-decoration: none white-space: nowrap @@ -133,3 +103,9 @@ pre#log &.active .status background-color: #6b0 +#main + .sponsor + float: left + margin-top: 1px + color: #999 + diff --git a/assets/stylesheets/main/repository.sass b/assets/stylesheets/main/repository.sass index 29d92aee..ef026d6f 100644 --- a/assets/stylesheets/main/repository.sass +++ b/assets/stylesheets/main/repository.sass @@ -1,22 +1,11 @@ -@import "_common" +@import "_mixins/all" #repository position: relative - h3 - margin: 15px 60px 0 0 - a - font-size: 24px - line-height: 24px - - a - color: #666 - text-decoration: underline - .description, .language font-weight: normal - font-size: 13px - color: #999 + color: $color-text-light .language padding-right: 5px @@ -30,13 +19,13 @@ a height: 16px display: block - font-size: 12px + font-size: $font-size-smaller font-weight: bold text-decoration: none margin-left: 10px padding-left: 20px background: no-repeat 0px 2px - color: #999 + color: $color-text-light &.watchers background-image: inline-image('icons/github-watchers.png') &.forks diff --git a/assets/stylesheets/main/summary.sass b/assets/stylesheets/main/summary.sass index f4ff84fd..39f39946 100644 --- a/assets/stylesheets/main/summary.sass +++ b/assets/stylesheets/main/summary.sass @@ -1,9 +1,7 @@ -@import "_common" +@import "_mixins/all" #summary margin: 0 0 0 12px - color: #666 - font-size: 80% @include clearfix .left, diff --git a/assets/stylesheets/main/tools.sass b/assets/stylesheets/main/tools.sass index 60095b95..1c416b5b 100644 --- a/assets/stylesheets/main/tools.sass +++ b/assets/stylesheets/main/tools.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #tools position: relative @@ -19,10 +19,8 @@ right: 0 width: 600px padding: 10px 20px - border: 1px solid #CCC - background-color: #F2F4F9 - font-size: 80% - color: #666 + border: 1px solid $color-border-light + background-color: $color-bg-tools-pane @include border-bottom-radius(4px) @include single-box-shadow(rgba(black, 0.1), 1px, 3px, 5px) @@ -32,7 +30,7 @@ width: 80px display: inline-block input - border: 1px solid #DDD + border: 1px solid $color-border-light width: 505px padding: 4px @include border-radius(3px) diff --git a/assets/stylesheets/profile.sass b/assets/stylesheets/profile.sass index 318019f1..351103f5 100644 --- a/assets/stylesheets/profile.sass +++ b/assets/stylesheets/profile.sass @@ -1,28 +1,17 @@ -@import "_common" +@import "_mixins/all" #profile #main - h3 - margin: 15px 60px 0 0 - font-size: 24px - line-height: 24px - color: #666 - - h4 - font-size: 15px - color: #666 - img float: left width: 48px height: 48px margin: 3px 15px 0 0 @include border-radius(4px) + background-color: $color-bg-light dl margin: 0 0 20px 18px - color: #666 - font-size: 13px dt display: block @@ -34,21 +23,14 @@ .tip margin-top: -5px - font-size: 13px - color: #999 + color: $color-text-light .message margin-top: 20px padding: 13px 20px - color: #999 - font-weight: normal - font-size: 13px + color: $color-text-light border: 1px solid #DDD @include border-radius(4px) button.sync_now float: right - - .highlight - color: #C7371A - diff --git a/assets/stylesheets/profile/hooks.sass b/assets/stylesheets/profile/hooks.sass index 7edd0c5e..15af6df6 100644 --- a/assets/stylesheets/profile/hooks.sass +++ b/assets/stylesheets/profile/hooks.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #hooks // @include list-base @@ -10,38 +10,40 @@ padding: 10px white-space: nowrap overflow: hidden - border-bottom: 1px solid #DDD + border-bottom: 1px solid $color-border-light &:nth-child(3) - border-top: 1px solid #DDD + border-top: 1px solid $color-border-light &:nth-child(odd) - background-color: #FAFBFC + background-color: $color-bg-hooks-odd + .controls + background: $color-bg-hooks-odd - &:nth-child(odd) .controls - background: #fafbfc + &:nth-child(even) + background-color: $color-bg-hooks-even + .controls + background: $color-bg-hooks-even > a float: left - font-size: 16px - color: #666 + font-size: $font-size-big text-decoration: none .description display: none margin-left: 10px - font-size: 12px + font-size: $font-size-smaller white-space: nowrap overflow: hidden text-overflow: ellipsis - color: #999 + color: $color-text-light .controls position: absolute top: 10px right: 0 white-space: nowrap - background: #fff a float: left display: block @@ -66,7 +68,7 @@ &:hover > a - color: #c7371a + color: $color-link-highlight .description display: inline diff --git a/assets/stylesheets/right.sass b/assets/stylesheets/right.sass index d4f35ea7..470e38aa 100644 --- a/assets/stylesheets/right.sass +++ b/assets/stylesheets/right.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #right position: absolute @@ -8,9 +8,8 @@ min-height: 100% width: 205px padding: 20px 20px 20px 10px - background-color: #f2f4f9 - border-bottom: 1px solid #ccc - font-size: 13px + background-color: $color-bg-sidebar + border-bottom: 1px solid $color-border-light // @include transition(width .1s ease-out) h4 @@ -22,8 +21,8 @@ .box margin-top: 25px padding: 15px - border: 1px solid #ccc - background-color: #fff + border: 1px solid $color-border-normal + background-color: $color-bg-sidebar-box @include border-radius(4px) h4 @@ -33,16 +32,3 @@ li list-style-type: square margin-left: 15px - - #alpha_warning - background-color: #ffffda - - #alpha_warning h4 - padding-left: 20px - background: inline-image('icons/construction.png') no-repeat top left - - #alpha_warning p - margin-bottom: 0 - color: #666 - - diff --git a/assets/stylesheets/right/github.sass b/assets/stylesheets/right/github.sass index 083e727f..3ebe3550 100644 --- a/assets/stylesheets/right/github.sass +++ b/assets/stylesheets/right/github.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #github display: block diff --git a/assets/stylesheets/right/lists.sass b/assets/stylesheets/right/lists.sass index 6dc3239f..eaa6dc0e 100644 --- a/assets/stylesheets/right/lists.sass +++ b/assets/stylesheets/right/lists.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #right #queues @@ -23,10 +23,9 @@ white-space: nowrap margin: 0 list-style-type: none - color: #666 h5 - font-size: 13px + font-size: $font-size-small font-weight: normal margin: 0px cursor: pointer diff --git a/assets/stylesheets/right/slider.sass b/assets/stylesheets/right/slider.sass index 7efbe825..f2868f36 100644 --- a/assets/stylesheets/right/slider.sass +++ b/assets/stylesheets/right/slider.sass @@ -1,8 +1,4 @@ -@import "_common" - -$slider-border-normal: #f2f4f9 -$slider-border-light: #999 -$slider-border-hover: #e1e2e6 +@import "_mixins/all" #slider position: absolute @@ -10,9 +6,9 @@ $slider-border-hover: #e1e2e6 top: 0 left: -10px width: 10px - border-left: 1px solid #ccc - border-bottom: 1px solid #ccc - background-color: #f2f4f9 + border-left: 1px solid $color-border-normal + border-bottom: 1px solid $color-border-normal + background-color: $color-bg-slider cursor: pointer .icon @@ -20,16 +16,16 @@ $slider-border-hover: #e1e2e6 height: 0 position: absolute top: 15px - border-color: $slider-border-normal $slider-border-normal $slider-border-normal $slider-border-light + border-color: $color-border-slider-normal $color-border-slider-normal $color-border-slider-normal $color-border-slider-light border-width: 5px 0 5px 5px border-style: solid margin-top: -5px margin-left: 3px &:hover - background: $slider-border-hover + background: $color-border-slider-hover .icon - border-color: $slider-border-hover $slider-border-hover $slider-border-hover $slider-border-light + border-color: $color-border-slider-hover $color-border-slider-hover $color-border-slider-hover $color-border-slider-light #home, #profile @@ -48,9 +44,9 @@ $slider-border-hover: #e1e2e6 width: 20px z-index: 50 .icon - border-color: $slider-border-normal $slider-border-light $slider-border-normal $slider-border-normal + border-color: $color-border-slider-normal $color-border-slider-light $color-border-slider-normal $color-border-slider-normal border-width: 5px 5px 5px 0 &:hover .icon - border-color: $slider-border-hover $slider-border-light $slider-border-hover $slider-border-hover + border-color: $color-border-slider-hover $color-border-slider-light $color-border-slider-hover $color-border-slider-hover diff --git a/assets/stylesheets/right/sponsors.sass b/assets/stylesheets/right/sponsors.sass index c5c80261..cf83e2ef 100644 --- a/assets/stylesheets/right/sponsors.sass +++ b/assets/stylesheets/right/sponsors.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #right .sponsors @@ -9,7 +9,7 @@ overflow: hidden width: 205px margin: 0 0 8px 0 - border: 1px solid #ddd + border: 1px solid $color-border-light @include border-radius(8px) list-style-type: none @@ -35,7 +35,6 @@ .silver h5 margin: 0 - font-size: 13px p margin: 0 @@ -45,13 +44,13 @@ margin-left: 0 padding-bottom: 12px a - color: #575c7c + color: $color-link-sponsor font-weight: bold text-decoration: none .hint margin: 0 0 0 2px - font-size: 10px + font-size: $font-size-tiniest text-align: left diff --git a/assets/stylesheets/stats.sass b/assets/stylesheets/stats.sass index 790ff569..0a6e72b4 100644 --- a/assets/stylesheets/stats.sass +++ b/assets/stylesheets/stats.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #repo_count_container, #build_count_container diff --git a/assets/stylesheets/status.sass b/assets/stylesheets/status.sass index 8aa92878..b95f05a7 100644 --- a/assets/stylesheets/status.sass +++ b/assets/stylesheets/status.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" #repositories li, #summary .number a, @@ -10,14 +10,14 @@ table.list .number a .green #summary .number a, table.list .green .number a background-image: inline-image('icons/status.green.png') - color: green + color: $color-text-status-passed background-repeat: no-repeat #repositories li.red, .red #summary .number a, table.list .red .number a background-image: inline-image('icons/status.red.png') - color: #c00 + color: $color-text-status-failed background-repeat: no-repeat #summary .number a, @@ -26,28 +26,26 @@ table.list .number a table.list tbody - tr.allow-failure - background-color: #BDBDBD td cursor: pointer - background-color: #fffffa + background-color: $color-bg-job tr:hover td - background-color: #ffffe1 + background-color: $color-bg-job-highlight .green td - background-color: #fafffa + background-color: $color-bg-job-passed &:hover td - background-color: #dcffdc + background-color: $color-bg-job-passed-highlight .number a - color: green + color: $color-text-status-passed .red td - background-color: #fffafa + background-color: $color-bg-job-failed &:hover td - background-color: #ffdcdc + background-color: $color-bg-job-failed-highlight .number a - color: #C00 + color: $color-text-status-failed diff --git a/assets/stylesheets/tabs.sass b/assets/stylesheets/tabs.sass index 1f0fb08a..2325788e 100644 --- a/assets/stylesheets/tabs.sass +++ b/assets/stylesheets/tabs.sass @@ -1,4 +1,4 @@ -@import "_common" +@import "_mixins/all" .tabs height: 29px @@ -8,28 +8,28 @@ display: inline-block height: 28px margin-right: 10px - background-color: #f6f6f6 - border: 1px solid #ccc + background-color: $color-bg-tab + border: 1px solid $color-border-light white-space: nowrap cursor: pointer @include border-top-radius(4px) &:hover - background-color: white + background-color: $color-bg-tab-hover .active - background-color: #fff - border-bottom-color: #fff + background-color: $color-bg-tab-active + border-bottom-color: $color-bg-tab-active h5 margin: 0 - - h5 a - display: block - padding: 0 10px - line-height: 30px - font-size: 13px + font-size: $font-size-small font-weight: normal + line-height: 30px + + a + display: block + padding: 0 10px #left .tabs diff --git a/assets/stylesheets/top.sass b/assets/stylesheets/top.sass index 0b92a0d8..29cf2989 100644 --- a/assets/stylesheets/top.sass +++ b/assets/stylesheets/top.sass @@ -1,9 +1,7 @@ -@import "_common" +@import "_mixins/all" #top - color: #ccc line-height: 40px - font-size: 13px padding-right: 30px @include background(linear-gradient(#444, #111)) @@ -19,67 +17,66 @@ list-style-type: none a - color: #ccc + color: $color-link-top text-decoration: none -#home:not(.maximized) - #top - padding-right: 140px - -#navigation li display: inline-block &.active - background-color: black + background-color: $color-bg-link-top a - color: white + color: $color-link-top-highlight a display: block padding: 0 15px &:hover - color: white + color: $color-link-top-highlight - li.profile - position: relative - float: right + &.profile + position: relative + float: right - img - position: absolute - top: 7px - left: 15px - width: 24px - height: 24px - @include border-radius(3px) + img + position: absolute + top: 7px + left: 15px + width: 24px + height: 24px + @include border-radius(3px) - & > a - padding: 0 15px 0 54px + & > a + padding: 0 15px 0 54px - &:hover > ul - display: block - - ul - display: none - position: absolute - z-index: 300 - top: 40px - width: 100% - background-color: #444 - @include border-bottom-radius(6px) - @include single-box-shadow(rgba(black, 0.3), 2px, 2px, 10px) - - li + &:hover > ul display: block - li:last-child a:hover - @include border-bottom-radius(4px) + ul + display: none + position: absolute + z-index: 300 + top: 40px + width: 100% + background-color: $color-bg-dropdown + @include border-bottom-radius(6px) + @include single-box-shadow(rgba(black, 0.3), 2px, 2px, 10px) - a - display: block - padding: 5px 0 5px 54px - line-height: 24px - white-space: nowrap - &:hover - background-color: #555 + li + display: block + + li:last-child a:hover + @include border-bottom-radius(4px) + + a + display: block + padding: 5px 0 5px 54px + line-height: 24px + white-space: nowrap + &:hover + background-color: $color-bg-dropdown-highlight + +#home:not(.maximized) + #top + padding-right: 140px diff --git a/assets/stylesheets/vendor/facebox.css b/assets/stylesheets/vendor/facebox.css deleted file mode 100644 index 3e2257aa..00000000 --- a/assets/stylesheets/vendor/facebox.css +++ /dev/null @@ -1,81 +0,0 @@ -#facebox { - position: absolute; - top: 0; - left: 0; - z-index: 100; - text-align: left; -} - - -#facebox .popup{ - position:relative; - border:3px solid rgba(0,0,0,0); - -webkit-border-radius:5px; - -moz-border-radius:5px; - border-radius:5px; - -webkit-box-shadow:0 0 18px rgba(0,0,0,0.4); - -moz-box-shadow:0 0 18px rgba(0,0,0,0.4); - box-shadow:0 0 18px rgba(0,0,0,0.4); -} - -#facebox .content { - display:table; - width: 370px; - padding: 10px; - background: #fff; - -webkit-border-radius:4px; - -moz-border-radius:4px; - border-radius:4px; -} - -#facebox .content > p:first-child{ - margin-top:0; -} -#facebox .content > p:last-child{ - margin-bottom:0; -} - -#facebox .close{ - position:absolute; - top:5px; - right:5px; - padding:2px; - background:#fff; -} -#facebox .close img{ - opacity:0.3; -} -#facebox .close:hover img{ - opacity:1.0; -} - -#facebox .loading { - text-align: center; -} - -#facebox .image { - text-align: center; -} - -#facebox img { - border: 0; - margin: 0; -} - -#facebox_overlay { - position: fixed; - top: 0px; - left: 0px; - height:100%; - width:100%; -} - -.facebox_hide { - z-index:-100; -} - -.facebox_overlayBG { - background-color: #000; - z-index: 99; -} - diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 6ae003bc..36fc7197 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(\"{{#if builds.isLoaded}}\\n \\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{{else}}\\n
    Loading
    \\n{{/if}}\\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
    \\n    \\n    \\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/accounts']=Ember.Handlebars.compile(\"
    \\n
    \\n\\n\\n\\n
    \\n {{#collection Travis.AccountsListView contentBinding=\\\"controller\\\"}}\\n {{view.name}}\\n

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

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

    {{account.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.isLoaded}}\\n {{#if user.isSyncing}}\\n

    \\n Please wait while we sync from GitHub\\n

    \\n {{else}}\\n

    \\n Last synchronized from GitHub: {{formatTime user.syncedAt}}\\n \\n

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

      {{hook.description}}

      \\n\\n
      \\n \\n \\n
      \\n
    • \\n {{else}}\\n
    • \\n You do not seem to have any repositories that we could sync.\\n
    • \\n {{/each}}\\n
    \\n {{/if}}\\n{{else}}\\n

    \\n Loading\\n

    \\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(\"
      \\n{{#each queue in controller}}\\n
    • \\n

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

      \\n \\n
    • \\n{{/each}}\\n
    \\n\");Ember.TEMPLATES['repos/list']=Ember.Handlebars.compile(\"
    \\n {{view Ember.TextField valueBinding=\\\"controller.search\\\"}}\\n
    \\n\\n{{view Travis.ReposListTabsView}}\\n\\n\\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\\n \\n\\n {{#if description}}\\n
    \\n

    {{description}}

    \\n
    \\n {{/if}}\\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 {{view Travis.RepoShowToolsView}}\\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\");Ember.TEMPLATES['repos/show/tools']=Ember.Handlebars.compile(\"
    \\n \\n
    \\n

    \\n \\n {{#if view.branches.isLoaded}}\\n {{view Ember.Select contentBinding=\\\"view.branches\\\" selectionBinding=\\\"view.branch\\\" optionLabelPath=\\\"content.commit.branch\\\" optionValuePath=\\\"content.commit.branch\\\"}}\\n {{else}}\\n \\n {{/if}}\\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(\"{{#view Travis.WorkersView}}\\n

    \\n {{t workers}}\\n \\n

    \\n
      \\n {{#each group in controller.groups}}\\n {{#view Travis.WorkersListView}}\\n
    • \\n
      \\n {{group.firstObject.host}}\\n
      \\n
        \\n {{#each worker in group}}\\n {{#view Travis.WorkersItemView workerBinding=\\\"worker\\\"}}\\n
      • \\n
        \\n {{#if worker.isWorking}}\\n \\n {{view.display}}\\n \\n {{else}}\\n {{view.display}}\\n {{/if}}\\n
      • \\n {{/view}}\\n {{/each}}\\n
      \\n
    • \\n {{/view}}\\n {{else}}\\n No workers\\n {{/each}}\\n
    \\n{{/view}}\\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('tailing');\nminispade.require('templates');\nminispade.require('views');\nminispade.require('config/locales');\nminispade.require('data/sponsors');\nminispade.require('travis/auth');\n\n Travis.reopen({\n App: Em.Application.extend({\n USER_PAYLOAD: {\n user: {\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 repo_count: 2,\n synced_at: '2012-09-15T20:53:14Z'\n },\n accounts: [\n {\n login: 'travis-ci',\n name: 'Travis CI',\n type: 'org',\n repoCounts: 1\n }\n ]\n },\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 this.tailing = new Travis.Tailing();\n return this.setCurrentUser(JSON.parse($.cookie('user')));\n },\n signIn: function() {\n var user;\n user = Travis.Auth.signIn();\n return console.log(user);\n },\n signOut: function() {\n return this.setCurrentUser();\n },\n setCurrentUser: function(data) {\n if (typeof data === 'string') {\n data = JSON.parse(data);\n }\n $.cookie('user', JSON.stringify(data));\n if (data) {\n this.store.load(Travis.User, data.user);\n this.store.loadMany(Travis.Account, data.accounts);\n }\n return this.set('currentUser', data ? Travis.User.find(data.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/accounts');\nminispade.require('controllers/auth');\nminispade.require('controllers/builds');\nminispade.require('controllers/home');\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/accounts', "(function() {(function() {\n\n Travis.AccountsController = 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.app.get('currentUser.accounts'));\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=controllers/accounts");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/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', 'accounts');\n this.connectTop();\n this.connectOutlet({\n outletName: 'left',\n controller: this.accountsController,\n viewClass: Travis.AccountsView\n });\n this.connectOutlet({\n outletName: 'main',\n controller: this,\n viewClass: Travis.ProfileView\n });\n return this.accounts = this.accountsController.get('content');\n },\n account: (function() {\n var login;\n login = this.get('params.login') || Travis.app.get('currentUser.login');\n return this.accounts.toArray().filter(function(account) {\n if (account.get('login') === login) {\n return account;\n }\n })[0];\n }).property('accounts.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 owner_name: 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.app.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 repositoryObserver: (function() {\n var repository;\n repository = this.get('repository');\n if (repository) {\n return repository.select();\n }\n }).observes('repository.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 account: 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/account');\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/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/account', "(function() {(function() {\nminispade.require('travis/model');\n\n this.Travis.Account = 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/account");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 startedAt: DS.attr('string'),\n finishedAt: 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 updateTimes: 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 name: DS.attr('string'),\n ownerName: DS.attr('string'),\n description: DS.attr('string'),\n active: DS.attr('boolean'),\n account: (function() {\n return this.get('slug').split('/')[0];\n }).property('slug'),\n slug: (function() {\n return \"\" + (this.get('ownerName')) + \"/\" + (this.get('name'));\n }).property('ownerName', 'name'),\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 isQueued: (function() {\n return console.log(this.get('state'));\n }).property('state'),\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 var queued;\n queued = ['created', 'queued'].indexOf(job.get('state')) !== -1;\n return queued && job.get('queue') === (\"builds.\" + 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/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 return Travis.Build.byRepositoryId(this.get('id'), {\n event_type: 'push'\n });\n }).property(),\n pullRequests: (function() {\n return Travis.Build.byRepositoryId(this.get('id'), {\n event_type: '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('lastBuildId'));\n }\n }).property('lastBuildFinishedAt', 'lastBuildId'),\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(this.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_name: 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 var repo;\n repo = $.select(this.find().toArray(), function(repo) {\n return repo.get('slug') === slug;\n });\n if (repo.length > 0) {\n return repo;\n } else {\n return this.find({\n slug: slug\n });\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 isSyncing: DS.attr('boolean'),\n syncedAt: DS.attr('string'),\n repoCount: DS.attr('number'),\n init: function() {\n if (this.get('isSyncing')) {\n this.poll();\n }\n return this._super();\n },\n urlGithub: (function() {\n return \"https://github.com/\" + (this.get('login'));\n }).property(),\n updateLocale: function(locale) {\n this.set('locale', locale);\n return Travis.app.store.commit();\n },\n type: (function() {\n return 'user';\n }).property(),\n accounts: (function() {\n return [this].concat(Travis.Account.filter().toArray());\n }).property(),\n sync: function() {\n $.post('/api/profile/sync');\n this.set('isSyncing', true);\n return this.poll();\n },\n poll: function() {\n return $.get('/api/profile', (function(data) {\n if (data.user.is_syncing) {\n return Ember.run.later(this, this.poll.bind(this), 3000);\n } else if (this.get('isSyncing')) {\n Travis.app.store.load(Travis.User, data.user);\n return Travis.app.store.loadMany(Travis.Account, data.accounts);\n }\n }).bind(this));\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 isWorking: (function() {\n return this.get('state') === 'working';\n }).property('state'),\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 var channel, _i, _len, _ref;\n this.active_channels = [];\n if (Travis.Pusher.KEY) {\n this.pusher = new Pusher(Travis.Pusher.KEY);\n _ref = Travis.Pusher.CHANNELS;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n channel = _ref[_i];\n this.subscribe(channel);\n }\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 Ember.run.next(function() {\n return Travis.app.store.receive(event, data);\n });\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).closest('a')[0].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 account: Travis.Account,\n accounts: Travis.Account,\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('tailing', "(function() {(function() {\n\n this.Travis.Tailing = function() {\n $(window).scroll(this.positionButton.bind(this));\n return this;\n };\n\n $.extend(Travis.Tailing.prototype, {\n options: {\n timeout: 200\n },\n run: function() {\n this.autoScroll();\n if (this.active()) {\n return Ember.run.later(this.run.bind(this), this.options.timeout);\n }\n },\n toggle: function(event) {\n if (this.active()) {\n return this.stop();\n } else {\n return this.start();\n }\n },\n active: function() {\n return $('#tail').hasClass('active');\n },\n start: function() {\n $('#tail').addClass('active');\n return this.run();\n },\n stop: function() {\n return $('#tail').removeClass('active');\n },\n autoScroll: function() {\n var log, logBottom, win, winBottom;\n if (!this.active()) {\n return;\n }\n win = $(window);\n log = $('#log');\n logBottom = log.offset().top + log.outerHeight() + 40;\n winBottom = win.scrollTop() + win.height();\n if (logBottom - winBottom > 0) {\n return win.scrollTop(logBottom - win.height());\n }\n },\n positionButton: function() {\n var max, offset, tail;\n tail = $('#tail');\n if (tail.length === 0) {\n return;\n }\n offset = $(window).scrollTop() - $('#log').offset().top;\n max = $('#log').height() - $('#tail').height() + 5;\n if (offset > max) {\n offset = max;\n }\n if (offset > 0) {\n return tail.css({\n top: offset - 2\n });\n } else {\n return tail.css({\n top: 0\n });\n }\n }\n });\n\n}).call(this);\n\n})();\n//@ sourceURL=tailing");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 toggleTailing: function(event) {\n Travis.app.tailing.toggle();\n return event.preventDefault();\n },\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 (Travis.app.get('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 AccountsView: Travis.View.extend({\n tabBinding: 'controller.tab',\n templateName: 'profile/accounts',\n classAccounts: (function() {\n if (this.get('tab') === 'accounts') {\n return 'active';\n }\n }).property('tab')\n }),\n AccountsListView: Em.CollectionView.extend({\n elementId: 'accounts',\n accountBinding: 'content',\n tagName: 'ul',\n emptyView: Ember.View.extend({\n template: Ember.Handlebars.compile('
    Loading
    ')\n }),\n itemViewClass: Travis.View.extend({\n accountBinding: 'content',\n typeBinding: 'content.type',\n selectedBinding: 'account.selected',\n classNames: ['account'],\n classNameBindings: ['type', 'selected'],\n name: (function() {\n return this.get('content.name') || this.get('content.login');\n }).property('content.login', 'content.name'),\n urlAccount: (function() {\n return Travis.Urls.account(this.get('account.login'));\n }).property('account.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.account.login') === this.get('controller.user.login');\n }).property('controller.account.login', 'controller.user.login')\n }),\n HooksView: Travis.View.extend({\n templateName: 'profile/tabs/hooks',\n userBinding: 'controller.user',\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: 'Čeština'\n }, {\n key: 'es',\n name: 'Español'\n }, {\n key: 'fr',\n name: 'Français'\n }, {\n key: 'ja',\n name: '日本語'\n }, {\n key: 'nl',\n name: 'Nederlands'\n }, {\n key: 'nb',\n name: 'Norsk Bokmål'\n }, {\n key: 'pl',\n name: 'Polski'\n }, {\n key: {\n 'pt-BR': {\n name: 'Português brasileiro'\n }\n }\n }, {\n key: 'ru',\n name: 'Русский'\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 toggleInfo: function(event) {\n return $('#repositories').toggleClass('open');\n }\n }),\n RepositoriesListView: Em.CollectionView.extend({\n elementId: 'repositories',\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 (Travis.app.get('currentUser')) {\n classes.push('display');\n }\n return classes.join(' ');\n }).property('tab', 'Travis.app.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 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 }),\n RepoShowToolsView: Travis.View.extend({\n templateName: 'repos/show/tools',\n repositoryBinding: 'controller.repository',\n buildBinding: 'controller.build',\n jobBinding: 'controller.job',\n tabBinding: 'controller.tab',\n toggle: function() {\n this.set('active', !this.get('active'));\n return $('#tools .pane').toggle();\n },\n branches: (function() {\n if (this.get('active')) {\n return this.get('repository.branches');\n }\n }).property('active', 'repository.branches'),\n urlRepository: (function() {\n return 'https://' + location.host + Travis.Urls.repository(this.get('repository.slug'));\n }).property('repository.slug'),\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 toggleWorkers: function(event) {\n var handle;\n handle = $(event.target).toggleClass('open');\n if (handle.hasClass('open')) {\n return $('#workers li').addClass('open');\n } else {\n return $('#workers li').removeClass('open');\n }\n }\n }),\n WorkersListView: Travis.View.extend({\n toggle: function(event) {\n return $(event.target).closest('li').toggleClass('open');\n }\n }),\n WorkersItemView: Travis.View.extend({\n display: (function() {\n var name, number, payload, repo, state;\n name = (this.get('worker.name') || '').replace('travis-', '');\n state = this.get('worker.state');\n payload = this.get('worker.payload');\n if (state === 'working' && payload !== void 0) {\n repo = payload.repository.slug;\n number = ' #' + payload.build.number;\n return (\"\" + name + \": \" + repo + \" \" + number).htmlSafe();\n } else {\n return \"\" + name + \": \" + state;\n }\n }).property('worker.state')\n }),\n QueueItemView: Travis.View.extend({\n urlJob: (function() {\n return Travis.Urls.job(this.get('job.repository.slug'), this.get('job.id'));\n }).property('job.repository.slug', 'job.id')\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 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: '/api/stats/repos',\n total: 0,\n map: function(data) {\n return [Date.parse(data.date), this.total += parseInt(data.count)];\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: '/api/stats/tests',\n map: function(data) {\n return [Date.parse(data.date), parseInt(data.count)];\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 \"https://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ür 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 var _this = this;\n $(function() {\n return _this.iframe.appendTo('body');\n });\n return this;\n };\n\n $.extend(Travis.Auth, {\n instance: new Travis.Auth(),\n signIn: function() {\n return this.instance.signIn();\n }\n });\n\n $.extend(Travis.Auth.prototype, {\n iframe: $('