Updates spin.js
authordsc <dsc@wikimedia.org>
Fri, 6 Apr 2012 14:54:42 +0000 (07:54 -0700)
committerdsc <dsc@wikimedia.org>
Fri, 6 Apr 2012 14:54:42 +0000 (07:54 -0700)
13 files changed:
static/vendor/jquery.spin.js [changed from file to symlink]
static/vendor/jquery.spin.min.js [changed from file to symlink]
static/vendor/spin [new symlink]
static/vendor/spin-1.2.0/jquery.spin.js [new file with mode: 0644]
static/vendor/spin-1.2.0/jquery.spin.min.js [new file with mode: 0644]
static/vendor/spin-1.2.0/spin.js [new file with mode: 0644]
static/vendor/spin-1.2.0/spin.min.js [new file with mode: 0644]
static/vendor/spin-1.2.5/jquery.spin.js [new file with mode: 0644]
static/vendor/spin-1.2.5/jquery.spin.min.js [new file with mode: 0644]
static/vendor/spin-1.2.5/spin.js [new file with mode: 0644]
static/vendor/spin-1.2.5/spin.min.js [new file with mode: 0644]
static/vendor/spin.js [changed from file to symlink]
static/vendor/spin.min.js [changed from file to symlink]

deleted file mode 100644 (file)
index 3bd63b7a1c0c446fcb048591c9103c42740d64c4..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,303 +0,0 @@
-//fgnass.github.com/spin.js#v1.2
-(function(window, document, undefined) {
-
-/**
- * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
- * Licensed under the MIT license
- */
-
-  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
-      animations = {}, /* Animation rules keyed by their name */
-      useCssAnimations;
-
-  /**
-   * Utility function to create elements. If no tag name is given,
-   * a DIV is created. Optionally properties can be passed.
-   */
-  function createEl(tag, prop) {
-    var el = document.createElement(tag || 'div'),
-        n;
-
-    for(n in prop) {
-      el[n] = prop[n];
-    }
-    return el;
-  }
-
-  /**
-   * Inserts child1 before child2. If child2 is not specified,
-   * child1 is appended. If child2 has no parentNode, child2 is
-   * appended first.
-   */
-  function ins(parent, child1, child2) {
-    if(child2 && !child2.parentNode) ins(parent, child2);
-    parent.insertBefore(child1, child2||null);
-    return parent;
-  }
-
-  /**
-   * Insert a new stylesheet to hold the @keyframe or VML rules.
-   */
-  ins(document.getElementsByTagName('head')[0], createEl('style'));
-  var sheet = document.styleSheets[document.styleSheets.length-1];
-
-  /**
-   * Creates an opacity keyframe animation rule and returns its name.
-   * Since most mobile Webkits have timing issues with animation-delay,
-   * we create separate rules for each line/segment.
-   */
-  function addAnimation(alpha, trail, i, lines) {
-    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
-        start = 0.01 + i/lines*100,
-        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
-        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
-        pre = prefix && '-'+prefix+'-' || '';
-
-    if (!animations[name]) {
-      sheet.insertRule(
-        '@' + pre + 'keyframes ' + name + '{' +
-        '0%{opacity:'+z+'}' +
-        start + '%{opacity:'+ alpha + '}' +
-        (start+0.01) + '%{opacity:1}' +
-        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
-        '100%{opacity:'+ z + '}' +
-        '}', 0);
-      animations[name] = 1;
-    }
-    return name;
-  }
-
-  /**
-   * Tries various vendor prefixes and returns the first supported property.
-   **/
-  function vendor(el, prop) {
-    var s = el.style,
-        pp,
-        i;
-
-    if(s[prop] !== undefined) return prop;
-    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
-    for(i=0; i<prefixes.length; i++) {
-      pp = prefixes[i]+prop;
-      if(s[pp] !== undefined) return pp;
-    }
-  }
-
-  /**
-   * Sets multiple style properties at once.
-   */
-  function css(el, prop) {
-    for (var n in prop) {
-      el.style[vendor(el, n)||n] = prop[n];
-    }
-    return el;
-  }
-
-  /**
-   * Fills in default values.
-   */
-  function defaults(obj, def) {
-    for (var n in def) {
-      if (obj[n] === undefined) obj[n] = def[n];
-    }
-    return obj;
-  }
-
-  /**
-   * Returns the absolute page-offset of the given element.
-   */
-  function pos(el) {
-    var o = {x:el.offsetLeft, y:el.offsetTop};
-    while((el = el.offsetParent)) {
-      o.x+=el.offsetLeft;
-      o.y+=el.offsetTop;
-    }
-    return o;
-  }
-
-  /** The constructor */
-  var Spinner = function Spinner(o) {
-    if (!this.spin) return new Spinner(o);
-    this.opts = defaults(o || {}, {
-      lines: 12, // The number of lines to draw
-      length: 7, // The length of each line
-      width: 5, // The line thickness
-      radius: 10, // The radius of the inner circle
-      color: '#000', // #rgb or #rrggbb
-      speed: 1, // Rounds per second
-      trail: 100, // Afterglow percentage
-      opacity: 1/4,
-      fps: 20
-    });
-  },
-  proto = Spinner.prototype = {
-    spin: function(target) {
-      this.stop();
-      var self = this,
-          el = self.el = css(createEl(), {position: 'relative'}),
-          ep, // element position
-          tp; // target position
-
-      if (target) {
-        tp = pos(ins(target, el, target.firstChild));
-        ep = pos(el);
-        css(el, {
-          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
-          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
-        });
-      }
-      el.setAttribute('aria-role', 'progressbar');
-      self.lines(el, self.opts);
-      if (!useCssAnimations) {
-        // No CSS animation support, use setTimeout() instead
-        var o = self.opts,
-            i = 0,
-            fps = o.fps,
-            f = fps/o.speed,
-            ostep = (1-o.opacity)/(f*o.trail / 100),
-            astep = f/o.lines;
-
-        (function anim() {
-          i++;
-          for (var s=o.lines; s; s--) {
-            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
-            self.opacity(el, o.lines-s, alpha, o);
-          }
-          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
-        })();
-      }
-      return self;
-    },
-    stop: function() {
-      var el = this.el;
-      if (el) {
-        clearTimeout(this.timeout);
-        if (el.parentNode) el.parentNode.removeChild(el);
-        this.el = undefined;
-      }
-      return this;
-    }
-  };
-  proto.lines = function(el, o) {
-    var i = 0,
-        seg;
-
-    function fill(color, shadow) {
-      return css(createEl(), {
-        position: 'absolute',
-        width: (o.length+o.width) + 'px',
-        height: o.width + 'px',
-        background: color,
-        boxShadow: shadow,
-        transformOrigin: 'left',
-        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
-        borderRadius: (o.width>>1) + 'px'
-      });
-    }
-    for (; i < o.lines; i++) {
-      seg = css(createEl(), {
-        position: 'absolute',
-        top: 1+~(o.width/2) + 'px',
-        transform: 'translate3d(0,0,0)',
-        opacity: o.opacity,
-        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
-      });
-      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
-      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
-    }
-    return el;
-  };
-  proto.opacity = function(el, i, val) {
-    el.childNodes[i].style.opacity = val;
-  };
-
-  /////////////////////////////////////////////////////////////////////////
-  // VML rendering for IE
-  /////////////////////////////////////////////////////////////////////////
-
-  /** 
-   * Check and init VML support
-   */
-  (function() {
-    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
-        i;
-
-    if (!vendor(s, 'transform') && s.adj) {
-
-      // VML support detected. Insert CSS rules ...
-      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
-
-      proto.lines = function(el, o) {
-        var r = o.length+o.width,
-            s = 2*r;
-
-        function grp() {
-          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
-        }
-
-        var g = grp(),
-            margin = ~(o.length+o.radius+o.width)+'px',
-            i;
-
-        function seg(i, dx, filter) {
-          ins(g,
-            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
-              ins(css(createEl('roundrect', {arcsize: 1}), {
-                  width: r,
-                  height: o.width,
-                  left: o.radius,
-                  top: -o.width>>1,
-                  filter: filter
-                }),
-                createEl('fill', {color: o.color, opacity: o.opacity}),
-                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
-              )
-            )
-          );
-        }
-
-        if (o.shadow) {
-          for (i = 1; i <= o.lines; i++) {
-            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
-          }
-        }
-        for (i = 1; i <= o.lines; i++) {
-          seg(i);
-        }
-        return ins(css(el, {
-          margin: margin + ' 0 0 ' + margin,
-          zoom: 1
-        }), g);
-      };
-      proto.opacity = function(el, i, val, o) {
-        o = o.shadow && o.lines || 0;
-        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
-      };
-    }
-    else {
-      useCssAnimations = vendor(s, 'animation');
-    }
-  })();
-
-  window.Spinner = Spinner;
-
-})(window, document);
-
-$.fn.spin = function(opts){
-    this.each(function(){
-        var el   = $(this)
-        ,   data = el.data()
-        ;
-        
-        if (data.spinner) {
-            data.spinner.stop();
-            delete data.spinner;
-        }
-        
-        if (!opts) return;
-        
-        opts = $.extend( {'color': el.css('color')}, opts );
-        data.spinner = new Spinner(opts).spin(this);
-    });
-    return this;
-};
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..db305ca88a742cfb20af5b80450e84fd77dd84df
--- /dev/null
@@ -0,0 +1 @@
+spin/jquery.spin.js
\ No newline at end of file
deleted file mode 100644 (file)
index 8264b4c5bd3fc237388a78f95e6da57a0c8b84b8..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,2 +0,0 @@
-//fgnass.github.com/spin.js#v1.2
-(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25,fps:20})},p=o.prototype={spin:function(a){this.stop();var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),c.setAttribute("aria-role","progressbar"),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=i.fps,m=k/i.speed,o=(1-i.opacity)/(m*i.trail/100),p=m/i.lines;(function q(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*p)%m*o,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))})()}return b},stop:function(){var a=this.el;a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c);return this}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i,zoom:1}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document),$.fn.spin=function(a){this.each(function(){var b=$(this),c=b.data();c.spinner&&(c.spinner.stop(),delete c.spinner);!a||(a=$.extend({color:b.css("color")},a),c.spinner=(new Spinner(a)).spin(this))});return this}
\ No newline at end of file
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..c5d6421ebfdf2616d0549a9cc46fd9005427bc32
--- /dev/null
@@ -0,0 +1 @@
+spin/jquery.spin.min.js
\ No newline at end of file
diff --git a/static/vendor/spin b/static/vendor/spin
new file mode 120000 (symlink)
index 0000000..1f89cad
--- /dev/null
@@ -0,0 +1 @@
+spin-1.2.5
\ No newline at end of file
diff --git a/static/vendor/spin-1.2.0/jquery.spin.js b/static/vendor/spin-1.2.0/jquery.spin.js
new file mode 100644 (file)
index 0000000..3bd63b7
--- /dev/null
@@ -0,0 +1,303 @@
+//fgnass.github.com/spin.js#v1.2
+(function(window, document, undefined) {
+
+/**
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Licensed under the MIT license
+ */
+
+  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
+      animations = {}, /* Animation rules keyed by their name */
+      useCssAnimations;
+
+  /**
+   * Utility function to create elements. If no tag name is given,
+   * a DIV is created. Optionally properties can be passed.
+   */
+  function createEl(tag, prop) {
+    var el = document.createElement(tag || 'div'),
+        n;
+
+    for(n in prop) {
+      el[n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Inserts child1 before child2. If child2 is not specified,
+   * child1 is appended. If child2 has no parentNode, child2 is
+   * appended first.
+   */
+  function ins(parent, child1, child2) {
+    if(child2 && !child2.parentNode) ins(parent, child2);
+    parent.insertBefore(child1, child2||null);
+    return parent;
+  }
+
+  /**
+   * Insert a new stylesheet to hold the @keyframe or VML rules.
+   */
+  ins(document.getElementsByTagName('head')[0], createEl('style'));
+  var sheet = document.styleSheets[document.styleSheets.length-1];
+
+  /**
+   * Creates an opacity keyframe animation rule and returns its name.
+   * Since most mobile Webkits have timing issues with animation-delay,
+   * we create separate rules for each line/segment.
+   */
+  function addAnimation(alpha, trail, i, lines) {
+    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
+        start = 0.01 + i/lines*100,
+        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
+        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
+        pre = prefix && '-'+prefix+'-' || '';
+
+    if (!animations[name]) {
+      sheet.insertRule(
+        '@' + pre + 'keyframes ' + name + '{' +
+        '0%{opacity:'+z+'}' +
+        start + '%{opacity:'+ alpha + '}' +
+        (start+0.01) + '%{opacity:1}' +
+        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
+        '100%{opacity:'+ z + '}' +
+        '}', 0);
+      animations[name] = 1;
+    }
+    return name;
+  }
+
+  /**
+   * Tries various vendor prefixes and returns the first supported property.
+   **/
+  function vendor(el, prop) {
+    var s = el.style,
+        pp,
+        i;
+
+    if(s[prop] !== undefined) return prop;
+    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
+    for(i=0; i<prefixes.length; i++) {
+      pp = prefixes[i]+prop;
+      if(s[pp] !== undefined) return pp;
+    }
+  }
+
+  /**
+   * Sets multiple style properties at once.
+   */
+  function css(el, prop) {
+    for (var n in prop) {
+      el.style[vendor(el, n)||n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Fills in default values.
+   */
+  function defaults(obj, def) {
+    for (var n in def) {
+      if (obj[n] === undefined) obj[n] = def[n];
+    }
+    return obj;
+  }
+
+  /**
+   * Returns the absolute page-offset of the given element.
+   */
+  function pos(el) {
+    var o = {x:el.offsetLeft, y:el.offsetTop};
+    while((el = el.offsetParent)) {
+      o.x+=el.offsetLeft;
+      o.y+=el.offsetTop;
+    }
+    return o;
+  }
+
+  /** The constructor */
+  var Spinner = function Spinner(o) {
+    if (!this.spin) return new Spinner(o);
+    this.opts = defaults(o || {}, {
+      lines: 12, // The number of lines to draw
+      length: 7, // The length of each line
+      width: 5, // The line thickness
+      radius: 10, // The radius of the inner circle
+      color: '#000', // #rgb or #rrggbb
+      speed: 1, // Rounds per second
+      trail: 100, // Afterglow percentage
+      opacity: 1/4,
+      fps: 20
+    });
+  },
+  proto = Spinner.prototype = {
+    spin: function(target) {
+      this.stop();
+      var self = this,
+          el = self.el = css(createEl(), {position: 'relative'}),
+          ep, // element position
+          tp; // target position
+
+      if (target) {
+        tp = pos(ins(target, el, target.firstChild));
+        ep = pos(el);
+        css(el, {
+          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
+          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
+        });
+      }
+      el.setAttribute('aria-role', 'progressbar');
+      self.lines(el, self.opts);
+      if (!useCssAnimations) {
+        // No CSS animation support, use setTimeout() instead
+        var o = self.opts,
+            i = 0,
+            fps = o.fps,
+            f = fps/o.speed,
+            ostep = (1-o.opacity)/(f*o.trail / 100),
+            astep = f/o.lines;
+
+        (function anim() {
+          i++;
+          for (var s=o.lines; s; s--) {
+            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
+            self.opacity(el, o.lines-s, alpha, o);
+          }
+          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
+        })();
+      }
+      return self;
+    },
+    stop: function() {
+      var el = this.el;
+      if (el) {
+        clearTimeout(this.timeout);
+        if (el.parentNode) el.parentNode.removeChild(el);
+        this.el = undefined;
+      }
+      return this;
+    }
+  };
+  proto.lines = function(el, o) {
+    var i = 0,
+        seg;
+
+    function fill(color, shadow) {
+      return css(createEl(), {
+        position: 'absolute',
+        width: (o.length+o.width) + 'px',
+        height: o.width + 'px',
+        background: color,
+        boxShadow: shadow,
+        transformOrigin: 'left',
+        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
+        borderRadius: (o.width>>1) + 'px'
+      });
+    }
+    for (; i < o.lines; i++) {
+      seg = css(createEl(), {
+        position: 'absolute',
+        top: 1+~(o.width/2) + 'px',
+        transform: 'translate3d(0,0,0)',
+        opacity: o.opacity,
+        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+      });
+      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
+      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
+    }
+    return el;
+  };
+  proto.opacity = function(el, i, val) {
+    el.childNodes[i].style.opacity = val;
+  };
+
+  /////////////////////////////////////////////////////////////////////////
+  // VML rendering for IE
+  /////////////////////////////////////////////////////////////////////////
+
+  /** 
+   * Check and init VML support
+   */
+  (function() {
+    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
+        i;
+
+    if (!vendor(s, 'transform') && s.adj) {
+
+      // VML support detected. Insert CSS rules ...
+      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
+
+      proto.lines = function(el, o) {
+        var r = o.length+o.width,
+            s = 2*r;
+
+        function grp() {
+          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
+        }
+
+        var g = grp(),
+            margin = ~(o.length+o.radius+o.width)+'px',
+            i;
+
+        function seg(i, dx, filter) {
+          ins(g,
+            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+              ins(css(createEl('roundrect', {arcsize: 1}), {
+                  width: r,
+                  height: o.width,
+                  left: o.radius,
+                  top: -o.width>>1,
+                  filter: filter
+                }),
+                createEl('fill', {color: o.color, opacity: o.opacity}),
+                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+              )
+            )
+          );
+        }
+
+        if (o.shadow) {
+          for (i = 1; i <= o.lines; i++) {
+            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
+          }
+        }
+        for (i = 1; i <= o.lines; i++) {
+          seg(i);
+        }
+        return ins(css(el, {
+          margin: margin + ' 0 0 ' + margin,
+          zoom: 1
+        }), g);
+      };
+      proto.opacity = function(el, i, val, o) {
+        o = o.shadow && o.lines || 0;
+        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
+      };
+    }
+    else {
+      useCssAnimations = vendor(s, 'animation');
+    }
+  })();
+
+  window.Spinner = Spinner;
+
+})(window, document);
+
+$.fn.spin = function(opts){
+    this.each(function(){
+        var el   = $(this)
+        ,   data = el.data()
+        ;
+        
+        if (data.spinner) {
+            data.spinner.stop();
+            delete data.spinner;
+        }
+        
+        if (!opts) return;
+        
+        opts = $.extend( {'color': el.css('color')}, opts );
+        data.spinner = new Spinner(opts).spin(this);
+    });
+    return this;
+};
diff --git a/static/vendor/spin-1.2.0/jquery.spin.min.js b/static/vendor/spin-1.2.0/jquery.spin.min.js
new file mode 100644 (file)
index 0000000..8264b4c
--- /dev/null
@@ -0,0 +1,2 @@
+//fgnass.github.com/spin.js#v1.2
+(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25,fps:20})},p=o.prototype={spin:function(a){this.stop();var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),c.setAttribute("aria-role","progressbar"),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=i.fps,m=k/i.speed,o=(1-i.opacity)/(m*i.trail/100),p=m/i.lines;(function q(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*p)%m*o,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))})()}return b},stop:function(){var a=this.el;a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c);return this}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i,zoom:1}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document),$.fn.spin=function(a){this.each(function(){var b=$(this),c=b.data();c.spinner&&(c.spinner.stop(),delete c.spinner);!a||(a=$.extend({color:b.css("color")},a),c.spinner=(new Spinner(a)).spin(this))});return this}
\ No newline at end of file
diff --git a/static/vendor/spin-1.2.0/spin.js b/static/vendor/spin-1.2.0/spin.js
new file mode 100644 (file)
index 0000000..7152f2b
--- /dev/null
@@ -0,0 +1,284 @@
+//fgnass.github.com/spin.js#v1.2
+(function(window, document, undefined) {
+
+/**
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Licensed under the MIT license
+ */
+
+  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
+      animations = {}, /* Animation rules keyed by their name */
+      useCssAnimations;
+
+  /**
+   * Utility function to create elements. If no tag name is given,
+   * a DIV is created. Optionally properties can be passed.
+   */
+  function createEl(tag, prop) {
+    var el = document.createElement(tag || 'div'),
+        n;
+
+    for(n in prop) {
+      el[n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Inserts child1 before child2. If child2 is not specified,
+   * child1 is appended. If child2 has no parentNode, child2 is
+   * appended first.
+   */
+  function ins(parent, child1, child2) {
+    if(child2 && !child2.parentNode) ins(parent, child2);
+    parent.insertBefore(child1, child2||null);
+    return parent;
+  }
+
+  /**
+   * Insert a new stylesheet to hold the @keyframe or VML rules.
+   */
+  ins(document.getElementsByTagName('head')[0], createEl('style'));
+  var sheet = document.styleSheets[document.styleSheets.length-1];
+
+  /**
+   * Creates an opacity keyframe animation rule and returns its name.
+   * Since most mobile Webkits have timing issues with animation-delay,
+   * we create separate rules for each line/segment.
+   */
+  function addAnimation(alpha, trail, i, lines) {
+    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
+        start = 0.01 + i/lines*100,
+        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
+        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
+        pre = prefix && '-'+prefix+'-' || '';
+
+    if (!animations[name]) {
+      sheet.insertRule(
+        '@' + pre + 'keyframes ' + name + '{' +
+        '0%{opacity:'+z+'}' +
+        start + '%{opacity:'+ alpha + '}' +
+        (start+0.01) + '%{opacity:1}' +
+        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
+        '100%{opacity:'+ z + '}' +
+        '}', 0);
+      animations[name] = 1;
+    }
+    return name;
+  }
+
+  /**
+   * Tries various vendor prefixes and returns the first supported property.
+   **/
+  function vendor(el, prop) {
+    var s = el.style,
+        pp,
+        i;
+
+    if(s[prop] !== undefined) return prop;
+    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
+    for(i=0; i<prefixes.length; i++) {
+      pp = prefixes[i]+prop;
+      if(s[pp] !== undefined) return pp;
+    }
+  }
+
+  /**
+   * Sets multiple style properties at once.
+   */
+  function css(el, prop) {
+    for (var n in prop) {
+      el.style[vendor(el, n)||n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Fills in default values.
+   */
+  function defaults(obj, def) {
+    for (var n in def) {
+      if (obj[n] === undefined) obj[n] = def[n];
+    }
+    return obj;
+  }
+
+  /**
+   * Returns the absolute page-offset of the given element.
+   */
+  function pos(el) {
+    var o = {x:el.offsetLeft, y:el.offsetTop};
+    while((el = el.offsetParent)) {
+      o.x+=el.offsetLeft;
+      o.y+=el.offsetTop;
+    }
+    return o;
+  }
+
+  /** The constructor */
+  var Spinner = function Spinner(o) {
+    if (!this.spin) return new Spinner(o);
+    this.opts = defaults(o || {}, {
+      lines: 12, // The number of lines to draw
+      length: 7, // The length of each line
+      width: 5, // The line thickness
+      radius: 10, // The radius of the inner circle
+      color: '#000', // #rgb or #rrggbb
+      speed: 1, // Rounds per second
+      trail: 100, // Afterglow percentage
+      opacity: 1/4,
+      fps: 20
+    });
+  },
+  proto = Spinner.prototype = {
+    spin: function(target) {
+      this.stop();
+      var self = this,
+          el = self.el = css(createEl(), {position: 'relative'}),
+          ep, // element position
+          tp; // target position
+
+      if (target) {
+        tp = pos(ins(target, el, target.firstChild));
+        ep = pos(el);
+        css(el, {
+          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
+          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
+        });
+      }
+      el.setAttribute('aria-role', 'progressbar');
+      self.lines(el, self.opts);
+      if (!useCssAnimations) {
+        // No CSS animation support, use setTimeout() instead
+        var o = self.opts,
+            i = 0,
+            fps = o.fps,
+            f = fps/o.speed,
+            ostep = (1-o.opacity)/(f*o.trail / 100),
+            astep = f/o.lines;
+
+        (function anim() {
+          i++;
+          for (var s=o.lines; s; s--) {
+            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
+            self.opacity(el, o.lines-s, alpha, o);
+          }
+          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
+        })();
+      }
+      return self;
+    },
+    stop: function() {
+      var el = this.el;
+      if (el) {
+        clearTimeout(this.timeout);
+        if (el.parentNode) el.parentNode.removeChild(el);
+        this.el = undefined;
+      }
+      return this;
+    }
+  };
+  proto.lines = function(el, o) {
+    var i = 0,
+        seg;
+
+    function fill(color, shadow) {
+      return css(createEl(), {
+        position: 'absolute',
+        width: (o.length+o.width) + 'px',
+        height: o.width + 'px',
+        background: color,
+        boxShadow: shadow,
+        transformOrigin: 'left',
+        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
+        borderRadius: (o.width>>1) + 'px'
+      });
+    }
+    for (; i < o.lines; i++) {
+      seg = css(createEl(), {
+        position: 'absolute',
+        top: 1+~(o.width/2) + 'px',
+        transform: 'translate3d(0,0,0)',
+        opacity: o.opacity,
+        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+      });
+      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
+      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
+    }
+    return el;
+  };
+  proto.opacity = function(el, i, val) {
+    el.childNodes[i].style.opacity = val;
+  };
+
+  /////////////////////////////////////////////////////////////////////////
+  // VML rendering for IE
+  /////////////////////////////////////////////////////////////////////////
+
+  /** 
+   * Check and init VML support
+   */
+  (function() {
+    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
+        i;
+
+    if (!vendor(s, 'transform') && s.adj) {
+
+      // VML support detected. Insert CSS rules ...
+      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
+
+      proto.lines = function(el, o) {
+        var r = o.length+o.width,
+            s = 2*r;
+
+        function grp() {
+          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
+        }
+
+        var g = grp(),
+            margin = ~(o.length+o.radius+o.width)+'px',
+            i;
+
+        function seg(i, dx, filter) {
+          ins(g,
+            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+              ins(css(createEl('roundrect', {arcsize: 1}), {
+                  width: r,
+                  height: o.width,
+                  left: o.radius,
+                  top: -o.width>>1,
+                  filter: filter
+                }),
+                createEl('fill', {color: o.color, opacity: o.opacity}),
+                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+              )
+            )
+          );
+        }
+
+        if (o.shadow) {
+          for (i = 1; i <= o.lines; i++) {
+            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
+          }
+        }
+        for (i = 1; i <= o.lines; i++) {
+          seg(i);
+        }
+        return ins(css(el, {
+          margin: margin + ' 0 0 ' + margin,
+          zoom: 1
+        }), g);
+      };
+      proto.opacity = function(el, i, val, o) {
+        o = o.shadow && o.lines || 0;
+        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
+      };
+    }
+    else {
+      useCssAnimations = vendor(s, 'animation');
+    }
+  })();
+
+  window.Spinner = Spinner;
+
+})(window, document);
diff --git a/static/vendor/spin-1.2.0/spin.min.js b/static/vendor/spin-1.2.0/spin.min.js
new file mode 100644 (file)
index 0000000..208b303
--- /dev/null
@@ -0,0 +1,2 @@
+//fgnass.github.com/spin.js#v1.2
+(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25,fps:20})},p=o.prototype={spin:function(a){this.stop();var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),c.setAttribute("aria-role","progressbar"),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=i.fps,m=k/i.speed,o=(1-i.opacity)/(m*i.trail/100),p=m/i.lines;(function q(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*p)%m*o,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))})()}return b},stop:function(){var a=this.el;a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c);return this}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i,zoom:1}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document)
\ No newline at end of file
diff --git a/static/vendor/spin-1.2.5/jquery.spin.js b/static/vendor/spin-1.2.5/jquery.spin.js
new file mode 100644 (file)
index 0000000..1a69583
--- /dev/null
@@ -0,0 +1,322 @@
+//fgnass.github.com/spin.js#v1.2.5
+(function(window, document, undefined) {
+
+/**
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Licensed under the MIT license
+ */
+
+  var prefixes = ['webkit', 'Moz', 'ms', 'O']; /* Vendor prefixes */
+  var animations = {}; /* Animation rules keyed by their name */
+  var useCssAnimations;
+
+  /**
+   * Utility function to create elements. If no tag name is given,
+   * a DIV is created. Optionally properties can be passed.
+   */
+  function createEl(tag, prop) {
+    var el = document.createElement(tag || 'div');
+    var n;
+
+    for(n in prop) {
+      el[n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Appends children and returns the parent.
+   */
+  function ins(parent /* child1, child2, ...*/) {
+    for (var i=1, n=arguments.length; i<n; i++) {
+      parent.appendChild(arguments[i]);
+    }
+    return parent;
+  }
+
+  /**
+   * Insert a new stylesheet to hold the @keyframe or VML rules.
+   */
+  var sheet = function() {
+    var el = createEl('style');
+    ins(document.getElementsByTagName('head')[0], el);
+    return el.sheet || el.styleSheet;
+  }();
+
+  /**
+   * Creates an opacity keyframe animation rule and returns its name.
+   * Since most mobile Webkits have timing issues with animation-delay,
+   * we create separate rules for each line/segment.
+   */
+  function addAnimation(alpha, trail, i, lines) {
+    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-');
+    var start = 0.01 + i/lines*100;
+    var z = Math.max(1-(1-alpha)/trail*(100-start) , alpha);
+    var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
+    var pre = prefix && '-'+prefix+'-' || '';
+
+    if (!animations[name]) {
+      sheet.insertRule(
+        '@' + pre + 'keyframes ' + name + '{' +
+        '0%{opacity:'+z+'}' +
+        start + '%{opacity:'+ alpha + '}' +
+        (start+0.01) + '%{opacity:1}' +
+        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
+        '100%{opacity:'+ z + '}' +
+        '}', 0);
+      animations[name] = 1;
+    }
+    return name;
+  }
+
+  /**
+   * Tries various vendor prefixes and returns the first supported property.
+   **/
+  function vendor(el, prop) {
+    var s = el.style;
+    var pp;
+    var i;
+
+    if(s[prop] !== undefined) return prop;
+    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
+    for(i=0; i<prefixes.length; i++) {
+      pp = prefixes[i]+prop;
+      if(s[pp] !== undefined) return pp;
+    }
+  }
+
+  /**
+   * Sets multiple style properties at once.
+   */
+  function css(el, prop) {
+    for (var n in prop) {
+      el.style[vendor(el, n)||n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Fills in default values.
+   */
+  function merge(obj) {
+    for (var i=1; i < arguments.length; i++) {
+      var def = arguments[i];
+      for (var n in def) {
+        if (obj[n] === undefined) obj[n] = def[n];
+      }
+    }
+    return obj;
+  }
+
+  /**
+   * Returns the absolute page-offset of the given element.
+   */
+  function pos(el) {
+    var o = {x:el.offsetLeft, y:el.offsetTop};
+    while((el = el.offsetParent)) {
+      o.x+=el.offsetLeft;
+      o.y+=el.offsetTop;
+    }
+    return o;
+  }
+
+  var defaults = {
+    lines: 12,            // The number of lines to draw
+    length: 7,            // The length of each line
+    width: 5,             // The line thickness
+    radius: 10,           // The radius of the inner circle
+    rotate: 0,            // rotation offset
+    color: '#000',        // #rgb or #rrggbb
+    speed: 1,             // Rounds per second
+    trail: 100,           // Afterglow percentage
+    opacity: 1/4,         // Opacity of the lines
+    fps: 20,              // Frames per second when using setTimeout()
+    zIndex: 2e9,          // Use a high z-index by default
+    className: 'spinner', // CSS class to assign to the element
+    top: 'auto',          // center vertically
+    left: 'auto'          // center horizontally
+  };
+
+  /** The constructor */
+  var Spinner = function Spinner(o) {
+    if (!this.spin) return new Spinner(o);
+    this.opts = merge(o || {}, Spinner.defaults, defaults);
+  };
+
+  Spinner.defaults = {};
+  merge(Spinner.prototype, {
+    spin: function(target) {
+      this.stop();
+      var self = this;
+      var o = self.opts;
+      var el = self.el = css(createEl(0, {className: o.className}), {position: 'relative', zIndex: o.zIndex});
+      var mid = o.radius+o.length+o.width;
+      var ep; // element position
+      var tp; // target position
+
+      if (target) {
+        target.insertBefore(el, target.firstChild||null);
+        tp = pos(target);
+        ep = pos(el);
+        css(el, {
+          left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : o.left+mid) + 'px',
+          top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : o.top+mid)  + 'px'
+        });
+      }
+
+      el.setAttribute('aria-role', 'progressbar');
+      self.lines(el, self.opts);
+
+      if (!useCssAnimations) {
+        // No CSS animation support, use setTimeout() instead
+        var i = 0;
+        var fps = o.fps;
+        var f = fps/o.speed;
+        var ostep = (1-o.opacity)/(f*o.trail / 100);
+        var astep = f/o.lines;
+
+        !function anim() {
+          i++;
+          for (var s=o.lines; s; s--) {
+            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
+            self.opacity(el, o.lines-s, alpha, o);
+          }
+          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
+        }();
+      }
+      return self;
+    },
+    stop: function() {
+      var el = this.el;
+      if (el) {
+        clearTimeout(this.timeout);
+        if (el.parentNode) el.parentNode.removeChild(el);
+        this.el = undefined;
+      }
+      return this;
+    },
+    lines: function(el, o) {
+      var i = 0;
+      var seg;
+
+      function fill(color, shadow) {
+        return css(createEl(), {
+          position: 'absolute',
+          width: (o.length+o.width) + 'px',
+          height: o.width + 'px',
+          background: color,
+          boxShadow: shadow,
+          transformOrigin: 'left',
+          transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
+          borderRadius: (o.width>>1) + 'px'
+        });
+      }
+      for (; i < o.lines; i++) {
+        seg = css(createEl(), {
+          position: 'absolute',
+          top: 1+~(o.width/2) + 'px',
+          transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
+          opacity: o.opacity,
+          animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+        });
+        if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
+        ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
+      }
+      return el;
+    },
+    opacity: function(el, i, val) {
+      if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
+    }
+  });
+
+  /////////////////////////////////////////////////////////////////////////
+  // VML rendering for IE
+  /////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Check and init VML support
+   */
+  !function() {
+
+    function vml(tag, attr) {
+      return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr);
+    }
+
+    var s = css(createEl('group'), {behavior: 'url(#default#VML)'});
+
+    if (!vendor(s, 'transform') && s.adj) {
+
+      // VML support detected. Insert CSS rule ...
+      sheet.addRule('.spin-vml', 'behavior:url(#default#VML)');
+
+      Spinner.prototype.lines = function(el, o) {
+        var r = o.length+o.width;
+        var s = 2*r;
+
+        function grp() {
+          return css(vml('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
+        }
+
+        var margin = -(o.width+o.length)*2+'px';
+        var g = css(grp(), {position: 'absolute', top: margin, left: margin});
+
+        var i;
+
+        function seg(i, dx, filter) {
+          ins(g,
+            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+              ins(css(vml('roundrect', {arcsize: 1}), {
+                  width: r,
+                  height: o.width,
+                  left: o.radius,
+                  top: -o.width>>1,
+                  filter: filter
+                }),
+                vml('fill', {color: o.color, opacity: o.opacity}),
+                vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+              )
+            )
+          );
+        }
+
+        if (o.shadow) {
+          for (i = 1; i <= o.lines; i++) {
+            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
+          }
+        }
+        for (i = 1; i <= o.lines; i++) seg(i);
+        return ins(el, g);
+      };
+      Spinner.prototype.opacity = function(el, i, val, o) {
+        var c = el.firstChild;
+        o = o.shadow && o.lines || 0;
+        if (c && i+o < c.childNodes.length) {
+          c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild;
+          if (c) c.opacity = val;
+        }
+      };
+    }
+    else {
+      useCssAnimations = vendor(s, 'animation');
+    }
+  }();
+
+  window.Spinner = Spinner;
+
+})(window, document);
+
+$.fn.spin = function(opts) {
+  this.each(function() {
+    var $this = $(this),
+        data = $this.data();
+    
+    if (data.spinner) {
+      data.spinner.stop();
+      delete data.spinner;
+    }
+    if (opts !== false) {
+      data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this);
+    }
+  });
+  return this;
+};
diff --git a/static/vendor/spin-1.2.5/jquery.spin.min.js b/static/vendor/spin-1.2.5/jquery.spin.min.js
new file mode 100644 (file)
index 0000000..84d352a
--- /dev/null
@@ -0,0 +1,2 @@
+//fgnass.github.com/spin.js#v1.2.5
+(function(a,b,c){function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;b<c;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1),g}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var d=["webkit","Moz","ms","O"],e={},f,i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},q.defaults,o)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width,h,i;a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:(c.left=="auto"?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,0,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p})(window,document),$.fn.spin=function(a){return this.each(function(){var b=$(this),c=b.data();c.spinner&&(c.spinner.stop(),delete c.spinner),a!==!1&&(c.spinner=(new Spinner($.extend({color:b.css("color")},a))).spin(this))}),this};
\ No newline at end of file
diff --git a/static/vendor/spin-1.2.5/spin.js b/static/vendor/spin-1.2.5/spin.js
new file mode 100644 (file)
index 0000000..32d6e42
--- /dev/null
@@ -0,0 +1,306 @@
+//fgnass.github.com/spin.js#v1.2.5
+(function(window, document, undefined) {
+
+/**
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Licensed under the MIT license
+ */
+
+  var prefixes = ['webkit', 'Moz', 'ms', 'O']; /* Vendor prefixes */
+  var animations = {}; /* Animation rules keyed by their name */
+  var useCssAnimations;
+
+  /**
+   * Utility function to create elements. If no tag name is given,
+   * a DIV is created. Optionally properties can be passed.
+   */
+  function createEl(tag, prop) {
+    var el = document.createElement(tag || 'div');
+    var n;
+
+    for(n in prop) {
+      el[n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Appends children and returns the parent.
+   */
+  function ins(parent /* child1, child2, ...*/) {
+    for (var i=1, n=arguments.length; i<n; i++) {
+      parent.appendChild(arguments[i]);
+    }
+    return parent;
+  }
+
+  /**
+   * Insert a new stylesheet to hold the @keyframe or VML rules.
+   */
+  var sheet = function() {
+    var el = createEl('style');
+    ins(document.getElementsByTagName('head')[0], el);
+    return el.sheet || el.styleSheet;
+  }();
+
+  /**
+   * Creates an opacity keyframe animation rule and returns its name.
+   * Since most mobile Webkits have timing issues with animation-delay,
+   * we create separate rules for each line/segment.
+   */
+  function addAnimation(alpha, trail, i, lines) {
+    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-');
+    var start = 0.01 + i/lines*100;
+    var z = Math.max(1-(1-alpha)/trail*(100-start) , alpha);
+    var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
+    var pre = prefix && '-'+prefix+'-' || '';
+
+    if (!animations[name]) {
+      sheet.insertRule(
+        '@' + pre + 'keyframes ' + name + '{' +
+        '0%{opacity:'+z+'}' +
+        start + '%{opacity:'+ alpha + '}' +
+        (start+0.01) + '%{opacity:1}' +
+        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
+        '100%{opacity:'+ z + '}' +
+        '}', 0);
+      animations[name] = 1;
+    }
+    return name;
+  }
+
+  /**
+   * Tries various vendor prefixes and returns the first supported property.
+   **/
+  function vendor(el, prop) {
+    var s = el.style;
+    var pp;
+    var i;
+
+    if(s[prop] !== undefined) return prop;
+    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
+    for(i=0; i<prefixes.length; i++) {
+      pp = prefixes[i]+prop;
+      if(s[pp] !== undefined) return pp;
+    }
+  }
+
+  /**
+   * Sets multiple style properties at once.
+   */
+  function css(el, prop) {
+    for (var n in prop) {
+      el.style[vendor(el, n)||n] = prop[n];
+    }
+    return el;
+  }
+
+  /**
+   * Fills in default values.
+   */
+  function merge(obj) {
+    for (var i=1; i < arguments.length; i++) {
+      var def = arguments[i];
+      for (var n in def) {
+        if (obj[n] === undefined) obj[n] = def[n];
+      }
+    }
+    return obj;
+  }
+
+  /**
+   * Returns the absolute page-offset of the given element.
+   */
+  function pos(el) {
+    var o = {x:el.offsetLeft, y:el.offsetTop};
+    while((el = el.offsetParent)) {
+      o.x+=el.offsetLeft;
+      o.y+=el.offsetTop;
+    }
+    return o;
+  }
+
+  var defaults = {
+    lines: 12,            // The number of lines to draw
+    length: 7,            // The length of each line
+    width: 5,             // The line thickness
+    radius: 10,           // The radius of the inner circle
+    rotate: 0,            // rotation offset
+    color: '#000',        // #rgb or #rrggbb
+    speed: 1,             // Rounds per second
+    trail: 100,           // Afterglow percentage
+    opacity: 1/4,         // Opacity of the lines
+    fps: 20,              // Frames per second when using setTimeout()
+    zIndex: 2e9,          // Use a high z-index by default
+    className: 'spinner', // CSS class to assign to the element
+    top: 'auto',          // center vertically
+    left: 'auto'          // center horizontally
+  };
+
+  /** The constructor */
+  var Spinner = function Spinner(o) {
+    if (!this.spin) return new Spinner(o);
+    this.opts = merge(o || {}, Spinner.defaults, defaults);
+  };
+
+  Spinner.defaults = {};
+  merge(Spinner.prototype, {
+    spin: function(target) {
+      this.stop();
+      var self = this;
+      var o = self.opts;
+      var el = self.el = css(createEl(0, {className: o.className}), {position: 'relative', zIndex: o.zIndex});
+      var mid = o.radius+o.length+o.width;
+      var ep; // element position
+      var tp; // target position
+
+      if (target) {
+        target.insertBefore(el, target.firstChild||null);
+        tp = pos(target);
+        ep = pos(el);
+        css(el, {
+          left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : o.left+mid) + 'px',
+          top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : o.top+mid)  + 'px'
+        });
+      }
+
+      el.setAttribute('aria-role', 'progressbar');
+      self.lines(el, self.opts);
+
+      if (!useCssAnimations) {
+        // No CSS animation support, use setTimeout() instead
+        var i = 0;
+        var fps = o.fps;
+        var f = fps/o.speed;
+        var ostep = (1-o.opacity)/(f*o.trail / 100);
+        var astep = f/o.lines;
+
+        !function anim() {
+          i++;
+          for (var s=o.lines; s; s--) {
+            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
+            self.opacity(el, o.lines-s, alpha, o);
+          }
+          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
+        }();
+      }
+      return self;
+    },
+    stop: function() {
+      var el = this.el;
+      if (el) {
+        clearTimeout(this.timeout);
+        if (el.parentNode) el.parentNode.removeChild(el);
+        this.el = undefined;
+      }
+      return this;
+    },
+    lines: function(el, o) {
+      var i = 0;
+      var seg;
+
+      function fill(color, shadow) {
+        return css(createEl(), {
+          position: 'absolute',
+          width: (o.length+o.width) + 'px',
+          height: o.width + 'px',
+          background: color,
+          boxShadow: shadow,
+          transformOrigin: 'left',
+          transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
+          borderRadius: (o.width>>1) + 'px'
+        });
+      }
+      for (; i < o.lines; i++) {
+        seg = css(createEl(), {
+          position: 'absolute',
+          top: 1+~(o.width/2) + 'px',
+          transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
+          opacity: o.opacity,
+          animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+        });
+        if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
+        ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
+      }
+      return el;
+    },
+    opacity: function(el, i, val) {
+      if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
+    }
+  });
+
+  /////////////////////////////////////////////////////////////////////////
+  // VML rendering for IE
+  /////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Check and init VML support
+   */
+  !function() {
+
+    function vml(tag, attr) {
+      return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr);
+    }
+
+    var s = css(createEl('group'), {behavior: 'url(#default#VML)'});
+
+    if (!vendor(s, 'transform') && s.adj) {
+
+      // VML support detected. Insert CSS rule ...
+      sheet.addRule('.spin-vml', 'behavior:url(#default#VML)');
+
+      Spinner.prototype.lines = function(el, o) {
+        var r = o.length+o.width;
+        var s = 2*r;
+
+        function grp() {
+          return css(vml('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
+        }
+
+        var margin = -(o.width+o.length)*2+'px';
+        var g = css(grp(), {position: 'absolute', top: margin, left: margin});
+
+        var i;
+
+        function seg(i, dx, filter) {
+          ins(g,
+            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+              ins(css(vml('roundrect', {arcsize: 1}), {
+                  width: r,
+                  height: o.width,
+                  left: o.radius,
+                  top: -o.width>>1,
+                  filter: filter
+                }),
+                vml('fill', {color: o.color, opacity: o.opacity}),
+                vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+              )
+            )
+          );
+        }
+
+        if (o.shadow) {
+          for (i = 1; i <= o.lines; i++) {
+            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
+          }
+        }
+        for (i = 1; i <= o.lines; i++) seg(i);
+        return ins(el, g);
+      };
+      Spinner.prototype.opacity = function(el, i, val, o) {
+        var c = el.firstChild;
+        o = o.shadow && o.lines || 0;
+        if (c && i+o < c.childNodes.length) {
+          c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild;
+          if (c) c.opacity = val;
+        }
+      };
+    }
+    else {
+      useCssAnimations = vendor(s, 'animation');
+    }
+  }();
+
+  window.Spinner = Spinner;
+
+})(window, document);
diff --git a/static/vendor/spin-1.2.5/spin.min.js b/static/vendor/spin-1.2.5/spin.min.js
new file mode 100644 (file)
index 0000000..c38b40e
--- /dev/null
@@ -0,0 +1,2 @@
+//fgnass.github.com/spin.js#v1.2.5
+(function(a,b,c){function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;b<c;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1),g}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var d=["webkit","Moz","ms","O"],e={},f,i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},q.defaults,o)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width,h,i;a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:(c.left=="auto"?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,0,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p})(window,document);
\ No newline at end of file
deleted file mode 100644 (file)
index 7152f2b9b10b2cd8884711916b9013e13cb24b9b..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,284 +0,0 @@
-//fgnass.github.com/spin.js#v1.2
-(function(window, document, undefined) {
-
-/**
- * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
- * Licensed under the MIT license
- */
-
-  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
-      animations = {}, /* Animation rules keyed by their name */
-      useCssAnimations;
-
-  /**
-   * Utility function to create elements. If no tag name is given,
-   * a DIV is created. Optionally properties can be passed.
-   */
-  function createEl(tag, prop) {
-    var el = document.createElement(tag || 'div'),
-        n;
-
-    for(n in prop) {
-      el[n] = prop[n];
-    }
-    return el;
-  }
-
-  /**
-   * Inserts child1 before child2. If child2 is not specified,
-   * child1 is appended. If child2 has no parentNode, child2 is
-   * appended first.
-   */
-  function ins(parent, child1, child2) {
-    if(child2 && !child2.parentNode) ins(parent, child2);
-    parent.insertBefore(child1, child2||null);
-    return parent;
-  }
-
-  /**
-   * Insert a new stylesheet to hold the @keyframe or VML rules.
-   */
-  ins(document.getElementsByTagName('head')[0], createEl('style'));
-  var sheet = document.styleSheets[document.styleSheets.length-1];
-
-  /**
-   * Creates an opacity keyframe animation rule and returns its name.
-   * Since most mobile Webkits have timing issues with animation-delay,
-   * we create separate rules for each line/segment.
-   */
-  function addAnimation(alpha, trail, i, lines) {
-    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
-        start = 0.01 + i/lines*100,
-        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
-        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
-        pre = prefix && '-'+prefix+'-' || '';
-
-    if (!animations[name]) {
-      sheet.insertRule(
-        '@' + pre + 'keyframes ' + name + '{' +
-        '0%{opacity:'+z+'}' +
-        start + '%{opacity:'+ alpha + '}' +
-        (start+0.01) + '%{opacity:1}' +
-        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
-        '100%{opacity:'+ z + '}' +
-        '}', 0);
-      animations[name] = 1;
-    }
-    return name;
-  }
-
-  /**
-   * Tries various vendor prefixes and returns the first supported property.
-   **/
-  function vendor(el, prop) {
-    var s = el.style,
-        pp,
-        i;
-
-    if(s[prop] !== undefined) return prop;
-    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
-    for(i=0; i<prefixes.length; i++) {
-      pp = prefixes[i]+prop;
-      if(s[pp] !== undefined) return pp;
-    }
-  }
-
-  /**
-   * Sets multiple style properties at once.
-   */
-  function css(el, prop) {
-    for (var n in prop) {
-      el.style[vendor(el, n)||n] = prop[n];
-    }
-    return el;
-  }
-
-  /**
-   * Fills in default values.
-   */
-  function defaults(obj, def) {
-    for (var n in def) {
-      if (obj[n] === undefined) obj[n] = def[n];
-    }
-    return obj;
-  }
-
-  /**
-   * Returns the absolute page-offset of the given element.
-   */
-  function pos(el) {
-    var o = {x:el.offsetLeft, y:el.offsetTop};
-    while((el = el.offsetParent)) {
-      o.x+=el.offsetLeft;
-      o.y+=el.offsetTop;
-    }
-    return o;
-  }
-
-  /** The constructor */
-  var Spinner = function Spinner(o) {
-    if (!this.spin) return new Spinner(o);
-    this.opts = defaults(o || {}, {
-      lines: 12, // The number of lines to draw
-      length: 7, // The length of each line
-      width: 5, // The line thickness
-      radius: 10, // The radius of the inner circle
-      color: '#000', // #rgb or #rrggbb
-      speed: 1, // Rounds per second
-      trail: 100, // Afterglow percentage
-      opacity: 1/4,
-      fps: 20
-    });
-  },
-  proto = Spinner.prototype = {
-    spin: function(target) {
-      this.stop();
-      var self = this,
-          el = self.el = css(createEl(), {position: 'relative'}),
-          ep, // element position
-          tp; // target position
-
-      if (target) {
-        tp = pos(ins(target, el, target.firstChild));
-        ep = pos(el);
-        css(el, {
-          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
-          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
-        });
-      }
-      el.setAttribute('aria-role', 'progressbar');
-      self.lines(el, self.opts);
-      if (!useCssAnimations) {
-        // No CSS animation support, use setTimeout() instead
-        var o = self.opts,
-            i = 0,
-            fps = o.fps,
-            f = fps/o.speed,
-            ostep = (1-o.opacity)/(f*o.trail / 100),
-            astep = f/o.lines;
-
-        (function anim() {
-          i++;
-          for (var s=o.lines; s; s--) {
-            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
-            self.opacity(el, o.lines-s, alpha, o);
-          }
-          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
-        })();
-      }
-      return self;
-    },
-    stop: function() {
-      var el = this.el;
-      if (el) {
-        clearTimeout(this.timeout);
-        if (el.parentNode) el.parentNode.removeChild(el);
-        this.el = undefined;
-      }
-      return this;
-    }
-  };
-  proto.lines = function(el, o) {
-    var i = 0,
-        seg;
-
-    function fill(color, shadow) {
-      return css(createEl(), {
-        position: 'absolute',
-        width: (o.length+o.width) + 'px',
-        height: o.width + 'px',
-        background: color,
-        boxShadow: shadow,
-        transformOrigin: 'left',
-        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
-        borderRadius: (o.width>>1) + 'px'
-      });
-    }
-    for (; i < o.lines; i++) {
-      seg = css(createEl(), {
-        position: 'absolute',
-        top: 1+~(o.width/2) + 'px',
-        transform: 'translate3d(0,0,0)',
-        opacity: o.opacity,
-        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
-      });
-      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
-      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
-    }
-    return el;
-  };
-  proto.opacity = function(el, i, val) {
-    el.childNodes[i].style.opacity = val;
-  };
-
-  /////////////////////////////////////////////////////////////////////////
-  // VML rendering for IE
-  /////////////////////////////////////////////////////////////////////////
-
-  /** 
-   * Check and init VML support
-   */
-  (function() {
-    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
-        i;
-
-    if (!vendor(s, 'transform') && s.adj) {
-
-      // VML support detected. Insert CSS rules ...
-      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
-
-      proto.lines = function(el, o) {
-        var r = o.length+o.width,
-            s = 2*r;
-
-        function grp() {
-          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
-        }
-
-        var g = grp(),
-            margin = ~(o.length+o.radius+o.width)+'px',
-            i;
-
-        function seg(i, dx, filter) {
-          ins(g,
-            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
-              ins(css(createEl('roundrect', {arcsize: 1}), {
-                  width: r,
-                  height: o.width,
-                  left: o.radius,
-                  top: -o.width>>1,
-                  filter: filter
-                }),
-                createEl('fill', {color: o.color, opacity: o.opacity}),
-                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
-              )
-            )
-          );
-        }
-
-        if (o.shadow) {
-          for (i = 1; i <= o.lines; i++) {
-            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
-          }
-        }
-        for (i = 1; i <= o.lines; i++) {
-          seg(i);
-        }
-        return ins(css(el, {
-          margin: margin + ' 0 0 ' + margin,
-          zoom: 1
-        }), g);
-      };
-      proto.opacity = function(el, i, val, o) {
-        o = o.shadow && o.lines || 0;
-        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
-      };
-    }
-    else {
-      useCssAnimations = vendor(s, 'animation');
-    }
-  })();
-
-  window.Spinner = Spinner;
-
-})(window, document);
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..af80e1ac95e698111fbffbe5998be8e0f975e12b
--- /dev/null
@@ -0,0 +1 @@
+spin/spin.js
\ No newline at end of file
deleted file mode 100644 (file)
index 208b3033214e5ece666de5ae2a36771468ada80f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,2 +0,0 @@
-//fgnass.github.com/spin.js#v1.2
-(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25,fps:20})},p=o.prototype={spin:function(a){this.stop();var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),c.setAttribute("aria-role","progressbar"),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=i.fps,m=k/i.speed,o=(1-i.opacity)/(m*i.trail/100),p=m/i.lines;(function q(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*p)%m*o,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))})()}return b},stop:function(){var a=this.el;a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c);return this}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i,zoom:1}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document)
\ No newline at end of file
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..57b2ed1bd96ac2640930703dd3738163b0ce804e
--- /dev/null
@@ -0,0 +1 @@
+spin/spin.min.js
\ No newline at end of file