Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit ef104ad4b04deec4934c69528642e46eb02946f1 1 parent f14362e
@kristianmandrup authored
Showing with 2,775 additions and 45 deletions.
  1. +1 −1  .gitignore
  2. +8 −9 Gemfile
  3. +56 −0 README.md
  4. +0 −19 README.rdoc
  5. +2 −2 Rakefile
  6. +6 −0 lib/bootstrap-addons-rails.rb
  7. +0 −7 spec/bootstrap-addons-rails_spec.rb
  8. +1 −7 spec/spec_helper.rb
  9. +127 −0 vendor/assets/colorpicker/css/colorpicker.css
  10. BIN  vendor/assets/colorpicker/img/alpha.png
  11. BIN  vendor/assets/colorpicker/img/hue.png
  12. BIN  vendor/assets/colorpicker/img/saturation.png
  13. +520 −0 vendor/assets/colorpicker/js/bootstrap-colorpicker.js
  14. +89 −0 vendor/assets/colorpicker/less/colorpicker.less
  15. BIN  vendor/assets/images/bootstrap/colorpicker/alpha.png
  16. BIN  vendor/assets/images/bootstrap/colorpicker/hue.png
  17. BIN  vendor/assets/images/bootstrap/colorpicker/saturation.png
  18. BIN  vendor/assets/images/bootstrap/loading.gif
  19. +520 −0 vendor/assets/javascripts/bootstrap/colorpicker.js
  20. +401 −0 vendor/assets/javascripts/bootstrap/datepicker.js
  21. +387 −0 vendor/assets/javascripts/bootstrap/image-gallery.js
  22. +1 −0  vendor/assets/javascripts/bootstrap/image-gallery.min.js
  23. +89 −0 vendor/assets/less/bootstrap/colorpicker.less
  24. +122 −0 vendor/assets/less/bootstrap/datepicker.less
  25. +127 −0 vendor/assets/stylesheets/bootstrap/colorpicker.css
  26. +156 −0 vendor/assets/stylesheets/bootstrap/datepicker.css
  27. +141 −0 vendor/assets/stylesheets/bootstrap/image-gallery.css
  28. +21 −0 vendor/assets/stylesheets/bootstrap/image-gallery.min.css
