diff --git a/.gitignore b/.gitignore index 4ef0a06d..65cbda82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ *DS_STORE -/Gemfile.lock \ No newline at end of file +/Gemfile.lock +*.gem +coverage/ +log/ +tmp/ +.ruby-version +history.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..f68ed763 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: ruby +rvm: + - 2.3.0 + - 2.2.4 + - 2.1.8 + +script: "rake test" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..6b22e83f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,16 @@ + +## Have an Issue? + +Dashing is no longer being actively maintained. + +1. Check the [Troubleshooting Guide](https://github.com/Shopify/dashing/wiki#how-tos) in the wiki. +2. Use the [GitHub Issue Search](https://help.github.com/articles/searching-issues/) to check if the issue has already been reported. +3. You can ask your issue on the tracker, but your best bet is to go to [Stack Overflow](http://stackoverflow.com/questions/tagged/dashing) + + + + +If you feel that you have a really amazing, super neato idea that should be a part of Dashing, it may be a good candidate for an external Gem which supercharges a project. An excellent example of this is +[dashing-contrib](https://github.com/QubitProducts/dashing-contrib). If you +do create a third-party extension for Dashing, please add it [here](https://github.com/Shopify/dashing/wiki/Additional-Widgets#other-third-party-tools). + diff --git a/MIT-LICENSE b/MIT-LICENSE index ade20390..ac9f2bf4 100644 --- a/MIT-LICENSE +++ b/MIT-LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012 AUTHOR_NAME +Copyright (c) 2016 Shopify Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index cdcc722a..fb9f286a 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -Check out the [Homepage](http://shopify.github.com/dashing) \ No newline at end of file +# [Dashing](http://shopify.github.com/dashing) +[![Build Status](https://secure.travis-ci.org/Shopify/dashing.png?branch=master)](http://travis-ci.org/Shopify/dashing) + +Dashing is a Sinatra based framework that lets you build beautiful dashboards. It looks especially great on TVs. + +[Check out the homepage](http://shopify.github.com/dashing). + +Note: Dashing is no longer being actively maintained. Read about it [here](https://github.com/Shopify/dashing/issues/711). There is a fork of the project being maintained at at [https://github.com/dashing-io/dashing](https://github.com/dashing-io/dashing) + +# License +Distributed under the [MIT license](MIT-LICENSE) diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..fc919698 --- /dev/null +++ b/Rakefile @@ -0,0 +1,11 @@ +require 'rubygems' +require 'rake' +require 'bundler/gem_tasks' + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.libs << 'lib' << 'test' + test.pattern = 'test/**/*_test.rb' +end + +task :default => [:test] diff --git a/bin/dashing b/bin/dashing index fb1332f5..cce9340e 100755 --- a/bin/dashing +++ b/bin/dashing @@ -1,83 +1,9 @@ #!/usr/bin/env ruby - -require 'thor' -require 'net/http' -require 'json' - -class MockScheduler - def method_missing(*args) - yield - end -end - -def send_event(id, data) - req = Net::HTTP::Post.new("/widgets/#{id}") - req["content-type"] = "application/json" - req.body = JSON.unparse(data.merge(:auth_token => Dashing::CLI.auth_token)) - res = Net::HTTP.new('localhost', 3030).start { |http| http.request(req) } - puts "Data Sent to #{id}: #{data}" -end - -SCHEDULER = MockScheduler.new - -module Dashing - - class CLI < Thor - include Thor::Actions - - class << self - attr_accessor :auth_token - end - - attr_accessor :name - - no_tasks do - ['widget', 'dashboard', 'job'].each do |type| - define_method "generate_#{type}" do |name| - @name = Thor::Util.snake_case(name) - directory type.to_sym, File.join("#{type}s") - end - end - end - - def self.source_root - File.expand_path('../../templates', __FILE__) - end - - desc "new PROJECT_NAME", "Sets up ALL THE THINGS needed for your dashboard project." - def new(name) - @name = Thor::Util.snake_case(name) - directory :project, @name - end - - desc "generate (widget/dashboard/job) NAME", "Creates a new widget, dashboard, or job." - def generate(type, name) - send("generate_#{type}".to_sym, name) - rescue NoMethodError => e - puts "Invalid generator. Either use widget, dashboard, or job" - end - map "g" => :generate - - desc "start", "Starts the server in style!" - method_option :job_path, :desc => "Specify the directory where jobs are stored" - def start(*args) - port_option = args.include?('-p')? '' : ' -p 3030' - args = args.join(" ") - command = "bundle exec thin -R config.ru start #{port_option} #{args}" - command.prepend "export JOB_PATH=#{options[:job_path]}; " if options[:job_path] - system(command) - end - map "s" => :start - - desc "job JOB_NAME AUTH_TOKEN(optional)", "Runs the specified job. Make sure to supply your auth token if you have one set." - def job(name, auth_token = "") - Dir[File.join(Dir.pwd, 'lib/**/*.rb')].each {|file| require file } - self.class.auth_token = auth_token - f = File.join(Dir.pwd, "jobs", "#{name}.rb") - require f - end - - end -end - -Dashing::CLI.start \ No newline at end of file +require "pathname" +bin_file = Pathname.new(__FILE__).realpath +$:.unshift File.expand_path("../../lib", bin_file) + +require 'dashing/cli' +require 'dashing/downloader' +Dashing::CLI.source_root(File.expand_path('../../templates', bin_file)) +Dashing::CLI.start(ARGV) diff --git a/dashing.gemspec b/dashing.gemspec index d9201379..5ec586b0 100644 --- a/dashing.gemspec +++ b/dashing.gemspec @@ -1,26 +1,36 @@ +# -*- encoding: utf-8 -*- + Gem::Specification.new do |s| s.name = 'dashing' - s.version = '1.0' - s.date = '2012-10-30' - s.executables << 'dashing' + s.version = '1.3.7' + s.date = '2016-04-11' + s.executables = %w(dashing) s.summary = "The exceptionally handsome dashboard framework." s.description = "This framework lets you build & easily layout dashboards with your own custom widgets. Use it to make a status boards for your ops team, or use it to track signups, conversion rates, or whatever else metrics you'd like to see in one spot. Included with the framework are ready-made widgets for you to use or customize. All of this code was extracted out of a project at Shopify that displays dashboards on TVs around the office." s.author = "Daniel Beauchamp" s.email = 'daniel.beauchamp@shopify.com' - s.files = ["lib/Dashing.rb"] s.homepage = 'http://shopify.github.com/dashing' + s.license = "MIT" s.files = Dir['README.md', 'javascripts/**/*', 'templates/**/*','templates/**/.[a-z]*', 'lib/**/*'] - s.add_dependency('sass') - s.add_dependency('coffee-script') - s.add_dependency('sinatra') - s.add_dependency('sinatra-contrib') - s.add_dependency('thin') - s.add_dependency('rufus-scheduler') - s.add_dependency('thor') - s.add_dependency('sprockets') + s.add_dependency('sass', '~> 3.2.12') + s.add_dependency('coffee-script', '~> 2.2.0') + s.add_dependency('execjs', '~> 2.0.2') + s.add_dependency('sinatra', '~> 1.4.4') + s.add_dependency('sinatra-contrib', '~> 1.4.2') + s.add_dependency('thin', '~> 1.6.1') + s.add_dependency('rufus-scheduler', '~> 2.0.24') + s.add_dependency('thor', '> 0.18.1') + s.add_dependency('sprockets', '~> 2.10.1') + s.add_dependency('rack', '~> 1.5.4') -end \ No newline at end of file + s.add_development_dependency('rake', '~> 10.1.0') + s.add_development_dependency('haml', '~> 4.0.4') + s.add_development_dependency('minitest', '~> 5.2.0') + s.add_development_dependency('mocha', '~> 0.14.0') + s.add_development_dependency('fakeweb', '~> 1.3.0') + s.add_development_dependency('simplecov', '~> 0.8.2') +end diff --git a/javascripts/batman.jquery.js b/javascripts/batman.jquery.js index 0716b0e3..30843e84 100644 --- a/javascripts/batman.jquery.js +++ b/javascripts/batman.jquery.js @@ -49,6 +49,9 @@ Batman.DOM.willInsertNode(child); jQuery(parent).append(child); return Batman.DOM.didInsertNode(child); + }, + innerText: function(node) { + return jQuery(node).text(); } }); @@ -66,8 +69,7 @@ }; Batman.Request.prototype._prepareOptions = function(data) { - var options, _ref, - _this = this; + var options, _ref, _this = this; options = { url: this.get('url'), type: this.get('method'), diff --git a/javascripts/batman.js b/javascripts/batman.js index c4e5f342..2619c942 100644 --- a/javascripts/batman.js +++ b/javascripts/batman.js @@ -1,18 +1,19 @@ (function() { - var Batman, - __slice = [].slice; + var Batman, __slice = [].slice; Batman = function() { var mixins; mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return (function(func, args, ctor) { ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; + var child = new ctor, + result = func.apply(child, args), + t = typeof result; return t == "object" || t == "function" ? result || child : child; - })(Batman.Object, mixins, function(){}); + })(Batman.Object, mixins, function() {}); }; - Batman.version = '0.13.0'; + Batman.version = '0.14.1'; Batman.config = { pathPrefix: '/', @@ -49,10 +50,129 @@ }).call(this); (function() { - var _implementImmediates, _objectToString, - __slice = [].slice, + var _Batman; + + Batman._Batman = _Batman = (function() { + + function _Batman(object) { + this.object = object; + } + + _Batman.prototype.check = function(object) { + if (object !== this.object) { + object._batman = new Batman._Batman(object); + return false; + } + return true; + }; + + _Batman.prototype.get = function(key) { + var reduction, results; + results = this.getAll(key); + switch (results.length) { + case 0: + return void 0; + case 1: + return results[0]; + default: + reduction = results[0].concat != null ? + function(a, b) { + return a.concat(b); + } : results[0].merge != null ? + function(a, b) { + return a.merge(b); + } : results.every(function(x) { + return typeof x === 'object'; + }) ? (results.unshift({}), function(a, b) { + return Batman.extend(a, b); + }) : void 0; + if (reduction) { + return results.reduceRight(reduction); + } else { + return results; + } + } + }; + + _Batman.prototype.getFirst = function(key) { + var results; + results = this.getAll(key); + return results[0]; + }; + + _Batman.prototype.getAll = function(keyOrGetter) { + var getter, results, val; + if (typeof keyOrGetter === 'function') { + getter = keyOrGetter; + } else { + getter = function(ancestor) { + var _ref; + return (_ref = ancestor._batman) != null ? _ref[keyOrGetter] : void 0; + }; + } + results = this.ancestors(getter); + if (val = getter(this.object)) { + results.unshift(val); + } + return results; + }; + + _Batman.prototype.ancestors = function(getter) { + var ancestor, results, val, _i, _len, _ref; + this._allAncestors || (this._allAncestors = this.allAncestors()); + if (getter) { + results = []; + _ref = this._allAncestors; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + ancestor = _ref[_i]; + val = getter(ancestor); + if (val != null) { + results.push(val); + } + } + return results; + } else { + return this._allAncestors; + } + }; + + _Batman.prototype.allAncestors = function() { + var isClass, parent, proto, results, _ref, _ref1; + results = []; + isClass = !! this.object.prototype; + parent = isClass ? (_ref = this.object.__super__) != null ? _ref.constructor : void 0 : (proto = Object.getPrototypeOf(this.object)) === this.object ? this.object.constructor.__super__ : proto; + if (parent != null) { + if ((_ref1 = parent._batman) != null) { + _ref1.check(parent); + } + results.push(parent); + if (parent._batman != null) { + results = results.concat(parent._batman.allAncestors()); + } + } + return results; + }; + + _Batman.prototype.set = function(key, value) { + return this[key] = value; + }; + + return _Batman; + + })(); + +}).call(this); + +(function() { + var chr, _encodedChars, _encodedCharsPattern, _entityMap, _implementImmediates, _objectToString, _unsafeChars, _unsafeCharsPattern, __slice = [].slice, __hasProp = {}.hasOwnProperty, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + __indexOf = [].indexOf || + function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; + }; Batman.typeOf = function(object) { if (typeof object === 'undefined') { @@ -147,8 +267,6 @@ return false; }; - Batman.setImmediate = Batman.clearImmediate = null; - _implementImmediates = function(container) { var canUsePostMessage, count, functions, getHandle, handler, prefix, tasks; canUsePostMessage = function() { @@ -170,12 +288,9 @@ getHandle = function() { return "go" + (++count); }; - if (container.setImmediate) { + if (container.setImmediate && container.clearImmediate) { Batman.setImmediate = container.setImmediate; - Batman.clearImmediate = container.clearImmediate; - } else if (container.msSetImmediate) { - Batman.setImmediate = msSetImmediate; - Batman.clearImmediate = msClearImmediate; + return Batman.clearImmediate = container.clearImmediate; } else if (canUsePostMessage()) { prefix = 'com.batman.'; functions = new Batman.SimpleHash; @@ -185,7 +300,7 @@ return; } handle = e.data.substring(prefix.length); - return typeof (_base = tasks.unset(handle)) === "function" ? _base() : void 0; + return typeof(_base = tasks.unset(handle)) === "function" ? _base() : void 0; }; if (container.addEventListener) { container.addEventListener('message', handler, false); @@ -198,7 +313,7 @@ container.postMessage(prefix + handle, "*"); return handle; }; - Batman.clearImmediate = function(handle) { + return Batman.clearImmediate = function(handle) { return tasks.unset(handle); }; } else if (typeof document !== 'undefined' && __indexOf.call(document.createElement("script"), "onreadystatechange") >= 0) { @@ -208,7 +323,7 @@ script = document.createElement("script"); script.onreadystatechange = function() { var _base; - if (typeof (_base = tasks.get(handle)) === "function") { + if (typeof(_base = tasks.get(handle)) === "function") { _base(); } script.onreadystatechange = null; @@ -218,7 +333,7 @@ document.documentElement.appendChild(script); return handle; }; - Batman.clearImmediate = function(handle) { + return Batman.clearImmediate = function(handle) { return tasks.unset(handle); }; } else if (typeof process !== "undefined" && process !== null ? process.nextTick : void 0) { @@ -235,19 +350,17 @@ }); return handle; }; - Batman.clearImmediate = function(handle) { + return Batman.clearImmediate = function(handle) { return delete functions[handle]; }; } else { Batman.setImmediate = function(f) { return setTimeout(f, 0); }; - Batman.clearImmediate = function(handle) { + return Batman.clearImmediate = function(handle) { return clearTimeout(handle); }; } - Batman.setImmediate = Batman.setImmediate; - return Batman.clearImmediate = Batman.clearImmediate; }; Batman.setImmediate = function() { @@ -323,22 +436,47 @@ return base; }; + _entityMap = { + "&": "&", + "<": "<", + ">": ">", + "\"": """, + "'": "'" + }; + + _unsafeChars = []; + + _encodedChars = []; + + for (chr in _entityMap) { + _unsafeChars.push(chr); + _encodedChars.push(_entityMap[chr]); + } + + _unsafeCharsPattern = new RegExp("[" + (_unsafeChars.join('')) + "]", "g"); + + _encodedCharsPattern = new RegExp("(" + (_encodedChars.join('|')) + ")", "g"); + Batman.escapeHTML = (function() { - var replacements; - replacements = { - "&": "&", - "<": "<", - ">": ">", - "\"": """, - "'": "'" - }; return function(s) { - return ("" + s).replace(/[&<>'"]/g, function(c) { - return replacements[c]; + return ("" + s).replace(_unsafeCharsPattern, function(c) { + return _entityMap[c]; }); }; })(); + Batman.unescapeHTML = (function() { + return function(s) { + var node; + if (s == null) { + return; + } + node = Batman._unescapeHTMLNode || (Batman._unescapeHTMLNode = document.createElement('DIV')); + node.innerHTML = s; + return Batman.DOM.innerText(node); + }; + })(); + Batman.translate = function(x, values) { if (values == null) { values = {}; @@ -369,7 +507,13 @@ (function() { var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + __indexOf = [].indexOf || + function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; + }; Batman.Inflector = (function() { @@ -419,14 +563,14 @@ return number + "th"; } else { switch (absNumber % 10) { - case 1: - return number + "st"; - case 2: - return number + "nd"; - case 3: - return number + "rd"; - default: - return number + "th"; + case 1: + return number + "st"; + case 2: + return number + "nd"; + case 3: + return number + "rd"; + default: + return number + "th"; } } }; @@ -780,6 +924,9 @@ return value; } }); + }, + deprecated: function(deprecatedName, upgradeString) { + return Batman.developer.warn("" + deprecatedName + " has been deprecated.", upgradeString || ''); } }; @@ -789,107 +936,6 @@ }).call(this); -(function() { - var _Batman; - - Batman._Batman = _Batman = (function() { - - function _Batman(object) { - this.object = object; - } - - _Batman.prototype.check = function(object) { - if (object !== this.object) { - object._batman = new Batman._Batman(object); - return false; - } - return true; - }; - - _Batman.prototype.get = function(key) { - var reduction, results; - results = this.getAll(key); - switch (results.length) { - case 0: - return void 0; - case 1: - return results[0]; - default: - reduction = results[0].concat != null ? function(a, b) { - return a.concat(b); - } : results[0].merge != null ? function(a, b) { - return a.merge(b); - } : results.every(function(x) { - return typeof x === 'object'; - }) ? (results.unshift({}), function(a, b) { - return Batman.extend(a, b); - }) : void 0; - if (reduction) { - return results.reduceRight(reduction); - } else { - return results; - } - } - }; - - _Batman.prototype.getFirst = function(key) { - var results; - results = this.getAll(key); - return results[0]; - }; - - _Batman.prototype.getAll = function(keyOrGetter) { - var getter, results, val; - if (typeof keyOrGetter === 'function') { - getter = keyOrGetter; - } else { - getter = function(ancestor) { - var _ref; - return (_ref = ancestor._batman) != null ? _ref[keyOrGetter] : void 0; - }; - } - results = this.ancestors(getter); - if (val = getter(this.object)) { - results.unshift(val); - } - return results; - }; - - _Batman.prototype.ancestors = function(getter) { - var isClass, parent, proto, results, val, _ref, _ref1; - if (getter == null) { - getter = function(x) { - return x; - }; - } - results = []; - isClass = !!this.object.prototype; - parent = isClass ? (_ref = this.object.__super__) != null ? _ref.constructor : void 0 : (proto = Object.getPrototypeOf(this.object)) === this.object ? this.object.constructor.__super__ : proto; - if (parent != null) { - if ((_ref1 = parent._batman) != null) { - _ref1.check(parent); - } - val = getter(parent); - if (val != null) { - results.push(val); - } - if (parent._batman != null) { - results = results.concat(parent._batman.ancestors(getter)); - } - } - return results; - }; - - _Batman.prototype.set = function(key, value) { - return this[key] = value; - }; - - return _Batman; - - })(); - -}).call(this); - (function() { Batman.Event = (function() { @@ -905,7 +951,6 @@ function Event(base, key) { this.base = base; this.key = key; - this.handlers = []; this._preventCount = 0; } @@ -924,6 +969,7 @@ }; Event.prototype.addHandler = function(handler) { + this.handlers || (this.handlers = []); if (this.handlers.indexOf(handler) === -1) { this.handlers.push(handler); } @@ -935,29 +981,35 @@ Event.prototype.removeHandler = function(handler) { var index; - if ((index = this.handlers.indexOf(handler)) !== -1) { + if (this.handlers && (index = this.handlers.indexOf(handler)) !== -1) { this.handlers.splice(index, 1); } return this; }; Event.prototype.eachHandler = function(iterator) { - var key, _ref, _ref1; - this.handlers.slice().forEach(iterator); - if ((_ref = this.base) != null ? _ref.isEventEmitter : void 0) { + var ancestor, key, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _results; + if ((_ref = this.handlers) != null) { + _ref.slice().forEach(iterator); + } + if ((_ref1 = this.base) != null ? _ref1.isEventEmitter : void 0) { key = this.key; - return (_ref1 = this.base._batman) != null ? _ref1.ancestors(function(ancestor) { - var handlers, _ref2, _ref3; - if (ancestor.isEventEmitter && ((_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.events) != null ? _ref3.hasOwnProperty(key) : void 0 : void 0)) { - handlers = ancestor.event(key).handlers; - return handlers.slice().forEach(iterator); + _ref3 = (_ref2 = this.base._batman) != null ? _ref2.ancestors() : void 0; + _results = []; + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + ancestor = _ref3[_i]; + if (ancestor.isEventEmitter && ((_ref4 = ancestor._batman) != null ? (_ref5 = _ref4.events) != null ? _ref5.hasOwnProperty(key) : void 0 : void 0)) { + _results.push((_ref6 = ancestor.event(key, false)) != null ? (_ref7 = _ref6.handlers) != null ? _ref7.slice().forEach(iterator) : void 0 : void 0); + } else { + _results.push(void 0); } - }) : void 0; + } + return _results; } }; Event.prototype.clearHandlers = function() { - return this.handlers = []; + return this.handlers = void 0; }; Event.prototype.handlerContext = function() { @@ -991,15 +1043,16 @@ }; Event.prototype.fire = function() { - var args, context; + return this.fireWithContext(this.handlerContext(), arguments); + }; + + Event.prototype.fireWithContext = function(context, args) { if (this.isPrevented() || this._oneShotFired) { return false; } - context = this.handlerContext(); - args = arguments; if (this.oneShot) { this._oneShotFired = true; - this._oneShotArgs = arguments; + this._oneShotArgs = args; } return this.eachHandler(function(handler) { return handler.apply(context, args); @@ -1007,8 +1060,12 @@ }; Event.prototype.allowAndFire = function() { + return this.allowAndFireWithContext(this.handlerContext, arguments); + }; + + Event.prototype.allowAndFireWithContext = function(context, args) { this.allow(); - return this.fire.apply(this, arguments); + return this.fireWithContext(context, args); }; return Event; @@ -1019,7 +1076,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PropertyEvent = (function(_super) { @@ -1052,21 +1120,32 @@ var _ref, _ref1; return (_ref = this._batman) != null ? typeof _ref.get === "function" ? (_ref1 = _ref.get('events')) != null ? _ref1.hasOwnProperty(key) : void 0 : void 0 : void 0; }, - event: function(key) { - var eventClass, events, existingEvent, newEvent, _base; + event: function(key, createEvent) { + var ancestor, eventClass, events, existingEvent, newEvent, _base, _i, _len, _ref, _ref1, _ref2, _ref3; + if (createEvent == null) { + createEvent = true; + } Batman.initializeObject(this); eventClass = this.eventClass || Batman.Event; - events = (_base = this._batman).events || (_base.events = {}); - if (events.hasOwnProperty(key)) { - return existingEvent = events[key]; + if ((_ref = this._batman.events) != null ? _ref.hasOwnProperty(key) : void 0) { + return existingEvent = this._batman.events[key]; } else { - this._batman.ancestors(function(ancestor) { - var _ref, _ref1; - return existingEvent || (existingEvent = (_ref = ancestor._batman) != null ? (_ref1 = _ref.events) != null ? _ref1[key] : void 0 : void 0); - }); - newEvent = events[key] = new eventClass(this, key); - newEvent.oneShot = existingEvent != null ? existingEvent.oneShot : void 0; - return newEvent; + _ref1 = this._batman.ancestors(); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + ancestor = _ref1[_i]; + existingEvent = (_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.events) != null ? _ref3[key] : void 0 : void 0; + if (existingEvent) { + break; + } + } + if (createEvent || (existingEvent != null ? existingEvent.oneShot : void 0)) { + events = (_base = this._batman).events || (_base.events = {}); + newEvent = events[key] = new eventClass(this, key); + newEvent.oneShot = existingEvent != null ? existingEvent.oneShot : void 0; + return newEvent; + } else { + return existingEvent; + } } }, on: function() { @@ -1093,9 +1172,11 @@ }, mutation: function(wrappedFunction) { return function() { - var result; + var result, _ref; result = wrappedFunction.apply(this, arguments); - this.event('change').fire(this, this); + if ((_ref = this.event('change', false)) != null) { + _ref.fire(this, this); + } return result; }; }, @@ -1108,17 +1189,18 @@ return this; }, isPrevented: function(key) { - return this.event(key).isPrevented(); + var _ref; + return (_ref = this.event(key, false)) != null ? _ref.isPrevented() : void 0; }, fire: function() { var args, key, _ref; key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - return (_ref = this.event(key)).fire.apply(_ref, args); + return (_ref = this.event(key, false)) != null ? _ref.fireWithContext(this, args) : void 0; }, allowAndFire: function() { var args, key, _ref; key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - return (_ref = this.event(key)).allowAndFire.apply(_ref, args); + return (_ref = this.event(key, false)) != null ? _ref.allowAndFireWithContext(this, args) : void 0; } }; @@ -1130,109 +1212,117 @@ Batman.Enumerable = { isEnumerable: true, map: function(f, ctx) { - var r; + var result; if (ctx == null) { ctx = Batman.container; } - r = []; + result = []; this.forEach(function() { - return r.push(f.apply(ctx, arguments)); + return result.push(f.apply(ctx, arguments)); }); - return r; + return result; }, mapToProperty: function(key) { - var r; - r = []; + var result; + result = []; this.forEach(function(item) { - return r.push(item.get(key)); + return result.push(item.get(key)); }); - return r; + return result; }, every: function(f, ctx) { - var r; + var result; if (ctx == null) { ctx = Batman.container; } - r = true; + result = true; this.forEach(function() { - return r = r && f.apply(ctx, arguments); + return result = result && f.apply(ctx, arguments); }); - return r; + return result; }, some: function(f, ctx) { - var r; + var result; if (ctx == null) { ctx = Batman.container; } - r = false; + result = false; this.forEach(function() { - return r = r || f.apply(ctx, arguments); + return result = result || f.apply(ctx, arguments); }); - return r; + return result; }, - reduce: function(f, r) { - var count, self; + reduce: function(f, accumulator) { + var count, initialValuePassed, self; count = 0; self = this; + if (accumulator != null) { + initialValuePassed = true; + } else { + initialValuePassed = false; + } this.forEach(function() { - if (r != null) { - return r = f.apply(null, [r].concat(__slice.call(arguments), [count], [self])); - } else { - return r = arguments[0]; + if (!initialValuePassed) { + accumulator = arguments[0]; + initialValuePassed = true; + return; } + return accumulator = f.apply(null, [accumulator].concat(__slice.call(arguments), [count], [self])); }); - return r; + return accumulator; }, filter: function(f) { - var r, wrap; - r = new this.constructor; - if (r.add) { - wrap = function(r, e) { - if (f(e)) { - r.add(e); + var result, wrap; + result = new this.constructor; + if (result.add) { + wrap = function(result, element) { + if (f(element)) { + result.add(element); } - return r; + return result; }; - } else if (r.set) { - wrap = function(r, k, v) { - if (f(k, v)) { - r.set(k, v); + } else if (result.set) { + wrap = function(result, key, value) { + if (f(key, value)) { + result.set(key, value); } - return r; + return result; }; } else { - if (!r.push) { - r = []; + if (!result.push) { + result = []; } - wrap = function(r, e) { - if (f(e)) { - r.push(e); + wrap = function(result, element) { + if (f(element)) { + result.push(element); } - return r; + return result; }; } - return this.reduce(wrap, r); + return this.reduce(wrap, result); }, - inGroupsOf: function(n) { - var current, i, r; - r = []; + inGroupsOf: function(groupSize) { + var current, i, result; + result = []; current = false; i = 0; - this.forEach(function(x) { - if (i++ % n === 0) { + this.forEach(function(element) { + if (i++ % groupSize === 0) { current = []; - r.push(current); + result.push(current); } - return current.push(x); + return current.push(element); }); - return r; + return result; } }; }).call(this); (function() { - var __slice = [].slice; + var _objectToString, __slice = [].slice; + + _objectToString = Object.prototype.toString; Batman.SimpleHash = (function() { @@ -1246,8 +1336,6 @@ Batman.extend(SimpleHash.prototype, Batman.Enumerable); - SimpleHash.prototype.propertyClass = Batman.Property; - SimpleHash.prototype.hasKey = function(key) { var pair, pairs, _i, _len; if (this.objectKey(key)) { @@ -1361,7 +1449,17 @@ }; SimpleHash.prototype.hashKeyFor = function(obj) { - return (obj != null ? typeof obj.hashKey === "function" ? obj.hashKey() : void 0 : void 0) || obj; + var hashKey, typeString; + if (hashKey = obj != null ? typeof obj.hashKey === "function" ? obj.hashKey() : void 0 : void 0) { + return hashKey; + } else { + typeString = _objectToString.call(obj); + if (typeString === "[object Array]") { + return typeString; + } else { + return obj; + } + } }; SimpleHash.prototype.equality = function(lhs, rhs) { @@ -1486,7 +1584,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.AssociationCurator = (function(_super) { @@ -1559,10 +1668,22 @@ Batman.SimpleSet = (function() { function SimpleSet() { + var item, itemsToAdd; this._storage = []; this.length = 0; - if (arguments.length > 0) { - this.add.apply(this, arguments); + itemsToAdd = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = arguments.length; _i < _len; _i++) { + item = arguments[_i]; + if (item != null) { + _results.push(item); + } + } + return _results; + }).apply(this, arguments); + if (itemsToAdd.length > 0) { + this.add.apply(this, itemsToAdd); } } @@ -1598,7 +1719,7 @@ removedItems = []; for (_i = 0, _len = items.length; _i < _len; _i++) { item = items[_i]; - if (!(~(index = this._indexOfItem(item)))) { + if (!(~ (index = this._indexOfItem(item)))) { continue; } this._storage.splice(index, 1); @@ -1624,11 +1745,14 @@ }; SimpleSet.prototype.forEach = function(iterator, ctx) { - var container; - container = this; - return this._storage.slice().forEach(function(key) { - return iterator.call(ctx, key, null, container); - }); + var key, _i, _len, _ref, _results; + _ref = this._storage; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + _results.push(iterator.call(ctx, key, null, this)); + } + return _results; }; SimpleSet.prototype.isEmpty = function() { @@ -1721,18 +1845,19 @@ }).call(this); (function() { - var __slice = [].slice; + var SOURCE_TRACKER_STACK, SOURCE_TRACKER_STACK_VALID, __slice = [].slice; + + SOURCE_TRACKER_STACK = []; + + SOURCE_TRACKER_STACK_VALID = true; Batman.Property = (function() { Batman.mixin(Property.prototype, Batman.EventEmitter); - Property._sourceTrackerStack = []; + Property._sourceTrackerStack = SOURCE_TRACKER_STACK; - Property.sourceTracker = function() { - var stack; - return (stack = this._sourceTrackerStack)[stack.length - 1]; - }; + Property._sourceTrackerStackValid = SOURCE_TRACKER_STACK_VALID; Property.defaultAccessor = { get: function(key) { @@ -1756,15 +1881,18 @@ }; Property.accessorForBaseAndKey = function(base, key) { - var accessor, _bm, _ref, - _this = this; + var accessor, ancestor, _bm, _i, _len, _ref, _ref1, _ref2, _ref3; if ((_bm = base._batman) != null) { accessor = (_ref = _bm.keyAccessors) != null ? _ref.get(key) : void 0; if (!accessor) { - _bm.ancestors(function(ancestor) { - var _ref1, _ref2; - return accessor || (accessor = (_ref1 = ancestor._batman) != null ? (_ref2 = _ref1.keyAccessors) != null ? _ref2.get(key) : void 0 : void 0); - }); + _ref1 = _bm.ancestors(); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + ancestor = _ref1[_i]; + accessor = (_ref2 = ancestor._batman) != null ? (_ref3 = _ref2.keyAccessors) != null ? _ref3.get(key) : void 0 : void 0; + if (accessor) { + break; + } + } } } return accessor || this.defaultAccessorForBase(base); @@ -1794,23 +1922,46 @@ }; Property.registerSource = function(obj) { - var _ref; + var set; if (!obj.isEventEmitter) { return; } - return (_ref = this.sourceTracker()) != null ? _ref.add(obj) : void 0; + if (SOURCE_TRACKER_STACK_VALID) { + set = SOURCE_TRACKER_STACK[SOURCE_TRACKER_STACK.length - 1]; + } else { + set = []; + SOURCE_TRACKER_STACK.push(set); + SOURCE_TRACKER_STACK_VALID = true; + } + if (set != null) { + set.push(obj); + } + return void 0; }; Property.pushSourceTracker = function() { - return Batman.Property._sourceTrackerStack.push(new Batman.SimpleSet); + if (SOURCE_TRACKER_STACK_VALID) { + return SOURCE_TRACKER_STACK_VALID = false; + } else { + return SOURCE_TRACKER_STACK.push([]); + } }; - Property.pushDummySourceTracker = function() { - return Batman.Property._sourceTrackerStack.push(null); + Property.popSourceTracker = function() { + if (SOURCE_TRACKER_STACK_VALID) { + return SOURCE_TRACKER_STACK.pop(); + } else { + SOURCE_TRACKER_STACK_VALID = true; + return void 0; + } }; - Property.popSourceTracker = function() { - return Batman.Property._sourceTrackerStack.pop(); + Property.pushDummySourceTracker = function() { + if (!SOURCE_TRACKER_STACK_VALID) { + SOURCE_TRACKER_STACK.push([]); + SOURCE_TRACKER_STACK_VALID = true; + } + return SOURCE_TRACKER_STACK.push(null); }; function Property(base, key) { @@ -1837,11 +1988,7 @@ }; Property.prototype.hashKey = function() { - var key; - this.hashKey = function() { - return key; - }; - return key = ""; + return this._hashKey || (this._hashKey = ""); }; Property.prototype.event = function(key) { @@ -1853,36 +2000,49 @@ }; Property.prototype.changeEvent = function() { - var event; - event = this.event('change'); - this.changeEvent = function() { - return event; - }; - return event; + return this._changeEvent || (this._changeEvent = this.event('change')); }; Property.prototype.accessor = function() { - var accessor; - accessor = this.constructor.accessorForBaseAndKey(this.base, this.key); - this.accessor = function() { - return accessor; - }; - return accessor; + return this._accessor || (this._accessor = this.constructor.accessorForBaseAndKey(this.base, this.key)); }; Property.prototype.eachObserver = function(iterator) { - var key; + var ancestor, handlers, key, object, property, _i, _j, _len, _len1, _ref, _ref1, _ref2, _results; key = this.key; - this.changeEvent().handlers.slice().forEach(iterator); + handlers = (_ref = this.changeEvent().handlers) != null ? _ref.slice() : void 0; + if (handlers) { + for (_i = 0, _len = handlers.length; _i < _len; _i++) { + object = handlers[_i]; + iterator(object); + } + } if (this.base.isObservable) { - return this.base._batman.ancestors(function(ancestor) { - var handlers, property; + _ref1 = this.base._batman.ancestors(); + _results = []; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + ancestor = _ref1[_j]; if (ancestor.isObservable && ancestor.hasProperty(key)) { property = ancestor.property(key); - handlers = property.changeEvent().handlers; - return handlers.slice().forEach(iterator); + handlers = (_ref2 = property.changeEvent().handlers) != null ? _ref2.slice() : void 0; + if (handlers) { + _results.push((function() { + var _k, _len2, _results1; + _results1 = []; + for (_k = 0, _len2 = handlers.length; _k < _len2; _k++) { + object = handlers[_k]; + _results1.push(iterator(object)); + } + return _results1; + })()); + } else { + _results.push(void 0); + } + } else { + _results.push(void 0); } - }); + } + return _results; } }; @@ -1900,25 +2060,28 @@ }; Property.prototype.updateSourcesFromTracker = function() { - var handler, newSources; + var handler, newSources, source, _i, _j, _len, _len1, _ref, _ref1, _results; newSources = this.constructor.popSourceTracker(); handler = this.sourceChangeHandler(); - this._eachSourceChangeEvent(function(e) { - return e.removeHandler(handler); - }); + if (this.sources) { + _ref = this.sources; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + source = _ref[_i]; + if (source != null) { + source.event('change').removeHandler(handler); + } + } + } this.sources = newSources; - return this._eachSourceChangeEvent(function(e) { - return e.addHandler(handler); - }); - }; - - Property.prototype._eachSourceChangeEvent = function(iterator) { - if (this.sources == null) { - return; + if (this.sources) { + _ref1 = this.sources; + _results = []; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + source = _ref1[_j]; + _results.push(source != null ? source.event('change').addHandler(handler) : void 0); + } + return _results; } - return this.sources.forEach(function(source) { - return iterator(source.event('change')); - }); }; Property.prototype.getValue = function() { @@ -1970,16 +2133,12 @@ }; Property.prototype.sourceChangeHandler = function() { - var handler, - _this = this; - handler = this._handleSourceChange.bind(this); + var _this = this; + this._sourceChangeHandler || (this._sourceChangeHandler = this._handleSourceChange.bind(this)); Batman.developer["do"](function() { - return handler.property = _this; + return _this._sourceChangeHandler.property = _this; }); - this.sourceChangeHandler = function() { - return handler; - }; - return handler; + return this._sourceChangeHandler; }; Property.prototype._handleSourceChange = function() { @@ -2069,11 +2228,15 @@ }; Property.prototype._removeHandlers = function() { - var handler; + var handler, source, _i, _len, _ref; handler = this.sourceChangeHandler(); - this._eachSourceChangeEvent(function(e) { - return e.removeHandler(handler); - }); + if (this.sources) { + _ref = this.sources; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + source = _ref[_i]; + source.event('change').removeHandler(handler); + } + } delete this.sources; return this.changeEvent().clearHandlers(); }; @@ -2136,7 +2299,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Keypath = (function(_super) { @@ -2379,25 +2553,25 @@ } isSetting = arguments.length > 1; switch (node.nodeName.toUpperCase()) { - case 'INPUT': - case 'TEXTAREA': - if (isSetting) { - return node.value = value; - } else { - return node.value; - } - break; - case 'SELECT': - if (isSetting) { - return node.value = value; - } - break; - default: - if (isSetting) { - return Batman.DOM.setInnerHTML(node, escapeValue ? Batman.escapeHTML(value) : value); - } else { - return node.innerHTML; - } + case 'INPUT': + case 'TEXTAREA': + if (isSetting) { + return node.value = value; + } else { + return node.value; + } + break; + case 'SELECT': + if (isSetting) { + return node.value = value; + } + break; + default: + if (isSetting) { + return Batman.DOM.setInnerHTML(node, escapeValue ? Batman.escapeHTML(value) : value); + } else { + return node.innerHTML; + } } }, nodeIsEditable: function(node) { @@ -2435,7 +2609,7 @@ return node.detachEvent('on' + eventName, callback); } }, - hasAddEventListener: !!(typeof window !== "undefined" && window !== null ? window.addEventListener : void 0), + hasAddEventListener: !! (typeof window !== "undefined" && window !== null ? window.addEventListener : void 0), preventDefault: function(e) { if (typeof e.preventDefault === "function") { return e.preventDefault(); @@ -2536,16 +2710,7 @@ var bindings, child, eventListeners, eventName, listeners, view, _i, _len, _ref; view = Batman._data(node, 'view'); if (view) { - view.fire('destroy', node); - view.get('yields').forEach(function(name, actions) { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = actions.length; _i < _len; _i++) { - node = actions[_i].node; - _results.push(Batman.DOM.didDestroyNode(node)); - } - return _results; - }); + view.die(); } if (bindings = Batman._data(node, 'bindings')) { bindings.forEach(function(binding) { @@ -2578,121 +2743,126 @@ }).call(this); (function() { - var __slice = [].slice; + + Batman.DOM.ReaderBindingDefinition = (function() { + + function ReaderBindingDefinition(node, keyPath, context, renderer) { + this.node = node; + this.keyPath = keyPath; + this.context = context; + this.renderer = renderer; + } + + return ReaderBindingDefinition; + + })(); + + Batman.BindingDefinitionOnlyObserve = { + Data: 'data', + Node: 'node', + All: 'all', + None: 'none' + }; Batman.DOM.readers = { - target: function(node, key, context, renderer) { - Batman.DOM.readers.bind(node, key, context, renderer, 'nodeChange'); - return true; + target: function(definition) { + definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Node; + return Batman.DOM.readers.bind(definition); }, - source: function(node, key, context, renderer) { - Batman.DOM.readers.bind(node, key, context, renderer, 'dataChange'); - return true; + source: function(definition) { + definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + return Batman.DOM.readers.bind(definition); }, - bind: function(node, key, context, renderer, only) { - var bindingClass; - bindingClass = false; + bind: function(definition) { + var bindingClass, node; + node = definition.node; switch (node.nodeName.toLowerCase()) { - case 'input': - switch (node.getAttribute('type')) { - case 'checkbox': - Batman.DOM.attrReaders.bind(node, 'checked', key, context, renderer, only); - return true; - case 'radio': - bindingClass = Batman.DOM.RadioBinding; - break; - case 'file': - bindingClass = Batman.DOM.FileBinding; - } + case 'input': + switch (node.getAttribute('type')) { + case 'checkbox': + definition.attr = 'checked'; + Batman.DOM.attrReaders.bind(definition); + return true; + case 'radio': + bindingClass = Batman.DOM.RadioBinding; break; - case 'select': - bindingClass = Batman.DOM.SelectBinding; + case 'file': + bindingClass = Batman.DOM.FileBinding; + } + break; + case 'select': + bindingClass = Batman.DOM.SelectBinding; } - bindingClass || (bindingClass = Batman.DOM.Binding); - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(bindingClass, arguments, function(){}); - return true; + bindingClass || (bindingClass = Batman.DOM.ValueBinding); + return new bindingClass(definition); }, - context: function(node, key, context, renderer) { - return context.descendWithKey(key); + context: function(definition) { + return definition.context.descendWithDefinition(definition); }, - mixin: function(node, key, context, renderer) { - new Batman.DOM.MixinBinding(node, key, context.descend(Batman.mixins), renderer); - return true; + mixin: function(definition) { + definition.context = definition.context.descend(Batman.mixins); + return new Batman.DOM.MixinBinding(definition); }, - showif: function(node, key, context, parentRenderer, invert) { - new Batman.DOM.ShowHideBinding(node, key, context, parentRenderer, false, invert); - return true; + showif: function(definition) { + return new Batman.DOM.ShowHideBinding(definition); }, - hideif: function() { - var _ref; - return (_ref = Batman.DOM.readers).showif.apply(_ref, __slice.call(arguments).concat([true])); + hideif: function(definition) { + definition.invert = true; + return new Batman.DOM.ShowHideBinding(definition); }, - insertif: function(node, key, context, parentRenderer, invert) { - new Batman.DOM.InsertionBinding(node, key, context, parentRenderer, false, invert); - return true; + insertif: function(definition) { + return new Batman.DOM.InsertionBinding(definition); }, - removeif: function() { - var _ref; - return (_ref = Batman.DOM.readers).insertif.apply(_ref, __slice.call(arguments).concat([true])); + removeif: function(definition) { + definition.invert = true; + return new Batman.DOM.InsertionBinding(definition); }, - route: function() { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.RouteBinding, arguments, function(){}); - return true; + route: function(definition) { + return new Batman.DOM.RouteBinding(definition); }, - view: function() { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.ViewBinding, arguments, function(){}); - return false; + view: function(definition) { + return new Batman.DOM.ViewBinding(definition); }, - partial: function(node, path, context, renderer) { - Batman.DOM.partial(node, path, context, renderer); - return true; + partial: function(definition) { + return Batman.DOM.partial(definition.node, definition.keyPath, definition.context, definition.renderer); }, - defineview: function(node, name, context, renderer) { + defineview: function(definition) { + var node; + node = definition.node; Batman.DOM.onParseExit(node, function() { var _ref; return (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0; }); - Batman.DOM.defineView(name, node); - return false; + Batman.DOM.defineView(definition.keyPath, node); + return { + skipChildren: true + }; }, - renderif: function(node, key, context, renderer) { - new Batman.DOM.DeferredRenderingBinding(node, key, context, renderer); - return false; + renderif: function(definition) { + return new Batman.DOM.DeferredRenderingBinding(definition); }, - "yield": function(node, key) { - Batman.DOM.onParseExit(node, function() { - return Batman.DOM.Yield.withName(key).set('containerNode', node); + "yield": function(definition) { + var keyPath, node; + node = definition.node, keyPath = definition.keyPath; + return Batman.DOM.onParseExit(node, function() { + return Batman.DOM.Yield.withName(keyPath).set('containerNode', node); }); - return true; }, - contentfor: function(node, key, context, renderer, action) { - if (action == null) { - action = 'append'; - } - Batman.DOM.onParseExit(node, function() { + contentfor: function(definition) { + var keyPath, node, renderer, swapMethod, value; + node = definition.node, value = definition.value, swapMethod = definition.swapMethod, renderer = definition.renderer, keyPath = definition.keyPath; + swapMethod || (swapMethod = 'append'); + return Batman.DOM.onParseExit(node, function() { var _ref; if ((_ref = node.parentNode) != null) { _ref.removeChild(node); } - return renderer.view.pushYieldAction(key, action, node); + return renderer.view.pushYieldAction(keyPath, swapMethod, node); }); - return true; }, - replace: function(node, key, context, renderer) { - Batman.DOM.readers.contentfor(node, key, context, renderer, 'replace'); - return true; + replace: function(definition) { + definition.swapMethod = 'replace'; + return Batman.DOM.readers.contentfor(definition); } }; @@ -2700,7 +2870,13 @@ (function() { var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + __indexOf = [].indexOf || + function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; + }; Batman.DOM.events = { click: function(node, callback, context, eventName) { @@ -2710,7 +2886,7 @@ Batman.DOM.addEventListener(node, eventName, function() { var args, event; event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - if (event.metaKey || event.ctrlKey) { + if (event.metaKey || event.ctrlKey || event.button === 1) { return; } Batman.DOM.preventDefault(event); @@ -2732,24 +2908,24 @@ eventNames = (function() { var _ref; switch (node.nodeName.toUpperCase()) { - case 'TEXTAREA': + case 'TEXTAREA': + return ['input', 'keyup', 'change']; + case 'INPUT': + if (_ref = node.type.toLowerCase(), __indexOf.call(Batman.DOM.textInputTypes, _ref) >= 0) { + oldCallback = callback; + callback = function(node, event) { + if (event.type === 'keyup' && Batman.DOM.events.isEnter(event)) { + return; + } + return oldCallback(node, event); + }; return ['input', 'keyup', 'change']; - case 'INPUT': - if (_ref = node.type.toLowerCase(), __indexOf.call(Batman.DOM.textInputTypes, _ref) >= 0) { - oldCallback = callback; - callback = function(node, event) { - if (event.type === 'keyup' && Batman.DOM.events.isEnter(event)) { - return; - } - return oldCallback.apply(null, arguments); - }; - return ['input', 'keyup', 'change']; - } else { - return ['input', 'change']; - } - break; - default: - return ['change']; + } else { + return ['input', 'change']; + } + break; + default: + return ['change']; } })(); _results = []; @@ -2820,6 +2996,20 @@ (function() { + Batman.DOM.AttrReaderBindingDefinition = (function() { + + function AttrReaderBindingDefinition(node, attr, keyPath, context, renderer) { + this.node = node; + this.attr = attr; + this.keyPath = keyPath; + this.context = context; + this.renderer = renderer; + } + + return AttrReaderBindingDefinition; + + })(); + Batman.DOM.attrReaders = { _parseAttribute: function(value) { if (value === 'false') { @@ -2830,80 +3020,72 @@ } return value; }, - source: function(node, attr, key, context, renderer) { - return Batman.DOM.attrReaders.bind(node, attr, key, context, renderer, 'dataChange'); + source: function(definition) { + definition.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + return Batman.DOM.attrReaders.bind(definition); }, - bind: function(node, attr, key, context, renderer, only) { + bind: function(definition) { var bindingClass; bindingClass = (function() { - switch (attr) { - case 'checked': - case 'disabled': - case 'selected': - return Batman.DOM.CheckedBinding; - case 'value': - case 'href': - case 'src': - case 'size': - return Batman.DOM.NodeAttributeBinding; - case 'class': - return Batman.DOM.ClassBinding; - case 'style': - return Batman.DOM.StyleBinding; - default: - return Batman.DOM.AttributeBinding; + switch (definition.attr) { + case 'checked': + case 'disabled': + case 'selected': + return Batman.DOM.CheckedBinding; + case 'value': + case 'href': + case 'src': + case 'size': + return Batman.DOM.NodeAttributeBinding; + case 'class': + return Batman.DOM.ClassBinding; + case 'style': + return Batman.DOM.StyleBinding; + default: + return Batman.DOM.AttributeBinding; } })(); - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(bindingClass, arguments, function(){}); - return true; + return new bindingClass(definition); }, - context: function(node, contextName, key, context) { - return context.descendWithKey(key, contextName); + context: function(definition) { + return definition.context.descendWithDefinition(definition); }, - event: function(node, eventName, key, context) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.EventBinding, arguments, function(){}); - return true; + event: function(definition) { + return new Batman.DOM.EventBinding(definition); }, - addclass: function(node, className, key, context, parentRenderer, invert) { - new Batman.DOM.AddClassBinding(node, className, key, context, parentRenderer, false, invert); - return true; + addclass: function(definition) { + return new Batman.DOM.AddClassBinding(definition); }, - removeclass: function(node, className, key, context, parentRenderer) { - return Batman.DOM.attrReaders.addclass(node, className, key, context, parentRenderer, true); + removeclass: function(definition) { + definition.invert = true; + return new Batman.DOM.AddClassBinding(definition); }, - foreach: function(node, iteratorName, key, context, parentRenderer) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.IteratorBinding, arguments, function(){}); - return false; + foreach: function(definition) { + return new Batman.DOM.IteratorBinding(definition); }, - formfor: function(node, localName, key, context) { - (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; - return t == "object" || t == "function" ? result || child : child; - })(Batman.DOM.FormBinding, arguments, function(){}); - return context.descendWithKey(key, localName); + formfor: function(definition) { + new Batman.DOM.FormBinding(definition); + return definition.context.descendWithDefinition(definition); } }; }).call(this); (function() { - var BatmanObject, ObjectFunctions, getAccessorObject, promiseWrapper, wrapSingleAccessor, - __slice = [].slice, + var BatmanObject, ObjectFunctions, getAccessorObject, promiseWrapper, wrapSingleAccessor, __slice = [].slice, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; getAccessorObject = function(base, accessor) { var deprecated, _i, _len, _ref; @@ -2929,8 +3111,7 @@ return function(defaultAccessor) { return { get: function(key) { - var asyncDeliver, existingValue, newValue, _base, _base1, _ref, _ref1, - _this = this; + var asyncDeliver, existingValue, newValue, _base, _base1, _ref, _ref1, _this = this; if ((existingValue = defaultAccessor.get.apply(this, arguments)) != null) { return existingValue; } @@ -3110,14 +3291,11 @@ }; BatmanObject.prototype.hashKey = function() { - var key; + var _base; if (typeof this.isEqual === 'function') { return; } - this.hashKey = function() { - return key; - }; - return key = ""; + return (_base = this._batman).hashKey || (_base.hashKey = ""); }; BatmanObject.prototype.toJSON = function() { @@ -3142,9 +3320,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Renderer = (function(_super) { var bindingRegexp, bindingSortOrder, bindingSortPositions, k, name, pos, _i, _j, _len, _len1, _ref; @@ -3233,8 +3426,7 @@ }; Renderer.prototype.parseNode = function(node) { - var argument, attribute, bindings, keypath, names, nextNode, oldContext, result, skipChildren, _base, _base1, _k, _l, _len2, _len3, _ref1, _ref2, _ref3, _ref4, - _this = this; + var attr, attribute, binding, bindingDefinition, bindings, names, nextNode, oldContext, reader, skipChildren, value, _k, _l, _len2, _len3, _ref1, _ref2, _ref3, _ref4, _this = this; if (this.deferEvery && (new Date - this.startTime) > this.deferEvery) { this.resumeNode = node; this.timeout = Batman.setImmediate(this.resume); @@ -3253,17 +3445,17 @@ } _ref3 = bindings.sort(this._sortBindings); for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { - _ref4 = _ref3[_l], name = _ref4[0], argument = _ref4[1], keypath = _ref4[2]; - result = argument ? typeof (_base = Batman.DOM.attrReaders)[name] === "function" ? _base[name](node, argument, keypath, this.context, this) : void 0 : typeof (_base1 = Batman.DOM.readers)[name] === "function" ? _base1[name](node, keypath, this.context, this) : void 0; - if (result === false) { - skipChildren = true; - break; - } else if (result instanceof Batman.RenderContext) { + _ref4 = _ref3[_l], name = _ref4[0], attr = _ref4[1], value = _ref4[2]; + binding = attr ? (reader = Batman.DOM.attrReaders[name]) ? (bindingDefinition = new Batman.DOM.AttrReaderBindingDefinition(node, attr, value, this.context, this), reader(bindingDefinition)) : void 0 : (reader = Batman.DOM.readers[name]) ? (bindingDefinition = new Batman.DOM.ReaderBindingDefinition(node, value, this.context, this), reader(bindingDefinition)) : void 0; + if (binding instanceof Batman.RenderContext) { oldContext = this.context; - this.context = result; + this.context = binding; Batman.DOM.onParseExit(node, function() { return _this.context = oldContext; }); + } else if (binding != null ? binding.skipChildren : void 0) { + skipChildren = true; + break; } } } @@ -3320,16 +3512,31 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.AbstractBinding = (function(_super) { - var get_dot_rx, get_rx, keypath_rx; + var get_dot_rx, get_rx, keypath_rx, onlyAll, onlyData, onlyNode; __extends(AbstractBinding, _super); - keypath_rx = /(^|,)\s*(?:(true|false)|("[^"]*")|(\{[^\}]*\})|([a-zA-Z][\w\-\.]*[\?\!]?))\s*(?=$|,)/g; + keypath_rx = /(^|,)\s*(?:(true|false)|("[^"]*")|(\{[^\}]*\})|(([0-9]+[a-zA-Z\_]|[a-zA-Z])[\w\-\.]*[\?\!]?))\s*(?=$|,)/g; get_dot_rx = /(?:\]\.)(.+?)(?=[\[\.]|\s*\||$)/; @@ -3397,6 +3604,12 @@ return this.renderContext.contextForKey(this.key); }); + onlyAll = Batman.BindingDefinitionOnlyObserve.All; + + onlyData = Batman.BindingDefinitionOnlyObserve.Data; + + onlyNode = Batman.BindingDefinitionOnlyObserve.Node; + AbstractBinding.prototype.bindImmediately = true; AbstractBinding.prototype.shouldSet = true; @@ -3405,17 +3618,22 @@ AbstractBinding.prototype.escapeValue = true; - function AbstractBinding(node, keyPath, renderContext, renderer, only) { - this.node = node; - this.keyPath = keyPath; - this.renderContext = renderContext; - this.renderer = renderer; - this.only = only != null ? only : false; - this._fireDataChange = __bind(this._fireDataChange, this); + AbstractBinding.prototype.onlyObserve = onlyAll; - this._fireNodeChange = __bind(this._fireNodeChange, this); + AbstractBinding.prototype.skipParseFilter = false; - this.parseFilter(); + function AbstractBinding(definition) { + this._fireDataChange = __bind(this._fireDataChange, this); + this.node = definition.node, this.keyPath = definition.keyPath, this.renderContext = definition.context, this.renderer = definition.renderer; + if (definition.onlyObserve) { + this.onlyObserve = definition.onlyObserve; + } + if (definition.skipParseFilter != null) { + this.skipParseFilter = definition.skipParseFilter; + } + if (!this.skipParseFilter) { + this.parseFilter(); + } if (this.bindImmediately) { this.bind(); } @@ -3427,16 +3645,16 @@ AbstractBinding.prototype.bind = function() { var _ref, _ref1; - if ((this.node != null) && ((_ref = this.only) === false || _ref === 'nodeChange') && Batman.DOM.nodeIsEditable(this.node)) { - Batman.DOM.events.change(this.node, this._fireNodeChange); - if (this.only === 'nodeChange') { + if (this.node && ((_ref = this.onlyObserve) === onlyAll || _ref === onlyNode) && Batman.DOM.nodeIsEditable(this.node)) { + Batman.DOM.events.change(this.node, this._fireNodeChange.bind(this)); + if (this.onlyObserve === onlyNode) { this._fireNodeChange(); } } - if ((_ref1 = this.only) === false || _ref1 === 'dataChange') { + if ((_ref1 = this.onlyObserve) === onlyAll || _ref1 === onlyData) { this.observeAndFire('filteredValue', this._fireDataChange); } - if (this.node != null) { + if (this.node) { return Batman.DOM.trackBinding(this, this.node); } }; @@ -3470,6 +3688,10 @@ }); } this.fire('die'); + this.node = null; + this.keyPath = null; + this.renderContext = null; + this.renderer = null; this.dead = true; return true; }; @@ -3536,12 +3758,27 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.ViewBinding = (function(_super) { __extends(ViewBinding, _super); + ViewBinding.prototype.skipChildren = true; + + ViewBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + function ViewBinding() { ViewBinding.__super__.constructor.apply(this, arguments); this.renderer.prevent('rendered'); @@ -3549,7 +3786,7 @@ } ViewBinding.prototype.dataChange = function(viewClassOrInstance) { - var _this = this; + var _ref, _this = this; if (viewClassOrInstance == null) { return; } @@ -3567,7 +3804,15 @@ this.view.on('ready', function() { return _this.renderer.allowAndFire('rendered'); }); - return this.die(); + this.forget(); + return (_ref = this._batman.properties) != null ? _ref.forEach(function(key, property) { + return property.die(); + }) : void 0; + }; + + ViewBinding.prototype.die = function() { + this.view = null; + return ViewBinding.__super__.die.apply(this, arguments); }; return ViewBinding; @@ -3578,7 +3823,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.ViewArgumentBinding = (function(_super) { @@ -3588,6 +3844,8 @@ return ViewArgumentBinding.__super__.constructor.apply(this, arguments); } + ViewArgumentBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; + return ViewArgumentBinding; })(Batman.DOM.AbstractBinding); @@ -3596,27 +3854,81 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; + + Batman.DOM.ValueBinding = (function(_super) { + + __extends(ValueBinding, _super); + + function ValueBinding(definition) { + var _ref; + this.isInputBinding = (_ref = definition.node.nodeName.toLowerCase()) === 'input' || _ref === 'textarea'; + ValueBinding.__super__.constructor.apply(this, arguments); + } + + ValueBinding.prototype.nodeChange = function(node, context) { + if (this.isTwoWay()) { + return this.set('filteredValue', this.node.value); + } + }; + + ValueBinding.prototype.dataChange = function(value, node) { + return Batman.DOM.valueForNode(this.node, value, this.escapeValue); + }; + + return ValueBinding; + + })(Batman.DOM.AbstractBinding); + +}).call(this); + +(function() { + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.ShowHideBinding = (function(_super) { __extends(ShowHideBinding, _super); - function ShowHideBinding(node, className, key, context, parentRenderer, invert) { + ShowHideBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + + function ShowHideBinding(definition) { var display; - this.invert = invert != null ? invert : false; - display = node.style.display; + display = definition.node.style.display; if (!display || display === 'none') { display = ''; } this.originalDisplay = display; + this.invert = definition.invert; ShowHideBinding.__super__.constructor.apply(this, arguments); } ShowHideBinding.prototype.dataChange = function(value) { var hide, view, _ref; view = Batman._data(this.node, 'view'); - if (!!value === !this.invert) { + if ( !! value === !this.invert) { if (view != null) { view.fire('beforeAppear', this.node); } @@ -3629,7 +3941,7 @@ if (view != null) { view.fire('beforeDisappear', this.node); } - if (typeof (hide = Batman.data(this.node, 'hide')) === 'function') { + if (typeof(hide = Batman.data(this.node, 'hide')) === 'function') { hide.call(this.node); } else { Batman.DOM.setStyleProperty(this.node, 'display', 'none', 'important'); @@ -3645,9 +3957,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.SelectBinding = (function(_super) { @@ -3670,8 +3997,7 @@ } SelectBinding.prototype.childBindingAdded = function(binding) { - var dataChangeHandler, - _this = this; + var dataChangeHandler, _this = this; if (binding instanceof Batman.DOM.CheckedBinding) { binding.on('dataChange', dataChangeHandler = function() { return _this.nodeChange(); @@ -3699,8 +4025,7 @@ SelectBinding.prototype.lastKeyContext = null; SelectBinding.prototype.dataChange = function(newValue) { - var child, matches, valueToChild, _i, _len, _name, _ref, - _this = this; + var child, matches, valueToChild, _i, _len, _name, _ref, _this = this; this.lastKeyContext || (this.lastKeyContext = this.get('keyContext')); if (this.lastKeyContext !== this.get('keyContext')) { this.canSetImplicitly = true; @@ -3777,7 +4102,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.RouteBinding = (function(_super) { @@ -3787,7 +4123,9 @@ return RouteBinding.__super__.constructor.apply(this, arguments); } - RouteBinding.prototype.onATag = false; + RouteBinding.prototype.onAnchorTag = false; + + RouteBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; RouteBinding.accessor('dispatcher', function() { return this.renderContext.get('dispatcher') || Batman.App.get('current.dispatcher'); @@ -3796,7 +4134,7 @@ RouteBinding.prototype.bind = function() { var _this = this; if (this.node.nodeName.toUpperCase() === 'A') { - this.onATag = true; + this.onAnchorTag = true; } RouteBinding.__super__.bind.apply(this, arguments); return Batman.DOM.events.click(this.node, function(node, event) { @@ -3814,11 +4152,11 @@ RouteBinding.prototype.dataChange = function(value) { var path; - if (value != null) { + if (value) { path = this.pathFromValue(value); } - if (this.onATag) { - if ((path != null) && (Batman.navigator != null)) { + if (this.onAnchorTag) { + if (path && Batman.navigator) { path = Batman.navigator.linkTo(path); } else { path = "#"; @@ -3829,7 +4167,7 @@ RouteBinding.prototype.pathFromValue = function(value) { var _ref; - if (value != null) { + if (value) { if (value.isNamedRouteQuery) { return value.get('path'); } else { @@ -3846,7 +4184,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.RadioBinding = (function(_super) { @@ -3889,7 +4238,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.MixinBinding = (function(_super) { @@ -3899,6 +4259,8 @@ return MixinBinding.__super__.constructor.apply(this, arguments); } + MixinBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + MixinBinding.prototype.dataChange = function(value) { if (value != null) { return Batman.mixin(this.node, value); @@ -3913,7 +4275,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.FileBinding = (function(_super) { @@ -3944,7 +4317,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.DeferredRenderingBinding = (function(_super) { @@ -3952,6 +4336,8 @@ DeferredRenderingBinding.prototype.rendered = false; + DeferredRenderingBinding.prototype.skipChildren = true; + function DeferredRenderingBinding() { DeferredRenderingBinding.__super__.constructor.apply(this, arguments); this.node.removeAttribute("data-renderif"); @@ -3978,48 +4364,26 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - - Batman.DOM.Binding = (function(_super) { - - __extends(Binding, _super); - - function Binding(node) { - var _ref; - this.isInputBinding = (_ref = node.nodeName.toLowerCase()) === 'input' || _ref === 'textarea'; - Binding.__super__.constructor.apply(this, arguments); - } - - Binding.prototype.nodeChange = function(node, context) { - if (this.isTwoWay()) { - return this.set('filteredValue', this.node.value); + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; }; - Binding.prototype.dataChange = function(value, node) { - return Batman.DOM.valueForNode(this.node, value, this.escapeValue); - }; - - return Binding; - - })(Batman.DOM.AbstractBinding); - -}).call(this); - -(function() { - var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __slice = [].slice; - Batman.DOM.AbstractAttributeBinding = (function(_super) { __extends(AbstractAttributeBinding, _super); - function AbstractAttributeBinding() { - var args, attributeName, node; - node = arguments[0], attributeName = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - this.attributeName = attributeName; - AbstractAttributeBinding.__super__.constructor.apply(this, [node].concat(__slice.call(args))); + function AbstractAttributeBinding(definition) { + this.attributeName = definition.attr; + AbstractAttributeBinding.__super__.constructor.apply(this, arguments); } return AbstractAttributeBinding; @@ -4029,9 +4393,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.FormBinding = (function(_super) { @@ -4043,14 +4422,16 @@ FormBinding.prototype.defaultErrorsListSelector = 'div.errors'; + FormBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; + FormBinding.accessor('errorsListSelector', function() { return this.get('node').getAttribute('data-errors-list') || this.defaultErrorsListSelector; }); - function FormBinding(node, contextName, keyPath, renderContext, renderer, only) { + function FormBinding() { this.childBindingAdded = __bind(this.childBindingAdded, this); FormBinding.__super__.constructor.apply(this, arguments); - this.contextName = contextName; + this.contextName = this.attributeName; delete this.attributeName; Batman.DOM.events.submit(this.get('node'), function(node, e) { return Batman.DOM.preventDefault(e); @@ -4059,12 +4440,13 @@ } FormBinding.prototype.childBindingAdded = function(binding) { - var field, index, node; + var definition, field, index, node; if (binding.isInputBinding && Batman.isChildOf(this.get('node'), binding.get('node'))) { - if (~(index = binding.get('key').indexOf(this.contextName))) { + if (~ (index = binding.get('key').indexOf(this.contextName))) { node = binding.get('node'); field = binding.get('key').slice(index + this.contextName.length + 1); - return new Batman.DOM.AddClassBinding(node, this.errorClass, this.get('keyPath') + (" | get 'errors." + field + ".length'"), this.renderContext, this.renderer); + definition = new Batman.DOM.AttrReaderBindingDefinition(node, this.errorClass, this.get('keyPath') + (" | get 'errors." + field + ".length'"), this.renderContext, this.renderer); + return new Batman.DOM.AddClassBinding(definition); } } }; @@ -4090,28 +4472,43 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.EventBinding = (function(_super) { __extends(EventBinding, _super); - EventBinding.prototype.bindImmediately = false; + EventBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.None; - function EventBinding(node, eventName, key, context) { - var attacher, callback, - _this = this; + function EventBinding() { + var attacher, callback, confirmText, _this = this; EventBinding.__super__.constructor.apply(this, arguments); + if (confirmText = this.node.getAttribute('data-confirm')) { + Batman.developer.deprecated("data-confirm"); + } callback = function() { var _ref; + if (confirmText && !confirm(confirmText)) { + return; + } return (_ref = _this.get('filteredValue')) != null ? _ref.apply(_this.get('callbackContext'), arguments) : void 0; }; if (attacher = Batman.DOM.events[this.attributeName]) { - attacher(this.node, callback, context); + attacher(this.node, callback, this.renderContext); } else { - Batman.DOM.events.other(this.node, this.attributeName, callback, context); + Batman.DOM.events.other(this.node, this.attributeName, callback, this.renderContext); } - this.bind(); } EventBinding.accessor('callbackContext', function() { @@ -4153,7 +4550,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.NodeAttributeBinding = (function(_super) { @@ -4184,7 +4592,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.CheckedBinding = (function(_super) { @@ -4197,7 +4616,7 @@ CheckedBinding.prototype.isInputBinding = true; CheckedBinding.prototype.dataChange = function(value) { - return this.node[this.attributeName] = !!value; + return this.node[this.attributeName] = !! value; }; return CheckedBinding; @@ -4208,7 +4627,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.AttributeBinding = (function(_super) { @@ -4218,6 +4648,8 @@ return AttributeBinding.__super__.constructor.apply(this, arguments); } + AttributeBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + AttributeBinding.prototype.dataChange = function(value) { return this.node.setAttribute(this.attributeName, value); }; @@ -4236,21 +4668,34 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.AddClassBinding = (function(_super) { __extends(AddClassBinding, _super); - function AddClassBinding(node, className, keyPath, renderContext, renderer, only, invert) { - var name, names; - this.invert = invert != null ? invert : false; - names = className.split('|'); + AddClassBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + + function AddClassBinding(definition) { + var name; + this.invert = definition.invert; this.classes = (function() { - var _i, _len, _results; + var _i, _len, _ref, _results; + _ref = definition.attr.split('|'); _results = []; - for (_i = 0, _len = names.length; _i < _len; _i++) { - name = names[_i]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; _results.push({ name: name, pattern: new RegExp("(?:^|\\s)" + name + "(?:$|\\s)", 'i') @@ -4259,7 +4704,6 @@ return _results; })(); AddClassBinding.__super__.constructor.apply(this, arguments); - delete this.attributeName; } AddClassBinding.prototype.dataChange = function(value) { @@ -4269,7 +4713,7 @@ for (_i = 0, _len = _ref.length; _i < _len; _i++) { _ref1 = _ref[_i], name = _ref1.name, pattern = _ref1.pattern; includesClassName = pattern.test(currentName); - if (!!value === !this.invert) { + if ( !! value === !this.invert) { if (!includesClassName) { this.node.className = "" + currentName + " " + name; } @@ -4290,7 +4734,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.AbstractCollectionBinding = (function(_super) { @@ -4339,37 +4794,31 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.DOM.StyleBinding = (function(_super) { __extends(StyleBinding, _super); - StyleBinding.SingleStyleBinding = (function(_super1) { - - __extends(SingleStyleBinding, _super1); - - SingleStyleBinding.prototype.isTwoWay = function() { - return false; - }; - - function SingleStyleBinding() { - var args, parent, _i; - args = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), parent = arguments[_i++]; - this.parent = parent; - SingleStyleBinding.__super__.constructor.apply(this, args); - } - - SingleStyleBinding.prototype.dataChange = function(value) { - return this.parent.setStyle(this.attributeName, value); - }; - - return SingleStyleBinding; - - })(Batman.DOM.AbstractAttributeBinding); + StyleBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; function StyleBinding() { this.setStyle = __bind(this.setStyle, this); @@ -4421,7 +4870,9 @@ }; StyleBinding.prototype.bindSingleAttribute = function(attr, keyPath) { - return this.styleBindings[attr] = new this.constructor.SingleStyleBinding(this.node, attr, keyPath, this.renderContext, this.renderer, this.only, this); + var definition; + definition = new Batman.DOM.AttrReaderBindingDefinition(this.node, attr, keyPath, this.renderContext, this.renderer); + return this.styleBindings[attr] = new Batman.DOM.StyleBinding.SingleStyleBinding(definition, this); }; StyleBinding.prototype.setStyle = function(key, value) { @@ -4466,6 +4917,29 @@ return StyleBinding.__super__.unbindCollection.apply(this, arguments); }; + StyleBinding.SingleStyleBinding = (function(_super1) { + + __extends(SingleStyleBinding, _super1); + + SingleStyleBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + + SingleStyleBinding.prototype.isTwoWay = function() { + return false; + }; + + function SingleStyleBinding(definition, parent) { + this.parent = parent; + SingleStyleBinding.__super__.constructor.call(this, definition); + } + + SingleStyleBinding.prototype.dataChange = function(value) { + return this.parent.setStyle(this.attributeName, value); + }; + + return SingleStyleBinding; + + })(Batman.DOM.AbstractAttributeBinding); + return StyleBinding; })(Batman.DOM.AbstractCollectionBinding); @@ -4473,9 +4947,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.IteratorBinding = (function(_super) { @@ -4487,18 +4976,17 @@ IteratorBinding.prototype.bindImmediately = false; - function IteratorBinding(sourceNode, iteratorName, key, context, parentRenderer) { - var previousSiblingNode, - _this = this; - this.iteratorName = iteratorName; - this.key = key; - this.context = context; - this.parentRenderer = parentRenderer; + IteratorBinding.prototype.skipChildren = true; + + IteratorBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + + function IteratorBinding(definition) { this.handleArrayChanged = __bind(this.handleArrayChanged, this); + var previousSiblingNode, sourceNode, _this = this; + sourceNode = definition.node, this.iteratorName = definition.attr, this.key = definition.keyPath, this.parentRenderer = definition.renderer; this.nodeMap = new Batman.SimpleHash; this.rendererMap = new Batman.SimpleHash; - this.fragment = document.createDocumentFragment(); this.prototypeNode = sourceNode.cloneNode(true); this.prototypeNode.removeAttribute("data-foreach-" + this.iteratorName); previousSiblingNode = sourceNode.nextSibling; @@ -4516,18 +5004,14 @@ _this.bind(); return _this.parentRenderer.allowAndFire('rendered'); }); - IteratorBinding.__super__.constructor.call(this, this.endNode, this.iteratorName, this.key, this.context, this.parentRenderer); + definition.node = this.endNode; + IteratorBinding.__super__.constructor.apply(this, arguments); } IteratorBinding.prototype.parentNode = function() { return this.endNode.parentNode; }; - IteratorBinding.prototype.die = function() { - this.dead = true; - return IteratorBinding.__super__.die.apply(this, arguments); - }; - IteratorBinding.prototype.dataChange = function(collection) { var items, _items; if (collection != null) { @@ -4543,12 +5027,11 @@ }; IteratorBinding.prototype.handleArrayChanged = function(newItems) { - var existingNode, index, newItem, node, nodeAtIndex, parentNode, startIndex, unseenNodeMap, _i, _len, - _this = this; + var existingNode, index, newItem, node, nodeAtIndex, parentNode, startIndex, unseenNodeMap, _i, _len, _this = this; parentNode = this.parentNode(); startIndex = this._getStartNodeIndex() + 1; unseenNodeMap = this.nodeMap.merge(); - if (newItems != null) { + if (newItems) { for (index = _i = 0, _len = newItems.length; _i < _len; index = ++_i) { newItem = newItems[index]; nodeAtIndex = parentNode.childNodes[startIndex + index]; @@ -4562,7 +5045,12 @@ } } unseenNodeMap.forEach(function(item, node) { - return _this._removeItem(item); + if (_this._nodesToBeRendered.has(node)) { + _this._nodesToBeRemoved || (_this._nodesToBeRemoved = new Batman.SimpleSet); + return _this._nodesToBeRemoved.add(node); + } else { + return _this._removeItem(item); + } }); }; @@ -4571,16 +5059,24 @@ }; IteratorBinding.prototype._newNodeForItem = function(newItem) { - var newNode, renderer, - _this = this; + var newNode, renderer, _this = this; newNode = this.prototypeNode.cloneNode(true); + this._nodesToBeRendered || (this._nodesToBeRendered = new Batman.SimpleSet); + this._nodesToBeRendered.add(newNode); Batman._data(newNode, "" + this.iteratorName + "Item", newItem); this.nodeMap.set(newItem, newNode); this.parentRenderer.prevent('rendered'); renderer = new Batman.Renderer(newNode, this.renderContext.descend(newItem, this.iteratorName), this.parentRenderer.view); - renderer.on('rendered', function() { - Batman.DOM.propagateBindingEvents(newNode); - _this.fire('nodeAdded', newNode, newItem); + renderer.once('rendered', function() { + var _ref; + _this._nodesToBeRendered.remove(newNode); + if ((_ref = _this._nodesToBeRemoved) != null ? _ref.has(newNode) : void 0) { + _this._nodesToBeRemoved.remove(newNode); + _this._removeItem(newItem); + } else { + Batman.DOM.propagateBindingEvents(newNode); + _this.fire('nodeAdded', newNode, newItem); + } return _this.parentRenderer.allowAndFire('rendered'); }); return newNode; @@ -4605,6 +5101,15 @@ return this.fire('nodeRemoved', node, item); }; + IteratorBinding.prototype.die = function() { + var _ref; + if (this._nodesToBeRendered && !this._nodesToBeRendered.isEmpty()) { + this._nodesToBeRemoved || (this._nodesToBeRemoved = new Batman.SimpleSet); + (_ref = this._nodesToBeRemoved).add.apply(_ref, this._nodesToBeRendered.toArray()); + } + return IteratorBinding.__super__.die.apply(this, arguments); + }; + return IteratorBinding; })(Batman.DOM.AbstractCollectionBinding); @@ -4612,9 +5117,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.ClassBinding = (function(_super) { @@ -4625,6 +5145,8 @@ return ClassBinding.__super__.constructor.apply(this, arguments); } + ClassBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + ClassBinding.prototype.dataChange = function(value) { if (value != null) { this.unbindCollection(); @@ -4672,7 +5194,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ValidationError = (function(_super) { @@ -4700,7 +5233,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.StorageAdapter = (function(_super) { @@ -4912,8 +5456,7 @@ }; StorageAdapter.prototype.runFilter = function(position, action, env, callback) { - var actionFilters, allFilters, filters, next, - _this = this; + var actionFilters, allFilters, filters, next, _this = this; this._inheritFilters(); allFilters = this._batman.filters[position].all || []; actionFilters = this._batman.filters[position][action] || []; @@ -4952,8 +5495,7 @@ }; StorageAdapter.prototype.perform = function(key, subject, options, callback) { - var env, next, - _this = this; + var env, next, _this = this; options || (options = {}); env = { options: options, @@ -4979,13 +5521,29 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + __indexOf = [].indexOf || + function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; + }; Batman.RestStorage = (function(_super) { - var key, _fn, _i, _len, _ref, - _this = this; + var key, _fn, _i, _len, _ref, _this = this; __extends(RestStorage, _super); @@ -5329,6 +5887,7 @@ '403': RestStorage.NotAllowedError, '404': RestStorage.NotFoundError, '406': RestStorage.NotAcceptableError, + '409': RestStorage.RecordExistsError, '422': RestStorage.UnprocessableRecordError, '500': RestStorage.InternalStorageError, '501': RestStorage.NotImplementedError @@ -5356,7 +5915,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.LocalStorage = (function(_super) { @@ -5533,7 +6103,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.SessionStorage = (function(_super) { @@ -5561,7 +6142,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ParamsReplacer = (function(_super) { @@ -5627,7 +6219,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ParamsPusher = (function(_super) { @@ -5649,7 +6252,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.NamedRouteQuery = (function(_super) { @@ -5791,7 +6405,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Dispatcher = (function(_super) { var ControllerDirectory; @@ -5922,7 +6547,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Route = (function(_super) { @@ -6080,9 +6716,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ControllerActionRoute = (function(_super) { @@ -6118,7 +6769,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.CallbackActionRoute = (function(_super) { @@ -6142,12 +6804,22 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.Hash = (function(_super) { - var k, _fn, _i, _j, _len, _len1, _ref, _ref1, - _this = this; + var k, _fn, _i, _j, _len, _len1, _ref, _ref1, _this = this; __extends(Hash, _super); @@ -6308,7 +6980,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.RenderCache = (function(_super) { @@ -6428,11 +7111,32 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + __indexOf = [].indexOf || + function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; + }; Batman.Controller = (function(_super) { var _optionsFromFilterArguments; @@ -6520,8 +7224,7 @@ }; Controller.prototype.errorHandler = function(callback) { - var errorFrame, _ref, - _this = this; + var errorFrame, _ref, _this = this; errorFrame = (_ref = this._actionFrames) != null ? _ref[this._actionFrames.length - 1] : void 0; return function(err, result, env) { if (err) { @@ -6541,8 +7244,7 @@ }; Controller.prototype.handleError = function(error) { - var handled, _ref, - _this = this; + var handled, _ref, _this = this; handled = false; if ((_ref = this.constructor._batman.getAll('errorHandlers')) != null) { _ref.forEach(function(hash) { @@ -6601,8 +7303,7 @@ }; Controller.prototype.executeAction = function(action, params) { - var frame, oldRedirect, parentFrame, result, _ref, _ref1, - _this = this; + var frame, oldRedirect, parentFrame, result, _ref, _ref1, _this = this; if (params == null) { params = this.get('params'); } @@ -6662,8 +7363,7 @@ }; Controller.prototype.render = function(options) { - var action, frame, view, _ref, _ref1, - _this = this; + var action, frame, view, _ref, _ref1, _this = this; if (options == null) { options = {}; } @@ -6691,7 +7391,7 @@ if ((_ref1 = Batman.currentApp) != null) { _ref1.prevent('ready'); } - view.on('ready', function() { + view.once('ready', function() { var _ref2; Batman.DOM.Yield.withName(options.into).replace(view.get('node')); if ((_ref2 = Batman.currentApp) != null) { @@ -6754,11 +7454,21 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Set = (function(_super) { - var k, _fn, _i, _j, _len, _len1, _ref, _ref1, - _this = this; + var k, _fn, _i, _j, _len, _len1, _ref, _ref1, _this = this; __extends(Set, _super); @@ -6850,7 +7560,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ErrorsSet = (function(_super) { @@ -6876,12 +7597,22 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetProxy = (function(_super) { - var k, _fn, _i, _len, _ref, - _this = this; + var k, _fn, _i, _len, _ref, _this = this; __extends(SetProxy, _super); @@ -6907,14 +7638,12 @@ Batman.extend(SetProxy.prototype, Batman.Enumerable); SetProxy.prototype.filter = function(f) { - var r; - r = new Batman.Set(); - return this.reduce((function(r, e) { - if (f(e)) { - r.add(e); + return this.reduce(function(accumulator, element) { + if (f(element)) { + accumulator.add(element); } - return r; - }), r); + return accumulator; + }, new Batman.Set()); }; SetProxy.prototype.replace = function() { @@ -6957,9 +7686,24 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.BinarySetOperation = (function(_super) { @@ -7015,7 +7759,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetUnion = (function(_super) { @@ -7057,7 +7812,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetIntersection = (function(_super) { @@ -7082,7 +7848,9 @@ } return _results; })(); - return this.add.apply(this, itemsToAdd); + if (itemsToAdd.length > 0) { + return this.add.apply(this, itemsToAdd); + } }; SetIntersection.prototype._itemsWereRemovedFromSource = function() { @@ -7099,7 +7867,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetComplement = (function(_super) { @@ -7125,7 +7904,9 @@ } return _results; })(); - return this.add.apply(this, itemsToAdd); + if (itemsToAdd.length > 0) { + return this.add.apply(this, itemsToAdd); + } } else { itemsToRemove = (function() { var _i, _len, _results; @@ -7138,7 +7919,9 @@ } return _results; })(); - return this.remove.apply(this, itemsToRemove); + if (itemsToRemove.length > 0) { + return this.remove.apply(this, itemsToRemove); + } } }; @@ -7159,13 +7942,15 @@ } return _results; })(); - return this.add.apply(this, itemsToAdd); + if (itemsToAdd.length > 0) { + return this.add.apply(this, itemsToAdd); + } } }; SetComplement.prototype._addComplement = function(items, opposite) { - var item; - return this.add.apply(this, (function() { + var item, itemsToAdd; + itemsToAdd = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = items.length; _i < _len; _i++) { @@ -7175,7 +7960,10 @@ } } return _results; - })()); + })(); + if (itemsToAdd.length > 0) { + return this.add.apply(this, itemsToAdd); + } }; return SetComplement; @@ -7186,7 +7974,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.StateMachine = (function(_super) { @@ -7200,8 +7999,7 @@ StateMachine.InvalidTransitionError.prototype = new Error; StateMachine.transitions = function(table) { - var definePredicate, fromState, k, object, predicateKeys, toState, transitions, v, _fn, _ref, - _this = this; + var definePredicate, fromState, k, object, predicateKeys, toState, transitions, v, _fn, _ref, _this = this; for (k in table) { v = table[k]; if (!(v.from && v.to)) { @@ -7347,9 +8145,19 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.Model = (function(_super) { @@ -7384,15 +8192,15 @@ Batman.initializeObject(this.prototype); (_base = this.prototype._batman).encoders || (_base.encoders = new Batman.SimpleHash); encoder = {}; - switch (Batman.typeOf(encoderOrLastKey)) { - case 'String': - keys.push(encoderOrLastKey); - break; - case 'Function': - encoder.encode = encoderOrLastKey; - break; - default: - encoder = encoderOrLastKey; + switch (Batman.typeOf(encoderOrLastKey)) { + case 'String': + keys.push(encoderOrLastKey); + break; + case 'Function': + encoder.encode = encoderOrLastKey; + break; + default: + encoder = encoderOrLastKey; } for (_j = 0, _len = keys.length; _j < _len; _j++) { key = keys[_j]; @@ -7543,20 +8351,12 @@ var _this = this; this.fire('loading', options); return this._doStorageOperation('readAll', options, function(err, records, env) { - var mappedRecords, record; + var mappedRecords; if (err != null) { _this.fire('error', err); return typeof callback === "function" ? callback(err, []) : void 0; } else { - mappedRecords = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = records.length; _i < _len; _i++) { - record = records[_i]; - _results.push(this._mapIdentity(record)); - } - return _results; - }).call(_this); + mappedRecords = _this._mapIdentities(records); _this.fire('loaded', mappedRecords, env); return typeof callback === "function" ? callback(err, mappedRecords, env) : void 0; } @@ -7566,7 +8366,8 @@ Model.create = function(attrs, callback) { var obj, _ref; if (!callback) { - _ref = [{}, attrs], attrs = _ref[0], callback = _ref[1]; + _ref = [{}, + attrs], attrs = _ref[0], callback = _ref[1]; } obj = new this(attrs); obj.save(callback); @@ -7595,22 +8396,30 @@ }; Model._mapIdentity = function(record) { - var existing, id, _ref; - if (typeof (id = record.get('id')) === 'undefined' || id === '') { - return record; - } else { - existing = (_ref = this.get("loaded.indexedBy.id").get(id)) != null ? _ref.toArray()[0] : void 0; - if (existing) { + return this._mapIdentities([record])[0]; + }; + + Model._mapIdentities = function(records) { + var existing, id, index, newRecords, record, _i, _len, _ref, _ref1; + newRecords = []; + for (index = _i = 0, _len = records.length; _i < _len; index = ++_i) { + record = records[index]; + if (!((id = record.get('id')) != null)) { + continue; + } else if (existing = (_ref = this.get('loaded.indexedBy.id').get(id)) != null ? _ref.toArray()[0] : void 0) { existing._withoutDirtyTracking(function() { var _ref1; return this.updateAttributes(((_ref1 = record.get('attributes')) != null ? _ref1.toObject() : void 0) || {}); }); - return existing; + records[index] = existing; } else { - this.get('loaded').add(record); - return record; + newRecords.push(record); } } + if (newRecords.length) { + (_ref1 = this.get('loaded')).add.apply(_ref1, newRecords); + } + return records; }; Model._doStorageOperation = function(operation, options, callback) { @@ -7685,14 +8494,6 @@ if (idOrAttributes == null) { idOrAttributes = {}; } - this.destroy = __bind(this.destroy, this); - - this.save = __bind(this.save, this); - - this.loadWithOptions = __bind(this.loadWithOptions, this); - - this.load = __bind(this.load, this); - Batman.developer.assert(this instanceof Batman.Object, "constructors must be called with new"); if (Batman.typeOf(idOrAttributes) === 'Object') { Model.__super__.constructor.call(this, idOrAttributes); @@ -7795,8 +8596,7 @@ }; Model.prototype.toJSON = function() { - var encoders, obj, - _this = this; + var encoders, obj, _this = this; obj = {}; encoders = this._batman.get('encoders'); if (!(!encoders || encoders.isEmpty())) { @@ -7817,8 +8617,7 @@ }; Model.prototype.fromJSON = function(data) { - var encoders, key, obj, value, - _this = this; + var encoders, key, obj, value, _this = this; obj = {}; encoders = this._batman.get('encoders'); if (!encoders || encoders.isEmpty() || !encoders.some(function(key, encoder) { @@ -7853,7 +8652,8 @@ Model.prototype.load = function(options, callback) { var _ref1; if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + _ref1 = [{}, + options], options = _ref1[0], callback = _ref1[1]; } else { options = { data: options @@ -7863,8 +8663,7 @@ }; Model.prototype.loadWithOptions = function(options, callback) { - var callbackQueue, hasOptions, _ref1, - _this = this; + var callbackQueue, hasOptions, _ref1, _this = this; hasOptions = Object.keys(options).length !== 0; if ((_ref1 = this.get('lifecycle.state')) === 'destroying' || _ref1 === 'destroyed') { if (typeof callback === "function") { @@ -7908,10 +8707,10 @@ }; Model.prototype.save = function(options, callback) { - var endState, isNew, startState, storageOperation, _ref1, _ref2, - _this = this; + var endState, isNew, startState, storageOperation, _ref1, _ref2, _this = this; if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + _ref1 = [{}, + options], options = _ref1[0], callback = _ref1[1]; } isNew = this.isNew(); _ref2 = isNew ? ['create', 'create', 'created'] : ['save', 'update', 'saved'], startState = _ref2[0], storageOperation = _ref2[1], endState = _ref2[2]; @@ -7924,8 +8723,7 @@ } associations = _this.constructor._batman.get('associations'); _this._withoutDirtyTracking(function() { - var _ref3, - _this = this; + var _ref3, _this = this; return associations != null ? (_ref3 = associations.getByType('belongsTo')) != null ? _ref3.forEach(function(association, label) { return association.apply(_this); }) : void 0 : void 0; @@ -7967,10 +8765,10 @@ }; Model.prototype.destroy = function(options, callback) { - var _ref1, - _this = this; + var _ref1, _this = this; if (!callback) { - _ref1 = [{}, options], options = _ref1[0], callback = _ref1[1]; + _ref1 = [{}, + options], options = _ref1[0], callback = _ref1[1]; } if (this.get('lifecycle').destroy()) { return this._doStorageOperation('destroy', { @@ -8053,8 +8851,7 @@ }; Model.prototype._doStorageOperation = function(operation, options, callback) { - var adapter, - _this = this; + var adapter, _this = this; Batman.developer.assert(this.hasStorage(), "Can't " + operation + " model " + (Batman.functionName(this.constructor)) + " without any storage adapters!"); adapter = this._batman.get('storage'); return adapter.perform(operation, this, options, function() { @@ -8083,8 +8880,7 @@ }).call(this); (function() { - var k, _fn, _i, _len, _ref, - _this = this; + var k, _fn, _i, _len, _ref, _this = this; _ref = Batman.AssociationCurator.availableAssociations; _fn = function(k) { @@ -8104,7 +8900,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Proxy = (function(_super) { @@ -8144,7 +8951,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.AssociationProxy = (function(_super) { @@ -8230,7 +9048,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.HasOneProxy = (function(_super) { @@ -8249,8 +9078,7 @@ }; HasOneProxy.prototype.fetchFromRemote = function(callback) { - var loadOptions, - _this = this; + var loadOptions, _this = this; loadOptions = { data: {} }; @@ -8279,7 +9107,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.BelongsToProxy = (function(_super) { @@ -8298,8 +9137,7 @@ }; BelongsToProxy.prototype.fetchFromRemote = function(callback) { - var loadOptions, - _this = this; + var loadOptions, _this = this; loadOptions = {}; if (this.association.options.url) { loadOptions.recordUrl = this.association.options.url; @@ -8320,7 +9158,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicBelongsToProxy = (function(_super) { @@ -8339,8 +9188,7 @@ }; PolymorphicBelongsToProxy.prototype.fetchFromRemote = function(callback) { - var loadOptions, - _this = this; + var loadOptions, _this = this; loadOptions = {}; if (this.association.options.url) { loadOptions.recordUrl = this.association.options.url; @@ -8361,7 +9209,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Accessible = (function(_super) { @@ -8557,36 +9416,36 @@ throw new Error("value must be an Object"); } switch (valueType) { - case 'Array': - return ((function() { - var _i, _len; - arrayResults = []; - if (value.length === 0) { - arrayResults.push(queryFromParams(null, "" + prefix + "[]")); - } else { - for (_i = 0, _len = value.length; _i < _len; _i++) { - v = value[_i]; - arrayResults.push(queryFromParams(v, "" + prefix + "[]")); - } - } - return arrayResults; - })()).join("&"); - case 'Object': - return ((function() { - var _results; - _results = []; - for (k in value) { - v = value[k]; - _results.push(queryFromParams(v, prefix ? "" + prefix + "[" + (encodeQueryComponent(k)) + "]" : encodeQueryComponent(k))); - } - return _results; - })()).join("&"); - default: - if (prefix != null) { - return "" + prefix + "=" + (encodeQueryComponent(value)); + case 'Array': + return ((function() { + var _i, _len; + arrayResults = []; + if (value.length === 0) { + arrayResults.push(queryFromParams(null, "" + prefix + "[]")); } else { - return encodeQueryComponent(value); + for (_i = 0, _len = value.length; _i < _len; _i++) { + v = value[_i]; + arrayResults.push(queryFromParams(v, "" + prefix + "[]")); + } + } + return arrayResults; + })()).join("&"); + case 'Object': + return ((function() { + var _results; + _results = []; + for (k in value) { + v = value[k]; + _results.push(queryFromParams(v, prefix ? "" + prefix + "[" + (encodeQueryComponent(k)) + "]" : encodeQueryComponent(k))); } + return _results; + })()).join("&"); + default: + if (prefix != null) { + return "" + prefix + "=" + (encodeQueryComponent(value)); + } else { + return encodeQueryComponent(value); + } } }; @@ -8610,7 +9469,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.Request = (function(_super) { var dataHasFileUploads; @@ -8629,25 +9499,25 @@ } return list = (function() { switch (Batman.typeOf(object)) { - case 'Object': - list = (function() { - var _results; - _results = []; - for (k in object) { - v = object[k]; - _results.push(pairForList((first ? k : "" + key + "[" + k + "]"), v)); - } - return _results; - })(); - return list.reduce(function(acc, list) { - return acc.concat(list); - }, []); - case 'Array': - return object.reduce(function(acc, element) { - return acc.concat(pairForList("" + key + "[]", element)); - }, []); - default: - return [[key, object != null ? object : ""]]; + case 'Object': + list = (function() { + var _results; + _results = []; + for (k in object) { + v = object[k]; + _results.push(pairForList((first ? k : "" + key + "[" + k + "]"), v)); + } + return _results; + })(); + return list.reduce(function(acc, list) { + return acc.concat(list); + }, []); + case 'Array': + return object.reduce(function(acc, element) { + return acc.concat(pairForList("" + key + "[]", element)); + }, []); + default: + return [[key, object != null ? object : ""]]; } })(); }; @@ -8667,21 +9537,21 @@ } type = Batman.typeOf(data); switch (type) { - case 'Object': - for (k in data) { - v = data[k]; - if (dataHasFileUploads(v)) { - return true; - } + case 'Object': + for (k in data) { + v = data[k]; + if (dataHasFileUploads(v)) { + return true; } - break; - case 'Array': - for (_i = 0, _len = data.length; _i < _len; _i++) { - v = data[_i]; - if (dataHasFileUploads(v)) { - return true; - } + } + break; + case 'Array': + for (_i = 0, _len = data.length; _i < _len; _i++) { + v = data[_i]; + if (dataHasFileUploads(v)) { + return true; } + } } return false; }; @@ -8745,7 +9615,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetObserver = (function(_super) { @@ -8854,14 +9735,25 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.SetSort = (function(_super) { __extends(SetSort, _super); function SetSort(base, key, order) { - var boundReIndex; + var boundReIndex, _this = this; this.key = key; if (order == null) { order = "asc"; @@ -8871,7 +9763,9 @@ if (this.base.isObservable) { this._setObserver = new Batman.SetObserver(this.base); this._setObserver.observedItemKeys = [this.key]; - boundReIndex = this._reIndex.bind(this); + boundReIndex = function() { + return _this._reIndex(); + }; this._setObserver.observerForItemAndKey = function() { return boundReIndex; }; @@ -8923,9 +9817,11 @@ this.base.registerAsMutableSource(); return (function(func, args, ctor) { ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; + var child = new ctor, + result = func.apply(child, args), + t = typeof result; return t == "object" || t == "function" ? result || child : child; - })(Batman.Set, this._storage, function(){}).merge(other).sortedBy(this.key, this.order); + })(Batman.Set, this._storage, function() {}).merge(other).sortedBy(this.key, this.order); }; SetSort.prototype.compare = function(a, b) { @@ -8976,8 +9872,7 @@ }; SetSort.prototype._reIndex = function() { - var newOrder, _ref, - _this = this; + var newOrder, _ref, _this = this; newOrder = this.base.toArray().sort(function(a, b) { var multiple, valueA, valueB; valueA = Batman.get(a, _this.key); @@ -9011,7 +9906,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.AssociationSet = (function(_super) { @@ -9068,7 +9974,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicAssociationSet = (function(_super) { @@ -9103,7 +10020,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.SetIndex = (function(_super) { @@ -9229,7 +10157,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicAssociationSetIndex = (function(_super) { @@ -9238,14 +10177,25 @@ function PolymorphicAssociationSetIndex(association, type, key) { this.association = association; this.type = type; - PolymorphicAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModelForType(type).get('loaded'), key); + PolymorphicAssociationSetIndex.__super__.constructor.call(this, this.association.getRelatedModel().get('loaded'), key); } PolymorphicAssociationSetIndex.prototype._resultSetForKey = function(key) { - var _this = this; - return this._storage.getOrSet(key, function() { - return new _this.association.proxyClass(key, _this.type, _this.association); - }); + return this.association.setForKey(key); + }; + + PolymorphicAssociationSetIndex.prototype._addItem = function(item) { + if (this.association.modelType() !== item.get(this.association.foreignTypeKey)) { + return; + } + return PolymorphicAssociationSetIndex.__super__._addItem.apply(this, arguments); + }; + + PolymorphicAssociationSetIndex.prototype._removeItem = function(item) { + if (this.association.modelType() !== item.get(this.association.foreignTypeKey)) { + return; + } + return PolymorphicAssociationSetIndex.__super__._removeItem.apply(this, arguments); }; return PolymorphicAssociationSetIndex; @@ -9256,7 +10206,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.AssociationSetIndex = (function(_super) { @@ -9299,7 +10260,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.UniqueSetIndex = (function(_super) { @@ -9340,7 +10312,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.UniqueAssociationSetIndex = (function(_super) { @@ -9359,7 +10342,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicUniqueAssociationSetIndex = (function(_super) { @@ -9378,7 +10372,11 @@ }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var __bind = function(fn, me) { + return function() { + return fn.apply(me, arguments); + }; + }, __slice = [].slice; Batman.Navigator = (function() { @@ -9392,7 +10390,7 @@ }; Navigator.forApp = function(app) { - return new (this.defaultClass())(app); + return new(this.defaultClass())(app); }; function Navigator(app) { @@ -9448,7 +10446,7 @@ Navigator.prototype.push = function(params) { var path, pathFromParams, _base; - pathFromParams = typeof (_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; + pathFromParams = typeof(_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; if (pathFromParams) { this._lastRedirect = pathFromParams; } @@ -9461,7 +10459,7 @@ Navigator.prototype.replace = function(params) { var path, pathFromParams, _base; - pathFromParams = typeof (_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; + pathFromParams = typeof(_base = this.app.get('dispatcher')).pathFromParams === "function" ? _base.pathFromParams(params) : void 0; if (pathFromParams) { this._lastRedirect = pathFromParams; } @@ -9499,7 +10497,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PushStateNavigator = (function(_super) { @@ -9563,7 +10572,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.HashbangNavigator = (function(_super) { @@ -9660,8 +10680,7 @@ }; RouteMap.prototype.addRoute = function(name, route) { - var base, names, - _this = this; + var base, names, _this = this; this.childrenByOrder.push(route); if (name.length > 0 && (names = name.split('.')).length > 0) { base = names.shift(); @@ -9948,7 +10967,7 @@ } else { nestingParam = ":" + Batman.helpers.singularize(this.baseOptions.controller) + "Id"; nestingSegment = Batman.helpers.underscore(this.baseOptions.controller); - return "" + (this.parent._nestingPath()) + "/" + nestingSegment + "/" + nestingParam + "/"; + return "" + (this.parent._nestingPath()) + nestingSegment + "/" + nestingParam + "/"; } }; @@ -9956,7 +10975,7 @@ if (!this.parent) { return ""; } else { - return this.baseOptions.controller + "."; + return this.parent._nestingName() + this.baseOptions.controller + "."; } }; @@ -9975,12 +10994,22 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.App = (function(_super) { - var name, _fn, _i, _len, _ref, - _this = this; + var name, _fn, _i, _len, _ref, _this = this; __extends(App, _super); @@ -10046,10 +11075,12 @@ App.requirePath = ''; Batman.developer["do"](function() { + var requireDeprecated; + requireDeprecated = "Please use whatever means you'd like to load your code before calling App.run."; App.require = function() { - var base, name, names, path, _i, _len, - _this = this; + var base, name, names, path, _i, _len, _this = this; path = arguments[0], names = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + Batman.developer.deprecated("App.require", requireDeprecated); base = this.requirePath + path; for (_i = 0, _len = names.length; _i < _len; _i++) { name = names[_i]; @@ -10075,15 +11106,18 @@ App.controller = function() { var names; names = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + Batman.developer.deprecated("App.controller", requireDeprecated); names = names.map(function(n) { return n + '_controller'; }); return this.require.apply(this, ['controllers'].concat(__slice.call(names))); }; App.model = function() { + Batman.developer.deprecated("App.model", requireDeprecated); return this.require.apply(this, ['models'].concat(__slice.call(arguments))); }; return App.view = function() { + Batman.developer.deprecated("App.view", requireDeprecated); return this.require.apply(this, ['views'].concat(__slice.call(arguments))); }; }); @@ -10109,8 +11143,7 @@ App.event('run').oneShot = true; App.run = function() { - var layout, layoutClass, - _this = this; + var layout, layoutClass, _this = this; if (Batman.currentApp) { if (Batman.currentApp === this) { return; @@ -10216,7 +11249,7 @@ this.options = Batman.extend(defaultOptions, this.defaultOptions, options); if (this.options.nestUrl) { if (!(this.model.urlNestsUnder != null)) { - developer.error("You must persist the the model " + this.model.constructor.name + " to use the url helpers on an association"); + Batman.developer.error("You must persist the the model " + this.model.constructor.name + " to use the url helpers on an association"); } this.model.urlNestsUnder(Batman.helpers.underscore(this.getRelatedModel().get('resourceName'))); } @@ -10261,8 +11294,7 @@ }; Association.prototype.inverse = function() { - var inverse, relatedAssocs, - _this = this; + var inverse, relatedAssocs, _this = this; if (relatedAssocs = this.getRelatedModel()._batman.get('associations')) { if (this.options.inverseOf) { return relatedAssocs.getByLabel(this.options.inverseOf); @@ -10290,7 +11322,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PluralAssociation = (function(_super) { @@ -10306,8 +11349,7 @@ } PluralAssociation.prototype.setForRecord = function(record) { - var childModelSetIndex, indexValue, - _this = this; + var childModelSetIndex, indexValue, _this = this; indexValue = this.indexValueForRecord(record); childModelSetIndex = this.setIndex(); Batman.Property.withoutTracking(function() { @@ -10319,7 +11361,7 @@ return existingValueSet; } } - newSet = new _this.proxyClass(indexValue, _this); + newSet = _this.proxyClassInstanceForKey(indexValue); if (indexValue != null) { _this._setsByValue.set(indexValue, newSet); } @@ -10334,8 +11376,7 @@ }; PluralAssociation.prototype.setForKey = Batman.Property.wrapTrackingPrevention(function(indexValue) { - var foundSet, - _this = this; + var foundSet, _this = this; foundSet = void 0; this._setsByRecord.forEach(function(record, set) { if (foundSet != null) { @@ -10350,13 +11391,16 @@ return foundSet; } return this._setsByValue.getOrSet(indexValue, function() { - return new _this.proxyClass(indexValue, _this); + return _this.proxyClassInstanceForKey(indexValue); }); }); + PluralAssociation.prototype.proxyClassInstanceForKey = function(indexValue) { + return new this.proxyClass(indexValue, this); + }; + PluralAssociation.prototype.getAccessor = function(self, model, label) { - var relatedRecords, setInAttributes, - _this = this; + var relatedRecords, setInAttributes, _this = this; if (!self.getRelatedModel()) { return; } @@ -10410,7 +11454,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.HasManyAssociation = (function(_super) { @@ -10424,9 +11479,11 @@ if (options != null ? options.as : void 0) { return (function(func, args, ctor) { ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; + var child = new ctor, + result = func.apply(child, args), + t = typeof result; return t == "object" || t == "function" ? result || child : child; - })(Batman.PolymorphicHasManyAssociation, arguments, function(){}); + })(Batman.PolymorphicHasManyAssociation, arguments, function() {}); } HasManyAssociation.__super__.constructor.apply(this, arguments); this.primaryKey = this.options.primaryKey || "id"; @@ -10434,8 +11491,7 @@ } HasManyAssociation.prototype.apply = function(baseSaveError, base) { - var relations, set, - _this = this; + var relations, set, _this = this; if (!baseSaveError) { if (relations = this.getFromAttributes(base)) { relations.forEach(function(model) { @@ -10522,7 +11578,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicHasManyAssociation = (function(_super) { @@ -10542,8 +11609,7 @@ } PolymorphicHasManyAssociation.prototype.apply = function(baseSaveError, base) { - var relations, - _this = this; + var relations, _this = this; if (!baseSaveError) { if (relations = this.getFromAttributes(base)) { PolymorphicHasManyAssociation.__super__.apply.apply(this, arguments); @@ -10555,8 +11621,25 @@ return true; }; - PolymorphicHasManyAssociation.prototype.getRelatedModelForType = function() { - return this.getRelatedModel(); + PolymorphicHasManyAssociation.prototype.proxyClassInstanceForKey = function(indexValue) { + return new this.proxyClass(indexValue, this.modelType(), this); + }; + + PolymorphicHasManyAssociation.prototype.getRelatedModelForType = function(type) { + var relatedModel, scope; + scope = this.options.namespace || Batman.currentApp; + if (type) { + relatedModel = scope != null ? scope[type] : void 0; + relatedModel || (relatedModel = scope != null ? scope[Batman.helpers.camelize(type)] : void 0); + } else { + relatedModel = this.getRelatedModel(); + } + Batman.developer["do"](function() { + if ((Batman.currentApp != null) && !relatedModel) { + return Batman.developer.warn("Related model " + type + " for polymorphic association not found."); + } + }); + return relatedModel; }; PolymorphicHasManyAssociation.prototype.modelType = function() { @@ -10564,9 +11647,7 @@ }; PolymorphicHasManyAssociation.prototype.setIndex = function() { - if (!this.typeIndex) { - this.typeIndex = new Batman.PolymorphicAssociationSetIndex(this, this.modelType(), this[this.indexRelatedModelOn]); - } + this.typeIndex || (this.typeIndex = new Batman.PolymorphicAssociationSetIndex(this, this.modelType(), this[this.indexRelatedModelOn])); return this.typeIndex; }; @@ -10589,6 +11670,53 @@ }; }; + PolymorphicHasManyAssociation.prototype.decoder = function() { + var association; + association = this; + return function(data, key, _, __, parentRecord) { + var existingRecord, existingRelations, jsonObject, newRelations, record, relatedModel, savedRecord, subType, type, _i, _len; + if (relatedModel = association.getRelatedModel()) { + existingRelations = association.getFromAttributes(parentRecord) || association.setForRecord(parentRecord); + newRelations = existingRelations.filter(function(relation) { + return relation.isNew(); + }).toArray(); + for (_i = 0, _len = data.length; _i < _len; _i++) { + jsonObject = data[_i]; + type = jsonObject[association.options.foreignTypeKey]; + subType = association.getRelatedModelForType(type); + record = new subType(); + record._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + existingRecord = relatedModel.get('loaded').indexedByUnique('id').get(record.get('id')); + if (existingRecord != null) { + existingRecord._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + record = existingRecord; + } else { + if (newRelations.length > 0) { + savedRecord = newRelations.shift(); + savedRecord._withoutDirtyTracking(function() { + return this.fromJSON(jsonObject); + }); + record = savedRecord; + } + } + record = relatedModel._mapIdentity(record); + existingRelations.add(record); + if (association.options.inverseOf) { + record.set(association.options.inverseOf, parentRecord); + } + } + existingRelations.markAsLoaded(); + } else { + Batman.developer.error("Can't decode model " + association.options.name + " because it hasn't been loaded yet!"); + } + return existingRelations; + }; + }; + return PolymorphicHasManyAssociation; })(Batman.HasManyAssociation); @@ -10597,7 +11725,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.SingularAssociation = (function(_super) { @@ -10653,7 +11792,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.HasOneAssociation = (function(_super) { @@ -10718,7 +11868,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.BelongsToAssociation = (function(_super) { @@ -10741,9 +11902,11 @@ delete options.polymorphic; return (function(func, args, ctor) { ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args), t = typeof result; + var child = new ctor, + result = func.apply(child, args), + t = typeof result; return t == "object" || t == "function" ? result || child : child; - })(Batman.PolymorphicBelongsToAssociation, arguments, function(){}); + })(Batman.PolymorphicBelongsToAssociation, arguments, function() {}); } BelongsToAssociation.__super__.constructor.apply(this, arguments); this.foreignKey = this.options.foreignKey || ("" + this.label + "_id"); @@ -10798,7 +11961,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PolymorphicBelongsToAssociation = (function(_super) { @@ -10828,15 +12002,10 @@ PolymorphicBelongsToAssociation.prototype.inverse = false; PolymorphicBelongsToAssociation.prototype.apply = function(base) { - var foreignTypeValue, instanceOrProxy, model; + var foreignTypeValue, instanceOrProxy; PolymorphicBelongsToAssociation.__super__.apply.apply(this, arguments); if (instanceOrProxy = base.get(this.label)) { - if (instanceOrProxy instanceof Batman.AssociationProxy) { - model = instanceOrProxy.association.model; - } else { - model = instanceOrProxy.constructor; - } - foreignTypeValue = model.get('resourceName'); + foreignTypeValue = instanceOrProxy instanceof Batman.PolymorphicBelongsToProxy ? instanceOrProxy.get('foreignTypeValue') : instanceOrProxy.constructor.get('resourceName'); return base.set(this.foreignTypeKey, foreignTypeValue); } }; @@ -10891,8 +12060,7 @@ }; PolymorphicBelongsToAssociation.prototype.inverseForType = function(type) { - var inverse, relatedAssocs, _ref, - _this = this; + var inverse, relatedAssocs, _ref, _this = this; if (relatedAssocs = (_ref = this.getRelatedModelForType(type)) != null ? _ref._batman.get('associations') : void 0) { if (this.options.inverseOf) { return relatedAssocs.getByLabel(this.options.inverseOf); @@ -10938,7 +12106,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.Validator = (function(_super) { @@ -10971,10 +12150,10 @@ shouldReturn = false; for (key in options) { value = options[key]; - if (~((_ref = this._options) != null ? _ref.indexOf(key) : void 0)) { + if (~ ((_ref = this._options) != null ? _ref.indexOf(key) : void 0)) { results[key] = value; } - if (~((_ref1 = this._triggers) != null ? _ref1.indexOf(key) : void 0)) { + if (~ ((_ref1 = this._triggers) != null ? _ref1.indexOf(key) : void 0)) { results[key] = value; shouldReturn = true; } @@ -11039,7 +12218,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.RegExpValidator = (function(_super) { @@ -11077,7 +12267,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.PresenceValidator = (function(_super) { @@ -11112,7 +12313,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.NumericValidator = (function(_super) { @@ -11183,7 +12395,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.LengthValidator = (function(_super) { @@ -11242,7 +12465,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.AssociatedValidator = (function(_super) { @@ -11255,8 +12489,7 @@ AssociatedValidator.triggers('associated'); AssociatedValidator.prototype.validateEach = function(errors, record, key, callback) { - var childFinished, count, value, - _this = this; + var childFinished, count, value, _this = this; value = record.get(key); if (value != null) { if (value instanceof Batman.AssociationProxy) { @@ -11296,7 +12529,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ControllerActionFrame = (function(_super) { @@ -11310,7 +12554,7 @@ function ControllerActionFrame(options, onComplete) { ControllerActionFrame.__super__.constructor.call(this, options); - this.on('complete', onComplete); + this.once('complete', onComplete); } ControllerActionFrame.prototype.startOperation = function(options) { @@ -11354,7 +12598,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.DOM.InsertionBinding = (function(_super) { @@ -11364,26 +12619,25 @@ InsertionBinding.prototype.bindImmediately = false; - function InsertionBinding(node, className, key, context, parentRenderer, invert) { - var result, - _this = this; - this.invert = invert != null ? invert : false; + InsertionBinding.prototype.onlyObserve = Batman.BindingDefinitionOnlyObserve.Data; + + function InsertionBinding(definition) { + var _this = this; + this.invert = definition.invert; this.placeholderNode = document.createComment("detached node " + (this.get('_batmanID'))); - result = InsertionBinding.__super__.constructor.apply(this, arguments); + InsertionBinding.__super__.constructor.apply(this, arguments); Batman.DOM.onParseExit(this.node, function() { _this.bind(); if (_this.placeholderNode != null) { return Batman.DOM.trackBinding(_this, _this.placeholderNode); } }); - result; - } InsertionBinding.prototype.dataChange = function(value) { var parentNode; parentNode = this.placeholderNode.parentNode || this.node.parentNode; - if (!!value === !this.invert) { + if ( !! value === !this.invert) { if (!(this.node.parentNode != null)) { Batman.DOM.insertBefore(parentNode, this.node, this.placeholderNode); return parentNode.removeChild(this.placeholderNode); @@ -11397,14 +12651,17 @@ }; InsertionBinding.prototype.die = function() { + var filteredValue, node, placeholderNode; if (this.dead) { return; } + node = this.node, placeholderNode = this.placeholderNode; + filteredValue = this.get('filteredValue'); InsertionBinding.__super__.die.apply(this, arguments); - if (!!this.get('filteredValue') === !this.invert) { - return Batman.DOM.destroyNode(this.placeholderNode); + if ( !! filteredValue === !this.invert) { + return Batman.DOM.destroyNode(placeholderNode); } else { - return Batman.DOM.destroyNode(this.node); + return Batman.DOM.destroyNode(node); } }; @@ -11555,8 +12812,7 @@ }).call(this); (function() { - var buntUndefined, defaultAndOr, - __slice = [].slice; + var buntUndefined, defaultAndOr, __slice = [].slice; buntUndefined = function(f) { return function(value) { @@ -11752,7 +13008,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.RenderContext = (function() { var ContextProxy; @@ -11815,10 +13082,10 @@ return new this.constructor(object, this); }; - RenderContext.prototype.descendWithKey = function(key, scopedKey) { + RenderContext.prototype.descendWithDefinition = function(definition) { var proxy; - proxy = new ContextProxy(this, key); - return this.descend(proxy, scopedKey); + proxy = new ContextProxy(definition); + return this.descend(proxy, definition.attr); }; RenderContext.prototype.chain = function() { @@ -11854,11 +13121,8 @@ } }); - function ContextProxy(renderContext, keyPath, localKey) { - this.renderContext = renderContext; - this.keyPath = keyPath; - this.localKey = localKey; - this.binding = new Batman.DOM.AbstractBinding(void 0, this.keyPath, this.renderContext); + function ContextProxy(definition) { + this.binding = new Batman.DOM.AbstractBinding(definition); } return ContextProxy; @@ -11875,7 +13139,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }; Batman.ViewStore = (function(_super) { @@ -11907,7 +13182,7 @@ 'final': true, get: function(path) { var contents; - if (path[0] !== '/') { + if (path.charAt(0) !== '/') { return this.get("/" + path); } if (this._viewContents[path]) { @@ -11926,7 +13201,7 @@ } }, set: function(path, content) { - if (path[0] !== '/') { + if (path.charAt(0) !== '/') { return this.set("/" + path, content); } this._requestedPaths.add(path); @@ -11959,7 +13234,18 @@ (function() { var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.View = (function(_super) { @@ -12025,7 +13311,7 @@ View.accessor('argumentBindings', function() { var _this = this; return new Batman.TerminalAccessible(function(key) { - var bindingKey, context, keyPath, node, _ref; + var bindingKey, context, definition, keyPath, node, _ref; if (!((node = _this.get('node')) && (context = _this.get('context')))) { return; } @@ -12037,7 +13323,8 @@ if ((_ref = _this[bindingKey]) != null) { _ref.die(); } - return _this[bindingKey] = new Batman.DOM.ViewArgumentBinding(node, keyPath, context); + definition = new Batman.DOM.ReaderBindingDefinition(node, keyPath, context); + return _this[bindingKey] = new Batman.DOM.ViewArgumentBinding(definition); }); }); @@ -12073,8 +13360,7 @@ return this.node; }, set: function(_, node) { - var updateHTML, - _this = this; + var updateHTML, _this = this; this.node = node; this._setNodeOwner(node); updateHTML = function(html) { @@ -12102,8 +13388,7 @@ }); function View(options) { - var context, - _this = this; + var context, _this = this; if (options == null) { options = {}; } @@ -12127,14 +13412,13 @@ } View.prototype.render = function() { - var node, - _this = this; + var node, _this = this; if (this._rendered) { return; } this._rendered = true; this._renderer = new Batman.Renderer(node = this.get('node'), this.get('context'), this); - return this._renderer.on('rendered', function() { + return this._renderer.once('rendered', function() { return _this.fire('ready', node); }); }; @@ -12157,6 +13441,26 @@ } }; + View.prototype.die = function() { + var _ref; + this.fire('destroy', this.node); + this.forget(); + if ((_ref = this._batman.properties) != null) { + _ref.forEach(function(key, property) { + return property.die(); + }); + } + return this.get('yields').forEach(function(name, actions) { + var node, _i, _len, _results; + _results = []; + for (_i = 0, _len = actions.length; _i < _len; _i++) { + node = actions[_i].node; + _results.push(Batman.DOM.didDestroyNode(node)); + } + return _results; + }); + }; + View.prototype.applyYields = function() { return this.get('yields').forEach(function(name, nodes) { var action, node, yieldObject, _i, _len, _ref, _results; @@ -12225,9 +13529,19 @@ }).call(this); (function() { - var Yield, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + var Yield, __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, __slice = [].slice; Batman.DOM.Yield = Yield = (function(_super) { @@ -12238,8 +13552,7 @@ Yield.queued = function(fn) { return function() { - var args, handler, - _this = this; + var args, handler, _this = this; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (this.containerNode != null) { return fn.apply(this, args); diff --git a/javascripts/dashing.coffee b/javascripts/dashing.coffee index d6d7e227..20a99874 100644 --- a/javascripts/dashing.coffee +++ b/javascripts/dashing.coffee @@ -11,7 +11,7 @@ Batman.Filters.dashize = (str) -> dashes_rx1 = /([A-Z]+)([A-Z][a-z])/g; dashes_rx2 = /([a-z\d])([A-Z])/g; - return str.replace(dashes_rx1, '$1_$2').replace(dashes_rx2, '$1_$2').replace('_', '-').toLowerCase() + return str.replace(dashes_rx1, '$1_$2').replace(dashes_rx2, '$1_$2').replace(/_/g, '-').toLowerCase() Batman.Filters.shortenedNumber = (num) -> return num if isNaN(num) @@ -25,6 +25,9 @@ Batman.Filters.shortenedNumber = (num) -> num class window.Dashing extends Batman.App + @on 'reload', (data) -> + window.location.reload(true) + @root -> Dashing.params = Batman.URI.paramsFromQuery(window.location.search.slice(1)); @@ -37,19 +40,26 @@ class Dashing.Widget extends Batman.View @mixin($(@node).data()) Dashing.widgets[@id] ||= [] Dashing.widgets[@id].push(@) - @mixin(Dashing.lastEvents[@id]) # in case the events from the server came before the widget was rendered type = Batman.Filters.dashize(@view) $(@node).addClass("widget widget-#{type} #{@id}") @accessor 'updatedAtMessage', -> if updatedAt = @get('updatedAt') - timestamp = updatedAt.toString().match(/\d*:\d*/)[0] - "Last updated at #{timestamp}" + timestamp = new Date(updatedAt * 1000) + hours = timestamp.getHours() + minutes = ("0" + timestamp.getMinutes()).slice(-2) + "Last updated at #{hours}:#{minutes}" @::on 'ready', -> Dashing.Widget.fire 'ready' + # In case the events from the server came before the widget was rendered + lastData = Dashing.lastEvents[@id] + if lastData + @mixin(lastData) + @onData(lastData) + receiveData: (data) => @mixin(data) @onData(data) @@ -70,7 +80,7 @@ Dashing.AnimatedValue = num = parseFloat(num) up = to > num num_interval = Math.abs(num - to) / 90 - @[timer] = + @[timer] = setInterval => num = if up then Math.ceil(num+num_interval) else Math.floor(num-num_interval) if (up && num > to) || (!up && num < to) @@ -80,30 +90,41 @@ Dashing.AnimatedValue = delete @[timer] @[k] = num @set k, to - @[k] = num + , 10 + @[k] = num Dashing.widgets = widgets = {} Dashing.lastEvents = lastEvents = {} Dashing.debugMode = false -source = new EventSource('/events') +source = new EventSource('events') source.addEventListener 'open', (e) -> - console.log("Connection opened") + console.log("Connection opened", e) source.addEventListener 'error', (e)-> - console.log("Connection error") - if (e.readyState == EventSource.CLOSED) + console.log("Connection error", e) + if (e.currentTarget.readyState == EventSource.CLOSED) console.log("Connection closed") + setTimeout (-> + window.location.reload() + ), 5*60*1000 -source.addEventListener 'message', (e) => +source.addEventListener 'message', (e) -> + data = JSON.parse(e.data) + if lastEvents[data.id]?.updatedAt != data.updatedAt + if Dashing.debugMode + console.log("Received data for #{data.id}", data) + lastEvents[data.id] = data + if widgets[data.id]?.length > 0 + for widget in widgets[data.id] + widget.receiveData(data) + +source.addEventListener 'dashboards', (e) -> data = JSON.parse(e.data) if Dashing.debugMode - console.log("Received data for #{data.id}", data) - lastEvents[data.id] = data - if widgets[data.id]?.length > 0 - for widget in widgets[data.id] - widget.receiveData(data) - + console.log("Received data for dashboards", data) + if data.dashboard is '*' or window.location.pathname is "/#{data.dashboard}" + Dashing.fire data.event, data $(document).ready -> Dashing.run() diff --git a/lib/dashing.rb b/lib/dashing.rb index 7d066cca..3527034b 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -1,111 +1,6 @@ -require 'sinatra' -require 'sprockets' -require 'sinatra/content_for' -require 'rufus/scheduler' -require 'coffee-script' -require 'sass' -require 'json' +require 'dashing/cli' +require 'dashing/downloader' +require 'dashing/app' -SCHEDULER = Rufus::Scheduler.start_new - -set :root, Dir.pwd - -set :sprockets, Sprockets::Environment.new(settings.root) -set :assets_prefix, '/assets' -set :digest_assets, false -['assets/javascripts', 'assets/stylesheets', 'assets/fonts', 'assets/images', 'widgets', File.expand_path('../../javascripts', __FILE__)]. each do |path| - settings.sprockets.append_path path -end - -set server: 'thin', connections: [], history: {} -set :public_folder, File.join(settings.root, 'public') -set :views, File.join(settings.root, 'dashboards') -set :default_dashboard, nil -set :auth_token, nil - -helpers Sinatra::ContentFor -helpers do - def protected! - # override with auth logic - end -end - -get '/events', provides: 'text/event-stream' do - protected! - stream :keep_open do |out| - settings.connections << out - out << latest_events - out.callback { settings.connections.delete(out) } - end -end - -get '/' do - begin - redirect "/" + (settings.default_dashboard || first_dashboard).to_s - rescue NoMethodError => e - raise Exception.new("There are no dashboards in your dashboard directory.") - end -end - -get '/:dashboard' do - protected! - erb params[:dashboard].to_sym -end - -get '/views/:widget?.html' do - protected! - widget = params[:widget] - send_file File.join(settings.root, 'widgets', widget, "#{widget}.html") -end - -post '/widgets/:id' do - request.body.rewind - body = JSON.parse(request.body.read) - auth_token = body.delete("auth_token") - if !settings.auth_token || settings.auth_token == auth_token - send_event(params['id'], body) - 204 # response without entity body - else - status 401 - "Invalid API key\n" - end -end - -def development? - ENV['RACK_ENV'] == 'development' -end - -def production? - ENV['RACK_ENV'] == 'production' -end - -def send_event(id, body) - body["id"] = id - body["updatedAt"] = Time.now - event = format_event(body.to_json) - settings.history[id] = event - settings.connections.each { |out| out << event } -end - -def format_event(body) - "data: #{body}\n\n" -end - -def latest_events - settings.history.inject("") do |str, (id, body)| - str << body - end -end - -def first_dashboard - files = Dir[File.join(settings.views, '*.erb')].collect { |f| f.match(/(\w*).erb/)[1] } - files -= ['layout'] - files.first -end - -Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } -{}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. - -job_path = ENV["JOB_PATH"] || 'jobs' -files = Dir[File.join(settings.root, job_path, '/*.rb')] -files.each { |job| require(job) } +module Dashing +end \ No newline at end of file diff --git a/lib/dashing/app.rb b/lib/dashing/app.rb new file mode 100644 index 00000000..b11352d2 --- /dev/null +++ b/lib/dashing/app.rb @@ -0,0 +1,181 @@ +require 'sinatra' +require 'sprockets' +require 'sinatra/content_for' +require 'rufus/scheduler' +require 'coffee-script' +require 'sass' +require 'json' +require 'yaml' +require 'thin' + +SCHEDULER = Rufus::Scheduler.new + +def development? + ENV['RACK_ENV'] == 'development' +end + +def production? + ENV['RACK_ENV'] == 'production' +end + +helpers Sinatra::ContentFor +helpers do + def protected! + # override with auth logic + end + + def authenticated?(token) + return true unless settings.auth_token + token && Rack::Utils.secure_compare(settings.auth_token, token) + end +end + +set :root, Dir.pwd +set :sprockets, Sprockets::Environment.new(settings.root) +set :assets_prefix, '/assets' +set :digest_assets, false +set server: 'thin', connections: [], history_file: 'history.yml' +set :public_folder, File.join(settings.root, 'public') +set :views, File.join(settings.root, 'dashboards') +set :default_dashboard, nil +set :auth_token, nil + +if File.exists?(settings.history_file) + set history: YAML.load_file(settings.history_file) +else + set history: {} +end + +%w(javascripts stylesheets fonts images).each do |path| + settings.sprockets.append_path("assets/#{path}") +end + +['widgets', File.expand_path('../../../javascripts', __FILE__)]. each do |path| + settings.sprockets.append_path(path) +end + +not_found do + send_file File.join(settings.public_folder, '404.html'), status: 404 +end + +at_exit do + File.write(settings.history_file, settings.history.to_yaml) +end + +get '/' do + protected! + dashboard = settings.default_dashboard || first_dashboard + raise Exception.new('There are no dashboards available') if not dashboard + + redirect "/" + dashboard +end + +get '/events', provides: 'text/event-stream' do + protected! + response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx + stream :keep_open do |out| + settings.connections << out + out << latest_events + out.callback { settings.connections.delete(out) } + end +end + +get '/:dashboard' do + protected! + tilt_html_engines.each do |suffix, _| + file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}") + return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file + end + + halt 404 +end + +post '/dashboards/:id' do + request.body.rewind + body = JSON.parse(request.body.read) + body['dashboard'] ||= params['id'] + if authenticated?(body.delete("auth_token")) + send_event(params['id'], body, 'dashboards') + 204 # response without entity body + else + status 401 + "Invalid API key\n" + end +end + +post '/widgets/:id' do + request.body.rewind + body = JSON.parse(request.body.read) + if authenticated?(body.delete("auth_token")) + send_event(params['id'], body) + 204 # response without entity body + else + status 401 + "Invalid API key\n" + end +end + +get '/views/:widget?.html' do + protected! + tilt_html_engines.each do |suffix, engines| + file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}") + return engines.first.new(file).render if File.exist? file + end +end + +Thin::Server.class_eval do + def stop_with_connection_closing + Sinatra::Application.settings.connections.dup.each(&:close) + stop_without_connection_closing + end + + alias_method :stop_without_connection_closing, :stop + alias_method :stop, :stop_with_connection_closing +end + +def send_event(id, body, target=nil) + body[:id] = id + body[:updatedAt] ||= Time.now.to_i + event = format_event(body.to_json, target) + Sinatra::Application.settings.history[id] = event unless target == 'dashboards' + Sinatra::Application.settings.connections.each { |out| out << event } +end + +def format_event(body, name=nil) + str = "" + str << "event: #{name}\n" if name + str << "data: #{body}\n\n" +end + +def latest_events + settings.history.inject("") do |str, (id, body)| + str << body + end +end + +def first_dashboard + files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') } + files -= ['layout'] + files.sort.first +end + +def tilt_html_engines + Tilt.mappings.select do |_, engines| + default_mime_type = engines.first.default_mime_type + default_mime_type.nil? || default_mime_type == 'text/html' + end +end + +def require_glob(relative_glob) + Dir[File.join(settings.root, relative_glob)].each do |file| + require file + end +end + +settings_file = File.join(settings.root, 'config/settings.rb') +require settings_file if File.exists?(settings_file) + +{}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. +job_path = ENV["JOB_PATH"] || 'jobs' +require_glob(File.join('lib', '**', '*.rb')) +require_glob(File.join(job_path, '**', '*.rb')) diff --git a/lib/dashing/cli.rb b/lib/dashing/cli.rb new file mode 100644 index 00000000..4b93f892 --- /dev/null +++ b/lib/dashing/cli.rb @@ -0,0 +1,109 @@ +require 'thor' +require 'open-uri' + +module Dashing + class CLI < Thor + include Thor::Actions + + attr_reader :name + + class << self + attr_accessor :auth_token + + def hyphenate(str) + return str.downcase if str =~ /^[A-Z-]+$/ + str.gsub('_', '-').gsub(/\B[A-Z]/, '-\&').squeeze('-').downcase + end + end + + no_tasks do + %w(widget dashboard job).each do |type| + define_method "generate_#{type}" do |name| + @name = Thor::Util.snake_case(name) + directory(type.to_sym, "#{type}s") + end + end + end + + desc "new PROJECT_NAME", "Sets up ALL THE THINGS needed for your dashboard project." + def new(name) + @name = Thor::Util.snake_case(name) + directory(:project, @name) + end + + desc "generate (widget/dashboard/job) NAME", "Creates a new widget, dashboard, or job." + def generate(type, name) + public_send("generate_#{type}".to_sym, name) + rescue NoMethodError => e + puts "Invalid generator. Either use widget, dashboard, or job" + end + + desc "install GIST_ID [--skip]", "Installs a new widget from a gist (skip overwrite)." + def install(gist_id, *args) + gist = Downloader.get_gist(gist_id) + public_url = "https://gist.github.com/#{gist_id}" + + install_widget_from_gist(gist, args.include?('--skip')) + + print set_color("Don't forget to edit the ", :yellow) + print set_color("Gemfile ", :yellow, :bold) + print set_color("and run ", :yellow) + print set_color("bundle install ", :yellow, :bold) + say set_color("if needed. More information for this widget can be found at #{public_url}", :yellow) + rescue OpenURI::HTTPError => http_error + say set_color("Could not find gist at #{public_url}"), :red + end + + desc "start", "Starts the server in style!" + method_option :job_path, :desc => "Specify the directory where jobs are stored" + def start(*args) + port_option = args.include?('-p') ? '' : ' -p 3030' + args = args.join(' ') + command = "bundle exec thin -R config.ru start#{port_option} #{args}" + command.prepend "export JOB_PATH=#{options[:job_path]}; " if options[:job_path] + run_command(command) + end + + desc "stop", "Stops the thin server" + def stop + command = "bundle exec thin stop" + run_command(command) + end + + desc "job JOB_NAME AUTH_TOKEN(optional)", "Runs the specified job. Make sure to supply your auth token if you have one set." + def job(name, auth_token = "") + Dir[File.join(Dir.pwd, 'lib/**/*.rb')].each {|file| require_file(file) } + self.class.auth_token = auth_token + f = File.join(Dir.pwd, "jobs", "#{name}.rb") + require_file(f) + end + + # map some commands + map 'g' => :generate + map 'i' => :install + map 's' => :start + + private + + def run_command(command) + system(command) + end + + def install_widget_from_gist(gist, skip_overwrite) + gist['files'].each do |file, details| + if file =~ /\.(html|coffee|scss)\z/ + widget_name = File.basename(file, '.*') + new_path = File.join(Dir.pwd, 'widgets', widget_name, file) + create_file(new_path, details['content'], :skip => skip_overwrite) + elsif file.end_with?('.rb') + new_path = File.join(Dir.pwd, 'jobs', file) + create_file(new_path, details['content'], :skip => skip_overwrite) + end + end + end + + def require_file(file) + require file + end + end +end diff --git a/lib/dashing/downloader.rb b/lib/dashing/downloader.rb new file mode 100644 index 00000000..140e8626 --- /dev/null +++ b/lib/dashing/downloader.rb @@ -0,0 +1,18 @@ +require 'net/http' +require 'open-uri' +require 'json' + +module Dashing + module Downloader + extend self + + def get_gist(gist_id) + get_json("https://api.github.com/gists/#{gist_id}") + end + + def get_json(url) + response = open(url).read + JSON.parse(response) + end + end +end diff --git a/shipit.rubygems.yml b/shipit.rubygems.yml new file mode 100644 index 00000000..c3f42d37 --- /dev/null +++ b/shipit.rubygems.yml @@ -0,0 +1 @@ +# using the default shipit config diff --git a/templates/project/.gitignore b/templates/project/.gitignore new file mode 100644 index 00000000..e1be11e4 --- /dev/null +++ b/templates/project/.gitignore @@ -0,0 +1,2 @@ +*DS_STORE +history.yml diff --git a/templates/project/Gemfile b/templates/project/Gemfile index 75cc574d..1235b375 100644 --- a/templates/project/Gemfile +++ b/templates/project/Gemfile @@ -1,3 +1,6 @@ -source :rubygems +source 'https://rubygems.org' -gem 'dashing' \ No newline at end of file +gem 'dashing' + +## Remove this if you don't need a twitter widget. +gem 'twitter', '>= 5.9.0' \ No newline at end of file diff --git a/templates/project/assets/fonts/FontAwesome.otf b/templates/project/assets/fonts/FontAwesome.otf new file mode 100644 index 00000000..3ed7f8b4 Binary files /dev/null and b/templates/project/assets/fonts/FontAwesome.otf differ diff --git a/templates/project/assets/fonts/fontawesome-webfont.eot b/templates/project/assets/fonts/fontawesome-webfont.eot index 89070c1e..9b6afaed 100644 Binary files a/templates/project/assets/fonts/fontawesome-webfont.eot and b/templates/project/assets/fonts/fontawesome-webfont.eot differ diff --git a/templates/project/assets/fonts/fontawesome-webfont.svg b/templates/project/assets/fonts/fontawesome-webfont.svg index 1245f92c..d05688e9 100644 --- a/templates/project/assets/fonts/fontawesome-webfont.svg +++ b/templates/project/assets/fonts/fontawesome-webfont.svg @@ -3,253 +3,653 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/project/assets/fonts/fontawesome-webfont.ttf b/templates/project/assets/fonts/fontawesome-webfont.ttf index c17e9f8d..26dea795 100644 Binary files a/templates/project/assets/fonts/fontawesome-webfont.ttf and b/templates/project/assets/fonts/fontawesome-webfont.ttf differ diff --git a/templates/project/assets/fonts/fontawesome-webfont.woff b/templates/project/assets/fonts/fontawesome-webfont.woff index 09f2469a..dc35ce3c 100644 Binary files a/templates/project/assets/fonts/fontawesome-webfont.woff and b/templates/project/assets/fonts/fontawesome-webfont.woff differ diff --git a/templates/project/assets/fonts/fontawesome-webfont.woff2 b/templates/project/assets/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..500e5172 Binary files /dev/null and b/templates/project/assets/fonts/fontawesome-webfont.woff2 differ diff --git a/templates/project/assets/javascripts/d3-3.2.8.js b/templates/project/assets/javascripts/d3-3.2.8.js new file mode 100755 index 00000000..91fa2ebd --- /dev/null +++ b/templates/project/assets/javascripts/d3-3.2.8.js @@ -0,0 +1,5 @@ +d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function i(){}function u(){}function a(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function o(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=Ca.length;r>e;++e){var i=Ca[e]+t;if(i in n)return i}}function c(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}function l(n){return Array.prototype.slice.call(n)}function s(){}function f(){}function h(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],a=0,o=u.length;o>a;a++)(i=u[a])&&t(i,a,e);return n}function C(n){return La(n,Ua),n}function z(n){var t,e;return function(r,i,u){var a,o=n[u].update,c=o.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(a=o[t])&&++t0&&(n=n.substring(0,o));var l=Va.get(n);return l&&(n=l,c=L),o?t?i:r:t?s:u}function j(n,t){return function(e){var r=ya.event;ya.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ya.event=r}}}function L(n,t){var e=j(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function H(){var n=".dragsuppress-"+ ++Za,t="touchmove"+n,e="selectstart"+n,r="dragstart"+n,i="click"+n,u=ya.select(ba).on(t,g).on(e,g).on(r,g),a=xa.style,o=a[Xa];return a[Xa]="none",function(t){function e(){u.on(i,null)}u.on(n,null),a[Xa]=o,t&&(u.on(i,function(){g(),e()},!0),setTimeout(e,0))}}function F(n,t){var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>Ba&&(ba.scrollX||ba.scrollY)){e=ya.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var i=e[0][0].getScreenCTM();Ba=!(i.f||i.e),e.remove()}return Ba?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var u=n.getBoundingClientRect();return[t.clientX-u.left-n.clientLeft,t.clientY-u.top-n.clientTop]}function P(){}function O(n,t,e){return new Y(n,t,e)}function Y(n,t,e){this.h=n,this.s=t,this.l=e}function R(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(a-u)*n/60:180>n?a:240>n?u+(a-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,a;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+t):e+t-e*t,u=2*e-a,at(i(n+120),i(n),i(n-120))}function U(n){return n>0?1:0>n?-1:0}function I(n){return n>1?0:-1>n?Ka:Math.acos(n)}function V(n){return n>1?Ka/2:-1>n?-Ka/2:Math.asin(n)}function X(n){return(Math.exp(n)-Math.exp(-n))/2}function Z(n){return(Math.exp(n)+Math.exp(-n))/2}function B(n){return(n=Math.sin(n/2))*n}function $(n,t,e){return new W(n,t,e)}function W(n,t,e){this.h=n,this.c=t,this.l=e}function J(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),G(e,Math.cos(n*=to)*t,Math.sin(n)*t)}function G(n,t,e){return new K(n,t,e)}function K(n,t,e){this.l=n,this.a=t,this.b=e}function Q(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=tt(i)*uo,r=tt(r)*ao,u=tt(u)*oo,at(rt(3.2404542*i-1.5371385*r-.4985314*u),rt(-.969266*i+1.8760108*r+.041556*u),rt(.0556434*i-.2040259*r+1.0572252*u))}function nt(n,t,e){return n>0?$(Math.atan2(e,t)*eo,Math.sqrt(t*t+e*e),n):$(0/0,0/0,n)}function tt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function et(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function rt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function it(n){return at(n>>16,255&n>>8,255&n)}function ut(n){return it(n)+""}function at(n,t,e){return new ot(n,t,e)}function ot(n,t,e){this.r=n,this.g=t,this.b=e}function ct(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function lt(n,t,e){var r,i,u,a=0,o=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(gt(i[0]),gt(i[1]),gt(i[2]))}return(u=so.get(n))?t(u.r,u.g,u.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(a=n.charAt(1),a+=a,o=n.charAt(2),o+=o,c=n.charAt(3),c+=c):7===n.length&&(a=n.substring(1,3),o=n.substring(3,5),c=n.substring(5,7)),a=parseInt(a,16),o=parseInt(o,16),c=parseInt(c,16)),t(a,o,c))}function st(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),a=Math.max(n,t,e),o=a-u,c=(a+u)/2;return o?(i=.5>c?o/(a+u):o/(2-a-u),r=n==a?(t-e)/o+(e>t?6:0):t==a?(e-n)/o+2:(n-t)/o+4,r*=60):(r=0/0,i=c>0&&1>c?0:r),O(r,i,c)}function ft(n,t,e){n=ht(n),t=ht(t),e=ht(e);var r=et((.4124564*n+.3575761*t+.1804375*e)/uo),i=et((.2126729*n+.7151522*t+.072175*e)/ao),u=et((.0193339*n+.119192*t+.9503041*e)/oo);return G(116*i-16,500*(r-i),200*(i-u))}function ht(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function gt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function pt(n){return"function"==typeof n?n:function(){return n}}function mt(n){return n}function dt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),vt(t,e,n,r)}}function vt(n,t,e,r){function i(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(u,c)}catch(r){return a.error.call(u,r),void 0}a.load.call(u,n)}else a.error.call(u,c)}var u={},a=ya.dispatch("progress","load","error"),o={},c=new XMLHttpRequest,l=null;return!ba.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=i:c.onreadystatechange=function(){c.readyState>3&&i()},c.onprogress=function(n){var t=ya.event;ya.event=n;try{a.progress.call(u,c)}finally{ya.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?o[n]:(null==t?delete o[n]:o[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(l=n,u):l},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(za(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),c.open(e,n,!0),null==t||"accept"in o||(o.accept=t+",*/*"),c.setRequestHeader)for(var a in o)c.setRequestHeader(a,o[a]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),c.send(null==r?null:r),u},u.abort=function(){return c.abort(),u},ya.rebind(u,a,"on"),null==r?u:u.get(yt(r))}function yt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Mt(){var n=bt(),t=_t()-n;t>24?(isFinite(t)&&(clearTimeout(po),po=setTimeout(Mt,t)),go=0):(go=1,vo(Mt))}function xt(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now()),mo.callback=n,mo.time=e+t}function bt(){var n=Date.now();for(mo=fo;mo;)n>=mo.time&&(mo.flush=mo.callback(n-mo.time)),mo=mo.next;return n}function _t(){for(var n,t=fo,e=1/0;t;)t.flush?t=n?n.next=t.next:fo=t.next:(t.time8?function(n){return n/e}:function(n){return n*e},symbol:n}}function St(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Et(n){return n+""}function kt(){}function At(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function Nt(n,t){n&&qo.hasOwnProperty(n.type)&&qo[n.type](n,t)}function qt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++io;++o)i.point((e=n[o])[0],e[1]);return i.lineEnd(),void 0}var c={point:e,points:n,other:null,visited:!1,entry:!0,subject:!0},l={point:e,points:[e],other:c,visited:!1,entry:!1,subject:!1};c.other=l,u.push(c),a.push(l),c={point:r,points:[r],other:null,visited:!1,entry:!1,subject:!0},l={point:r,points:[r],other:c,visited:!1,entry:!0,subject:!1},c.other=l,u.push(c),a.push(l)}}),a.sort(t),Bt(u),Bt(a),u.length){if(e)for(var o=1,c=!e(a[0].point),l=a.length;l>o;++o)a[o].entry=c=!c;for(var s,f,h,g=u[0];;){for(s=g;s.visited;)if((s=s.next)===g)return;f=s.points,i.lineStart();do{if(s.visited=s.other.visited=!0,s.entry){if(s.subject)for(var o=0;o=0;)i.point((h=f[o])[0],h[1])}else r(s.point,s.prev.point,-1,i);s=s.prev}s=s.other,f=s.points}while(!s.visited);i.lineEnd()}}}function Bt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r1&&2&t&&e.push(e.pop().concat(e.shift())),h.push(e.filter(Wt))}}var h,g,p,m=t(i),d={point:u,lineStart:o,lineEnd:c,polygonStart:function(){d.point=l,d.lineStart=s,d.lineEnd=f,h=[],g=[],i.polygonStart()},polygonEnd:function(){d.point=u,d.lineStart=o,d.lineEnd=c,h=ya.merge(h),h.length?Zt(h,Gt,null,e,i):r(g)&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),h=g=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},v=Jt(),y=t(v);return d}}function Wt(n){return n.length>1}function Jt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:s,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Gt(n,t){return((n=n.point)[0]<0?n[1]-Ka/2-Qa:Ka/2-n[1])-((t=t.point)[0]<0?t[1]-Ka/2-Qa:Ka/2-t[1])}function Kt(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,a=!1,o=!1,c=0;Co.reset();for(var l=0,s=t.length;s>l;++l){var f=t[l],h=f.length;if(h){for(var g=f[0],p=g[0],m=g[1]/2+Ka/4,d=Math.sin(m),v=Math.cos(m),y=1;;){y===h&&(y=0),n=f[y];var M=n[0],x=n[1]/2+Ka/4,b=Math.sin(x),_=Math.cos(x),w=M-p,S=Math.abs(w)>Ka,E=d*b;if(Co.add(Math.atan2(E*Math.sin(w),v*_+E*Math.cos(w))),Math.abs(x)=0?2:-2)*Ka:w,S^p>=e^M>=e){var k=jt(zt(g),zt(n));Ft(k);var A=jt(i,k);Ft(A);var N=(S^w>=0?-1:1)*V(A[2]);r>N&&(c+=S^w>=0?1:-1)}if(!y++)break;p=M,d=b,v=_,g=n}Math.abs(u)>Qa&&(a=!0)}}return(!o&&!a&&0>Co||-Qa>u)^1&c}function Qt(n){var t,e=0/0,r=0/0,i=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(u,a){var o=u>0?Ka:-Ka,c=Math.abs(u-e);Math.abs(c-Ka)0?Ka/2:-Ka/2),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(o,r),n.point(u,r),t=0):i!==o&&c>=Ka&&(Math.abs(e-i)Qa?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*a)):(t+r)/2}function te(n,t,e,r){var i;if(null==n)i=e*Ka/2,r.point(-Ka,i),r.point(0,i),r.point(Ka,i),r.point(Ka,0),r.point(Ka,-i),r.point(0,-i),r.point(-Ka,-i),r.point(-Ka,0),r.point(-Ka,i);else if(Math.abs(n[0]-t[0])>Qa){var u=(n[0]a}function e(n){var e,u,a,c,s;return{lineStart:function(){c=a=!1,s=1},point:function(f,h){var g,p=[f,h],m=t(f,h),d=o?m?0:i(f,h):m?i(f+(0>f?Ka:-Ka),h):0;if(!e&&(c=a=m)&&n.lineStart(),m!==a&&(g=r(e,p),(Ot(e,g)||Ot(p,g))&&(p[0]+=Qa,p[1]+=Qa,m=t(p[0],p[1]))),m!==a)s=0,m?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(l&&e&&o^m){var v;d&u||!(v=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(v[0][0],v[0][1]),n.point(v[1][0],v[1][1]),n.lineEnd()):(n.point(v[1][0],v[1][1]),n.lineEnd(),n.lineStart(),n.point(v[0][0],v[0][1])))}!m||e&&Ot(e,p)||n.point(p[0],p[1]),e=p,a=m,u=d},lineEnd:function(){a&&n.lineEnd(),e=null},clean:function(){return s|(c&&a)<<1}}}function r(n,t,e){var r=zt(n),i=zt(t),u=[1,0,0],o=jt(r,i),c=Dt(o,o),l=o[0],s=c-l*l;if(!s)return!e&&n;var f=a*c/s,h=-a*l/s,g=jt(u,o),p=Ht(u,f),m=Ht(o,h);Lt(p,m);var d=g,v=Dt(p,d),y=Dt(d,d),M=v*v-y*(Dt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=Ht(d,(-v-x)/y);if(Lt(b,p),b=Pt(b),!e)return b;var _,w=n[0],S=t[0],E=n[1],k=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=Math.abs(A-Ka)A;if(!N&&E>k&&(_=E,E=k,k=_),q?N?E+k>0^b[1]<(Math.abs(b[0]-w)Ka^(w<=b[0]&&b[0]<=S)){var T=Ht(d,(-v+x)/y);return Lt(T,p),[b,Pt(T)]}}}function i(t,e){var r=o?n:Ka-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}function u(n){return Kt(c,n)}var a=Math.cos(n),o=a>0,c=[n,0],l=Math.abs(a)>Qa,s=Ne(n,6*to);return $t(t,e,s,u)}function ie(n,t,e,r){function i(r,i){return Math.abs(r[0]-n)0?0:3:Math.abs(r[0]-e)0?2:1:Math.abs(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return a(n.point,t.point)}function a(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}function o(i,u){var a=u[0]-i[0],o=u[1]-i[1],c=[0,1];return Math.abs(a)0&&(i[0]+=c[0]*a,i[1]+=c[0]*o),!0):!1}return function(c){function l(u){var a=i(u,-1),o=s([0===a||3===a?n:e,a>1?r:t]);return o}function s(n){for(var t=0,e=M.length,r=n[1],i=0;e>i;++i)for(var u,a=1,o=M[i],c=o.length,l=o[0];c>a;++a)u=o[a],l[1]<=r?u[1]>r&&f(l,u,n)>0&&++t:u[1]<=r&&f(l,u,n)<0&&--t,l=u;return 0!==t}function f(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(e[0]-n[0])*(t[1]-n[1])}function h(u,o,c,l){var s=0,f=0;if(null==u||(s=i(u,c))!==(f=i(o,c))||a(u,o)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(o[0],o[1])}function g(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function p(n,t){g(n,t)&&c.point(n,t)}function m(){T.point=v,M&&M.push(x=[]),A=!0,k=!1,S=E=0/0}function d(){y&&(v(b,_),w&&k&&q.rejoin(),y.push(q.buffer())),T.point=p,k&&c.lineEnd()}function v(n,t){n=Math.max(-Bo,Math.min(Bo,n)),t=Math.max(-Bo,Math.min(Bo,t));var e=g(n,t);if(M&&x.push([n,t]),A)b=n,_=t,w=e,A=!1,e&&(c.lineStart(),c.point(n,t));else if(e&&k)c.point(n,t);else{var r=[S,E],i=[n,t];o(r,i)?(k||(c.lineStart(),c.point(r[0],r[1])),c.point(i[0],i[1]),e||c.lineEnd()):e&&(c.lineStart(),c.point(n,t))}S=n,E=t,k=e}var y,M,x,b,_,w,S,E,k,A,N=c,q=Jt(),T={point:p,lineStart:m,lineEnd:d,polygonStart:function(){c=q,y=[],M=[]},polygonEnd:function(){c=N,(y=ya.merge(y)).length?(c.polygonStart(),Zt(y,u,l,h,c),c.polygonEnd()):s([n,t])&&(c.polygonStart(),c.lineStart(),h(null,null,1,c),c.lineEnd(),c.polygonEnd()),y=M=x=null}};return T}}function ue(n,t,e){if(Math.abs(t)=n;var r=n/t;if(t>0){if(r>e[1])return!1;r>e[0]&&(e[0]=r)}else{if(rn&&(Jo=n),n>Ko&&(Ko=n),Go>t&&(Go=t),t>Qo&&(Qo=t)}function fe(){function n(n,t){a.push("M",n,",",t,u)}function t(n,t){a.push("M",n,",",t),o.point=e}function e(n,t){a.push("L",n,",",t)}function r(){o.point=n}function i(){a.push("Z")}var u=he(4.5),a=[],o={point:n,lineStart:function(){o.point=t},lineEnd:r,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=r,o.point=n},pointRadius:function(n){return u=he(n),o},result:function(){if(a.length){var n=a.join("");return a=[],n}}};return o}function he(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function ge(n,t){Lo+=n,Ho+=t,++Fo}function pe(){function n(n,r){var i=n-t,u=r-e,a=Math.sqrt(i*i+u*u);Po+=a*(t+n)/2,Oo+=a*(e+r)/2,Yo+=a,ge(t=n,e=r)}var t,e;ec.point=function(r,i){ec.point=n,ge(t=r,e=i)}}function me(){ec.point=ge}function de(){function n(n,t){var e=n-r,u=t-i,a=Math.sqrt(e*e+u*u);Po+=a*(r+n)/2,Oo+=a*(i+t)/2,Yo+=a,a=i*n-r*t,Ro+=a*(r+n),Uo+=a*(i+t),Io+=3*a,ge(r=n,i=t)}var t,e,r,i;ec.point=function(u,a){ec.point=n,ge(t=r=u,e=i=a)},ec.lineEnd=function(){n(t,e)}}function ve(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,a,0,2*Ka)}function e(t,e){n.moveTo(t,e),o.point=r}function r(t,e){n.lineTo(t,e)}function i(){o.point=t}function u(){n.closePath()}var a=4.5,o={point:t,lineStart:function(){o.point=e},lineEnd:i,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=i,o.point=t},pointRadius:function(n){return a=n,o},result:s};return o}function ye(n){function t(t){function r(e,r){e=n(e,r),t.point(e[0],e[1])}function i(){M=0/0,S.point=a,t.lineStart()}function a(r,i){var a=zt([r,i]),o=n(r,i);e(M,x,y,b,_,w,M=o[0],x=o[1],y=r,b=a[0],_=a[1],w=a[2],u,t),t.point(M,x)}function o(){S.point=r,t.lineEnd()}function c(){i(),S.point=l,S.lineEnd=s}function l(n,t){a(f=n,h=t),g=M,p=x,m=b,d=_,v=w,S.point=a}function s(){e(M,x,y,b,_,w,g,p,f,m,d,v,u,t),S.lineEnd=o,o()}var f,h,g,p,m,d,v,y,M,x,b,_,w,S={point:r,lineStart:i,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=i}};return S}function e(t,u,a,o,c,l,s,f,h,g,p,m,d,v){var y=s-t,M=f-u,x=y*y+M*M;if(x>4*r&&d--){var b=o+g,_=c+p,w=l+m,S=Math.sqrt(b*b+_*_+w*w),E=Math.asin(w/=S),k=Math.abs(Math.abs(w)-1)r||Math.abs((y*T+M*C)/x-.5)>.3||i>o*g+c*p+l*m)&&(e(t,u,a,o,c,l,N,q,k,b/=S,_/=S,w,d,v),v.point(N,q),e(N,q,k,b,_,w,s,f,h,g,p,m,d,v))}}var r=.5,i=Math.cos(30*to),u=16;return t.precision=function(n){return arguments.length?(u=(r=n*n)>0&&16,t):Math.sqrt(r)},t}function Me(n){var t=ye(function(t,e){return n([t*eo,e*eo])});return function(n){return n=t(n),{point:function(t,e){n.point(t*to,e*to)},sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}}function xe(n){return be(function(){return n})()}function be(n){function t(n){return n=o(n[0]*to,n[1]*to),[n[0]*h+c,l-n[1]*h]}function e(n){return n=o.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*eo,n[1]*eo]}function r(){o=ae(a=Se(v,y,M),u);var n=u(m,d);return c=g-n[0]*h,l=p+n[1]*h,i()}function i(){return s&&(s.valid=!1,s=null),t}var u,a,o,c,l,s,f=ye(function(n,t){return n=u(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,m=0,d=0,v=0,y=0,M=0,x=Xo,b=mt,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=_e(a,x(f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Xo):re((_=+n)*to),i()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=null==n?mt:ie(n[0][0],n[0][1],n[1][0],n[1][1]),i()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(m=n[0]%360*to,d=n[1]%360*to,r()):[m*eo,d*eo]},t.rotate=function(n){return arguments.length?(v=n[0]%360*to,y=n[1]%360*to,M=n.length>2?n[2]%360*to:0,r()):[v*eo,y*eo,M*eo]},ya.rebind(t,f,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function _e(n,t){return{point:function(e,r){r=n(e*to,r*to),e=r[0],t.point(e>Ka?e-2*Ka:-Ka>e?e+2*Ka:e,r[1])},sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}function we(n,t){return[n,t]}function Se(n,t,e){return n?t||e?ae(ke(n),Ae(t,e)):ke(n):t||e?Ae(t,e):we}function Ee(n){return function(t,e){return t+=n,[t>Ka?t-2*Ka:-Ka>t?t+2*Ka:t,e]}}function ke(n){var t=Ee(n);return t.invert=Ee(-n),t}function Ae(n,t){function e(n,t){var e=Math.cos(t),o=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+o*i;return[Math.atan2(c*u-s*a,o*r-l*i),V(s*u+c*a)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),a=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),o=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*u-c*a;return[Math.atan2(c*u+l*a,o*r+s*i),V(s*r-o*i)]},e}function Ne(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,a,o){null!=i?(i=qe(e,i),u=qe(e,u),(a>0?u>i:i>u)&&(i+=2*a*Ka)):(i=n+2*a*Ka,u=n);for(var c,l=a*t,s=i;a>0?s>u:u>s;s-=l)o.point((c=Pt([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],c[1])}}function qe(n,t){var e=zt(t);e[0]-=n,Ft(e);var r=I(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Qa)%(2*Math.PI)}function Te(n,t,e){var r=ya.range(n,t-Qa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function Ce(n,t,e){var r=ya.range(n,t-Qa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function ze(n){return n.source}function De(n){return n.target}function je(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),a=Math.cos(r),o=Math.sin(r),c=i*Math.cos(n),l=i*Math.sin(n),s=a*Math.cos(e),f=a*Math.sin(e),h=2*Math.asin(Math.sqrt(B(r-t)+i*a*B(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,i=e*l+t*f,a=e*u+t*o;return[Math.atan2(i,r)*eo,Math.atan2(a,Math.sqrt(r*r+i*i))*eo]}:function(){return[n*eo,t*eo]};return p.distance=h,p}function Le(){function n(n,i){var u=Math.sin(i*=to),a=Math.cos(i),o=Math.abs((n*=to)-t),c=Math.cos(o);rc+=Math.atan2(Math.sqrt((o=a*Math.sin(o))*o+(o=r*u-e*a*c)*o),e*u+r*a*c),t=n,e=u,r=a}var t,e,r;ic.point=function(i,u){t=i*to,e=Math.sin(u*=to),r=Math.cos(u),ic.point=n},ic.lineEnd=function(){ic.point=ic.lineEnd=s}}function He(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),a=Math.cos(i);return[Math.atan2(n*u,r*a),Math.asin(r&&e*u/r)]},e}function Fe(n,t){function e(n,t){var e=Math.abs(Math.abs(t)-Ka/2)1&&i.push("H",r[0]),i.join("")}function $e(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){o=t[1],u=n[c],c++,r+="C"+(i[0]+a[0])+","+(i[1]+a[1])+","+(u[0]-o[0])+","+(u[1]-o[1])+","+u[0]+","+u[1];for(var l=2;l9&&(i=3*t/Math.sqrt(i),a[o]=i*e,a[o+1]=i*r));for(o=-1;++o<=c;)i=(n[Math.min(c,o+1)][0]-n[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),u.push([i||0,a[o]*i||0]);return u}function sr(n){return n.length<3?Xe(n):n[0]+Qe(n,lr(n))}function fr(n,t,e,r){var i,u,a,o,c,l,s;return i=r[n],u=i[0],a=i[1],i=r[t],o=i[0],c=i[1],i=r[e],l=i[0],s=i[1],(s-a)*(o-u)-(c-a)*(l-u)>0}function hr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function gr(n,t,e,r){var i=n[0],u=e[0],a=t[0]-i,o=r[0]-u,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(o*(c-l)-f*(i-u))/(f*a-o*s);return[i+h*a,c+h*s]}function pr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function mr(n,t){var e={list:n.map(function(n,t){return{index:t,x:n[0],y:n[1]}}).sort(function(n,t){return n.yt.y?1:n.xt.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(n,t){return{edge:n,side:t,vertex:null,l:null,r:null}},insert:function(n,t){t.l=n,t.r=n.r,n.r.l=t,n.r=t},leftBound:function(n){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&i.rightOf(t,n));return t=t.l},del:function(n){n.l.r=n.r,n.r.l=n.l,n.edge=null},right:function(n){return n.r},left:function(n){return n.l},leftRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[n.side]},rightRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[mc[n.side]]}},i={bisect:function(n,t){var e={region:{l:n,r:t},ep:{l:null,r:null}},r=t.x-n.x,i=t.y-n.y,u=r>0?r:-r,a=i>0?i:-i;return e.c=n.x*r+n.y*i+.5*(r*r+i*i),u>a?(e.a=1,e.b=i/r,e.c/=r):(e.b=1,e.a=r/i,e.c/=i),e},intersect:function(n,t){var e=n.edge,r=t.edge;if(!e||!r||e.region.r==r.region.r)return null;var i=e.a*r.b-e.b*r.a;if(Math.abs(i)<1e-10)return null;var u,a,o=(e.c*r.b-r.c*e.b)/i,c=(r.c*e.a-e.c*r.a)/i,l=e.region.r,s=r.region.r;l.y=a.region.r.x;return f&&"l"===u.side||!f&&"r"===u.side?null:{x:o,y:c}},rightOf:function(n,t){var e=n.edge,r=e.region.r,i=t.x>r.x;if(i&&"l"===n.side)return 1;if(!i&&"r"===n.side)return 0;if(1===e.a){var u=t.y-r.y,a=t.x-r.x,o=0,c=0;if(!i&&e.b<0||i&&e.b>=0?c=o=u>=e.b*a:(c=t.x+t.y*e.b>e.c,e.b<0&&(c=!c),c||(o=1)),!o){var l=r.x-e.region.l.x;c=e.b*(a*a-u*u)h*h+g*g}return"l"===n.side?c:!c},endPoint:function(n,e,r){n.ep[e]=r,n.ep[mc[e]]&&t(n)},distance:function(n,t){var e=n.x-t.x,r=n.y-t.y;return Math.sqrt(e*e+r*r)}},u={list:[],insert:function(n,t,e){n.vertex=t,n.ystar=t.y+e;for(var r=0,i=u.list,a=i.length;a>r;r++){var o=i[r];if(!(n.ystar>o.ystar||n.ystar==o.ystar&&t.x>o.vertex.x))break}i.splice(r,0,n)},del:function(n){for(var t=0,e=u.list,r=e.length;r>t&&e[t]!=n;++t);e.splice(t,1)},empty:function(){return 0===u.list.length},nextEvent:function(n){for(var t=0,e=u.list,r=e.length;r>t;++t)if(e[t]==n)return e[t+1];return null},min:function(){var n=u.list[0];return{x:n.vertex.x,y:n.ystar}},extractMin:function(){return u.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var a,o,c,l,s,f,h,g,p,m,d,v,y,M=e.list.shift();;)if(u.empty()||(a=u.min()),M&&(u.empty()||M.yg.y&&(p=h,h=g,g=p,y="r"),v=i.bisect(h,g),f=r.createHalfEdge(v,y),r.insert(l,f),i.endPoint(v,mc[y],d),m=i.intersect(l,f),m&&(u.del(l),u.insert(l,m,i.distance(m,h))),m=i.intersect(f,s),m&&u.insert(f,m,i.distance(m,h))}for(o=r.right(r.leftEnd);o!=r.rightEnd;o=r.right(o))t(o.edge)}function dr(n){return n.x}function vr(n){return n.y}function yr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function Mr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var a=.5*(e+i),o=.5*(r+u),c=t.nodes;c[0]&&Mr(n,c[0],e,r,a,o),c[1]&&Mr(n,c[1],a,r,i,o),c[2]&&Mr(n,c[2],e,o,a,u),c[3]&&Mr(n,c[3],a,o,i,u)}}function xr(n,t){n=ya.rgb(n),t=ya.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,a=t.g-r,o=t.b-i;return function(n){return"#"+ct(Math.round(e+u*n))+ct(Math.round(r+a*n))+ct(Math.round(i+o*n))}}function br(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Sr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function _r(n,t){return t-=n=+n,function(e){return n+t*e}}function wr(n,t){var e,r,i,u,a,o=0,c=0,l=[],s=[];for(n+="",t+="",dc.lastIndex=0,r=0;e=dc.exec(t);++r)e.index&&l.push(t.substring(o,c=e.index)),s.push({i:l.length,x:e[0]}),l.push(null),o=dc.lastIndex;for(or;++r)if(a=s[r],a.x==e[0]){if(a.i)if(null==l[a.i+1])for(l[a.i-1]+=a.x,l.splice(a.i,1),i=r+1;u>i;++i)s[i].i--;else for(l[a.i-1]+=a.x+l[a.i+1],l.splice(a.i,2),i=r+1;u>i;++i)s[i].i-=2;else if(null==l[a.i+1])l[a.i]=a.x;else for(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1),i=r+1;u>i;++i)s[i].i--;s.splice(r,1),u--,r--}else a.x=_r(parseFloat(e[0]),parseFloat(a.x));for(;u>r;)a=s.pop(),null==l[a.i+1]?l[a.i]=a.x:(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1)),u--;return 1===l.length?null==l[0]?(a=s[0].x,function(n){return a(n)+""}):function(){return t}:function(n){for(r=0;u>r;++r)l[(a=s[r]).i]=a.x(n);return l.join("")}}function Sr(n,t){for(var e,r=ya.interpolators.length;--r>=0&&!(e=ya.interpolators[r](n,t)););return e}function Er(n,t){var e,r=[],i=[],u=n.length,a=t.length,o=Math.min(n.length,t.length);for(e=0;o>e;++e)r.push(Sr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;a>e;++e)i[e]=t[e];return function(n){for(e=0;o>e;++e)i[e]=r[e](n);return i}}function kr(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function Ar(n){return function(t){return 1-n(1-t)}}function Nr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function qr(n){return n*n}function Tr(n){return n*n*n}function Cr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function zr(n){return function(t){return Math.pow(t,n)}}function Dr(n){return 1-Math.cos(n*Ka/2)}function jr(n){return Math.pow(2,10*(n-1))}function Lr(n){return 1-Math.sqrt(1-n*n)}function Hr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/(2*Ka)*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,10*-r)*Math.sin(2*(r-e)*Ka/t)}}function Fr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Pr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Or(n,t){n=ya.hcl(n),t=ya.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,a=t.c-r,o=t.l-i;return isNaN(a)&&(a=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return J(e+u*n,r+a*n,i+o*n)+""}}function Yr(n,t){n=ya.hsl(n),t=ya.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,a=t.s-r,o=t.l-i;return isNaN(a)&&(a=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return R(e+u*n,r+a*n,i+o*n)+""}}function Rr(n,t){n=ya.lab(n),t=ya.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,a=t.a-r,o=t.b-i;return function(n){return Q(e+u*n,r+a*n,i+o*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Ir(n){var t=[n.a,n.b],e=[n.c,n.d],r=Xr(t),i=Vr(t,e),u=Xr(Zr(e,t,-i))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),i.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:_r(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?i.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:_r(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),i.push({i:e-4,x:_r(g[0],p[0])},{i:e-2,x:_r(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=i.length,function(n){for(var t,u=-1;++ue;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function mi(n){return n.reduce(di,0)}function di(n,t){return n+t[1]}function vi(n,t){return yi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function yi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function Mi(n){return[ya.min(n),ya.max(n)]}function xi(n,t){return n.parent==t.parent?1:2}function bi(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function _i(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function wi(n,t){var e=n.children;if(e&&(i=e.length))for(var r,i,u=-1;++u0&&(n=r);return n}function Si(n,t){return n.x-t.x}function Ei(n,t){return t.x-n.x}function ki(n,t){return n.depth-t.depth}function Ai(n,t){function e(n,r){var i=n.children;if(i&&(a=i.length))for(var u,a,o=null,c=-1;++c=0;)t=i[u]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function qi(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function Ti(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function Ci(n,t){return n.value-t.value}function zi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Di(n,t){n._pack_next=t,t._pack_prev=n}function ji(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Li(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,i,u,a,o,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(Hi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(i=e[1],i.x=i.r,i.y=0,t(i),l>2))for(u=e[2],Oi(r,i,u),t(u),zi(r,u),r._pack_prev=u,zi(u,i),i=r._pack_next,a=3;l>a;a++){Oi(r,i,u=e[a]);var p=0,m=1,d=1;for(o=i._pack_next;o!==i;o=o._pack_next,m++)if(ji(o,u)){p=1;break}if(1==p)for(c=r._pack_prev;c!==o._pack_prev&&!ji(c,u);c=c._pack_prev,d++);p?(d>m||m==d&&i.ra;a++)u=e[a],u.x-=v,u.y-=y,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Fi)}}function Hi(n){n._pack_next=n._pack_prev=n}function Fi(n){delete n._pack_next,delete n._pack_prev}function Pi(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,a=i.length;++ui&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Bi(n){return n.rangeExtent?n.rangeExtent():Zi(n.range())}function $i(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Wi(n,t){var e,r=0,i=n.length-1,u=n[r],a=n[i];return u>a&&(e=r,r=i,i=e,e=u,u=a,a=e),n[r]=t.floor(u),n[i]=t.ceil(a),n}function Ji(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:kc}function Gi(n,t,e,r){var i=[],u=[],a=0,o=Math.min(n.length,t.length)-1;for(n[o]2?Gi:$i,c=r?Wr:$r;return a=i(n,t,c,e),o=i(t,n,c,Sr),u}function u(n){return a(n)}var a,o;return u.invert=function(n){return o(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return ru(n,t)},u.tickFormat=function(t,e){return iu(n,t,e)},u.nice=function(t){return nu(n,t),i()},u.copy=function(){return Ki(n,t,e,r)},i()}function Qi(n,t){return ya.rebind(n,t,"range","rangeRound","interpolate","clamp")}function nu(n,t){return Wi(n,Ji(t?eu(n,t)[2]:tu(n)))}function tu(n){var t=Zi(n),e=t[1]-t[0];return Math.pow(10,Math.round(Math.log(e)/Math.LN10)-1)}function eu(n,t){var e=Zi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function ru(n,t){return ya.range.apply(ya,eu(n,t))}function iu(n,t,e){var r=-Math.floor(Math.log(eu(n,t)[2])/Math.LN10+.01);return ya.format(e?e.replace(wo,function(n,t,e,i,u,a,o,c,l,s){return[t,e,i,u,a,o,c,l||"."+(r-2*("%"===s)),s].join("")}):",."+r+"f")}function uu(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function a(t){return n(i(t))}return a.invert=function(t){return u(n.invert(t))},a.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),a):r},a.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),a):t},a.nice=function(){var t=Wi(r.map(i),e?Math:Nc);return n.domain(t),r=t.map(u),a},a.ticks=function(){var n=Zi(r),a=[],o=n[0],c=n[1],l=Math.floor(i(o)),s=Math.ceil(i(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)a.push(u(l)*h);a.push(u(l))}else for(a.push(u(l));l++0;h--)a.push(u(l)*h);for(l=0;a[l]c;s--);a=a.slice(l,s)}return a},a.tickFormat=function(n,t){if(!arguments.length)return Ac;arguments.length<2?t=Ac:"function"!=typeof t&&(t=ya.format(t));var r,o=Math.max(.1,n/a.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/u(c(i(n)+r))<=o?t(n):""}},a.copy=function(){return uu(n.copy(),t,e,r)},Qi(a,n)}function au(n,t,e){function r(t){return n(i(t))}var i=ou(t),u=ou(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return ru(e,n)},r.tickFormat=function(n,t){return iu(e,n,t)},r.nice=function(n){return r.domain(nu(e,n))},r.exponent=function(a){return arguments.length?(i=ou(t=a),u=ou(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return au(n.copy(),t,e)},Qi(r,n)}function ou(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function cu(n,t){function e(t){return a[((u.get(t)||u.set(t,n.push(t)))-1)%a.length]}function r(t,e){return ya.range(n.length).map(function(n){return t+e*n})}var u,a,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new i;for(var a,o=-1,c=r.length;++oe?[0/0,0/0]:[e>0?i[e-1]:n[0],et?0/0:t/u+n,[t,t+1/u]},r.copy=function(){return su(n,t,e)},i()}function fu(n,t){function e(e){return e>=e?t[ya.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return fu(n,t)},e}function hu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return ru(n,t)},t.tickFormat=function(t,e){return iu(n,t,e)},t.copy=function(){return hu(n)},t}function gu(n){return n.innerRadius}function pu(n){return n.outerRadius}function mu(n){return n.startAngle}function du(n){return n.endAngle}function vu(n){for(var t,e,r,i=-1,u=n.length;++ie?l():(u.active=e,a.event&&a.event.start.call(n,s,t),a.tween.forEach(function(e,r){(r=r.call(n,s,t))&&p.push(r)}),c(r)?1:(xt(c,0,o),void 0))}function c(r){if(u.active!==e)return l();for(var i=(r-h)/g,o=f(i),c=p.length;c>0;)p[--c].call(n,o);return i>=1?(l(),a.event&&a.event.end.call(n,s,t),1):void 0}function l(){return--u.count?delete u[e]:delete n.__transition__,1}var s=n.__data__,f=a.ease,h=a.delay,g=a.duration,p=[];return r>=h?i(r):(xt(i,h,o),void 0)},0,o)}}function qu(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Tu(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Cu(n,t,e){if(r=[],e&&t.length>1){for(var r,i,u,a=Zi(n.domain()),o=-1,c=t.length,l=(t[1]-t[0])/++e;++o0;)(u=+t[o]-i*l)>=a[0]&&r.push(u);for(--o,i=0;++i1?Date.UTC.apply(this,arguments):arguments[0])}function Du(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new Zc(e-1)),1),e}function u(n,e){return t(n=new Zc(+n),e),n}function a(n,r,u){var a=i(n),o=[];if(u>1)for(;r>a;)e(a)%u||o.push(new Date(+a)),t(a,1);else for(;r>a;)o.push(new Date(+a)),t(a,1);return o}function o(n,t,e){try{Zc=zu;var r=new zu;return r._=n,a(r,t,e)}finally{Zc=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=a;var c=n.utc=ju(n);return c.floor=c,c.round=ju(r),c.ceil=ju(i),c.offset=ju(u),c.range=o,n}function ju(n){return function(t,e){try{Zc=zu;var r=new zu;return r._=t,n(r,e)._}finally{Zc=Date}}}function Lu(n,t,e,r){for(var i,u,a=0,o=t.length,c=e.length;o>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(u=gl[t.charAt(a++)],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function Hu(n){return new RegExp("^(?:"+n.map(ya.requote).join("|")+")","i")}function Fu(n){for(var t=new i,e=-1,r=n.length;++en?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Ou(n,t,e){il.lastIndex=0;var r=il.exec(t.substring(e));return r?(n.w=ul.get(r[0].toLowerCase()),e+r[0].length):-1}function Yu(n,t,e){el.lastIndex=0;var r=el.exec(t.substring(e));return r?(n.w=rl.get(r[0].toLowerCase()),e+r[0].length):-1}function Ru(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Uu(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Iu(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Vu(n,t,e){cl.lastIndex=0;var r=cl.exec(t.substring(e));return r?(n.m=ll.get(r[0].toLowerCase()),e+r[0].length):-1}function Xu(n,t,e){al.lastIndex=0;var r=al.exec(t.substring(e));return r?(n.m=ol.get(r[0].toLowerCase()),e+r[0].length):-1}function Zu(n,t,e){return Lu(n,hl.c.toString(),t,e)}function Bu(n,t,e){return Lu(n,hl.x.toString(),t,e)}function $u(n,t,e){return Lu(n,hl.X.toString(),t,e)}function Wu(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Ju(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.y=Gu(+r[0]),e+r[0].length):-1}function Gu(n){return n+(n>68?1900:2e3)}function Ku(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qu(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function na(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function ta(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ea(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ra(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ia(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ua(n,t,e){var r=ml.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}function aa(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(Math.abs(t)/60),i=Math.abs(t)%60;return e+Pu(r,"0",2)+Pu(i,"0",2)}function oa(n,t,e){sl.lastIndex=0;var r=sl.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ca(n){return n.toISOString()}function la(n,t,e){function r(t){return n(t)}return r.invert=function(t){return sa(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(sa)},r.nice=function(n){return r.domain(Wi(r.domain(),n))},r.ticks=function(e,i){var u=Zi(r.domain());if("function"!=typeof e){var a=u[1]-u[0],o=a/e,c=ya.bisect(vl,o);if(c==vl.length)return t.year(u,e);if(!c)return n.ticks(e).map(sa);o/vl[c-1]n?-1:n>t?1:n>=t?0:0/0},ya.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ya.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=e);)e=void 0;for(;++ir&&(e=r)}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r)}return e},ya.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=e);)e=void 0;for(;++ie&&(e=r)}else{for(;++i=e);)e=void 0;for(;++ie&&(e=r)}return e},ya.extent=function(n,t){var e,r,i,u=-1,a=n.length;if(1===arguments.length){for(;++u=e);)e=i=void 0;for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ya.sum=function(n,t){var e,r=0,i=n.length,u=-1;if(1===arguments.length)for(;++u1&&(t=t.map(e)),t=t.filter(n),t.length?ya.quantile(t.sort(ya.ascending),.5):void 0},ya.bisector=function(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n.call(t,t[u],u)r;){var u=r+i>>>1;er)for(;(i=n+r*++o)>t;)u.push(i/a);else for(;(i=n+r*++o)=a.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,m=a[c++],d=new i;++g=a.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,u={},a=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ya.map,e,0),0)},u.key=function(n){return a.push(n),u},u.sortKeys=function(n){return o[a.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ya.set=function(n){var t=new u;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(u,{has:function(n){return qa+n in this},add:function(n){return this[qa+n]=!0,n},remove:function(n){return n=qa+n,n in this&&delete this[n]},values:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===Ta&&n.call(this,t.substring(1))}}),ya.behavior={},ya.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ya.event=null,ya.requote=function(n){return n.replace(ja,"\\$&")};var ja=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,La={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ha=function(n,t){return t.querySelector(n)},Fa=function(n,t){return t.querySelectorAll(n)},Pa=xa[o(xa,"matchesSelector")],Oa=function(n,t){return Pa.call(n,t)};"function"==typeof Sizzle&&(Ha=function(n,t){return Sizzle(n,t)[0]||null},Fa=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},Oa=Sizzle.matchesSelector),ya.selection=function(){return Ia};var Ya=ya.selection.prototype=[];Ya.select=function(n){var t,e,r,i,u=[];n=v(n);for(var a=-1,o=this.length;++a=0&&(e=n.substring(0,t),n=n.substring(t+1)),Ra.hasOwnProperty(e)?{space:Ra[e],local:n}:n}},Ya.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ya.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(M(t,n[t]));return this}return this.each(M(n,t))},Ya.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=n.trim().split(/^|\s+/g)).length,i=-1;if(t=e.classList){for(;++ir){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(S(e,n[e],t));return this}if(2>r)return ba.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(S(n,t,e))},Ya.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},Ya.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Ya.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Ya.append=function(n){return n=k(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Ya.insert=function(n,t){return n=k(n),t=v(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments))})},Ya.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},Ya.data=function(n,t){function e(n,e){var r,u,a,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),m=new Array(o);if(t){var d,v=new i,y=new i,M=[];for(r=-1;++rr;++r)p[r]=A(e[r]);for(;o>r;++r)m[r]=n[r]}p.update=g,p.parentNode=g.parentNode=m.parentNode=n.parentNode,c.push(p),l.push(g),s.push(m)}var r,u,a=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++au;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var o=0,c=e.length;c>o;o++)(r=e[o])&&n.call(r,r.__data__,o)&&t.push(r)}return d(i)},Ya.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Ya.sort=function(n){n=q.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Ya.size=function(){var n=0;return this.each(function(){++n}),n};var Ua=[];ya.selection.enter=C,ya.selection.enter.prototype=Ua,Ua.append=Ya.append,Ua.empty=Ya.empty,Ua.node=Ya.node,Ua.call=Ya.call,Ua.size=Ya.size,Ua.select=function(n){for(var t,e,r,i,u,a=[],o=-1,c=this.length;++or){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(D(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(D(n,t,e))};var Va=ya.map({mouseenter:"mouseover",mouseleave:"mouseout"});Va.forEach(function(n){"on"+n in Ma&&Va.remove(n)});var Xa=o(xa.style,"userSelect"),Za=0;ya.mouse=function(n){return F(n,p())};var Ba=/WebKit/.test(ba.navigator.userAgent)?-1:0;ya.touches=function(n,t){return arguments.length<2&&(t=p().touches),t?za(t).map(function(t){var e=F(n,t);return e.identifier=t.identifier,e}):[]},ya.behavior.drag=function(){function n(){this.on("mousedown.drag",a).on("touchstart.drag",o)}function t(){return ya.event.changedTouches[0].identifier}function e(n,t){return ya.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function a(){if(!s)return o();var n=t(s,g),e=n[0]-m[0],r=n[1]-m[1];d|=e|r,m=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function o(){v.on(e+"."+p,null).on(r+"."+p,null),y(d&&ya.event.target===h),f({type:"dragend"})}var c,l=this,s=l.parentNode,f=i.of(l,arguments),h=ya.event.target,g=n(),p=null==g?"drag":"drag-"+g,m=t(s,g),d=0,v=ya.select(ba).on(e+"."+p,a).on(r+"."+p,o),y=H();u?(c=u.apply(l,arguments),c=[c.x-m[0],c.y-m[1]]):c=[0,0],f({type:"dragstart"})}}var i=m(n,"drag","dragstart","dragend"),u=null,a=r(s,ya.mouse,"mousemove","mouseup"),o=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ya.rebind(n,i,"on")},ya.behavior.zoom=function(){function n(){this.on(w,o).on(Ja+".zoom",l).on(S,s).on("dblclick.zoom",f).on(k,c)}function t(n){return[(n[0]-x[0])/b,(n[1]-x[1])/b]}function e(n){return[n[0]*b+x[0],n[1]*b+x[1]]}function r(n){b=Math.max(_[0],Math.min(_[1],n))}function i(n,t){t=e(t),x[0]+=n[0]-t[0],x[1]+=n[1]-t[1]}function u(){v&&v.domain(d.range().map(function(n){return(n-x[0])/b}).map(d.invert)),M&&M.domain(y.range().map(function(n){return(n-x[1])/b}).map(y.invert))}function a(n){u(),n({type:"zoom",scale:b,translate:x})}function o(){function n(){c=1,i(ya.mouse(r),f),a(u)}function e(){l.on(S,ba===r?s:null).on(E,null),h(c&&ya.event.target===o)}var r=this,u=q.of(r,arguments),o=ya.event.target,c=0,l=ya.select(ba).on(S,n).on(E,e),f=t(ya.mouse(r)),h=H()}function c(){function n(){var n=ya.touches(h);return f=b,s={},n.forEach(function(n){s[n.identifier]=t(n)}),n}function e(){var t=Date.now(),e=n();if(1===e.length){if(500>t-p){var u=e[0],o=s[u.identifier];r(2*b),i(u,o),g(),a(m)}p=t}else if(e.length>1){var u=e[0],c=e[1],l=u[0]-c[0],f=u[1]-c[1];d=l*l+f*f}}function u(){var n=ya.touches(h),t=n[0],e=s[t.identifier];if(u=n[1]){var u,o=s[u.identifier],c=ya.event.scale;if(null==c){var l=(l=u[0]-t[0])*l+(l=u[1]-t[1])*l;c=d&&Math.sqrt(l/d)}t=[(t[0]+u[0])/2,(t[1]+u[1])/2],e=[(e[0]+o[0])/2,(e[1]+o[1])/2],r(c*f)}p=null,i(t,e),a(m)}function l(){ya.event.touches.length?n():(v.on(A,null).on(N,null),y.on(w,o).on(k,c),M())}var s,f,h=this,m=q.of(h,arguments),d=0,v=ya.select(ba).on(A,u).on(N,l),y=ya.select(h).on(w,null).on(k,e),M=H();e()}function l(){g(),h||(h=t(ya.mouse(this))),r(Math.pow(2,.002*$a())*b),i(ya.mouse(this),h),a(q.of(this,arguments))}function s(){h=null}function f(){var n=ya.mouse(this),e=t(n),u=Math.log(b)/Math.LN2;r(Math.pow(2,ya.event.shiftKey?Math.ceil(u)-1:Math.floor(u)+1)),i(n,e),a(q.of(this,arguments))}var h,p,d,v,y,M,x=[0,0],b=1,_=Wa,w="mousedown.zoom",S="mousemove.zoom",E="mouseup.zoom",k="touchstart.zoom",A="touchmove.zoom",N="touchend.zoom",q=m(n,"zoom");return n.translate=function(t){return arguments.length?(x=t.map(Number),u(),n):x},n.scale=function(t){return arguments.length?(b=+t,u(),n):b},n.scaleExtent=function(t){return arguments.length?(_=null==t?Wa:t.map(Number),n):_},n.x=function(t){return arguments.length?(v=t,d=t.copy(),x=[0,0],b=1,n):v},n.y=function(t){return arguments.length?(M=t,y=t.copy(),x=[0,0],b=1,n):M},ya.rebind(n,q,"on")};var $a,Wa=[0,1/0],Ja="onwheel"in Ma?($a=function(){return-ya.event.deltaY*(ya.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Ma?($a=function(){return ya.event.wheelDelta},"mousewheel"):($a=function(){return-ya.event.detail},"MozMousePixelScroll");P.prototype.toString=function(){return this.rgb()+""},ya.hsl=function(n,t,e){return 1===arguments.length?n instanceof Y?O(n.h,n.s,n.l):lt(""+n,st,O):O(+n,+t,+e)};var Ga=Y.prototype=new P;Ga.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),O(this.h,this.s,this.l/n)},Ga.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),O(this.h,this.s,n*this.l)},Ga.rgb=function(){return R(this.h,this.s,this.l)};var Ka=Math.PI,Qa=1e-6,no=Qa*Qa,to=Ka/180,eo=180/Ka;ya.hcl=function(n,t,e){return 1===arguments.length?n instanceof W?$(n.h,n.c,n.l):n instanceof K?nt(n.l,n.a,n.b):nt((n=ft((n=ya.rgb(n)).r,n.g,n.b)).l,n.a,n.b):$(+n,+t,+e)};var ro=W.prototype=new P;ro.brighter=function(n){return $(this.h,this.c,Math.min(100,this.l+io*(arguments.length?n:1)))},ro.darker=function(n){return $(this.h,this.c,Math.max(0,this.l-io*(arguments.length?n:1)))},ro.rgb=function(){return J(this.h,this.c,this.l).rgb()},ya.lab=function(n,t,e){return 1===arguments.length?n instanceof K?G(n.l,n.a,n.b):n instanceof W?J(n.l,n.c,n.h):ft((n=ya.rgb(n)).r,n.g,n.b):G(+n,+t,+e)};var io=18,uo=.95047,ao=1,oo=1.08883,co=K.prototype=new P;co.brighter=function(n){return G(Math.min(100,this.l+io*(arguments.length?n:1)),this.a,this.b)},co.darker=function(n){return G(Math.max(0,this.l-io*(arguments.length?n:1)),this.a,this.b)},co.rgb=function(){return Q(this.l,this.a,this.b)},ya.rgb=function(n,t,e){return 1===arguments.length?n instanceof ot?at(n.r,n.g,n.b):lt(""+n,at,R):at(~~n,~~t,~~e)};var lo=ot.prototype=new P;lo.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),at(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):at(i,i,i)},lo.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),at(~~(n*this.r),~~(n*this.g),~~(n*this.b))},lo.hsl=function(){return st(this.r,this.g,this.b)},lo.toString=function(){return"#"+ct(this.r)+ct(this.g)+ct(this.b)};var so=ya.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});so.forEach(function(n,t){so.set(n,it(t))}),ya.functor=pt,ya.xhr=dt(mt),ya.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var a=ya.xhr(n,t,u);return a.row=function(n){return arguments.length?a.response(null==(e=n)?r:i(n)):e},a.row(e)}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function a(t){return t.map(o).join(n)}function o(n){return c.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var c=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(s>=c)return a;if(i)return i=!1,u;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),o=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(s)&&(++s,++o);else if(r!==l)continue;return n.substring(t,s-o)}return n.substring(t)}for(var r,i,u={},a={},o=[],c=n.length,s=0,f=0;(r=e())!==a;){for(var h=[];r!==u&&r!==a;)h.push(r),r=e();(!t||(h=t(h,f++)))&&o.push(h)}return o},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new u,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(a).join("\n")},e},ya.csv=ya.dsv(",","text/csv"),ya.tsv=ya.dsv(" ","text/tab-separated-values");var fo,ho,go,po,mo,vo=ba[o(ba,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ya.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={callback:n,time:i,next:null};ho?ho.next=u:fo=u,ho=u,go||(po=clearTimeout(po),go=1,vo(Mt))},ya.timer.flush=function(){bt(),_t()};var yo=".",Mo=",",xo=[3,3],bo="$",_o=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"].map(wt);ya.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ya.round(n,St(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),_o[8+e/3]},ya.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)},ya.format=function(n){var t=wo.exec(n),e=t[1]||" ",r=t[2]||">",i=t[3]||"",u=t[4]||"",a=t[5],o=+t[6],c=t[7],l=t[8],s=t[9],f=1,h="",g=!1;switch(l&&(l=+l.substring(1)),(a||"0"===e&&"="===r)&&(a=e="0",r="=",c&&(o-=Math.floor((o-1)/4))),s){case"n":c=!0,s="g";break;case"%":f=100,h="%",s="f";break;case"p":f=100,h="%",s="r";break;case"b":case"o":case"x":case"X":"#"===u&&(u="0"+s.toLowerCase());case"c":case"d":g=!0,l=0;break;case"s":f=-1,s="r"}"#"===u?u="":"$"===u&&(u=bo),"r"!=s||l||(s="g"),null!=l&&("g"==s?l=Math.max(1,Math.min(21,l)):("e"==s||"f"==s)&&(l=Math.max(0,Math.min(20,l)))),s=So.get(s)||Et;var p=a&&c;return function(n){if(g&&n%1)return"";var t=0>n||0===n&&0>1/n?(n=-n,"-"):i;if(0>f){var m=ya.formatPrefix(n,l);n=m.scale(n),h=m.symbol}else n*=f;n=s(n,l);var d=n.lastIndexOf("."),v=0>d?n:n.substring(0,d),y=0>d?"":yo+n.substring(d+1);!a&&c&&(v=Eo(v));var M=u.length+v.length+y.length+(p?0:t.length),x=o>M?new Array(M=o-M+1).join(e):"";return p&&(v=Eo(x+v)),t+=u,n=v+y,("<"===r?t+n+x:">"===r?x+t+n:"^"===r?x.substring(0,M>>=1)+t+n+x.substring(M):t+(p?n:x+n))+h}};var wo=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,So=ya.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ya.round(n,St(n,t))).toFixed(Math.max(0,Math.min(20,St(n*(1+1e-15),t))))}}),Eo=mt;if(xo){var ko=xo.length;Eo=function(n){for(var t=n.length,e=[],r=0,i=xo[0];t>0&&i>0;)e.push(n.substring(t-=i,t+i)),i=xo[r=(r+1)%ko];return e.reverse().join(Mo)}}ya.geo={},kt.prototype={s:0,t:0,add:function(n){At(n,this.t,Ao),At(Ao.s,this.s,this),this.s?this.t+=Ao.t:this.s=Ao.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var Ao=new kt;ya.geo.stream=function(n,t){n&&No.hasOwnProperty(n.type)?No[n.type](n,t):Nt(n,t)};var No={Feature:function(n,t){Nt(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Ka+n:n,zo.lineStart=zo.lineEnd=zo.point=s}};ya.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=zt([t*to,e*to]);if(v){var i=jt(v,r),u=[i[1],-i[0],0],a=jt(u,i);Ft(a),a=Pt(a);var c=t-p,l=c>0?1:-1,m=a[0]*eo*l,d=Math.abs(c)>180;if(d^(m>l*p&&l*t>m)){var y=a[1]*eo;y>g&&(g=y)}else if(m=(m+360)%360-180,d^(m>l*p&&l*t>m)){var y=-a[1]*eo;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t)}else n(t,e);v=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,v=null}function i(n,e){if(v){var r=n-p;y+=Math.abs(r)>180?r+(r>0?360:-360):r}else m=n,d=e;zo.point(n,e),t(n,e)}function u(){zo.lineStart()}function a(){i(m,d),zo.lineEnd(),Math.abs(y)>Qa&&(s=-(h=180)),x[0]=s,x[1]=h,v=null}function o(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nCo?(s=-(h=180),f=-(g=90)):y>Qa?g=90:-Qa>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ya.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],l(e[0],i)||l(e[1],i)?(o(i[0],e[1])>o(i[0],i[1])&&(i[1]=e[1]),o(e[0],i[1])>o(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var a,e,p=-1/0,t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(a=o(i[1],e[0]))>p&&(p=a,s=e[0],h=i[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ya.geo.centroid=function(n){Do=jo=Lo=Ho=Fo=Po=Oo=Yo=Ro=Uo=Io=0,ya.geo.stream(n,Vo);var t=Ro,e=Uo,r=Io,i=t*t+e*e+r*r;return no>i&&(t=Po,e=Oo,r=Yo,Qa>jo&&(t=Lo,e=Ho,r=Fo),i=t*t+e*e+r*r,no>i)?[0/0,0/0]:[Math.atan2(e,t)*eo,V(r/Math.sqrt(i))*eo]};var Do,jo,Lo,Ho,Fo,Po,Oo,Yo,Ro,Uo,Io,Vo={sphere:s,point:Yt,lineStart:Ut,lineEnd:It,polygonStart:function(){Vo.lineStart=Vt},polygonEnd:function(){Vo.lineStart=Ut}},Xo=$t(Xt,Qt,te,ee),Zo=[-Ka,0],Bo=1e9;(ya.geo.conicEqualArea=function(){return oe(ce)}).raw=ce,ya.geo.albers=function(){return ya.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ya.geo.albersUsa=function(){function n(n){var u=n[0],a=n[1];return t=null,e(u,a),t||(r(u,a),t)||i(u,a),t}var t,e,r,i,u=ya.geo.albers(),a=ya.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),o=ya.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?a:i>=.166&&.234>i&&r>=-.214&&-.115>r?o:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=a.stream(n),r=o.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),a.precision(t),o.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),a.scale(.35*t),o.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var l=u.scale(),s=+t[0],f=+t[1];return e=u.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=a.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Qa,f+.12*l+Qa],[s-.214*l-Qa,f+.234*l-Qa]]).stream(c).point,i=o.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Qa,f+.166*l+Qa],[s-.115*l-Qa,f+.234*l-Qa]]).stream(c).point,n},n.scale(1070)};var $o,Wo,Jo,Go,Ko,Qo,nc={point:s,lineStart:s,lineEnd:s,polygonStart:function(){Wo=0,nc.lineStart=le},polygonEnd:function(){nc.lineStart=nc.lineEnd=nc.point=s,$o+=Math.abs(Wo/2)}},tc={point:se,lineStart:s,lineEnd:s,polygonStart:s,polygonEnd:s},ec={point:ge,lineStart:pe,lineEnd:me,polygonStart:function(){ec.lineStart=de},polygonEnd:function(){ec.point=ge,ec.lineStart=pe,ec.lineEnd=me}};ya.geo.path=function(){function n(n){return n&&("function"==typeof o&&u.pointRadius(+o.apply(this,arguments)),a&&a.valid||(a=i(u)),ya.geo.stream(n,a)),u.result()}function t(){return a=null,n}var e,r,i,u,a,o=4.5;return n.area=function(n){return $o=0,ya.geo.stream(n,i(nc)),$o},n.centroid=function(n){return Lo=Ho=Fo=Po=Oo=Yo=Ro=Uo=Io=0,ya.geo.stream(n,i(ec)),Io?[Ro/Io,Uo/Io]:Yo?[Po/Yo,Oo/Yo]:Fo?[Lo/Fo,Ho/Fo]:[0/0,0/0]},n.bounds=function(n){return Ko=Qo=-(Jo=Go=1/0),ya.geo.stream(n,i(tc)),[[Jo,Go],[Ko,Qo]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||Me(n):mt,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new fe:new ve(n),"function"!=typeof o&&u.pointRadius(o),t()):r},n.pointRadius=function(t){return arguments.length?(o="function"==typeof t?t:(u.pointRadius(+t),+t),n):o},n.projection(ya.geo.albersUsa()).context(null)},ya.geo.projection=xe,ya.geo.projectionMutator=be,(ya.geo.equirectangular=function(){return xe(we)}).raw=we.invert=we,ya.geo.rotation=function(n){function t(t){return t=n(t[0]*to,t[1]*to),t[0]*=eo,t[1]*=eo,t}return n=Se(n[0]%360*to,n[1]*to,n.length>2?n[2]*to:0),t.invert=function(t){return t=n.invert(t[0]*to,t[1]*to),t[0]*=eo,t[1]*=eo,t},t},ya.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=Se(-n[0]*to,-n[1]*to,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=eo,n[1]*=eo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=Ne((t=+r)*to,i*to),n):t},n.precision=function(r){return arguments.length?(e=Ne(t*to,(i=+r)*to),n):i},n.angle(90)},ya.geo.distance=function(n,t){var e,r=(t[0]-n[0])*to,i=n[1]*to,u=t[1]*to,a=Math.sin(r),o=Math.cos(r),c=Math.sin(i),l=Math.cos(i),s=Math.sin(u),f=Math.cos(u);return Math.atan2(Math.sqrt((e=f*a)*e+(e=l*s-c*f*o)*e),c*s+l*f*o)},ya.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ya.range(Math.ceil(u/d)*d,i,d).map(h).concat(ya.range(Math.ceil(l/v)*v,c,v).map(g)).concat(ya.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Math.abs(n%d)>Qa}).map(s)).concat(ya.range(Math.ceil(o/m)*m,a,m).filter(function(n){return Math.abs(n%v)>Qa}).map(f))}var e,r,i,u,a,o,c,l,s,f,h,g,p=10,m=p,d=90,v=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(g(c).slice(1),h(i).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],l=+t[0][1],c=+t[1][1],u>i&&(t=u,u=i,i=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[u,l],[i,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],o=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),o>a&&(t=o,o=a,a=t),n.precision(y)):[[r,o],[e,a]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],v=+t[1],n):[d,v]},n.minorStep=function(t){return arguments.length?(p=+t[0],m=+t[1],n):[p,m]},n.precision=function(t){return arguments.length?(y=+t,s=Te(o,a,90),f=Ce(r,e,y),h=Te(l,c,90),g=Ce(u,i,y),n):y},n.majorExtent([[-180,-90+Qa],[180,90-Qa]]).minorExtent([[-180,-80-Qa],[180,80+Qa]])},ya.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=ze,i=De;return n.distance=function(){return ya.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ya.geo.interpolate=function(n,t){return je(n[0]*to,n[1]*to,t[0]*to,t[1]*to)},ya.geo.length=function(n){return rc=0,ya.geo.stream(n,ic),rc};var rc,ic={sphere:s,point:s,lineStart:Le,lineEnd:s,polygonStart:s,polygonEnd:s},uc=He(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ya.geo.azimuthalEqualArea=function(){return xe(uc)}).raw=uc;var ac=He(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},mt);(ya.geo.azimuthalEquidistant=function(){return xe(ac)}).raw=ac,(ya.geo.conicConformal=function(){return oe(Fe)}).raw=Fe,(ya.geo.conicEquidistant=function(){return oe(Pe)}).raw=Pe;var oc=He(function(n){return 1/n},Math.atan);(ya.geo.gnomonic=function(){return xe(oc)}).raw=oc,Oe.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ka/2]},(ya.geo.mercator=function(){return Ye(Oe)}).raw=Oe;var cc=He(function(){return 1},Math.asin);(ya.geo.orthographic=function(){return xe(cc)}).raw=cc;var lc=He(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ya.geo.stereographic=function(){return xe(lc)}).raw=lc,Re.invert=function(n,t){return[Math.atan2(X(n),Math.cos(t)),V(Math.sin(t)/Z(n))]},(ya.geo.transverseMercator=function(){return Ye(Re)}).raw=Re,ya.geom={},ya.svg={},ya.svg.line=function(){return Ue(mt)};var sc=ya.map({linear:Xe,"linear-closed":Ze,step:Be,"step-before":$e,"step-after":We,basis:tr,"basis-open":er,"basis-closed":rr,bundle:ir,cardinal:Ke,"cardinal-open":Je,"cardinal-closed":Ge,monotone:sr}); +sc.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var fc=[0,2/3,1/3,0],hc=[0,1/3,2/3,0],gc=[0,1/6,2/3,1/6];ya.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i,u,a,o,c,l,s,f,h,g,p,m=pt(e),d=pt(r),v=n.length,y=v-1,M=[],x=[],b=0;if(m===Ie&&r===Ve)t=n;else for(u=0,t=[];v>u;++u)t.push([+m.call(this,i=n[u],u),+d.call(this,i,u)]);for(u=1;v>u;++u)(t[u][1]u;++u)u!==b&&(c=t[u][1]-t[b][1],o=t[u][0]-t[b][0],M.push({angle:Math.atan2(c,o),index:u}));for(M.sort(function(n,t){return n.angle-t.angle}),g=M[0].angle,h=M[0].index,f=0,u=1;y>u;++u){if(a=M[u].index,g==M[u].angle){if(o=t[h][0]-t[b][0],c=t[h][1]-t[b][1],l=t[a][0]-t[b][0],s=t[a][1]-t[b][1],o*o+c*c>=l*l+s*s){M[u].index=-1;continue}M[f].index=-1}g=M[u].angle,f=u,h=a}for(x.push(b),u=0,a=0;2>u;++a)M[a].index>-1&&(x.push(M[a].index),u++);for(p=x.length;y>a;++a)if(!(M[a].index<0)){for(;!fr(x[p-2],x[p-1],M[a].index,t);)--p;x[p++]=M[a].index}var _=[];for(u=p-1;u>=0;--u)_.push(n[x[u]]);return _}var e=Ie,r=Ve;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ya.geom.polygon=function(n){return La(n,pc),n};var pc=ya.geom.polygon.prototype=[];pc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++to;o++)e.push([i,t[o],t[o+1]])}),e},ya.geom.voronoi=function(n){function t(n){var t,u,a,o=n.map(function(){return[]}),c=pt(e),l=pt(r),s=n.length,f=1e6;if(c===Ie&&l===Ve)t=n;else for(t=new Array(s),a=0;s>a;++a)t[a]=[+c.call(this,u=n[a],a),+l.call(this,u,a)];if(mr(t,function(n){var t,e,r,i,u,a;1===n.a&&n.b>=0?(t=n.ep.r,e=n.ep.l):(t=n.ep.l,e=n.ep.r),1===n.a?(u=t?t.y:-f,r=n.c-n.b*u,a=e?e.y:f,i=n.c-n.b*a):(r=t?t.x:-f,u=n.c-n.a*r,i=e?e.x:f,a=n.c-n.a*i);var c=[r,u],l=[i,a];o[n.region.l.index].push(c,l),o[n.region.r.index].push(c,l)}),o=o.map(function(n,e){var r=t[e][0],i=t[e][1],u=n.map(function(n){return Math.atan2(n[0]-r,n[1]-i)}),a=ya.range(n.length).sort(function(n,t){return u[n]-u[t]});return a.filter(function(n,t){return!t||u[n]-u[a[t-1]]>Qa}).map(function(t){return n[t]})}),o.forEach(function(n,e){var r=n.length;if(!r)return n.push([-f,-f],[-f,f],[f,f],[f,-f]);if(!(r>2)){var i=t[e],u=n[0],a=n[1],o=i[0],c=i[1],l=u[0],s=u[1],h=a[0],g=a[1],p=Math.abs(h-l),m=g-s;if(Math.abs(m)c?-f:f;n.push([-f,d],[f,d])}else if(Qa>p){var v=l>o?-f:f;n.push([v,-f],[v,f])}else{var d=(l-o)*(g-s)>(h-l)*(s-c)?f:-f,y=Math.abs(m)-p;Math.abs(y)m?d:-d,d]):(y>0&&(d*=-1),n.push([-f,d],[f,d]))}}}),i)for(a=0;s>a;++a)i.clip(o[a]);for(a=0;s>a;++a)o[a].point=n[a];return o}var e=Ie,r=Ve,i=null;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.clipExtent=function(n){if(!arguments.length)return i&&[i[0],i[2]];if(null==n)i=null;else{var e=+n[0][0],r=+n[0][1],u=+n[1][0],a=+n[1][1];i=ya.geom.polygon([[e,r],[e,a],[u,a],[u,r]])}return t},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):i&&i[2]},t.links=function(n){var t,i,u,a=n.map(function(){return[]}),o=[],c=pt(e),l=pt(r),s=n.length;if(c===Ie&&l===Ve)t=n;else for(t=new Array(s),u=0;s>u;++u)t[u]=[+c.call(this,i=n[u],u),+l.call(this,i,u)];return mr(t,function(t){var e=t.region.l.index,r=t.region.r.index;a[e][r]||(a[e][r]=a[r][e]=!0,o.push({source:n[e],target:n[r]}))}),o},t.triangles=function(n){if(e===Ie&&r===Ve)return ya.geom.delaunay(n);for(var t,i=new Array(c),u=pt(e),a=pt(r),o=-1,c=n.length;++o=l,h=r>=s,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=yr()),f?i=l:o=l,h?a=s:c=s,u(n,t,e,r,i,a,o,c)}var s,f,h,g,p,m,d,v,y,M=pt(o),x=pt(c);if(null!=t)m=t,d=e,v=r,y=i;else if(v=y=-(m=d=1/0),f=[],h=[],p=n.length,a)for(g=0;p>g;++g)s=n[g],s.xv&&(v=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);m>b&&(m=b),d>_&&(d=_),b>v&&(v=b),_>y&&(y=_),f.push(b),h.push(_)}var w=v-m,S=y-d;w>S?y=d+w:v=m+S;var E=yr();if(E.add=function(n){u(E,n,+M(n,++g),+x(n,g),m,d,v,y)},E.visit=function(n){Mr(n,E,m,d,v,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=yc.get(e)||vc,r=Mc.get(r)||mt,kr(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},ya.interpolateHcl=Or,ya.interpolateHsl=Yr,ya.interpolateLab=Rr,ya.interpolateRound=Ur,ya.transform=function(n){var t=Ma.createElementNS(ya.ns.prefix.svg,"g");return(ya.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Ir(e?e.matrix:xc)})(n)},Ir.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var xc={a:1,b:0,c:0,d:1,e:0,f:0};ya.interpolateTransform=Br,ya.layout={},ya.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e(i-e)*o){var c=t.charge*o*o;return n.px-=u*c,n.py-=a*c,!0}if(t.point&&isFinite(o)){var c=t.pointCharge*o*o;n.px-=u*c,n.py-=a*c}}return!t.charge}}function t(n){n.px=ya.event.x,n.py=ya.event.y,o.resume()}var e,r,i,u,a,o={},c=ya.dispatch("start","tick","end"),l=[1,1],s=.9,f=bc,h=_c,g=-30,p=.1,m=.8,d=[],v=[];return o.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,o,f,h,m,y,M,x,b=d.length,_=v.length;for(e=0;_>e;++e)o=v[e],f=o.source,h=o.target,M=h.x-f.x,x=h.y-f.y,(m=M*M+x*x)&&(m=r*u[e]*((m=Math.sqrt(m))-i[e])/m,M*=m,x*=m,h.x-=M*(y=f.weight/(h.weight+f.weight)),h.y-=x*y,f.x+=M*(y=1-y),f.y+=x*y);if((y=r*p)&&(M=l[0]/2,x=l[1]/2,e=-1,y))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ya.timer(o.tick)),o):r},o.start=function(){function n(n,r){for(var i,u=t(e),a=-1,o=u.length;++ar;++r)c[r]=[];for(r=0;m>r;++r){var n=v[r];c[n.source.index].push(n.target),c[n.target.index].push(n.source)}}return c[e]}var e,r,c,s,p=d.length,m=v.length,y=l[0],M=l[1];for(e=0;p>e;++e)(s=d[e]).index=e,s.weight=0;for(e=0;m>e;++e)s=v[e],"number"==typeof s.source&&(s.source=d[s.source]),"number"==typeof s.target&&(s.target=d[s.target]),++s.source.weight,++s.target.weight;for(e=0;p>e;++e)s=d[e],isNaN(s.x)&&(s.x=n("x",y)),isNaN(s.y)&&(s.y=n("y",M)),isNaN(s.px)&&(s.px=s.x),isNaN(s.py)&&(s.py=s.y);if(i=[],"function"==typeof f)for(e=0;m>e;++e)i[e]=+f.call(this,v[e],e);else for(e=0;m>e;++e)i[e]=f;if(u=[],"function"==typeof h)for(e=0;m>e;++e)u[e]=+h.call(this,v[e],e);else for(e=0;m>e;++e)u[e]=h;if(a=[],"function"==typeof g)for(e=0;p>e;++e)a[e]=+g.call(this,d[e],e);else for(e=0;p>e;++e)a[e]=g;return o.resume()},o.resume=function(){return o.alpha(.1)},o.stop=function(){return o.alpha(0)},o.drag=function(){return e||(e=ya.behavior.drag().origin(mt).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?(this.on("mouseover.force",ti).on("mouseout.force",ei).call(e),void 0):e},ya.rebind(o,c,"on")};var bc=20,_c=1;ya.layout.hierarchy=function(){function n(t,a,o){var c=i.call(e,t,a);if(t.depth=a,o.push(t),c&&(l=c.length)){for(var l,s,f=-1,h=t.children=[],g=0,p=a+1;++fg;++g)for(i.call(n,l[0][g],p=m[g],s[0][g][1]),h=1;d>h;++h)i.call(n,l[h][g],p+=s[h-1][g][1],s[h][g][1]);return o}var t=mt,e=hi,r=gi,i=fi,u=li,a=si;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Sc.get(t)||hi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:Ec.get(t)||gi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(a=t,n):a},n.out=function(t){return arguments.length?(i=t,n):i},n};var Sc=ya.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(pi),u=n.map(mi),a=ya.range(r).sort(function(n,t){return i[n]-i[t]}),o=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=a[t],c>o?(o+=u[e],l.push(e)):(c+=u[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ya.range(n.length).reverse()},"default":hi}),Ec=ya.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,a=[],o=0,c=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>o&&(o=r),a.push(r)}for(e=0;u>e;++e)c[e]=(o-a[e])/2;return c},wiggle:function(n){var t,e,r,i,u,a,o,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,i=0;s>t;++t)i+=n[t][e][1];for(t=0,u=0,o=f[e][0]-f[e-1][0];s>t;++t){for(r=0,a=(n[t][e][1]-n[t][e-1][1])/(2*o);t>r;++r)a+=(n[r][e][1]-n[r][e-1][1])/o;u+=a*n[t][e][1]}g[e]=c-=i?u/i*o:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,i=n.length,u=n[0].length,a=1/i,o=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=a}for(e=0;u>e;++e)o[e]=0;return o},zero:gi});ya.layout.histogram=function(){function n(n,u){for(var a,o,c=[],l=n.map(e,this),s=r.call(this,l,u),f=i.call(this,s,l,u),u=-1,h=l.length,g=f.length-1,p=t?1:1/h;++u0)for(u=-1;++u=s[0]&&o<=s[1]&&(a=c[ya.bisect(f,o,1,g)-1],a.y+=p,a.push(n[u]));return c}var t=!0,e=Number,r=Mi,i=vi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=pt(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return yi(n,t)}:pt(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ya.layout.tree=function(){function n(n,u){function a(n,t){var r=n.children,i=n._tree;if(r&&(u=r.length)){for(var u,o,l,s=r[0],f=s,h=-1;++h0&&(qi(Ti(o,n,r),n,i),l+=i,s+=i),f+=o._tree.mod,l+=u._tree.mod,h+=c._tree.mod,s+=a._tree.mod;o&&!_i(a)&&(a._tree.thread=o,a._tree.mod+=f-s),u&&!bi(c)&&(c._tree.thread=u,c._tree.mod+=l-h,r=n)}return r}var l=t.call(this,n,u),s=l[0];Ai(s,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),a(s),o(s,-s._tree.prelim);var f=wi(s,Ei),h=wi(s,Si),g=wi(s,ki),p=f.x-e(f,h)/2,m=h.x+e(h,f)/2,d=g.depth||1;return Ai(s,i?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(m-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),l}var t=ya.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ya.layout.pack=function(){function n(n,u){var a=e.call(this,n,u),o=a[0],c=i[0],l=i[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(o.x=o.y=0,Ai(o,function(n){n.r=+s(n.value)}),Ai(o,Li),r){var f=r*(t?1:Math.max(2*o.r/c,2*o.r/l))/2;Ai(o,function(n){n.r+=f}),Ai(o,Li),Ai(o,function(n){n.r-=f})}return Pi(o,c/2,l/2,t?1:1/Math.max(2*o.r/c,2*o.r/l)),a}var t,e=ya.layout.hierarchy().sort(Ci),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ya.layout.cluster=function(){function n(n,u){var a,o=t.call(this,n,u),c=o[0],l=0;Ai(c,function(n){var t=n.children;t&&t.length?(n.x=Ri(t),n.y=Yi(t)):(n.x=a?l+=e(n,a):0,n.y=0,a=n)});var s=Ui(c),f=Ii(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Ai(c,i?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),o}var t=ya.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ya.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var a,o,c,l=f(e),s=[],h=u.slice(),p=1/0,m="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(a=h[c-1]),s.area+=a.area,"squarify"!==g||(o=r(s,m))<=p?(h.pop(),p=o):(s.area-=s.pop().area,i(s,m,l,!1),m=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(i(s,m,l,!0),s.length=s.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,a=f(t),o=r.slice(),c=[];for(n(o,a.dx*a.dy/t.value),c.area=0;u=o.pop();)c.push(u),c.area+=u.area,null!=u.z&&(i(c,u.z?a.dx:a.dy,a,!o.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,a=-1,o=n.length;++ae&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*p/r,r/(t*u*p)):1/0}function i(n,t,e,r){var i,u=-1,a=n.length,o=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ue.dx)&&(s=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ya.random.normal.apply(ya,arguments);return function(){return Math.exp(n())}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t/n}}},ya.scale={};var kc={floor:mt,ceil:mt};ya.scale.linear=function(){return Ki([0,1],[0,1],Sr,!1)},ya.scale.log=function(){return uu(ya.scale.linear().domain([0,1]),10,!0,[1,10])};var Ac=ya.format(".0e"),Nc={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ya.scale.pow=function(){return au(ya.scale.linear(),1,[0,1])},ya.scale.sqrt=function(){return ya.scale.pow().exponent(.5)},ya.scale.ordinal=function(){return cu([],{t:"range",a:[[]]})},ya.scale.category10=function(){return ya.scale.ordinal().range(qc)},ya.scale.category20=function(){return ya.scale.ordinal().range(Tc)},ya.scale.category20b=function(){return ya.scale.ordinal().range(Cc)},ya.scale.category20c=function(){return ya.scale.ordinal().range(zc)};var qc=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ut),Tc=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ut),Cc=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ut),zc=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ut);ya.scale.quantile=function(){return lu([],[])},ya.scale.quantize=function(){return su(0,1,[0,1])},ya.scale.threshold=function(){return fu([.5],[0,1])},ya.scale.identity=function(){return hu([0,1])},ya.svg.arc=function(){function n(){var n=t.apply(this,arguments),u=e.apply(this,arguments),a=r.apply(this,arguments)+Dc,o=i.apply(this,arguments)+Dc,c=(a>o&&(c=a,a=o,o=c),o-a),l=Ka>c?"0":"1",s=Math.cos(a),f=Math.sin(a),h=Math.cos(o),g=Math.sin(o);return c>=jc?n?"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"Z":n?"M"+u*s+","+u*f+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*s+","+n*f+"Z":"M"+u*s+","+u*f+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*g+"L0,0"+"Z"}var t=gu,e=pu,r=mu,i=du;return n.innerRadius=function(e){return arguments.length?(t=pt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=pt(t),n):e},n.startAngle=function(t){return arguments.length?(r=pt(t),n):r},n.endAngle=function(t){return arguments.length?(i=pt(t),n):i},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,u=(r.apply(this,arguments)+i.apply(this,arguments))/2+Dc;return[Math.cos(u)*n,Math.sin(u)*n]},n};var Dc=-Ka/2,jc=2*Ka-1e-6;ya.svg.line.radial=function(){var n=Ue(vu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},$e.reverse=We,We.reverse=$e,ya.svg.area=function(){return yu(mt)},ya.svg.area.radial=function(){var n=yu(vu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ya.svg.chord=function(){function n(n,o){var c=t(this,u,n,o),l=t(this,a,n,o);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?i(c.r,c.p1,c.r,c.p0):i(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+i(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=o.call(n,i,r),a=c.call(n,i,r)+Dc,s=l.call(n,i,r)+Dc;return{r:u,a0:a,a1:s,p0:[u*Math.cos(a),u*Math.sin(a)],p1:[u*Math.cos(s),u*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Ka)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=ze,a=De,o=Mu,c=mu,l=du;return n.radius=function(t){return arguments.length?(o=pt(t),n):o},n.source=function(t){return arguments.length?(u=pt(t),n):u},n.target=function(t){return arguments.length?(a=pt(t),n):a},n.startAngle=function(t){return arguments.length?(c=pt(t),n):c},n.endAngle=function(t){return arguments.length?(l=pt(t),n):l},n},ya.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),a=e.call(this,n,i),o=(u.y+a.y)/2,c=[u,{x:u.x,y:o},{x:a.x,y:o},a];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=ze,e=De,r=xu;return n.source=function(e){return arguments.length?(t=pt(e),n):t},n.target=function(t){return arguments.length?(e=pt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ya.svg.diagonal.radial=function(){var n=ya.svg.diagonal(),t=xu,e=n.projection;return n.projection=function(n){return arguments.length?e(bu(t=n)):t},n},ya.svg.symbol=function(){function n(n,r){return(Lc.get(t.call(this,n,r))||Su)(e.call(this,n,r))}var t=wu,e=_u;return n.type=function(e){return arguments.length?(t=pt(e),n):t},n.size=function(t){return arguments.length?(e=pt(t),n):e},n};var Lc=ya.map({circle:Su,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Oc)),e=t*Oc;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Pc),e=t*Pc/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Pc),e=t*Pc/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ya.svg.symbolTypes=Lc.keys();var Hc,Fc,Pc=Math.sqrt(3),Oc=Math.tan(30*to),Yc=[],Rc=0;Yc.call=Ya.call,Yc.empty=Ya.empty,Yc.node=Ya.node,Yc.size=Ya.size,ya.transition=function(n){return arguments.length?Hc?n.transition():n:Ia.transition()},ya.transition.prototype=Yc,Yc.select=function(n){var t,e,r,i=this.id,u=[];n=v(n);for(var a=-1,o=this.length;++au;u++){i.push(t=[]);for(var e=this[u],o=0,c=e.length;c>o;o++)(r=e[o])&&n.call(r,r.__data__,o)&&t.push(r)}return Eu(i,this.id)},Yc.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):T(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Yc.attr=function(n,t){function e(){this.removeAttribute(o)}function r(){this.removeAttributeNS(o.space,o.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(o);return e!==n&&(t=a(e,n),function(n){this.setAttribute(o,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(o.space,o.local);return e!==n&&(t=a(e,n),function(n){this.setAttributeNS(o.space,o.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var a="transform"==n?Br:Sr,o=ya.ns.qualify(n);return ku(this,"attr."+n,t,o.local?u:i)},Yc.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ya.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yc.style=function(n,t,e){function r(){this.style.removeProperty(n)}function i(t){return null==t?r:(t+="",function(){var r,i=ba.getComputedStyle(this,null).getPropertyValue(n);return i!==t&&(r=Sr(i,t),function(t){this.style.setProperty(n,r(t),e)})})}var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return ku(this,"style."+n,t,i)},Yc.styleTween=function(n,t,e){function r(r,i){var u=t.call(this,r,i,ba.getComputedStyle(this,null).getPropertyValue(n));return u&&function(t){this.style.setProperty(n,u(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Yc.text=function(n){return ku(this,"text",n,Au)},Yc.remove=function(){return this.each("end.transition",function(){var n;!this.__transition__&&(n=this.parentNode)&&n.removeChild(this)})},Yc.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=ya.ease.apply(ya,arguments)),T(this,function(e){e.__transition__[t].ease=n}))},Yc.delay=function(n){var t=this.id;return T(this,"function"==typeof n?function(e,r,i){e.__transition__[t].delay=0|n.call(e,e.__data__,r,i)}:(n|=0,function(e){e.__transition__[t].delay=n}))},Yc.duration=function(n){var t=this.id;return T(this,"function"==typeof n?function(e,r,i){e.__transition__[t].duration=Math.max(1,0|n.call(e,e.__data__,r,i))}:(n=Math.max(1,0|n),function(e){e.__transition__[t].duration=n}))},Yc.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Fc,i=Hc;Hc=e,T(this,function(t,r,i){Fc=t.__transition__[e],n.call(t,t.__data__,r,i)}),Fc=r,Hc=i}else T(this,function(r){var i=r.__transition__[e];(i.event||(i.event=ya.dispatch("start","end"))).on(n,t)});return this},Yc.transition=function(){for(var n,t,e,r,i=this.id,u=++Rc,a=[],o=0,c=this.length;c>o;o++){a.push(n=[]);for(var t=this[o],l=0,s=t.length;s>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[i]),r.delay+=r.duration,Nu(e,l,u,r)),n.push(e)}return Eu(a,u)},ya.svg.axis=function(){function n(n){n.each(function(){var n,f=ya.select(this),h=null==l?e.ticks?e.ticks.apply(e,c):e.domain():l,g=null==t?e.tickFormat?e.tickFormat.apply(e,c):String:t,p=Cu(e,h,s),m=f.selectAll(".tick.minor").data(p,String),d=m.enter().insert("line",".tick").attr("class","tick minor").style("opacity",1e-6),v=ya.transition(m.exit()).style("opacity",1e-6).remove(),y=ya.transition(m).style("opacity",1),M=f.selectAll(".tick.major").data(h,String),x=M.enter().insert("g",".domain").attr("class","tick major").style("opacity",1e-6),b=ya.transition(M.exit()).style("opacity",1e-6).remove(),_=ya.transition(M).style("opacity",1),w=Bi(e),S=f.selectAll(".domain").data([0]),E=(S.enter().append("path").attr("class","domain"),ya.transition(S)),k=e.copy(),A=this.__chart__||k; +this.__chart__=k,x.append("line"),x.append("text");var N=x.select("line"),q=_.select("line"),T=M.select("text").text(g),C=x.select("text"),z=_.select("text");switch(r){case"bottom":n=qu,d.attr("y2",u),y.attr("x2",0).attr("y2",u),N.attr("y2",i),C.attr("y",Math.max(i,0)+o),q.attr("x2",0).attr("y2",i),z.attr("x",0).attr("y",Math.max(i,0)+o),T.attr("dy",".71em").style("text-anchor","middle"),E.attr("d","M"+w[0]+","+a+"V0H"+w[1]+"V"+a);break;case"top":n=qu,d.attr("y2",-u),y.attr("x2",0).attr("y2",-u),N.attr("y2",-i),C.attr("y",-(Math.max(i,0)+o)),q.attr("x2",0).attr("y2",-i),z.attr("x",0).attr("y",-(Math.max(i,0)+o)),T.attr("dy","0em").style("text-anchor","middle"),E.attr("d","M"+w[0]+","+-a+"V0H"+w[1]+"V"+-a);break;case"left":n=Tu,d.attr("x2",-u),y.attr("x2",-u).attr("y2",0),N.attr("x2",-i),C.attr("x",-(Math.max(i,0)+o)),q.attr("x2",-i).attr("y2",0),z.attr("x",-(Math.max(i,0)+o)).attr("y",0),T.attr("dy",".32em").style("text-anchor","end"),E.attr("d","M"+-a+","+w[0]+"H0V"+w[1]+"H"+-a);break;case"right":n=Tu,d.attr("x2",u),y.attr("x2",u).attr("y2",0),N.attr("x2",i),C.attr("x",Math.max(i,0)+o),q.attr("x2",i).attr("y2",0),z.attr("x",Math.max(i,0)+o).attr("y",0),T.attr("dy",".32em").style("text-anchor","start"),E.attr("d","M"+a+","+w[0]+"H0V"+w[1]+"H"+a)}if(e.rangeBand){var D=k.rangeBand()/2,j=function(n){return k(n)+D};x.call(n,j),_.call(n,j)}else x.call(n,A),_.call(n,k),b.call(n,k),d.call(n,A),y.call(n,k),v.call(n,k)})}var t,e=ya.scale.linear(),r=Uc,i=6,u=6,a=6,o=3,c=[10],l=null,s=0;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ic?t+"":Uc,n):r},n.ticks=function(){return arguments.length?(c=arguments,n):c},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t,e){if(!arguments.length)return i;var r=arguments.length-1;return i=+t,u=r>1?+e:i,a=r>0?+arguments[r]:i,n},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(t){return arguments.length?(s=+t,n):s},n};var Uc="bottom",Ic={top:1,right:1,bottom:1,left:1};ya.svg.brush=function(){function n(u){u.each(function(){var u,a=ya.select(this),s=a.selectAll(".background").data([0]),f=a.selectAll(".extent").data([0]),h=a.selectAll(".resize").data(l,String);a.style("pointer-events","all").on("mousedown.brush",i).on("touchstart.brush",i),s.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),f.enter().append("rect").attr("class","extent").style("cursor","move"),h.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Vc[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),h.style("display",n.empty()?"none":null),h.exit().remove(),o&&(u=Bi(o),s.attr("x",u[0]).attr("width",u[1]-u[0]),e(a)),c&&(u=Bi(c),s.attr("y",u[0]).attr("height",u[1]-u[0]),r(a)),t(a)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)][0]+","+s[+/^s/.test(n)][1]+")"})}function e(n){n.select(".extent").attr("x",s[0][0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1][0]-s[0][0])}function r(n){n.select(".extent").attr("y",s[0][1]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",s[1][1]-s[0][1])}function i(){function i(){var n=ya.event.changedTouches;return n?ya.touches(M,n)[0]:ya.mouse(M)}function l(){32==ya.event.keyCode&&(k||(v=null,N[0]-=s[1][0],N[1]-=s[1][1],k=2),g())}function h(){32==ya.event.keyCode&&2==k&&(N[0]+=s[1][0],N[1]+=s[1][1],k=0,g())}function p(){var n=i(),u=!1;y&&(n[0]+=y[0],n[1]+=y[1]),k||(ya.event.altKey?(v||(v=[(s[0][0]+s[1][0])/2,(s[0][1]+s[1][1])/2]),N[0]=s[+(n[0]l?(i=r,r=l):i=l),s[0][e]!==r||s[1][e]!==i?(u=null,s[0][e]=r,s[1][e]=i,!0):void 0}function d(){p(),_.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ya.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),A(),b({type:"brushend"})}var v,y,M=this,x=ya.select(ya.event.target),b=a.of(M,arguments),_=ya.select(M),w=x.datum(),S=!/^(n|s)$/.test(w)&&o,E=!/^(e|w)$/.test(w)&&c,k=x.classed("extent"),A=H(),N=i(),q=ya.select(ba).on("keydown.brush",l).on("keyup.brush",h);if(ya.event.changedTouches?q.on("touchmove.brush",p).on("touchend.brush",d):q.on("mousemove.brush",p).on("mouseup.brush",d),k)N[0]=s[0][0]-N[0],N[1]=s[0][1]-N[1];else if(w){var T=+/w$/.test(w),C=+/^n/.test(w);y=[s[1-T][0]-N[0],s[1-C][1]-N[1]],N[0]=s[T][0],N[1]=s[C][1]}else ya.event.altKey&&(v=N.slice());_.style("pointer-events","none").selectAll(".resize").style("display",null),ya.select("body").style("cursor",x.style("cursor")),b({type:"brushstart"}),p()}var u,a=m(n,"brushstart","brush","brushend"),o=null,c=null,l=Xc[0],s=[[0,0],[0,0]],f=[!0,!0];return n.x=function(t){return arguments.length?(o=t,l=Xc[!o<<1|!c],n):o},n.y=function(t){return arguments.length?(c=t,l=Xc[!o<<1|!c],n):c},n.clamp=function(t){return arguments.length?(o&&c?f=[!!t[0],!!t[1]]:(o||c)&&(f[+!o]=!!t),n):o&&c?f:o||c?f[+!o]:null},n.extent=function(t){var e,r,i,a,l;return arguments.length?(u=[[0,0],[0,0]],o&&(e=t[0],r=t[1],c&&(e=e[0],r=r[0]),u[0][0]=e,u[1][0]=r,o.invert&&(e=o(e),r=o(r)),e>r&&(l=e,e=r,r=l),s[0][0]=0|e,s[1][0]=0|r),c&&(i=t[0],a=t[1],o&&(i=i[1],a=a[1]),u[0][1]=i,u[1][1]=a,c.invert&&(i=c(i),a=c(a)),i>a&&(l=i,i=a,a=l),s[0][1]=0|i,s[1][1]=0|a),n):(t=u||s,o&&(e=t[0][0],r=t[1][0],u||(e=s[0][0],r=s[1][0],o.invert&&(e=o.invert(e),r=o.invert(r)),e>r&&(l=e,e=r,r=l))),c&&(i=t[0][1],a=t[1][1],u||(i=s[0][1],a=s[1][1],c.invert&&(i=c.invert(i),a=c.invert(a)),i>a&&(l=i,i=a,a=l))),o&&c?[[e,i],[r,a]]:o?[e,r]:c&&[i,a])},n.clear=function(){return u=null,s[0][0]=s[0][1]=s[1][0]=s[1][1]=0,n},n.empty=function(){return o&&s[0][0]===s[1][0]||c&&s[0][1]===s[1][1]},ya.rebind(n,a,"on")};var Vc={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Xc=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]];ya.time={};var Zc=Date,Bc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];zu.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){$c.setUTCDate.apply(this._,arguments)},setDay:function(){$c.setUTCDay.apply(this._,arguments)},setFullYear:function(){$c.setUTCFullYear.apply(this._,arguments)},setHours:function(){$c.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){$c.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){$c.setUTCMinutes.apply(this._,arguments)},setMonth:function(){$c.setUTCMonth.apply(this._,arguments)},setSeconds:function(){$c.setUTCSeconds.apply(this._,arguments)},setTime:function(){$c.setTime.apply(this._,arguments)}};var $c=Date.prototype,Wc="%a %b %e %X %Y",Jc="%m/%d/%Y",Gc="%H:%M:%S",Kc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Qc=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],nl=["January","February","March","April","May","June","July","August","September","October","November","December"],tl=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];ya.time.year=Du(function(n){return n=ya.time.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ya.time.years=ya.time.year.range,ya.time.years.utc=ya.time.year.utc.range,ya.time.day=Du(function(n){var t=new Zc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ya.time.days=ya.time.day.range,ya.time.days.utc=ya.time.day.utc.range,ya.time.dayOfYear=function(n){var t=ya.time.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},Bc.forEach(function(n,t){n=n.toLowerCase(),t=7-t;var e=ya.time[n]=Du(function(n){return(n=ya.time.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ya.time.year(n).getDay();return Math.floor((ya.time.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ya.time[n+"s"]=e.range,ya.time[n+"s"].utc=e.utc.range,ya.time[n+"OfYear"]=function(n){var e=ya.time.year(n).getDay();return Math.floor((ya.time.dayOfYear(n)+(e+t)%7)/7)}}),ya.time.week=ya.time.sunday,ya.time.weeks=ya.time.sunday.range,ya.time.weeks.utc=ya.time.sunday.utc.range,ya.time.weekOfYear=ya.time.sundayOfYear,ya.time.format=function(n){function t(t){for(var r,i,u,a=[],o=-1,c=0;++o=12?"PM":"AM"},S:function(n,t){return Pu(n.getSeconds(),t,2)},U:function(n,t){return Pu(ya.time.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Pu(ya.time.mondayOfYear(n),t,2)},x:ya.time.format(Jc),X:ya.time.format(Gc),y:function(n,t){return Pu(n.getFullYear()%100,t,2)},Y:function(n,t){return Pu(n.getFullYear()%1e4,t,4)},Z:aa,"%":function(){return"%"}},gl={a:Ou,A:Yu,b:Vu,B:Xu,c:Zu,d:Qu,e:Qu,H:ta,I:ta,j:na,L:ia,m:Ku,M:ea,p:ua,S:ra,U:Uu,w:Ru,W:Iu,x:Bu,X:$u,y:Ju,Y:Wu,"%":oa},pl=/^\s*\d+/,ml=ya.map({am:0,pm:1});ya.time.format.utc=function(n){function t(n){try{Zc=zu;var t=new Zc;return t._=n,e(t)}finally{Zc=Date}}var e=ya.time.format(n);return t.parse=function(n){try{Zc=zu;var t=e.parse(n);return t&&t._}finally{Zc=Date}},t.toString=e.toString,t};var dl=ya.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");ya.time.format.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?ca:dl,ca.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},ca.toString=dl.toString,ya.time.second=Du(function(n){return new Zc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ya.time.seconds=ya.time.second.range,ya.time.seconds.utc=ya.time.second.utc.range,ya.time.minute=Du(function(n){return new Zc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ya.time.minutes=ya.time.minute.range,ya.time.minutes.utc=ya.time.minute.utc.range,ya.time.hour=Du(function(n){var t=n.getTimezoneOffset()/60;return new Zc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ya.time.hours=ya.time.hour.range,ya.time.hours.utc=ya.time.hour.utc.range,ya.time.month=Du(function(n){return n=ya.time.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ya.time.months=ya.time.month.range,ya.time.months.utc=ya.time.month.utc.range;var vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],yl=[[ya.time.second,1],[ya.time.second,5],[ya.time.second,15],[ya.time.second,30],[ya.time.minute,1],[ya.time.minute,5],[ya.time.minute,15],[ya.time.minute,30],[ya.time.hour,1],[ya.time.hour,3],[ya.time.hour,6],[ya.time.hour,12],[ya.time.day,1],[ya.time.day,2],[ya.time.week,1],[ya.time.month,1],[ya.time.month,3],[ya.time.year,1]],Ml=[[ya.time.format("%Y"),Xt],[ya.time.format("%B"),function(n){return n.getMonth()}],[ya.time.format("%b %d"),function(n){return 1!=n.getDate()}],[ya.time.format("%a %d"),function(n){return n.getDay()&&1!=n.getDate()}],[ya.time.format("%I %p"),function(n){return n.getHours()}],[ya.time.format("%I:%M"),function(n){return n.getMinutes()}],[ya.time.format(":%S"),function(n){return n.getSeconds()}],[ya.time.format(".%L"),function(n){return n.getMilliseconds()}]],xl=ya.scale.linear(),bl=fa(Ml);yl.year=function(n,t){return xl.domain(n.map(ga)).ticks(t).map(ha)},ya.time.scale=function(){return la(ya.scale.linear(),yl,bl)};var _l=yl.map(function(n){return[n[0].utc,n[1]]}),wl=[[ya.time.format.utc("%Y"),Xt],[ya.time.format.utc("%B"),function(n){return n.getUTCMonth()}],[ya.time.format.utc("%b %d"),function(n){return 1!=n.getUTCDate()}],[ya.time.format.utc("%a %d"),function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],[ya.time.format.utc("%I %p"),function(n){return n.getUTCHours()}],[ya.time.format.utc("%I:%M"),function(n){return n.getUTCMinutes()}],[ya.time.format.utc(":%S"),function(n){return n.getUTCSeconds()}],[ya.time.format.utc(".%L"),function(n){return n.getUTCMilliseconds()}]],Sl=fa(wl);return _l.year=function(n,t){return xl.domain(n.map(ma)).ticks(t).map(pa)},ya.time.scale.utc=function(){return la(ya.scale.linear(),_l,Sl)},ya.text=dt(function(n){return n.responseText}),ya.json=function(n,t){return vt(n,"application/json",da,t)},ya.html=function(n,t){return vt(n,"text/html",va,t)},ya.xml=dt(function(n){return n.responseXML}),ya}(); \ No newline at end of file diff --git a/templates/project/assets/javascripts/d3.v2.min.js b/templates/project/assets/javascripts/d3.v2.min.js deleted file mode 100644 index ecd5ff07..00000000 --- a/templates/project/assets/javascripts/d3.v2.min.js +++ /dev/null @@ -1,4 +0,0 @@ -(function(){function d(a,b){try{for(var c in b)Object.defineProperty(a.prototype,c,{value:b[c],enumerable:!1})}catch(d){a.prototype=b}}function f(a){var b=-1,c=a.length,d=[];while(++b=0?a.substring(b):(b=a.length,""),d=[];while(b>0)d.push(a.substring(b-=3,b+3));return d.reverse().join(",")+c}function H(a,b){var c=Math.pow(10,Math.abs(8-b)*3);return{scale:b>8?function(a){return a/c}:function(a){return a*c},symbol:a}}function N(a){return function(b){return b<=0?0:b>=1?1:a(b)}}function O(a){return function(b){return 1-a(1-b)}}function P(a){return function(b){return.5*(b<.5?a(2*b):2-a(2-2*b))}}function Q(a){return a}function R(a){return function(b){return Math.pow(b,a)}}function S(a){return 1-Math.cos(a*Math.PI/2)}function T(a){return Math.pow(2,10*(a-1))}function U(a){return 1-Math.sqrt(1-a*a)}function V(a,b){var c;return arguments.length<2&&(b=.45),arguments.length<1?(a=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/a),function(d){return 1+a*Math.pow(2,10*-d)*Math.sin((d-c)*2*Math.PI/b)}}function W(a){return a||(a=1.70158),function(b){return b*b*((a+1)*b-a)}}function X(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375}function Y(){d3.event.stopPropagation(),d3.event.preventDefault()}function Z(){var a=d3.event,b;while(b=a.sourceEvent)a=b;return a}function $(a){var b=new z,c=0,d=arguments.length;while(++c360?a-=360:a<0&&(a+=360),a<60?d+(e-d)*a/60:a<180?e:a<240?d+(e-d)*(240-a)/60:d}function g(a){return Math.round(f(a)*255)}var d,e;return a%=360,a<0&&(a+=360),b=b<0?0:b>1?1:b,c=c<0?0:c>1?1:c,e=c<=.5?c*(1+b):c+b-c*b,d=2*c-e,bj(g(a+120),g(a),g(a-120))}function bv(a,b,c){return new bw(a,b,c)}function bw(a,b,c){this.h=a,this.c=b,this.l=c}function bx(a,b,c){return by(c,Math.cos(a*=Math.PI/180)*b,Math.sin(a)*b)}function by(a,b,c){return new bz(a,b,c)}function bz(a,b,c){this.l=a,this.a=b,this.b=c}function bE(a,b,c){var d=(a+16)/116,e=d+b/500,f=d-c/200;return e=bG(e)*bB,d=bG(d)*bC,f=bG(f)*bD,bj(bI(3.2404542*e-1.5371385*d-.4985314*f),bI(-0.969266*e+1.8760108*d+.041556*f),bI(.0556434*e-.2040259*d+1.0572252*f))}function bF(a,b,c){return bv(Math.atan2(c,b)/Math.PI*180,Math.sqrt(b*b+c*c),a)}function bG(a){return a>.206893034?a*a*a:(a-4/29)/7.787037}function bH(a){return a>.008856?Math.pow(a,1/3):7.787037*a+4/29}function bI(a){return Math.round(255*(a<=.00304?12.92*a:1.055*Math.pow(a,1/2.4)-.055))}function bJ(a){return i(a,bP),a}function bQ(a){return function(){return bK(a,this)}}function bR(a){return function(){return bL(a,this)}}function bS(a,b){function c(){this.removeAttribute(a)}function d(){this.removeAttributeNS(a.space,a.local)}function e(){this.setAttribute(a,b)}function f(){this.setAttributeNS(a.space,a.local,b)}function g(){var c=b.apply(this,arguments);c==null?this.removeAttribute(a):this.setAttribute(a,c)}function h(){var c=b.apply(this,arguments);c==null?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}return a=d3.ns.qualify(a),b==null?a.local?d:c:typeof b=="function"?a.local?h:g:a.local?f:e}function bT(a){return new RegExp("(?:^|\\s+)"+d3.requote(a)+"(?:\\s+|$)","g")}function bU(a,b){function d(){var d=-1;while(++d0&&(a=a.substring(0,e)),b?g:f}function ca(a,b){for(var c=0,d=a.length;cb?q():(m.active=b,d.forEach(function(b,c){(c=c.call(a,n,h))&&j.push(c)}),e.start.call(a,n,h),p(f)||d3.timer(p,0,c),1)}function p(c){if(m.active!==b)return q();var d=(c-k)/l,g=f(d),i=j.length;while(i>0)j[--i].call(a,g);if(d>=1)return q(),ch=b,e.end.call(a,n,h),ch=0,1}function q(){return--m.count||delete a.__transition__,1}var j=[],k=a.delay,l=a.duration,m=(a=a.node).__transition__||(a.__transition__={active:0,count:0}),n=a.__data__;++m.count,k<=g?o(g):d3.timer(o,k,c)})},0,c),a}function co(a){var b=ch,c=cn,d=cl,e=cm;return ch=this.id,cn=this.ease(),ca(this,function(b,c,d){cl=b.delay,cm=b.duration,a.call(b=b.node,b.__data__,c,d)}),ch=b,cn=c,cl=d,cm=e,this}function cq(a,b,c){return c!=""&&cp}function cr(a,b){return d3.tween(a,bg(b))}function cv(){var a,b=Date.now(),c=cs;while(c)a=b-c.then,a>=c.delay&&(c.flush=c.callback(a)),c=c.next;var d=cw()-b;d>24?(isFinite(d)&&(clearTimeout(cu),cu=setTimeout(cv,d)),ct=0):(ct=1,cx(cv))}function cw(){var a=null,b=cs,c=Infinity;while(b)b.flush?b=a?a.next=b.next:cs=b.next:(c=Math.min(c,b.then+b.delay),b=(a=b).next);return c}function cz(a,b){var c=a.ownerSVGElement||a;if(c.createSVGPoint){var d=c.createSVGPoint();if(cy<0&&(window.scrollX||window.scrollY)){c=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var e=c[0][0].getScreenCTM();cy=!e.f&&!e.e,c.remove()}return cy?(d.x=b.pageX,d.y=b.pageY):(d.x=b.clientX,d.y=b.clientY),d=d.matrixTransform(a.getScreenCTM().inverse()),[d.x,d.y]}var f=a.getBoundingClientRect();return[b.clientX-f.left-a.clientLeft,b.clientY-f.top-a.clientTop]}function cA(){}function cB(a){var b=a[0],c=a[a.length-1];return b2?cM:cL,i=d?bi:bh;return e=g(a,b,i,c),f=g(b,a,i,d3.interpolate),h}function h(a){return e(a)}var e,f;return h.invert=function(a){return f(a)},h.domain=function(b){return arguments.length?(a=b.map(Number),g()):a},h.range=function(a){return arguments.length?(b=a,g()):b},h.rangeRound=function(a){return h.range(a).interpolate(d3.interpolateRound)},h.clamp=function(a){return arguments.length?(d=a,g()):d},h.interpolate=function(a){return arguments.length?(c=a,g()):c},h.ticks=function(b){return cJ(a,b)},h.tickFormat=function(b){return cK(a,b)},h.nice=function(){return cD(a,cH),g()},h.copy=function(){return cF(a,b,c,d)},g()}function cG(a,b){return d3.rebind(a,b,"range","rangeRound","interpolate","clamp")}function cH(a){return a=Math.pow(10,Math.round(Math.log(a)/Math.LN10)-1),a&&{floor:function(b){return Math.floor(b/a)*a},ceil:function(b){return Math.ceil(b/a)*a}}}function cI(a,b){var c=cB(a),d=c[1]-c[0],e=Math.pow(10,Math.floor(Math.log(d/b)/Math.LN10)),f=b/d*e;return f<=.15?e*=10:f<=.35?e*=5:f<=.75&&(e*=2),c[0]=Math.ceil(c[0]/e)*e,c[1]=Math.floor(c[1]/e)*e+e*.5,c[2]=e,c}function cJ(a,b){return d3.range.apply(d3,cI(a,b))}function cK(a,b){return d3.format(",."+Math.max(0,-Math.floor(Math.log(cI(a,b)[2])/Math.LN10+.01))+"f")}function cL(a,b,c,d){var e=c(a[0],a[1]),f=d(b[0],b[1]);return function(a){return f(e(a))}}function cM(a,b,c,d){var e=[],f=[],g=0,h=Math.min(a.length,b.length)-1;a[h]0;j--)e.push(c(f)*j)}else{for(;fi;g--);e=e.slice(f,g)}return e},d.tickFormat=function(a,e){arguments.length<2&&(e=cO);if(arguments.length<1)return e;var f=Math.max(.1,a/d.ticks().length),g=b===cQ?(h=-1e-12,Math.floor):(h=1e-12,Math.ceil),h;return function(a){return a/c(g(b(a)+h))<=f?e(a):""}},d.copy=function(){return cN(a.copy(),b)},cG(d,a)}function cP(a){return Math.log(a<0?0:a)/Math.LN10}function cQ(a){return-Math.log(a>0?0:-a)/Math.LN10}function cR(a,b){function e(b){return a(c(b))}var c=cS(b),d=cS(1/b);return e.invert=function(b){return d(a.invert(b))},e.domain=function(b){return arguments.length?(a.domain(b.map(c)),e):a.domain().map(d)},e.ticks=function(a){return cJ(e.domain(),a)},e.tickFormat=function(a){return cK(e.domain(),a)},e.nice=function(){return e.domain(cD(e.domain(),cH))},e.exponent=function(a){if(!arguments.length)return b;var f=e.domain();return c=cS(b=a),d=cS(1/b),e.domain(f)},e.copy=function(){return cR(a.copy(),b)},cG(e,a)}function cS(a){return function(b){return b<0?-Math.pow(-b,a):Math.pow(b,a)}}function cT(a,b){function f(b){return d[((c.get(b)||c.set(b,a.push(b)))-1)%d.length]}function g(b,c){return d3.range(a.length).map(function(a){return b+c*a})}var c,d,e;return f.domain=function(d){if(!arguments.length)return a;a=[],c=new j;var e=-1,g=d.length,h;while(++e1){h=b[1],f=a[i],i++,d+="C"+(e[0]+g[0])+","+(e[1]+g[1])+","+(f[0]-h[0])+","+(f[1]-h[1])+","+f[0]+","+f[1];for(var j=2;j9&&(f=c*3/Math.sqrt(f),g[h]=f*d,g[h+1]=f*e));h=-1;while(++h<=i)f=(a[Math.min(i,h+1)][0]-a[Math.max(0,h-1)][0])/(6*(1+g[h]*g[h])),b.push([f||0,g[h]*f||0]);return b}function dG(a){return a.length<3?dk(a):a[0]+ds(a,dF(a))}function dH(a){var b,c=-1,d=a.length,e,f;while(++c1){var d=cB(a.domain()),e,f=-1,g=b.length,h=(b[1]-b[0])/++c,i,j;while(++f0;)(j=+b[f]-i*h)>=d[0]&&e.push(j);for(--f,i=0;++id&&(c=b,d=e);return c}function ex(a){return a.reduce(ey,0)}function ey(a,b){return a+b[1]}function ez(a,b){return eA(a,Math.ceil(Math.log(b.length)/Math.LN2+1))}function eA(a,b){var c=-1,d=+a[0],e=(a[1]-d)/b,f=[];while(++c<=b)f[c]=e*c+d;return f}function eB(a){return[d3.min(a),d3.max(a)]}function eC(a,b){return d3.rebind(a,b,"sort","children","value"),a.links=eG,a.nodes=function(b){return eH=!0,(a.nodes=a)(b)},a}function eD(a){return a.children}function eE(a){return a.value}function eF(a,b){return b.value-a.value}function eG(a){return d3.merge(a.map(function(a){return(a.children||[]).map(function(b){return{source:a,target:b}})}))}function eI(a,b){return a.value-b.value}function eJ(a,b){var c=a._pack_next;a._pack_next=b,b._pack_prev=a,b._pack_next=c,c._pack_prev=b}function eK(a,b){a._pack_next=b,b._pack_prev=a}function eL(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-c*c-d*d>.001}function eM(a){function n(a){c=Math.min(a.x-a.r,c),d=Math.max(a.x+a.r,d),e=Math.min(a.y-a.r,e),f=Math.max(a.y+a.r,f)}if(!(b=a.children)||!(m=b.length))return;var b,c=Infinity,d=-Infinity,e=Infinity,f=-Infinity,g,h,i,j,k,l,m;b.forEach(eN),g=b[0],g.x=-g.r,g.y=0,n(g);if(m>1){h=b[1],h.x=h.r,h.y=0,n(h);if(m>2){i=b[2],eQ(g,h,i),n(i),eJ(g,i),g._pack_prev=i,eJ(i,h),h=g._pack_next;for(j=3;j0&&(a=d)}return a}function eZ(a,b){return a.x-b.x}function e$(a,b){return b.x-a.x}function e_(a,b){return a.depth-b.depth}function fa(a,b){function c(a,d){var e=a.children;if(e&&(i=e.length)){var f,g=null,h=-1,i;while(++h=0)f=d[e]._tree,f.prelim+=b,f.mod+=b,b+=f.shift+(c+=f.change)}function fc(a,b,c){a=a._tree,b=b._tree;var d=c/(b.number-a.number);a.change+=d,b.change-=d,b.shift+=c,b.prelim+=c,b.mod+=c}function fd(a,b,c){return a._tree.ancestor.parent==b.parent?a._tree.ancestor:c}function fe(a){return{x:a.x,y:a.y,dx:a.dx,dy:a.dy}}function ff(a,b){var c=a.x+b[3],d=a.y+b[0],e=a.dx-b[1]-b[3],f=a.dy-b[0]-b[2];return e<0&&(c+=e/2,e=0),f<0&&(d+=f/2,f=0),{x:c,y:d,dx:e,dy:f}}function fg(a,b){function f(a,c){d3.text(a,b,function(a){c(a&&f.parse(a))})}function g(b){return b.map(h).join(a)}function h(a){return d.test(a)?'"'+a.replace(/\"/g,'""')+'"':a}var c=new RegExp("\r\n|["+a+"\r\n]","g"),d=new RegExp('["'+a+"\n]"),e=a.charCodeAt(0);return f.parse=function(a){var b;return f.parseRows(a,function(a,c){if(c){var d={},e=-1,f=b.length;while(++e=a.length)return f;if(j)return j=!1,d;var b=c.lastIndex;if(a.charCodeAt(b)===34){var g=b;while(g++0}function fC(a,b,c){return(c[0]-b[0])*(a[1]-b[1])<(c[1]-b[1])*(a[0]-b[0])}function fD(a,b,c,d){var e=a[0],f=b[0],g=c[0],h=d[0],i=a[1],j=b[1],k=c[1],l=d[1],m=e-g,n=f-e,o=h-g,p=i-k,q=j-i,r=l-k,s=(o*p-r*m)/(r*n-o*q);return[e+s*n,i+s*q]}function fF(a,b){var c={list:a.map(function(a,b){return{index:b,x:a[0],y:a[1]}}).sort(function(a,b){return a.yb.y?1:a.xb.x?1:0}),bottomSite:null},d={list:[],leftEnd:null,rightEnd:null,init:function(){d.leftEnd=d.createHalfEdge(null,"l"),d.rightEnd=d.createHalfEdge(null,"l"),d.leftEnd.r=d.rightEnd,d.rightEnd.l=d.leftEnd,d.list.unshift(d.leftEnd,d.rightEnd)},createHalfEdge:function(a,b){return{edge:a,side:b,vertex:null,l:null,r:null}},insert:function(a,b){b.l=a,b.r=a.r,a.r.l=b,a.r=b},leftBound:function(a){var b=d.leftEnd;do b=b.r;while(b!=d.rightEnd&&e.rightOf(b,a));return b=b.l,b},del:function(a){a.l.r=a.r,a.r.l=a.l,a.edge=null},right:function(a){return a.r},left:function(a){return a.l},leftRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[a.side]},rightRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[fE[a.side]]}},e={bisect:function(a,b){var c={region:{l:a,r:b},ep:{l:null,r:null}},d=b.x-a.x,e=b.y-a.y,f=d>0?d:-d,g=e>0?e:-e;return c.c=a.x*d+a.y*e+(d*d+e*e)*.5,f>g?(c.a=1,c.b=e/d,c.c/=d):(c.b=1,c.a=d/e,c.c/=e),c},intersect:function(a,b){var c=a.edge,d=b.edge;if(!c||!d||c.region.r==d.region.r)return null;var e=c.a*d.b-c.b*d.a;if(Math.abs(e)<1e-10)return null;var f=(c.c*d.b-d.c*c.b)/e,g=(d.c*c.a-c.c*d.a)/e,h=c.region.r,i=d.region.r,j,k;h.y=k.region.r.x;return l&&j.side==="l"||!l&&j.side==="r"?null:{x:f,y:g}},rightOf:function(a,b){var c=a.edge,d=c.region.r,e=b.x>d.x;if(e&&a.side==="l")return 1;if(!e&&a.side==="r")return 0;if(c.a===1){var f=b.y-d.y,g=b.x-d.x,h=0,i=0;!e&&c.b<0||e&&c.b>=0?i=h=f>=c.b*g:(i=b.x+b.y*c.b>c.c,c.b<0&&(i=!i),i||(h=1));if(!h){var j=d.x-c.region.l.x;i=c.b*(g*g-f*f)m*m+n*n}return a.side==="l"?i:!i},endPoint:function(a,c,d){a.ep[c]=d;if(!a.ep[fE[c]])return;b(a)},distance:function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}},f={list:[],insert:function(a,b,c){a.vertex=b,a.ystar=b.y+c;for(var d=0,e=f.list,g=e.length;dh.ystar||a.ystar==h.ystar&&b.x>h.vertex.x)continue;break}e.splice(d,0,a)},del:function(a){for(var b=0,c=f.list,d=c.length;bo.y&&(p=n,n=o,o=p,t="r"),s=e.bisect(n,o),m=d.createHalfEdge(s,t),d.insert(k,m),e.endPoint(s,fE[t],r),q=e.intersect(k,m),q&&(f.del(k),f.insert(k,q,e.distance(q,n))),q=e.intersect(m,l),q&&f.insert(m,q,e.distance(q,n));else break}for(i=d.right(d.leftEnd);i!=d.rightEnd;i=d.right(i))b(i.edge)}function fG(){return{leaf:!0,nodes:[],point:null}}function fH(a,b,c,d,e,f){if(!a(b,c,d,e,f)){var g=(c+e)*.5,h=(d+f)*.5,i=b.nodes;i[0]&&fH(a,i[0],c,d,g,h),i[1]&&fH(a,i[1],g,d,e,h),i[2]&&fH(a,i[2],c,h,g,f),i[3]&&fH(a,i[3],g,h,e,f)}}function fI(a){return{x:a[0],y:a[1]}}function fL(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function fU(a){return a.substring(0,3)}function fV(a,b,c,d){var e,f,g=0,h=b.length,i=c.length;while(g=i)return-1;e=b.charCodeAt(g++);if(e==37){f=gh[b.charAt(g++)];if(!f||(d=f(a,c,d))<0)return-1}else if(e!=c.charCodeAt(d++))return-1}return d}function fW(a){return new RegExp("^(?:"+a.map(d3.requote).join("|")+")","i")}function fX(a){var b=new j,c=-1,d=a.length;while(++c68?1900:2e3)}function gs(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.m=d[0]-1,c+=d[0].length):-1}function gt(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.d=+d[0],c+=d[0].length):-1}function gu(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.H=+d[0],c+=d[0].length):-1}function gv(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.M=+d[0],c+=d[0].length):-1}function gw(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.S=+d[0],c+=d[0].length):-1}function gx(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+3));return d?(a.L=+d[0],c+=d[0].length):-1}function gz(a,b,c){var d=gA.get(b.substring(c,c+=2).toLowerCase());return d==null?-1:(a.p=d,c)}function gB(a){var b=a.getTimezoneOffset(),c=b>0?"-":"+",d=~~(Math.abs(b)/60),e=Math.abs(b)%60;return c+fY(d)+fY(e)}function gD(a){return a.toISOString()}function gE(a,b,c){function d(b){var c=a(b),d=f(c,1);return b-c1)while(gb?1:a>=b?0:NaN},d3.descending=function(a,b){return ba?1:b>=a?0:NaN},d3.mean=function(a,b){var c=a.length,d,e=0,f=-1,g=0;if(arguments.length===1)while(++f1&&(a=a.map(b)),a=a.filter(r),a.length?d3.quantile(a.sort(d3.ascending),.5):undefined},d3.min=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++cf&&(e=f)}else{while(++cf&&(e=f)}return e},d3.max=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++ce&&(e=f)}else{while(++ce&&(e=f)}return e},d3.extent=function(a,b){var c=-1,d=a.length,e,f,g;if(arguments.length===1){while(++cf&&(e=f),gf&&(e=f),g1);return a+b*c*Math.sqrt(-2*Math.log(e)/e)}},logNormal:function(a,b){var c=arguments.length;c<2&&(b=1),c<1&&(a=0);var d=d3.random.normal();return function(){return Math.exp(a+b*d())}},irwinHall:function(a){return function(){for(var b=0,c=0;c>>1;a.call(b,b[f],f)>>1;c0&&(e=f);return e},d3.last=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c=b.length)return e?e.call(a,c):d?c.sort(d):c;var h=-1,i=c.length,k=b[g++],l,m,n=new j,o,p={};while(++h=b.length)return a;var e=[],f=c[d++],h;for(h in a)e.push({key:h,values:g(a[h],d)});return f&&e.sort(function(a,b){return f(a.key,b.key)}),e}var a={},b=[],c=[],d,e;return a.map=function(a){return f(a,0)},a.entries=function(a){return g(f(a,0),0)},a.key=function(c){return b.push(c),a},a.sortKeys=function(d){return c[b.length-1]=d,a},a.sortValues=function(b){return d=b,a},a.rollup=function(b){return e=b,a},a},d3.keys=function(a){var b=[];for(var c in a)b.push(c);return b},d3.values=function(a){var b=[];for(var c in a)b.push(a[c]);return b},d3.entries=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},d3.permute=function(a,b){var c=[],d=-1,e=b.length;while(++db)d.push(g/e);else while((g=a+c*++f)=200&&a<300||a===304?d:null)}},d.send(null)},d3.text=function(a,b,c){function d(a){c(a&&a.responseText)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)},d3.json=function(a,b){d3.text(a,"application/json",function(a){b(a?JSON.parse(a):null)})},d3.html=function(a,b){d3.text(a,"text/html",function(a){if(a!=null){var c=document.createRange();c.selectNode(document.body),a=c.createContextualFragment(a)}b(a)})},d3.xml=function(a,b,c){function d(a){c(a&&a.responseXML)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)};var y={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:y,qualify:function(a){var b=a.indexOf(":"),c=a;return b>=0&&(c=a.substring(0,b),a=a.substring(b+1)),y.hasOwnProperty(c)?{space:y[c],local:a}:a}},d3.dispatch=function(){var a=new z,b=-1,c=arguments.length;while(++b0&&(d=a.substring(c+1),a=a.substring(0,c)),arguments.length<2?this[a].on(d):this[a].on(d,b)},d3.format=function(a){var b=B.exec(a),c=b[1]||" ",d=b[3]||"",e=b[5],f=+b[6],g=b[7],h=b[8],i=b[9],j=1,k="",l=!1;h&&(h=+h.substring(1)),e&&(c="0",g&&(f-=Math.floor((f-1)/4)));switch(i){case"n":g=!0,i="g";break;case"%":j=100,k="%",i="f";break;case"p":j=100,k="%",i="r";break;case"d":l=!0,h=0;break;case"s":j=-1,i="r"}return i=="r"&&!h&&(i="g"),i=C.get(i)||E,function(a){if(l&&a%1)return"";var b=a<0&&(a=-a)?"-":d;if(j<0){var m=d3.formatPrefix(a,h);a=m.scale(a),k=m.symbol}else a*=j;a=i(a,h);if(e){var n=a.length+b.length;n=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,C=d3.map({g:function(a,b){return a.toPrecision(b)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},r:function(a,b){return d3.round(a,b=D(a,b)).toFixed(Math.max(0,Math.min(20,b)))}}),G=["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(H);d3.formatPrefix=function(a,b){var c=0;return a&&(a<0&&(a*=-1),b&&(a=d3.round(a,D(a,b))),c=1+Math.floor(1e-12+Math.log(a)/Math.LN10),c=Math.max(-24,Math.min(24,Math.floor((c<=0?c+1:c-1)/3)*3))),G[8+c/3]};var I=R(2),J=R(3),K=function(){return Q},L=d3.map({linear:K,poly:R,quad:function(){return I},cubic:function(){return J},sin:function(){return S},exp:function(){return T},circle:function(){return U},elastic:V,back:W,bounce:function(){return X}}),M=d3.map({"in":Q,out:O,"in-out":P,"out-in":function(a){return P(O(a))}});d3.ease=function(a){var b=a.indexOf("-"),c=b>=0?a.substring(0,b):a,d=b>=0?a.substring(b+1):"in";return c=L.get(c)||K,d=M.get(d)||Q,N(d(c.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.transform=function(a){var b=document.createElementNS(d3.ns.prefix.svg,"g");return(d3.transform=function(a){b.setAttribute("transform",a);var c=b.transform.baseVal.consolidate();return new _(c?c.matrix:be)})(a)},_.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var bd=180/Math.PI,be={a:1,b:0,c:0,d:1,e:0,f:0};d3.interpolate=function(a,b){var c=d3.interpolators.length,d;while(--c>=0&&!(d=d3.interpolators[c](a,b)));return d},d3.interpolateNumber=function(a,b){return b-=a,function(c){return a+b*c}},d3.interpolateRound=function(a,b){return b-=a,function(c){return Math.round(a+b*c)}},d3.interpolateString=function(a,b){var c,d,e,f=0,g=0,h=[],i=[],j,k;bf.lastIndex=0;for(d=0;c=bf.exec(b);++d)c.index&&h.push(b.substring(f,g=c.index)),i.push({i:h.length,x:c[0]}),h.push(null),f=bf.lastIndex;f180?k+=360:k-j>180&&(j+=360),d.push({i:c.push(c.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(j,k)})):k&&c.push(c.pop()+"rotate("+k+")"),l!=m?d.push({i:c.push(c.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(l,m)}):m&&c.push(c.pop()+"skewX("+m+")"),n[0]!=o[0]||n[1]!=o[1]?(e=c.push(c.pop()+"scale(",null,",",null,")"),d.push({i:e-4,x:d3.interpolateNumber(n[0],o[0])},{i:e-2,x:d3.interpolateNumber(n[1],o[1])})):(o[0]!=1||o[1]!=1)&&c.push(c.pop()+"scale("+o+")"),e=d.length,function(a){var b=-1,f;while(++b180?f-=360:f<-180&&(f+=360),function(a){return bu(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateLab=function(a,b){a=d3.lab(a),b=d3.lab(b);var c=a.l,d=a.a,e=a.b,f=b.l-c,g=b.a-d,h=b.b-e;return function(a){return bE(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateHcl=function(a,b){a=d3.hcl(a),b=d3.hcl(b);var c=a.h,d=a.c,e=a.l,f=b.h-c,g=b.c-d,h=b.l-e;return f>180?f-=360:f<-180&&(f+=360),function(a){return bx(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateArray=function(a,b){var c=[],d=[],e=a.length,f=b.length,g=Math.min(a.length,b.length),h;for(h=0;h=0;)if(f=c[d])e&&e!==f.nextSibling&&e.parentNode.insertBefore(f,e),e=f;return this},bP.sort=function(a){a=b$.apply(this,arguments);for(var b=-1,c=this.length;++b=db?e?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+e+"A"+e+","+e+" 0 1,0 0,"+ -e+"A"+e+","+e+" 0 1,0 0,"+e+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":e?"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L"+e*m+","+e*n+"A"+e+","+e+" 0 "+j+",0 "+e*k+","+e*l+"Z":"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L0,0"+"Z"}var a=dc,b=dd,c=de,d=df;return e.innerRadius=function(b){return arguments.length?(a=p(b),e):a},e.outerRadius=function(a){return arguments.length?(b=p(a),e):b},e.startAngle=function(a){return arguments.length?(c=p(a),e):c},e.endAngle=function(a){return arguments.length?(d=p(a),e):d},e.centroid=function(){var e=(a.apply(this,arguments)+b.apply(this,arguments))/2,f=(c.apply(this,arguments)+d.apply(this,arguments))/2+da;return[Math.cos(f)*e,Math.sin(f)*e]},e};var da=-Math.PI/2,db=2*Math.PI-1e-6;d3.svg.line=function(){return dg(m)};var dj=d3.map({linear:dk,"linear-closed":dl,"step-before":dm,"step-after":dn,basis:du,"basis-open":dv,"basis-closed":dw,bundle:dx,cardinal:dr,"cardinal-open":dp,"cardinal-closed":dq,monotone:dG});dj.forEach(function(a,b){b.key=a,b.closed=/-closed$/.test(a)});var dz=[0,2/3,1/3,0],dA=[0,1/3,2/3,0],dB=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var a=dg(dH);return a.radius=a.x,delete a.x,a.angle=a.y,delete a.y,a},dm.reverse=dn,dn.reverse=dm,d3.svg.area=function(){return dI(m)},d3.svg.area.radial=function(){var a=dI(dH);return a.radius=a.x,delete a.x,a.innerRadius=a.x0,delete a.x0,a.outerRadius=a.x1,delete a.x1,a.angle=a.y,delete a.y,a.startAngle=a.y0,delete a.y0,a.endAngle=a.y1,delete a.y1,a},d3.svg.chord=function(){function f(c,d){var e=g(this,a,c,d),f=g(this,b,c,d);return"M"+e.p0+i(e.r,e.p1,e.a1-e.a0)+(h(e,f)?j(e.r,e.p1,e.r,e.p0):j(e.r,e.p1,f.r,f.p0)+i(f.r,f.p1,f.a1-f.a0)+j(f.r,f.p1,e.r,e.p0))+"Z"}function g(a,b,f,g){var h=b.call(a,f,g),i=c.call(a,h,g),j=d.call(a,h,g)+da,k=e.call(a,h,g)+da;return{r:i,a0:j,a1:k,p0:[i*Math.cos(j),i*Math.sin(j)],p1:[i*Math.cos(k),i*Math.sin(k)]}}function h(a,b){return a.a0==b.a0&&a.a1==b.a1}function i(a,b,c){return"A"+a+","+a+" 0 "+ +(c>Math.PI)+",1 "+b}function j(a,b,c,d){return"Q 0,0 "+d}var a=dJ,b=dK,c=dL,d=de,e=df;return f.radius=function(a){return arguments.length?(c=p(a),f):c},f.source=function(b){return arguments.length?(a=p(b),f):a},f.target=function(a){return arguments.length?(b=p(a),f):b},f.startAngle=function(a){return arguments.length?(d=p(a),f):d},f.endAngle=function(a){return arguments.length?(e=p(a),f):e},f},d3.svg.diagonal=function(){function d(d,e){var f=a.call(this,d,e),g=b.call(this,d,e),h=(f.y+g.y)/2,i=[f,{x:f.x,y:h},{x:g.x,y:h},g];return i=i.map(c),"M"+i[0]+"C"+i[1]+" "+i[2]+" "+i[3]}var a=dJ,b=dK,c=dO;return d.source=function(b){return arguments.length?(a=p(b),d):a},d.target=function(a){return arguments.length?(b=p(a),d):b},d.projection=function(a){return arguments.length?(c=a,d):c},d},d3.svg.diagonal.radial=function(){var a=d3.svg.diagonal(),b=dO,c=a.projection;return a.projection=function(a){return arguments.length?c(dP(b=a)):b},a},d3.svg.mouse=d3.mouse,d3.svg.touches=d3.touches,d3.svg.symbol=function(){function c(c,d){return(dT.get(a.call(this,c,d))||dS)(b.call(this,c,d))}var a=dR,b=dQ;return c.type=function(b){return arguments.length?(a=p(b),c):a},c.size=function(a){return arguments.length?(b=p(a),c):b},c};var dT=d3.map({circle:dS,cross:function(a){var b=Math.sqrt(a/5)/2;return"M"+ -3*b+","+ -b+"H"+ -b+"V"+ -3*b+"H"+b+"V"+ -b+"H"+3*b+"V"+b+"H"+b+"V"+3*b+"H"+ -b+"V"+b+"H"+ -3*b+"Z"},diamond:function(a){var b=Math.sqrt(a/(2*dV)),c=b*dV;return"M0,"+ -b+"L"+c+",0"+" 0,"+b+" "+ -c+",0"+"Z"},square:function(a){var b=Math.sqrt(a)/2;return"M"+ -b+","+ -b+"L"+b+","+ -b+" "+b+","+b+" "+ -b+","+b+"Z"},"triangle-down":function(a){var b=Math.sqrt(a/dU),c=b*dU/2;return"M0,"+c+"L"+b+","+ -c+" "+ -b+","+ -c+"Z"},"triangle-up":function(a){var b=Math.sqrt(a/dU),c=b*dU/2;return"M0,"+ -c+"L"+b+","+c+" "+ -b+","+c+"Z"}});d3.svg.symbolTypes=dT.keys();var dU=Math.sqrt(3),dV=Math.tan(30*Math.PI/180);d3.svg.axis=function(){function k(k){k.each(function(){var k=d3.select(this),l=h==null?a.ticks?a.ticks.apply(a,g):a.domain():h,m=i==null?a.tickFormat?a.tickFormat.apply(a,g):String:i,n=dY(a,l,j),o=k.selectAll(".minor").data(n,String),p=o.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),q=d3.transition(o.exit()).style("opacity",1e-6).remove(),r=d3.transition(o).style("opacity",1),s=k.selectAll("g").data(l,String),t=s.enter().insert("g","path").style("opacity",1e-6),u=d3.transition(s.exit()).style("opacity",1e-6).remove(),v=d3.transition(s).style("opacity",1),w,x=cC(a),y=k.selectAll(".domain").data([0]),z=y.enter().append("path").attr("class","domain"),A=d3.transition(y),B=a.copy(),C=this.__chart__||B;this.__chart__=B,t.append("line").attr("class","tick"),t.append("text");var D=t.select("line"),E=v.select("line"),F=s.select("text").text(m),G=t.select("text"),H=v.select("text");switch(b){case"bottom":w=dW,p.attr("y2",d),r.attr("x2",0).attr("y2",d),D.attr("y2",c),G.attr("y",Math.max(c,0)+f),E.attr("x2",0).attr("y2",c),H.attr("x",0).attr("y",Math.max(c,0)+f),F.attr("dy",".71em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+e+"V0H"+x[1]+"V"+e);break;case"top":w=dW,p.attr("y2",-d),r.attr("x2",0).attr("y2",-d),D.attr("y2",-c),G.attr("y",-(Math.max(c,0)+f)),E.attr("x2",0).attr("y2",-c),H.attr("x",0).attr("y",-(Math.max(c,0)+f)),F.attr("dy","0em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+ -e+"V0H"+x[1]+"V"+ -e);break;case"left":w=dX,p.attr("x2",-d),r.attr("x2",-d).attr("y2",0),D.attr("x2",-c),G.attr("x",-(Math.max(c,0)+f)),E.attr("x2",-c).attr("y2",0),H.attr("x",-(Math.max(c,0)+f)).attr("y",0),F.attr("dy",".32em").attr("text-anchor","end"),A.attr("d","M"+ -e+","+x[0]+"H0V"+x[1]+"H"+ -e);break;case"right":w=dX,p.attr("x2",d),r.attr("x2",d).attr("y2",0),D.attr("x2",c),G.attr("x",Math.max(c,0)+f),E.attr("x2",c).attr("y2",0),H.attr("x",Math.max(c,0)+f).attr("y",0),F.attr("dy",".32em").attr("text-anchor","start"),A.attr("d","M"+e+","+x[0]+"H0V"+x[1]+"H"+e)}if(a.ticks)t.call(w,C),v.call(w,B),u.call(w,B),p.call(w,C),r.call(w,B),q.call(w,B);else{var I=B.rangeBand()/2,J=function(a){return B(a)+I};t.call(w,J),v.call(w,J)}})}var a=d3.scale.linear(),b="bottom",c=6,d=6,e=6,f=3,g=[10],h=null,i,j=0;return k.scale=function(b){return arguments.length?(a=b,k):a},k.orient=function(a){return arguments.length?(b=a,k):b},k.ticks=function(){return arguments.length?(g=arguments,k):g},k.tickValues=function(a){return arguments.length?(h=a,k):h},k.tickFormat=function(a){return arguments.length?(i=a,k):i},k.tickSize=function(a,b,f){if(!arguments.length)return c;var g=arguments.length-1;return c=+a,d=g>1?+b:c,e=g>0?+arguments[g]:c,k},k.tickPadding=function(a){return arguments.length?(f=+a,k):f},k.tickSubdivide=function(a){return arguments.length?(j=+a,k):j},k},d3.svg.brush=function(){function g(a){a.each(function(){var a=d3.select(this),e=a.selectAll(".background").data([0]),f=a.selectAll(".extent").data([0]),l=a.selectAll(".resize").data(d,String),m;a.style("pointer-events","all").on("mousedown.brush",k).on("touchstart.brush",k),e.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),f.enter().append("rect").attr("class","extent").style("cursor","move"),l.enter().append("g").attr("class",function(a){return"resize "+a}).style("cursor",function(a){return dZ[a]}).append("rect").attr("x",function(a){return/[ew]$/.test(a)?-3:null}).attr("y",function(a){return/^[ns]/.test(a)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),l.style("display",g.empty()?"none":null),l.exit().remove(),b&&(m=cC(b),e.attr("x",m[0]).attr("width",m[1]-m[0]),i(a)),c&&(m=cC(c),e.attr("y",m[0]).attr("height",m[1]-m[0]),j(a)),h(a)})}function h(a){a.selectAll(".resize").attr("transform",function(a){return"translate("+e[+/e$/.test(a)][0]+","+e[+/^s/.test(a)][1]+")"})}function i(a){a.select(".extent").attr("x",e[0][0]),a.selectAll(".extent,.n>rect,.s>rect").attr("width",e[1][0]-e[0][0])}function j(a){a.select(".extent").attr("y",e[0][1]),a.selectAll(".extent,.e>rect,.w>rect").attr("height",e[1][1]-e[0][1])}function k(){function x(){var a=d3.event.changedTouches;return a?d3.touches(d,a)[0]:d3.mouse(d)}function y(){d3.event.keyCode==32&&(q||(r=null,s[0]-=e[1][0],s[1]-=e[1][1],q=2),Y())}function z(){d3.event.keyCode==32&&q==2&&(s[0]+=e[1][0],s[1]+=e[1][1],q=0,Y())}function A(){var a=x(),d=!1;t&&(a[0]+=t[0],a[1]+=t[1]),q||(d3.event.altKey?(r||(r=[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]),s[0]=e[+(a[0]0?e=c:e=0:c>0&&(b.start({type:"start",alpha:e=c}),d3.timer(a.tick)),a):e},a.start=function(){function p(a,c){var d=t(b),e=-1,f=d.length,g;while(++ee&&(e=h),d.push(h)}for(g=0;g0){f=-1;while(++f=i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]))}return g}var a=!0,b=Number,c=eB,d=ez;return e.value=function(a){return arguments.length?(b=a,e):b},e.range=function(a){return arguments.length?(c=p(a),e):c},e.bins=function(a){return arguments.length?(d=typeof a=="number"?function(b){return eA(b,a)}:p(a),e):d},e.frequency=function(b){return arguments.length?(a=!!b,e):a},e},d3.layout.hierarchy=function(){function d(e,g,h){var i=b.call(f,e,g),j=eH?e:{data:e};j.depth=g,h.push(j);if(i&&(l=i.length)){var k=-1,l,m=j.children=[],n=0,o=g+1,p;while(++k0){var k=b*j/2;fa(g,function(a){a.r+=k}),fa(g,eM),fa(g,function(a){a.r-=k}),j=Math.max(2*g.r/h,2*g.r/i)}return eP(g,h/2,i/2,1/j),f}var a=d3.layout.hierarchy().sort(eI),b=0,c=[1,1];return d.size=function(a){return arguments.length?(c=a,d):c},d.padding=function(a){return arguments.length?(b=+a,d):b},eC(d,a)},d3.layout.cluster=function(){function d(d,e){var f=a.call(this,d,e),g=f[0],h,i=0,j,k;fa(g,function(a){var c=a.children;c&&c.length?(a.x=eS(c),a.y=eR(c)):(a.x=h?i+=b(a,h):0,a.y=0,h=a)});var l=eT(g),m=eU(g),n=l.x-b(l,m)/2,o=m.x+b(m,l)/2;return fa(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=(1-(g.y?a.y/g.y:1))*c[1]}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=eV,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},eC(d,a)},d3.layout.tree=function(){function d(d,e){function h(a,c){var d=a.children,e=a._tree;if(d&&(f=d.length)){var f,g=d[0],i,k=g,l,m=-1;while(++m0&&(fc(fd(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!eX(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!eW(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}var f=a.call(this,d,e),g=f[0];fa(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=eY(g,e$),l=eY(g,eZ),m=eY(g,e_),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;return fa(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=eV,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},eC(d,a)},d3.layout.treemap=function(){function i(a,b){var c=-1,d=a.length,e,f;while(++c0)d.push(g=f[o-1]),d.area+=g.area,(k=l(d,n))<=h?(f.pop(),h=k):(d.area-=d.pop().area,m(d,n,c,!1),n=Math.min(c.dx,c.dy),d.length=d.area=0,h=Infinity);d.length&&(m(d,n,c,!0),d.length=d.area=0),b.forEach(j)}}function k(a){var b=a.children;if(b&&b.length){var c=e(a),d=b.slice(),f,g=[];i(d,c.dx*c.dy/a.value),g.area=0;while(f=d.pop())g.push(f),g.area+=f.area,f.z!=null&&(m(g,f.z?c.dx:c.dy,c,!d.length),g.length=g.area=0);b.forEach(k)}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++ge&&(e=d)}return c*=c,b*=b,c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++fd.dx)j=d.dx;while(++f50?b:f<-140?c:g<21?d:a)(e)}var a=d3.geo.albers(),b=d3.geo.albers().origin([-160,60]).parallels([55,65]),c=d3.geo.albers().origin([-160,20]).parallels([8,18]),d=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(f){return arguments.length?(a.scale(f),b.scale(f*.6),c.scale(f),d.scale(f*1.5),e.translate(a.translate())):a.scale()},e.translate=function(f){if(!arguments.length)return a.translate();var g=a.scale()/1e3,h=f[0],i=f[1];return a.translate(f),b.translate([h-400*g,i+170*g]),c.translate([h-190*g,i+200*g]),d.translate([h+580*g,i+430*g]),e},e.scale(a.scale())},d3.geo.bonne=function(){function g(g){var h=g[0]*fh-c,i=g[1]*fh-d;if(e){var j=f+e-i,k=h*Math.cos(i)/j;h=j*Math.sin(k),i=j*Math.cos(k)-f}else h*=Math.cos(i),i*=-1;return[a*h+b[0],a*i+b[1]]}var a=200,b=[480,250],c,d,e,f;return g.invert=function(d){var g=(d[0]-b[0])/a,h=(d[1]-b[1])/a;if(e){var i=f+h,j=Math.sqrt(g*g+i*i);h=f+e-j,g=c+j*Math.atan2(g,i)/Math.cos(h)}else h*=-1,g/=Math.cos(h);return[g/fh,h/fh]},g.parallel=function(a){return arguments.length?(f=1/ -Math.tan(e=a*fh),g):e/fh},g.origin=function(a){return arguments.length?(c=a[0]*fh,d=a[1]*fh,g):[c/fh,d/fh]},g.scale=function(b){return arguments.length?(a=+b,g):a},g.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],g):b},g.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function c(c){var d=c[0]/360,e=-c[1]/360;return[a*d+b[0],a*e+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,-360*e]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.mercator=function(){function c(c){var d=c[0]/360,e=-(Math.log(Math.tan(Math.PI/4+c[1]*fh/2))/fh)/360;return[a*d+b[0],a*Math.max(-0.5,Math.min(.5,e))+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,2*Math.atan(Math.exp(-360*e*fh))/fh-90]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.path=function(){function e(c,e){typeof a=="function"&&(b=fj(a.apply(this,arguments))),g(c);var f=d.length?d.join(""):null;return d=[],f}function f(a){return c(a).join(",")}function i(a){var b=l(a[0]),c=0,d=a.length;while(++c0){d.push("M");while(++h0){d.push("M");while(++kd&&(d=a),fe&&(e=f)}),[[b,c],[d,e]]};var fl={Feature:fm,FeatureCollection:fn,GeometryCollection:fo,LineString:fp,MultiLineString:fq,MultiPoint:fp,MultiPolygon:fr,Point:fs,Polygon:ft};d3.geo.circle=function(){function e(){}function f(a){return d.distance(a)=k*k+l*l?d[f].index=-1:(d[m].index=-1,o=d[f].angle,m=f,n=g)):(o=d[f].angle,m=f,n=g);e.push(h);for(f=0,g=0;f<2;++g)d[g].index!==-1&&(e.push(d[g].index),f++);p=e.length;for(;g=0?(c=a.ep.r,d=a.ep.l):(c=a.ep.l,d=a.ep.r),a.a===1?(g=c?c.y:-1e6,e=a.c-a.b*g,h=d?d.y:1e6,f=a.c-a.b*h):(e=c?c.x:-1e6,g=a.c-a.a*e,f=d?d.x:1e6,h=a.c-a.a*f);var i=[e,g],j=[f,h];b[a.region.l.index].push(i,j),b[a.region.r.index].push(i,j)}),b.map(function(b,c){var d=a[c][0],e=a[c][1];return b.forEach(function(a){a.angle=Math.atan2(a[0]-d,a[1]-e)}),b.sort(function(a,b){return a.angle-b.angle}).filter(function(a,c){return!c||a.angle-b[c-1].angle>1e-10})})};var fE={l:"r",r:"l"};d3.geom.delaunay=function(a){var b=a.map(function(){return[]}),c=[];return fF(a,function(c){b[c.region.l.index].push(a[c.region.r.index])}),b.forEach(function(b,d){var e=a[d],f=e[0],g=e[1];b.forEach(function(a){a.angle=Math.atan2(a[0]-f,a[1]-g)}),b.sort(function(a,b){return a.angle-b.angle});for(var h=0,i=b.length-1;h=g,j=b.y>=h,l=(j<<1)+i;a.leaf=!1,a=a.nodes[l]||(a.nodes[l]=fG()),i?c=g:e=g,j?d=h:f=h,k(a,b,c,d,e,f)}var f,g=-1,h=a.length;h&&isNaN(a[0].x)&&(a=a.map(fI));if(arguments.length<5)if(arguments.length===3)e=d=c,c=b;else{b=c=Infinity,d=e=-Infinity;while(++gd&&(d=f.x),f.y>e&&(e=f.y);var i=d-b,j=e-c;i>j?e=c+i:d=b+j}var m=fG();return m.add=function(a){k(m,a,b,c,d,e)},m.visit=function(a){fH(a,m,b,c,d,e)},a.forEach(m.add),m},d3.time={};var fJ=Date,fK=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];fL.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){fM.setUTCDate.apply(this._,arguments)},setDay:function(){fM.setUTCDay.apply(this._,arguments)},setFullYear:function(){fM.setUTCFullYear.apply(this._,arguments)},setHours:function(){fM.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){fM.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){fM.setUTCMinutes.apply(this._,arguments)},setMonth:function(){fM.setUTCMonth.apply(this._,arguments)},setSeconds:function(){fM.setUTCSeconds.apply(this._,arguments)},setTime:function(){fM.setTime.apply(this._,arguments)}};var fM=Date.prototype,fN="%a %b %e %H:%M:%S %Y",fO="%m/%d/%y",fP="%H:%M:%S",fQ=fK,fR=fQ.map(fU),fS=["January","February","March","April","May","June","July","August","September","October","November","December"],fT=fS.map(fU);d3.time.format=function(a){function c(c){var d=[],e=-1,f=0,g,h;while(++e=12?"PM":"AM"},S:function(a){return fY(a.getSeconds())},U:function(a){return fY(d3.time.sundayOfYear(a))},w:function(a){return a.getDay()},W:function(a){return fY(d3.time.mondayOfYear(a))},x:d3.time.format(fO),X:d3.time.format(fP),y:function(a){return fY(a.getFullYear()%100)},Y:function(a){return f$(a.getFullYear()%1e4)},Z:gB,"%":function(a){return"%"}},gh={a:gi,A:gj,b:gk,B:gl,c:gm,d:gt,e:gt,H:gu,I:gu,L:gx,m:gs,M:gv,p:gz,S:gw,x:gn,X:go,y:gq,Y:gp},gy=/^\s*\d+/,gA=d3.map({am:0,pm:1});d3.time.format.utc=function(a){function c(a){try{fJ=fL;var c=new fJ;return c._=a,b(c)}finally{fJ=Date}}var b=d3.time.format(a);return c.parse=function(a){try{fJ=fL;var c=b.parse(a);return c&&c._}finally{fJ=Date}},c.toString=b.toString,c};var gC=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?gD:gC,gD.parse=function(a){var b=new Date(a);return isNaN(b)?null:b},gD.toString=gC.toString,d3.time.second=gE(function(a){return new fJ(Math.floor(a/1e3)*1e3)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*1e3)},function(a){return a.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=gE(function(a){return new fJ(Math.floor(a/6e4)*6e4)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*6e4)},function(a){return a.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=gE(function(a){var b=a.getTimezoneOffset()/60;return new fJ((Math.floor(a/36e5-b)+b)*36e5)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*36e5)},function(a){return a.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=gE(function(a){var b=new fJ(0,a.getMonth(),a.getDate());return b.setFullYear(a.getFullYear()),b},function(a,b){a.setDate(a.getDate()+b)},function(a){return a.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(a){var b=d3.time.year(a);return Math.floor((a-b-(a.getTimezoneOffset()-b.getTimezoneOffset())*6e4)/864e5)},fK.forEach(function(a,b){a=a.toLowerCase(),b=7-b;var c=d3.time[a]=gE(function(a){return(a=d3.time.day(a)).setDate(a.getDate()-(a.getDay()+b)%7),a},function(a,b){a.setDate(a.getDate()+Math.floor(b)*7)},function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)-(c!==b)});d3.time[a+"s"]=c.range,d3.time[a+"s"].utc=c.utc.range,d3.time[a+"OfYear"]=function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=gE(function(a){return a=d3.time.day(a),a.setDate(1),a},function(a,b){a.setMonth(a.getMonth()+b)},function(a){return a.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=gE(function(a){return a=d3.time.day(a),a.setMonth(0,1),a},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a){return a.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var gM=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],gN=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],gO=[[d3.time.format("%Y"),function(a){return!0}],[d3.time.format("%B"),function(a){return a.getMonth()}],[d3.time.format("%b %d"),function(a){return a.getDate()!=1}],[d3.time.format("%a %d"),function(a){return a.getDay()&&a.getDate()!=1}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]],gP=d3.scale.linear(),gQ=gJ(gO);gN.year=function(a,b){return gP.domain(a.map(gL)).ticks(b).map(gK)},d3.time.scale=function(){return gG(d3.scale.linear(),gN,gQ)};var gR=gN.map(function(a){return[a[0].utc,a[1]]}),gS=[[d3.time.format.utc("%Y"),function(a){return!0}],[d3.time.format.utc("%B"),function(a){return a.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(a){return a.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(a){return a.getUTCDay()&&a.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(a){return a.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(a){return a.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(a){return a.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(a){return a.getUTCMilliseconds()}]],gT=gJ(gS);gR.year=function(a,b){return gP.domain(a.map(gV)).ticks(b).map(gU)},d3.time.scale.utc=function(){return gG(d3.scale.linear(),gR,gT)}})(); \ No newline at end of file diff --git a/templates/project/assets/javascripts/dashing.gridster.coffee b/templates/project/assets/javascripts/dashing.gridster.coffee index e25c5618..7c1f94ad 100644 --- a/templates/project/assets/javascripts/dashing.gridster.coffee +++ b/templates/project/assets/javascripts/dashing.gridster.coffee @@ -26,9 +26,7 @@ Dashing.showGridsterInstructions = -> - ") + });\n") $ -> $('#save-gridster').leanModal() diff --git a/templates/project/assets/javascripts/gridster/jquery.gridster.js b/templates/project/assets/javascripts/gridster/jquery.gridster.js deleted file mode 100644 index 90991779..00000000 --- a/templates/project/assets/javascripts/gridster/jquery.gridster.js +++ /dev/null @@ -1,2890 +0,0 @@ -/*! gridster.js - v0.1.0 - 2012-08-14 -* http://gridster.net/ -* Copyright (c) 2012 ducksboard; Licensed MIT */ - -;(function($, window, document, undefined){ - /** - * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height) - * to simulate DOM elements on the screen. - * Coords is used by Gridster to create a faux grid with any DOM element can - * collide. - * - * @class Coords - * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left, - * top, width and height properties. - * @return {Object} Coords instance. - * @constructor - */ - function Coords(obj) { - if (obj[0] && $.isPlainObject(obj[0])) { - this.data = obj[0]; - }else { - this.el = obj; - } - - this.isCoords = true; - this.coords = {}; - this.init(); - return this; - } - - - var fn = Coords.prototype; - - - fn.init = function(){ - this.set(); - this.original_coords = this.get(); - }; - - - fn.set = function(update, not_update_offsets) { - var el = this.el; - - if (el && !update) { - this.data = el.offset(); - this.data.width = el.width(); - this.data.height = el.height(); - } - - if (el && update && !not_update_offsets) { - var offset = el.offset(); - this.data.top = offset.top; - this.data.left = offset.left; - } - - var d = this.data; - - this.coords.x1 = d.left; - this.coords.y1 = d.top; - this.coords.x2 = d.left + d.width; - this.coords.y2 = d.top + d.height; - this.coords.cx = d.left + (d.width / 2); - this.coords.cy = d.top + (d.height / 2); - this.coords.width = d.width; - this.coords.height = d.height; - this.coords.el = el || false ; - - return this; - }; - - - fn.update = function(data){ - if (!data && !this.el) { - return this; - } - - if (data) { - var new_data = $.extend({}, this.data, data); - this.data = new_data; - return this.set(true, true); - } - - this.set(true); - return this; - }; - - - fn.get = function(){ - return this.coords; - }; - - - //jQuery adapter - $.fn.coords = function() { - if (this.data('coords') ) { - return this.data('coords'); - } - - var ins = new Coords(this, arguments[0]); - this.data('coords', ins); - return ins; - }; - -}(jQuery, window, document)); - -;(function($, window, document, undefined){ - - var defaults = { - colliders_context: document.body - // ,on_overlap: function(collider_data){}, - // on_overlap_start : function(collider_data){}, - // on_overlap_stop : function(collider_data){} - }; - - - /** - * Detects collisions between a DOM element against other DOM elements or - * Coords objects. - * - * @class Collision - * @uses Coords - * @param {HTMLElement} el The jQuery wrapped HTMLElement. - * @param {HTMLElement|Array} colliders Can be a jQuery collection - * of HTMLElements or an Array of Coords instances. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {Function} [options.on_overlap_start] Executes a function the first - * time each `collider ` is overlapped. - * @param {Function} [options.on_overlap_stop] Executes a function when a - * `collider` is no longer collided. - * @param {Function} [options.on_overlap] Executes a function when the - * mouse is moved during the collision. - * @return {Object} Collision instance. - * @constructor - */ - function Collision(el, colliders, options) { - this.options = $.extend(defaults, options); - this.$element = el; - this.last_colliders = []; - this.last_colliders_coords = []; - if (typeof colliders === 'string' || colliders instanceof jQuery) { - this.$colliders = $(colliders, - this.options.colliders_context).not(this.$element); - }else{ - this.colliders = $(colliders); - } - - this.init(); - } - - - var fn = Collision.prototype; - - - fn.init = function() { - this.find_collisions(); - }; - - - fn.overlaps = function(a, b) { - var x = false; - var y = false; - - if ((b.x1 >= a.x1 && b.x1 <= a.x2) || - (b.x2 >= a.x1 && b.x2 <= a.x2) || - (a.x1 >= b.x1 && a.x2 <= b.x2) - ) { x = true; } - - if ((b.y1 >= a.y1 && b.y1 <= a.y2) || - (b.y2 >= a.y1 && b.y2 <= a.y2) || - (a.y1 >= b.y1 && a.y2 <= b.y2) - ) { y = true; } - - return (x && y); - }; - - - fn.detect_overlapping_region = function(a, b){ - var regionX = ''; - var regionY = ''; - - if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; } - if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; } - if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; } - if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; } - - return (regionX + regionY) || 'C'; - }; - - - fn.calculate_overlapped_area_coords = function(a, b){ - var x1 = Math.max(a.x1, b.x1); - var y1 = Math.max(a.y1, b.y1); - var x2 = Math.min(a.x2, b.x2); - var y2 = Math.min(a.y2, b.y2); - - return $({ - left: x1, - top: y1, - width : (x2 - x1), - height: (y2 - y1) - }).coords().get(); - }; - - - fn.calculate_overlapped_area = function(coords){ - return (coords.width * coords.height); - }; - - - fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){ - var last = this.last_colliders_coords; - - for (var i = 0, il = last.length; i < il; i++) { - if ($.inArray(last[i], new_colliders_coords) === -1) { - start_callback.call(this, last[i]); - } - } - - for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) { - if ($.inArray(new_colliders_coords[j], last) === -1) { - stop_callback.call(this, new_colliders_coords[j]); - } - - } - }; - - - fn.find_collisions = function(player_data_coords){ - var self = this; - var colliders_coords = []; - var colliders_data = []; - var $colliders = (this.colliders || this.$colliders); - var count = $colliders.length; - var player_coords = self.$element.coords() - .update(player_data_coords || false).get(); - - while(count--){ - var $collider = self.$colliders ? - $($colliders[count]) : $colliders[count]; - var $collider_coords_ins = ($collider.isCoords) ? - $collider : $collider.coords(); - var collider_coords = $collider_coords_ins.get(); - var overlaps = self.overlaps(player_coords, collider_coords); - - if (!overlaps) { - continue; - } - - var region = self.detect_overlapping_region( - player_coords, collider_coords); - - //todo: make this an option - if (region === 'C'){ - var area_coords = self.calculate_overlapped_area_coords( - player_coords, collider_coords); - var area = self.calculate_overlapped_area(area_coords); - var collider_data = { - area: area, - area_coords : area_coords, - region: region, - coords: collider_coords, - player_coords: player_coords, - el: $collider - }; - - if (self.options.on_overlap) { - self.options.on_overlap.call(this, collider_data); - } - colliders_coords.push($collider_coords_ins); - colliders_data.push(collider_data); - } - } - - if (self.options.on_overlap_stop || self.options.on_overlap_start) { - this.manage_colliders_start_stop(colliders_coords, - self.options.on_overlap_stop, self.options.on_overlap_start); - } - - this.last_colliders_coords = colliders_coords; - - return colliders_data; - }; - - - fn.get_closest_colliders = function(player_data_coords){ - var colliders = this.find_collisions(player_data_coords); - var min_area = 100; - colliders.sort(function(a, b){ - if (a.area <= min_area) { - return 1; - } - - /* if colliders are being overlapped by the "C" (center) region, - * we have to set a lower index in the array to which they are placed - * above in the grid. */ - if (a.region === 'C' && b.region === 'C') { - if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) { - return - 1; - }else{ - return 1; - } - } - - if (a.area < b.area){ - return 1; - } - - return 1; - }); - return colliders; - }; - - - //jQuery adapter - $.fn.collision = function(collider, options) { - return new Collision( this, collider, options ); - }; - - -}(jQuery, window, document)); - -;(function(window, undefined) { - /* Debounce and throttle functions taken from underscore.js */ - window.debounce = function(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - if (immediate && !timeout) func.apply(context, args); - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }; - - - window.throttle = function(func, wait) { - var context, args, timeout, throttling, more, result; - var whenDone = debounce( - function(){ more = throttling = false; }, wait); - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) func.apply(context, args); - whenDone(); - }; - if (!timeout) timeout = setTimeout(later, wait); - if (throttling) { - more = true; - } else { - result = func.apply(context, args); - } - whenDone(); - throttling = true; - return result; - }; - }; - -})(window); - -;(function($, window, document, undefined){ - - var defaults = { - items: '.gs_w', - distance: 1, - limit: true, - offset_left: 0, - autoscroll: true - // ,drag: function(e){}, - // start : function(e, ui){}, - // stop : function(e){} - }; - - var $window = $(window); - var isTouch = !!('ontouchstart' in window); - var pointer_events = { - start: isTouch ? 'touchstart' : 'mousedown.draggable', - move: isTouch ? 'touchmove' : 'mousemove.draggable', - end: isTouch ? 'touchend' : 'mouseup.draggable' - }; - - /** - * Basic drag implementation for DOM elements inside a container. - * Provide start/stop/drag callbacks. - * - * @class Draggable - * @param {HTMLElement} el The HTMLelement that contains all the widgets - * to be dragged. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.items] Define who will - * be the draggable items. Can be a CSS Selector String or a - * collection of HTMLElements. - * @param {Number} [options.distance] Distance in pixels after mousedown - * the mouse must move before dragging should start. - * @param {Boolean} [options.limit] Constrains dragging to the width of - * the container - * @param {offset_left} [options.offset_left] Offset added to the item - * that is being dragged. - * @param {Number} [options.drag] Executes a callback when the mouse is - * moved during the dragging. - * @param {Number} [options.start] Executes a callback when the drag - * starts. - * @param {Number} [options.stop] Executes a callback when the drag stops. - * @return {Object} Returns `el`. - * @constructor - */ - function Draggable(el, options) { - this.options = $.extend({}, defaults, options); - this.$body = $(document.body); - this.$container = $(el); - this.$dragitems = $(this.options.items, this.$container); - this.is_dragging = false; - this.player_min_left = 0 + this.options.offset_left; - this.init(); - } - - var fn = Draggable.prototype; - - fn.init = function() { - this.calculate_positions(); - this.$container.css('position', 'relative'); - this.enable(); - - $(window).bind('resize', - throttle($.proxy(this.calculate_positions, this), 200)); - }; - - - fn.get_actual_pos = function($el) { - var pos = $el.position(); - return pos; - }; - - - fn.get_mouse_pos = function(e) { - if (isTouch) { - var oe = e.originalEvent; - e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0]; - }; - - return { - left: e.clientX, - top: e.clientY - }; - }; - - - fn.get_offset = function(e) { - e.preventDefault(); - var mouse_actual_pos = this.get_mouse_pos(e); - var diff_x = Math.round( - mouse_actual_pos.left - this.mouse_init_pos.left); - var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top); - - var left = Math.round(this.el_init_offset.left + diff_x - this.baseX); - var top = Math.round( - this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset); - - if (this.options.limit) { - if (left > this.player_max_left) { - left = this.player_max_left; - }else if(left < this.player_min_left) { - left = this.player_min_left; - } - } - - return { - left: left, - top: top, - mouse_left: mouse_actual_pos.left, - mouse_top: mouse_actual_pos.top - }; - }; - - - fn.manage_scroll = function(offset) { - /* scroll document */ - var nextScrollTop; - var scrollTop = $window.scrollTop(); - var min_window_y = scrollTop; - var max_window_y = min_window_y + this.window_height; - - var mouse_down_zone = max_window_y - 50; - var mouse_up_zone = min_window_y + 50; - - var abs_mouse_left = offset.mouse_left; - var abs_mouse_top = min_window_y + offset.mouse_top; - - var max_player_y = (this.doc_height - this.window_height + - this.player_height); - - if (abs_mouse_top >= mouse_down_zone) { - nextScrollTop = scrollTop + 30; - if (nextScrollTop < max_player_y) { - $window.scrollTop(nextScrollTop); - this.scrollOffset = this.scrollOffset + 30; - } - }; - - if (abs_mouse_top <= mouse_up_zone) { - nextScrollTop = scrollTop - 30; - if (nextScrollTop > 0) { - $window.scrollTop(nextScrollTop); - this.scrollOffset = this.scrollOffset - 30; - } - }; - } - - - fn.calculate_positions = function(e) { - this.window_height = $window.height(); - } - - - fn.drag_handler = function(e) { - var node = e.target.nodeName; - - if (e.which !== 1 && !isTouch) { - return; - } - - if (node === 'INPUT' || node === 'TEXTAREA' || node === 'SELECT' || - node === 'BUTTON') { - return; - }; - - var self = this; - var first = true; - this.$player = $(e.currentTarget); - - this.el_init_pos = this.get_actual_pos(this.$player); - this.mouse_init_pos = this.get_mouse_pos(e); - this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; - - this.$body.on(pointer_events.move, function(mme){ - var mouse_actual_pos = self.get_mouse_pos(mme); - var diff_x = Math.abs( - mouse_actual_pos.left - self.mouse_init_pos.left); - var diff_y = Math.abs( - mouse_actual_pos.top - self.mouse_init_pos.top); - if (!(diff_x > self.options.distance || - diff_y > self.options.distance) - ) { - return false; - } - - if (first) { - first = false; - self.on_dragstart.call(self, mme); - return false; - } - - if (self.is_dragging == true) { - self.on_dragmove.call(self, mme); - } - - return false; - }); - - return false; - }; - - - fn.on_dragstart = function(e) { - e.preventDefault(); - this.drag_start = true; - this.is_dragging = true; - var offset = this.$container.offset(); - this.baseX = Math.round(offset.left); - this.baseY = Math.round(offset.top); - this.doc_height = $(document).height(); - - if (this.options.helper === 'clone') { - this.$helper = this.$player.clone() - .appendTo(this.$container).addClass('helper'); - this.helper = true; - }else{ - this.helper = false; - } - this.scrollOffset = 0; - this.el_init_offset = this.$player.offset(); - this.player_width = this.$player.width(); - this.player_height = this.$player.height(); - this.player_max_left = (this.$container.width() - this.player_width + - this.options.offset_left); - - if (this.options.start) { - this.options.start.call(this.$player, e, { - helper: this.helper ? this.$helper : this.$player - }); - } - return false; - }; - - - fn.on_dragmove = function(e) { - var offset = this.get_offset(e); - - this.options.autoscroll && this.manage_scroll(offset); - - (this.helper ? this.$helper : this.$player).css({ - 'position': 'absolute', - 'left' : offset.left, - 'top' : offset.top - }); - - var ui = { - 'position': { - 'left': offset.left, - 'top': offset.top - } - }; - - if (this.options.drag) { - this.options.drag.call(this.$player, e, ui); - } - return false; - }; - - - fn.on_dragstop = function(e) { - var offset = this.get_offset(e); - this.drag_start = false; - - var ui = { - 'position': { - 'left': offset.left, - 'top': offset.top - } - }; - - if (this.options.stop) { - this.options.stop.call(this.$player, e, ui); - } - - if (this.helper) { - this.$helper.remove(); - } - - return false; - }; - - fn.on_select_start = function(e) { - return false; - } - - - fn.enable = function(){ - this.$container.on('selectstart', this.on_select_start); - - this.$container.on(pointer_events.start, this.options.items, $.proxy( - this.drag_handler, this)); - - this.$body.on(pointer_events.end, $.proxy(function(e) { - this.is_dragging = false; - this.$body.off(pointer_events.move); - if (this.drag_start) { - this.on_dragstop(e); - } - }, this)); - }; - - - fn.disable = function(){ - this.$container.off(pointer_events.start); - this.$body.off(pointer_events.end); - this.$container.off('selectstart', this.on_select_start); - }; - - - fn.destroy = function(){ - this.disable(); - $.removeData(this.$container, 'drag'); - }; - - - //jQuery adapter - $.fn.drag = function ( options ) { - return this.each(function () { - if (!$.data(this, 'drag')) { - $.data(this, 'drag', new Draggable( this, options )); - } - }); - }; - - -}(jQuery, window, document)); - -;(function($, window, document, undefined) { - - var defaults = { - widget_selector: '> li', - widget_margins: [10, 10], - widget_base_dimensions: [400, 225], - extra_rows: 0, - extra_cols: 0, - min_cols: 1, - min_rows: 15, - max_size_x: 6, - max_size_y: 6, - autogenerate_stylesheet: true, - avoid_overlapped_widgets: true, - serialize_params: function($w, wgd) { - return { - col: wgd.col, - row: wgd.row - }; - }, - collision: {}, - draggable: { - distance: 4 - } - }; - - - /** - * @class Gridster - * @uses Draggable - * @uses Collision - * @param {HTMLElement} el The HTMLelement that contains all the widgets. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.widget_selector] Define who will - * be the draggable widgets. Can be a CSS Selector String or a - * collection of HTMLElements - * @param {Array} [options.widget_margins] Margin between widgets. - * The first index for the horizontal margin (left, right) and - * the second for the vertical margin (top, bottom). - * @param {Array} [options.widget_base_dimensions] Base widget dimensions - * in pixels. The first index for the width and the second for the - * height. - * @param {Number} [options.extra_cols] Add more columns in addition to - * those that have been calculated. - * @param {Number} [options.extra_rows] Add more rows in addition to - * those that have been calculated. - * @param {Number} [options.min_cols] The minimum required columns. - * @param {Number} [options.min_rows] The minimum required rows. - * @param {Number} [options.max_size_x] The maximum number of columns - * that a widget can span. - * @param {Number} [options.max_size_y] The maximum number of rows - * that a widget can span. - * @param {Boolean} [options.autogenerate_stylesheet] If true, all the - * CSS required to position all widgets in their respective columns - * and rows will be generated automatically and injected to the - * `` of the document. You can set this to false, and write - * your own CSS targeting rows and cols via data-attributes like so: - * `[data-col="1"] { left: 10px; }` - * @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded - * from the DOM can be overlapped. It is helpful if the positions were - * bad stored in the database or if there was any conflict. - * @param {Function} [options.serialize_params] Return the data you want - * for each widget in the serialization. Two arguments are passed: - * `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid - * coords object (`col`, `row`, `size_x`, `size_y`). - * @param {Object} [options.collision] An Object with all options for - * Collision class you want to overwrite. See Collision docs for - * more info. - * @param {Object} [options.draggable] An Object with all options for - * Draggable class you want to overwrite. See Draggable docs for more - * info. - * - * @constructor - */ - function Gridster(el, options) { - this.options = $.extend(true, defaults, options); - this.$el = $(el); - this.$wrapper = this.$el.parent(); - this.$widgets = $(this.options.widget_selector, this.$el).addClass('gs_w'); - this.widgets = []; - this.$changed = $([]); - this.wrapper_width = this.$wrapper.width(); - this.min_widget_width = (this.options.widget_margins[0] * 2) + - this.options.widget_base_dimensions[0]; - this.min_widget_height = (this.options.widget_margins[1] * 2) + - this.options.widget_base_dimensions[1]; - this.init(); - } - - Gridster.generated_stylesheets = []; - - var fn = Gridster.prototype; - - fn.init = function() { - this.generate_grid_and_stylesheet(); - this.get_widgets_from_DOM(); - this.set_dom_grid_height(); - this.$wrapper.addClass('ready'); - this.draggable(); - - $(window).bind( - 'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200)); - }; - - - /** - * Disables dragging. - * - * @method disable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.disable = function() { - this.$wrapper.find('.player-revert').removeClass('player-revert'); - this.drag_api.disable(); - return this; - }; - - - /** - * Enables dragging. - * - * @method enable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.enable = function() { - this.drag_api.enable(); - return this; - }; - - - /** - * Add a new widget to the grid. - * - * @method add_widget - * @param {String} html The string representing the HTML of the widget. - * @param {Number} size_x The nº of rows the widget occupies horizontally. - * @param {Number} size_y The nº of columns the widget occupies vertically. - * @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing. - * the widget that was just created. - */ - fn.add_widget = function(html, size_x, size_y) { - var next_pos = this.next_position(size_x, size_y); - - var $w = $(html).attr({ - 'data-col': next_pos.col, - 'data-row': next_pos.row, - 'data-sizex' : next_pos.size_x, - 'data-sizey' : next_pos.size_y - }).addClass('gs_w').appendTo(this.$el).hide(); - - this.$widgets = this.$widgets.add($w); - - this.register_widget($w); - - this.set_dom_grid_height(); - - return $w.fadeIn(); - }; - - - /** - * Get the most left column below to add a new widget. - * - * @method next_position - * @param {Number} size_x The nº of rows the widget occupies horizontally. - * @param {Number} size_y The nº of columns the widget occupies vertically. - * @return {Object} Returns a grid coords object representing the future - * widget coords. - */ - fn.next_position = function(size_x, size_y) { - size_x || (size_x = 1); - size_y || (size_y = 1); - var ga = this.gridmap; - var cols_l = ga.length; - var valid_pos = []; - - for (var c = 1; c < cols_l; c++) { - var rows_l = ga[c].length; - for (var r = 1; r <= rows_l; r++) { - var can_move_to = this.can_move_to({ - size_x: size_x, - size_y: size_y - }, c, r); - - if (can_move_to) { - valid_pos.push({ - col: c, - row: r, - size_y: size_y, - size_x: size_x - }); - } - } - } - - if (valid_pos.length) { - return this.sort_by_row_and_col_asc(valid_pos)[0]; - } - return false; - }; - - - /** - * Remove a widget from the grid. - * - * @method remove_widget - * @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_widget = function(el, callback) { - var $el = el instanceof jQuery ? el : $(el); - var wgd = $el.coords().grid; - - this.cells_occupied_by_placeholder = {}; - this.$widgets = this.$widgets.not($el); - - var $nexts = this.widgets_below($el); - - this.remove_from_gridmap(wgd); - - $el.fadeOut($.proxy(function() { - $el.remove(); - - $nexts.each($.proxy(function(i, widget) { - this.move_widget_up( $(widget), wgd.size_y ); - }, this)); - - this.set_dom_grid_height(); - - if (callback) { - callback.call(this, el); - } - }, this)); - }; - - - /** - * Returns a serialized array of the widgets in the grid. - * - * @method serialize - * @param {HTMLElement} [$widgets] The collection of jQuery wrapped - * HTMLElements you want to serialize. If no argument is passed all widgets - * will be serialized. - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize = function($widgets) { - $widgets || ($widgets = this.$widgets); - var result = []; - $widgets.each($.proxy(function(i, widget) { - result.push(this.options.serialize_params( - $(widget), $(widget).coords().grid ) ); - }, this)); - - return result; - }; - - - /** - * Returns a serialized array of the widgets that have changed their - * position. - * - * @method serialize_changed - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize_changed = function() { - return this.serialize(this.$changed); - }; - - - /** - * Creates the grid coords object representing the widget a add it to the - * mapped array of positions. - * - * @method register_widget - * @return {Array} Returns the instance of the Gridster class. - */ - fn.register_widget = function($el) { - - var wgd = { - 'col': parseInt($el.attr('data-col'), 10), - 'row': parseInt($el.attr('data-row'), 10), - 'size_x': parseInt($el.attr('data-sizex'), 10), - 'size_y': parseInt($el.attr('data-sizey'), 10), - 'el': $el - }; - - if (this.options.avoid_overlapped_widgets && - !this.can_move_to( - {size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row) - ) { - wgd = this.next_position(wgd.size_x, wgd.size_y); - wgd.el = $el; - $el.attr({ - 'data-col': wgd.col, - 'data-row': wgd.row, - 'data-sizex': wgd.size_x, - 'data-sizey': wgd.size_y - }); - } - - // attach Coord object to player data-coord attribute - $el.data('coords', $el.coords()); - - // Extend Coord object with grid position info - $el.data('coords').grid = wgd; - - this.add_to_gridmap(wgd, $el); - this.widgets.push($el); - return this; - }; - - - /** - * Update in the mapped array of positions the value of cells represented by - * the grid coords object passed in the `grid_data` param. - * - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value Pass `false` or the jQuery wrapped - * HTMLElement, depends if you want to delete an existing position or add - * a new one. - * @method update_widget_position - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.update_widget_position = function(grid_data, value) { - this.for_each_cell_occupied(grid_data, function(col, row) { - if (!this.gridmap[col]) { return this; } - this.gridmap[col][row] = value; - }); - return this; - }; - - - /** - * Remove a widget from the mapped array of positions. - * - * @method remove_from_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_from_gridmap = function(grid_data) { - return this.update_widget_position(grid_data, false); - }; - - - /** - * Add a widget to the mapped array of positions. - * - * @method add_to_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value The value to set in the specified - * position . - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.add_to_gridmap = function(grid_data, value) { - this.update_widget_position(grid_data, value || grid_data.el); - - if (grid_data.el) { - var $widgets = this.widgets_below(grid_data.el); - $widgets.each($.proxy(function(i, widget) { - this.move_widget_up( $(widget)); - }, this)); - } - }; - - - /** - * Make widgets draggable. - * - * @uses Draggable - * @method draggable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.draggable = function() { - var self = this; - var draggable_options = $.extend(true, {}, this.options.draggable, { - offset_left: this.options.widget_margins[0], - items: '.gs_w', - start: function(event, ui) { - self.$widgets.filter('.player-revert') - .removeClass('player-revert'); - - self.$player = $(this); - self.$helper = self.options.draggable.helper === 'clone' ? - $(ui.helper) : self.$player; - self.helper = !self.$helper.is(self.$player); - - self.on_start_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstart'); - }, - stop: function(event, ui) { - self.on_stop_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstop'); - }, - drag: throttle(function(event, ui) { - self.on_drag.call(self, event, ui); - self.$el.trigger('gridster:drag'); - }, 60) - }); - - this.drag_api = this.$el.drag(draggable_options).data('drag'); - return this; - }; - - - /** - * This function is executed when the player begins to be dragged. - * - * @method on_start_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_start_drag = function(event, ui) { - - this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging'); - - this.$player.addClass('player'); - this.player_grid_data = this.$player.coords().grid; - this.placeholder_grid_data = $.extend({}, this.player_grid_data); - - //set new grid height along the dragging period - this.$el.css('height', this.$el.height() + - (this.player_grid_data.size_y * this.min_widget_height)); - - var colliders = this.faux_grid; - var coords = this.$player.data('coords').coords; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.last_cols = []; - this.last_rows = []; - - - // see jquery.collision.js - this.collision_api = this.$helper.collision( - colliders, this.options.collision); - - this.$preview_holder = $('
  • ', { - 'class': 'preview-holder', - 'data-row': this.$player.attr('data-row'), - 'data-col': this.$player.attr('data-col'), - css: { - width: coords.width, - height: coords.height - } - }).appendTo(this.$el); - - if (this.options.draggable.start) { - this.options.draggable.start.call(this, event, ui); - } - }; - - - /** - * This function is executed when the player is being dragged. - * - * @method on_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_drag = function(event, ui) { - //break if dragstop has been fired - if (this.$player === null) { - return false; - }; - - var abs_offset = { - left: ui.position.left + this.baseX, - top: ui.position.top + this.baseY - }; - - this.colliders_data = this.collision_api.get_closest_colliders( - abs_offset); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, - this.on_stop_overlapping_column - ); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, - this.on_stop_overlapping_row - ); - - if (this.helper && this.$player) { - this.$player.css({ - 'left': ui.position.left, - 'top': ui.position.top - }); - } - - if (this.options.draggable.drag) { - this.options.draggable.drag.call(this, event, ui); - } - }; - - /** - * This function is executed when the player stops being dragged. - * - * @method on_stop_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_stop_drag = function(event, ui) { - this.$helper.add(this.$player).add(this.$wrapper) - .removeClass('dragging'); - - ui.position.left = ui.position.left + this.baseX; - ui.position.top = ui.position.top + this.baseY; - this.colliders_data = this.collision_api.get_closest_colliders(ui.position); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, - this.on_stop_overlapping_column - ); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, - this.on_stop_overlapping_row - ); - - this.$player.addClass('player-revert').removeClass('player') - .attr({ - 'data-col': this.placeholder_grid_data.col, - 'data-row': this.placeholder_grid_data.row - }).css({ - 'left': '', - 'top': '' - }); - - this.$changed = this.$changed.add(this.$player); - - this.cells_occupied_by_player = this.get_cells_occupied( - this.placeholder_grid_data); - this.set_cells_player_occupies( - this.placeholder_grid_data.col, this.placeholder_grid_data.row); - - this.$player.coords().grid.row = this.placeholder_grid_data.row; - this.$player.coords().grid.col = this.placeholder_grid_data.col; - - if (this.options.draggable.stop) { - this.options.draggable.stop.call(this, event, ui); - } - - this.$preview_holder.remove(); - this.$player = null; - - this.set_dom_grid_height(); - }; - - - /** - * Executes the callbacks passed as arguments when a column begins to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new column - * begins to be overlapped. The column is passed as first argument. - * @param {Function} stop_callback Function executed when a column stops - * being overlapped. The column is passed as first argument. - * @method on_overlapped_column_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_column_change = function(start_callback, stop_callback) { - if (!this.colliders_data.length) { - return; - } - var cols = this.get_targeted_columns( - this.colliders_data[0].el.data.col); - - var last_n_cols = this.last_cols.length; - var n_cols = cols.length; - var i; - - for (i = 0; i < n_cols; i++) { - if ($.inArray(cols[i], this.last_cols) === -1) { - (start_callback || $.noop).call(this, cols[i]); - } - } - - for (i = 0; i< last_n_cols; i++) { - if ($.inArray(this.last_cols[i], cols) === -1) { - (stop_callback || $.noop).call(this, this.last_cols[i]); - } - } - - this.last_cols = cols; - - return this; - }; - - - /** - * Executes the callbacks passed as arguments when a row starts to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new row begins - * to be overlapped. The row is passed as first argument. - * @param {Function} stop_callback Function executed when a row stops being - * overlapped. The row is passed as first argument. - * @method on_overlapped_row_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_row_change = function(start_callback, end_callback) { - if (!this.colliders_data.length) { - return; - } - var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); - var last_n_rows = this.last_rows.length; - var n_rows = rows.length; - var i; - - for (i = 0; i < n_rows; i++) { - if ($.inArray(rows[i], this.last_rows) === -1) { - (start_callback || $.noop).call(this, rows[i]); - } - } - - for (i = 0; i < last_n_rows; i++) { - if ($.inArray(this.last_rows[i], rows) === -1) { - (end_callback || $.noop).call(this, this.last_rows[i]); - } - } - - this.last_rows = rows; - }; - - - /** - * Sets the current position of the player - * - * @param {Function} start_callback Function executed when a new row begins - * to be overlapped. The row is passed as first argument. - * @param {Function} stop_callback Function executed when a row stops being - * overlapped. The row is passed as first argument. - * @method set_player - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_player = function(col, row) { - this.empty_cells_player_occupies(); - - var self = this; - var cell = self.colliders_data[0].el.data; - var to_col = cell.col; - var to_row = row || cell.row; - - this.player_grid_data = { - col: to_col, - row: to_row, - size_y : this.player_grid_data.size_y, - size_x : this.player_grid_data.size_x - }; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - - var $overlapped_widgets = this.get_widgets_overlapped( - this.player_grid_data); - - var constraints = this.widgets_constraints($overlapped_widgets); - - this.manage_movements(constraints.can_go_up, to_col, to_row); - this.manage_movements(constraints.can_not_go_up, to_col, to_row); - - /* if there is not widgets overlapping in the new player position, - * update the new placeholder position. */ - if (!$overlapped_widgets.length) { - var pp = this.can_go_player_up(this.player_grid_data); - if (pp !== false) { - to_row = pp; - } - this.set_placeholder(to_col, to_row); - } - - return { - col: to_col, - row: to_row - }; - }; - - - /** - * See which of the widgets in the $widgets param collection can go to - * a upper row and which not. - * - * @method widgets_contraints - * @param {HTMLElements} $widgets A jQuery wrapped collection of - * HTMLElements. - * @return {Array} Returns a literal Object with two keys: `can_go_up` & - * `can_not_go_up`. Each contains a set of HTMLElements. - */ - fn.widgets_constraints = function($widgets) { - var $widgets_can_go_up = $([]); - var $widgets_can_not_go_up; - var wgd_can_go_up = []; - var wgd_can_not_go_up = []; - - $widgets.each($.proxy(function(i, w) { - var $w = $(w); - var wgd = $w.coords().grid; - if (this.can_go_widget_up(wgd)) { - $widgets_can_go_up = $widgets_can_go_up.add($w); - wgd_can_go_up.push(wgd); - }else{ - wgd_can_not_go_up.push(wgd); - } - }, this)); - - $widgets_can_not_go_up = $widgets.not($widgets_can_go_up); - - return { - can_go_up: this.sort_by_row_asc(wgd_can_go_up), - can_not_go_up: this.sort_by_row_desc(wgd_can_not_go_up) - }; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in ascending way. - * - * @method sort_by_row_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row > b.row) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) placing first the empty cells upper left. - * - * @method sort_by_row_and_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_and_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row > b.row || a.row == b.row && a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects by column (representing the grid - * coords of each widget) in ascending way. - * - * @method sort_by_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - * - * @method sort_by_row_desc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_desc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row + a.size_y < b.row + b.size_y) { - return 1; - } - return -1; - }); - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - * - * @method manage_movements - * @param {HTMLElements} $widgets A jQuery collection of HTMLElements - * representing the widgets you want to move. - * @param {Number} to_col The column to which we want to move the widgets. - * @param {Number} to_row The row to which we want to move the widgets. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.manage_movements = function($widgets, to_col, to_row) { - $.each($widgets, $.proxy(function(i, w) { - var wgd = w; - var $w = wgd.el; - - var can_go_widget_up = this.can_go_widget_up(wgd); - - if (can_go_widget_up) { - //target CAN go up - //so move widget up - this.move_widget_to($w, can_go_widget_up); - this.set_placeholder(to_col, can_go_widget_up + wgd.size_y); - - } else { - //target can't go up - var can_go_player_up = this.can_go_player_up( - this.player_grid_data); - - if (!can_go_player_up) { - // target can't go up - // player cant't go up - // so we need to move widget down to a position that dont - // overlaps player - var y = (to_row + this.player_grid_data.size_y) - wgd.row; - - this.move_widget_down($w, y); - this.set_placeholder(to_col, to_row); - } - } - }, this)); - - return this; - }; - - /** - * Determines if there is a widget in the row and col given. Or if the - * HTMLElement passed as first argument is the player. - * - * @method is_player - * @param {Number|HTMLElement} col_or_el A jQuery wrapped collection of - * HTMLElements. - * @param {Number} [row] The column to which we want to move the widgets. - * @return {Boolean} Returns true or false. - */ - fn.is_player = function(col_or_el, row) { - if (row && !this.gridmap[col_or_el]) { return false; } - var $w = row ? this.gridmap[col_or_el][row] : col_or_el; - return $w && ($w.is(this.$player) || $w.is(this.$helper)); - }; - - - /** - * Determines if the widget that is being dragged is currently over the row - * and col given. - * - * @method is_player_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_player_in = function(col, row) { - var c = this.cells_occupied_by_player || {}; - return $.inArray(col, c.cols) >= 0 && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the row and col given. - * - * @method is_placeholder_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in = function(col, row) { - var c = this.cells_occupied_by_placeholder || {}; - return this.is_placeholder_in_col(col) && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the column given. - * - * @method is_placeholder_in_col - * @param {Number} col The column to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in_col = function(col) { - var c = this.cells_occupied_by_placeholder || []; - return $.inArray(col, c.cols) >= 0; - }; - - - /** - * Determines if the cell represented by col and row params is empty. - * - * @method is_empty - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_empty = function(col, row) { - if (typeof this.gridmap[col] !== 'undefined' && - typeof this.gridmap[col][row] !== 'undefined' && - this.gridmap[col][row] === false - ) { - return true; - } - return false; - }; - - - /** - * Determines if the cell represented by col and row params is occupied. - * - * @method is_occupied - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_occupied = function(col, row) { - if (!this.gridmap[col]) { - return false; - } - - if (this.gridmap[col][row]) { - return true; - } - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row params. - * - * @method is_widget - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean|HTMLElement} Returns false if there is no widget, - * else returns the jQuery HTMLElement - */ - fn.is_widget = function(col, row) { - var cell = this.gridmap[col]; - if (!cell) { - return false; - } - - cell = cell[row]; - - if (cell) { - return cell; - } - - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row - * params and if this is under the widget that is being dragged. - * - * @method is_widget_under_player - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_widget_under_player = function(col, row) { - if (this.is_widget(col, row)) { - return this.is_player_in(col, row); - } - return false; - }; - - - /** - * Get widgets overlapping with the player. - * - * @method get_widgets_under_player - * @return {HTMLElement} Returns a jQuery collection of HTMLElements - */ - fn.get_widgets_under_player = function() { - var cells = this.cells_occupied_by_player; - var $widgets = $([]); - - $.each(cells.cols, $.proxy(function(i, col) { - $.each(cells.rows, $.proxy(function(i, row) { - if(this.is_widget(col, row)) { - $widgets = $widgets.add(this.gridmap[col][row]); - } - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * Put placeholder at the row and column specified. - * - * @method set_placeholder - * @param {Number} col The column to which we want to move the - * placeholder. - * @param {Number} row The row to which we want to move the - * placeholder. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_placeholder = function(col, row) { - var phgd = $.extend({}, this.placeholder_grid_data); - var $nexts = this.widgets_below({ - col: phgd.col, - row: phgd.row, - size_y: phgd.size_y, - size_x: phgd.size_x - }); - - //Prevents widgets go out of the grid - var right_col = (col + phgd.size_x - 1); - if (right_col > this.cols) { - col = col - (right_col - col); - } - - var moved_down = this.placeholder_grid_data.row < row; - var changed_column = this.placeholder_grid_data.col !== col; - - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.$preview_holder.attr({ - 'data-row' : row, - 'data-col' : col - }); - - if (moved_down || changed_column) { - $nexts.each($.proxy(function(i, widget) { - this.move_widget_up( - $(widget), this.placeholder_grid_data.col - col + phgd.size_y); - }, this)); - } - - }; - - - /** - * Determines whether the player can move to a position above. - * - * @method can_go_player_up - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @return {Number|Boolean} If the player can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_player_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - var $widgets_under_player = this.get_widgets_under_player(); - - /* generate an array with columns as index and array with upper rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - var r = p_bottom_row + 1; - upper_rows[tcol] = []; - - while (--r > 0) { - if (this.is_empty(tcol, r) || this.is_player(tcol, r) || - this.is_widget(tcol, r) && - grid_col[r].is($widgets_under_player) - ) { - upper_rows[tcol].push(r); - min_row = r < min_row ? r : min_row; - }else{ - break; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Determines whether a widget can move to a position above. - * - * @method can_go_widget_up - * @param {Object} widget_grid_data The actual grid coords object of the - * widget we want to check. - * @return {Number|Boolean} If the widget can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_widget_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - - if (widget_grid_data.col < this.player_grid_data.col && - (widget_grid_data.col + widget_grid_data.size_y - 1) > - (this.player_grid_data.col + this.player_grid_data.size_y - 1) - ) { - return false; - }; - - /* generate an array with columns as index and array with upper rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - upper_rows[tcol] = []; - - var r = p_bottom_row + 1; - - while (--r > 0) { - if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) { - if (!grid_col[r].is(widget_grid_data.el)) { - break; - }; - } - - if (!this.is_player(tcol, r) && - !this.is_placeholder_in(tcol, r) && - !this.is_player_in(tcol, r)) { - upper_rows[tcol].push(r); - }; - - if (r < min_row) { - min_row = r; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Search a valid row for the widget represented by `widget_grid_data' in - * the `upper_rows` array. Iteration starts from row specified in `min_row`. - * - * @method get_valid_rows - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @param {Array} upper_rows An array with columns as index and arrays - * of valid rows as values. - * @param {Number} min_row The upper row from which the iteration will start. - * @return {Number|Boolean} Returns the upper row valid from the `upper_rows` - * for the widget in question. - */ - fn.get_valid_rows = function(widget_grid_data, upper_rows, min_row) { - var p_top_row = widget_grid_data.row; - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var size_y = widget_grid_data.size_y; - var r = min_row - 1; - var valid_rows = []; - - while (++r <= p_bottom_row ) { - var common = true; - $.each(upper_rows, function(col, rows) { - if ($.isArray(rows) && $.inArray(r, rows) === -1) { - common = false; - } - }); - - if (common === true) { - valid_rows.push(r); - if (valid_rows.length === size_y) { - break; - } - } - } - - var new_row = false; - if (size_y === 1) { - if (valid_rows[0] !== p_top_row) { - new_row = valid_rows[0] || false; - } - }else{ - if (valid_rows[0] !== p_top_row) { - new_row = this.get_consecutive_numbers_index( - valid_rows, size_y); - } - } - - return new_row; - }; - - - fn.get_consecutive_numbers_index = function(arr, size_y) { - var max = arr.length; - var result = []; - var first = true; - var prev = -1; // or null? - - for (var i=0; i < max; i++) { - if (first || arr[i] === prev + 1) { - result.push(i); - if (result.length === size_y) { - break; - } - first = false; - }else{ - result = []; - first = true; - } - - prev = arr[i]; - } - - return result.length >= size_y ? arr[result[0]] : false; - }; - - - /** - * Get widgets overlapping with the player. - * - * @method get_widgets_overlapped - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.get_widgets_overlapped = function() { - var $w; - var $widgets = $([]); - var used = []; - var rows_from_bottom = this.cells_occupied_by_player.rows.slice(0); - rows_from_bottom.reverse(); - - $.each(this.cells_occupied_by_player.cols, $.proxy(function(i, col) { - $.each(rows_from_bottom, $.proxy(function(i, row) { - // if there is a widget in the player position - if (!this.gridmap[col]) { return true; } //next iteration - var $w = this.gridmap[col][row]; - - if (this.is_occupied(col, row) && !this.is_player($w) && - $.inArray($w, used) === -1 - ) { - $widgets = $widgets.add($w); - used.push($w); - } - - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * This callback is executed when the player begins to collide with a column. - * - * @method on_start_overlapping_column - * @param {Number} col The collided column. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_column = function(col) { - this.set_player(col, false); - }; - - - /** - * A callback executed when the player begins to collide with a row. - * - * @method on_start_overlapping_row - * @param {Number} col The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_row = function(row) { - this.set_player(false, row); - }; - - - /** - * A callback executed when the the player ends to collide with a column. - * - * @method on_stop_overlapping_column - * @param {Number} col The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_column = function(col) { - this.set_player(col, false); - - var self = this; - this.for_each_widget_below(col, this.cells_occupied_by_player.rows[0], - function(tcol, trow) { - self.move_widget_up(this, self.player_grid_data.size_y); - }); - }; - - - /** - * This callback is executed when the player ends to collide with a row. - * - * @method on_stop_overlapping_row - * @param {Number} row The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_row = function(row) { - this.set_player(false, row); - - var self = this; - var cols = this.cells_occupied_by_player.cols; - for (var c = 0, cl = cols.length; c < cl; c++) { - this.for_each_widget_below(cols[c], row, function(tcol, trow) { - self.move_widget_up(this, self.player_grid_data.size_y); - }); - } - }; - - - /** - * Move a widget to a specific row. The cell or cells must be empty. - * If the widget has widgets below, all of these widgets will be moved also - * if they can. - * - * @method move_widget_to - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement of the - * widget is going to be moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_to = function($widget, row) { - var self = this; - var widget_grid_data = $widget.coords().grid; - var diff = row - widget_grid_data.row; - var $next_widgets = this.widgets_below($widget); - - var can_move_to_new_cell = this.can_move_to( - widget_grid_data, widget_grid_data.col, row, $widget); - - if (can_move_to_new_cell === false) { - return false; - } - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', row); - this.$changed = this.$changed.add($widget); - - - $next_widgets.each(function(i, widget) { - var $w = $(widget); - var wgd = $w.coords().grid; - var can_go_up = self.can_go_widget_up(wgd); - if (can_go_up && can_go_up !== wgd.row) { - self.move_widget_to($w, can_go_up); - } - }); - - return this; - }; - - - /** - * Move up the specified widget and all below it. - * - * @method move_widget_up - * @param {HTMLElement} $widget The widget you want to move. - * @param {Number} [y_units] The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_up = function($widget, y_units) { - var el_grid_data = $widget.coords().grid; - var actual_row = el_grid_data.row; - var moved = []; - var can_go_up = true; - y_units || (y_units = 1); - - if (!this.can_go_up($widget)) { return false; } //break; - - this.for_each_column_occupied(el_grid_data, function(col) { - // can_go_up - if ($.inArray($widget, moved) === -1) { - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row - y_units; - next_row = this.can_go_up_to_row( - widget_grid_data, col, next_row); - - if (!next_row) { - return true; - } - - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = next_row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - - $next_widgets.each($.proxy(function(i, widget) { - this.move_widget_up($(widget), y_units); - }, this)); - } - }); - - }; - - - /** - * Move down the specified widget and all below it. - * - * @method move_widget_down - * @param {HTMLElement} $widget The jQuery object representing the widget - * you want to move. - * @param {Number} The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_down = function($widget, y_units) { - var el_grid_data = $widget.coords().grid; - var actual_row = el_grid_data.row; - var moved = []; - var y_diff = y_units; - - if (!$widget) { return false; } - - if ($.inArray($widget, moved) === -1) { - - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row + y_units; - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - - $next_widgets.each($.proxy(function(i, widget) { - var $w = $(widget); - var wd = $w.coords().grid; - var tmp_y = this.displacement_diff( - wd, widget_grid_data, y_diff); - - if (tmp_y > 0) { - this.move_widget_down($w, tmp_y); - } - }, this)); - - widget_grid_data.row = next_row; - this.update_widget_position(widget_grid_data, $widget); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - } - }; - - - /** - * Check if the widget can move to the specified row, else returns the - * upper row possible. - * - * @method can_go_up_to_row - * @param {Number} widget_grid_data The current grid coords object of the - * widget. - * @param {Number} col The target column. - * @param {Number} row The target row. - * @return {Boolean|Number} Returns the row number if the widget can move - * to the target position, else returns false. - */ - fn.can_go_up_to_row = function(widget_grid_data, col, row) { - var ga = this.gridmap; - var result = true; - var urc = []; // upper_rows_in_columns - var actual_row = widget_grid_data.row; - var r; - - /* generate an array with columns as index and array with - * upper rows empty in the column */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = ga[tcol]; - urc[tcol] = []; - - r = actual_row; - while (r--) { - if (this.is_empty(tcol, r) && - !this.is_placeholder_in(tcol, r) - ) { - urc[tcol].push(r); - }else{ - break; - } - } - - if (!urc[tcol].length) { - result = false; - return true; - } - - }); - - if (!result) { return false; } - - /* get common rows starting from upper position in all the columns - * that widget occupies */ - r = row; - for (r = 1; r < actual_row; r++) { - var common = true; - - for (var uc = 0, ucl = urc.length; uc < ucl; uc++) { - if (urc[uc] && $.inArray(r, urc[uc]) === -1) { - common = false; - } - } - - if (common === true) { - result = r; - break; - } - } - - return result; - }; - - - fn.displacement_diff = function(widget_grid_data, parent_bgd, y_units) { - var actual_row = widget_grid_data.row; - var diffs = []; - var parent_max_y = parent_bgd.row + parent_bgd.size_y; - - this.for_each_column_occupied(widget_grid_data, function(col) { - var temp_y_units = 0; - - for (var r = parent_max_y; r < actual_row; r++) { - if (this.is_empty(col, r)) { - temp_y_units = temp_y_units + 1; - } - } - - diffs.push(temp_y_units); - }); - - var max_diff = Math.max.apply(Math, diffs); - y_units = (y_units - max_diff); - - return y_units > 0 ? y_units : 0; - }; - - - /** - * Get widgets below a widget. - * - * @method widgets_below - * @param {HTMLElement} $el The jQuery wrapped HTMLElement. - * @return {HTMLElements} A jQuery collection of HTMLElements. - */ - fn.widgets_below = function($el) { - var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; - var self = this; - var ga = this.gridmap; - var next_row = el_grid_data.row + el_grid_data.size_y - 1; - var $nexts = $([]); - - this.for_each_column_occupied(el_grid_data, function(col) { - self.for_each_widget_below(col, next_row, - function(tcol, trow) { - if (!self.is_player(this) && - $.inArray(this, $nexts) === -1) { - $nexts = $nexts.add(this); - return true; // break - } - }); - }); - - return this.sort_by_row_asc($nexts); - }; - - - /** - * Update the array of mapped positions with the new player position. - * - * @method set_cells_player_occupies - * @param {Number} col The new player col. - * @param {Number} col The new player row. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_cells_player_occupies = function(col, row) { - this.remove_from_gridmap(this.placeholder_grid_data); - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - this.add_to_gridmap(this.placeholder_grid_data, this.$player); - return this; - }; - - - /** - * Remove from the array of mapped positions the reference to the player. - * - * @method empty_cells_player_occupies - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.empty_cells_player_occupies = function() { - this.remove_from_gridmap(this.placeholder_grid_data); - return this; - }; - - - fn.can_go_up = function($el) { - var el_grid_data = $el.coords().grid; - var initial_row = el_grid_data.row; - var prev_row = initial_row - 1; - var ga = this.gridmap; - var upper_rows_by_column = []; - - var result = true; - if (initial_row === 1) { return false; } - - this.for_each_column_occupied(el_grid_data, function(col) { - var $w = this.is_widget(col, prev_row); - if (this.is_occupied(col, prev_row) || - this.is_player(col, prev_row) || - this.is_placeholder_in(col, prev_row) || - this.is_player_in(col, prev_row) - ) { - result = false; - return true; //break - } - }); - - return result; - }; - - - - /** - * Check if it's possible to move a widget to a specific col/row. It takes - * into account the dimensions (`size_y` and `size_x` attrs. of the grid - * coords object) the widget occupies. - * - * @method can_move_to - * @param {Object} widget_grid_data The grid coords object that represents - * the widget. - * @param {Object} col The col to check. - * @param {Object} row The row to check. - * @return {Boolean} Returns true if all cells are empty, else return false. - */ - fn.can_move_to = function(widget_grid_data, col, row) { - var ga = this.gridmap; - var $w = widget_grid_data.el; - var future_wd = { - size_y: widget_grid_data.size_y, - size_x: widget_grid_data.size_x, - col: col, - row: row - }; - var result = true; - - //Prevents widgets go out of the grid - var right_col = col + widget_grid_data.size_x - 1; - if (right_col > this.cols) { - return false; - }; - - this.for_each_cell_occupied(future_wd, function(tcol, trow) { - var $tw = this.is_widget(tcol, trow); - if ($tw && (!widget_grid_data.el || $tw.is($w))) { - result = false; - } - }); - - return result; - }; - - - /** - * Given the leftmost column returns all columns that are overlapping - * with the player. - * - * @method get_targeted_columns - * @param {Number} [from_col] The leftmost column. - * @return {Array} Returns an array with column numbers. - */ - fn.get_targeted_columns = function(from_col) { - var max = (from_col || this.player_grid_data.col) + - (this.player_grid_data.size_x - 1); - var cols = []; - for (var col = from_col; col <= max; col++) { - cols.push(col); - } - return cols; - }; - - - /** - * Given the upper row returns all rows that are overlapping with the player. - * - * @method get_targeted_rows - * @param {Number} [from_row] The upper row. - * @return {Array} Returns an array with row numbers. - */ - fn.get_targeted_rows = function(from_row) { - var max = (from_row || this.player_grid_data.row) + - (this.player_grid_data.size_y - 1); - var rows = []; - for (var row = from_row; row <= max; row++) { - rows.push(row); - } - return rows; - }; - - /** - * Get all columns and rows that a widget occupies. - * - * @method get_cells_occupied - * @param {Object} el_grid_data The grid coords object of the widget. - * @return {Object} Returns an object like `{ cols: [], rows: []}`. - */ - fn.get_cells_occupied = function(el_grid_data) { - var cells = { cols: [], rows: []}; - var i; - if (arguments[1] instanceof jQuery) { - el_grid_data = arguments[1].coords().grid; - } - - for (i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - cells.cols.push(col); - } - - for (i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - cells.rows.push(row); - } - - return cells; - }; - - - /** - * Iterate over the cells occupied by a widget executing a function for - * each one. - * - * @method for_each_cell_occupied - * @param {Object} el_grid_data The grid coords object that represents the - * widget. - * @param {Function} callback The function to execute on each column - * iteration. Column and row are passed as arguments. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_cell_occupied = function(grid_data, callback) { - this.for_each_column_occupied(grid_data, function(col) { - this.for_each_row_occupied(grid_data, function(row) { - callback.call(this, col, row); - }); - }); - return this; - }; - - - /** - * Iterate over the columns occupied by a widget executing a function for - * each one. - * - * @method for_each_column_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The column number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_column_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - callback.call(this, col, el_grid_data); - } - }; - - - /** - * Iterate over the rows occupied by a widget executing a function for - * each one. - * - * @method for_each_row_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The row number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_row_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - callback.call(this, row, el_grid_data); - } - }; - - - - fn._traversing_widgets = function(type, direction, col, row, callback) { - var ga = this.gridmap; - if (!ga[col]) { return; } - - var cr, max; - var action = type + '/' + direction; - if (arguments[2] instanceof jQuery) { - var el_grid_data = arguments[2].coords().grid; - col = el_grid_data.col; - row = el_grid_data.row; - callback = arguments[3]; - } - var matched = []; - var trow = row; - - - var methods = { - 'for_each/above': function() { - while (trow--) { - if (trow > 0 && this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - if (cr) { break; } - } - } - }, - 'for_each/below': function() { - for (trow = row + 1, max = ga[col].length; trow < max; trow++) { - if (this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - if (cr) { break; } - } - } - } - }; - - if (methods[action]) { - methods[action].call(this); - } - }; - - - /** - * Iterate over each widget above the column and row specified. - * - * @method for_each_widget_above - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery - * wrapped HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_above = function(col, row, callback) { - this._traversing_widgets('for_each', 'above', col, row, callback); - return this; - }; - - - /** - * Iterate over each widget below the column and row specified. - * - * @method for_each_widget_below - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery wrapped - * HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_below = function(col, row, callback) { - this._traversing_widgets('for_each', 'below', col, row, callback); - return this; - }; - - - /** - * Returns the highest occupied cell in the grid. - * - * @method get_highest_occupied_cell - * @return {Object} Returns an object with `col` and `row` numbers. - */ - fn.get_highest_occupied_cell = function() { - var r; - var gm = this.gridmap; - var rows = []; - var row_in_col = []; - for (var c = gm.length - 1; c >= 1; c--) { - for (r = gm[c].length - 1; r >= 1; r--) { - if (this.is_widget(c, r)) { - rows.push(r); - row_in_col[r] = c; - break; - } - } - } - - var highest_row = Math.max.apply(Math, rows); - - this.highest_occupied_cell = { - col: row_in_col[highest_row], - row: highest_row - }; - - return this.highest_occupied_cell; - }; - - - fn.get_widgets_from = function(col, row) { - var ga = this.gridmap; - var $widgets = $(); - - if (col) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var tcol = $(this).attr('data-col'); - return (tcol === col || tcol > col); - }) - ); - } - - if (row) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var trow = $(this).attr('data-row'); - return (trow === row || trow > row); - }) - ); - } - - return $widgets; - } - - - /** - * Set the current height of the parent grid. - * - * @method set_dom_grid_height - * @return {Object} Returns the instance of the Gridster class. - */ - fn.set_dom_grid_height = function() { - var r = this.get_highest_occupied_cell().row; - this.$el.css('height', r * this.min_widget_height); - return this; - }; - - - /** - * It generates the neccessary styles to position the widgets. - * - * @method generate_stylesheet - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_stylesheet = function(opts) { - var styles = ''; - var extra_cells = 10; - var max_size_y = this.options.max_size_y; - var max_size_x = this.options.max_size_x; - var i; - var rules; - - opts || (opts = {}); - opts.cols || (opts.cols = this.cols); - opts.rows || (opts.rows = this.rows); - opts.namespace || (opts.namespace = ''); - opts.widget_base_dimensions || - (opts.widget_base_dimensions = this.options.widget_base_dimensions); - opts.widget_margins || - (opts.widget_margins = this.options.widget_margins); - opts.min_widget_width = (opts.widget_margins[0] * 2) + - opts.widget_base_dimensions[0]; - opts.min_widget_height = (opts.widget_margins[1] * 2) + - opts.widget_base_dimensions[1]; - - var serialized_opts = $.param(opts); - // don't duplicate stylesheets for the same configuration - if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) { - return false; - } - - Gridster.generated_stylesheets.push(serialized_opts); - - /* generate CSS styles for cols */ - for (i = opts.cols + extra_cells; i >= 0; i--) { - styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' + - ((i * opts.widget_base_dimensions[0]) + - (i * opts.widget_margins[0]) + - ((i + 1) * opts.widget_margins[0])) + 'px;} '); - } - - /* generate CSS styles for rows */ - for (i = opts.rows + extra_cells; i >= 0; i--) { - styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' + - ((i * opts.widget_base_dimensions[1]) + - (i * opts.widget_margins[1]) + - ((i + 1) * opts.widget_margins[1]) ) + 'px;} '); - } - - for (var y = 1; y <= max_size_y; y++) { - styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' + - (y * opts.widget_base_dimensions[1] + - (y - 1) * (opts.widget_margins[1] * 2)) + 'px;}'); - } - - for (var x = 1; x <= max_size_x; x++) { - styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' + - (x * opts.widget_base_dimensions[0] + - (x - 1) * (opts.widget_margins[0] * 2)) + 'px;}'); - } - - return this.add_style_tag(styles); - }; - - - /** - * Injects the given CSS as string to the head of the document. - * - * @method add_style_tag - * @param {String} css The styles to apply. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_style_tag = function(css) { - var d = document; - var tag = d.createElement('style'); - - d.getElementsByTagName('head')[0].appendChild(tag); - tag.setAttribute('type', 'text/css'); - - if (tag.styleSheet) { - tag.styleSheet.cssText = css; - }else{ - tag.appendChild(document.createTextNode(css)); - } - return this; - }; - - - /** - * Generates a faux grid to collide with it when a widget is dragged and - * detect row or column that we want to go. - * - * @method generate_faux_grid - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_faux_grid = function(rows, cols) { - this.faux_grid = []; - this.gridmap = []; - var col; - var row; - for (col = cols; col > 0; col--) { - this.gridmap[col] = []; - for (row = rows; row > 0; row--) { - var coords = $({ - left: this.baseX + ((col - 1) * this.min_widget_width), - top: this.baseY + (row -1) * this.min_widget_height, - width: this.min_widget_width, - height: this.min_widget_height, - col: col, - row: row, - original_col: col, - original_row: row - }).coords(); - - this.gridmap[col][row] = false; - this.faux_grid.push(coords); - } - } - return this; - }; - - - /** - * Recalculates the offsets for the faux grid. You need to use it when - * the browser is resized. - * - * @method recalculate_faux_grid - * @return {Object} Returns the instance of the Gridster class. - */ - fn.recalculate_faux_grid = function() { - var aw = this.$wrapper.width(); - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - $.each(this.faux_grid, $.proxy(function(i, coords) { - this.faux_grid[i] = coords.update({ - left: this.baseX + (coords.data.col -1) * this.min_widget_width, - top: this.baseY + (coords.data.row -1) * this.min_widget_height - }); - - }, this)); - - return this; - }; - - - /** - * Get all widgets in the DOM and register them. - * - * @method get_widgets_from_DOM - * @return {Object} Returns the instance of the Gridster class. - */ - fn.get_widgets_from_DOM = function() { - this.$widgets.each($.proxy(function(i, widget) { - this.register_widget($(widget)); - }, this)); - return this; - }; - - - /** - * Calculate columns and rows to be set based on the configuration - * parameters, grid dimensions, etc ... - * - * @method generate_grid_and_stylesheet - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_grid_and_stylesheet = function() { - var aw = this.$wrapper.width(); - var ah = this.$wrapper.height(); - - var cols = Math.floor(aw / this.min_widget_width) + - this.options.extra_cols; - var rows = Math.floor(ah / this.min_widget_height) + - this.options.extra_rows; - - var actual_cols = this.$widgets.map(function() { - return $(this).attr('data-col'); - }); - actual_cols = Array.prototype.slice.call(actual_cols, 0); - //needed to pass tests with phantomjs - actual_cols.length || (actual_cols = [0]); - - var actual_rows = this.$widgets.map(function() { - return $(this).attr('data-row'); - }); - actual_rows = Array.prototype.slice.call(actual_rows, 0); - //needed to pass tests with phantomjs - actual_rows.length || (actual_rows = [0]); - - var min_cols = Math.max.apply(Math, actual_cols); - var min_rows = Math.max.apply(Math, actual_rows); - - this.cols = Math.max(min_cols, cols, this.options.min_cols); - this.rows = Math.max(min_rows, rows, this.options.min_rows); - - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - /* more faux rows that needed are created so that there are cells - * where drag beyond the limits */ - return this.generate_faux_grid(this.rows, this.cols); - }; - - - //jQuery adapter - $.fn.gridster = function(options) { - return this.each(function() { - if (!$(this).data('gridster')) { - $(this).data('gridster', new Gridster( this, options )); - } - }); - }; - - -}(jQuery, window, document)); \ No newline at end of file diff --git a/templates/project/assets/javascripts/gridster/jquery.gridster.min.js b/templates/project/assets/javascripts/gridster/jquery.gridster.min.js new file mode 100644 index 00000000..ac34904e --- /dev/null +++ b/templates/project/assets/javascripts/gridster/jquery.gridster.min.js @@ -0,0 +1,2 @@ +/*! gridster.js - v0.5.1 - 2014-03-26 - * http://gridster.net/ - Copyright (c) 2014 ducksboard; Licensed MIT */ (function(t){function i(i){return i[0]&&t.isPlainObject(i[0])?this.data=i[0]:this.el=i,this.isCoords=!0,this.coords={},this.init(),this}var e=i.prototype;e.init=function(){this.set(),this.original_coords=this.get()},e.set=function(t,i){var e=this.el;if(e&&!t&&(this.data=e.offset(),this.data.width=e.width(),this.data.height=e.height()),e&&t&&!i){var s=e.offset();this.data.top=s.top,this.data.left=s.left}var r=this.data;return r.left===undefined&&(r.left=r.x1),r.top===undefined&&(r.top=r.y1),this.coords.x1=r.left,this.coords.y1=r.top,this.coords.x2=r.left+r.width,this.coords.y2=r.top+r.height,this.coords.cx=r.left+r.width/2,this.coords.cy=r.top+r.height/2,this.coords.width=r.width,this.coords.height=r.height,this.coords.el=e||!1,this},e.update=function(i){if(!i&&!this.el)return this;if(i){var e=t.extend({},this.data,i);return this.data=e,this.set(!0,!0)}return this.set(!0),this},e.get=function(){return this.coords},e.destroy=function(){this.el.removeData("coords"),delete this.el},t.fn.coords=function(){if(this.data("coords"))return this.data("coords");var t=new i(this,arguments[0]);return this.data("coords",t),t}})(jQuery,window,document),function(t,i,e){function s(i,e,s){this.options=t.extend(r,s),this.$element=i,this.last_colliders=[],this.last_colliders_coords=[],this.set_colliders(e),this.init()}var r={colliders_context:e.body,overlapping_region:"C"},o=s.prototype;o.init=function(){this.find_collisions()},o.overlaps=function(t,i){var e=!1,s=!1;return(i.x1>=t.x1&&i.x1<=t.x2||i.x2>=t.x1&&i.x2<=t.x2||t.x1>=i.x1&&t.x2<=i.x2)&&(e=!0),(i.y1>=t.y1&&i.y1<=t.y2||i.y2>=t.y1&&i.y2<=t.y2||t.y1>=i.y1&&t.y2<=i.y2)&&(s=!0),e&&s},o.detect_overlapping_region=function(t,i){var e="",s="";return t.y1>i.cy&&t.y1i.y1&&t.y2i.cx&&t.x1i.x1&&t.x2o;o++)-1===t.inArray(r[o],i)&&e.call(this,r[o]);for(var h=0,n=i.length;n>h;h++)-1===t.inArray(i[h],r)&&s.call(this,i[h])},o.find_collisions=function(i){for(var e=this,s=this.options.overlapping_region,r=[],o=[],a=this.colliders||this.$colliders,h=a.length,n=e.$element.coords().update(i||!1).get();h--;){var _=e.$colliders?t(a[h]):a[h],d=_.isCoords?_:_.coords(),l=d.get(),c=e.overlaps(n,l);if(c){var p=e.detect_overlapping_region(n,l);if(p===s||"all"===s){var g=e.calculate_overlapped_area_coords(n,l),u=e.calculate_overlapped_area(g),f={area:u,area_coords:g,region:p,coords:l,player_coords:n,el:_};e.options.on_overlap&&e.options.on_overlap.call(this,f),r.push(d),o.push(f)}}}return(e.options.on_overlap_stop||e.options.on_overlap_start)&&this.manage_colliders_start_stop(r,e.options.on_overlap_start,e.options.on_overlap_stop),this.last_colliders_coords=r,o},o.get_closest_colliders=function(t){var i=this.find_collisions(t);return i.sort(function(t,i){return"C"===t.region&&"C"===i.region?t.coords.y1this.player_max_left?r=this.player_max_left:this.player_min_left>r&&(r=this.player_min_left)),{position:{left:r,top:o},pointer:{left:i.left,top:i.top,diff_left:e+this.scroll_offset_x,diff_top:s+this.scroll_offset_y}}},d.get_drag_data=function(t){var i=this.get_offset(t);return i.$player=this.$player,i.$helper=this.helper?this.$helper:this.$player,i},d.set_limits=function(t){return t||(t=this.$container.width()),this.player_max_left=t-this.player_width+-this.options.offset_left,this.options.container_width=t,this},d.scroll_in=function(i,s){var r,h=a[i],n=50,d=30,l="x"===i,c=l?this.window_width:this.window_height,p=l?t(e).width():t(e).height(),g=l?this.$player.width():this.$player.height(),u=o["scroll"+_(h)](),f=u,w=f+c,m=w-n,y=f+n,v=f+s.pointer[h],z=p-c+g;return v>=m&&(r=u+d,z>r&&(o["scroll"+_(h)](r),this["scroll_offset_"+i]+=d)),y>=v&&(r=u-d,r>0&&(o["scroll"+_(h)](r),this["scroll_offset_"+i]-=d)),this},d.manage_scroll=function(t){this.scroll_in("x",t),this.scroll_in("y",t)},d.calculate_dimensions=function(){this.window_height=o.height(),this.window_width=o.width()},d.drag_handler=function(i){if(i.target.nodeName,!this.disabled&&(1===i.which||h)&&!this.ignore_drag(i)){var e=this,s=!0;return this.$player=t(i.currentTarget),this.el_init_pos=this.get_actual_pos(this.$player),this.mouse_init_pos=this.get_mouse_pos(i),this.offsetY=this.mouse_init_pos.top-this.el_init_pos.top,this.$body.on(n.move,function(t){var i=e.get_mouse_pos(t),r=Math.abs(i.left-e.mouse_init_pos.left),o=Math.abs(i.top-e.mouse_init_pos.top);return r>e.options.distance||o>e.options.distance?s?(s=!1,e.on_dragstart.call(e,t),!1):(e.is_dragging===!0&&e.on_dragmove.call(e,t),!1):!1}),h?undefined:!1}},d.on_dragstart=function(t){if(t.preventDefault(),this.is_dragging)return this;this.drag_start=this.is_dragging=!0;var i=this.$container.offset();return this.baseX=Math.round(i.left),this.baseY=Math.round(i.top),this.initial_container_width=this.options.container_width||this.$container.width(),"clone"===this.options.helper?(this.$helper=this.$player.clone().appendTo(this.$container).addClass("helper"),this.helper=!0):this.helper=!1,this.scroll_offset_y=0,this.scroll_offset_x=0,this.el_init_offset=this.$player.offset(),this.player_width=this.$player.width(),this.player_height=this.$player.height(),this.set_limits(this.options.container_width),this.options.start&&this.options.start.call(this.$player,t,this.get_drag_data(t)),!1},d.on_dragmove=function(t){var i=this.get_drag_data(t);this.options.autoscroll&&this.manage_scroll(i),this.options.move_element&&(this.helper?this.$helper:this.$player).css({position:"absolute",left:i.position.left,top:i.position.top});var e=this.last_position||i.position;return i.prev_position=e,this.options.drag&&this.options.drag.call(this.$player,t,i),this.last_position=i.position,!1},d.on_dragstop=function(t){var i=this.get_drag_data(t);return this.drag_start=!1,this.options.stop&&this.options.stop.call(this.$player,t,i),this.helper&&this.options.remove_helper&&this.$helper.remove(),!1},d.on_select_start=function(t){return this.disabled||this.ignore_drag(t)?undefined:!1},d.enable=function(){this.disabled=!1},d.disable=function(){this.disabled=!0},d.destroy=function(){this.disable(),this.$container.off(".gridster-draggable"),this.$body.off(".gridster-draggable"),t(i).off(".gridster-draggable"),t.removeData(this.$container,"drag")},d.ignore_drag=function(i){return this.options.handle?!t(i.target).is(this.options.handle):t.isFunction(this.options.ignore_dragging)?this.options.ignore_dragging(i):t(i.target).is(this.options.ignore_dragging.join(", "))},t.fn.drag=function(t){return new s(this,t)}}(jQuery,window,document),function(t,i,e){function s(i,e){this.options=t.extend(!0,{},r,e),this.$el=t(i),this.$wrapper=this.$el.parent(),this.$widgets=this.$el.children(this.options.widget_selector).addClass("gs-w"),this.widgets=[],this.$changed=t([]),this.wrapper_width=this.$wrapper.width(),this.min_widget_width=2*this.options.widget_margins[0]+this.options.widget_base_dimensions[0],this.min_widget_height=2*this.options.widget_margins[1]+this.options.widget_base_dimensions[1],this.generated_stylesheets=[],this.$style_tags=t([]),this.init()}var r={namespace:"",widget_selector:"li",widget_margins:[10,10],widget_base_dimensions:[400,225],extra_rows:0,extra_cols:0,min_cols:1,max_cols:1/0,min_rows:15,max_size_x:!1,autogrow_cols:!1,autogenerate_stylesheet:!0,avoid_overlapped_widgets:!0,serialize_params:function(t,i){return{col:i.col,row:i.row,size_x:i.size_x,size_y:i.size_y}},collision:{},draggable:{items:".gs-w",distance:4},resize:{enabled:!1,axes:["both"],handle_append_to:"",handle_class:"gs-resize-handle",max_size:[1/0,1/0],min_size:[1,1]}};s.generated_stylesheets=[];var o=s.prototype;o.init=function(){this.options.resize.enabled&&this.setup_resize(),this.generate_grid_and_stylesheet(),this.get_widgets_from_DOM(),this.set_dom_grid_height(),this.set_dom_grid_width(),this.$wrapper.addClass("ready"),this.draggable(),this.options.resize.enabled&&this.resizable(),t(i).bind("resize.gridster",throttle(t.proxy(this.recalculate_faux_grid,this),200))},o.disable=function(){return this.$wrapper.find(".player-revert").removeClass("player-revert"),this.drag_api.disable(),this},o.enable=function(){return this.drag_api.enable(),this},o.disable_resize=function(){return this.$el.addClass("gs-resize-disabled"),this.resize_api.disable(),this},o.enable_resize=function(){return this.$el.removeClass("gs-resize-disabled"),this.resize_api.enable(),this},o.add_widget=function(i,e,s,r,o,a,h){var n;e||(e=1),s||(s=1),!r&!o?n=this.next_position(e,s):(n={col:r,row:o},this.empty_cells(r,o,e,s));var _=t(i).attr({"data-col":n.col,"data-row":n.row,"data-sizex":e,"data-sizey":s}).addClass("gs-w").appendTo(this.$el).hide();return this.$widgets=this.$widgets.add(_),this.register_widget(_),this.add_faux_rows(n.size_y),a&&this.set_widget_max_size(_,a),h&&this.set_widget_min_size(_,h),this.set_dom_grid_width(),this.set_dom_grid_height(),this.drag_api.set_limits(this.cols*this.min_widget_width),_.fadeIn()},o.set_widget_min_size=function(t,i){if(t="number"==typeof t?this.$widgets.eq(t):t,!t.length)return this;var e=t.data("coords").grid;return e.min_size_x=i[0],e.min_size_y=i[1],this},o.set_widget_max_size=function(t,i){if(t="number"==typeof t?this.$widgets.eq(t):t,!t.length)return this;var e=t.data("coords").grid;return e.max_size_x=i[0],e.max_size_y=i[1],this},o.add_resize_handle=function(i){var e=this.options.resize.handle_append_to;return t(this.resize_handle_tpl).appendTo(e?t(e,i):i),this},o.resize_widget=function(t,i,e,s){var r=t.coords().grid,o=r.col,a=this.options.max_cols,h=r.size_y,n=r.col,_=n;i||(i=r.size_x),e||(e=r.size_y),1/0!==a&&(i=Math.min(i,a-o+1)),e>h&&this.add_faux_rows(Math.max(e-h,0));var d=o+i-1;d>this.cols&&this.add_faux_cols(d-this.cols);var l={col:_,row:r.row,size_x:i,size_y:e};return this.mutate_widget_in_gridmap(t,r,l),this.set_dom_grid_height(),this.set_dom_grid_width(),s&&s.call(this,l.size_x,l.size_y),t},o.mutate_widget_in_gridmap=function(i,e,s){e.size_x;var r=e.size_y,o=this.get_cells_occupied(e),a=this.get_cells_occupied(s),h=[];t.each(o.cols,function(i,e){-1===t.inArray(e,a.cols)&&h.push(e)});var n=[];t.each(a.cols,function(i,e){-1===t.inArray(e,o.cols)&&n.push(e)});var _=[];t.each(o.rows,function(i,e){-1===t.inArray(e,a.rows)&&_.push(e)});var d=[];if(t.each(a.rows,function(i,e){-1===t.inArray(e,o.rows)&&d.push(e)}),this.remove_from_gridmap(e),n.length){var l=[s.col,s.row,s.size_x,Math.min(r,s.size_y),i];this.empty_cells.apply(this,l)}if(d.length){var c=[s.col,s.row,s.size_x,s.size_y,i];this.empty_cells.apply(this,c)}if(e.col=s.col,e.row=s.row,e.size_x=s.size_x,e.size_y=s.size_y,this.add_to_gridmap(s,i),i.removeClass("player-revert"),i.data("coords").update({width:s.size_x*this.options.widget_base_dimensions[0]+2*(s.size_x-1)*this.options.widget_margins[0],height:s.size_y*this.options.widget_base_dimensions[1]+2*(s.size_y-1)*this.options.widget_margins[1]}),i.attr({"data-col":s.col,"data-row":s.row,"data-sizex":s.size_x,"data-sizey":s.size_y}),h.length){var p=[h[0],s.row,h.length,Math.min(r,s.size_y),i];this.remove_empty_cells.apply(this,p)}if(_.length){var g=[s.col,s.row,s.size_x,s.size_y,i];this.remove_empty_cells.apply(this,g)}return this.move_widget_up(i),this},o.empty_cells=function(i,e,s,r,o){var a=this.widgets_below({col:i,row:e-r,size_x:s,size_y:r});return a.not(o).each(t.proxy(function(i,s){var o=t(s).coords().grid;if(e+r-1>=o.row){var a=e+r-o.row;this.move_widget_down(t(s),a)}},this)),this.set_dom_grid_height(),this},o.remove_empty_cells=function(i,e,s,r,o){var a=this.widgets_below({col:i,row:e,size_x:s,size_y:r});return a.not(o).each(t.proxy(function(i,e){this.move_widget_up(t(e),r)},this)),this.set_dom_grid_height(),this},o.next_position=function(t,i){t||(t=1),i||(i=1);for(var e,s=this.gridmap,r=s.length,o=[],a=1;r>a;a++){e=s[a].length;for(var h=1;e>=h;h++){var n=this.can_move_to({size_x:t,size_y:i},a,h);n&&o.push({col:a,row:h,size_y:i,size_x:t})}}return o.length?this.sort_by_row_and_col_asc(o)[0]:!1},o.remove_widget=function(i,e,s){var r=i instanceof t?i:t(i),o=r.coords().grid;t.isFunction(e)&&(s=e,e=!1),this.cells_occupied_by_placeholder={},this.$widgets=this.$widgets.not(r);var a=this.widgets_below(r);return this.remove_from_gridmap(o),r.fadeOut(t.proxy(function(){r.remove(),e||a.each(t.proxy(function(i,e){this.move_widget_up(t(e),o.size_y)},this)),this.set_dom_grid_height(),s&&s.call(this,i)},this)),this},o.remove_all_widgets=function(i){return this.$widgets.each(t.proxy(function(t,e){this.remove_widget(e,!0,i)},this)),this},o.serialize=function(i){i||(i=this.$widgets);var e=[];return i.each(t.proxy(function(i,s){e.push(this.options.serialize_params(t(s),t(s).coords().grid))},this)),e},o.serialize_changed=function(){return this.serialize(this.$changed)},o.register_widget=function(i){var e={col:parseInt(i.attr("data-col"),10),row:parseInt(i.attr("data-row"),10),size_x:parseInt(i.attr("data-sizex"),10),size_y:parseInt(i.attr("data-sizey"),10),max_size_x:parseInt(i.attr("data-max-sizex"),10)||!1,max_size_y:parseInt(i.attr("data-max-sizey"),10)||!1,min_size_x:parseInt(i.attr("data-min-sizex"),10)||!1,min_size_y:parseInt(i.attr("data-min-sizey"),10)||!1,el:i};return this.options.avoid_overlapped_widgets&&!this.can_move_to({size_x:e.size_x,size_y:e.size_y},e.col,e.row)&&(t.extend(e,this.next_position(e.size_x,e.size_y)),i.attr({"data-col":e.col,"data-row":e.row,"data-sizex":e.size_x,"data-sizey":e.size_y})),i.data("coords",i.coords()),i.data("coords").grid=e,this.add_to_gridmap(e,i),this.options.resize.enabled&&this.add_resize_handle(i),this},o.update_widget_position=function(t,i){return this.for_each_cell_occupied(t,function(t,e){return this.gridmap[t]?(this.gridmap[t][e]=i,undefined):this}),this},o.remove_from_gridmap=function(t){return this.update_widget_position(t,!1)},o.add_to_gridmap=function(i,e){if(this.update_widget_position(i,e||i.el),i.el){var s=this.widgets_below(i.el);s.each(t.proxy(function(i,e){this.move_widget_up(t(e))},this))}},o.draggable=function(){var i=this,e=t.extend(!0,{},this.options.draggable,{offset_left:this.options.widget_margins[0],offset_top:this.options.widget_margins[1],container_width:this.cols*this.min_widget_width,limit:!0,ignore_dragging:["INPUT","TEXTAREA","SELECT","BUTTON","."+this.options.resize.handle_class],start:function(e,s){i.$widgets.filter(".player-revert").removeClass("player-revert"),i.$player=t(this),i.$helper=t(s.$helper),i.helper=!i.$helper.is(i.$player),i.on_start_drag.call(i,e,s),i.$el.trigger("gridster:dragstart")},stop:function(t,e){i.on_stop_drag.call(i,t,e),i.$el.trigger("gridster:dragstop")},drag:throttle(function(t,e){i.on_drag.call(i,t,e),i.$el.trigger("gridster:drag")},60)});return this.drag_api=this.$el.drag(e),this},o.resizable=function(){return this.resize_api=this.$el.drag({items:"."+this.options.resize.handle_class,offset_left:this.options.widget_margins[0],container_width:this.container_width,move_element:!1,resize:!0,limit:this.options.autogrow_cols?!1:!0,start:t.proxy(this.on_start_resize,this),stop:t.proxy(function(i,e){delay(t.proxy(function(){this.on_stop_resize(i,e)},this),120)},this),drag:throttle(t.proxy(this.on_resize,this),60)}),this},o.setup_resize=function(){this.resize_handle_class=this.options.resize.handle_class;var i=this.options.resize.axes,e='';return this.resize_handle_tpl=t.map(i,function(t){return e.replace("{type}",t)}).join(""),this},o.on_start_drag=function(i,e){this.$helper.add(this.$player).add(this.$wrapper).addClass("dragging"),this.highest_col=this.get_highest_occupied_cell().col,this.$player.addClass("player"),this.player_grid_data=this.$player.coords().grid,this.placeholder_grid_data=t.extend({},this.player_grid_data),this.set_dom_grid_height(this.$el.height()+this.player_grid_data.size_y*this.min_widget_height),this.set_dom_grid_width(this.cols);var s=this.player_grid_data.size_x,r=this.cols-this.highest_col;this.options.autogrow_cols&&s>=r&&this.add_faux_cols(Math.min(s-r,1));var o=this.faux_grid,a=this.$player.data("coords").coords;this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data),this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.last_cols=[],this.last_rows=[],this.collision_api=this.$helper.collision(o,this.options.collision),this.$preview_holder=t("<"+this.$player.get(0).tagName+" />",{"class":"preview-holder","data-row":this.$player.attr("data-row"),"data-col":this.$player.attr("data-col"),css:{width:a.width,height:a.height}}).appendTo(this.$el),this.options.draggable.start&&this.options.draggable.start.call(this,i,e)},o.on_drag=function(t,i){if(null===this.$player)return!1;var e={left:i.position.left+this.baseX,top:i.position.top+this.baseY};if(this.options.autogrow_cols){var s=this.placeholder_grid_data.col+this.placeholder_grid_data.size_x-1;s>=this.cols-1&&this.options.max_cols>=this.cols+1&&(this.add_faux_cols(1),this.set_dom_grid_width(this.cols+1),this.drag_api.set_limits(this.container_width)),this.collision_api.set_colliders(this.faux_grid)}this.colliders_data=this.collision_api.get_closest_colliders(e),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.helper&&this.$player&&this.$player.css({left:i.position.left,top:i.position.top}),this.options.draggable.drag&&this.options.draggable.drag.call(this,t,i)},o.on_stop_drag=function(t,i){this.$helper.add(this.$player).add(this.$wrapper).removeClass("dragging"),i.position.left=i.position.left+this.baseX,i.position.top=i.position.top+this.baseY,this.colliders_data=this.collision_api.get_closest_colliders(i.position),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.$player.addClass("player-revert").removeClass("player").attr({"data-col":this.placeholder_grid_data.col,"data-row":this.placeholder_grid_data.row}).css({left:"",top:""}),this.$changed=this.$changed.add(this.$player),this.cells_occupied_by_player=this.get_cells_occupied(this.placeholder_grid_data),this.set_cells_player_occupies(this.placeholder_grid_data.col,this.placeholder_grid_data.row),this.$player.coords().grid.row=this.placeholder_grid_data.row,this.$player.coords().grid.col=this.placeholder_grid_data.col,this.options.draggable.stop&&this.options.draggable.stop.call(this,t,i),this.$preview_holder.remove(),this.$player=null,this.$helper=null,this.placeholder_grid_data={},this.player_grid_data={},this.cells_occupied_by_placeholder={},this.cells_occupied_by_player={},this.set_dom_grid_height(),this.set_dom_grid_width(),this.options.autogrow_cols&&this.drag_api.set_limits(this.cols*this.min_widget_width)},o.on_start_resize=function(i,e){this.$resized_widget=e.$player.closest(".gs-w"),this.resize_coords=this.$resized_widget.coords(),this.resize_wgd=this.resize_coords.grid,this.resize_initial_width=this.resize_coords.coords.width,this.resize_initial_height=this.resize_coords.coords.height,this.resize_initial_sizex=this.resize_coords.grid.size_x,this.resize_initial_sizey=this.resize_coords.grid.size_y,this.resize_initial_col=this.resize_coords.grid.col,this.resize_last_sizex=this.resize_initial_sizex,this.resize_last_sizey=this.resize_initial_sizey,this.resize_max_size_x=Math.min(this.resize_wgd.max_size_x||this.options.resize.max_size[0],this.options.max_cols-this.resize_initial_col+1),this.resize_max_size_y=this.resize_wgd.max_size_y||this.options.resize.max_size[1],this.resize_min_size_x=this.resize_wgd.min_size_x||this.options.resize.min_size[0]||1,this.resize_min_size_y=this.resize_wgd.min_size_y||this.options.resize.min_size[1]||1,this.resize_initial_last_col=this.get_highest_occupied_cell().col,this.set_dom_grid_width(this.cols),this.resize_dir={right:e.$player.is("."+this.resize_handle_class+"-x"),bottom:e.$player.is("."+this.resize_handle_class+"-y")},this.$resized_widget.css({"min-width":this.options.widget_base_dimensions[0],"min-height":this.options.widget_base_dimensions[1]});var s=this.$resized_widget.get(0).tagName;this.$resize_preview_holder=t("<"+s+" />",{"class":"preview-holder resize-preview-holder","data-row":this.$resized_widget.attr("data-row"),"data-col":this.$resized_widget.attr("data-col"),css:{width:this.resize_initial_width,height:this.resize_initial_height}}).appendTo(this.$el),this.$resized_widget.addClass("resizing"),this.options.resize.start&&this.options.resize.start.call(this,i,e,this.$resized_widget),this.$el.trigger("gridster:resizestart")},o.on_stop_resize=function(i,e){this.$resized_widget.removeClass("resizing").css({width:"",height:""}),delay(t.proxy(function(){this.$resize_preview_holder.remove().css({"min-width":"","min-height":""}),this.options.resize.stop&&this.options.resize.stop.call(this,i,e,this.$resized_widget),this.$el.trigger("gridster:resizestop")},this),300),this.set_dom_grid_width(),this.options.autogrow_cols&&this.drag_api.set_limits(this.cols*this.min_widget_width)},o.on_resize=function(t,i){var e,s=i.pointer.diff_left,r=i.pointer.diff_top,o=this.options.widget_base_dimensions[0],a=this.options.widget_base_dimensions[1],h=this.options.widget_margins[0],n=this.options.widget_margins[1],_=this.resize_max_size_x,d=this.resize_min_size_x,l=this.resize_max_size_y,c=this.resize_min_size_y,p=this.options.autogrow_cols,g=1/0,u=1/0,f=Math.ceil(s/(o+2*h)-.2),w=Math.ceil(r/(a+2*n)-.2),m=Math.max(1,this.resize_initial_sizex+f),y=Math.max(1,this.resize_initial_sizey+w),v=this.container_width/this.min_widget_width-this.resize_initial_col+1,z=v*this.min_widget_width-2*h;if(m=Math.max(Math.min(m,_),d),m=Math.min(v,m),e=_*o+2*(m-1)*h,g=Math.min(e,z),min_width=d*o+2*(m-1)*h,y=Math.max(Math.min(y,l),c),u=l*a+2*(y-1)*n,min_height=c*a+2*(y-1)*n,this.resize_dir.right?y=this.resize_initial_sizey:this.resize_dir.bottom&&(m=this.resize_initial_sizex),p){var x=this.resize_initial_col+m-1;p&&x>=this.resize_initial_last_col&&(this.set_dom_grid_width(Math.max(x+1,this.cols)),x>this.cols&&this.add_faux_cols(x-this.cols))}var $={};!this.resize_dir.bottom&&($.width=Math.max(Math.min(this.resize_initial_width+s,g),min_width)),!this.resize_dir.right&&($.height=Math.max(Math.min(this.resize_initial_height+r,u),min_height)),this.$resized_widget.css($),(m!==this.resize_last_sizex||y!==this.resize_last_sizey)&&(this.resize_widget(this.$resized_widget,m,y),this.set_dom_grid_width(this.cols),this.$resize_preview_holder.css({width:"",height:""}).attr({"data-row":this.$resized_widget.attr("data-row"),"data-sizex":m,"data-sizey":y})),this.options.resize.resize&&this.options.resize.resize.call(this,t,i,this.$resized_widget),this.$el.trigger("gridster:resize"),this.resize_last_sizex=m,this.resize_last_sizey=y},o.on_overlapped_column_change=function(i,e){if(!this.colliders_data.length)return this;var s,r=this.get_targeted_columns(this.colliders_data[0].el.data.col),o=this.last_cols.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_cols)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_cols[s],r)&&(e||t.noop).call(this,this.last_cols[s]);return this.last_cols=r,this},o.on_overlapped_row_change=function(i,e){if(!this.colliders_data.length)return this;var s,r=this.get_targeted_rows(this.colliders_data[0].el.data.row),o=this.last_rows.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_rows)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_rows[s],r)&&(e||t.noop).call(this,this.last_rows[s]);this.last_rows=r},o.set_player=function(t,i,e){var s=this;e||this.empty_cells_player_occupies();var r=e?{col:t}:s.colliders_data[0].el.data,o=r.col,a=i||r.row;this.player_grid_data={col:o,row:a,size_y:this.player_grid_data.size_y,size_x:this.player_grid_data.size_x},this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data);var h=this.get_widgets_overlapped(this.player_grid_data),n=this.widgets_constraints(h);if(this.manage_movements(n.can_go_up,o,a),this.manage_movements(n.can_not_go_up,o,a),!h.length){var _=this.can_go_player_up(this.player_grid_data);_!==!1&&(a=_),this.set_placeholder(o,a)}return{col:o,row:a}},o.widgets_constraints=function(i){var e,s=t([]),r=[],o=[];return i.each(t.proxy(function(i,e){var a=t(e),h=a.coords().grid;this.can_go_widget_up(h)?(s=s.add(a),r.push(h)):o.push(h)},this)),e=i.not(s),{can_go_up:this.sort_by_row_asc(r),can_not_go_up:this.sort_by_row_desc(o)}},o.sort_by_row_asc=function(i){return i=i.sort(function(i,e){return i.row||(i=t(i).coords().grid,e=t(e).coords().grid),i.row>e.row?1:-1})},o.sort_by_row_and_col_asc=function(t){return t=t.sort(function(t,i){return t.row>i.row||t.row===i.row&&t.col>i.col?1:-1})},o.sort_by_col_asc=function(t){return t=t.sort(function(t,i){return t.col>i.col?1:-1})},o.sort_by_row_desc=function(t){return t=t.sort(function(t,i){return t.row+t.size_y=0&&t.inArray(e,s.rows)>=0},o.is_placeholder_in=function(i,e){var s=this.cells_occupied_by_placeholder||{};return this.is_placeholder_in_col(i)&&t.inArray(e,s.rows)>=0},o.is_placeholder_in_col=function(i){var e=this.cells_occupied_by_placeholder||[];return t.inArray(i,e.cols)>=0},o.is_empty=function(t,i){return this.gridmap[t]!==undefined?this.gridmap[t][i]!==undefined&&this.gridmap[t][i]===!1?!0:!1:!0},o.is_occupied=function(t,i){return this.gridmap[t]?this.gridmap[t][i]?!0:!1:!1},o.is_widget=function(t,i){var e=this.gridmap[t];return e?(e=e[i],e?e:!1):!1},o.is_widget_under_player=function(t,i){return this.is_widget(t,i)?this.is_player_in(t,i):!1},o.get_widgets_under_player=function(i){i||(i=this.cells_occupied_by_player||{cols:[],rows:[]});var e=t([]);return t.each(i.cols,t.proxy(function(s,r){t.each(i.rows,t.proxy(function(t,i){this.is_widget(r,i)&&(e=e.add(this.gridmap[r][i]))},this))},this)),e},o.set_placeholder=function(i,e){var s=t.extend({},this.placeholder_grid_data),r=this.widgets_below({col:s.col,row:s.row,size_y:s.size_y,size_x:s.size_x}),o=i+s.size_x-1;o>this.cols&&(i-=o-i);var a=e>this.placeholder_grid_data.row,h=this.placeholder_grid_data.col!==i;this.placeholder_grid_data.col=i,this.placeholder_grid_data.row=e,this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.$preview_holder.attr({"data-row":e,"data-col":i}),(a||h)&&r.each(t.proxy(function(e,r){this.move_widget_up(t(r),this.placeholder_grid_data.col-i+s.size_y)},this));var n=this.get_widgets_under_player(this.cells_occupied_by_placeholder);n.length&&n.each(t.proxy(function(i,r){var o=t(r);this.move_widget_down(o,e+s.size_y-o.data("coords").grid.row)},this))},o.can_go_player_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4,o=this.get_widgets_under_player();return this.for_each_column_occupied(t,function(t){var a=this.gridmap[t],h=i+1;for(s[t]=[];--h>0&&(this.is_empty(t,h)||this.is_player(t,h)||this.is_widget(t,h)&&a[h].is(o));)s[t].push(h),r=r>h?h:r;return 0===s[t].length?(e=!1,!0):(s[t].sort(function(t,i){return t-i}),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.can_go_widget_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4;return this.for_each_column_occupied(t,function(o){var a=this.gridmap[o];s[o]=[];for(var h=i+1;--h>0&&(!this.is_widget(o,h)||this.is_player_in(o,h)||a[h].is(t.el));)this.is_player(o,h)||this.is_placeholder_in(o,h)||this.is_player_in(o,h)||s[o].push(h),r>h&&(r=h);return 0===s[o].length?(e=!1,!0):(s[o].sort(function(t,i){return t-i}),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.get_valid_rows=function(i,e,s){for(var r=i.row,o=i.row+i.size_y-1,a=i.size_y,h=s-1,n=[];o>=++h;){var _=!0;if(t.each(e,function(i,e){t.isArray(e)&&-1===t.inArray(h,e)&&(_=!1)}),_===!0&&(n.push(h),n.length===a))break}var d=!1;return 1===a?n[0]!==r&&(d=n[0]||!1):n[0]!==r&&(d=this.get_consecutive_numbers_index(n,a)),d},o.get_consecutive_numbers_index=function(t,i){for(var e=t.length,s=[],r=!0,o=-1,a=0;e>a;a++){if(r||t[a]===o+1){if(s.push(a),s.length===i)break;r=!1}else s=[],r=!0;o=t[a]}return s.length>=i?t[s[0]]:!1},o.get_widgets_overlapped=function(){var i=t([]),e=[],s=this.cells_occupied_by_player.rows.slice(0);return s.reverse(),t.each(this.cells_occupied_by_player.cols,t.proxy(function(r,o){t.each(s,t.proxy(function(s,r){if(!this.gridmap[o])return!0;var a=this.gridmap[o][r];this.is_occupied(o,r)&&!this.is_player(a)&&-1===t.inArray(a,e)&&(i=i.add(a),e.push(a)) +},this))},this)),i},o.on_start_overlapping_column=function(t){this.set_player(t,!1)},o.on_start_overlapping_row=function(t){this.set_player(!1,t)},o.on_stop_overlapping_column=function(t){this.set_player(t,!1);var i=this;this.for_each_widget_below(t,this.cells_occupied_by_player.rows[0],function(){i.move_widget_up(this,i.player_grid_data.size_y)})},o.on_stop_overlapping_row=function(t){this.set_player(!1,t);for(var i=this,e=this.cells_occupied_by_player.cols,s=0,r=e.length;r>s;s++)this.for_each_widget_below(e[s],t,function(){i.move_widget_up(this,i.player_grid_data.size_y)})},o.move_widget_to=function(i,e){var s=this,r=i.coords().grid;e-r.row;var o=this.widgets_below(i),a=this.can_move_to(r,r.col,e,i);return a===!1?!1:(this.remove_from_gridmap(r),r.row=e,this.add_to_gridmap(r),i.attr("data-row",e),this.$changed=this.$changed.add(i),o.each(function(i,e){var r=t(e),o=r.coords().grid,a=s.can_go_widget_up(o);a&&a!==o.row&&s.move_widget_to(r,a)}),this)},o.move_widget_up=function(i,e){var s=i.coords().grid,r=s.row,o=[];return e||(e=1),this.can_go_up(i)?(this.for_each_column_occupied(s,function(s){if(-1===t.inArray(i,o)){var a=i.coords().grid,h=r-e;if(h=this.can_go_up_to_row(a,s,h),!h)return!0;var n=this.widgets_below(i);this.remove_from_gridmap(a),a.row=h,this.add_to_gridmap(a),i.attr("data-row",a.row),this.$changed=this.$changed.add(i),o.push(i),n.each(t.proxy(function(i,s){this.move_widget_up(t(s),e)},this))}}),undefined):!1},o.move_widget_down=function(i,e){var s,r,o,a;if(0>=e)return!1;if(s=i.coords().grid,r=s.row,o=[],a=e,!i)return!1;if(-1===t.inArray(i,o)){var h=i.coords().grid,n=r+e,_=this.widgets_below(i);this.remove_from_gridmap(h),_.each(t.proxy(function(i,e){var s=t(e),r=s.coords().grid,o=this.displacement_diff(r,h,a);o>0&&this.move_widget_down(s,o)},this)),h.row=n,this.update_widget_position(h,i),i.attr("data-row",h.row),this.$changed=this.$changed.add(i),o.push(i)}},o.can_go_up_to_row=function(i,e,s){var r,o=this.gridmap,a=!0,h=[],n=i.row;if(this.for_each_column_occupied(i,function(t){for(o[t],h[t]=[],r=n;r--&&this.is_empty(t,r)&&!this.is_placeholder_in(t,r);)h[t].push(r);return h[t].length?undefined:(a=!1,!0)}),!a)return!1;for(r=s,r=1;n>r;r++){for(var _=!0,d=0,l=h.length;l>d;d++)h[d]&&-1===t.inArray(r,h[d])&&(_=!1);if(_===!0){a=r;break}}return a},o.displacement_diff=function(t,i,e){var s=t.row,r=[],o=i.row+i.size_y;this.for_each_column_occupied(t,function(t){for(var i=0,e=o;s>e;e++)this.is_empty(t,e)&&(i+=1);r.push(i)});var a=Math.max.apply(Math,r);return e-=a,e>0?e:0},o.widgets_below=function(i){var e=t.isPlainObject(i)?i:i.coords().grid,s=this;this.gridmap;var r=e.row+e.size_y-1,o=t([]);return this.for_each_column_occupied(e,function(i){s.for_each_widget_below(i,r,function(){return s.is_player(this)||-1!==t.inArray(this,o)?undefined:(o=o.add(this),!0)})}),this.sort_by_row_asc(o)},o.set_cells_player_occupies=function(t,i){return this.remove_from_gridmap(this.placeholder_grid_data),this.placeholder_grid_data.col=t,this.placeholder_grid_data.row=i,this.add_to_gridmap(this.placeholder_grid_data,this.$player),this},o.empty_cells_player_occupies=function(){return this.remove_from_gridmap(this.placeholder_grid_data),this},o.can_go_up=function(t){var i=t.coords().grid,e=i.row,s=e-1;this.gridmap;var r=!0;return 1===e?!1:(this.for_each_column_occupied(i,function(t){return this.is_widget(t,s),this.is_occupied(t,s)||this.is_player(t,s)||this.is_placeholder_in(t,s)||this.is_player_in(t,s)?(r=!1,!0):undefined}),r)},o.can_move_to=function(t,i,e,s){this.gridmap;var r=t.el,o={size_y:t.size_y,size_x:t.size_x,col:i,row:e},a=!0,h=i+t.size_x-1;return h>this.cols?!1:s&&e+t.size_y-1>s?!1:(this.for_each_cell_occupied(o,function(i,e){var s=this.is_widget(i,e);!s||t.el&&!s.is(r)||(a=!1)}),a)},o.get_targeted_columns=function(t){for(var i=(t||this.player_grid_data.col)+(this.player_grid_data.size_x-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_targeted_rows=function(t){for(var i=(t||this.player_grid_data.row)+(this.player_grid_data.size_y-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_cells_occupied=function(i){var e,s={cols:[],rows:[]};for(arguments[1]instanceof t&&(i=arguments[1].coords().grid),e=0;i.size_x>e;e++){var r=i.col+e;s.cols.push(r)}for(e=0;i.size_y>e;e++){var o=i.row+e;s.rows.push(o)}return s},o.for_each_cell_occupied=function(t,i){return this.for_each_column_occupied(t,function(e){this.for_each_row_occupied(t,function(t){i.call(this,e,t)})}),this},o.for_each_column_occupied=function(t,i){for(var e=0;t.size_x>e;e++){var s=t.col+e;i.call(this,s,t)}},o.for_each_row_occupied=function(t,i){for(var e=0;t.size_y>e;e++){var s=t.row+e;i.call(this,s,t)}},o._traversing_widgets=function(i,e,s,r,o){var a=this.gridmap;if(a[s]){var h,n,_=i+"/"+e;if(arguments[2]instanceof t){var d=arguments[2].coords().grid;s=d.col,r=d.row,o=arguments[3]}var l=[],c=r,p={"for_each/above":function(){for(;c--&&!(c>0&&this.is_widget(s,c)&&-1===t.inArray(a[s][c],l)&&(h=o.call(a[s][c],s,c),l.push(a[s][c]),h)););},"for_each/below":function(){for(c=r+1,n=a[s].length;n>c&&(!this.is_widget(s,c)||-1!==t.inArray(a[s][c],l)||(h=o.call(a[s][c],s,c),l.push(a[s][c]),!h));c++);}};p[_]&&p[_].call(this)}},o.for_each_widget_above=function(t,i,e){return this._traversing_widgets("for_each","above",t,i,e),this},o.for_each_widget_below=function(t,i,e){return this._traversing_widgets("for_each","below",t,i,e),this},o.get_highest_occupied_cell=function(){for(var t,i=this.gridmap,e=i[1].length,s=[],r=[],o=i.length-1;o>=1;o--)for(t=e-1;t>=1;t--)if(this.is_widget(o,t)){s.push(t),r.push(o);break}return{col:Math.max.apply(Math,r),row:Math.max.apply(Math,s)}},o.get_widgets_from=function(i,e){this.gridmap;var s=t();return i&&(s=s.add(this.$widgets.filter(function(){var e=t(this).attr("data-col");return e===i||e>i}))),e&&(s=s.add(this.$widgets.filter(function(){var i=t(this).attr("data-row");return i===e||i>e}))),s},o.set_dom_grid_height=function(t){if(t===undefined){var i=this.get_highest_occupied_cell().row;t=i*this.min_widget_height}return this.container_height=t,this.$el.css("height",this.container_height),this},o.set_dom_grid_width=function(t){t===undefined&&(t=this.get_highest_occupied_cell().col);var i=this.options.autogrow_cols?this.options.max_cols:this.cols;return t=Math.min(i,Math.max(t,this.options.min_cols)),this.container_width=t*this.min_widget_width,this.$el.css("width",this.container_width),this},o.generate_stylesheet=function(i){var e,r="",o=this.options.max_size_x||this.cols;i||(i={}),i.cols||(i.cols=this.cols),i.rows||(i.rows=this.rows),i.namespace||(i.namespace=this.options.namespace),i.widget_base_dimensions||(i.widget_base_dimensions=this.options.widget_base_dimensions),i.widget_margins||(i.widget_margins=this.options.widget_margins),i.min_widget_width=2*i.widget_margins[0]+i.widget_base_dimensions[0],i.min_widget_height=2*i.widget_margins[1]+i.widget_base_dimensions[1];var a=t.param(i);if(t.inArray(a,s.generated_stylesheets)>=0)return!1;for(this.generated_stylesheets.push(a),s.generated_stylesheets.push(a),e=i.cols;e>=0;e--)r+=i.namespace+' [data-col="'+(e+1)+'"] { left:'+(e*i.widget_base_dimensions[0]+e*i.widget_margins[0]+(e+1)*i.widget_margins[0])+"px; }\n";for(e=i.rows;e>=0;e--)r+=i.namespace+' [data-row="'+(e+1)+'"] { top:'+(e*i.widget_base_dimensions[1]+e*i.widget_margins[1]+(e+1)*i.widget_margins[1])+"px; }\n";for(var h=1;i.rows>=h;h++)r+=i.namespace+' [data-sizey="'+h+'"] { height:'+(h*i.widget_base_dimensions[1]+(h-1)*2*i.widget_margins[1])+"px; }\n";for(var n=1;o>=n;n++)r+=i.namespace+' [data-sizex="'+n+'"] { width:'+(n*i.widget_base_dimensions[0]+(n-1)*2*i.widget_margins[0])+"px; }\n";return this.add_style_tag(r)},o.add_style_tag=function(t){var i=e,s=i.createElement("style");return i.getElementsByTagName("head")[0].appendChild(s),s.setAttribute("type","text/css"),s.styleSheet?s.styleSheet.cssText=t:s.appendChild(e.createTextNode(t)),this.$style_tags=this.$style_tags.add(s),this},o.remove_style_tags=function(){var i=s.generated_stylesheets,e=this.generated_stylesheets;this.$style_tags.remove(),s.generated_stylesheets=t.map(i,function(i){return-1===t.inArray(i,e)?i:undefined})},o.generate_faux_grid=function(t,i){this.faux_grid=[],this.gridmap=[];var e,s;for(e=i;e>0;e--)for(this.gridmap[e]=[],s=t;s>0;s--)this.add_faux_cell(s,e);return this},o.add_faux_cell=function(i,e){var s=t({left:this.baseX+(e-1)*this.min_widget_width,top:this.baseY+(i-1)*this.min_widget_height,width:this.min_widget_width,height:this.min_widget_height,col:e,row:i,original_col:e,original_row:i}).coords();return t.isArray(this.gridmap[e])||(this.gridmap[e]=[]),this.gridmap[e][i]=!1,this.faux_grid.push(s),this},o.add_faux_rows=function(t){for(var i=this.rows,e=i+(t||1),s=e;s>i;s--)for(var r=this.cols;r>=1;r--)this.add_faux_cell(s,r);return this.rows=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.add_faux_cols=function(t){var i=this.cols,e=i+(t||1);e=Math.min(e,this.options.max_cols);for(var s=i+1;e>=s;s++)for(var r=this.rows;r>=1;r--)this.add_faux_cell(r,s);return this.cols=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.recalculate_faux_grid=function(){var e=this.$wrapper.width();return this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,t.each(this.faux_grid,t.proxy(function(t,i){this.faux_grid[t]=i.update({left:this.baseX+(i.data.col-1)*this.min_widget_width,top:this.baseY+(i.data.row-1)*this.min_widget_height})},this)),this},o.get_widgets_from_DOM=function(){return this.$widgets.each(t.proxy(function(i,e){this.register_widget(t(e))},this)),this},o.generate_grid_and_stylesheet=function(){var e=this.$wrapper.width(),s=this.options.max_cols,r=Math.floor(e/this.min_widget_width)+this.options.extra_cols,o=this.$widgets.map(function(){return t(this).attr("data-col")}).get();o.length||(o=[0]);var a=Math.max.apply(Math,o);this.cols=Math.max(a,r,this.options.min_cols),1/0!==s&&s>=a&&this.cols>s&&(this.cols=s);var h=this.options.extra_rows;return this.$widgets.each(function(i,e){h+=+t(e).attr("data-sizey")}),this.rows=Math.max(h,this.options.min_rows),this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this.generate_faux_grid(this.rows,this.cols)},o.destroy=function(e){return this.$el.removeData("gridster"),t(i).unbind(".gridster"),this.drag_api&&this.drag_api.destroy(),this.remove_style_tags(),e&&this.$el.remove(),this},t.fn.gridster=function(i){return this.each(function(){t(this).data("gridster")||t(this).data("gridster",new s(this,i))})},t.Gridster=o}(jQuery,window,document); diff --git a/templates/project/assets/javascripts/rickshaw-1.4.3.min.js b/templates/project/assets/javascripts/rickshaw-1.4.3.min.js new file mode 100644 index 00000000..fac600ff --- /dev/null +++ b/templates/project/assets/javascripts/rickshaw-1.4.3.min.js @@ -0,0 +1,2 @@ +var Rickshaw={namespace:function(namespace,obj){var parts=namespace.split(".");var parent=Rickshaw;for(var i=1,length=parts.length;i=3){if(s.data[2].xthis.window.xMax)isInRange=false;return isInRange}return true};this.onUpdate=function(callback){this.updateCallbacks.push(callback)};this.registerRenderer=function(renderer){this._renderers=this._renderers||{};this._renderers[renderer.name]=renderer};this.configure=function(args){if(args.width||args.height){this.setSize(args)}Rickshaw.keys(this.defaults).forEach(function(k){this[k]=k in args?args[k]:k in this?this[k]:this.defaults[k]},this);this.setRenderer(args.renderer||this.renderer.name,args)};this.setRenderer=function(r,args){if(typeof r=="function"){this.renderer=new r({graph:self});this.registerRenderer(this.renderer)}else{if(!this._renderers[r]){throw"couldn't find renderer "+r}this.renderer=this._renderers[r]}if(typeof args=="object"){this.renderer.configure(args)}};this.setSize=function(args){args=args||{};if(typeof window!==undefined){var style=window.getComputedStyle(this.element,null);var elementWidth=parseInt(style.getPropertyValue("width"),10);var elementHeight=parseInt(style.getPropertyValue("height"),10)}this.width=args.width||elementWidth||400;this.height=args.height||elementHeight||250;this.vis&&this.vis.attr("width",this.width).attr("height",this.height)};this.initialize(args)};Rickshaw.namespace("Rickshaw.Fixtures.Color");Rickshaw.Fixtures.Color=function(){this.schemes={};this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse();this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"];this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"];this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse();this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"};this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse();this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"];this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]};Rickshaw.namespace("Rickshaw.Fixtures.RandomData");Rickshaw.Fixtures.RandomData=function(timeInterval){var addData;timeInterval=timeInterval||1;var lastRandomValue=200;var timeBase=Math.floor((new Date).getTime()/1e3);this.addData=function(data){var randomValue=Math.random()*100+15+lastRandomValue;var index=data[0].length;var counter=1;data.forEach(function(series){var randomVariance=Math.random()*20;var v=randomValue/25+counter++ +(Math.cos(index*counter*11/960)+2)*15+(Math.cos(index/7)+2)*7+(Math.cos(index/17)+2)*1;series.push({x:index*timeInterval+timeBase,y:v+randomVariance})});lastRandomValue=randomValue*.85};this.removeData=function(data){data.forEach(function(series){series.shift()});timeBase+=timeInterval}};Rickshaw.namespace("Rickshaw.Fixtures.Time");Rickshaw.Fixtures.Time=function(){var tzOffset=(new Date).getTimezoneOffset()*60;var self=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];this.units=[{name:"decade",seconds:86400*365.25*10,formatter:function(d){return parseInt(d.getUTCFullYear()/10,10)*10}},{name:"year",seconds:86400*365.25,formatter:function(d){return d.getUTCFullYear()}},{name:"month",seconds:86400*30.5,formatter:function(d){return self.months[d.getUTCMonth()]}},{name:"week",seconds:86400*7,formatter:function(d){return self.formatDate(d)}},{name:"day",seconds:86400,formatter:function(d){return d.getUTCDate()}},{name:"6 hour",seconds:3600*6,formatter:function(d){return self.formatTime(d)}},{name:"hour",seconds:3600,formatter:function(d){return self.formatTime(d)}},{name:"15 minute",seconds:60*15,formatter:function(d){return self.formatTime(d)}},{name:"minute",seconds:60,formatter:function(d){return d.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(d){return d.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(d){return d.getUTCSeconds()+"s"}}];this.unit=function(unitName){return this.units.filter(function(unit){return unitName==unit.name}).shift()};this.formatDate=function(d){return d3.time.format("%b %e")(d)};this.formatTime=function(d){return d.toUTCString().match(/(\d+:\d+):/)[1]};this.ceil=function(time,unit){var nearFuture;var rounded;if(unit.name=="month"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setUTCFullYear(nearFuture.getUTCFullYear());rounded.setUTCMonth(nearFuture.getUTCMonth());rounded.setUTCDate(1);rounded.setUTCHours(0);rounded.setUTCMinutes(0);rounded.setUTCSeconds(0);rounded.setUTCMilliseconds(0);return rounded.getTime()/1e3}if(unit.name=="year"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setUTCFullYear(nearFuture.getUTCFullYear());rounded.setUTCMonth(0);rounded.setUTCDate(1);rounded.setUTCHours(0);rounded.setUTCMinutes(0);rounded.setUTCSeconds(0);rounded.setUTCMilliseconds(0);return rounded.getTime()/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Time.Local");Rickshaw.Fixtures.Time.Local=function(){var tzOffset=(new Date).getTimezoneOffset()*60;var self=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];this.units=[{name:"decade",seconds:86400*365.25*10,formatter:function(d){return parseInt(d.getFullYear()/10,10)*10}},{name:"year",seconds:86400*365.25,formatter:function(d){return d.getFullYear()}},{name:"month",seconds:86400*30.5,formatter:function(d){return self.months[d.getMonth()]}},{name:"week",seconds:86400*7,formatter:function(d){return self.formatDate(d)}},{name:"day",seconds:86400,formatter:function(d){return d.getDate()}},{name:"6 hour",seconds:3600*6,formatter:function(d){return self.formatTime(d)}},{name:"hour",seconds:3600,formatter:function(d){return self.formatTime(d)}},{name:"15 minute",seconds:60*15,formatter:function(d){return self.formatTime(d)}},{name:"minute",seconds:60,formatter:function(d){return d.getMinutes()}},{name:"15 second",seconds:15,formatter:function(d){return d.getSeconds()+"s"}},{name:"second",seconds:1,formatter:function(d){return d.getSeconds()+"s"}}];this.unit=function(unitName){return this.units.filter(function(unit){return unitName==unit.name}).shift()};this.formatDate=function(d){return d3.time.format("%b %e")(d)};this.formatTime=function(d){return d.toString().match(/(\d+:\d+):/)[1]};this.ceil=function(time,unit){var nearFuture;var rounded;if(unit.name=="day"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(nearFuture.getDate());rounded.setMonth(nearFuture.getMonth());rounded.setFullYear(nearFuture.getFullYear());return rounded.getTime()/1e3}if(unit.name=="month"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(1);rounded.setMonth(nearFuture.getMonth());rounded.setFullYear(nearFuture.getFullYear());return rounded.getTime()/1e3}if(unit.name=="year"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setFullYear(nearFuture.getFullYear());rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(1);rounded.setMonth(0);return rounded.getTime()/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Number");Rickshaw.Fixtures.Number.formatKMBT=function(y){var abs_y=Math.abs(y);if(abs_y>=1e12){return y/1e12+"T"}else if(abs_y>=1e9){return y/1e9+"B"}else if(abs_y>=1e6){return y/1e6+"M"}else if(abs_y>=1e3){return y/1e3+"K"}else if(abs_y<1&&y>0){return y.toFixed(2)}else if(abs_y===0){return""}else{return y}};Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(y){var abs_y=Math.abs(y);if(abs_y>=0x4000000000000){return y/0x4000000000000+"P"}else if(abs_y>=1099511627776){return y/1099511627776+"T"}else if(abs_y>=1073741824){return y/1073741824+"G"}else if(abs_y>=1048576){return y/1048576+"M"}else if(abs_y>=1024){return y/1024+"K"}else if(abs_y<1&&y>0){return y.toFixed(2)}else if(abs_y===0){return""}else{return y}};Rickshaw.namespace("Rickshaw.Color.Palette");Rickshaw.Color.Palette=function(args){var color=new Rickshaw.Fixtures.Color;args=args||{};this.schemes={};this.scheme=color.schemes[args.scheme]||args.scheme||color.schemes.colorwheel;this.runningIndex=0;this.generatorIndex=0;if(args.interpolatedStopCount){var schemeCount=this.scheme.length-1;var i,j,scheme=[];for(i=0;iself.graph.x.range()[1]){if(annotation.element){annotation.line.classList.add("offscreen");annotation.element.style.display="none"}annotation.boxes.forEach(function(box){if(box.rangeElement)box.rangeElement.classList.add("offscreen")});return}if(!annotation.element){var element=annotation.element=document.createElement("div");element.classList.add("annotation");this.elements.timeline.appendChild(element);element.addEventListener("click",function(e){element.classList.toggle("active");annotation.line.classList.toggle("active");annotation.boxes.forEach(function(box){if(box.rangeElement)box.rangeElement.classList.toggle("active")})},false)}annotation.element.style.left=left+"px";annotation.element.style.display="block";annotation.boxes.forEach(function(box){var element=box.element;if(!element){element=box.element=document.createElement("div");element.classList.add("content");element.innerHTML=box.content;annotation.element.appendChild(element);annotation.line=document.createElement("div");annotation.line.classList.add("annotation_line");self.graph.element.appendChild(annotation.line);if(box.end){box.rangeElement=document.createElement("div");box.rangeElement.classList.add("annotation_range");self.graph.element.appendChild(box.rangeElement)}}if(box.end){var annotationRangeStart=left;var annotationRangeEnd=Math.min(self.graph.x(box.end),self.graph.x.range()[1]);if(annotationRangeStart>annotationRangeEnd){annotationRangeEnd=left;annotationRangeStart=Math.max(self.graph.x(box.end),self.graph.x.range()[0])}var annotationRangeWidth=annotationRangeEnd-annotationRangeStart;box.rangeElement.style.left=annotationRangeStart+"px";box.rangeElement.style.width=annotationRangeWidth+"px";box.rangeElement.classList.remove("offscreen")}annotation.line.classList.remove("offscreen");annotation.line.style.left=left+"px"})},this)};this.graph.onUpdate(function(){self.update()})};Rickshaw.namespace("Rickshaw.Graph.Axis.Time");Rickshaw.Graph.Axis.Time=function(args){var self=this;this.graph=args.graph;this.elements=[];this.ticksTreatment=args.ticksTreatment||"plain";this.fixedTimeUnit=args.timeUnit;var time=args.timeFixture||new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var unit;var units=time.units;var domain=this.graph.x.domain();var rangeSeconds=domain[1]-domain[0];units.forEach(function(u){if(Math.floor(rangeSeconds/u.seconds)>=2){unit=unit||u}});return unit||time.units[time.units.length-1]};this.tickOffsets=function(){var domain=this.graph.x.domain();var unit=this.fixedTimeUnit||this.appropriateTimeUnit();var count=Math.ceil((domain[1]-domain[0])/unit.seconds);var runningTick=domain[0];var offsets=[];for(var i=0;iself.graph.x.range()[1])return;var element=document.createElement("div");element.style.left=self.graph.x(o.value)+"px";element.classList.add("x_tick");element.classList.add(self.ticksTreatment);var title=document.createElement("div");title.classList.add("title");title.innerHTML=o.unit.formatter(new Date(o.value*1e3));element.appendChild(title);self.graph.element.appendChild(element);self.elements.push(element)})};this.graph.onUpdate(function(){self.render()})};Rickshaw.namespace("Rickshaw.Graph.Axis.X");Rickshaw.Graph.Axis.X=function(args){var self=this;var berthRate=.1;this.initialize=function(args){this.graph=args.graph;this.orientation=args.orientation||"top";this.pixelsPerTick=args.pixelsPerTick||75;if(args.ticks)this.staticTicks=args.ticks;if(args.tickValues)this.tickValues=args.tickValues;this.tickSize=args.tickSize||4;this.ticksTreatment=args.ticksTreatment||"plain";if(args.element){this.element=args.element;this._discoverSize(args.element,args);this.vis=d3.select(args.element).append("svg:svg").attr("height",this.height).attr("width",this.width).attr("class","rickshaw_graph x_axis_d3");this.element=this.vis[0][0];this.element.style.position="relative";this.setSize({width:args.width,height:args.height})}else{this.vis=this.graph.vis}this.graph.onUpdate(function(){self.render()})};this.setSize=function(args){args=args||{};if(!this.element)return;this._discoverSize(this.element.parentNode,args);this.vis.attr("height",this.height).attr("width",this.width*(1+berthRate));var berth=Math.floor(this.width*berthRate/2);this.element.style.left=-1*berth+"px"};this.render=function(){if(this.graph.width!==this._renderWidth)this.setSize({auto:true});var axis=d3.svg.axis().scale(this.graph.x).orient(this.orientation);axis.tickFormat(args.tickFormat||function(x){return x});if(this.tickValues)axis.tickValues(this.tickValues);this.ticks=this.staticTicks||Math.floor(this.graph.width/this.pixelsPerTick);var berth=Math.floor(this.width*berthRate/2)||0;var transform;if(this.orientation=="top"){var yOffset=this.height||this.graph.height;transform="translate("+berth+","+yOffset+")"}else{transform="translate("+berth+", 0)"}if(this.element){this.vis.selectAll("*").remove()}this.vis.append("svg:g").attr("class",["x_ticks_d3",this.ticksTreatment].join(" ")).attr("transform",transform).call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var gridSize=(this.orientation=="bottom"?1:-1)*this.graph.height;this.graph.vis.append("svg:g").attr("class","x_grid_d3").call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));this._renderHeight=this.graph.height};this._discoverSize=function(element,args){if(typeof window!=="undefined"){var style=window.getComputedStyle(element,null);var elementHeight=parseInt(style.getPropertyValue("height"),10);if(!args.auto){var elementWidth=parseInt(style.getPropertyValue("width"),10)}}this.width=(args.width||elementWidth||this.graph.width)*(1+berthRate);this.height=args.height||elementHeight||40};this.initialize(args)};Rickshaw.namespace("Rickshaw.Graph.Axis.Y");Rickshaw.Graph.Axis.Y=Rickshaw.Class.create({initialize:function(args){this.graph=args.graph;this.orientation=args.orientation||"right";this.pixelsPerTick=args.pixelsPerTick||75;if(args.ticks)this.staticTicks=args.ticks;if(args.tickValues)this.tickValues=args.tickValues;this.tickSize=args.tickSize||4;this.ticksTreatment=args.ticksTreatment||"plain";this.tickFormat=args.tickFormat||function(y){return y};this.berthRate=.1;if(args.element){this.element=args.element;this.vis=d3.select(args.element).append("svg:svg").attr("class","rickshaw_graph y_axis");this.element=this.vis[0][0];this.element.style.position="relative";this.setSize({width:args.width,height:args.height})}else{this.vis=this.graph.vis}var self=this;this.graph.onUpdate(function(){self.render()})},setSize:function(args){args=args||{};if(!this.element)return;if(typeof window!=="undefined"){var style=window.getComputedStyle(this.element.parentNode,null);var elementWidth=parseInt(style.getPropertyValue("width"),10);if(!args.auto){var elementHeight=parseInt(style.getPropertyValue("height"),10)}}this.width=args.width||elementWidth||this.graph.width*this.berthRate;this.height=args.height||elementHeight||this.graph.height;this.vis.attr("width",this.width).attr("height",this.height*(1+this.berthRate));var berth=this.height*this.berthRate;if(this.orientation=="left"){this.element.style.top=-1*berth+"px"}},render:function(){if(this.graph.height!==this._renderHeight)this.setSize({auto:true});this.ticks=this.staticTicks||Math.floor(this.graph.height/this.pixelsPerTick);var axis=this._drawAxis(this.graph.y);this._drawGrid(axis);this._renderHeight=this.graph.height},_drawAxis:function(scale){var axis=d3.svg.axis().scale(scale).orient(this.orientation);axis.tickFormat(this.tickFormat);if(this.tickValues)axis.tickValues(this.tickValues);if(this.orientation=="left"){var berth=this.height*this.berthRate;var transform="translate("+this.width+", "+berth+")"}if(this.element){this.vis.selectAll("*").remove()}this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",transform).call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));return axis},_drawGrid:function(axis){var gridSize=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize))}});Rickshaw.namespace("Rickshaw.Graph.Axis.Y.Scaled");Rickshaw.Graph.Axis.Y.Scaled=Rickshaw.Class.create(Rickshaw.Graph.Axis.Y,{initialize:function($super,args){if(typeof args.scale==="undefined"){throw new Error("Scaled requires scale")}this.scale=args.scale;if(typeof args.grid==="undefined"){this.grid=true}else{this.grid=args.grid}$super(args)},_drawAxis:function($super,scale){var adjustedScale=this.scale.copy().range(scale.range());return $super(adjustedScale)},_drawGrid:function($super,axis){if(this.grid){$super(axis)}}});Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight");Rickshaw.Graph.Behavior.Series.Highlight=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;var colorSafe={};var activeLine=null;var disabledColor=args.disabledColor||function(seriesColor){return d3.interpolateRgb(seriesColor,d3.rgb("#d8d8d8"))(.8).toString()};this.addHighlightEvents=function(l){l.element.addEventListener("mouseover",function(e){if(activeLine)return;else activeLine=l;self.legend.lines.forEach(function(line,index){if(l===line){if(index>0&&self.graph.renderer.unstack&&(line.series.renderer?line.series.renderer.unstack:true)){var seriesIndex=self.graph.series.length-index-1; +line.originalIndex=seriesIndex;var series=self.graph.series.splice(seriesIndex,1)[0];self.graph.series.push(series)}return}colorSafe[line.series.name]=colorSafe[line.series.name]||line.series.color;line.series.color=disabledColor(line.series.color)});self.graph.update()},false);l.element.addEventListener("mouseout",function(e){if(!activeLine)return;else activeLine=null;self.legend.lines.forEach(function(line){if(l===line&&line.hasOwnProperty("originalIndex")){var series=self.graph.series.pop();self.graph.series.splice(line.originalIndex,0,series);delete line.originalIndex}if(colorSafe[line.series.name]){line.series.color=colorSafe[line.series.name]}});self.graph.update()},false)};if(this.legend){this.legend.lines.forEach(function(l){self.addHighlightEvents(l)})}};Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order");Rickshaw.Graph.Behavior.Series.Order=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;if(typeof window.$=="undefined"){throw"couldn't find jQuery at window.$"}if(typeof window.$.ui=="undefined"){throw"couldn't find jQuery UI at window.$.ui"}$(function(){$(self.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(event,ui){var series=[];$(self.legend.list).find("li").each(function(index,item){if(!item.series)return;series.push(item.series)});for(var i=self.graph.series.length-1;i>=0;i--){self.graph.series[i]=series.shift()}self.graph.update()}});$(self.legend.list).disableSelection()});this.graph.onUpdate(function(){var h=window.getComputedStyle(self.legend.element).height;self.legend.element.style.height=h})};Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle");Rickshaw.Graph.Behavior.Series.Toggle=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;this.addAnchor=function(line){var anchor=document.createElement("a");anchor.innerHTML="✔";anchor.classList.add("action");line.element.insertBefore(anchor,line.element.firstChild);anchor.onclick=function(e){if(line.series.disabled){line.series.enable();line.element.classList.remove("disabled")}else{if(this.graph.series.filter(function(s){return!s.disabled}).length<=1)return;line.series.disable();line.element.classList.add("disabled")}}.bind(this);var label=line.element.getElementsByTagName("span")[0];label.onclick=function(e){var disableAllOtherLines=line.series.disabled;if(!disableAllOtherLines){for(var i=0;idomainX){dataIndex=Math.abs(domainX-data[i].x)yMax)yMax=y});if(series[0].xxMax)xMax=series[series.length-1].x});xMin-=(xMax-xMin)*this.padding.left;xMax+=(xMax-xMin)*this.padding.right;yMin=this.graph.min==="auto"?yMin:this.graph.min||0;yMax=this.graph.max===undefined?yMax:this.graph.max;if(this.graph.min==="auto"||yMin<0){yMin-=(yMax-yMin)*this.padding.bottom}if(this.graph.max===undefined){yMax+=(yMax-yMin)*this.padding.top}return{x:[xMin,xMax],y:[yMin,yMax]}},render:function(args){args=args||{};var graph=this.graph;var series=args.series||graph.series;var vis=args.vis||graph.vis;vis.selectAll("*").remove();var data=series.filter(function(s){return!s.disabled}).map(function(s){return s.stack});var nodes=vis.selectAll("path").data(data).enter().append("svg:path").attr("d",this.seriesPathFactory());var i=0;series.forEach(function(series){if(series.disabled)return;series.path=nodes[0][i++];this._styleSeries(series)},this)},_styleSeries:function(series){var fill=this.fill?series.color:"none";var stroke=this.stroke?series.color:"none";series.path.setAttribute("fill",fill);series.path.setAttribute("stroke",stroke);series.path.setAttribute("stroke-width",this.strokeWidth);series.path.setAttribute("class",series.className)},configure:function(args){args=args||{};Rickshaw.keys(this.defaults()).forEach(function(key){if(!args.hasOwnProperty(key)){this[key]=this[key]||this.graph[key]||this.defaults()[key];return}if(typeof this.defaults()[key]=="object"){Rickshaw.keys(this.defaults()[key]).forEach(function(k){this[key][k]=args[key][k]!==undefined?args[key][k]:this[key][k]!==undefined?this[key][k]:this.defaults()[key][k]},this)}else{this[key]=args[key]!==undefined?args[key]:this[key]!==undefined?this[key]:this.graph[key]!==undefined?this.graph[key]:this.defaults()[key]}},this)},setStrokeWidth:function(strokeWidth){if(strokeWidth!==undefined){this.strokeWidth=strokeWidth}},setTension:function(tension){if(tension!==undefined){this.tension=tension}}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Line");Rickshaw.Graph.Renderer.Line=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"line",defaults:function($super){return Rickshaw.extend($super(),{unstack:true,fill:false,stroke:true})},seriesPathFactory:function(){var graph=this.graph;var factory=d3.svg.line().x(function(d){return graph.x(d.x)}).y(function(d){return graph.y(d.y)}).interpolate(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Stack");Rickshaw.Graph.Renderer.Stack=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"stack",defaults:function($super){return Rickshaw.extend($super(),{fill:true,stroke:false,unstack:false})},seriesPathFactory:function(){var graph=this.graph;var factory=d3.svg.area().x(function(d){return graph.x(d.x)}).y0(function(d){return graph.y(d.y0)}).y1(function(d){return graph.y(d.y+d.y0)}).interpolate(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Bar");Rickshaw.Graph.Renderer.Bar=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"bar",defaults:function($super){var defaults=Rickshaw.extend($super(),{gapSize:.05,unstack:false});delete defaults.tension;return defaults},initialize:function($super,args){args=args||{};this.gapSize=args.gapSize||this.gapSize;$super(args)},domain:function($super){var domain=$super();var frequentInterval=this._frequentInterval(this.graph.stackedData.slice(-1).shift());domain.x[1]+=Number(frequentInterval.magnitude);return domain},barWidth:function(series){var frequentInterval=this._frequentInterval(series.stack);var barWidth=this.graph.x(series.stack[0].x+frequentInterval.magnitude*(1-this.gapSize));return barWidth},render:function(args){args=args||{};var graph=this.graph;var series=args.series||graph.series;var vis=args.vis||graph.vis;vis.selectAll("*").remove();var barWidth=this.barWidth(series.active()[0]);var barXOffset=0;var activeSeriesCount=series.filter(function(s){return!s.disabled}).length;var seriesBarWidth=this.unstack?barWidth/activeSeriesCount:barWidth;var transform=function(d){var matrix=[1,0,0,d.y<0?-1:1,0,d.y<0?graph.y.magnitude(Math.abs(d.y))*2:0];return"matrix("+matrix.join(",")+")"};series.forEach(function(series){if(series.disabled)return;var barWidth=this.barWidth(series);var nodes=vis.selectAll("path").data(series.stack.filter(function(d){return d.y!==null})).enter().append("svg:rect").attr("x",function(d){return graph.x(d.x)+barXOffset}).attr("y",function(d){return graph.y(d.y0+Math.abs(d.y))*(d.y<0?-1:1)}).attr("width",seriesBarWidth).attr("height",function(d){return graph.y.magnitude(Math.abs(d.y))}).attr("transform",transform);Array.prototype.forEach.call(nodes[0],function(n){n.setAttribute("fill",series.color)});if(this.unstack)barXOffset+=seriesBarWidth},this)},_frequentInterval:function(data){var intervalCounts={};for(var i=0;i0){this[0].data.forEach(function(plot){item.data.push({x:plot.x,y:0})})}else if(item.data.length===0){item.data.push({x:this.timeBase-(this.timeInterval||0),y:0})}this.push(item);if(this.legend){this.legend.addLine(this.itemByName(item.name))}},addData:function(data,x){var index=this.getIndex();Rickshaw.keys(data).forEach(function(name){if(!this.itemByName(name)){this.addItem({name:name})}},this);this.forEach(function(item){item.data.push({x:x||(index*this.timeInterval||1)+this.timeBase,y:data[item.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(name){for(var i=0;i1;i--){this.currentSize+=1;this.currentIndex+=1;this.forEach(function(item){item.data.unshift({x:((i-1)*this.timeInterval||1)+this.timeBase,y:0,i:i})},this)}}},addData:function($super,data,x){$super(data,x);this.currentSize+=1;this.currentIndex+=1;if(this.maxDataPoints!==undefined){while(this.currentSize>this.maxDataPoints){this.dropData()}}},dropData:function(){this.forEach(function(item){item.data.splice(0,1)});this.currentSize-=1},getIndex:function(){return this.currentIndex}}); \ No newline at end of file diff --git a/templates/project/assets/javascripts/rickshaw.min.js b/templates/project/assets/javascripts/rickshaw.min.js deleted file mode 100644 index 33fa34fe..00000000 --- a/templates/project/assets/javascripts/rickshaw.min.js +++ /dev/null @@ -1,2 +0,0 @@ -Rickshaw={namespace:function(a,b){var c=a.split("."),d=typeof global!="undefined"?global:window,e=d.Rickshaw;for(var f=1,g=c.length;fthis.window.xMax&&(b=!1),b}return!0},this.onUpdate=function(a){this.updateCallbacks.push(a)},this.registerRenderer=function(a){this._renderers=this._renderers||{},this._renderers[a.name]=a},this.configure=function(a){(a.width||a.height)&&this.setSize(a),Rickshaw.keys(this.defaults).forEach(function(b){this[b]=b in a?a[b]:b in this?this[b]:this.defaults[b]},this),this.setRenderer(a.renderer||this.renderer.name,a)},this.setRenderer=function(a,b){if(!this._renderers[a])throw"couldn't find renderer "+a;this.renderer=this._renderers[a],typeof b=="object"&&this.renderer.configure(b)},this.setSize=function(a){a=a||{};if(typeof window!==undefined)var b=window.getComputedStyle(this.element,null),c=parseInt(b.getPropertyValue("width")),d=parseInt(b.getPropertyValue("height"));this.width=a.width||c||400,this.height=a.height||d||250,this.vis&&this.vis.attr("width",this.width).attr("height",this.height)},this.initialize(a)},Rickshaw.namespace("Rickshaw.Fixtures.Color"),Rickshaw.Fixtures.Color=function(){this.schemes={},this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse(),this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"],this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"],this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse(),this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"},this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse(),this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"],this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]},Rickshaw.namespace("Rickshaw.Fixtures.RandomData"),Rickshaw.Fixtures.RandomData=function(a){var b;a=a||1;var c=200,d=Math.floor((new Date).getTime()/1e3);this.addData=function(b){var e=Math.random()*100+15+c,f=b[0].length,g=1;b.forEach(function(b){var c=Math.random()*20,h=e/25+g++ +(Math.cos(f*g*11/960)+2)*15+(Math.cos(f/7)+2)*7+(Math.cos(f/17)+2)*1;b.push({x:f*a+d,y:h+c})}),c=e*.85}},Rickshaw.namespace("Rickshaw.Fixtures.Time"),Rickshaw.Fixtures.Time=function(){var a=(new Date).getTimezoneOffset()*60,b=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.units=[{name:"decade",seconds:315576e3,formatter:function(a){return parseInt(a.getUTCFullYear()/10)*10}},{name:"year",seconds:31557600,formatter:function(a){return a.getUTCFullYear()}},{name:"month",seconds:2635200,formatter:function(a){return b.months[a.getUTCMonth()]}},{name:"week",seconds:604800,formatter:function(a){return b.formatDate(a)}},{name:"day",seconds:86400,formatter:function(a){return a.getUTCDate()}},{name:"6 hour",seconds:21600,formatter:function(a){return b.formatTime(a)}},{name:"hour",seconds:3600,formatter:function(a){return b.formatTime(a)}},{name:"15 minute",seconds:900,formatter:function(a){return b.formatTime(a)}},{name:"minute",seconds:60,formatter:function(a){return a.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(a){return a.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(a){return a.getUTCSeconds()+"s"}}],this.unit=function(a){return this.units.filter(function(b){return a==b.name}).shift()},this.formatDate=function(a){return a.toUTCString().match(/, (\w+ \w+ \w+)/)[1]},this.formatTime=function(a){return a.toUTCString().match(/(\d+:\d+):/)[1]},this.ceil=function(a,b){if(b.name=="month"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(c.getUTCMonth()),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}if(b.name=="year"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(0),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}return Math.ceil(a/b.seconds)*b.seconds}},Rickshaw.namespace("Rickshaw.Fixtures.Number"),Rickshaw.Fixtures.Number.formatKMBT=function(a){return a>=1e12?a/1e12+"T":a>=1e9?a/1e9+"B":a>=1e6?a/1e6+"M":a>=1e3?a/1e3+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(a){return a>=0x4000000000000?a/0x4000000000000+"P":a>=1099511627776?a/1099511627776+"T":a>=1073741824?a/1073741824+"G":a>=1048576?a/1048576+"M":a>=1024?a/1024+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.namespace("Rickshaw.Color.Palette"),Rickshaw.Color.Palette=function(a){var b=new Rickshaw.Fixtures.Color;a=a||{},this.schemes={},this.scheme=b.schemes[a.scheme]||a.scheme||b.schemes.colorwheel,this.runningIndex=0,this.generatorIndex=0;if(a.interpolatedStopCount){var c=this.scheme.length-1,d,e,f=[];for(d=0;dc.graph.x.range()[1]){b.element&&(b.element.style.display="none");return}if(!b.element){var e=b.element=document.createElement("div");e.classList.add("annotation"),this.elements.timeline.appendChild(e),e.addEventListener("click",function(a){e.classList.toggle("active"),b.line.classList.toggle("active")},!1)}b.element.style.left=d+"px",b.element.style.display="block",b.boxes.forEach(function(a){var e=a.element;e||(e=a.element=document.createElement("div"),e.classList.add("content"),e.innerHTML=a.content,b.element.appendChild(e),b.line=document.createElement("div"),b.line.classList.add("annotation_line"),c.graph.element.appendChild(b.line)),b.line.style.left=d+"px"})},this)},this.graph.onUpdate(function(){c.update()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Time"),Rickshaw.Graph.Axis.Time=function(a){var b=this;this.graph=a.graph,this.elements=[],this.ticksTreatment=a.ticksTreatment||"plain",this.fixedTimeUnit=a.timeUnit;var c=new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var a,b=c.units,d=this.graph.x.domain(),e=d[1]-d[0];return b.forEach(function(b){Math.floor(e/b.seconds)>=2&&(a=a||b)}),a||c.units[c.units.length-1]},this.tickOffsets=function(){var a=this.graph.x.domain(),b=this.fixedTimeUnit||this.appropriateTimeUnit(),d=Math.ceil((a[1]-a[0])/b.seconds),e=a[0],f=[];for(var g=0;gb.graph.x.range()[1])return;var c=document.createElement("div");c.style.left=b.graph.x(a.value)+"px",c.classList.add("x_tick"),c.classList.add(b.ticksTreatment);var d=document.createElement("div");d.classList.add("title"),d.innerHTML=a.unit.formatter(new Date(a.value*1e3)),c.appendChild(d),b.graph.element.appendChild(c),b.elements.push(c)})},this.graph.onUpdate(function(){b.render()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Y"),Rickshaw.Graph.Axis.Y=function(a){var b=this,c=.1;this.initialize=function(a){this.graph=a.graph,this.orientation=a.orientation||"right";var c=a.pixelsPerTick||75;this.ticks=a.ticks||Math.floor(this.graph.height/c),this.tickSize=a.tickSize||4,this.ticksTreatment=a.ticksTreatment||"plain",a.element?(this.element=a.element,this.vis=d3.select(a.element).append("svg:svg").attr("class","rickshaw_graph y_axis"),this.element=this.vis[0][0],this.element.style.position="relative",this.setSize({width:a.width,height:a.height})):this.vis=this.graph.vis,this.graph.onUpdate(function(){b.render()})},this.setSize=function(a){a=a||{};if(!this.element)return;if(typeof window!="undefined"){var b=window.getComputedStyle(this.element.parentNode,null),d=parseInt(b.getPropertyValue("width"));if(!a.auto)var e=parseInt(b.getPropertyValue("height"))}this.width=a.width||d||this.graph.width*c,this.height=a.height||e||this.graph.height,this.vis.attr("width",this.width).attr("height",this.height*(1+c));var f=this.height*c;this.element.style.top=-1*f+"px"},this.render=function(){this.graph.height!==this._renderHeight&&this.setSize({auto:!0});var b=d3.svg.axis().scale(this.graph.y).orient(this.orientation);b.tickFormat(a.tickFormat||function(a){return a});if(this.orientation=="left")var d=this.height*c,e="translate("+this.width+", "+d+")";this.element&&this.vis.selectAll("*").remove(),this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",e).call(b.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var f=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(b.ticks(this.ticks).tickSubdivide(0).tickSize(f)),this._renderHeight=this.graph.height},this.initialize(a)},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight"),Rickshaw.Graph.Behavior.Series.Highlight=function(a){this.graph=a.graph,this.legend=a.legend;var b=this,c={};this.addHighlightEvents=function(a){a.element.addEventListener("mouseover",function(d){b.legend.lines.forEach(function(b){if(a===b)return;c[b.series.name]=c[b.series.name]||b.series.color,b.series.color=d3.interpolateRgb(b.series.color,d3.rgb("#d8d8d8"))(.8).toString()}),b.graph.update()},!1),a.element.addEventListener("mouseout",function(a){b.legend.lines.forEach(function(a){c[a.series.name]&&(a.series.color=c[a.series.name])}),b.graph.update()},!1)},this.legend&&this.legend.lines.forEach(function(a){b.addHighlightEvents(a)})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order"),Rickshaw.Graph.Behavior.Series.Order=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;$(function(){$(b.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(a,c){var d=[];$(b.legend.list).find("li").each(function(a,b){if(!b.series)return;d.push(b.series)});for(var e=b.graph.series.length-1;e>=0;e--)b.graph.series[e]=d.shift();b.graph.update()}}),$(b.legend.list).disableSelection()}),this.graph.onUpdate(function(){var a=window.getComputedStyle(b.legend.element).height;b.legend.element.style.height=a})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle"),Rickshaw.Graph.Behavior.Series.Toggle=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;this.addAnchor=function(a){var c=document.createElement("a");c.innerHTML="✔",c.classList.add("action"),a.element.insertBefore(c,a.element.firstChild),c.onclick=function(b){a.series.disabled?(a.series.enable(),a.element.classList.remove("disabled")):(a.series.disable(),a.element.classList.add("disabled"))};var d=a.element.getElementsByTagName("span")[0];d.onclick=function(c){var d=a.series.disabled;if(!d)for(var e=0;ee){j=k;break}f[0][k+1]<=e?k++:k--}var e=f[0][j].x,l=this.xFormatter(e),m=b.x(e),n=0,o=b.series.active().map(function(a){return{order:n++,series:a,name:a.name,value:a.stack[j]}}),p,q=function(a,b){return a.value.y0+a.value.y-(b.value.y0+b.value.y)},r=b.y.magnitude.invert(b.element.offsetHeight-d);o.sort(q).forEach(function(a){a.formattedYValue=this.yFormatter.constructor==Array?this.yFormatter[o.indexOf(a)](a.value.y):this.yFormatter(a.value.y),a.graphX=m,a.graphY=b.y(a.value.y0+a.value.y),r>a.value.y0&&r0?this[0].data.forEach(function(b){a.data.push({x:b.x,y:0})}):a.data.length==0&&a.data.push({x:this.timeBase-(this.timeInterval||0),y:0}),this.push(a),this.legend&&this.legend.addLine(this.itemByName(a.name))},addData:function(a){var b=this.getIndex();Rickshaw.keys(a).forEach(function(a){this.itemByName(a)||this.addItem({name:a})},this),this.forEach(function(c){c.data.push({x:(b*this.timeInterval||1)+this.timeBase,y:a[c.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(a){for(var b=0;b0;d--)this.currentSize+=1,this.currentIndex+=1,this.forEach(function(a){a.data.unshift({x:((d-1)*this.timeInterval||1)+this.timeBase,y:0,i:d})},this)},addData:function($super,a){$super(a),this.currentSize+=1,this.currentIndex+=1;if(this.maxDataPoints!==undefined)while(this.currentSize>this.maxDataPoints)this.dropData()},dropData:function(){this.forEach(function(a){a.data.splice(0,1)}),this.currentSize-=1},getIndex:function(){return this.currentIndex}}); \ No newline at end of file diff --git a/templates/project/assets/stylesheets/application.scss b/templates/project/assets/stylesheets/application.scss index ea2cd86e..451f03e3 100644 --- a/templates/project/assets/stylesheets/application.scss +++ b/templates/project/assets/stylesheets/application.scss @@ -35,22 +35,22 @@ $text-danger-color: #fff; // ---------------------------------------------------------------------------- // Base styles // ---------------------------------------------------------------------------- -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } -body { - margin: 0; +body { + margin: 0; background-color: $background-color; font-size: 20px; color: $text-color; font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif; } -b, strong { - font-weight: bold; +b, strong { + font-weight: bold; } a { @@ -58,18 +58,18 @@ a { color: inherit; } -img { - border: 0; - -ms-interpolation-mode: bicubic; - vertical-align: middle; +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; } -img, object { - max-width: 100%; +img, object { + max-width: 100%; } -iframe { - max-width: 100%; +iframe { + max-width: 100%; } table { @@ -82,16 +82,16 @@ td { vertical-align: middle; } -ul, ol { - padding: 0; - margin: 0; +ul, ol { + padding: 0; + margin: 0; } -h1, h2, h3, h4, h5, p { +h1, h2, h3, h4, h5, p { padding: 0; - margin: 0; + margin: 0; } -h1 { +h1 { margin-bottom: 12px; text-align: center; font-size: 30px; @@ -117,6 +117,7 @@ h3 { } .icon-background { + pointer-events: none; width: 100%!important; height: 100%; position: absolute; @@ -124,6 +125,8 @@ h3 { top: 0; opacity: 0.1; font-size: 275px; + text-align: center; + margin-top: 82px; } .list-nostyle { @@ -141,9 +144,9 @@ h3 { } .widget { - padding: 25px 12px; text-align: center; - width: 100%; + width: inherit; + height: inherit; display: table-cell; vertical-align: middle; } @@ -152,7 +155,7 @@ h3 { background-color: $background-warning-color-1; @include animation(status-warning-background, 2s, ease, infinite); - .icon-warning-sign { + .icon-warning-sign { display: inline-block; } @@ -166,7 +169,7 @@ h3 { background-color: $background-danger-color-1; @include animation(status-danger-background, 2s, ease, infinite); - .icon-warning-sign { + .icon-warning-sign { display: inline-block; } diff --git a/templates/project/assets/stylesheets/font-awesome.css b/templates/project/assets/stylesheets/font-awesome.css index c642925b..cf6fe783 100644 --- a/templates/project/assets/stylesheets/font-awesome.css +++ b/templates/project/assets/stylesheets/font-awesome.css @@ -1,303 +1,2086 @@ -/* Font Awesome - the iconic font designed for use with Twitter Bootstrap - ------------------------------------------------------- - The full suite of pictographic icons, examples, and documentation - can be found at: http://fortawesome.github.com/Font-Awesome/ - - License - ------------------------------------------------------- - The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0: - http://creativecommons.org/licenses/by/3.0/ A mention of - 'Font Awesome - http://fortawesome.github.com/Font-Awesome' in human-readable - source code is considered acceptable attribution (most common on the web). - If human readable source code is not available to the end user, a mention in - an 'About' or 'Credits' screen is considered acceptable (most common in desktop - or mobile software). - - Contact - ------------------------------------------------------- - Email: dave@davegandy.com - Twitter: http://twitter.com/fortaweso_me - Work: http://lemonwi.se co-founder - - */ +/*! + * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ @font-face { - font-family: "FontAwesome"; - src: url('/assets/fontawesome-webfont.eot'); - src: url('/assets/fontawesome-webfont.eot?#iefix') format('eot'), url('/assets/fontawesome-webfont.woff') format('woff'), url('/assets/fontawesome-webfont.ttf') format('truetype'), url('/assets/fontawesome-webfont.svg#FontAwesome') format('svg'); + font-family: 'FontAwesome'; + src: url('../assets/fontawesome-webfont.eot?v=4.5.0'); + src: url('../assets/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'), url('../assets/fontawesome-webfont.woff2?v=4.5.0') format('woff2'), url('../assets/fontawesome-webfont.woff?v=4.5.0') format('woff'), url('../assets/fontawesome-webfont.ttf?v=4.5.0') format('truetype'), url('../assets/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } - -/* Font Awesome styles - ------------------------------------------------------- */ -[class^="icon-"]:before, [class*=" icon-"]:before { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - display: inline-block; - text-decoration: inherit; -} -a [class^="icon-"], a [class*=" icon-"] { +.fa { display: inline-block; - text-decoration: inherit; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } /* makes the font 33% larger relative to the icon container */ -.icon-large:before { - vertical-align: top; - font-size: 1.3333333333333333em; +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; } -.btn [class^="icon-"], .btn [class*=" icon-"] { - /* keeps button heights with and without icons the same */ - - line-height: .9em; +.fa-2x { + font-size: 2em; } -li [class^="icon-"], li [class*=" icon-"] { - display: inline-block; - width: 1.25em; - text-align: center; +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; } -li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] { - /* 1.5 increased font size for icon-large * 1.25 width */ - - width: 1.875em; +.fa-fw { + width: 1.28571429em; + text-align: center; } -li[class^="icon-"], li[class*=" icon-"] { - margin-left: 0; +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; list-style-type: none; } -li[class^="icon-"]:before, li[class*=" icon-"]:before { - text-indent: -2em; +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; text-align: center; } -li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before { - text-indent: -1.3333333333333333em; -} -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.icon-glass:before { content: "\f000"; } -.icon-music:before { content: "\f001"; } -.icon-search:before { content: "\f002"; } -.icon-envelope:before { content: "\f003"; } -.icon-heart:before { content: "\f004"; } -.icon-star:before { content: "\f005"; } -.icon-star-empty:before { content: "\f006"; } -.icon-user:before { content: "\f007"; } -.icon-film:before { content: "\f008"; } -.icon-th-large:before { content: "\f009"; } -.icon-th:before { content: "\f00a"; } -.icon-th-list:before { content: "\f00b"; } -.icon-ok:before { content: "\f00c"; } -.icon-remove:before { content: "\f00d"; } -.icon-zoom-in:before { content: "\f00e"; } - -.icon-zoom-out:before { content: "\f010"; } -.icon-off:before { content: "\f011"; } -.icon-signal:before { content: "\f012"; } -.icon-cog:before { content: "\f013"; } -.icon-trash:before { content: "\f014"; } -.icon-home:before { content: "\f015"; } -.icon-file:before { content: "\f016"; } -.icon-time:before { content: "\f017"; } -.icon-road:before { content: "\f018"; } -.icon-download-alt:before { content: "\f019"; } -.icon-download:before { content: "\f01a"; } -.icon-upload:before { content: "\f01b"; } -.icon-inbox:before { content: "\f01c"; } -.icon-play-circle:before { content: "\f01d"; } -.icon-repeat:before { content: "\f01e"; } - -/* \f020 doesn't work in Safari. all shifted one down */ -.icon-refresh:before { content: "\f021"; } -.icon-list-alt:before { content: "\f022"; } -.icon-lock:before { content: "\f023"; } -.icon-flag:before { content: "\f024"; } -.icon-headphones:before { content: "\f025"; } -.icon-volume-off:before { content: "\f026"; } -.icon-volume-down:before { content: "\f027"; } -.icon-volume-up:before { content: "\f028"; } -.icon-qrcode:before { content: "\f029"; } -.icon-barcode:before { content: "\f02a"; } -.icon-tag:before { content: "\f02b"; } -.icon-tags:before { content: "\f02c"; } -.icon-book:before { content: "\f02d"; } -.icon-bookmark:before { content: "\f02e"; } -.icon-print:before { content: "\f02f"; } - -.icon-camera:before { content: "\f030"; } -.icon-font:before { content: "\f031"; } -.icon-bold:before { content: "\f032"; } -.icon-italic:before { content: "\f033"; } -.icon-text-height:before { content: "\f034"; } -.icon-text-width:before { content: "\f035"; } -.icon-align-left:before { content: "\f036"; } -.icon-align-center:before { content: "\f037"; } -.icon-align-right:before { content: "\f038"; } -.icon-align-justify:before { content: "\f039"; } -.icon-list:before { content: "\f03a"; } -.icon-indent-left:before { content: "\f03b"; } -.icon-indent-right:before { content: "\f03c"; } -.icon-facetime-video:before { content: "\f03d"; } -.icon-picture:before { content: "\f03e"; } - -.icon-pencil:before { content: "\f040"; } -.icon-map-marker:before { content: "\f041"; } -.icon-adjust:before { content: "\f042"; } -.icon-tint:before { content: "\f043"; } -.icon-edit:before { content: "\f044"; } -.icon-share:before { content: "\f045"; } -.icon-check:before { content: "\f046"; } -.icon-move:before { content: "\f047"; } -.icon-step-backward:before { content: "\f048"; } -.icon-fast-backward:before { content: "\f049"; } -.icon-backward:before { content: "\f04a"; } -.icon-play:before { content: "\f04b"; } -.icon-pause:before { content: "\f04c"; } -.icon-stop:before { content: "\f04d"; } -.icon-forward:before { content: "\f04e"; } - -.icon-fast-forward:before { content: "\f050"; } -.icon-step-forward:before { content: "\f051"; } -.icon-eject:before { content: "\f052"; } -.icon-chevron-left:before { content: "\f053"; } -.icon-chevron-right:before { content: "\f054"; } -.icon-plus-sign:before { content: "\f055"; } -.icon-minus-sign:before { content: "\f056"; } -.icon-remove-sign:before { content: "\f057"; } -.icon-ok-sign:before { content: "\f058"; } -.icon-question-sign:before { content: "\f059"; } -.icon-info-sign:before { content: "\f05a"; } -.icon-screenshot:before { content: "\f05b"; } -.icon-remove-circle:before { content: "\f05c"; } -.icon-ok-circle:before { content: "\f05d"; } -.icon-ban-circle:before { content: "\f05e"; } - -.icon-arrow-left:before { content: "\f060"; } -.icon-arrow-right:before { content: "\f061"; } -.icon-arrow-up:before { content: "\f062"; } -.icon-arrow-down:before { content: "\f063"; } -.icon-share-alt:before { content: "\f064"; } -.icon-resize-full:before { content: "\f065"; } -.icon-resize-small:before { content: "\f066"; } -.icon-plus:before { content: "\f067"; } -.icon-minus:before { content: "\f068"; } -.icon-asterisk:before { content: "\f069"; } -.icon-exclamation-sign:before { content: "\f06a"; } -.icon-gift:before { content: "\f06b"; } -.icon-leaf:before { content: "\f06c"; } -.icon-fire:before { content: "\f06d"; } -.icon-eye-open:before { content: "\f06e"; } - -.icon-eye-close:before { content: "\f070"; } -.icon-warning-sign:before { content: "\f071"; } -.icon-plane:before { content: "\f072"; } -.icon-calendar:before { content: "\f073"; } -.icon-random:before { content: "\f074"; } -.icon-comment:before { content: "\f075"; } -.icon-magnet:before { content: "\f076"; } -.icon-chevron-up:before { content: "\f077"; } -.icon-chevron-down:before { content: "\f078"; } -.icon-retweet:before { content: "\f079"; } -.icon-shopping-cart:before { content: "\f07a"; } -.icon-folder-close:before { content: "\f07b"; } -.icon-folder-open:before { content: "\f07c"; } -.icon-resize-vertical:before { content: "\f07d"; } -.icon-resize-horizontal:before { content: "\f07e"; } - -.icon-bar-chart:before { content: "\f080"; } -.icon-twitter-sign:before { content: "\f081"; } -.icon-facebook-sign:before { content: "\f082"; } -.icon-camera-retro:before { content: "\f083"; } -.icon-key:before { content: "\f084"; } -.icon-cogs:before { content: "\f085"; } -.icon-comments:before { content: "\f086"; } -.icon-thumbs-up:before { content: "\f087"; } -.icon-thumbs-down:before { content: "\f088"; } -.icon-star-half:before { content: "\f089"; } -.icon-heart-empty:before { content: "\f08a"; } -.icon-signout:before { content: "\f08b"; } -.icon-linkedin-sign:before { content: "\f08c"; } -.icon-pushpin:before { content: "\f08d"; } -.icon-external-link:before { content: "\f08e"; } - -.icon-signin:before { content: "\f090"; } -.icon-trophy:before { content: "\f091"; } -.icon-github-sign:before { content: "\f092"; } -.icon-upload-alt:before { content: "\f093"; } -.icon-lemon:before { content: "\f094"; } -.icon-phone:before { content: "\f095"; } -.icon-check-empty:before { content: "\f096"; } -.icon-bookmark-empty:before { content: "\f097"; } -.icon-phone-sign:before { content: "\f098"; } -.icon-twitter:before { content: "\f099"; } -.icon-facebook:before { content: "\f09a"; } -.icon-github:before { content: "\f09b"; } -.icon-unlock:before { content: "\f09c"; } -.icon-credit-card:before { content: "\f09d"; } -.icon-rss:before { content: "\f09e"; } - -.icon-hdd:before { content: "\f0a0"; } -.icon-bullhorn:before { content: "\f0a1"; } -.icon-bell:before { content: "\f0a2"; } -.icon-certificate:before { content: "\f0a3"; } -.icon-hand-right:before { content: "\f0a4"; } -.icon-hand-left:before { content: "\f0a5"; } -.icon-hand-up:before { content: "\f0a6"; } -.icon-hand-down:before { content: "\f0a7"; } -.icon-circle-arrow-left:before { content: "\f0a8"; } -.icon-circle-arrow-right:before { content: "\f0a9"; } -.icon-circle-arrow-up:before { content: "\f0aa"; } -.icon-circle-arrow-down:before { content: "\f0ab"; } -.icon-globe:before { content: "\f0ac"; } -.icon-wrench:before { content: "\f0ad"; } -.icon-tasks:before { content: "\f0ae"; } - -.icon-filter:before { content: "\f0b0"; } -.icon-briefcase:before { content: "\f0b1"; } -.icon-fullscreen:before { content: "\f0b2"; } - -.icon-group:before { content: "\f0c0"; } -.icon-link:before { content: "\f0c1"; } -.icon-cloud:before { content: "\f0c2"; } -.icon-beaker:before { content: "\f0c3"; } -.icon-cut:before { content: "\f0c4"; } -.icon-copy:before { content: "\f0c5"; } -.icon-paper-clip:before { content: "\f0c6"; } -.icon-save:before { content: "\f0c7"; } -.icon-sign-blank:before { content: "\f0c8"; } -.icon-reorder:before { content: "\f0c9"; } -.icon-list-ul:before { content: "\f0ca"; } -.icon-list-ol:before { content: "\f0cb"; } -.icon-strikethrough:before { content: "\f0cc"; } -.icon-underline:before { content: "\f0cd"; } -.icon-table:before { content: "\f0ce"; } - -.icon-magic:before { content: "\f0d0"; } -.icon-truck:before { content: "\f0d1"; } -.icon-pinterest:before { content: "\f0d2"; } -.icon-pinterest-sign:before { content: "\f0d3"; } -.icon-google-plus-sign:before { content: "\f0d4"; } -.icon-google-plus:before { content: "\f0d5"; } -.icon-money:before { content: "\f0d6"; } -.icon-caret-down:before { content: "\f0d7"; } -.icon-caret-up:before { content: "\f0d8"; } -.icon-caret-left:before { content: "\f0d9"; } -.icon-caret-right:before { content: "\f0da"; } -.icon-columns:before { content: "\f0db"; } -.icon-sort:before { content: "\f0dc"; } -.icon-sort-down:before { content: "\f0dd"; } -.icon-sort-up:before { content: "\f0de"; } - -.icon-envelope-alt:before { content: "\f0e0"; } -.icon-linkedin:before { content: "\f0e1"; } -.icon-undo:before { content: "\f0e2"; } -.icon-legal:before { content: "\f0e3"; } -.icon-dashboard:before { content: "\f0e4"; } -.icon-comment-alt:before { content: "\f0e5"; } -.icon-comments-alt:before { content: "\f0e6"; } -.icon-bolt:before { content: "\f0e7"; } -.icon-sitemap:before { content: "\f0e8"; } -.icon-umbrella:before { content: "\f0e9"; } -.icon-paste:before { content: "\f0ea"; } - -.icon-user-md:before { content: "\f200"; } +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} diff --git a/templates/project/assets/stylesheets/jquery.gridster.css b/templates/project/assets/stylesheets/jquery.gridster.css deleted file mode 100644 index d5124848..00000000 --- a/templates/project/assets/stylesheets/jquery.gridster.css +++ /dev/null @@ -1,57 +0,0 @@ -/*! gridster.js - v0.1.0 - 2012-08-14 -* http://gridster.net/ -* Copyright (c) 2012 ducksboard; Licensed MIT */ - -.gridster { - position:relative; -} - -.gridster > * { - margin: 0 auto; - -webkit-transition: height .4s; - -moz-transition: height .4s; - -o-transition: height .4s; - -ms-transition: height .4s; - transition: height .4s; -} - -.gridster .gs_w{ - z-index: 2; - position: absolute; -} - -.ready .gs_w:not(.preview-holder) { - -webkit-transition: opacity .3s, left .3s, top .3s; - -moz-transition: opacity .3s, left .3s, top .3s; - -o-transition: opacity .3s, left .3s, top .3s; - transition: opacity .3s, left .3s, top .3s; -} - -.gridster .preview-holder { - z-index: 1; - position: absolute; - background-color: #fff; - border-color: #fff; - opacity: 0.3; -} - -.gridster .player-revert { - z-index: 10!important; - -webkit-transition: left .3s, top .3s!important; - -moz-transition: left .3s, top .3s!important; - -o-transition: left .3s, top .3s!important; - transition: left .3s, top .3s!important; -} - -.gridster .dragging { - z-index: 10!important; - -webkit-transition: all 0s !important; - -moz-transition: all 0s !important; - -o-transition: all 0s !important; - transition: all 0s !important; -} - -/* Uncomment this if you set helper : "clone" in draggable options */ -/*.gridster .player { - opacity:0; -}*/ \ No newline at end of file diff --git a/templates/project/assets/stylesheets/jquery.gridster.min.css b/templates/project/assets/stylesheets/jquery.gridster.min.css new file mode 100644 index 00000000..4639de9d --- /dev/null +++ b/templates/project/assets/stylesheets/jquery.gridster.min.css @@ -0,0 +1,2 @@ +/*! gridster.js - v0.5.1 - 2014-03-26 - * http://gridster.net/ - Copyright (c) 2014 ducksboard; Licensed MIT */ +.gridster{position:relative}.gridster>*{margin:0 auto;-webkit-transition:height .4s,width .4s;-moz-transition:height .4s,width .4s;-o-transition:height .4s,width .4s;-ms-transition:height .4s,width .4s;transition:height .4s,width .4s}.gridster .gs-w{z-index:2;position:absolute}.ready .gs-w:not(.preview-holder){-webkit-transition:opacity .3s,left .3s,top .3s;-moz-transition:opacity .3s,left .3s,top .3s;-o-transition:opacity .3s,left .3s,top .3s;transition:opacity .3s,left .3s,top .3s}.ready .gs-w:not(.preview-holder),.ready .resize-preview-holder{-webkit-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-moz-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-o-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;transition:opacity .3s,left .3s,top .3s,width .3s,height .3s}.gridster .preview-holder{z-index:1;position:absolute;background-color:#fff;border-color:#fff;opacity:.3}.gridster .player-revert{z-index:10!important;-webkit-transition:left .3s,top .3s!important;-moz-transition:left .3s,top .3s!important;-o-transition:left .3s,top .3s!important;transition:left .3s,top .3s!important}.gridster .dragging,.gridster .resizing{z-index:10!important;-webkit-transition:all 0s!important;-moz-transition:all 0s!important;-o-transition:all 0s!important;transition:all 0s!important}.gs-resize-handle{position:absolute;z-index:1}.gs-resize-handle-both{width:20px;height:20px;bottom:-8px;right:-8px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=);background-position:top left;background-repeat:no-repeat;cursor:se-resize;z-index:20}.gs-resize-handle-x{top:0;bottom:13px;right:-5px;width:10px;cursor:e-resize}.gs-resize-handle-y{left:0;right:13px;bottom:-5px;height:10px;cursor:s-resize}.gs-w:hover .gs-resize-handle,.resizing .gs-resize-handle{opacity:1}.gs-resize-handle,.gs-w.dragging .gs-resize-handle{opacity:0}.gs-resize-disabled .gs-resize-handle{display:none!important}[data-max-sizex="1"] .gs-resize-handle-x,[data-max-sizey="1"] .gs-resize-handle-y,[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle{display:none!important} diff --git a/templates/project/config.ru b/templates/project/config.ru index 6e1076a0..624244ea 100644 --- a/templates/project/config.ru +++ b/templates/project/config.ru @@ -5,8 +5,8 @@ configure do helpers do def protected! - # Put any authentication code you want in here. - # This method is run before accessing any resource. + # Put any authentication code you want in here. + # This method is run before accessing any resource. end end end @@ -15,4 +15,4 @@ map Sinatra::Application.assets_prefix do run Sinatra::Application.sprockets end -run Sinatra::Application \ No newline at end of file +run Sinatra::Application diff --git a/templates/project/dashboards/layout.erb b/templates/project/dashboards/layout.erb index 23d3c9aa..eae97859 100644 --- a/templates/project/dashboards/layout.erb +++ b/templates/project/dashboards/layout.erb @@ -12,7 +12,7 @@ - + diff --git a/templates/project/dashboards/sample.erb b/templates/project/dashboards/sample.erb index 7435b565..08c3b512 100644 --- a/templates/project/dashboards/sample.erb +++ b/templates/project/dashboards/sample.erb @@ -1,4 +1,4 @@ -<% content_for(:title) { "My super sweet dashboard" } %> +<% content_for :title do %>My super sweet dashboard<% end %>
    • @@ -6,7 +6,7 @@
    • -
      +
    • @@ -22,4 +22,4 @@
    Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://<%=request.host%>:<%=request.port%>/widgets/welcome
    -
    \ No newline at end of file + diff --git a/templates/project/dashboards/sampletv.erb b/templates/project/dashboards/sampletv.erb index 7ac91126..6f3cb607 100644 --- a/templates/project/dashboards/sampletv.erb +++ b/templates/project/dashboards/sampletv.erb @@ -8,13 +8,13 @@ $(function() { -<% content_for(:title) { "1080p dashboard" } %> +<% content_for :title do %>1080p dashboard<% end %>
    • - +
    • @@ -39,18 +39,18 @@ $(function() {
    • - +
    • -
      +
    • - +
    Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://<%=request.host%>:<%=request.port%>/widgets/welcome
    -
    \ No newline at end of file + diff --git a/templates/project/jobs/twitter.rb b/templates/project/jobs/twitter.rb index 9359a89f..7b2bd6fb 100644 --- a/templates/project/jobs/twitter.rb +++ b/templates/project/jobs/twitter.rb @@ -1,17 +1,28 @@ -require 'net/http' -require 'json' +require 'twitter' + + +#### Get your twitter keys & secrets: +#### https://dev.twitter.com/docs/auth/tokens-devtwittercom +twitter = Twitter::REST::Client.new do |config| + config.consumer_key = 'YOUR_CONSUMER_KEY' + config.consumer_secret = 'YOUR_CONSUMER_SECRET' + config.access_token = 'YOUR_OAUTH_TOKEN' + config.access_token_secret = 'YOUR_OAUTH_SECRET' +end search_term = URI::encode('#todayilearned') SCHEDULER.every '10m', :first_in => 0 do |job| - http = Net::HTTP.new('search.twitter.com') - response = http.request(Net::HTTP::Get.new("/search.json?q=#{search_term}")) - tweets = JSON.parse(response.body)["results"] - if tweets - tweets.map! do |tweet| - { name: tweet['from_user'], body: tweet['text'], avatar: tweet['profile_image_url_https'] } + begin + tweets = twitter.search("#{search_term}") + + if tweets + tweets = tweets.map do |tweet| + { name: tweet.user.name, body: tweet.text, avatar: tweet.user.profile_image_url_https } + end + send_event('twitter_mentions', comments: tweets) end - - send_event('twitter_mentions', comments: tweets) + rescue Twitter::Error + puts "\e[33mFor the twitter widget to work, you need to put in your twitter API keys in the jobs/twitter.rb file.\e[0m" end end \ No newline at end of file diff --git a/templates/project/public/404.html b/templates/project/public/404.html new file mode 100644 index 00000000..1a8f334e --- /dev/null +++ b/templates/project/public/404.html @@ -0,0 +1,26 @@ + + + + This Dashboard doesn't exist. + + + + + +
    +

    Drats! That Dashboard doesn't exist.

    +

    You may have mistyped the address or the page may have moved.

    +
    + + \ No newline at end of file diff --git a/templates/project/assets/images/favicon.ico b/templates/project/public/favicon.ico similarity index 100% rename from templates/project/assets/images/favicon.ico rename to templates/project/public/favicon.ico diff --git a/templates/project/widgets/clock/clock.scss b/templates/project/widgets/clock/clock.scss index 831ea943..19e91bf1 100644 --- a/templates/project/widgets/clock/clock.scss +++ b/templates/project/widgets/clock/clock.scss @@ -6,8 +6,8 @@ $background-color: #dc5945; // ---------------------------------------------------------------------------- // Widget-clock styles // ---------------------------------------------------------------------------- -.widget-clock { +.widget-clock { background-color: $background-color; - -} \ No newline at end of file + +} diff --git a/templates/project/widgets/comments/comments.coffee b/templates/project/widgets/comments/comments.coffee index 1e81b56c..ff659ecc 100644 --- a/templates/project/widgets/comments/comments.coffee +++ b/templates/project/widgets/comments/comments.coffee @@ -21,4 +21,4 @@ class Dashing.Comments extends Dashing.Widget @commentElem.fadeOut => @currentIndex = (@currentIndex + 1) % comments.length @set 'current_comment', comments[@currentIndex] - @commentElem.fadeIn() \ No newline at end of file + @commentElem.fadeIn() diff --git a/templates/project/widgets/comments/comments.html b/templates/project/widgets/comments/comments.html index 844800f4..7c580be1 100644 --- a/templates/project/widgets/comments/comments.html +++ b/templates/project/widgets/comments/comments.html @@ -1,7 +1,7 @@

    -

    +

    -

    \ No newline at end of file +

    diff --git a/templates/project/widgets/comments/comments.scss b/templates/project/widgets/comments/comments.scss index 40e2a6b3..2ace30ec 100644 --- a/templates/project/widgets/comments/comments.scss +++ b/templates/project/widgets/comments/comments.scss @@ -9,11 +9,11 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); // ---------------------------------------------------------------------------- // Widget-comment styles // ---------------------------------------------------------------------------- -.widget-comments { +.widget-comments { background-color: $background-color; - - .title { + + .title { color: $title-color; margin-bottom: 15px; } @@ -29,5 +29,5 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); .more-info { color: $moreinfo-color; } - -} \ No newline at end of file + +} diff --git a/templates/project/widgets/graph/graph.coffee b/templates/project/widgets/graph/graph.coffee index 9b2eeec2..5d6b9abe 100644 --- a/templates/project/widgets/graph/graph.coffee +++ b/templates/project/widgets/graph/graph.coffee @@ -15,12 +15,14 @@ class Dashing.Graph extends Dashing.Widget element: @node width: width height: height + renderer: @get("graphtype") series: [ { color: "#fff", data: [{x:0, y:0}] } ] + padding: {top: 0.02, left: 0.02, right: 0.02, bottom: 0.02} ) @graph.series[0].data = @get('points') if @get('points') diff --git a/templates/project/widgets/graph/graph.html b/templates/project/widgets/graph/graph.html index d1794db1..786bbb73 100644 --- a/templates/project/widgets/graph/graph.html +++ b/templates/project/widgets/graph/graph.html @@ -1,5 +1,5 @@

    -

    +

    -

    \ No newline at end of file +

    diff --git a/templates/project/widgets/graph/graph.scss b/templates/project/widgets/graph/graph.scss index 71cd4d41..1000b6ff 100644 --- a/templates/project/widgets/graph/graph.scss +++ b/templates/project/widgets/graph/graph.scss @@ -11,7 +11,7 @@ $tick-color: rgba(0, 0, 0, 0.4); // ---------------------------------------------------------------------------- // Widget-graph styles // ---------------------------------------------------------------------------- -.widget-graph { +.widget-graph { background-color: $background-color; position: relative; @@ -30,7 +30,7 @@ $tick-color: rgba(0, 0, 0, 0.4); z-index: 99; } - .title { + .title { color: $title-color; } @@ -51,7 +51,7 @@ $tick-color: rgba(0, 0, 0, 0.4); padding-bottom: 3px; } } - + .y_ticks { font-size: 20px; fill: $tick-color; @@ -62,4 +62,4 @@ $tick-color: rgba(0, 0, 0, 0.4); display: none; } -} \ No newline at end of file +} diff --git a/templates/project/widgets/iframe/iframe.coffee b/templates/project/widgets/iframe/iframe.coffee index 4d4ca9a8..e3ee9477 100644 --- a/templates/project/widgets/iframe/iframe.coffee +++ b/templates/project/widgets/iframe/iframe.coffee @@ -6,4 +6,4 @@ class Dashing.Iframe extends Dashing.Widget onData: (data) -> # Handle incoming data # You can access the html node of this widget with `@node` - # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. \ No newline at end of file + # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. diff --git a/templates/project/widgets/iframe/iframe.html b/templates/project/widgets/iframe/iframe.html index bfccba4e..385f6daa 100644 --- a/templates/project/widgets/iframe/iframe.html +++ b/templates/project/widgets/iframe/iframe.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/templates/project/widgets/iframe/iframe.scss b/templates/project/widgets/iframe/iframe.scss index 7c757bfc..6827a1b7 100644 --- a/templates/project/widgets/iframe/iframe.scss +++ b/templates/project/widgets/iframe/iframe.scss @@ -1,8 +1,8 @@ -.widget-iframe { +.widget-iframe { padding: 3px 0px 0px 0px !important; iframe { width: 100%; height: 100%; } -} \ No newline at end of file +} diff --git a/templates/project/widgets/image/image.coffee b/templates/project/widgets/image/image.coffee index 418e385c..c3892c0d 100644 --- a/templates/project/widgets/image/image.coffee +++ b/templates/project/widgets/image/image.coffee @@ -6,4 +6,4 @@ class Dashing.Image extends Dashing.Widget onData: (data) -> # Handle incoming data # You can access the html node of this widget with `@node` - # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. \ No newline at end of file + # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. diff --git a/templates/project/widgets/image/image.html b/templates/project/widgets/image/image.html index cf2b2287..41a88eb9 100644 --- a/templates/project/widgets/image/image.html +++ b/templates/project/widgets/image/image.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/templates/project/widgets/image/image.scss b/templates/project/widgets/image/image.scss index 10ca81d6..0b1a3163 100644 --- a/templates/project/widgets/image/image.scss +++ b/templates/project/widgets/image/image.scss @@ -6,8 +6,8 @@ $background-color: #4b4b4b; // ---------------------------------------------------------------------------- // Widget-image styles // ---------------------------------------------------------------------------- -.widget-image { +.widget-image { background-color: $background-color; -} \ No newline at end of file +} diff --git a/templates/project/widgets/list/list.coffee b/templates/project/widgets/list/list.coffee index 3cbf7a14..00280731 100644 --- a/templates/project/widgets/list/list.coffee +++ b/templates/project/widgets/list/list.coffee @@ -3,4 +3,4 @@ class Dashing.List extends Dashing.Widget if @get('unordered') $(@node).find('ol').remove() else - $(@node).find('ul').remove() \ No newline at end of file + $(@node).find('ul').remove() diff --git a/templates/project/widgets/list/list.html b/templates/project/widgets/list/list.html index 86752bff..07e04716 100644 --- a/templates/project/widgets/list/list.html +++ b/templates/project/widgets/list/list.html @@ -15,4 +15,4 @@

    -

    \ No newline at end of file +

    diff --git a/templates/project/widgets/list/list.scss b/templates/project/widgets/list/list.scss index 90b6c841..bce70105 100644 --- a/templates/project/widgets/list/list.scss +++ b/templates/project/widgets/list/list.scss @@ -11,12 +11,12 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); // ---------------------------------------------------------------------------- // Widget-list styles // ---------------------------------------------------------------------------- -.widget-list { +.widget-list { background-color: $background-color; vertical-align: top; - .title { + .title { color: $title-color; } @@ -39,7 +39,7 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); } .label { - color: $label-color; + color: $label-color; } .value { @@ -57,4 +57,4 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); color: $moreinfo-color; } -} \ No newline at end of file +} diff --git a/templates/project/widgets/meter/meter.coffee b/templates/project/widgets/meter/meter.coffee index 0e0a8ad3..b823ec7a 100644 --- a/templates/project/widgets/meter/meter.coffee +++ b/templates/project/widgets/meter/meter.coffee @@ -11,4 +11,4 @@ class Dashing.Meter extends Dashing.Widget meter = $(@node).find(".meter") meter.attr("data-bgcolor", meter.css("background-color")) meter.attr("data-fgcolor", meter.css("color")) - meter.knob() \ No newline at end of file + meter.knob() diff --git a/templates/project/widgets/meter/meter.html b/templates/project/widgets/meter/meter.html index 7d51b15c..72592fb1 100644 --- a/templates/project/widgets/meter/meter.html +++ b/templates/project/widgets/meter/meter.html @@ -1,7 +1,7 @@

    - +

    -

    \ No newline at end of file +

    diff --git a/templates/project/widgets/meter/meter.scss b/templates/project/widgets/meter/meter.scss index 98cf638c..da9ff0b4 100644 --- a/templates/project/widgets/meter/meter.scss +++ b/templates/project/widgets/meter/meter.scss @@ -11,16 +11,16 @@ $meter-background: darken($background-color, 15%); // ---------------------------------------------------------------------------- // Widget-meter styles // ---------------------------------------------------------------------------- -.widget-meter { +.widget-meter { background-color: $background-color; - - input.meter { + + input.meter { background-color: $meter-background; color: #fff; } - .title { + .title { color: $title-color; } @@ -31,5 +31,5 @@ $meter-background: darken($background-color, 15%); .updated-at { color: rgba(0, 0, 0, 0.3); } - -} \ No newline at end of file + +} diff --git a/templates/project/widgets/number/number.coffee b/templates/project/widgets/number/number.coffee index 46cd6c24..0e5950c0 100644 --- a/templates/project/widgets/number/number.coffee +++ b/templates/project/widgets/number/number.coffee @@ -13,8 +13,12 @@ class Dashing.Number extends Dashing.Widget @accessor 'arrow', -> if @get('last') - if parseInt(@get('current')) > parseInt(@get('last')) then 'icon-arrow-up' else 'icon-arrow-down' + if parseInt(@get('current')) > parseInt(@get('last')) then 'fa fa-arrow-up' else 'fa fa-arrow-down' onData: (data) -> if data.status - $(@get('node')).addClass("status-#{data.status}") \ No newline at end of file + # clear existing "status-*" classes + $(@get('node')).attr 'class', (i,c) -> + c.replace /\bstatus-\S+/g, '' + # add new class + $(@get('node')).addClass "status-#{data.status}" diff --git a/templates/project/widgets/number/number.html b/templates/project/widgets/number/number.html index d7eeab9d..c82e5f4a 100644 --- a/templates/project/widgets/number/number.html +++ b/templates/project/widgets/number/number.html @@ -1,11 +1,11 @@

    -

    +

    -

    +

    -

    +

    diff --git a/templates/project/widgets/number/number.scss b/templates/project/widgets/number/number.scss index 608624b5..88757941 100644 --- a/templates/project/widgets/number/number.scss +++ b/templates/project/widgets/number/number.scss @@ -4,17 +4,17 @@ $background-color: #47bbb3; $value-color: #fff; -$title-color: rgba(255, 255, 255, 0.7);; -$moreinfo-color: rgba(255, 255, 255, 0.7);; +$title-color: rgba(255, 255, 255, 0.7); +$moreinfo-color: rgba(255, 255, 255, 0.7); // ---------------------------------------------------------------------------- // Widget-number styles // ---------------------------------------------------------------------------- -.widget-number { +.widget-number { background-color: $background-color; - - .title { + + .title { color: $title-color; } @@ -35,5 +35,5 @@ $moreinfo-color: rgba(255, 255, 255, 0.7);; .updated-at { color: rgba(0, 0, 0, 0.3); } - -} \ No newline at end of file + +} diff --git a/templates/project/widgets/text/text.coffee b/templates/project/widgets/text/text.coffee index 05974b82..1741d8b4 100644 --- a/templates/project/widgets/text/text.coffee +++ b/templates/project/widgets/text/text.coffee @@ -1 +1 @@ -class Dashing.Text extends Dashing.Widget \ No newline at end of file +class Dashing.Text extends Dashing.Widget diff --git a/templates/project/widgets/text/text.html b/templates/project/widgets/text/text.html index 45322ca2..decd109d 100644 --- a/templates/project/widgets/text/text.html +++ b/templates/project/widgets/text/text.html @@ -1,7 +1,7 @@

    -

    +

    -

    +

    -

    \ No newline at end of file +

    diff --git a/templates/project/widgets/text/text.scss b/templates/project/widgets/text/text.scss index 4e6c6e3f..45d790ee 100644 --- a/templates/project/widgets/text/text.scss +++ b/templates/project/widgets/text/text.scss @@ -9,11 +9,11 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); // ---------------------------------------------------------------------------- // Widget-text styles // ---------------------------------------------------------------------------- -.widget-text { +.widget-text { background-color: $background-color; - - .title { + + .title { color: $title-color; } @@ -24,9 +24,9 @@ $moreinfo-color: rgba(255, 255, 255, 0.7); .updated-at { color: rgba(255, 255, 255, 0.7); } - + &.large h3 { font-size: 65px; } -} \ No newline at end of file +} diff --git a/templates/widget/%name%/%name%.scss.tt b/templates/widget/%name%/%name%.scss.tt index 0da5c496..660a554b 100644 --- a/templates/widget/%name%/%name%.scss.tt +++ b/templates/widget/%name%/%name%.scss.tt @@ -1,3 +1,3 @@ -.widget-<%= name %> { +.widget-<%= Dashing::CLI.hyphenate(name) %> { } \ No newline at end of file diff --git a/test/app_test.rb b/test/app_test.rb new file mode 100644 index 00000000..36cd3100 --- /dev/null +++ b/test/app_test.rb @@ -0,0 +1,166 @@ +require 'test_helper' +require 'haml' + +class AppTest < Dashing::Test + def setup + @connection = [] + app.settings.connections = [@connection] + app.settings.auth_token = nil + app.settings.default_dashboard = nil + app.settings.history_file = File.join(Dir.tmpdir, 'history.yml') + end + + def test_redirect_to_first_dashboard + with_generated_project do + get '/' + assert_equal 302, last_response.status + assert_equal 'http://example.org/sample', last_response.location + end + end + + def test_redirect_to_first_dashboard_without_erb + with_generated_project do |dir| + FileUtils.touch(File.join(dir, "dashboards/htmltest.html")) + get '/' + assert_equal 302, last_response.status + assert_equal 'http://example.org/htmltest', last_response.location + end + end + + def test_redirect_to_default_dashboard + with_generated_project do + app.settings.default_dashboard = 'test1' + get '/' + assert_equal 302, last_response.status + assert_equal 'http://example.org/test1', last_response.location + end + end + + def test_errors_out_when_no_dashboards_available + with_generated_project do + app.settings.views = File.join(app.settings.root, 'lib') + + get '/' + assert_equal 500, last_response.status + end + end + + def test_post_widgets_without_auth_token + post '/widgets/some_widget', JSON.generate({value: 6}) + assert_equal 204, last_response.status + + assert_equal 1, @connection.length + data = parse_data @connection[0] + assert_equal 6, data['value'] + assert_equal 'some_widget', data['id'] + assert data['updatedAt'] + end + + def test_post_widgets_with_invalid_auth_token + app.settings.auth_token = 'sekrit' + post '/widgets/some_widget', JSON.generate({value: 9}) + assert_equal 401, last_response.status + end + + def test_post_widgets_with_valid_auth_token + app.settings.auth_token = 'sekrit' + post '/widgets/some_widget', JSON.generate({value: 9, auth_token: 'sekrit'}) + assert_equal 204, last_response.status + end + + def test_get_events + post '/widgets/some_widget', JSON.generate({value: 8}) + assert_equal 204, last_response.status + + get '/events' + assert_equal 200, last_response.status + assert_equal 8, parse_data(@connection[0])['value'] + end + + def test_dashboard_events + post '/dashboards/my_super_sweet_dashboard', JSON.generate({event: 'reload'}) + assert_equal 204, last_response.status + + get '/events' + assert_equal 200, last_response.status + assert_equal 'dashboards', parse_event(@connection[0]) + assert_equal 'reload', parse_data(@connection[0])['event'] + end + + def test_get_dashboard + with_generated_project do + get '/sampletv' + assert_equal 200, last_response.status + assert_includes last_response.body, 'class="gridster"' + assert_includes last_response.body, "DOCTYPE" + end + end + + def test_page_title_set_correctly + with_generated_project do + get '/sampletv' + assert_includes last_response.body, '1080p dashboard' + end + end + + def test_get_haml_dashboard + with_generated_project do |dir| + File.write(File.join(dir, 'dashboards/hamltest.haml'), '.gridster') + get '/hamltest' + assert_equal 200, last_response.status + assert_includes last_response.body, "class='gridster'" + end + end + + def test_get_haml_widget + with_generated_project do |dir| + File.write(File.join(dir, 'widgets/clock/clock.haml'), '%h1 haml') + File.unlink(File.join(dir, 'widgets/clock/clock.html')) + get '/views/clock.html' + assert_equal 200, last_response.status + assert_includes last_response.body, '

    haml

    ' + end + end + + def test_get_nonexistent_dashboard + with_generated_project do + get '/nodashboard' + assert_equal 404, last_response.status + end + end + + def test_get_widget + with_generated_project do + get '/views/meter.html' + assert_equal 200, last_response.status + assert_includes last_response.body, 'class="meter"' + end + end + + def with_generated_project + source_path = File.expand_path('../../templates', __FILE__) + + temp do |dir| + cli = Dashing::CLI.new + cli.stubs(:source_paths).returns([source_path]) + silent { cli.new 'new_project' } + + app.settings.public_folder = File.join(dir, 'new_project/public') + app.settings.views = File.join(dir, 'new_project/dashboards') + app.settings.root = File.join(dir, 'new_project') + yield app.settings.root + end + end + + def app + Sinatra::Application + end + + def parse_data(string) + JSON.parse string[/data: (.+)/, 1] + end + + def parse_event(string) + string[/event: (.+)/, 1] + end +end diff --git a/test/cli_test.rb b/test/cli_test.rb new file mode 100644 index 00000000..4d822969 --- /dev/null +++ b/test/cli_test.rb @@ -0,0 +1,168 @@ +require 'test_helper' + +class CLITest < Dashing::Test + def setup + @cli = Dashing::CLI.new + end + + def test_new_task_creates_project_directory + app_name = 'custom_dashboard' + @cli.stubs(:directory).with(:project, app_name).once + @cli.new(app_name) + end + + def test_generate_task_delegates_to_type + types = %w(widget dashboard job) + + types.each do |type| + @cli.stubs(:public_send).with("generate_#{type}".to_sym, 'name').once + @cli.generate(type, 'name') + end + end + + def test_generate_task_warns_when_generator_is_not_defined + output, _ = capture_io do + @cli.generate('wtf', 'name') + end + + assert_includes output, 'Invalid generator' + end + + def test_generate_widget_creates_a_new_widget + @cli.stubs(:directory).with(:widget, 'widgets').once + @cli.generate_widget('WidgetName') + assert_equal 'widget_name', @cli.name + end + + def test_generate_dashboard_creates_a_new_dashboard + @cli.stubs(:directory).with(:dashboard, 'dashboards').once + @cli.generate_dashboard('DashBoardName') + assert_equal 'dash_board_name', @cli.name + end + + def test_generate_job_creates_a_new_job + @cli.stubs(:directory).with(:job, 'jobs').once + @cli.generate_job('MyCustomJob') + assert_equal 'my_custom_job', @cli.name + end + + def test_install_task_requests_gist_from_downloader + return_value = { 'files' => [] } + Dashing::Downloader.stubs(:get_gist).with(123).returns(return_value).once + + capture_io { @cli.install(123) } + end + + def test_install_task_calls_create_file_for_each_valid_file_in_gist + json_response = <<-JSON + { + "files": { + "ruby_job.rb": { "content": "some job content" }, + "num.html": { "content": "some html content" }, + "num.scss": { "content": "some sass content" }, + "num.coffee": { "content": "some coffee content" } + } + } + JSON + + Dir.stubs(:pwd).returns('') + + Dashing::Downloader.stubs(:get_gist).returns(JSON.parse(json_response)) + @cli.stubs(:create_file).with('/jobs/ruby_job.rb', 'some job content', {:skip => false}).once + @cli.stubs(:create_file).with('/widgets/num/num.html', 'some html content', {:skip => false}).once + @cli.stubs(:create_file).with('/widgets/num/num.scss', 'some sass content', {:skip => false}).once + @cli.stubs(:create_file).with('/widgets/num/num.coffee', 'some coffee content', {:skip => false}).once + + capture_io { @cli.install(123) } + end + + def test_install_task_ignores_invalid_files + json_response = <<-JSON + { + "files": { + "ruby_job.js": { "content": "some job content" }, + "num.css": { "content": "some sass content" } + } + } + JSON + + Dashing::Downloader.stubs(:get_gist).returns(JSON.parse(json_response)) + @cli.stubs(:create_file).never + + capture_io { @cli.install(123) } + end + + def test_install_task_warns_when_gist_not_found + error = OpenURI::HTTPError.new('error', mock()) + Dashing::Downloader.stubs(:get_gist).raises(error) + + output, _ = capture_io { @cli.install(123) } + + assert_includes output, 'Could not find gist at ' + end + + def test_start_task_starts_thin_with_default_port + command = 'bundle exec thin -R config.ru start -p 3030 ' + @cli.stubs(:run_command).with(command).once + @cli.start + end + + def test_start_task_starts_thin_with_specified_port + command = 'bundle exec thin -R config.ru start -p 2020' + @cli.stubs(:run_command).with(command).once + @cli.start('-p', '2020') + end + + def test_start_task_supports_job_path_option + commands = [ + 'export JOB_PATH=other_spot; ', + 'bundle exec thin -R config.ru start -p 3030 ' + ] + + @cli.stubs(:options).returns(job_path: 'other_spot') + @cli.stubs(:run_command).with(commands.join('')).once + @cli.start + end + + def test_stop_task_stops_thin_server + @cli.stubs(:run_command).with('bundle exec thin stop') + @cli.stop + end + + def test_job_task_requires_job_file + Dir.stubs(:pwd).returns('') + @cli.stubs(:require_file).with('/jobs/special_job.rb').once + + @cli.job('special_job') + end + + def test_job_task_requires_every_ruby_file_in_lib + Dir.stubs(:pwd).returns('') + Dir.stubs(:[]).returns(['lib/dashing/cli.rb', 'lib/dashing.rb']) + @cli.stubs(:require_file).times(3) + + @cli.job('special_job') + end + + def test_job_sets_auth_token + @cli.class.stubs(:auth_token=).with('my_token').once + @cli.stubs(:require_file) + + @cli.job('my_job', 'my_token') + end + + def test_hyphenate_lowers_and_hyphenates_inputs + assertion_map = { + 'Power' => 'power', + 'POWER' => 'power', + 'PowerRangers' => 'power-rangers', + 'Power_ranger' => 'power-ranger', + 'SuperPowerRangers' => 'super-power-rangers' + } + + assertion_map.each do |input, expected| + assert_equal expected, Dashing::CLI.hyphenate(input) + end + end + +end diff --git a/test/downloader_test.rb b/test/downloader_test.rb new file mode 100644 index 00000000..930ad56f --- /dev/null +++ b/test/downloader_test.rb @@ -0,0 +1,26 @@ +require 'test_helper' + +class DownloaderTest < Minitest::Test + + def test_get_json_requests_and_parses_content + endpoint = 'http://somehost.com/file.json' + response = '{ "name": "value" }' + FakeWeb.register_uri(:get, endpoint, body: response) + JSON.stubs(:parse).with(response).once + + Dashing::Downloader.get_json(endpoint) + end + + def test_get_json_raises_on_bad_request + FakeWeb.register_uri(:get, 'http://dead-host.com/', status: '404') + + assert_raises(OpenURI::HTTPError) do + Dashing::Downloader.get_json('http://dead-host.com/') + end + end + + def test_load_gist_attempts_to_get_the_gist + Dashing::Downloader.stubs(:get_json).once + Dashing::Downloader.get_gist(123) + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 00000000..0b719f52 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,49 @@ +require 'simplecov' +SimpleCov.start do + add_filter "/vendor/" + add_filter "/test/" +end + +require 'rack/test' +require 'stringio' +require 'tmpdir' +require 'fakeweb' +require 'minitest/autorun' +require 'minitest/pride' +require 'mocha/setup' + +require_relative '../lib/dashing' + +FakeWeb.allow_net_connect = false + +ENV['RACK_ENV'] = 'test' +WORKING_DIRECTORY = Dir.pwd.freeze +ARGV.clear + +def load_quietly(file) + Minitest::Test.new(nil).capture_io do + load file + end +end + +def temp + path = File.expand_path "#{Dir.tmpdir}/#{Time.now.to_i}#{rand(1000)}/" + FileUtils.mkdir_p path + Dir.chdir path + yield path +ensure + Dir.chdir WORKING_DIRECTORY + FileUtils.rm_rf(path) if File.exists?(path) +end + +module Dashing + class Test < Minitest::Test + include Rack::Test::Methods + + alias_method :silent, :capture_io + + def teardown + FileUtils.rm_f('history.yml') + end + end +end