View
2  .gitignore
@@ -28,7 +28,7 @@ pkg
#
# For MacOS:
#
-#.DS_Store
+.DS_Store
# For TextMate
#*.tmproj
View
17 Gemfile
@@ -1,14 +1,13 @@
-source "http://rubygems.org"
-# Add dependencies required to use your gem here.
-# Example:
-# gem "activesupport", ">= 2.3.5"
+source :rubygems
+
+gem 'rails'
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
- gem "rspec", "~> 2.8.0"
- gem "rdoc", "~> 3.12"
- gem "bundler", "~> 1.0.0"
- gem "jeweler", "~> 1.8.4"
- gem "rcov", ">= 0"
+ gem "rspec", ">= 2.8.0"
+ gem "rdoc", ">= 3.12"
+ gem "bundler", ">= 1.0.0"
+ gem "jeweler", ">= 1.8.3"
+ gem "simplecov",">= 0.5"
end
View
56 README.md
@@ -0,0 +1,56 @@
+# Twitter Bootstrap addons for Rails asset pipeline
+
+Includes:
+
+* [colorpicker](http://www.eyecon.ro/bootstrap-colorpicker/)
+* [datepicker](http://www.eyecon.ro/bootstrap-datepicker/)
+* [Image Gallery](https://github.com/blueimp/Bootstrap-Image-Gallery)
+
+## Installation
+
+in Gemfile
+
+`gem 'bootstrap-addons-rails'`
+
+Note: Currently use the `git:
+
+then bundle it!
+
+## Configuration
+
+```css
+ *= require bootstrap/colorpicker
+ *= require bootstrap/datepicker
+ *= require bootstrap/image-gallery
+```
+
+```javascript
+//= require bootstrap/colorpicker
+//= require bootstrap/datepicker
+//= require bootstrap/image-gallery.min
+```
+
+Note: In the stylesheets the image refs must be updated to reflect their assets location. Please send me a pull request with these fixes ;)
+
+## Extras
+
+To customize Bootstrap, check out:
+
+* http://charliepark.org/bootstrap_buttons/
+* http://bootswatch.com/
+
+## Contributing to bootstrap-addons-rails
+
+* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
+* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
+* Fork the project.
+* Start a feature/bugfix branch.
+* Commit and push until you are happy with your contribution.
+* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
+* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
+
+## Copyright
+
+Copyright (c) 2012 Kristian Mandrup. See LICENSE.txt for
+further details.
+
View
19 README.rdoc
@@ -1,19 +0,0 @@
-= bootstrap-addons-rails
-
-Description goes here.
-
-== Contributing to bootstrap-addons-rails
-
-* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
-* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
-* Fork the project.
-* Start a feature/bugfix branch.
-* Commit and push until you are happy with your contribution.
-* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
-* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
-
-== Copyright
-
-Copyright (c) 2012 Kristian Mandrup. See LICENSE.txt for
-further details.
-
View
4 Rakefile
@@ -17,8 +17,8 @@ Jeweler::Tasks.new do |gem|
gem.name = "bootstrap-addons-rails"
gem.homepage = "http://github.com/kristianmandrup/bootstrap-addons-rails"
gem.license = "MIT"
- gem.summary = %Q{TODO: one-line summary of your gem}
- gem.description = %Q{TODO: longer description of your gem}
+ gem.summary = %Q{Twitter Bootstrap addons: Color- and Datepicker, Image gallery, ready for use with Rails asset pipeline}
+ gem.description = %Q{Adds nice Bootstrap addons to your Rails Twitter Bootstrap based app}
gem.email = "kmandrup@gmail.com"
gem.authors = ["Kristian Mandrup"]
# dependencies defined in Gemfile
View
6 lib/bootstrap-addons-rails.rb
@@ -0,0 +1,6 @@
+module BootstrapAddons
+ module Rails
+ class Engine < ::Rails::Engine
+ end
+ end
+end
View
7 spec/bootstrap-addons-rails_spec.rb
@@ -1,7 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-
-describe "BootstrapAddonsRails" do
- it "fails" do
- fail "hey buddy, you should probably rename this file and start specing for real"
- end
-end
View
8 spec/spec_helper.rb
@@ -1,12 +1,6 @@
-$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
-$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rspec'
require 'bootstrap-addons-rails'
-# Requires supporting files with custom matchers and macros, etc,
-# in ./support/ and its subdirectories.
-Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
-RSpec.configure do |config|
-
+RSpec.configure do |config|
end
View
127 vendor/assets/colorpicker/css/colorpicker.css
@@ -0,0 +1,127 @@
+/*!
+* Colorpicker for Bootstrap
+*
+* Copyright 2012 Stefan Petre
+* Licensed under the Apache License v2.0
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+*/
+.colorpicker-saturation {
+width: 100px;
+height: 100px;
+background-image: url(../img/saturation.png);
+cursor: crosshair;
+float: left;
+}
+.colorpicker-saturation i {
+display: block;
+height: 5px;
+width: 5px;
+border: 1px solid #000;
+-webkit-border-radius: 5px;
+-moz-border-radius: 5px;
+border-radius: 5px;
+position: absolute;
+top: 0;
+left: 0;
+margin: -4px 0 0 -4px;
+}
+.colorpicker-saturation i b {
+display: block;
+height: 5px;
+width: 5px;
+border: 1px solid #fff;
+-webkit-border-radius: 5px;
+-moz-border-radius: 5px;
+border-radius: 5px;
+}
+.colorpicker-hue, .colorpicker-alpha {
+width: 15px;
+height: 100px;
+float: left;
+cursor: row-resize;
+margin-left: 4px;
+margin-bottom: 4px;
+}
+.colorpicker-hue i, .colorpicker-alpha i {
+display: block;
+height: 1px;
+background: #000;
+border-top: 1px solid #fff;
+position: absolute;
+top: 0;
+left: 0;
+width: 100%;
+margin-top: -1px;
+}
+.colorpicker-hue {
+background-image: url(../img/hue.png);
+}
+.colorpicker-alpha {
+background-image: url(../img/alpha.png);
+display: none;
+}
+.colorpicker {
+*zoom: 1;
+top: 0;
+left: 0;
+padding: 4px;
+min-width: 120px;
+margin-top: 1px;
+-webkit-border-radius: 4px;
+-moz-border-radius: 4px;
+border-radius: 4px;
+}
+.colorpicker:before, .colorpicker:after {
+display: table;
+content: "";
+}
+.colorpicker:after {
+clear: both;
+}
+.colorpicker:before {
+content: '';
+display: inline-block;
+border-left: 7px solid transparent;
+border-right: 7px solid transparent;
+border-bottom: 7px solid #ccc;
+border-bottom-color: rgba(0, 0, 0, 0.2);
+position: absolute;
+top: -7px;
+left: 6px;
+}
+.colorpicker:after {
+content: '';
+display: inline-block;
+border-left: 6px solid transparent;
+border-right: 6px solid transparent;
+border-bottom: 6px solid #ffffff;
+position: absolute;
+top: -6px;
+left: 7px;
+}
+.colorpicker div {
+position: relative;
+}
+.colorpicker.alpha {
+min-width: 140px;
+}
+.colorpicker.alpha .colorpicker-alpha {
+display: block;
+}
+.colorpicker-color {
+height: 10px;
+margin-top: 5px;
+clear: both;
+background-image: url(../img/alpha.png);
+background-position: 0 100%;
+}
+.colorpicker-color div {
+height: 10px;
+}
+.input-append.color .add-on i, .input-prepend.color .add-on i {
+display: block;
+cursor: pointer;
+width: 16px;
+height: 16px;
+}
View
BIN  vendor/assets/colorpicker/img/alpha.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  vendor/assets/colorpicker/img/hue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  vendor/assets/colorpicker/img/saturation.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
520 vendor/assets/colorpicker/js/bootstrap-colorpicker.js
@@ -0,0 +1,520 @@
+/* =========================================================
+ * bootstrap-colorpicker.js
+ * http://www.eyecon.ro/bootstrap-colorpicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+!function( $ ) {
+
+ // Color object
+
+ var Color = function(val) {
+ this.value = {
+ h: 1,
+ s: 1,
+ b: 1,
+ a: 1
+ };
+ this.setColor(val);
+ };
+
+ Color.prototype = {
+ constructor: Color,
+
+ //parse a string to HSB
+ setColor: function(val){
+ val = val.toLowerCase();
+ var that = this;
+ $.each( CPGlobal.stringParsers, function( i, parser ) {
+ var match = parser.re.exec( val ),
+ values = match && parser.parse( match ),
+ space = parser.space||'rgba';
+ if ( values ) {
+ if (space == 'hsla') {
+ that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
+ } else {
+ that.value = CPGlobal.RGBtoHSB.apply(null, values);
+ }
+ return false;
+ }
+ });
+ },
+
+ setHue: function(h) {
+ this.value.h = 1- h;
+ },
+
+ setSaturation: function(s) {
+ this.value.s = s;
+ },
+
+ setLightness: function(b) {
+ this.value.b = 1- b;
+ },
+
+ setAlpha: function(a) {
+ this.value.a = parseInt((1 - a)*100, 10)/100;
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ toRGB: function(h, s, b, a) {
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ h *= 360;
+ var R, G, B, X, C;
+ h = (h % 360) / 60;
+ C = b * s;
+ X = C * (1 - Math.abs(h % 2 - 1));
+ R = G = B = b - C;
+
+ h = ~~h;
+ R += [C, X, 0, 0, X, C][h];
+ G += [X, C, C, X, 0, 0][h];
+ B += [0, 0, X, C, C, X][h];
+ return {
+ r: Math.round(R*255),
+ g: Math.round(G*255),
+ b: Math.round(B*255),
+ a: a||this.value.a
+ };
+ },
+
+ toHex: function(h, s, b, a){
+ var rgb = this.toRGB(h, s, b, a);
+ return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
+ },
+
+ toHSL: function(h, s, b, a){
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ var H = h,
+ L = (2 - s) * b,
+ S = s * b;
+ if (L > 0 && L <= 1) {
+ S /= L;
+ } else {
+ S /= 2 - L;
+ }
+ L /= 2;
+ if (S > 1) {
+ S = 1;
+ }
+ return {
+ h: H,
+ s: S,
+ l: L,
+ a: a||this.value.a
+ };
+ }
+ };
+
+ // Picker object
+
+ var Colorpicker = function(element, options){
+ this.element = $(element);
+ var format = options.format||this.element.data('color-format')||'hex';
+ this.format = CPGlobal.translateFormats[format];
+ this.isInput = this.element.is('input');
+ this.component = this.element.is('.color') ? this.element.find('.add-on') : false;
+
+ this.picker = $(CPGlobal.template)
+ .appendTo('body')
+ .on('mousedown', $.proxy(this.mousedown, this));
+
+ if (this.isInput) {
+ this.element.on({
+ 'focus': $.proxy(this.show, this),
+ 'keyup': $.proxy(this.update, this)
+ });
+ } else if (this.component){
+ this.component.on({
+ 'click': $.proxy(this.show, this)
+ });
+ } else {
+ this.element.on({
+ 'click': $.proxy(this.show, this)
+ });
+ }
+ if (format == 'rgba' || format == 'hsla') {
+ this.picker.addClass('alpha');
+ this.alpha = this.picker.find('.colorpicker-alpha')[0].style;
+ }
+
+ if (this.component){
+ this.picker.find('.colorpicker-color').hide();
+ this.preview = this.element.find('i')[0].style;
+ } else {
+ this.preview = this.picker.find('div:last')[0].style;
+ }
+
+ this.base = this.picker.find('div:first')[0].style;
+ this.update();
+ };
+
+ Colorpicker.prototype = {
+ constructor: Colorpicker,
+
+ show: function(e) {
+ this.picker.show();
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+ this.place();
+ $(window).on('resize', $.proxy(this.place, this));
+ if (!this.isInput) {
+ if (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }
+ $(document).on({
+ 'mousedown': $.proxy(this.hide, this)
+ });
+ this.element.trigger({
+ type: 'show',
+ color: this.color
+ });
+ },
+
+ update: function(){
+ this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color'));
+ this.picker.find('i')
+ .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
+ .eq(1).css('top', 100 * (1 - this.color.value.h)).end()
+ .eq(2).css('top', 100 * (1 - this.color.value.a));
+ this.previewColor();
+ },
+
+ hide: function(){
+ this.picker.hide();
+ $(window).off('resize', this.place);
+ if (!this.isInput) {
+ $(document).off({
+ 'mousedown': this.hide
+ });
+ if (this.component){
+ this.element.find('input').prop('value', this.format.call(this));
+ }
+ this.element.data('color', this.format.call(this));
+ } else {
+ this.element.prop('value', this.format.call(this));
+ }
+ this.element.trigger({
+ type: 'hide',
+ color: this.color
+ });
+ },
+
+ place: function(){
+ var offset = this.component ? this.component.offset() : this.element.offset();
+ this.picker.css({
+ top: offset.top + this.height,
+ left: offset.left
+ });
+ },
+
+ //preview color change
+ previewColor: function(){
+ this.preview.backgroundColor = this.format.call(this);
+ //set the color for brightness/saturation slider
+ this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1);
+ //set te color for alpha slider
+ if (this.alpha) {
+ this.alpha.backgroundColor = this.color.toHex();
+ }
+ },
+
+ pointer: null,
+
+ slider: null,
+
+ mousedown: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+
+ var target = $(e.target);
+
+ //detect the slider and set the limits and callbacks
+ var zone = target.closest('div');
+ if (!zone.is('.colorpicker')) {
+ if (zone.is('.colorpicker-saturation')) {
+ this.slider = $.extend({}, CPGlobal.sliders['saturation']);
+ }
+ else if (zone.is('.colorpicker-hue')) {
+ this.slider = $.extend({}, CPGlobal.sliders['hue']);
+ }
+ else if (zone.is('.colorpicker-alpha')) {
+ this.slider = $.extend({}, CPGlobal.sliders['alpha']);
+ }
+ var offset = zone.offset();
+ //reference to knob's style
+ this.slider.knob = zone.find('i')[0].style;
+ this.slider.left = e.pageX - offset.left;
+ this.slider.top = e.pageY - offset.top;
+ this.pointer = {
+ left: e.pageX,
+ top: e.pageY
+ };
+ //trigger mousemove to move the knob to the current position
+ $(document).on({
+ mousemove: $.proxy(this.mousemove, this),
+ mouseup: $.proxy(this.mouseup, this)
+ }).trigger('mousemove');
+ }
+ return false;
+ },
+
+ mousemove: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ var left = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxLeft,
+ this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left)
+ )
+ );
+ var top = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxTop,
+ this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top)
+ )
+ );
+ this.slider.knob.left = left + 'px';
+ this.slider.knob.top = top + 'px';
+ if (this.slider.callLeft) {
+ this.color[this.slider.callLeft].call(this.color, left/100);
+ }
+ if (this.slider.callTop) {
+ this.color[this.slider.callTop].call(this.color, top/100);
+ }
+ this.previewColor();
+ this.element.trigger({
+ type: 'changeColor',
+ color: this.color
+ });
+ return false;
+ },
+
+ mouseup: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ $(document).off({
+ mousemove: this.mousemove,
+ mouseup: this.mouseup
+ });
+ return false;
+ }
+ }
+
+ $.fn.colorpicker = function ( option ) {
+ return this.each(function () {
+ var $this = $(this),
+ data = $this.data('colorpicker'),
+ options = typeof option == 'object' && option;
+ if (!data) {
+ $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults,options))));
+ }
+ if (typeof option == 'string') data[option]();
+ });
+ };
+
+ $.fn.colorpicker.defaults = {
+ };
+
+ $.fn.colorpicker.Constructor = Colorpicker;
+
+ var CPGlobal = {
+
+ // translate a format from Color object to a string
+ translateFormats: {
+ 'rgb': function(){
+ var rgb = this.color.toRGB();
+ return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
+ },
+
+ 'rgba': function(){
+ var rgb = this.color.toRGB();
+ return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')';
+ },
+
+ 'hsl': function(){
+ var hsl = this.color.toHSL();
+ return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)';
+ },
+
+ 'hsla': function(){
+ var hsl = this.color.toHSL();
+ return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')';
+ },
+
+ 'hex': function(){
+ return this.color.toHex();
+ }
+ },
+
+ sliders: {
+ saturation: {
+ maxLeft: 100,
+ maxTop: 100,
+ callLeft: 'setSaturation',
+ callTop: 'setLightness'
+ },
+
+ hue: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setHue'
+ },
+
+ alpha: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setAlpha'
+ }
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ RGBtoHSB: function (r, g, b, a){
+ r /= 255;
+ g /= 255;
+ b /= 255;
+
+ var H, S, V, C;
+ V = Math.max(r, g, b);
+ C = V - Math.min(r, g, b);
+ H = (C == 0 ? null :
+ V == r ? (g - b) / C :
+ V == g ? (b - r) / C + 2 :
+ (r - g) / C + 4
+ );
+ H = ((H + 360) % 6) * 60 / 360;
+ S = C == 0 ? 0 : C / V;
+ return {h: H||1, s: S, b: V, a: a||1};
+ },
+
+ HueToRGB: function (p, q, h) {
+ if (h < 0)
+ h += 1;
+ else if (h > 1)
+ h -= 1;
+
+ if ((h * 6) < 1)
+ return p + (q - p) * h * 6;
+ else if ((h * 2) < 1)
+ return q;
+ else if ((h * 3) < 2)
+ return p + (q - p) * ((2 / 3) - h) * 6;
+ else
+ return p;
+ },
+
+ HSLtoRGB: function (h, s, l, a)
+ {
+
+ if (s < 0)
+ s = 0;
+
+ if (l <= 0.5)
+ var q = l * (1 + s);
+ else
+ var q = l + s - (l * s);
+
+ var p = 2 * l - q;
+
+ var tr = h + (1 / 3);
+ var tg = h;
+ var tb = h - (1 / 3);
+
+ var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255);
+ var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255);
+ var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255);
+ return [r, g, b, a||1];
+ },
+
+ // a set of RE's that can match strings and generate color tuples.
+ // from John Resig color plugin
+ // https://github.com/jquery/jquery-color/
+ stringParsers: [
+ {
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ execResult[ 1 ],
+ execResult[ 2 ],
+ execResult[ 3 ],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ 2.55 * execResult[1],
+ 2.55 * execResult[2],
+ 2.55 * execResult[3],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ space: 'hsla',
+ parse: function( execResult ) {
+ return [
+ execResult[1]/360,
+ execResult[2] / 100,
+ execResult[3] / 100,
+ execResult[4]
+ ];
+ }
+ }
+ ],
+ template: '<div class="colorpicker dropdown-menu">'+
+ '<div class="colorpicker-saturation"><i><b></b></i></div>'+
+ '<div class="colorpicker-hue"><i></i></div>'+
+ '<div class="colorpicker-alpha"><i></i></div>'+
+ '<div class="colorpicker-color"><div /></div>'+
+ '</div>'
+ };
+
+}( window.jQuery )
View
89 vendor/assets/colorpicker/less/colorpicker.less
@@ -0,0 +1,89 @@
+.colorpicker-saturation {
+ width: 100px;
+ height: 100px;
+ background-image: url(../img/saturation.png);
+ cursor: crosshair;
+ float: left;
+ i {
+ display: block;
+ height: 5px;
+ width: 5px;
+ border: 1px solid #000;
+ .border-radius();
+ position: absolute;
+ top: 0;
+ left: 0;
+ margin: -4px 0 0 -4px;
+ b{
+ display: block;
+ height: 5px;
+ width: 5px;
+ border: 1px solid #fff;
+ .border-radius();
+ }
+ }
+}
+.colorpicker-hue,
+.colorpicker-alpha {
+ width: 15px;
+ height: 100px;
+ float: left;
+ cursor: row-resize;
+ margin-left: 4px;
+ margin-bottom: 4px;
+ i {
+ display: block;
+ height: 1px;
+ background: #000;
+ border-top: 1px solid #fff;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ margin-top: -1px;
+ }
+}
+.colorpicker-hue {
+ background-image: url(../img/hue.png);
+}
+.colorpicker-alpha {
+ background-image: url(../img/alpha.png);
+ display:none;
+}
+.colorpicker {
+ .clearfix();
+ top: 0;
+ left: 0;
+ padding: 4px;
+ min-width: 120px;
+ div {
+ position: relative;
+ }
+ &.alpha {
+ min-width: 140px;
+ .colorpicker-alpha {
+ display: block;
+ }
+ }
+}
+.colorpicker-color {
+ height: 10px;
+ margin-top: 5px;
+ clear: both;
+ background-image: url(../img/alpha.png);
+ background-position: 0 100%;
+ div {
+ height: 10px;
+ }
+}
+.input-append,
+.input-prepend {
+ &.color {
+ .add-on i {
+ display: block;
+ cursor: pointer;
+ width: 16px;
+ height: 16px;
+ }
+ }
+}
View
BIN  vendor/assets/images/bootstrap/colorpicker/alpha.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  vendor/assets/images/bootstrap/colorpicker/hue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  vendor/assets/images/bootstrap/colorpicker/saturation.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  vendor/assets/images/bootstrap/loading.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
520 vendor/assets/javascripts/bootstrap/colorpicker.js
@@ -0,0 +1,520 @@
+/* =========================================================
+ * bootstrap-colorpicker.js
+ * http://www.eyecon.ro/bootstrap-colorpicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+!function( $ ) {
+
+ // Color object
+
+ var Color = function(val) {
+ this.value = {
+ h: 1,
+ s: 1,
+ b: 1,
+ a: 1
+ };
+ this.setColor(val);
+ };
+
+ Color.prototype = {
+ constructor: Color,
+
+ //parse a string to HSB
+ setColor: function(val){
+ val = val.toLowerCase();
+ var that = this;
+ $.each( CPGlobal.stringParsers, function( i, parser ) {
+ var match = parser.re.exec( val ),
+ values = match && parser.parse( match ),
+ space = parser.space||'rgba';
+ if ( values ) {
+ if (space == 'hsla') {
+ that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
+ } else {
+ that.value = CPGlobal.RGBtoHSB.apply(null, values);
+ }
+ return false;
+ }
+ });
+ },
+
+ setHue: function(h) {
+ this.value.h = 1- h;
+ },
+
+ setSaturation: function(s) {
+ this.value.s = s;
+ },
+
+ setLightness: function(b) {
+ this.value.b = 1- b;
+ },
+
+ setAlpha: function(a) {
+ this.value.a = parseInt((1 - a)*100, 10)/100;
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ toRGB: function(h, s, b, a) {
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ h *= 360;
+ var R, G, B, X, C;
+ h = (h % 360) / 60;
+ C = b * s;
+ X = C * (1 - Math.abs(h % 2 - 1));
+ R = G = B = b - C;
+
+ h = ~~h;
+ R += [C, X, 0, 0, X, C][h];
+ G += [X, C, C, X, 0, 0][h];
+ B += [0, 0, X, C, C, X][h];
+ return {
+ r: Math.round(R*255),
+ g: Math.round(G*255),
+ b: Math.round(B*255),
+ a: a||this.value.a
+ };
+ },
+
+ toHex: function(h, s, b, a){
+ var rgb = this.toRGB(h, s, b, a);
+ return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
+ },
+
+ toHSL: function(h, s, b, a){
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ var H = h,
+ L = (2 - s) * b,
+ S = s * b;
+ if (L > 0 && L <= 1) {
+ S /= L;
+ } else {
+ S /= 2 - L;
+ }
+ L /= 2;
+ if (S > 1) {
+ S = 1;
+ }
+ return {
+ h: H,
+ s: S,
+ l: L,
+ a: a||this.value.a
+ };
+ }
+ };
+
+ // Picker object
+
+ var Colorpicker = function(element, options){
+ this.element = $(element);
+ var format = options.format||this.element.data('color-format')||'hex';
+ this.format = CPGlobal.translateFormats[format];
+ this.isInput = this.element.is('input');
+ this.component = this.element.is('.color') ? this.element.find('.add-on') : false;
+
+ this.picker = $(CPGlobal.template)
+ .appendTo('body')
+ .on('mousedown', $.proxy(this.mousedown, this));
+
+ if (this.isInput) {
+ this.element.on({
+ 'focus': $.proxy(this.show, this),
+ 'keyup': $.proxy(this.update, this)
+ });
+ } else if (this.component){
+ this.component.on({
+ 'click': $.proxy(this.show, this)
+ });
+ } else {
+ this.element.on({
+ 'click': $.proxy(this.show, this)
+ });
+ }
+ if (format == 'rgba' || format == 'hsla') {
+ this.picker.addClass('alpha');
+ this.alpha = this.picker.find('.colorpicker-alpha')[0].style;
+ }
+
+ if (this.component){
+ this.picker.find('.colorpicker-color').hide();
+ this.preview = this.element.find('i')[0].style;
+ } else {
+ this.preview = this.picker.find('div:last')[0].style;
+ }
+
+ this.base = this.picker.find('div:first')[0].style;
+ this.update();
+ };
+
+ Colorpicker.prototype = {
+ constructor: Colorpicker,
+
+ show: function(e) {
+ this.picker.show();
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+ this.place();
+ $(window).on('resize', $.proxy(this.place, this));
+ if (!this.isInput) {
+ if (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }
+ $(document).on({
+ 'mousedown': $.proxy(this.hide, this)
+ });
+ this.element.trigger({
+ type: 'show',
+ color: this.color
+ });
+ },
+
+ update: function(){
+ this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color'));
+ this.picker.find('i')
+ .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
+ .eq(1).css('top', 100 * (1 - this.color.value.h)).end()
+ .eq(2).css('top', 100 * (1 - this.color.value.a));
+ this.previewColor();
+ },
+
+ hide: function(){
+ this.picker.hide();
+ $(window).off('resize', this.place);
+ if (!this.isInput) {
+ $(document).off({
+ 'mousedown': this.hide
+ });
+ if (this.component){
+ this.element.find('input').prop('value', this.format.call(this));
+ }
+ this.element.data('color', this.format.call(this));
+ } else {
+ this.element.prop('value', this.format.call(this));
+ }
+ this.element.trigger({
+ type: 'hide',
+ color: this.color
+ });
+ },
+
+ place: function(){
+ var offset = this.component ? this.component.offset() : this.element.offset();
+ this.picker.css({
+ top: offset.top + this.height,
+ left: offset.left
+ });
+ },
+
+ //preview color change
+ previewColor: function(){
+ this.preview.backgroundColor = this.format.call(this);
+ //set the color for brightness/saturation slider
+ this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1);
+ //set te color for alpha slider
+ if (this.alpha) {
+ this.alpha.backgroundColor = this.color.toHex();
+ }
+ },
+
+ pointer: null,
+
+ slider: null,
+
+ mousedown: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+
+ var target = $(e.target);
+
+ //detect the slider and set the limits and callbacks
+ var zone = target.closest('div');
+ if (!zone.is('.colorpicker')) {
+ if (zone.is('.colorpicker-saturation')) {
+ this.slider = $.extend({}, CPGlobal.sliders['saturation']);
+ }
+ else if (zone.is('.colorpicker-hue')) {
+ this.slider = $.extend({}, CPGlobal.sliders['hue']);
+ }
+ else if (zone.is('.colorpicker-alpha')) {
+ this.slider = $.extend({}, CPGlobal.sliders['alpha']);
+ }
+ var offset = zone.offset();
+ //reference to knob's style
+ this.slider.knob = zone.find('i')[0].style;
+ this.slider.left = e.pageX - offset.left;
+ this.slider.top = e.pageY - offset.top;
+ this.pointer = {
+ left: e.pageX,
+ top: e.pageY
+ };
+ //trigger mousemove to move the knob to the current position
+ $(document).on({
+ mousemove: $.proxy(this.mousemove, this),
+ mouseup: $.proxy(this.mouseup, this)
+ }).trigger('mousemove');
+ }
+ return false;
+ },
+
+ mousemove: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ var left = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxLeft,
+ this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left)
+ )
+ );
+ var top = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxTop,
+ this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top)
+ )
+ );
+ this.slider.knob.left = left + 'px';
+ this.slider.knob.top = top + 'px';
+ if (this.slider.callLeft) {
+ this.color[this.slider.callLeft].call(this.color, left/100);
+ }
+ if (this.slider.callTop) {
+ this.color[this.slider.callTop].call(this.color, top/100);
+ }
+ this.previewColor();
+ this.element.trigger({
+ type: 'changeColor',
+ color: this.color
+ });
+ return false;
+ },
+
+ mouseup: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ $(document).off({
+ mousemove: this.mousemove,
+ mouseup: this.mouseup
+ });
+ return false;
+ }
+ }
+
+ $.fn.colorpicker = function ( option ) {
+ return this.each(function () {
+ var $this = $(this),
+ data = $this.data('colorpicker'),
+ options = typeof option == 'object' && option;
+ if (!data) {
+ $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults,options))));
+ }
+ if (typeof option == 'string') data[option]();
+ });
+ };
+
+ $.fn.colorpicker.defaults = {
+ };
+
+ $.fn.colorpicker.Constructor = Colorpicker;
+
+ var CPGlobal = {
+
+ // translate a format from Color object to a string
+ translateFormats: {
+ 'rgb': function(){
+ var rgb = this.color.toRGB();
+ return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
+ },
+
+ 'rgba': function(){
+ var rgb = this.color.toRGB();
+ return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')';
+ },
+
+ 'hsl': function(){
+ var hsl = this.color.toHSL();
+ return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)';
+ },
+
+ 'hsla': function(){
+ var hsl = this.color.toHSL();
+ return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')';
+ },
+
+ 'hex': function(){
+ return this.color.toHex();
+ }
+ },
+
+ sliders: {
+ saturation: {
+ maxLeft: 100,
+ maxTop: 100,
+ callLeft: 'setSaturation',
+ callTop: 'setLightness'
+ },
+
+ hue: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setHue'
+ },
+
+ alpha: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setAlpha'
+ }
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ RGBtoHSB: function (r, g, b, a){
+ r /= 255;
+ g /= 255;
+ b /= 255;
+
+ var H, S, V, C;
+ V = Math.max(r, g, b);
+ C = V - Math.min(r, g, b);
+ H = (C == 0 ? null :
+ V == r ? (g - b) / C :
+ V == g ? (b - r) / C + 2 :
+ (r - g) / C + 4
+ );
+ H = ((H + 360) % 6) * 60 / 360;
+ S = C == 0 ? 0 : C / V;
+ return {h: H||1, s: S, b: V, a: a||1};
+ },
+
+ HueToRGB: function (p, q, h) {
+ if (h < 0)
+ h += 1;
+ else if (h > 1)
+ h -= 1;
+
+ if ((h * 6) < 1)
+ return p + (q - p) * h * 6;
+ else if ((h * 2) < 1)
+ return q;
+ else if ((h * 3) < 2)
+ return p + (q - p) * ((2 / 3) - h) * 6;
+ else
+ return p;
+ },
+
+ HSLtoRGB: function (h, s, l, a)
+ {
+
+ if (s < 0)
+ s = 0;
+
+ if (l <= 0.5)
+ var q = l * (1 + s);
+ else
+ var q = l + s - (l * s);
+
+ var p = 2 * l - q;
+
+ var tr = h + (1 / 3);
+ var tg = h;
+ var tb = h - (1 / 3);
+
+ var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255);
+ var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255);
+ var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255);
+ return [r, g, b, a||1];
+ },
+
+ // a set of RE's that can match strings and generate color tuples.
+ // from John Resig color plugin
+ // https://github.com/jquery/jquery-color/
+ stringParsers: [
+ {
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ execResult[ 1 ],
+ execResult[ 2 ],
+ execResult[ 3 ],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ 2.55 * execResult[1],
+ 2.55 * execResult[2],
+ 2.55 * execResult[3],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ space: 'hsla',
+ parse: function( execResult ) {
+ return [
+ execResult[1]/360,
+ execResult[2] / 100,
+ execResult[3] / 100,
+ execResult[4]
+ ];
+ }
+ }
+ ],
+ template: '<div class="colorpicker dropdown-menu">'+
+ '<div class="colorpicker-saturation"><i><b></b></i></div>'+
+ '<div class="colorpicker-hue"><i></i></div>'+
+ '<div class="colorpicker-alpha"><i></i></div>'+
+ '<div class="colorpicker-color"><div /></div>'+
+ '</div>'
+ };
+
+}( window.jQuery )
View
401 vendor/assets/javascripts/bootstrap/datepicker.js
@@ -0,0 +1,401 @@
+/* =========================================================
+ * bootstrap-datepicker.js
+ * http://www.eyecon.ro/bootstrap-datepicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+!function( $ ) {
+
+ // Picker object
+
+ var Datepicker = function(element, options){
+ this.element = $(element);
+ this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
+ this.picker = $(DPGlobal.template)
+ .appendTo('body')
+ .on({
+ click: $.proxy(this.click, this),
+ mousedown: $.proxy(this.mousedown, this)
+ });
+ this.isInput = this.element.is('input');
+ this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
+
+ if (this.isInput) {
+ this.element.on({
+ focus: $.proxy(this.show, this),
+ blur: $.proxy(this.hide, this),
+ keyup: $.proxy(this.update, this)
+ });
+ } else {
+ if (this.component){
+ this.component.on('click', $.proxy(this.show, this));
+ } else {
+ this.element.on('click', $.proxy(this.show, this));
+ }
+ }
+
+ this.viewMode = 0;
+ this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
+ this.weekEnd = this.weekStart == 0 ? 6 : this.weekStart - 1;
+ this.fillDow();
+ this.fillMonths();
+ this.update();
+ this.showMode();
+ };
+
+ Datepicker.prototype = {
+ constructor: Datepicker,
+
+ show: function(e) {
+ this.picker.show();
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+ this.place();
+ $(window).on('resize', $.proxy(this.place, this));
+ if (e ) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ if (!this.isInput) {
+ $(document).on('mousedown', $.proxy(this.hide, this));
+ }
+ this.element.trigger({
+ type: 'show',
+ date: this.date
+ });
+ },
+
+ hide: function(){
+ this.picker.hide();
+ $(window).off('resize', this.place);
+ this.viewMode = 0;
+ this.showMode();
+ if (!this.isInput) {
+ $(document).off('mousedown', this.hide);
+ }
+ this.setValue();
+ this.element.trigger({
+ type: 'hide',
+ date: this.date
+ });
+ },
+
+ setValue: function() {
+ var formated = DPGlobal.formatDate(this.date, this.format);
+ if (!this.isInput) {
+ if (this.component){
+ this.element.find('input').prop('value', formated);
+ }
+ this.element.data('date', formated);
+ } else {
+ this.element.prop('value', formated);
+ }
+ },
+
+ place: function(){
+ var offset = this.component ? this.component.offset() : this.element.offset();
+ this.picker.css({
+ top: offset.top + this.height,
+ left: offset.left
+ });
+ },
+
+ update: function(){
+ this.date = DPGlobal.parseDate(
+ this.isInput ? this.element.prop('value') : this.element.data('date'),
+ this.format
+ );
+ this.viewDate = new Date(this.date);
+ this.fill();
+ },
+
+ fillDow: function(){
+ var dowCnt = this.weekStart;
+ var html = '<tr>';
+ while (dowCnt < this.weekStart + 7) {
+ html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
+ }
+ html += '</tr>';
+ this.picker.find('.datepicker-days thead').append(html);
+ },
+
+ fillMonths: function(){
+ var html = '';
+ var i = 0
+ while (i < 12) {
+ html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
+ }
+ this.picker.find('.datepicker-months td').append(html);
+ },
+
+ fill: function() {
+ var d = new Date(this.viewDate),
+ year = d.getFullYear(),
+ month = d.getMonth(),
+ currentDate = this.date.valueOf();
+ this.picker.find('.datepicker-days th:eq(1)')
+ .text(DPGlobal.dates.months[month]+' '+year);
+ var prevMonth = new Date(year, month-1, 28,0,0,0,0),
+ day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
+ prevMonth.setDate(day);
+ prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
+ var nextMonth = new Date(prevMonth);
+ nextMonth.setDate(nextMonth.getDate() + 42);
+ nextMonth = nextMonth.valueOf();
+ html = [];
+ var clsName;
+ while(prevMonth.valueOf() < nextMonth) {
+ if (prevMonth.getDay() == this.weekStart) {
+ html.push('<tr>');
+ }
+ clsName = '';
+ if (prevMonth.getMonth() < month) {
+ clsName += ' old';
+ } else if (prevMonth.getMonth() > month) {
+ clsName += ' new';
+ }
+ if (prevMonth.valueOf() == currentDate) {
+ clsName += ' active';
+ }
+ html.push('<td class="day'+clsName+'">'+prevMonth.getDate() + '</td>');
+ if (prevMonth.getDay() == this.weekEnd) {
+ html.push('</tr>');
+ }
+ prevMonth.setDate(prevMonth.getDate()+1);
+ }
+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
+ var currentYear = this.date.getFullYear();
+
+ var months = this.picker.find('.datepicker-months')
+ .find('th:eq(1)')
+ .text(year)
+ .end()
+ .find('span').removeClass('active');
+ if (currentYear == year) {
+ months.eq(this.date.getMonth()).addClass('active');
+ }
+
+ html = '';
+ year = parseInt(year/10, 10) * 10;
+ var yearCont = this.picker.find('.datepicker-years')
+ .find('th:eq(1)')
+ .text(year + '-' + (year + 9))
+ .end()
+ .find('td');
+ year -= 1;
+ for (var i = -1; i < 11; i++) {
+ html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' active' : '')+'">'+year+'</span>';
+ year += 1;
+ }
+ yearCont.html(html);
+ },
+
+ click: function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ var target = $(e.target).closest('span, td, th');
+ if (target.length == 1) {
+ switch(target[0].nodeName.toLowerCase()) {
+ case 'th':
+ switch(target[0].className) {
+ case 'switch':
+ this.showMode(1);
+ break;
+ case 'prev':
+ case 'next':
+ this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
+ this.viewDate,
+ this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
+ DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1)
+ );
+ this.fill();
+ break;
+ }
+ break;
+ case 'span':
+ if (target.is('.month')) {
+ var month = target.parent().find('span').index(target);
+ this.viewDate.setMonth(month);
+ } else {
+ var year = parseInt(target.text(), 10)||0;
+ this.viewDate.setFullYear(year);
+ }
+ this.showMode(-1);
+ this.fill();
+ break;
+ case 'td':
+ if (target.is('.day')){
+ var day = parseInt(target.text(), 10)||1;
+ var month = this.viewDate.getMonth();
+ if (target.is('.old')) {
+ month -= 1;
+ } else if (target.is('.new')) {
+ month += 1;
+ }
+ var year = this.viewDate.getFullYear();
+ this.date = new Date(year, month, day,0,0,0,0);
+ this.viewDate = new Date(year, month, day,0,0,0,0);
+ this.fill();
+ this.setValue();
+ this.element.trigger({
+ type: 'changeDate',
+ date: this.date
+ });
+ }
+ break;
+ }
+ }
+ },
+
+ mousedown: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ },
+
+ showMode: function(dir) {
+ if (dir) {
+ this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
+ }
+ this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
+ }
+ };
+
+ $.fn.datepicker = function ( option ) {
+ return this.each(function () {
+ var $this = $(this),
+ data = $this.data('datepicker'),
+ options = typeof option == 'object' && option;
+ if (!data) {
+ $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
+ }
+ if (typeof option == 'string') data[option]();
+ });
+ };
+
+ $.fn.datepicker.defaults = {
+ };
+ $.fn.datepicker.Constructor = Datepicker;
+
+ var DPGlobal = {
+ modes: [
+ {
+ clsName: 'days',
+ navFnc: 'Month',
+ navStep: 1
+ },
+ {
+ clsName: 'months',
+ navFnc: 'FullYear',
+ navStep: 1
+ },
+ {
+ clsName: 'years',
+ navFnc: 'FullYear',
+ navStep: 10
+ }],
+ dates:{
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+ },
+ isLeapYear: function (year) {
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
+ },
+ getDaysInMonth: function (year, month) {
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
+ },
+ parseFormat: function(format){
+ var separator = format.match(/[.\/-].*?/),
+ parts = format.split(/\W+/);
+ if (!separator || !parts || parts.length == 0){
+ throw new Error("Invalid date format.");
+ }
+ return {separator: separator, parts: parts};
+ },
+ parseDate: function(date, format) {
+ var parts = date.split(format.separator),
+ date = new Date(1970, 1, 1, 0, 0, 0),
+ val;
+ if (parts.length == format.parts.length) {
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
+ val = parseInt(parts[i], 10)||1;
+ switch(format.parts[i]) {
+ case 'dd':
+ case 'd':
+ date.setDate(val);
+ break;
+ case 'mm':
+ case 'm':
+ date.setMonth(val - 1);
+ break;
+ case 'yy':
+ date.setFullYear(2000 + val);
+ break;
+ case 'yyyy':
+ date.setFullYear(val);
+ break;
+ }
+ }
+ }
+ return date;
+ },
+ formatDate: function(date, format){
+ var val = {
+ d: date.getDate(),
+ m: date.getMonth() + 1,
+ yy: date.getFullYear().toString().substring(2),
+ yyyy: date.getFullYear()
+ };
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
+ var date = [];
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
+ date.push(val[format.parts[i]]);
+ }
+ return date.join(format.separator);
+ },
+ headTemplate: '<thead>'+
+ '<tr>'+
+ '<th class="prev"><i class="icon-arrow-left"/></th>'+
+ '<th colspan="5" class="switch"></th>'+
+ '<th class="next"><i class="icon-arrow-right"/></th>'+
+ '</tr>'+
+ '</thead>',
+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
+ };
+ DPGlobal.template = '<div class="datepicker dropdown-menu">'+
+ '<div class="datepicker-days">'+
+ '<table class=" table-condensed">'+
+ DPGlobal.headTemplate+
+ '<tbody></tbody>'+
+ '</table>'+
+ '</div>'+
+ '<div class="datepicker-months">'+
+ '<table class="table-condensed">'+
+ DPGlobal.headTemplate+
+ DPGlobal.contTemplate+
+ '</table>'+
+ '</div>'+
+ '<div class="datepicker-years">'+
+ '<table class="table-condensed">'+
+ DPGlobal.headTemplate+
+ DPGlobal.contTemplate+
+ '</table>'+
+ '</div>'+
+ '</div>';
+
+}( window.jQuery )
View
387 vendor/assets/javascripts/bootstrap/image-gallery.js
@@ -0,0 +1,387 @@
+/*
+ * Bootstrap Image Gallery 2.8
+ * https://github.com/blueimp/Bootstrap-Image-Gallery
+ *
+ * Copyright 2011, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint nomen: true, regexp: true */
+/*global define, window, document, jQuery */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'load-image',
+ 'bootstrap'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery,
+ window.loadImage
+ );
+ }
+}(function ($, loadImage) {
+ 'use strict';
+ // Bootstrap Image Gallery is an extension to the Modal dialog of Twitter's
+ // Bootstrap toolkit, to ease navigation between a set of gallery images.
+ // It features transition effects, fullscreen mode and slideshow functionality.
+ $.extend($.fn.modal.defaults, {
+ // Delegate to search gallery links from, can be anything that
+ // is accepted as parameter for $():
+ delegate: document,
+ // Selector for gallery links:
+ selector: null,
+ // The filter for the selected gallery links (e.g. set to ":odd" to
+ // filter out label and thumbnail linking twice to the same image):
+ filter: '*',
+ // The index of the first gallery image to show:
+ index: 0,
+ // The href of the first gallery image to show (overrides index):
+ href: null,
+ // The range of images around the current one to preload:
+ preloadRange: 2,
+ // Offset of image width to viewport width:
+ offsetWidth: 100,
+ // Offset of image height to viewport height:
+ offsetHeight: 200,
+ // Set to true to display images as canvas elements:
+ canvas: false,
+ // Shows the next image after the given time in ms (0 = disabled):
+ slideshow: 0,
+ // Defines the image division for previous/next clicks:
+ imageClickDivision: 0.5
+ });
+ var originalShow = $.fn.modal.Constructor.prototype.show,
+ originalHide = $.fn.modal.Constructor.prototype.hide;
+ $.extend($.fn.modal.Constructor.prototype, {
+ initLinks: function () {
+ var $this = this,
+ options = this.options,
+ selector = options.selector ||
+ 'a[data-target=' + options.target + ']';
+ this.$links = $(options.delegate).find(selector)
+ .filter(options.filter).each(function (index) {
+ if ($this.getUrl(this) === options.href) {
+ options.index = index;
+ }
+ });
+ if (!this.$links[options.index]) {
+ options.index = 0;
+ }
+ },
+ getUrl: function (element) {
+ return element.href || $(element).data('href');
+ },
+ startSlideShow: function () {
+ var $this = this;
+ if (this.options.slideshow) {
+ this._slideShow = window.setTimeout(
+ function () {
+ $this.next();
+ },
+ this.options.slideshow
+ );
+ }
+ },
+ stopSlideShow: function () {
+ window.clearTimeout(this._slideShow);
+ },
+ toggleSlideShow: function () {
+ var node = this.$element.find('.modal-slideshow');
+ if (this.options.slideshow) {
+ this.options.slideshow = 0;
+ this.stopSlideShow();
+ } else {
+ this.options.slideshow = node.data('slideshow') || 5000;
+ this.startSlideShow();
+ }
+ node.find('i').toggleClass('icon-play icon-pause');
+ },
+ preloadImages: function () {
+ var options = this.options,
+ range = options.index + options.preloadRange + 1,
+ link,
+ i;
+ for (i = options.index - options.preloadRange; i < range; i += 1) {
+ link = this.$links[i];
+ if (link && i !== options.index) {
+ $('<img>').prop('src', this.getUrl(link));
+ }
+ }
+ },
+ loadImage: function () {
+ var $this = this,
+ modal = this.$element,
+ index = this.options.index,
+ url = this.getUrl(this.$links[index]),
+ oldImg;
+ this.abortLoad();
+ this.stopSlideShow();
+ modal.trigger('beforeLoad');
+ // The timeout prevents displaying a loading status,
+ // if the image has already been loaded:
+ this._loadingTimeout = window.setTimeout(function () {
+ modal.addClass('modal-loading');
+ }, 100);
+ oldImg = modal.find('.modal-image').children().removeClass('in');
+ // The timeout allows transition effects to finish:
+ window.setTimeout(function () {
+ oldImg.remove();
+ }, 3000);
+ modal.find('.modal-title').text(this.$links[index].title);
+ modal.find('.modal-download').prop(
+ 'href',
+ url
+ );
+ this._loadingImage = loadImage(
+ url,
+ function (img) {
+ $this.img = img;
+ window.clearTimeout($this._loadingTimeout);
+ modal.removeClass('modal-loading');
+ modal.trigger('load');
+ $this.showImage(img);
+ $this.startSlideShow();
+ },
+ this._loadImageOptions
+ );
+ this.preloadImages();
+ },
+ showImage: function (img) {
+ var modal = this.$element,
+ transition = $.support.transition && modal.hasClass('fade'),
+ method = transition ? modal.animate : modal.css,
+ modalImage = modal.find('.modal-image'),
+ clone,
+ forceReflow;
+ modalImage.css({
+ width: img.width,
+ height: img.height
+ });
+ modal.find('.modal-title').css({ width: Math.max(img.width, 380) });
+ if ($(window).width() > 480) {
+ if (transition) {
+ clone = modal.clone().hide().appendTo(document.body);
+ }
+ method.call(modal.stop(), {
+ 'margin-top': -((clone || modal).outerHeight() / 2),
+ 'margin-left': -((clone || modal).outerWidth() / 2)
+ });
+ if (clone) {
+ clone.remove();
+ }
+ }
+ modalImage.append(img);
+ forceReflow = img.offsetWidth;
+ modal.trigger('display');
+ if (transition) {
+ if (modal.is(':visible')) {
+ $(img).on(
+ $.support.transition.end,
+ function (e) {
+ // Make sure we don't respond to other transitions events
+ // in the container element, e.g. from button elements:
+ if (e.target === img) {
+ $(img).off($.support.transition.end);
+ modal.trigger('displayed');
+ }
+ }
+ ).addClass('in');
+ } else {
+ $(img).addClass('in');
+ modal.one('shown', function () {
+ modal.trigger('displayed');
+ });
+ }
+ } else {
+ $(img).addClass('in');
+ modal.trigger('displayed');
+ }
+ },
+ abortLoad: function () {
+ if (this._loadingImage) {
+ this._loadingImage.onload = this._loadingImage.onerror = null;
+ }
+ window.clearTimeout(this._loadingTimeout);
+ },
+ prev: function () {
+ var options = this.options;
+ options.index -= 1;
+ if (options.index < 0) {
+ options.index = this.$links.length - 1;
+ }
+ this.loadImage();
+ },
+ next: function () {
+ var options = this.options;
+ options.index += 1;
+ if (options.index > this.$links.length - 1) {
+ options.index = 0;
+ }
+ this.loadImage();
+ },
+ keyHandler: function (e) {
+ switch (e.which) {
+ case 37: // left
+ case 38: // up
+ e.preventDefault();
+ this.prev();
+ break;
+ case 39: // right
+ case 40: // down
+ e.preventDefault();
+ this.next();
+ break;
+ }
+ },
+ wheelHandler: function (e) {
+ e.preventDefault();
+ e = e.originalEvent;
+ this._wheelCounter = this._wheelCounter || 0;
+ this._wheelCounter += (e.wheelDelta || e.detail || 0);
+ if ((e.wheelDelta && this._wheelCounter >= 120) ||
+ (!e.wheelDelta && this._wheelCounter < 0)) {
+ this.prev();
+ this._wheelCounter = 0;
+ } else if ((e.wheelDelta && this._wheelCounter <= -120) ||
+ (!e.wheelDelta && this._wheelCounter > 0)) {
+ this.next();
+ this._wheelCounter = 0;
+ }
+ },
+ initGalleryEvents: function () {
+ var $this = this,
+ modal = this.$element;
+ modal.find('.modal-image').on('click.modal-gallery', function (e) {
+ var modalImage = $(this);
+ if ($this.$links.length === 1) {
+ $this.hide();
+ } else {
+ if ((e.pageX - modalImage.offset().left) / modalImage.width() <
+ $this.options.imageClickDivision) {
+ $this.prev(e);
+ } else {
+ $this.next(e);
+ }
+ }
+ });
+ modal.find('.modal-prev').on('click.modal-gallery', function (e) {
+ $this.prev(e);
+ });
+ modal.find('.modal-next').on('click.modal-gallery', function (e) {
+ $this.next(e);
+ });
+ modal.find('.modal-slideshow').on('click.modal-gallery', function (e) {
+ $this.toggleSlideShow(e);
+ });
+ $(document)
+ .on('keydown.modal-gallery', function (e) {
+ $this.keyHandler(e);
+ })
+ .on(
+ 'mousewheel.modal-gallery, DOMMouseScroll.modal-gallery',
+ function (e) {
+ $this.wheelHandler(e);
+ }
+ );
+ },
+ destroyGalleryEvents: function () {
+ var modal = this.$element;
+ this.abortLoad();
+ this.stopSlideShow();
+ modal.find('.modal-image, .modal-prev, .modal-next, .modal-slideshow')
+ .off('click.modal-gallery');
+ $(document)
+ .off('keydown.modal-gallery')
+ .off('mousewheel.modal-gallery, DOMMouseScroll.modal-gallery');
+ },
+ show: function () {
+ if (!this.isShown && this.$element.hasClass('modal-gallery')) {
+ var modal = this.$element,
+ options = this.options,
+ windowWidth = $(window).width(),
+ windowHeight = $(window).height();
+ if (modal.hasClass('modal-fullscreen')) {
+ this._loadImageOptions = {
+ maxWidth: windowWidth,
+ maxHeight: windowHeight,
+ canvas: options.canvas
+ };
+ if (modal.hasClass('modal-fullscreen-stretch')) {
+ this._loadImageOptions.minWidth = windowWidth;
+ this._loadImageOptions.minHeight = windowHeight;
+ }
+ } else {
+ this._loadImageOptions = {
+ maxWidth: windowWidth - options.offsetWidth,
+ maxHeight: windowHeight - options.offsetHeight,
+ canvas: options.canvas
+ };
+ }
+ if (windowWidth > 480) {
+ modal.css({
+ 'margin-top': -(modal.outerHeight() / 2),
+ 'margin-left': -(modal.outerWidth() / 2)
+ });
+ }
+ this.initGalleryEvents();
+ this.initLinks();
+ if (this.$links.length) {
+ modal.find('.modal-slideshow, .modal-prev, .modal-next')
+ .toggle(this.$links.length !== 1);
+ modal.toggleClass(
+ 'modal-single',
+ this.$links.length === 1
+ );
+ this.loadImage();
+ }
+ }
+ originalShow.apply(this, arguments);
+ },
+ hide: function () {
+ if (this.isShown && this.$element.hasClass('modal-gallery')) {
+ this.options.delegate = document;
+ this.options.href = null;
+ this.destroyGalleryEvents();
+ }
+ originalHide.apply(this, arguments);
+ }
+ });
+ $(function () {
+ $(document.body).on(
+ 'click.modal-gallery.data-api',
+ '[data-toggle="modal-gallery"]',
+ function (e) {
+ var $this = $(this),
+ options = $this.data(),
+ modal = $(options.target),
+ data = modal.data('modal'),
+ link;
+ if (!data) {
+ options = $.extend(modal.data(), options);
+ }
+ if (!options.selector) {
+ options.selector = 'a[rel=gallery]';
+ }
+ link = $(e.target).closest(options.selector);
+ if (link.length && modal.length) {
+ e.preventDefault();
+ options.href = link.prop('href') || link.data('href');
+ options.delegate = link[0] !== this ? this : document;
+ if (data) {
+ $.extend(data.options, options);
+ }
+ modal.modal(options);
+ }
+ }
+ );
+ });
+}));
View
1  vendor/assets/javascripts/bootstrap/image-gallery.min.js
@@ -0,0 +1 @@
+(function(a){"use strict",typeof define=="function"&&define.amd?define(["jquery","load-image","bootstrap"],a):a(window.jQuery,window.loadImage)})(function(a,b){"use strict",a.extend(a.fn.modal.defaults,{delegate:document,selector:null,filter:"*",index:0,href:null,preloadRange:2,offsetWidth:100,offsetHeight:200,canvas:!1,slideshow:0,imageClickDivision:.5});var c=a.fn.modal.Constructor.prototype.show,d=a.fn.modal.Constructor.prototype.hide;a.extend(a.fn.modal.Constructor.prototype,{initLinks:function(){var b=this,c=this.options,d=c.selector||"a[data-target="+c.target+"]";this.$links=a(c.delegate).find(d).filter(c.filter).each(function(a){b.getUrl(this)===c.href&&(c.index=a)}),this.$links[c.index]||(c.index=0)},getUrl:function(b){return b.href||a(b).data("href")},startSlideShow:function(){var a=this;this.options.slideshow&&(this._slideShow=window.setTimeout(function(){a.next()},this.options.slideshow))},stopSlideShow:function(){window.clearTimeout(this._slideShow)},toggleSlideShow:function(){var a=this.$element.find(".modal-slideshow");this.options.slideshow?(this.options.slideshow=0,this.stopSlideShow()):(this.options.slideshow=a.data("slideshow")||5e3,this.startSlideShow()),a.find("i").toggleClass("icon-play icon-pause")},preloadImages:function(){var b=this.options,c=b.index+b.preloadRange+1,d,e;for(e=b.index-b.preloadRange;e<c;e+=1)d=this.$links[e],d&&e!==b.index&&a("<img>").prop("src",this.getUrl(d))},loadImage:function(){var a=this,c=this.$element,d=this.options.index,e=this.getUrl(this.$links[d]),f;this.abortLoad(),this.stopSlideShow(),c.trigger("beforeLoad"),this._loadingTimeout=window.setTimeout(function(){c.addClass("modal-loading")},100),f=c.find(".modal-image").children().removeClass("in"),window.setTimeout(function(){f.remove()},3e3),c.find(".modal-title").text(this.$links[d].title),c.find(".modal-download").prop("href",e),this._loadingImage=b(e,function(b){a.img=b,window.clearTimeout(a._loadingTimeout),c.removeClass("modal-loading"),c.trigger("load"),a.showImage(b),a.startSlideShow()},this._loadImageOptions),this.preloadImages()},showImage:function(b){var c=this.$element,d=a.support.transition&&c.hasClass("fade"),e=d?c.animate:c.css,f=c.find(".modal-image"),g,h;f.css({width:b.width,height:b.height}),c.find(".modal-title").css({width:Math.max(b.width,380)}),a(window).width()>480&&(d&&(g=c.clone().hide().appendTo(document.body)),e.call(c.stop(),{"margin-top":-((g||c).outerHeight()/2),"margin-left":-((g||c).outerWidth()/2)}),g&&g.remove()),f.append(b),h=b.offsetWidth,c.trigger("display"),d?c.is(":visible")?a(b).on(a.support.transition.end,function(d){d.target===b&&(a(b).off(a.support.transition.end),c.trigger("displayed"))}).addClass("in"):(a(b).addClass("in"),c.one("shown",function(){c.trigger("displayed")})):(a(b).addClass("in"),c.trigger("displayed"))},abortLoad:function(){this._loadingImage&&(this._loadingImage.onload=this._loadingImage.onerror=null),window.clearTimeout(this._loadingTimeout)},prev:function(){var a=this.options;a.index-=1,a.index<0&&(a.index=this.$links.length-1),this.loadImage()},next:function(){var a=this.options;a.index+=1,a.index>this.$links.length-1&&(a.index=0),this.loadImage()},keyHandler:function(a){switch(a.which){case 37:case 38:a.preventDefault(),this.prev();break;case 39:case 40:a.preventDefault(),this.next()}},wheelHandler:function(a){a.preventDefault(),a=a.originalEvent,this._wheelCounter=this._wheelCounter||0,this._wheelCounter+=a.wheelDelta||a.detail||0;if(a.wheelDelta&&this._wheelCounter>=120||!a.wheelDelta&&this._wheelCounter<0)this.prev(),this._wheelCounter=0;else if(a.wheelDelta&&this._wheelCounter<=-120||!a.wheelDelta&&this._wheelCounter>0)this.next(),this._wheelCounter=0},initGalleryEvents:function(){var b=this,c=this.$element;c.find(".modal-image").on("click.modal-gallery",function(c){var d=a(this);b.$links.length===1?b.hide():(c.pageX-d.offset().left)/d.width()<b.options.imageClickDivision?b.prev(c):b.next(c)}),c.find(".modal-prev").on("click.modal-gallery",function(a){b.prev(a)}),c.find(".modal-next").on("click.modal-gallery",function(a){b.next(a)}),c.find(".modal-slideshow").on("click.modal-gallery",function(a){b.toggleSlideShow(a)}),a(document).on("keydown.modal-gallery",function(a){b.keyHandler(a)}).on("mousewheel.modal-gallery, DOMMouseScroll.modal-gallery",function(a){b.wheelHandler(a)})},destroyGalleryEvents:function(){var b=this.$element;this.abortLoad(),this.stopSlideShow(),b.find(".modal-image, .modal-prev, .modal-next, .modal-slideshow").off("click.modal-gallery"),a(document).off("keydown.modal-gallery").off("mousewheel.modal-gallery, DOMMouseScroll.modal-gallery")},show:function(){if(!this.isShown&&this.$element.hasClass("modal-gallery")){var b=this.$element,d=this.options,e=a(window).width(),f=a(window).height();b.hasClass("modal-fullscreen")?(this._loadImageOptions={maxWidth:e,maxHeight:f,canvas:d.canvas},b.hasClass("modal-fullscreen-stretch")&&(this._loadImageOptions.minWidth=e,this._loadImageOptions.minHeight=f)):this._loadImageOptions={maxWidth:e-d.offsetWidth,maxHeight:f-d.offsetHeight,canvas:d.canvas},e>480&&b.css({"margin-top":-(b.outerHeight()/2),"margin-left":-(b.outerWidth()/2)}),this.initGalleryEvents(),this.initLinks(),this.$links.length&&(b.find(".modal-slideshow, .modal-prev, .modal-next").toggle(this.$links.length!==1),b.toggleClass("modal-single",this.$links.length===1),this.loadImage())}c.apply(this,arguments)},hide:function(){this.isShown&&this.$element.hasClass("modal-gallery")&&(this.options.delegate=document,this.options.href=null,this.destroyGalleryEvents()),d.apply(this,arguments)}}),a(function(){a(document.body).on("click.modal-gallery.data-api",'[data-toggle="modal-gallery"]',function(b){var c=a(this),d=c.data(),e=a(d.target),f=e.data("modal"),g;f||(d=a.extend(e.data(),d)),d.selector||(d.selector="a[rel=gallery]"),g=a(b.target).closest(d.selector),g.length&&e.length&&(b.preventDefault(),d.href=g.prop("href")||g.data("href"),d.delegate=g[0]!==this?this:document,f&&a.extend(f.options,d),e.modal(d))})})});
View
89 vendor/assets/less/bootstrap/colorpicker.less
@@ -0,0 +1,89 @@
+.colorpicker-saturation {
+ width: 100px;
+ height: 100px;
+ background-image: url(../img/saturation.png);
+ cursor: crosshair;
+ float: left;
+ i {
+ display: block;
+ height: 5px;
+ width: 5px;
+ border: 1px solid #000;
+ .border-radius();