PageRenderTime 155ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 2ms

/public/js/myapp.js

https://github.com/robertd/benm
JavaScript | 15790 lines | 10428 code | 2454 blank | 2908 comment | 2832 complexity | 45d5867476733b3433bd7ccb65eee9e3 MD5 | raw file
  1. require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"cy31T3":[function(require,module,exports){
  2. var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};(function browserifyShim(module, exports, define, browserify_shim__define__module__export__) {
  3. ; global.$ = require("jquery");
  4. global.Backbone = require("backbone");
  5. global._ = require("underscore");
  6. // MarionetteJS (Backbone.Marionette)
  7. // ----------------------------------
  8. // v1.4.1
  9. //
  10. // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
  11. // Distributed under MIT license
  12. //
  13. // http://marionettejs.com
  14. /*!
  15. * Includes BabySitter
  16. * https://github.com/marionettejs/backbone.babysitter/
  17. *
  18. * Includes Wreqr
  19. * https://github.com/marionettejs/backbone.wreqr/
  20. */
  21. // Backbone.BabySitter
  22. // -------------------
  23. // v0.0.6
  24. //
  25. // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
  26. // Distributed under MIT license
  27. //
  28. // http://github.com/babysitterjs/backbone.babysitter
  29. // Backbone.ChildViewContainer
  30. // ---------------------------
  31. //
  32. // Provide a container to store, retrieve and
  33. // shut down child views.
  34. Backbone.ChildViewContainer = (function(Backbone, _){
  35. // Container Constructor
  36. // ---------------------
  37. var Container = function(views){
  38. this._views = {};
  39. this._indexByModel = {};
  40. this._indexByCustom = {};
  41. this._updateLength();
  42. _.each(views, this.add, this);
  43. };
  44. // Container Methods
  45. // -----------------
  46. _.extend(Container.prototype, {
  47. // Add a view to this container. Stores the view
  48. // by `cid` and makes it searchable by the model
  49. // cid (and model itself). Optionally specify
  50. // a custom key to store an retrieve the view.
  51. add: function(view, customIndex){
  52. var viewCid = view.cid;
  53. // store the view
  54. this._views[viewCid] = view;
  55. // index it by model
  56. if (view.model){
  57. this._indexByModel[view.model.cid] = viewCid;
  58. }
  59. // index by custom
  60. if (customIndex){
  61. this._indexByCustom[customIndex] = viewCid;
  62. }
  63. this._updateLength();
  64. },
  65. // Find a view by the model that was attached to
  66. // it. Uses the model's `cid` to find it.
  67. findByModel: function(model){
  68. return this.findByModelCid(model.cid);
  69. },
  70. // Find a view by the `cid` of the model that was attached to
  71. // it. Uses the model's `cid` to find the view `cid` and
  72. // retrieve the view using it.
  73. findByModelCid: function(modelCid){
  74. var viewCid = this._indexByModel[modelCid];
  75. return this.findByCid(viewCid);
  76. },
  77. // Find a view by a custom indexer.
  78. findByCustom: function(index){
  79. var viewCid = this._indexByCustom[index];
  80. return this.findByCid(viewCid);
  81. },
  82. // Find by index. This is not guaranteed to be a
  83. // stable index.
  84. findByIndex: function(index){
  85. return _.values(this._views)[index];
  86. },
  87. // retrieve a view by it's `cid` directly
  88. findByCid: function(cid){
  89. return this._views[cid];
  90. },
  91. // Remove a view
  92. remove: function(view){
  93. var viewCid = view.cid;
  94. // delete model index
  95. if (view.model){
  96. delete this._indexByModel[view.model.cid];
  97. }
  98. // delete custom index
  99. _.any(this._indexByCustom, function(cid, key) {
  100. if (cid === viewCid) {
  101. delete this._indexByCustom[key];
  102. return true;
  103. }
  104. }, this);
  105. // remove the view from the container
  106. delete this._views[viewCid];
  107. // update the length
  108. this._updateLength();
  109. },
  110. // Call a method on every view in the container,
  111. // passing parameters to the call method one at a
  112. // time, like `function.call`.
  113. call: function(method){
  114. this.apply(method, _.tail(arguments));
  115. },
  116. // Apply a method on every view in the container,
  117. // passing parameters to the call method one at a
  118. // time, like `function.apply`.
  119. apply: function(method, args){
  120. _.each(this._views, function(view){
  121. if (_.isFunction(view[method])){
  122. view[method].apply(view, args || []);
  123. }
  124. });
  125. },
  126. // Update the `.length` attribute on this container
  127. _updateLength: function(){
  128. this.length = _.size(this._views);
  129. }
  130. });
  131. // Borrowing this code from Backbone.Collection:
  132. // http://backbonejs.org/docs/backbone.html#section-106
  133. //
  134. // Mix in methods from Underscore, for iteration, and other
  135. // collection related features.
  136. var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
  137. 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
  138. 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
  139. 'last', 'without', 'isEmpty', 'pluck'];
  140. _.each(methods, function(method) {
  141. Container.prototype[method] = function() {
  142. var views = _.values(this._views);
  143. var args = [views].concat(_.toArray(arguments));
  144. return _[method].apply(_, args);
  145. };
  146. });
  147. // return the public API
  148. return Container;
  149. })(Backbone, _);
  150. // Backbone.Wreqr (Backbone.Marionette)
  151. // ----------------------------------
  152. // v0.2.0
  153. //
  154. // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
  155. // Distributed under MIT license
  156. //
  157. // http://github.com/marionettejs/backbone.wreqr
  158. Backbone.Wreqr = (function(Backbone, Marionette, _){
  159. "use strict";
  160. var Wreqr = {};
  161. // Handlers
  162. // --------
  163. // A registry of functions to call, given a name
  164. Wreqr.Handlers = (function(Backbone, _){
  165. "use strict";
  166. // Constructor
  167. // -----------
  168. var Handlers = function(options){
  169. this.options = options;
  170. this._wreqrHandlers = {};
  171. if (_.isFunction(this.initialize)){
  172. this.initialize(options);
  173. }
  174. };
  175. Handlers.extend = Backbone.Model.extend;
  176. // Instance Members
  177. // ----------------
  178. _.extend(Handlers.prototype, Backbone.Events, {
  179. // Add multiple handlers using an object literal configuration
  180. setHandlers: function(handlers){
  181. _.each(handlers, function(handler, name){
  182. var context = null;
  183. if (_.isObject(handler) && !_.isFunction(handler)){
  184. context = handler.context;
  185. handler = handler.callback;
  186. }
  187. this.setHandler(name, handler, context);
  188. }, this);
  189. },
  190. // Add a handler for the given name, with an
  191. // optional context to run the handler within
  192. setHandler: function(name, handler, context){
  193. var config = {
  194. callback: handler,
  195. context: context
  196. };
  197. this._wreqrHandlers[name] = config;
  198. this.trigger("handler:add", name, handler, context);
  199. },
  200. // Determine whether or not a handler is registered
  201. hasHandler: function(name){
  202. return !! this._wreqrHandlers[name];
  203. },
  204. // Get the currently registered handler for
  205. // the specified name. Throws an exception if
  206. // no handler is found.
  207. getHandler: function(name){
  208. var config = this._wreqrHandlers[name];
  209. if (!config){
  210. throw new Error("Handler not found for '" + name + "'");
  211. }
  212. return function(){
  213. var args = Array.prototype.slice.apply(arguments);
  214. return config.callback.apply(config.context, args);
  215. };
  216. },
  217. // Remove a handler for the specified name
  218. removeHandler: function(name){
  219. delete this._wreqrHandlers[name];
  220. },
  221. // Remove all handlers from this registry
  222. removeAllHandlers: function(){
  223. this._wreqrHandlers = {};
  224. }
  225. });
  226. return Handlers;
  227. })(Backbone, _);
  228. // Wreqr.CommandStorage
  229. // --------------------
  230. //
  231. // Store and retrieve commands for execution.
  232. Wreqr.CommandStorage = (function(){
  233. "use strict";
  234. // Constructor function
  235. var CommandStorage = function(options){
  236. this.options = options;
  237. this._commands = {};
  238. if (_.isFunction(this.initialize)){
  239. this.initialize(options);
  240. }
  241. };
  242. // Instance methods
  243. _.extend(CommandStorage.prototype, Backbone.Events, {
  244. // Get an object literal by command name, that contains
  245. // the `commandName` and the `instances` of all commands
  246. // represented as an array of arguments to process
  247. getCommands: function(commandName){
  248. var commands = this._commands[commandName];
  249. // we don't have it, so add it
  250. if (!commands){
  251. // build the configuration
  252. commands = {
  253. command: commandName,
  254. instances: []
  255. };
  256. // store it
  257. this._commands[commandName] = commands;
  258. }
  259. return commands;
  260. },
  261. // Add a command by name, to the storage and store the
  262. // args for the command
  263. addCommand: function(commandName, args){
  264. var command = this.getCommands(commandName);
  265. command.instances.push(args);
  266. },
  267. // Clear all commands for the given `commandName`
  268. clearCommands: function(commandName){
  269. var command = this.getCommands(commandName);
  270. command.instances = [];
  271. }
  272. });
  273. return CommandStorage;
  274. })();
  275. // Wreqr.Commands
  276. // --------------
  277. //
  278. // A simple command pattern implementation. Register a command
  279. // handler and execute it.
  280. Wreqr.Commands = (function(Wreqr){
  281. "use strict";
  282. return Wreqr.Handlers.extend({
  283. // default storage type
  284. storageType: Wreqr.CommandStorage,
  285. constructor: function(options){
  286. this.options = options || {};
  287. this._initializeStorage(this.options);
  288. this.on("handler:add", this._executeCommands, this);
  289. var args = Array.prototype.slice.call(arguments);
  290. Wreqr.Handlers.prototype.constructor.apply(this, args);
  291. },
  292. // Execute a named command with the supplied args
  293. execute: function(name, args){
  294. name = arguments[0];
  295. args = Array.prototype.slice.call(arguments, 1);
  296. if (this.hasHandler(name)){
  297. this.getHandler(name).apply(this, args);
  298. } else {
  299. this.storage.addCommand(name, args);
  300. }
  301. },
  302. // Internal method to handle bulk execution of stored commands
  303. _executeCommands: function(name, handler, context){
  304. var command = this.storage.getCommands(name);
  305. // loop through and execute all the stored command instances
  306. _.each(command.instances, function(args){
  307. handler.apply(context, args);
  308. });
  309. this.storage.clearCommands(name);
  310. },
  311. // Internal method to initialize storage either from the type's
  312. // `storageType` or the instance `options.storageType`.
  313. _initializeStorage: function(options){
  314. var storage;
  315. var StorageType = options.storageType || this.storageType;
  316. if (_.isFunction(StorageType)){
  317. storage = new StorageType();
  318. } else {
  319. storage = StorageType;
  320. }
  321. this.storage = storage;
  322. }
  323. });
  324. })(Wreqr);
  325. // Wreqr.RequestResponse
  326. // ---------------------
  327. //
  328. // A simple request/response implementation. Register a
  329. // request handler, and return a response from it
  330. Wreqr.RequestResponse = (function(Wreqr){
  331. "use strict";
  332. return Wreqr.Handlers.extend({
  333. request: function(){
  334. var name = arguments[0];
  335. var args = Array.prototype.slice.call(arguments, 1);
  336. return this.getHandler(name).apply(this, args);
  337. }
  338. });
  339. })(Wreqr);
  340. // Event Aggregator
  341. // ----------------
  342. // A pub-sub object that can be used to decouple various parts
  343. // of an application through event-driven architecture.
  344. Wreqr.EventAggregator = (function(Backbone, _){
  345. "use strict";
  346. var EA = function(){};
  347. // Copy the `extend` function used by Backbone's classes
  348. EA.extend = Backbone.Model.extend;
  349. // Copy the basic Backbone.Events on to the event aggregator
  350. _.extend(EA.prototype, Backbone.Events);
  351. return EA;
  352. })(Backbone, _);
  353. return Wreqr;
  354. })(Backbone, Backbone.Marionette, _);
  355. var Marionette = (function(global, Backbone, _){
  356. "use strict";
  357. // Define and export the Marionette namespace
  358. var Marionette = {};
  359. Backbone.Marionette = Marionette;
  360. // Get the DOM manipulator for later use
  361. Marionette.$ = Backbone.$;
  362. // Helpers
  363. // -------
  364. // For slicing `arguments` in functions
  365. var protoSlice = Array.prototype.slice;
  366. function slice(args) {
  367. return protoSlice.call(args);
  368. }
  369. function throwError(message, name) {
  370. var error = new Error(message);
  371. error.name = name || 'Error';
  372. throw error;
  373. }
  374. // Marionette.extend
  375. // -----------------
  376. // Borrow the Backbone `extend` method so we can use it as needed
  377. Marionette.extend = Backbone.Model.extend;
  378. // Marionette.getOption
  379. // --------------------
  380. // Retrieve an object, function or other value from a target
  381. // object or its `options`, with `options` taking precedence.
  382. Marionette.getOption = function(target, optionName){
  383. if (!target || !optionName){ return; }
  384. var value;
  385. if (target.options && (optionName in target.options) && (target.options[optionName] !== undefined)){
  386. value = target.options[optionName];
  387. } else {
  388. value = target[optionName];
  389. }
  390. return value;
  391. };
  392. // Trigger an event and/or a corresponding method name. Examples:
  393. //
  394. // `this.triggerMethod("foo")` will trigger the "foo" event and
  395. // call the "onFoo" method.
  396. //
  397. // `this.triggerMethod("foo:bar") will trigger the "foo:bar" event and
  398. // call the "onFooBar" method.
  399. Marionette.triggerMethod = (function(){
  400. // split the event name on the :
  401. var splitter = /(^|:)(\w)/gi;
  402. // take the event section ("section1:section2:section3")
  403. // and turn it in to uppercase name
  404. function getEventName(match, prefix, eventName) {
  405. return eventName.toUpperCase();
  406. }
  407. // actual triggerMethod name
  408. var triggerMethod = function(event) {
  409. // get the method name from the event name
  410. var methodName = 'on' + event.replace(splitter, getEventName);
  411. var method = this[methodName];
  412. // trigger the event, if a trigger method exists
  413. if(_.isFunction(this.trigger)) {
  414. this.trigger.apply(this, arguments);
  415. }
  416. // call the onMethodName if it exists
  417. if (_.isFunction(method)) {
  418. // pass all arguments, except the event name
  419. return method.apply(this, _.tail(arguments));
  420. }
  421. };
  422. return triggerMethod;
  423. })();
  424. // DOMRefresh
  425. // ----------
  426. //
  427. // Monitor a view's state, and after it has been rendered and shown
  428. // in the DOM, trigger a "dom:refresh" event every time it is
  429. // re-rendered.
  430. Marionette.MonitorDOMRefresh = (function(){
  431. // track when the view has been shown in the DOM,
  432. // using a Marionette.Region (or by other means of triggering "show")
  433. function handleShow(view){
  434. view._isShown = true;
  435. triggerDOMRefresh(view);
  436. }
  437. // track when the view has been rendered
  438. function handleRender(view){
  439. view._isRendered = true;
  440. triggerDOMRefresh(view);
  441. }
  442. // Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
  443. function triggerDOMRefresh(view){
  444. if (view._isShown && view._isRendered){
  445. if (_.isFunction(view.triggerMethod)){
  446. view.triggerMethod("dom:refresh");
  447. }
  448. }
  449. }
  450. // Export public API
  451. return function(view){
  452. view.listenTo(view, "show", function(){
  453. handleShow(view);
  454. });
  455. view.listenTo(view, "render", function(){
  456. handleRender(view);
  457. });
  458. };
  459. })();
  460. // Marionette.bindEntityEvents & unbindEntityEvents
  461. // ---------------------------
  462. //
  463. // These methods are used to bind/unbind a backbone "entity" (collection/model)
  464. // to methods on a target object.
  465. //
  466. // The first parameter, `target`, must have a `listenTo` method from the
  467. // EventBinder object.
  468. //
  469. // The second parameter is the entity (Backbone.Model or Backbone.Collection)
  470. // to bind the events from.
  471. //
  472. // The third parameter is a hash of { "event:name": "eventHandler" }
  473. // configuration. Multiple handlers can be separated by a space. A
  474. // function can be supplied instead of a string handler name.
  475. (function(Marionette){
  476. "use strict";
  477. // Bind the event to handlers specified as a string of
  478. // handler names on the target object
  479. function bindFromStrings(target, entity, evt, methods){
  480. var methodNames = methods.split(/\s+/);
  481. _.each(methodNames,function(methodName) {
  482. var method = target[methodName];
  483. if(!method) {
  484. throwError("Method '"+ methodName +"' was configured as an event handler, but does not exist.");
  485. }
  486. target.listenTo(entity, evt, method, target);
  487. });
  488. }
  489. // Bind the event to a supplied callback function
  490. function bindToFunction(target, entity, evt, method){
  491. target.listenTo(entity, evt, method, target);
  492. }
  493. // Bind the event to handlers specified as a string of
  494. // handler names on the target object
  495. function unbindFromStrings(target, entity, evt, methods){
  496. var methodNames = methods.split(/\s+/);
  497. _.each(methodNames,function(methodName) {
  498. var method = target[methodName];
  499. target.stopListening(entity, evt, method, target);
  500. });
  501. }
  502. // Bind the event to a supplied callback function
  503. function unbindToFunction(target, entity, evt, method){
  504. target.stopListening(entity, evt, method, target);
  505. }
  506. // generic looping function
  507. function iterateEvents(target, entity, bindings, functionCallback, stringCallback){
  508. if (!entity || !bindings) { return; }
  509. // allow the bindings to be a function
  510. if (_.isFunction(bindings)){
  511. bindings = bindings.call(target);
  512. }
  513. // iterate the bindings and bind them
  514. _.each(bindings, function(methods, evt){
  515. // allow for a function as the handler,
  516. // or a list of event names as a string
  517. if (_.isFunction(methods)){
  518. functionCallback(target, entity, evt, methods);
  519. } else {
  520. stringCallback(target, entity, evt, methods);
  521. }
  522. });
  523. }
  524. // Export Public API
  525. Marionette.bindEntityEvents = function(target, entity, bindings){
  526. iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);
  527. };
  528. Marionette.unbindEntityEvents = function(target, entity, bindings){
  529. iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);
  530. };
  531. })(Marionette);
  532. // Callbacks
  533. // ---------
  534. // A simple way of managing a collection of callbacks
  535. // and executing them at a later point in time, using jQuery's
  536. // `Deferred` object.
  537. Marionette.Callbacks = function(){
  538. this._deferred = Marionette.$.Deferred();
  539. this._callbacks = [];
  540. };
  541. _.extend(Marionette.Callbacks.prototype, {
  542. // Add a callback to be executed. Callbacks added here are
  543. // guaranteed to execute, even if they are added after the
  544. // `run` method is called.
  545. add: function(callback, contextOverride){
  546. this._callbacks.push({cb: callback, ctx: contextOverride});
  547. this._deferred.done(function(context, options){
  548. if (contextOverride){ context = contextOverride; }
  549. callback.call(context, options);
  550. });
  551. },
  552. // Run all registered callbacks with the context specified.
  553. // Additional callbacks can be added after this has been run
  554. // and they will still be executed.
  555. run: function(options, context){
  556. this._deferred.resolve(context, options);
  557. },
  558. // Resets the list of callbacks to be run, allowing the same list
  559. // to be run multiple times - whenever the `run` method is called.
  560. reset: function(){
  561. var callbacks = this._callbacks;
  562. this._deferred = Marionette.$.Deferred();
  563. this._callbacks = [];
  564. _.each(callbacks, function(cb){
  565. this.add(cb.cb, cb.ctx);
  566. }, this);
  567. }
  568. });
  569. // Marionette Controller
  570. // ---------------------
  571. //
  572. // A multi-purpose object to use as a controller for
  573. // modules and routers, and as a mediator for workflow
  574. // and coordination of other objects, views, and more.
  575. Marionette.Controller = function(options){
  576. this.triggerMethod = Marionette.triggerMethod;
  577. this.options = options || {};
  578. if (_.isFunction(this.initialize)){
  579. this.initialize(this.options);
  580. }
  581. };
  582. Marionette.Controller.extend = Marionette.extend;
  583. // Controller Methods
  584. // --------------
  585. // Ensure it can trigger events with Backbone.Events
  586. _.extend(Marionette.Controller.prototype, Backbone.Events, {
  587. close: function(){
  588. this.stopListening();
  589. this.triggerMethod("close");
  590. this.unbind();
  591. }
  592. });
  593. // Region
  594. // ------
  595. //
  596. // Manage the visual regions of your composite application. See
  597. // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
  598. Marionette.Region = function(options){
  599. this.options = options || {};
  600. this.el = Marionette.getOption(this, "el");
  601. if (!this.el){
  602. var err = new Error("An 'el' must be specified for a region.");
  603. err.name = "NoElError";
  604. throw err;
  605. }
  606. if (this.initialize){
  607. var args = Array.prototype.slice.apply(arguments);
  608. this.initialize.apply(this, args);
  609. }
  610. };
  611. // Region Type methods
  612. // -------------------
  613. _.extend(Marionette.Region, {
  614. // Build an instance of a region by passing in a configuration object
  615. // and a default region type to use if none is specified in the config.
  616. //
  617. // The config object should either be a string as a jQuery DOM selector,
  618. // a Region type directly, or an object literal that specifies both
  619. // a selector and regionType:
  620. //
  621. // ```js
  622. // {
  623. // selector: "#foo",
  624. // regionType: MyCustomRegion
  625. // }
  626. // ```
  627. //
  628. buildRegion: function(regionConfig, defaultRegionType){
  629. var regionIsString = (typeof regionConfig === "string");
  630. var regionSelectorIsString = (typeof regionConfig.selector === "string");
  631. var regionTypeIsUndefined = (typeof regionConfig.regionType === "undefined");
  632. var regionIsType = (typeof regionConfig === "function");
  633. if (!regionIsType && !regionIsString && !regionSelectorIsString) {
  634. throw new Error("Region must be specified as a Region type, a selector string or an object with selector property");
  635. }
  636. var selector, RegionType;
  637. // get the selector for the region
  638. if (regionIsString) {
  639. selector = regionConfig;
  640. }
  641. if (regionConfig.selector) {
  642. selector = regionConfig.selector;
  643. }
  644. // get the type for the region
  645. if (regionIsType){
  646. RegionType = regionConfig;
  647. }
  648. if (!regionIsType && regionTypeIsUndefined) {
  649. RegionType = defaultRegionType;
  650. }
  651. if (regionConfig.regionType) {
  652. RegionType = regionConfig.regionType;
  653. }
  654. // build the region instance
  655. var region = new RegionType({
  656. el: selector
  657. });
  658. // override the `getEl` function if we have a parentEl
  659. // this must be overridden to ensure the selector is found
  660. // on the first use of the region. if we try to assign the
  661. // region's `el` to `parentEl.find(selector)` in the object
  662. // literal to build the region, the element will not be
  663. // guaranteed to be in the DOM already, and will cause problems
  664. if (regionConfig.parentEl){
  665. region.getEl = function(selector) {
  666. var parentEl = regionConfig.parentEl;
  667. if (_.isFunction(parentEl)){
  668. parentEl = parentEl();
  669. }
  670. return parentEl.find(selector);
  671. };
  672. }
  673. return region;
  674. }
  675. });
  676. // Region Instance Methods
  677. // -----------------------
  678. _.extend(Marionette.Region.prototype, Backbone.Events, {
  679. // Displays a backbone view instance inside of the region.
  680. // Handles calling the `render` method for you. Reads content
  681. // directly from the `el` attribute. Also calls an optional
  682. // `onShow` and `close` method on your view, just after showing
  683. // or just before closing the view, respectively.
  684. show: function(view){
  685. this.ensureEl();
  686. var isViewClosed = view.isClosed || _.isUndefined(view.$el);
  687. var isDifferentView = view !== this.currentView;
  688. if (isDifferentView) {
  689. this.close();
  690. }
  691. view.render();
  692. if (isDifferentView || isViewClosed) {
  693. this.open(view);
  694. }
  695. this.currentView = view;
  696. Marionette.triggerMethod.call(this, "show", view);
  697. Marionette.triggerMethod.call(view, "show");
  698. },
  699. ensureEl: function(){
  700. if (!this.$el || this.$el.length === 0){
  701. this.$el = this.getEl(this.el);
  702. }
  703. },
  704. // Override this method to change how the region finds the
  705. // DOM element that it manages. Return a jQuery selector object.
  706. getEl: function(selector){
  707. return Marionette.$(selector);
  708. },
  709. // Override this method to change how the new view is
  710. // appended to the `$el` that the region is managing
  711. open: function(view){
  712. this.$el.empty().append(view.el);
  713. },
  714. // Close the current view, if there is one. If there is no
  715. // current view, it does nothing and returns immediately.
  716. close: function(){
  717. var view = this.currentView;
  718. if (!view || view.isClosed){ return; }
  719. // call 'close' or 'remove', depending on which is found
  720. if (view.close) { view.close(); }
  721. else if (view.remove) { view.remove(); }
  722. Marionette.triggerMethod.call(this, "close");
  723. delete this.currentView;
  724. },
  725. // Attach an existing view to the region. This
  726. // will not call `render` or `onShow` for the new view,
  727. // and will not replace the current HTML for the `el`
  728. // of the region.
  729. attachView: function(view){
  730. this.currentView = view;
  731. },
  732. // Reset the region by closing any existing view and
  733. // clearing out the cached `$el`. The next time a view
  734. // is shown via this region, the region will re-query the
  735. // DOM for the region's `el`.
  736. reset: function(){
  737. this.close();
  738. delete this.$el;
  739. }
  740. });
  741. // Copy the `extend` function used by Backbone's classes
  742. Marionette.Region.extend = Marionette.extend;
  743. // Marionette.RegionManager
  744. // ------------------------
  745. //
  746. // Manage one or more related `Marionette.Region` objects.
  747. Marionette.RegionManager = (function(Marionette){
  748. var RegionManager = Marionette.Controller.extend({
  749. constructor: function(options){
  750. this._regions = {};
  751. Marionette.Controller.prototype.constructor.call(this, options);
  752. },
  753. // Add multiple regions using an object literal, where
  754. // each key becomes the region name, and each value is
  755. // the region definition.
  756. addRegions: function(regionDefinitions, defaults){
  757. var regions = {};
  758. _.each(regionDefinitions, function(definition, name){
  759. if (typeof definition === "string"){
  760. definition = { selector: definition };
  761. }
  762. if (definition.selector){
  763. definition = _.defaults({}, definition, defaults);
  764. }
  765. var region = this.addRegion(name, definition);
  766. regions[name] = region;
  767. }, this);
  768. return regions;
  769. },
  770. // Add an individual region to the region manager,
  771. // and return the region instance
  772. addRegion: function(name, definition){
  773. var region;
  774. var isObject = _.isObject(definition);
  775. var isString = _.isString(definition);
  776. var hasSelector = !!definition.selector;
  777. if (isString || (isObject && hasSelector)){
  778. region = Marionette.Region.buildRegion(definition, Marionette.Region);
  779. } else if (_.isFunction(definition)){
  780. region = Marionette.Region.buildRegion(definition, Marionette.Region);
  781. } else {
  782. region = definition;
  783. }
  784. this._store(name, region);
  785. this.triggerMethod("region:add", name, region);
  786. return region;
  787. },
  788. // Get a region by name
  789. get: function(name){
  790. return this._regions[name];
  791. },
  792. // Remove a region by name
  793. removeRegion: function(name){
  794. var region = this._regions[name];
  795. this._remove(name, region);
  796. },
  797. // Close all regions in the region manager, and
  798. // remove them
  799. removeRegions: function(){
  800. _.each(this._regions, function(region, name){
  801. this._remove(name, region);
  802. }, this);
  803. },
  804. // Close all regions in the region manager, but
  805. // leave them attached
  806. closeRegions: function(){
  807. _.each(this._regions, function(region, name){
  808. region.close();
  809. }, this);
  810. },
  811. // Close all regions and shut down the region
  812. // manager entirely
  813. close: function(){
  814. this.removeRegions();
  815. var args = Array.prototype.slice.call(arguments);
  816. Marionette.Controller.prototype.close.apply(this, args);
  817. },
  818. // internal method to store regions
  819. _store: function(name, region){
  820. this._regions[name] = region;
  821. this._setLength();
  822. },
  823. // internal method to remove a region
  824. _remove: function(name, region){
  825. region.close();
  826. delete this._regions[name];
  827. this._setLength();
  828. this.triggerMethod("region:remove", name, region);
  829. },
  830. // set the number of regions current held
  831. _setLength: function(){
  832. this.length = _.size(this._regions);
  833. }
  834. });
  835. // Borrowing this code from Backbone.Collection:
  836. // http://backbonejs.org/docs/backbone.html#section-106
  837. //
  838. // Mix in methods from Underscore, for iteration, and other
  839. // collection related features.
  840. var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
  841. 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
  842. 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
  843. 'last', 'without', 'isEmpty', 'pluck'];
  844. _.each(methods, function(method) {
  845. RegionManager.prototype[method] = function() {
  846. var regions = _.values(this._regions);
  847. var args = [regions].concat(_.toArray(arguments));
  848. return _[method].apply(_, args);
  849. };
  850. });
  851. return RegionManager;
  852. })(Marionette);
  853. // Template Cache
  854. // --------------
  855. // Manage templates stored in `<script>` blocks,
  856. // caching them for faster access.
  857. Marionette.TemplateCache = function(templateId){
  858. this.templateId = templateId;
  859. };
  860. // TemplateCache object-level methods. Manage the template
  861. // caches from these method calls instead of creating
  862. // your own TemplateCache instances
  863. _.extend(Marionette.TemplateCache, {
  864. templateCaches: {},
  865. // Get the specified template by id. Either
  866. // retrieves the cached version, or loads it
  867. // from the DOM.
  868. get: function(templateId){
  869. var cachedTemplate = this.templateCaches[templateId];
  870. if (!cachedTemplate){
  871. cachedTemplate = new Marionette.TemplateCache(templateId);
  872. this.templateCaches[templateId] = cachedTemplate;
  873. }
  874. return cachedTemplate.load();
  875. },
  876. // Clear templates from the cache. If no arguments
  877. // are specified, clears all templates:
  878. // `clear()`
  879. //
  880. // If arguments are specified, clears each of the
  881. // specified templates from the cache:
  882. // `clear("#t1", "#t2", "...")`
  883. clear: function(){
  884. var i;
  885. var args = slice(arguments);
  886. var length = args.length;
  887. if (length > 0){
  888. for(i=0; i<length; i++){
  889. delete this.templateCaches[args[i]];
  890. }
  891. } else {
  892. this.templateCaches = {};
  893. }
  894. }
  895. });
  896. // TemplateCache instance methods, allowing each
  897. // template cache object to manage its own state
  898. // and know whether or not it has been loaded
  899. _.extend(Marionette.TemplateCache.prototype, {
  900. // Internal method to load the template
  901. load: function(){
  902. // Guard clause to prevent loading this template more than once
  903. if (this.compiledTemplate){
  904. return this.compiledTemplate;
  905. }
  906. // Load the template and compile it
  907. var template = this.loadTemplate(this.templateId);
  908. this.compiledTemplate = this.compileTemplate(template);
  909. return this.compiledTemplate;
  910. },
  911. // Load a template from the DOM, by default. Override
  912. // this method to provide your own template retrieval
  913. // For asynchronous loading with AMD/RequireJS, consider
  914. // using a template-loader plugin as described here:
  915. // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs
  916. loadTemplate: function(templateId){
  917. var template = Marionette.$(templateId).html();
  918. if (!template || template.length === 0){
  919. throwError("Could not find template: '" + templateId + "'", "NoTemplateError");
  920. }
  921. return template;
  922. },
  923. // Pre-compile the template before caching it. Override
  924. // this method if you do not need to pre-compile a template
  925. // (JST / RequireJS for example) or if you want to change
  926. // the template engine used (Handebars, etc).
  927. compileTemplate: function(rawTemplate){
  928. return _.template(rawTemplate);
  929. }
  930. });
  931. // Renderer
  932. // --------
  933. // Render a template with data by passing in the template
  934. // selector and the data to render.
  935. Marionette.Renderer = {
  936. // Render a template with data. The `template` parameter is
  937. // passed to the `TemplateCache` object to retrieve the
  938. // template function. Override this method to provide your own
  939. // custom rendering and template handling for all of Marionette.
  940. render: function(template, data){
  941. if (!template) {
  942. var error = new Error("Cannot render the template since it's false, null or undefined.");
  943. error.name = "TemplateNotFoundError";
  944. throw error;
  945. }
  946. var templateFunc;
  947. if (typeof template === "function"){
  948. templateFunc = template;
  949. } else {
  950. templateFunc = Marionette.TemplateCache.get(template);
  951. }
  952. return templateFunc(data);
  953. }
  954. };
  955. // Marionette.View
  956. // ---------------
  957. // The core view type that other Marionette views extend from.
  958. Marionette.View = Backbone.View.extend({
  959. constructor: function(options){
  960. _.bindAll(this, "render");
  961. var args = Array.prototype.slice.apply(arguments);
  962. // this exposes view options to the view initializer
  963. // this is a backfill since backbone removed the assignment
  964. // of this.options
  965. // at some point however this may be removed
  966. this.options = _.extend({}, this.options, options);
  967. // parses out the @ui DSL for events
  968. this.events = this.normalizeUIKeys(_.result(this, 'events'));
  969. Backbone.View.prototype.constructor.apply(this, args);
  970. Marionette.MonitorDOMRefresh(this);
  971. this.listenTo(this, "show", this.onShowCalled, this);
  972. },
  973. // import the "triggerMethod" to trigger events with corresponding
  974. // methods if the method exists
  975. triggerMethod: Marionette.triggerMethod,
  976. // Get the template for this view
  977. // instance. You can set a `template` attribute in the view
  978. // definition or pass a `template: "whatever"` parameter in
  979. // to the constructor options.
  980. getTemplate: function(){
  981. return Marionette.getOption(this, "template");
  982. },
  983. // Mix in template helper methods. Looks for a
  984. // `templateHelpers` attribute, which can either be an
  985. // object literal, or a function that returns an object
  986. // literal. All methods and attributes from this object
  987. // are copies to the object passed in.
  988. mixinTemplateHelpers: function(target){
  989. target = target || {};
  990. var templateHelpers = Marionette.getOption(this, "templateHelpers");
  991. if (_.isFunction(templateHelpers)){
  992. templateHelpers = templateHelpers.call(this);
  993. }
  994. return _.extend(target, templateHelpers);
  995. },
  996. // allows for the use of the @ui. syntax within
  997. // a given key for triggers and events
  998. // swaps the @ui with the associated selector
  999. normalizeUIKeys: function(hash) {
  1000. if (typeof(hash) === "undefined") {
  1001. return;
  1002. }
  1003. _.each(_.keys(hash), function(v) {
  1004. var split = v.split("@ui.");
  1005. if (split.length === 2) {
  1006. hash[split[0]+this.ui[split[1]]] = hash[v];
  1007. delete hash[v];
  1008. }
  1009. }, this);
  1010. return hash;
  1011. },
  1012. // Configure `triggers` to forward DOM events to view
  1013. // events. `triggers: {"click .foo": "do:foo"}`
  1014. configureTriggers: function(){
  1015. if (!this.triggers) { return; }
  1016. var triggerEvents = {};
  1017. // Allow `triggers` to be configured as a function
  1018. var triggers = this.normalizeUIKeys(_.result(this, "triggers"));
  1019. // Configure the triggers, prevent default
  1020. // action and stop propagation of DOM events
  1021. _.each(triggers, function(value, key){
  1022. var hasOptions = _.isObject(value);
  1023. var eventName = hasOptions ? value.event : value;
  1024. // build the event handler function for the DOM event
  1025. triggerEvents[key] = function(e){
  1026. // stop the event in its tracks
  1027. if (e) {
  1028. var prevent = e.preventDefault;
  1029. var stop = e.stopPropagation;
  1030. var shouldPrevent = hasOptions ? value.preventDefault : prevent;
  1031. var shouldStop = hasOptions ? value.stopPropagation : stop;
  1032. if (shouldPrevent && prevent) { prevent.apply(e); }
  1033. if (shouldStop && stop) { stop.apply(e); }
  1034. }
  1035. // build the args for the event
  1036. var args = {
  1037. view: this,
  1038. model: this.model,
  1039. collection: this.collection
  1040. };
  1041. // trigger the event
  1042. this.triggerMethod(eventName, args);
  1043. };
  1044. }, this);
  1045. return triggerEvents;
  1046. },
  1047. // Overriding Backbone.View's delegateEvents to handle
  1048. // the `triggers`, `modelEvents`, and `collectionEvents` configuration
  1049. delegateEvents: function(events){
  1050. this._delegateDOMEvents(events);
  1051. Marionette.bindEntityEvents(this, this.model, Marionette.getOption(this, "modelEvents"));
  1052. Marionette.bindEntityEvents(this, this.collection, Marionette.getOption(this, "collectionEvents"));
  1053. },
  1054. // internal method to delegate DOM events and triggers
  1055. _delegateDOMEvents: function(events){
  1056. events = events || this.events;
  1057. if (_.isFunction(events)){ events = events.call(this); }
  1058. var combinedEvents = {};
  1059. var triggers = this.configureTriggers();
  1060. _.extend(combinedEvents, events, triggers);
  1061. Backbone.View.prototype.delegateEvents.call(this, combinedEvents);
  1062. },
  1063. // Overriding Backbone.View's undelegateEvents to handle unbinding
  1064. // the `triggers`, `modelEvents`, and `collectionEvents` config
  1065. undelegateEvents: function(){
  1066. var args = Array.prototype.slice.call(arguments);
  1067. Backbone.View.prototype.undelegateEvents.apply(this, args);
  1068. Marionette.unbindEntityEvents(this, this.model, Marionette.getOption(this, "modelEvents"));
  1069. Marionette.unbindEntityEvents(this, this.collection, Marionette.getOption(this, "collectionEvents"));
  1070. },
  1071. // Internal method, handles the `show` event.
  1072. onShowCalled: function(){},
  1073. // Default `close` implementation, for removing a view from the
  1074. // DOM and unbinding it. Regions will call this method
  1075. // for you. You can specify an `onClose` method in your view to
  1076. // add custom code that is called after the view is closed.
  1077. close: function(){
  1078. if (this.isClosed) { return; }
  1079. // allow the close to be stopped by returning `false`
  1080. // from the `onBeforeClose` method
  1081. var shouldClose = this.triggerMethod("before:close");
  1082. if (shouldClose === false){
  1083. return;
  1084. }
  1085. // mark as closed before doing the actual close, to
  1086. // prevent infinite loops within "close" event handlers
  1087. // that are trying to close other views
  1088. this.isClosed = true;
  1089. this.triggerMethod("close");
  1090. // unbind UI elements
  1091. this.unbindUIElements();
  1092. // remove the view from the DOM
  1093. this.remove();
  1094. },
  1095. // This method binds the elements specified in the "ui" hash inside the view's code with
  1096. // the associated jQuery selectors.
  1097. bindUIElements: function(){
  1098. if (!this.ui) { return; }
  1099. // store the ui hash in _uiBindings so they can be reset later
  1100. // and so re-rendering the view will be able to find the bindings
  1101. if (!this._uiBindings){
  1102. this._uiBindings = this.ui;
  1103. }
  1104. // get the bindings result, as a function or otherwise
  1105. var bindings = _.result(this, "_uiBindings");
  1106. // empty the ui so we don't have anything to start with
  1107. this.ui = {};
  1108. // bind each of the selectors
  1109. _.each(_.keys(bindings), function(key) {
  1110. var selector = bindings[key];
  1111. this.ui[key] = this.$(selector);
  1112. }, this);
  1113. },
  1114. // This method unbinds the elements specified in the "ui" hash
  1115. unbindUIElements: function(){
  1116. if (!this.ui || !this._uiBindings){ return; }
  1117. // delete all of the existing ui bindings
  1118. _.each(this.ui, function($el, name){
  1119. delete this.ui[name];
  1120. }, this);
  1121. // reset the ui element to the original bindings configuration
  1122. this.ui = this._uiBindings;
  1123. delete this._uiBindings;
  1124. }
  1125. });
  1126. // Item View
  1127. // ---------
  1128. // A single item view implementation that contains code for rendering
  1129. // with underscore.js templates, serializing the view's model or collection,
  1130. // and calling several methods on extended views, such as `onRender`.
  1131. Marionette.ItemView = Marionette.View.extend({
  1132. // Setting up the inheritance chain which allows changes to
  1133. // Marionette.View.prototype.constructor which allows overriding
  1134. constructor: function(){
  1135. Marionette.View.prototype.constructor.apply(this, slice(arguments));
  1136. },
  1137. // Serialize the model or collection for the view. If a model is
  1138. // found, `.toJSON()` is called. If a collection is found, `.toJSON()`
  1139. // is also called, but is used to populate an `items` array in the
  1140. // resulting data. If both are found, defaults to the model.
  1141. // You can override the `serializeData` method in your own view
  1142. // definition, to provide custom serialization for your view's data.
  1143. serializeData: function(){
  1144. var data = {};
  1145. if (this.model) {
  1146. data = this.model.toJSON();
  1147. }
  1148. else if (this.collection) {
  1149. data = { items: this.collection.toJSON() };
  1150. }
  1151. return data;
  1152. },
  1153. // Render the view, defaulting to underscore.js templates.
  1154. // You can override this in your view definition to provide
  1155. // a very specific rendering for your view. In general, though,
  1156. // you should override the `Marionette.Renderer` object to
  1157. // change how Marionette renders views.
  1158. render: function(){
  1159. this.isClosed = false;
  1160. this.triggerMethod("before:render", this);
  1161. this.triggerMethod("item:before:render", this);
  1162. var data = this.serializeData();
  1163. data = this.mixinTemplateHelpers(data);
  1164. var template = this.getTemplate();
  1165. var html = Marionette.Renderer.render(template, data);
  1166. this.$el.html(html);
  1167. this.bindUIElements();
  1168. this.triggerMethod("render", this);
  1169. this.triggerMethod("item:rendered", this);
  1170. return this;
  1171. },
  1172. // Override the default close event to add a few
  1173. // more events that are triggered.
  1174. close: function(){
  1175. if (this.isClosed){ return; }
  1176. this.triggerMethod('item:before:close');
  1177. Marionette.View.prototype.close.apply(this, slice(arguments));
  1178. this.triggerMethod('item:closed');
  1179. }
  1180. });
  1181. // Collection View
  1182. // ---------------
  1183. // A view that iterates over a Backbone.Collection
  1184. // and renders an individual ItemView for each model.
  1185. Marionette.CollectionView = Marionette.View.extend({
  1186. // used as the prefix for item view events
  1187. // that are forwarded through the collectionview
  1188. itemViewEventPrefix: "itemview",
  1189. // constructor
  1190. constructor: function(options){
  1191. this._initChildViewStorage();
  1192. Marionette.View.prototype.constructor.apply(this, slice(arguments));
  1193. this._initialEvents();
  1194. this.initRenderBuffer();
  1195. },
  1196. // Instead of inserting elements one by one into the page,
  1197. // it's much more performant to insert elements into a document
  1198. // fragment and then insert that document fragment into the page
  1199. initRenderBuffer: function() {
  1200. this.elBuffer = document.createDocumentFragment();
  1201. },
  1202. startBuffering: function() {
  1203. this.initRenderBuffer();
  1204. this.isBuffering = true;
  1205. },
  1206. endBuffering: function() {
  1207. this.appendBuffer(this, this.elBuffer);
  1208. this.initRenderBuffer();
  1209. this.isBuffering = false;
  1210. },
  1211. // Configured the initial events that the collection view
  1212. // binds to. Override this method to prevent the initial
  1213. // events, or to add your own initial events.
  1214. _initialEvents: function(){
  1215. if (this.collection){
  1216. this.listenTo(this.collection, "add", this.addChildView, this);
  1217. this.listenTo(this.collection, "remove", this.removeItemView, this);
  1218. this.listenTo(this.collection, "reset", this.render, this);
  1219. }
  1220. },
  1221. // Handle a child item added to the collection
  1222. addChildView: function(item, collection, options){
  1223. this.closeEmptyView();
  1224. var ItemView = this.getItemView(item);
  1225. var index = this.collection.indexOf(item);
  1226. this.addItemView(item, ItemView, index);
  1227. },
  1228. // Override from `Marionette.View` to guarantee the `onShow` method
  1229. // of child views is called.
  1230. onShowCalled: function(){
  1231. this.children.each(function(child){
  1232. Marionette.triggerMethod.call(child, "show");
  1233. });
  1234. },
  1235. // Internal method to trigger the before render callbacks
  1236. // and events
  1237. triggerBeforeRender: function(){
  1238. this.triggerMethod("before:render", this);
  1239. this.triggerMethod("collection:before:render", this);
  1240. },
  1241. // Internal method to trigger the rendered callbacks and
  1242. // events
  1243. triggerRendered: function(){
  1244. this.triggerMethod("render", this);
  1245. this.triggerMethod("collection:rendered", this);
  1246. },
  1247. // Render the collection of items. Override this method to
  1248. // provide your own implementation of a render function for
  1249. // the collection view.
  1250. render: function(){
  1251. this.isClosed = false;
  1252. this.triggerBeforeRender();
  1253. this._renderChildren();
  1254. this.triggerRendered();
  1255. return this;
  1256. },
  1257. // Internal method. Separated so that CompositeView can have
  1258. // more control over events being triggered, around the rendering
  1259. // process
  1260. _renderChildren: function(){
  1261. this.startBuffering();
  1262. this.closeEmptyView();
  1263. this.closeChildren();
  1264. if (this.collection && this.collection.length > 0) {
  1265. this.showCollection();
  1266. } else {
  1267. this.showEmptyView();
  1268. }
  1269. this.endBuffering();
  1270. },
  1271. // Internal method to loop through each item in the
  1272. // collection view and show it
  1273. showCollection: function(){
  1274. var ItemView;
  1275. this.collection.each(function(item, index){
  1276. ItemView = this.getItemView(item);
  1277. this.addItemView(item, ItemView, index);
  1278. }, this);
  1279. },
  1280. // Internal method to show an empty view in place of
  1281. // a collection of item views, when the collection is
  1282. // empty
  1283. showEmptyView: function(){
  1284. var EmptyView = this.getEmptyView();
  1285. if (EmptyView && !this._showingEmptyView){
  1286. this._showingEmptyView = true;
  1287. var model = new Backbone.Model();
  1288. this.addItemView(model, EmptyView, 0);
  1289. }
  1290. },
  1291. // Internal method to close an existing emptyView instance
  1292. // if one exists. Called when a collection view has been
  1293. // rendered empty, and then an item is added to the collection.
  1294. closeEmptyView: function(){
  1295. if (this._showingEmptyView){
  1296. this.closeChildren();
  1297. delete this._showingEmptyView;
  1298. }
  1299. },
  1300. // Retrieve the empty view type
  1301. getEmptyView: function(){
  1302. return Marionette.getOption(this, "emptyView");
  1303. },
  1304. // Retrieve the itemView type, either from `this.options.itemView`
  1305. // or from the `itemView` in the object definition. The "options"
  1306. // takes precedence.
  1307. getItemView: function(item){
  1308. var itemView = Marionette.getOption(this, "itemView");
  1309. if (!itemView){
  1310. throwError("An `itemView` must be specified", "NoItemViewError");
  1311. }
  1312. return itemView;
  1313. },
  1314. // Render the child item's view and add it to the
  1315. // HTML for the collection view.
  1316. addItemView: function(item, ItemView, index){
  1317. // get the itemViewOptions if any were specified
  1318. var itemViewOptions = Marionette.getOption(this, "itemViewOptions");
  1319. if (_.isFunction(itemViewOptions)){
  1320. itemViewOptions = itemViewOptions.call(this, item, index);
  1321. }
  1322. // build the view
  1323. var view = this.buildItemView(item, ItemView, itemViewOptions);
  1324. // set up the child view event forwarding
  1325. this.addChildViewEventForwarding(view);
  1326. // this view is about to be added
  1327. this.triggerMethod("before:item:added", view);
  1328. // Store the child view itself so we can properly
  1329. // remove and/or close it later
  1330. this.children.add(view);
  1331. // Render it and show it
  1332. this.renderItemView(view, index);
  1333. // call the "show" method if the collection view
  1334. // has already been shown
  1335. if (this._isShown){
  1336. Marionette.triggerMethod.call(view, "show");
  1337. }
  1338. // this view was added
  1339. this.triggerMethod("after:item:added", view);
  1340. },
  1341. // Set up the child view event forwarding. Uses an "itemview:"
  1342. // prefix in front of all forwarded events.
  1343. addChildViewEventForwarding: function(view){
  1344. var prefix = Marionette.getOption(this, "itemViewEventPrefix");
  1345. // Forward all child item view events through the parent,
  1346. // prepending "itemview:" to the event name
  1347. this.listenTo(view, "all", function(){
  1348. var args = slice(arguments);
  1349. args[0] = prefix + ":" + args[0];
  1350. args.splice(1, 0, view);
  1351. Marionette.triggerMethod.apply(this, args);
  1352. }, this);
  1353. },
  1354. // render the item view
  1355. renderItemView: function(view, index) {
  1356. view.render();
  1357. this.appendHtml(this, view, index);
  1358. },
  1359. // Build an `itemView` for every model in the collection.
  1360. buildItemView: function(item, ItemViewType, itemViewOptions){
  1361. var options = _.extend({model: item}, itemViewOptions);
  1362. return new ItemViewType(options);
  1363. },
  1364. // get the child view by item it holds, and remove it
  1365. removeItemView: function(item){
  1366. var view = this.children.findByModel(item);
  1367. this.removeChildView(view);
  1368. this.checkEmpty();
  1369. },
  1370. // Remove the child view and close it
  1371. removeChildView: function(view){
  1372. // shut down the child view properly,
  1373. // including events that the collection has from it
  1374. if (view){
  1375. this.stopListening(view);
  1376. // call 'close' or 'remove', depending on which is found
  1377. if (view.close) { view.close(); }
  1378. else if (view.remove) { view.remove(); }
  1379. this.children.remove(view);
  1380. }
  1381. this.triggerMethod("item:removed", view);
  1382. },
  1383. // helper to show the empty view if the collection is empty
  1384. checkEmpty: function() {
  1385. // check if we're empty now, and if we are, show the
  1386. // empty view
  1387. if (!this.collection || this.collection.length === 0){
  1388. this.showEmptyView();
  1389. }
  1390. },
  1391. // You might need to override this if you've overridden appendHtml
  1392. appendBuffer: function(collectionView, buffer) {
  1393. collectionView.$el.append(buffer);
  1394. },
  1395. // Append the HTML to the collection's `el`.
  1396. // Override this method to do something other
  1397. // then `.append`.
  1398. appendHtml: function(collectionView, itemView, index){
  1399. if (collectionView.isBuffering) {
  1400. // buffering happens on reset events and initial renders
  1401. // in order to reduce the number of inserts into the
  1402. // document, which are expensive.
  1403. collectionView.elBuffer.appendChild(itemView.el);
  1404. }
  1405. else {
  1406. // If we've already rendered the main collection, just
  1407. // append the new items directly into the element.
  1408. collectionView.$el.append(itemView.el);
  1409. }
  1410. },
  1411. // Internal method to set up the `children` object for
  1412. // storing all of the child views
  1413. _initChildViewStorage: function(){
  1414. this.children = new Backbone.ChildViewContainer();
  1415. },
  1416. // Handle cleanup and other closing needs for
  1417. // the collection of views.
  1418. close: function(){
  1419. if (this.isClosed){ return; }
  1420. this.triggerMethod("collection:before:close");
  1421. this.closeChildren();
  1422. this.triggerMethod("collection:closed");
  1423. Marionette.View.prototype.close.apply(this, slice(arguments));
  1424. },
  1425. // Close the child views that this collection view
  1426. // is holding on to, if any
  1427. closeChildren: function(){
  1428. this.children.each(function(child){
  1429. this.removeChildView(child);
  1430. }, this);
  1431. this.checkEmpty();
  1432. }
  1433. });
  1434. // Composite View
  1435. // --------------
  1436. // Used for rendering a branch-leaf, hierarchical structure.
  1437. // Extends directly from CollectionView and also renders an
  1438. // an item view as `modelView`, for the top leaf
  1439. Marionette.CompositeView = Marionette.CollectionView.extend({
  1440. // Setting up the inheritance chain which allows changes to
  1441. // Marionette.CollectionView.prototype.constructor which allows overriding
  1442. constructor: function(){
  1443. Marionette.CollectionView.prototype.constructor.apply(this, slice(arguments));
  1444. },
  1445. // Configured the initial events that the composite view
  1446. // binds to. Override this method to prevent the initial
  1447. // events, or to add your own initial events.
  1448. _initialEvents: function(){
  1449. // Bind only after composite view in rendered to avoid adding child views
  1450. // to unexisting itemViewContainer
  1451. this.once('render', function () {
  1452. if (this.collection){
  1453. this.listenTo(this.collection, "add", this.addChildView, this);
  1454. this.listenTo(this.collection, "remove", this.removeItemView, this);
  1455. this.listenTo(this.collection, "reset", this._renderChildren, this);
  1456. }
  1457. });
  1458. },
  1459. // Retrieve the `itemView` to be used when rendering each of
  1460. // the items in the collection. The default is to return
  1461. // `this.itemView` or Marionette.CompositeView if no `itemView`
  1462. // has been defined
  1463. getItemView: function(item){
  1464. var itemView = Marionette.getOption(this, "itemView") || this.constructor;
  1465. if (!itemView){
  1466. throwError("An `itemView` must be specified", "NoItemViewError");
  1467. }
  1468. return itemView;
  1469. },
  1470. // Serialize the collection for the view.
  1471. // You can override the `serializeData` method in your own view
  1472. // definition, to provide custom serialization for your view's data.
  1473. serializeData: function(){
  1474. var data = {};
  1475. if (this.model){
  1476. data = this.model.toJSON();
  1477. }
  1478. return data;
  1479. },
  1480. // Renders the model once, and the collection once. Calling
  1481. // this again will tell the model's view to re-render itself
  1482. // but the collection will not re-render.
  1483. render: function(){
  1484. this.isRendered = true;
  1485. this.isClosed = false;
  1486. this.resetItemViewContainer();
  1487. this.triggerBeforeRender();
  1488. var html = this.renderModel();
  1489. this.$el.html(html);
  1490. // the ui bindings is done here and not at the end of render since they
  1491. // will not be available until after the model is rendered, but should be
  1492. // available before the collection is rendered.
  1493. this.bindUIElements();
  1494. this.triggerMethod("composite:model:rendered");
  1495. this._renderChildren();
  1496. this.triggerMethod("composite:rendered");
  1497. this.triggerRendered();
  1498. return this;
  1499. },
  1500. _renderChildren: function(){
  1501. if (this.isRendered){
  1502. Marionette.CollectionView.prototype._renderChildren.call(this);
  1503. this.triggerMethod("composite:collection:rendered");
  1504. }
  1505. },
  1506. // Render an individual model, if we have one, as
  1507. // part of a composite view (branch / leaf). For example:
  1508. // a treeview.
  1509. renderModel: function(){
  1510. var data = {};
  1511. data = this.serializeData();
  1512. data = this.mixinTemplateHelpers(data);
  1513. var template = this.getTemplate();
  1514. return Marionette.Renderer.render(template, data);
  1515. },
  1516. // You might need to override this if you've overridden appendHtml
  1517. appendBuffer: function(compositeView, buffer) {
  1518. var $container = this.getItemViewContainer(compositeView);
  1519. $container.append(buffer);
  1520. },
  1521. // Appends the `el` of itemView instances to the specified
  1522. // `itemViewContainer` (a jQuery selector). Override this method to
  1523. // provide custom logic of how the child item view instances have their
  1524. // HTML appended to the composite view instance.
  1525. appendHtml: function(compositeView, itemView, index){
  1526. if (compositeView.isBuffering) {
  1527. compositeView.elBuffer.appendChild(itemView.el);
  1528. }
  1529. else {
  1530. // If we've already rendered the main collection, just
  1531. // append the new items directly into the element.
  1532. var $container = this.getItemViewContainer(compositeView);
  1533. $container.append(itemView.el);
  1534. }
  1535. },
  1536. // Internal method to ensure an `$itemViewContainer` exists, for the
  1537. // `appendHtml` method to use.
  1538. getItemViewContainer: function(containerView){
  1539. if ("$itemViewContainer" in containerView){
  1540. return containerView.$itemViewContainer;
  1541. }
  1542. var container;
  1543. var itemViewContainer = Marionette.getOption(containerView, "itemViewContainer");
  1544. if (itemViewContainer){
  1545. var selector = _.isFunction(itemViewContainer) ? itemViewContainer() : itemViewContainer;
  1546. container = containerView.$(selector);
  1547. if (container.length <= 0) {
  1548. throwError("The specified `itemViewContainer` was not found: " + containerView.itemViewContainer, "ItemViewContainerMissingError");
  1549. }
  1550. } else {
  1551. container = containerView.$el;
  1552. }
  1553. containerView.$itemViewContainer = container;
  1554. return container;
  1555. },
  1556. // Internal method to reset the `$itemViewContainer` on render
  1557. resetItemViewContainer: function(){
  1558. if (this.$itemViewContainer){
  1559. delete this.$itemViewContainer;
  1560. }
  1561. }
  1562. });
  1563. // Layout
  1564. // ------
  1565. // Used for managing application layouts, nested layouts and
  1566. // multiple regions within an application or sub-application.
  1567. //
  1568. // A specialized view type that renders an area of HTML and then
  1569. // attaches `Region` instances to the specified `regions`.
  1570. // Used for composite view management and sub-application areas.
  1571. Marionette.Layout = Marionette.ItemView.extend({
  1572. regionType: Marionette.Region,
  1573. // Ensure the regions are available when the `initialize` method
  1574. // is called.
  1575. constructor: function (options) {
  1576. options = options || {};
  1577. this._firstRender = true;
  1578. this._initializeRegions(options);
  1579. Marionette.ItemView.prototype.constructor.call(this, options);
  1580. },
  1581. // Layout's render will use the existing region objects the
  1582. // first time it is called. Subsequent calls will close the
  1583. // views that the regions are showing and then reset the `el`
  1584. // for the regions to the newly rendered DOM elements.
  1585. render: function(){
  1586. if (this.isClosed){
  1587. // a previously closed layout means we need to
  1588. // completely re-initialize the regions
  1589. this._initializeRegions();
  1590. }
  1591. if (this._firstRender) {
  1592. // if this is the first render, don't do anything to
  1593. // reset the regions
  1594. this._firstRender = false;
  1595. } else if (!this.isClosed){
  1596. // If this is not the first render call, then we need to
  1597. // re-initializing the `el` for each region
  1598. this._reInitializeRegions();
  1599. }
  1600. var args = Array.prototype.slice.apply(arguments);
  1601. var result = Marionette.ItemView.prototype.render.apply(this, args);
  1602. return result;
  1603. },
  1604. // Handle closing regions, and then close the view itself.
  1605. close: function () {
  1606. if (this.isClosed){ return; }
  1607. this.regionManager.close();
  1608. var args = Array.prototype.slice.apply(arguments);
  1609. Marionette.ItemView.prototype.close.apply(this, args);
  1610. },
  1611. // Add a single region, by name, to the layout
  1612. addRegion: function(name, definition){
  1613. var regions = {};
  1614. regions[name] = definition;
  1615. return this._buildRegions(regions)[name];
  1616. },
  1617. // Add multiple regions as a {name: definition, name2: def2} object literal
  1618. addRegions: function(regions){
  1619. this.regions = _.extend({}, this.regions, regions);
  1620. return this._buildRegions(regions);
  1621. },
  1622. // Remove a single region from the Layout, by name
  1623. removeRegion: function(name){
  1624. delete this.regions[name];
  1625. return this.regionManager.removeRegion(name);
  1626. },
  1627. // internal method to build regions
  1628. _buildRegions: function(regions){
  1629. var that = this;
  1630. var defaults = {
  1631. regionType: Marionette.getOption(this, "regionType"),
  1632. parentEl: function(){ return that.$el; }
  1633. };
  1634. return this.regionManager.addRegions(regions, defaults);
  1635. },
  1636. // Internal method to initialize the regions that have been defined in a
  1637. // `regions` attribute on this layout.
  1638. _initializeRegions: function (options) {
  1639. var regions;
  1640. this._initRegionManager();
  1641. if (_.isFunction(this.regions)) {
  1642. regions = this.regions(options);
  1643. } else {
  1644. regions = this.regions || {};
  1645. }
  1646. this.addRegions(regions);
  1647. },
  1648. // Internal method to re-initialize all of the regions by updating the `el` that
  1649. // they point to
  1650. _reInitializeRegions: function(){
  1651. this.regionManager.closeRegions();
  1652. this.regionManager.each(function(region){
  1653. region.reset();
  1654. });
  1655. },
  1656. // Internal method to initialize the region manager
  1657. // and all regions in it
  1658. _initRegionManager: function(){
  1659. this.regionManager = new Marionette.RegionManager();
  1660. this.listenTo(this.regionManager, "region:add", function(name, region){
  1661. this[name] = region;
  1662. this.trigger("region:add", name, region);
  1663. });
  1664. this.listenTo(this.regionManager, "region:remove", function(name, region){
  1665. delete this[name];
  1666. this.trigger("region:remove", name, region);
  1667. });
  1668. }
  1669. });
  1670. // AppRouter
  1671. // ---------
  1672. // Reduce the boilerplate code of handling route events
  1673. // and then calling a single method on another object.
  1674. // Have your routers configured to call the method on
  1675. // your object, directly.
  1676. //
  1677. // Configure an AppRouter with `appRoutes`.
  1678. //
  1679. // App routers can only take one `controller` object.
  1680. // It is recommended that you divide your controller
  1681. // objects in to smaller pieces of related functionality
  1682. // and have multiple routers / controllers, instead of
  1683. // just one giant router and controller.
  1684. //
  1685. // You can also add standard routes to an AppRouter.
  1686. Marionette.AppRouter = Backbone.Router.extend({
  1687. constructor: function(options){
  1688. Backbone.Router.prototype.constructor.apply(this, slice(arguments));
  1689. this.options = options || {};
  1690. var appRoutes = Marionette.getOption(this, "appRoutes");
  1691. var controller = this._getController();
  1692. this.processAppRoutes(controller, appRoutes);
  1693. },
  1694. // Similar to route method on a Backbone Router but
  1695. // method is called on the controller
  1696. appRoute: function(route, methodName) {
  1697. var controller = this._getController();
  1698. this._addAppRoute(controller, route, methodName);
  1699. },
  1700. // Internal method to process the `appRoutes` for the
  1701. // router, and turn them in to routes that trigger the
  1702. // specified method on the specified `controller`.
  1703. processAppRoutes: function(controller, appRoutes) {
  1704. if (!appRoutes){ return; }
  1705. var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes
  1706. _.each(routeNames, function(route) {
  1707. this._addAppRoute(controller, route, appRoutes[route]);
  1708. }, this);
  1709. },
  1710. _getController: function(){
  1711. return Marionette.getOption(this, "controller");
  1712. },
  1713. _addAppRoute: function(controller, route, methodName){
  1714. var method = controller[methodName];
  1715. if (!method) {
  1716. throw new Error("Method '" + methodName + "' was not found on the controller");
  1717. }
  1718. this.route(route, methodName, _.bind(method, controller));
  1719. }
  1720. });
  1721. // Application
  1722. // -----------
  1723. // Contain and manage the composite application as a whole.
  1724. // Stores and starts up `Region` objects, includes an
  1725. // event aggregator as `app.vent`
  1726. Marionette.Application = function(options){
  1727. this._initRegionManager();
  1728. this._initCallbacks = new Marionette.Callbacks();
  1729. this.vent = new Backbone.Wreqr.EventAggregator();
  1730. this.commands = new Backbone.Wreqr.Commands();
  1731. this.reqres = new Backbone.Wreqr.RequestResponse();
  1732. this.submodules = {};
  1733. _.extend(this, options);
  1734. this.triggerMethod = Marionette.triggerMethod;
  1735. };
  1736. _.extend(Marionette.Application.prototype, Backbone.Events, {
  1737. // Command execution, facilitated by Backbone.Wreqr.Commands
  1738. execute: function(){
  1739. var args = Array.prototype.slice.apply(arguments);
  1740. this.commands.execute.apply(this.commands, args);
  1741. },
  1742. // Request/response, facilitated by Backbone.Wreqr.RequestResponse
  1743. request: function(){
  1744. var args = Array.prototype.slice.apply(arguments);
  1745. return this.reqres.request.apply(this.reqres, args);
  1746. },
  1747. // Add an initializer that is either run at when the `start`
  1748. // method is called, or run immediately if added after `start`
  1749. // has already been called.
  1750. addInitializer: function(initializer){
  1751. this._initCallbacks.add(initializer);
  1752. },
  1753. // kick off all of the application's processes.
  1754. // initializes all of the regions that have been added
  1755. // to the app, and runs all of the initializer functions
  1756. start: function(options){
  1757. this.triggerMethod("initialize:before", options);
  1758. this._initCallbacks.run(options, this);
  1759. this.triggerMethod("initialize:after", options);
  1760. this.triggerMethod("start", options);
  1761. },
  1762. // Add regions to your app.
  1763. // Accepts a hash of named strings or Region objects
  1764. // addRegions({something: "#someRegion"})
  1765. // addRegions({something: Region.extend({el: "#someRegion"}) });
  1766. addRegions: function(regions){
  1767. return this._regionManager.addRegions(regions);
  1768. },
  1769. // Close all regions in the app, without removing them
  1770. closeRegions: function(){
  1771. this._regionManager.closeRegions();
  1772. },
  1773. // Removes a region from your app, by name
  1774. // Accepts the regions name
  1775. // removeRegion('myRegion')
  1776. removeRegion: function(region) {
  1777. this._regionManager.removeRegion(region);
  1778. },
  1779. // Provides alternative access to regions
  1780. // Accepts the region name
  1781. // getRegion('main')
  1782. getRegion: function(region) {
  1783. return this._regionManager.get(region);
  1784. },
  1785. // Create a module, attached to the application
  1786. module: function(moduleNames, moduleDefinition){
  1787. // slice the args, and add this application object as the
  1788. // first argument of the array
  1789. var args = slice(arguments);
  1790. args.unshift(this);
  1791. // see the Marionette.Module object for more information
  1792. return Marionette.Module.create.apply(Marionette.Module, args);
  1793. },
  1794. // Internal method to set up the region manager
  1795. _initRegionManager: function(){
  1796. this._regionManager = new Marionette.RegionManager();
  1797. this.listenTo(this._regionManager, "region:add", function(name, region){
  1798. this[name] = region;
  1799. });
  1800. this.listenTo(this._regionManager, "region:remove", function(name, region){
  1801. delete this[name];
  1802. });
  1803. }
  1804. });
  1805. // Copy the `extend` function used by Backbone's classes
  1806. Marionette.Application.extend = Marionette.extend;
  1807. // Module
  1808. // ------
  1809. // A simple module system, used to create privacy and encapsulation in
  1810. // Marionette applications
  1811. Marionette.Module = function(moduleName, app){
  1812. this.moduleName = moduleName;
  1813. // store sub-modules
  1814. this.submodules = {};
  1815. this._setupInitializersAndFinalizers();
  1816. // store the configuration for this module
  1817. this.app = app;
  1818. this.startWithParent = true;
  1819. this.triggerMethod = Marionette.triggerMethod;
  1820. };
  1821. // Extend the Module prototype with events / listenTo, so that the module
  1822. // can be used as an event aggregator or pub/sub.
  1823. _.extend(Marionette.Module.prototype, Backbone.Events, {
  1824. // Initializer for a specific module. Initializers are run when the
  1825. // module's `start` method is called.
  1826. addInitializer: function(callback){
  1827. this._initializerCallbacks.add(callback);
  1828. },
  1829. // Finalizers are run when a module is stopped. They are used to teardown
  1830. // and finalize any variables, references, events and other code that the
  1831. // module had set up.
  1832. addFinalizer: function(callback){
  1833. this._finalizerCallbacks.add(callback);
  1834. },
  1835. // Start the module, and run all of its initializers
  1836. start: function(options){
  1837. // Prevent re-starting a module that is already started
  1838. if (this._isInitialized){ return; }
  1839. // start the sub-modules (depth-first hierarchy)
  1840. _.each(this.submodules, function(mod){
  1841. // check to see if we should start the sub-module with this parent
  1842. if (mod.startWithParent){
  1843. mod.start(options);
  1844. }
  1845. });
  1846. // run the callbacks to "start" the current module
  1847. this.triggerMethod("before:start", options);
  1848. this._initializerCallbacks.run(options, this);
  1849. this._isInitialized = true;
  1850. this.triggerMethod("start", options);
  1851. },
  1852. // Stop this module by running its finalizers and then stop all of
  1853. // the sub-modules for this module
  1854. stop: function(){
  1855. // if we are not initialized, don't bother finalizing
  1856. if (!this._isInitialized){ return; }
  1857. this._isInitialized = false;
  1858. Marionette.triggerMethod.call(this, "before:stop");
  1859. // stop the sub-modules; depth-first, to make sure the
  1860. // sub-modules are stopped / finalized before parents
  1861. _.each(this.submodules, function(mod){ mod.stop(); });
  1862. // run the finalizers
  1863. this._finalizerCallbacks.run(undefined,this);
  1864. // reset the initializers and finalizers
  1865. this._initializerCallbacks.reset();
  1866. this._finalizerCallbacks.reset();
  1867. Marionette.triggerMethod.call(this, "stop");
  1868. },
  1869. // Configure the module with a definition function and any custom args
  1870. // that are to be passed in to the definition function
  1871. addDefinition: function(moduleDefinition, customArgs){
  1872. this._runModuleDefinition(moduleDefinition, customArgs);
  1873. },
  1874. // Internal method: run the module definition function with the correct
  1875. // arguments
  1876. _runModuleDefinition: function(definition, customArgs){
  1877. if (!definition){ return; }
  1878. // build the correct list of arguments for the module definition
  1879. var args = _.flatten([
  1880. this,
  1881. this.app,
  1882. Backbone,
  1883. Marionette,
  1884. Marionette.$, _,
  1885. customArgs
  1886. ]);
  1887. definition.apply(this, args);
  1888. },
  1889. // Internal method: set up new copies of initializers and finalizers.
  1890. // Calling this method will wipe out all existing initializers and
  1891. // finalizers.
  1892. _setupInitializersAndFinalizers: function(){
  1893. this._initializerCallbacks = new Marionette.Callbacks();
  1894. this._finalizerCallbacks = new Marionette.Callbacks();
  1895. }
  1896. });
  1897. // Type methods to create modules
  1898. _.extend(Marionette.Module, {
  1899. // Create a module, hanging off the app parameter as the parent object.
  1900. create: function(app, moduleNames, moduleDefinition){
  1901. var module = app;
  1902. // get the custom args passed in after the module definition and
  1903. // get rid of the module name and definition function
  1904. var customArgs = slice(arguments);
  1905. customArgs.splice(0, 3);
  1906. // split the module names and get the length
  1907. moduleNames = moduleNames.split(".");
  1908. var length = moduleNames.length;
  1909. // store the module definition for the last module in the chain
  1910. var moduleDefinitions = [];
  1911. moduleDefinitions[length-1] = moduleDefinition;
  1912. // Loop through all the parts of the module definition
  1913. _.each(moduleNames, function(moduleName, i){
  1914. var parentModule = module;
  1915. module = this._getModule(parentModule, moduleName, app);
  1916. this._addModuleDefinition(parentModule, module, moduleDefinitions[i], customArgs);
  1917. }, this);
  1918. // Return the last module in the definition chain
  1919. return module;
  1920. },
  1921. _getModule: function(parentModule, moduleName, app, def, args){
  1922. // Get an existing module of this name if we have one
  1923. var module = parentModule[moduleName];
  1924. if (!module){
  1925. // Create a new module if we don't have one
  1926. module = new Marionette.Module(moduleName, app);
  1927. parentModule[moduleName] = module;
  1928. // store the module on the parent
  1929. parentModule.submodules[moduleName] = module;
  1930. }
  1931. return module;
  1932. },
  1933. _addModuleDefinition: function(parentModule, module, def, args){
  1934. var fn;
  1935. var startWithParent;
  1936. if (_.isFunction(def)){
  1937. // if a function is supplied for the module definition
  1938. fn = def;
  1939. startWithParent = true;
  1940. } else if (_.isObject(def)){
  1941. // if an object is supplied
  1942. fn = def.define;
  1943. startWithParent = def.startWithParent;
  1944. } else {
  1945. // if nothing is supplied
  1946. startWithParent = true;
  1947. }
  1948. // add module definition if needed
  1949. if (fn){
  1950. module.addDefinition(fn, args);
  1951. }
  1952. // `and` the two together, ensuring a single `false` will prevent it
  1953. // from starting with the parent
  1954. module.startWithParent = module.startWithParent && startWithParent;
  1955. // setup auto-start if needed
  1956. if (module.startWithParent && !module.startWithParentIsConfigured){
  1957. // only configure this once
  1958. module.startWithParentIsConfigured = true;
  1959. // add the module initializer config
  1960. parentModule.addInitializer(function(options){
  1961. if (module.startWithParent){
  1962. module.start(options);
  1963. }
  1964. });
  1965. }
  1966. }
  1967. });
  1968. return Marionette;
  1969. })(this, Backbone, _);
  1970. ; browserify_shim__define__module__export__(typeof Marionette != "undefined" ? Marionette : window.Marionette);
  1971. }).call(global, undefined, undefined, undefined, function defineExport(ex) { module.exports = ex; });
  1972. },{"backbone":"n1NM5u","jquery":"RIh26+","underscore":"zNh35D"}],"backbone.marionette":[function(require,module,exports){
  1973. module.exports=require('cy31T3');
  1974. },{}],"n1NM5u":[function(require,module,exports){
  1975. var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};(function browserifyShim(module, exports, define, browserify_shim__define__module__export__) {
  1976. ; global.underscore = require("underscore");
  1977. // Backbone.js 1.1.0
  1978. // (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
  1979. // (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  1980. // Backbone may be freely distributed under the MIT license.
  1981. // For all details and documentation:
  1982. // http://backbonejs.org
  1983. (function(){
  1984. // Initial Setup
  1985. // -------------
  1986. // Save a reference to the global object (`window` in the browser, `exports`
  1987. // on the server).
  1988. var root = this;
  1989. // Save the previous value of the `Backbone` variable, so that it can be
  1990. // restored later on, if `noConflict` is used.
  1991. var previousBackbone = root.Backbone;
  1992. // Create local references to array methods we'll want to use later.
  1993. var array = [];
  1994. var push = array.push;
  1995. var slice = array.slice;
  1996. var splice = array.splice;
  1997. // The top-level namespace. All public Backbone classes and modules will
  1998. // be attached to this. Exported for both the browser and the server.
  1999. var Backbone;
  2000. if (typeof exports !== 'undefined') {
  2001. Backbone = exports;
  2002. } else {
  2003. Backbone = root.Backbone = {};
  2004. }
  2005. // Current version of the library. Keep in sync with `package.json`.
  2006. Backbone.VERSION = '1.1.0';
  2007. // Require Underscore, if we're on the server, and it's not already present.
  2008. var _ = root._;
  2009. if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
  2010. // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
  2011. // the `$` variable.
  2012. Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
  2013. // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
  2014. // to its previous owner. Returns a reference to this Backbone object.
  2015. Backbone.noConflict = function() {
  2016. root.Backbone = previousBackbone;
  2017. return this;
  2018. };
  2019. // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
  2020. // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
  2021. // set a `X-Http-Method-Override` header.
  2022. Backbone.emulateHTTP = false;
  2023. // Turn on `emulateJSON` to support legacy servers that can't deal with direct
  2024. // `application/json` requests ... will encode the body as
  2025. // `application/x-www-form-urlencoded` instead and will send the model in a
  2026. // form param named `model`.
  2027. Backbone.emulateJSON = false;
  2028. // Backbone.Events
  2029. // ---------------
  2030. // A module that can be mixed in to *any object* in order to provide it with
  2031. // custom events. You may bind with `on` or remove with `off` callback
  2032. // functions to an event; `trigger`-ing an event fires all callbacks in
  2033. // succession.
  2034. //
  2035. // var object = {};
  2036. // _.extend(object, Backbone.Events);
  2037. // object.on('expand', function(){ alert('expanded'); });
  2038. // object.trigger('expand');
  2039. //
  2040. var Events = Backbone.Events = {
  2041. // Bind an event to a `callback` function. Passing `"all"` will bind
  2042. // the callback to all events fired.
  2043. on: function(name, callback, context) {
  2044. if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
  2045. this._events || (this._events = {});
  2046. var events = this._events[name] || (this._events[name] = []);
  2047. events.push({callback: callback, context: context, ctx: context || this});
  2048. return this;
  2049. },
  2050. // Bind an event to only be triggered a single time. After the first time
  2051. // the callback is invoked, it will be removed.
  2052. once: function(name, callback, context) {
  2053. if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
  2054. var self = this;
  2055. var once = _.once(function() {
  2056. self.off(name, once);
  2057. callback.apply(this, arguments);
  2058. });
  2059. once._callback = callback;
  2060. return this.on(name, once, context);
  2061. },
  2062. // Remove one or many callbacks. If `context` is null, removes all
  2063. // callbacks with that function. If `callback` is null, removes all
  2064. // callbacks for the event. If `name` is null, removes all bound
  2065. // callbacks for all events.
  2066. off: function(name, callback, context) {
  2067. var retain, ev, events, names, i, l, j, k;
  2068. if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
  2069. if (!name && !callback && !context) {
  2070. this._events = {};
  2071. return this;
  2072. }
  2073. names = name ? [name] : _.keys(this._events);
  2074. for (i = 0, l = names.length; i < l; i++) {
  2075. name = names[i];
  2076. if (events = this._events[name]) {
  2077. this._events[name] = retain = [];
  2078. if (callback || context) {
  2079. for (j = 0, k = events.length; j < k; j++) {
  2080. ev = events[j];
  2081. if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
  2082. (context && context !== ev.context)) {
  2083. retain.push(ev);
  2084. }
  2085. }
  2086. }
  2087. if (!retain.length) delete this._events[name];
  2088. }
  2089. }
  2090. return this;
  2091. },
  2092. // Trigger one or many events, firing all bound callbacks. Callbacks are
  2093. // passed the same arguments as `trigger` is, apart from the event name
  2094. // (unless you're listening on `"all"`, which will cause your callback to
  2095. // receive the true name of the event as the first argument).
  2096. trigger: function(name) {
  2097. if (!this._events) return this;
  2098. var args = slice.call(arguments, 1);
  2099. if (!eventsApi(this, 'trigger', name, args)) return this;
  2100. var events = this._events[name];
  2101. var allEvents = this._events.all;
  2102. if (events) triggerEvents(events, args);
  2103. if (allEvents) triggerEvents(allEvents, arguments);
  2104. return this;
  2105. },
  2106. // Tell this object to stop listening to either specific events ... or
  2107. // to every object it's currently listening to.
  2108. stopListening: function(obj, name, callback) {
  2109. var listeningTo = this._listeningTo;
  2110. if (!listeningTo) return this;
  2111. var remove = !name && !callback;
  2112. if (!callback && typeof name === 'object') callback = this;
  2113. if (obj) (listeningTo = {})[obj._listenId] = obj;
  2114. for (var id in listeningTo) {
  2115. obj = listeningTo[id];
  2116. obj.off(name, callback, this);
  2117. if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
  2118. }
  2119. return this;
  2120. }
  2121. };
  2122. // Regular expression used to split event strings.
  2123. var eventSplitter = /\s+/;
  2124. // Implement fancy features of the Events API such as multiple event
  2125. // names `"change blur"` and jQuery-style event maps `{change: action}`
  2126. // in terms of the existing API.
  2127. var eventsApi = function(obj, action, name, rest) {
  2128. if (!name) return true;
  2129. // Handle event maps.
  2130. if (typeof name === 'object') {
  2131. for (var key in name) {
  2132. obj[action].apply(obj, [key, name[key]].concat(rest));
  2133. }
  2134. return false;
  2135. }
  2136. // Handle space separated event names.
  2137. if (eventSplitter.test(name)) {
  2138. var names = name.split(eventSplitter);
  2139. for (var i = 0, l = names.length; i < l; i++) {
  2140. obj[action].apply(obj, [names[i]].concat(rest));
  2141. }
  2142. return false;
  2143. }
  2144. return true;
  2145. };
  2146. // A difficult-to-believe, but optimized internal dispatch function for
  2147. // triggering events. Tries to keep the usual cases speedy (most internal
  2148. // Backbone events have 3 arguments).
  2149. var triggerEvents = function(events, args) {
  2150. var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
  2151. switch (args.length) {
  2152. case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
  2153. case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
  2154. case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
  2155. case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
  2156. default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
  2157. }
  2158. };
  2159. var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
  2160. // Inversion-of-control versions of `on` and `once`. Tell *this* object to
  2161. // listen to an event in another object ... keeping track of what it's
  2162. // listening to.
  2163. _.each(listenMethods, function(implementation, method) {
  2164. Events[method] = function(obj, name, callback) {
  2165. var listeningTo = this._listeningTo || (this._listeningTo = {});
  2166. var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
  2167. listeningTo[id] = obj;
  2168. if (!callback && typeof name === 'object') callback = this;
  2169. obj[implementation](name, callback, this);
  2170. return this;
  2171. };
  2172. });
  2173. // Aliases for backwards compatibility.
  2174. Events.bind = Events.on;
  2175. Events.unbind = Events.off;
  2176. // Allow the `Backbone` object to serve as a global event bus, for folks who
  2177. // want global "pubsub" in a convenient place.
  2178. _.extend(Backbone, Events);
  2179. // Backbone.Model
  2180. // --------------
  2181. // Backbone **Models** are the basic data object in the framework --
  2182. // frequently representing a row in a table in a database on your server.
  2183. // A discrete chunk of data and a bunch of useful, related methods for
  2184. // performing computations and transformations on that data.
  2185. // Create a new model with the specified attributes. A client id (`cid`)
  2186. // is automatically generated and assigned for you.
  2187. var Model = Backbone.Model = function(attributes, options) {
  2188. var attrs = attributes || {};
  2189. options || (options = {});
  2190. this.cid = _.uniqueId('c');
  2191. this.attributes = {};
  2192. if (options.collection) this.collection = options.collection;
  2193. if (options.parse) attrs = this.parse(attrs, options) || {};
  2194. attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
  2195. this.set(attrs, options);
  2196. this.changed = {};
  2197. this.initialize.apply(this, arguments);
  2198. };
  2199. // Attach all inheritable methods to the Model prototype.
  2200. _.extend(Model.prototype, Events, {
  2201. // A hash of attributes whose current and previous value differ.
  2202. changed: null,
  2203. // The value returned during the last failed validation.
  2204. validationError: null,
  2205. // The default name for the JSON `id` attribute is `"id"`. MongoDB and
  2206. // CouchDB users may want to set this to `"_id"`.
  2207. idAttribute: 'id',
  2208. // Initialize is an empty function by default. Override it with your own
  2209. // initialization logic.
  2210. initialize: function(){},
  2211. // Return a copy of the model's `attributes` object.
  2212. toJSON: function(options) {
  2213. return _.clone(this.attributes);
  2214. },
  2215. // Proxy `Backbone.sync` by default -- but override this if you need
  2216. // custom syncing semantics for *this* particular model.
  2217. sync: function() {
  2218. return Backbone.sync.apply(this, arguments);
  2219. },
  2220. // Get the value of an attribute.
  2221. get: function(attr) {
  2222. return this.attributes[attr];
  2223. },
  2224. // Get the HTML-escaped value of an attribute.
  2225. escape: function(attr) {
  2226. return _.escape(this.get(attr));
  2227. },
  2228. // Returns `true` if the attribute contains a value that is not null
  2229. // or undefined.
  2230. has: function(attr) {
  2231. return this.get(attr) != null;
  2232. },
  2233. // Set a hash of model attributes on the object, firing `"change"`. This is
  2234. // the core primitive operation of a model, updating the data and notifying
  2235. // anyone who needs to know about the change in state. The heart of the beast.
  2236. set: function(key, val, options) {
  2237. var attr, attrs, unset, changes, silent, changing, prev, current;
  2238. if (key == null) return this;
  2239. // Handle both `"key", value` and `{key: value}` -style arguments.
  2240. if (typeof key === 'object') {
  2241. attrs = key;
  2242. options = val;
  2243. } else {
  2244. (attrs = {})[key] = val;
  2245. }
  2246. options || (options = {});
  2247. // Run validation.
  2248. if (!this._validate(attrs, options)) return false;
  2249. // Extract attributes and options.
  2250. unset = options.unset;
  2251. silent = options.silent;
  2252. changes = [];
  2253. changing = this._changing;
  2254. this._changing = true;
  2255. if (!changing) {
  2256. this._previousAttributes = _.clone(this.attributes);
  2257. this.changed = {};
  2258. }
  2259. current = this.attributes, prev = this._previousAttributes;
  2260. // Check for changes of `id`.
  2261. if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
  2262. // For each `set` attribute, update or delete the current value.
  2263. for (attr in attrs) {
  2264. val = attrs[attr];
  2265. if (!_.isEqual(current[attr], val)) changes.push(attr);
  2266. if (!_.isEqual(prev[attr], val)) {
  2267. this.changed[attr] = val;
  2268. } else {
  2269. delete this.changed[attr];
  2270. }
  2271. unset ? delete current[attr] : current[attr] = val;
  2272. }
  2273. // Trigger all relevant attribute changes.
  2274. if (!silent) {
  2275. if (changes.length) this._pending = true;
  2276. for (var i = 0, l = changes.length; i < l; i++) {
  2277. this.trigger('change:' + changes[i], this, current[changes[i]], options);
  2278. }
  2279. }
  2280. // You might be wondering why there's a `while` loop here. Changes can
  2281. // be recursively nested within `"change"` events.
  2282. if (changing) return this;
  2283. if (!silent) {
  2284. while (this._pending) {
  2285. this._pending = false;
  2286. this.trigger('change', this, options);
  2287. }
  2288. }
  2289. this._pending = false;
  2290. this._changing = false;
  2291. return this;
  2292. },
  2293. // Remove an attribute from the model, firing `"change"`. `unset` is a noop
  2294. // if the attribute doesn't exist.
  2295. unset: function(attr, options) {
  2296. return this.set(attr, void 0, _.extend({}, options, {unset: true}));
  2297. },
  2298. // Clear all attributes on the model, firing `"change"`.
  2299. clear: function(options) {
  2300. var attrs = {};
  2301. for (var key in this.attributes) attrs[key] = void 0;
  2302. return this.set(attrs, _.extend({}, options, {unset: true}));
  2303. },
  2304. // Determine if the model has changed since the last `"change"` event.
  2305. // If you specify an attribute name, determine if that attribute has changed.
  2306. hasChanged: function(attr) {
  2307. if (attr == null) return !_.isEmpty(this.changed);
  2308. return _.has(this.changed, attr);
  2309. },
  2310. // Return an object containing all the attributes that have changed, or
  2311. // false if there are no changed attributes. Useful for determining what
  2312. // parts of a view need to be updated and/or what attributes need to be
  2313. // persisted to the server. Unset attributes will be set to undefined.
  2314. // You can also pass an attributes object to diff against the model,
  2315. // determining if there *would be* a change.
  2316. changedAttributes: function(diff) {
  2317. if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
  2318. var val, changed = false;
  2319. var old = this._changing ? this._previousAttributes : this.attributes;
  2320. for (var attr in diff) {
  2321. if (_.isEqual(old[attr], (val = diff[attr]))) continue;
  2322. (changed || (changed = {}))[attr] = val;
  2323. }
  2324. return changed;
  2325. },
  2326. // Get the previous value of an attribute, recorded at the time the last
  2327. // `"change"` event was fired.
  2328. previous: function(attr) {
  2329. if (attr == null || !this._previousAttributes) return null;
  2330. return this._previousAttributes[attr];
  2331. },
  2332. // Get all of the attributes of the model at the time of the previous
  2333. // `"change"` event.
  2334. previousAttributes: function() {
  2335. return _.clone(this._previousAttributes);
  2336. },
  2337. // Fetch the model from the server. If the server's representation of the
  2338. // model differs from its current attributes, they will be overridden,
  2339. // triggering a `"change"` event.
  2340. fetch: function(options) {
  2341. options = options ? _.clone(options) : {};
  2342. if (options.parse === void 0) options.parse = true;
  2343. var model = this;
  2344. var success = options.success;
  2345. options.success = function(resp) {
  2346. if (!model.set(model.parse(resp, options), options)) return false;
  2347. if (success) success(model, resp, options);
  2348. model.trigger('sync', model, resp, options);
  2349. };
  2350. wrapError(this, options);
  2351. return this.sync('read', this, options);
  2352. },
  2353. // Set a hash of model attributes, and sync the model to the server.
  2354. // If the server returns an attributes hash that differs, the model's
  2355. // state will be `set` again.
  2356. save: function(key, val, options) {
  2357. var attrs, method, xhr, attributes = this.attributes;
  2358. // Handle both `"key", value` and `{key: value}` -style arguments.
  2359. if (key == null || typeof key === 'object') {
  2360. attrs = key;
  2361. options = val;
  2362. } else {
  2363. (attrs = {})[key] = val;
  2364. }
  2365. options = _.extend({validate: true}, options);
  2366. // If we're not waiting and attributes exist, save acts as
  2367. // `set(attr).save(null, opts)` with validation. Otherwise, check if
  2368. // the model will be valid when the attributes, if any, are set.
  2369. if (attrs && !options.wait) {
  2370. if (!this.set(attrs, options)) return false;
  2371. } else {
  2372. if (!this._validate(attrs, options)) return false;
  2373. }
  2374. // Set temporary attributes if `{wait: true}`.
  2375. if (attrs && options.wait) {
  2376. this.attributes = _.extend({}, attributes, attrs);
  2377. }
  2378. // After a successful server-side save, the client is (optionally)
  2379. // updated with the server-side state.
  2380. if (options.parse === void 0) options.parse = true;
  2381. var model = this;
  2382. var success = options.success;
  2383. options.success = function(resp) {
  2384. // Ensure attributes are restored during synchronous saves.
  2385. model.attributes = attributes;
  2386. var serverAttrs = model.parse(resp, options);
  2387. if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
  2388. if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
  2389. return false;
  2390. }
  2391. if (success) success(model, resp, options);
  2392. model.trigger('sync', model, resp, options);
  2393. };
  2394. wrapError(this, options);
  2395. method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
  2396. if (method === 'patch') options.attrs = attrs;
  2397. xhr = this.sync(method, this, options);
  2398. // Restore attributes.
  2399. if (attrs && options.wait) this.attributes = attributes;
  2400. return xhr;
  2401. },
  2402. // Destroy this model on the server if it was already persisted.
  2403. // Optimistically removes the model from its collection, if it has one.
  2404. // If `wait: true` is passed, waits for the server to respond before removal.
  2405. destroy: function(options) {
  2406. options = options ? _.clone(options) : {};
  2407. var model = this;
  2408. var success = options.success;
  2409. var destroy = function() {
  2410. model.trigger('destroy', model, model.collection, options);
  2411. };
  2412. options.success = function(resp) {
  2413. if (options.wait || model.isNew()) destroy();
  2414. if (success) success(model, resp, options);
  2415. if (!model.isNew()) model.trigger('sync', model, resp, options);
  2416. };
  2417. if (this.isNew()) {
  2418. options.success();
  2419. return false;
  2420. }
  2421. wrapError(this, options);
  2422. var xhr = this.sync('delete', this, options);
  2423. if (!options.wait) destroy();
  2424. return xhr;
  2425. },
  2426. // Default URL for the model's representation on the server -- if you're
  2427. // using Backbone's restful methods, override this to change the endpoint
  2428. // that will be called.
  2429. url: function() {
  2430. var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
  2431. if (this.isNew()) return base;
  2432. return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
  2433. },
  2434. // **parse** converts a response into the hash of attributes to be `set` on
  2435. // the model. The default implementation is just to pass the response along.
  2436. parse: function(resp, options) {
  2437. return resp;
  2438. },
  2439. // Create a new model with identical attributes to this one.
  2440. clone: function() {
  2441. return new this.constructor(this.attributes);
  2442. },
  2443. // A model is new if it has never been saved to the server, and lacks an id.
  2444. isNew: function() {
  2445. return this.id == null;
  2446. },
  2447. // Check if the model is currently in a valid state.
  2448. isValid: function(options) {
  2449. return this._validate({}, _.extend(options || {}, { validate: true }));
  2450. },
  2451. // Run validation against the next complete set of model attributes,
  2452. // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
  2453. _validate: function(attrs, options) {
  2454. if (!options.validate || !this.validate) return true;
  2455. attrs = _.extend({}, this.attributes, attrs);
  2456. var error = this.validationError = this.validate(attrs, options) || null;
  2457. if (!error) return true;
  2458. this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
  2459. return false;
  2460. }
  2461. });
  2462. // Underscore methods that we want to implement on the Model.
  2463. var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
  2464. // Mix in each Underscore method as a proxy to `Model#attributes`.
  2465. _.each(modelMethods, function(method) {
  2466. Model.prototype[method] = function() {
  2467. var args = slice.call(arguments);
  2468. args.unshift(this.attributes);
  2469. return _[method].apply(_, args);
  2470. };
  2471. });
  2472. // Backbone.Collection
  2473. // -------------------
  2474. // If models tend to represent a single row of data, a Backbone Collection is
  2475. // more analagous to a table full of data ... or a small slice or page of that
  2476. // table, or a collection of rows that belong together for a particular reason
  2477. // -- all of the messages in this particular folder, all of the documents
  2478. // belonging to this particular author, and so on. Collections maintain
  2479. // indexes of their models, both in order, and for lookup by `id`.
  2480. // Create a new **Collection**, perhaps to contain a specific type of `model`.
  2481. // If a `comparator` is specified, the Collection will maintain
  2482. // its models in sort order, as they're added and removed.
  2483. var Collection = Backbone.Collection = function(models, options) {
  2484. options || (options = {});
  2485. if (options.model) this.model = options.model;
  2486. if (options.comparator !== void 0) this.comparator = options.comparator;
  2487. this._reset();
  2488. this.initialize.apply(this, arguments);
  2489. if (models) this.reset(models, _.extend({silent: true}, options));
  2490. };
  2491. // Default options for `Collection#set`.
  2492. var setOptions = {add: true, remove: true, merge: true};
  2493. var addOptions = {add: true, remove: false};
  2494. // Define the Collection's inheritable methods.
  2495. _.extend(Collection.prototype, Events, {
  2496. // The default model for a collection is just a **Backbone.Model**.
  2497. // This should be overridden in most cases.
  2498. model: Model,
  2499. // Initialize is an empty function by default. Override it with your own
  2500. // initialization logic.
  2501. initialize: function(){},
  2502. // The JSON representation of a Collection is an array of the
  2503. // models' attributes.
  2504. toJSON: function(options) {
  2505. return this.map(function(model){ return model.toJSON(options); });
  2506. },
  2507. // Proxy `Backbone.sync` by default.
  2508. sync: function() {
  2509. return Backbone.sync.apply(this, arguments);
  2510. },
  2511. // Add a model, or list of models to the set.
  2512. add: function(models, options) {
  2513. return this.set(models, _.extend({merge: false}, options, addOptions));
  2514. },
  2515. // Remove a model, or a list of models from the set.
  2516. remove: function(models, options) {
  2517. var singular = !_.isArray(models);
  2518. models = singular ? [models] : _.clone(models);
  2519. options || (options = {});
  2520. var i, l, index, model;
  2521. for (i = 0, l = models.length; i < l; i++) {
  2522. model = models[i] = this.get(models[i]);
  2523. if (!model) continue;
  2524. delete this._byId[model.id];
  2525. delete this._byId[model.cid];
  2526. index = this.indexOf(model);
  2527. this.models.splice(index, 1);
  2528. this.length--;
  2529. if (!options.silent) {
  2530. options.index = index;
  2531. model.trigger('remove', model, this, options);
  2532. }
  2533. this._removeReference(model);
  2534. }
  2535. return singular ? models[0] : models;
  2536. },
  2537. // Update a collection by `set`-ing a new list of models, adding new ones,
  2538. // removing models that are no longer present, and merging models that
  2539. // already exist in the collection, as necessary. Similar to **Model#set**,
  2540. // the core operation for updating the data contained by the collection.
  2541. set: function(models, options) {
  2542. options = _.defaults({}, options, setOptions);
  2543. if (options.parse) models = this.parse(models, options);
  2544. var singular = !_.isArray(models);
  2545. models = singular ? (models ? [models] : []) : _.clone(models);
  2546. var i, l, id, model, attrs, existing, sort;
  2547. var at = options.at;
  2548. var targetModel = this.model;
  2549. var sortable = this.comparator && (at == null) && options.sort !== false;
  2550. var sortAttr = _.isString(this.comparator) ? this.comparator : null;
  2551. var toAdd = [], toRemove = [], modelMap = {};
  2552. var add = options.add, merge = options.merge, remove = options.remove;
  2553. var order = !sortable && add && remove ? [] : false;
  2554. // Turn bare objects into model references, and prevent invalid models
  2555. // from being added.
  2556. for (i = 0, l = models.length; i < l; i++) {
  2557. attrs = models[i];
  2558. if (attrs instanceof Model) {
  2559. id = model = attrs;
  2560. } else {
  2561. id = attrs[targetModel.prototype.idAttribute];
  2562. }
  2563. // If a duplicate is found, prevent it from being added and
  2564. // optionally merge it into the existing model.
  2565. if (existing = this.get(id)) {
  2566. if (remove) modelMap[existing.cid] = true;
  2567. if (merge) {
  2568. attrs = attrs === model ? model.attributes : attrs;
  2569. if (options.parse) attrs = existing.parse(attrs, options);
  2570. existing.set(attrs, options);
  2571. if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
  2572. }
  2573. models[i] = existing;
  2574. // If this is a new, valid model, push it to the `toAdd` list.
  2575. } else if (add) {
  2576. model = models[i] = this._prepareModel(attrs, options);
  2577. if (!model) continue;
  2578. toAdd.push(model);
  2579. // Listen to added models' events, and index models for lookup by
  2580. // `id` and by `cid`.
  2581. model.on('all', this._onModelEvent, this);
  2582. this._byId[model.cid] = model;
  2583. if (model.id != null) this._byId[model.id] = model;
  2584. }
  2585. if (order) order.push(existing || model);
  2586. }
  2587. // Remove nonexistent models if appropriate.
  2588. if (remove) {
  2589. for (i = 0, l = this.length; i < l; ++i) {
  2590. if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
  2591. }
  2592. if (toRemove.length) this.remove(toRemove, options);
  2593. }
  2594. // See if sorting is needed, update `length` and splice in new models.
  2595. if (toAdd.length || (order && order.length)) {
  2596. if (sortable) sort = true;
  2597. this.length += toAdd.length;
  2598. if (at != null) {
  2599. for (i = 0, l = toAdd.length; i < l; i++) {
  2600. this.models.splice(at + i, 0, toAdd[i]);
  2601. }
  2602. } else {
  2603. if (order) this.models.length = 0;
  2604. var orderedModels = order || toAdd;
  2605. for (i = 0, l = orderedModels.length; i < l; i++) {
  2606. this.models.push(orderedModels[i]);
  2607. }
  2608. }
  2609. }
  2610. // Silently sort the collection if appropriate.
  2611. if (sort) this.sort({silent: true});
  2612. // Unless silenced, it's time to fire all appropriate add/sort events.
  2613. if (!options.silent) {
  2614. for (i = 0, l = toAdd.length; i < l; i++) {
  2615. (model = toAdd[i]).trigger('add', model, this, options);
  2616. }
  2617. if (sort || (order && order.length)) this.trigger('sort', this, options);
  2618. }
  2619. // Return the added (or merged) model (or models).
  2620. return singular ? models[0] : models;
  2621. },
  2622. // When you have more items than you want to add or remove individually,
  2623. // you can reset the entire set with a new list of models, without firing
  2624. // any granular `add` or `remove` events. Fires `reset` when finished.
  2625. // Useful for bulk operations and optimizations.
  2626. reset: function(models, options) {
  2627. options || (options = {});
  2628. for (var i = 0, l = this.models.length; i < l; i++) {
  2629. this._removeReference(this.models[i]);
  2630. }
  2631. options.previousModels = this.models;
  2632. this._reset();
  2633. models = this.add(models, _.extend({silent: true}, options));
  2634. if (!options.silent) this.trigger('reset', this, options);
  2635. return models;
  2636. },
  2637. // Add a model to the end of the collection.
  2638. push: function(model, options) {
  2639. return this.add(model, _.extend({at: this.length}, options));
  2640. },
  2641. // Remove a model from the end of the collection.
  2642. pop: function(options) {
  2643. var model = this.at(this.length - 1);
  2644. this.remove(model, options);
  2645. return model;
  2646. },
  2647. // Add a model to the beginning of the collection.
  2648. unshift: function(model, options) {
  2649. return this.add(model, _.extend({at: 0}, options));
  2650. },
  2651. // Remove a model from the beginning of the collection.
  2652. shift: function(options) {
  2653. var model = this.at(0);
  2654. this.remove(model, options);
  2655. return model;
  2656. },
  2657. // Slice out a sub-array of models from the collection.
  2658. slice: function() {
  2659. return slice.apply(this.models, arguments);
  2660. },
  2661. // Get a model from the set by id.
  2662. get: function(obj) {
  2663. if (obj == null) return void 0;
  2664. return this._byId[obj.id] || this._byId[obj.cid] || this._byId[obj];
  2665. },
  2666. // Get the model at the given index.
  2667. at: function(index) {
  2668. return this.models[index];
  2669. },
  2670. // Return models with matching attributes. Useful for simple cases of
  2671. // `filter`.
  2672. where: function(attrs, first) {
  2673. if (_.isEmpty(attrs)) return first ? void 0 : [];
  2674. return this[first ? 'find' : 'filter'](function(model) {
  2675. for (var key in attrs) {
  2676. if (attrs[key] !== model.get(key)) return false;
  2677. }
  2678. return true;
  2679. });
  2680. },
  2681. // Return the first model with matching attributes. Useful for simple cases
  2682. // of `find`.
  2683. findWhere: function(attrs) {
  2684. return this.where(attrs, true);
  2685. },
  2686. // Force the collection to re-sort itself. You don't need to call this under
  2687. // normal circumstances, as the set will maintain sort order as each item
  2688. // is added.
  2689. sort: function(options) {
  2690. if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
  2691. options || (options = {});
  2692. // Run sort based on type of `comparator`.
  2693. if (_.isString(this.comparator) || this.comparator.length === 1) {
  2694. this.models = this.sortBy(this.comparator, this);
  2695. } else {
  2696. this.models.sort(_.bind(this.comparator, this));
  2697. }
  2698. if (!options.silent) this.trigger('sort', this, options);
  2699. return this;
  2700. },
  2701. // Pluck an attribute from each model in the collection.
  2702. pluck: function(attr) {
  2703. return _.invoke(this.models, 'get', attr);
  2704. },
  2705. // Fetch the default set of models for this collection, resetting the
  2706. // collection when they arrive. If `reset: true` is passed, the response
  2707. // data will be passed through the `reset` method instead of `set`.
  2708. fetch: function(options) {
  2709. options = options ? _.clone(options) : {};
  2710. if (options.parse === void 0) options.parse = true;
  2711. var success = options.success;
  2712. var collection = this;
  2713. options.success = function(resp) {
  2714. var method = options.reset ? 'reset' : 'set';
  2715. collection[method](resp, options);
  2716. if (success) success(collection, resp, options);
  2717. collection.trigger('sync', collection, resp, options);
  2718. };
  2719. wrapError(this, options);
  2720. return this.sync('read', this, options);
  2721. },
  2722. // Create a new instance of a model in this collection. Add the model to the
  2723. // collection immediately, unless `wait: true` is passed, in which case we
  2724. // wait for the server to agree.
  2725. create: function(model, options) {
  2726. options = options ? _.clone(options) : {};
  2727. if (!(model = this._prepareModel(model, options))) return false;
  2728. if (!options.wait) this.add(model, options);
  2729. var collection = this;
  2730. var success = options.success;
  2731. options.success = function(model, resp, options) {
  2732. if (options.wait) collection.add(model, options);
  2733. if (success) success(model, resp, options);
  2734. };
  2735. model.save(null, options);
  2736. return model;
  2737. },
  2738. // **parse** converts a response into a list of models to be added to the
  2739. // collection. The default implementation is just to pass it through.
  2740. parse: function(resp, options) {
  2741. return resp;
  2742. },
  2743. // Create a new collection with an identical list of models as this one.
  2744. clone: function() {
  2745. return new this.constructor(this.models);
  2746. },
  2747. // Private method to reset all internal state. Called when the collection
  2748. // is first initialized or reset.
  2749. _reset: function() {
  2750. this.length = 0;
  2751. this.models = [];
  2752. this._byId = {};
  2753. },
  2754. // Prepare a hash of attributes (or other model) to be added to this
  2755. // collection.
  2756. _prepareModel: function(attrs, options) {
  2757. if (attrs instanceof Model) {
  2758. if (!attrs.collection) attrs.collection = this;
  2759. return attrs;
  2760. }
  2761. options = options ? _.clone(options) : {};
  2762. options.collection = this;
  2763. var model = new this.model(attrs, options);
  2764. if (!model.validationError) return model;
  2765. this.trigger('invalid', this, model.validationError, options);
  2766. return false;
  2767. },
  2768. // Internal method to sever a model's ties to a collection.
  2769. _removeReference: function(model) {
  2770. if (this === model.collection) delete model.collection;
  2771. model.off('all', this._onModelEvent, this);
  2772. },
  2773. // Internal method called every time a model in the set fires an event.
  2774. // Sets need to update their indexes when models change ids. All other
  2775. // events simply proxy through. "add" and "remove" events that originate
  2776. // in other collections are ignored.
  2777. _onModelEvent: function(event, model, collection, options) {
  2778. if ((event === 'add' || event === 'remove') && collection !== this) return;
  2779. if (event === 'destroy') this.remove(model, options);
  2780. if (model && event === 'change:' + model.idAttribute) {
  2781. delete this._byId[model.previous(model.idAttribute)];
  2782. if (model.id != null) this._byId[model.id] = model;
  2783. }
  2784. this.trigger.apply(this, arguments);
  2785. }
  2786. });
  2787. // Underscore methods that we want to implement on the Collection.
  2788. // 90% of the core usefulness of Backbone Collections is actually implemented
  2789. // right here:
  2790. var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
  2791. 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
  2792. 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
  2793. 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
  2794. 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
  2795. 'lastIndexOf', 'isEmpty', 'chain'];
  2796. // Mix in each Underscore method as a proxy to `Collection#models`.
  2797. _.each(methods, function(method) {
  2798. Collection.prototype[method] = function() {
  2799. var args = slice.call(arguments);
  2800. args.unshift(this.models);
  2801. return _[method].apply(_, args);
  2802. };
  2803. });
  2804. // Underscore methods that take a property name as an argument.
  2805. var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
  2806. // Use attributes instead of properties.
  2807. _.each(attributeMethods, function(method) {
  2808. Collection.prototype[method] = function(value, context) {
  2809. var iterator = _.isFunction(value) ? value : function(model) {
  2810. return model.get(value);
  2811. };
  2812. return _[method](this.models, iterator, context);
  2813. };
  2814. });
  2815. // Backbone.View
  2816. // -------------
  2817. // Backbone Views are almost more convention than they are actual code. A View
  2818. // is simply a JavaScript object that represents a logical chunk of UI in the
  2819. // DOM. This might be a single item, an entire list, a sidebar or panel, or
  2820. // even the surrounding frame which wraps your whole app. Defining a chunk of
  2821. // UI as a **View** allows you to define your DOM events declaratively, without
  2822. // having to worry about render order ... and makes it easy for the view to
  2823. // react to specific changes in the state of your models.
  2824. // Creating a Backbone.View creates its initial element outside of the DOM,
  2825. // if an existing element is not provided...
  2826. var View = Backbone.View = function(options) {
  2827. this.cid = _.uniqueId('view');
  2828. options || (options = {});
  2829. _.extend(this, _.pick(options, viewOptions));
  2830. this._ensureElement();
  2831. this.initialize.apply(this, arguments);
  2832. this.delegateEvents();
  2833. };
  2834. // Cached regex to split keys for `delegate`.
  2835. var delegateEventSplitter = /^(\S+)\s*(.*)$/;
  2836. // List of view options to be merged as properties.
  2837. var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
  2838. // Set up all inheritable **Backbone.View** properties and methods.
  2839. _.extend(View.prototype, Events, {
  2840. // The default `tagName` of a View's element is `"div"`.
  2841. tagName: 'div',
  2842. // jQuery delegate for element lookup, scoped to DOM elements within the
  2843. // current view. This should be preferred to global lookups where possible.
  2844. $: function(selector) {
  2845. return this.$el.find(selector);
  2846. },
  2847. // Initialize is an empty function by default. Override it with your own
  2848. // initialization logic.
  2849. initialize: function(){},
  2850. // **render** is the core function that your view should override, in order
  2851. // to populate its element (`this.el`), with the appropriate HTML. The
  2852. // convention is for **render** to always return `this`.
  2853. render: function() {
  2854. return this;
  2855. },
  2856. // Remove this view by taking the element out of the DOM, and removing any
  2857. // applicable Backbone.Events listeners.
  2858. remove: function() {
  2859. this.$el.remove();
  2860. this.stopListening();
  2861. return this;
  2862. },
  2863. // Change the view's element (`this.el` property), including event
  2864. // re-delegation.
  2865. setElement: function(element, delegate) {
  2866. if (this.$el) this.undelegateEvents();
  2867. this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
  2868. this.el = this.$el[0];
  2869. if (delegate !== false) this.delegateEvents();
  2870. return this;
  2871. },
  2872. // Set callbacks, where `this.events` is a hash of
  2873. //
  2874. // *{"event selector": "callback"}*
  2875. //
  2876. // {
  2877. // 'mousedown .title': 'edit',
  2878. // 'click .button': 'save',
  2879. // 'click .open': function(e) { ... }
  2880. // }
  2881. //
  2882. // pairs. Callbacks will be bound to the view, with `this` set properly.
  2883. // Uses event delegation for efficiency.
  2884. // Omitting the selector binds the event to `this.el`.
  2885. // This only works for delegate-able events: not `focus`, `blur`, and
  2886. // not `change`, `submit`, and `reset` in Internet Explorer.
  2887. delegateEvents: function(events) {
  2888. if (!(events || (events = _.result(this, 'events')))) return this;
  2889. this.undelegateEvents();
  2890. for (var key in events) {
  2891. var method = events[key];
  2892. if (!_.isFunction(method)) method = this[events[key]];
  2893. if (!method) continue;
  2894. var match = key.match(delegateEventSplitter);
  2895. var eventName = match[1], selector = match[2];
  2896. method = _.bind(method, this);
  2897. eventName += '.delegateEvents' + this.cid;
  2898. if (selector === '') {
  2899. this.$el.on(eventName, method);
  2900. } else {
  2901. this.$el.on(eventName, selector, method);
  2902. }
  2903. }
  2904. return this;
  2905. },
  2906. // Clears all callbacks previously bound to the view with `delegateEvents`.
  2907. // You usually don't need to use this, but may wish to if you have multiple
  2908. // Backbone views attached to the same DOM element.
  2909. undelegateEvents: function() {
  2910. this.$el.off('.delegateEvents' + this.cid);
  2911. return this;
  2912. },
  2913. // Ensure that the View has a DOM element to render into.
  2914. // If `this.el` is a string, pass it through `$()`, take the first
  2915. // matching element, and re-assign it to `el`. Otherwise, create
  2916. // an element from the `id`, `className` and `tagName` properties.
  2917. _ensureElement: function() {
  2918. if (!this.el) {
  2919. var attrs = _.extend({}, _.result(this, 'attributes'));
  2920. if (this.id) attrs.id = _.result(this, 'id');
  2921. if (this.className) attrs['class'] = _.result(this, 'className');
  2922. var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
  2923. this.setElement($el, false);
  2924. } else {
  2925. this.setElement(_.result(this, 'el'), false);
  2926. }
  2927. }
  2928. });
  2929. // Backbone.sync
  2930. // -------------
  2931. // Override this function to change the manner in which Backbone persists
  2932. // models to the server. You will be passed the type of request, and the
  2933. // model in question. By default, makes a RESTful Ajax request
  2934. // to the model's `url()`. Some possible customizations could be:
  2935. //
  2936. // * Use `setTimeout` to batch rapid-fire updates into a single request.
  2937. // * Send up the models as XML instead of JSON.
  2938. // * Persist models via WebSockets instead of Ajax.
  2939. //
  2940. // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
  2941. // as `POST`, with a `_method` parameter containing the true HTTP method,
  2942. // as well as all requests with the body as `application/x-www-form-urlencoded`
  2943. // instead of `application/json` with the model in a param named `model`.
  2944. // Useful when interfacing with server-side languages like **PHP** that make
  2945. // it difficult to read the body of `PUT` requests.
  2946. Backbone.sync = function(method, model, options) {
  2947. var type = methodMap[method];
  2948. // Default options, unless specified.
  2949. _.defaults(options || (options = {}), {
  2950. emulateHTTP: Backbone.emulateHTTP,
  2951. emulateJSON: Backbone.emulateJSON
  2952. });
  2953. // Default JSON-request options.
  2954. var params = {type: type, dataType: 'json'};
  2955. // Ensure that we have a URL.
  2956. if (!options.url) {
  2957. params.url = _.result(model, 'url') || urlError();
  2958. }
  2959. // Ensure that we have the appropriate request data.
  2960. if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
  2961. params.contentType = 'application/json';
  2962. params.data = JSON.stringify(options.attrs || model.toJSON(options));
  2963. }
  2964. // For older servers, emulate JSON by encoding the request into an HTML-form.
  2965. if (options.emulateJSON) {
  2966. params.contentType = 'application/x-www-form-urlencoded';
  2967. params.data = params.data ? {model: params.data} : {};
  2968. }
  2969. // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
  2970. // And an `X-HTTP-Method-Override` header.
  2971. if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
  2972. params.type = 'POST';
  2973. if (options.emulateJSON) params.data._method = type;
  2974. var beforeSend = options.beforeSend;
  2975. options.beforeSend = function(xhr) {
  2976. xhr.setRequestHeader('X-HTTP-Method-Override', type);
  2977. if (beforeSend) return beforeSend.apply(this, arguments);
  2978. };
  2979. }
  2980. // Don't process data on a non-GET request.
  2981. if (params.type !== 'GET' && !options.emulateJSON) {
  2982. params.processData = false;
  2983. }
  2984. // If we're sending a `PATCH` request, and we're in an old Internet Explorer
  2985. // that still has ActiveX enabled by default, override jQuery to use that
  2986. // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
  2987. if (params.type === 'PATCH' && noXhrPatch) {
  2988. params.xhr = function() {
  2989. return new ActiveXObject("Microsoft.XMLHTTP");
  2990. };
  2991. }
  2992. // Make the request, allowing the user to override any Ajax options.
  2993. var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
  2994. model.trigger('request', model, xhr, options);
  2995. return xhr;
  2996. };
  2997. var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
  2998. // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  2999. var methodMap = {
  3000. 'create': 'POST',
  3001. 'update': 'PUT',
  3002. 'patch': 'PATCH',
  3003. 'delete': 'DELETE',
  3004. 'read': 'GET'
  3005. };
  3006. // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
  3007. // Override this if you'd like to use a different library.
  3008. Backbone.ajax = function() {
  3009. return Backbone.$.ajax.apply(Backbone.$, arguments);
  3010. };
  3011. // Backbone.Router
  3012. // ---------------
  3013. // Routers map faux-URLs to actions, and fire events when routes are
  3014. // matched. Creating a new one sets its `routes` hash, if not set statically.
  3015. var Router = Backbone.Router = function(options) {
  3016. options || (options = {});
  3017. if (options.routes) this.routes = options.routes;
  3018. this._bindRoutes();
  3019. this.initialize.apply(this, arguments);
  3020. };
  3021. // Cached regular expressions for matching named param parts and splatted
  3022. // parts of route strings.
  3023. var optionalParam = /\((.*?)\)/g;
  3024. var namedParam = /(\(\?)?:\w+/g;
  3025. var splatParam = /\*\w+/g;
  3026. var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
  3027. // Set up all inheritable **Backbone.Router** properties and methods.
  3028. _.extend(Router.prototype, Events, {
  3029. // Initialize is an empty function by default. Override it with your own
  3030. // initialization logic.
  3031. initialize: function(){},
  3032. // Manually bind a single named route to a callback. For example:
  3033. //
  3034. // this.route('search/:query/p:num', 'search', function(query, num) {
  3035. // ...
  3036. // });
  3037. //
  3038. route: function(route, name, callback) {
  3039. if (!_.isRegExp(route)) route = this._routeToRegExp(route);
  3040. if (_.isFunction(name)) {
  3041. callback = name;
  3042. name = '';
  3043. }
  3044. if (!callback) callback = this[name];
  3045. var router = this;
  3046. Backbone.history.route(route, function(fragment) {
  3047. var args = router._extractParameters(route, fragment);
  3048. callback && callback.apply(router, args);
  3049. router.trigger.apply(router, ['route:' + name].concat(args));
  3050. router.trigger('route', name, args);
  3051. Backbone.history.trigger('route', router, name, args);
  3052. });
  3053. return this;
  3054. },
  3055. // Simple proxy to `Backbone.history` to save a fragment into the history.
  3056. navigate: function(fragment, options) {
  3057. Backbone.history.navigate(fragment, options);
  3058. return this;
  3059. },
  3060. // Bind all defined routes to `Backbone.history`. We have to reverse the
  3061. // order of the routes here to support behavior where the most general
  3062. // routes can be defined at the bottom of the route map.
  3063. _bindRoutes: function() {
  3064. if (!this.routes) return;
  3065. this.routes = _.result(this, 'routes');
  3066. var route, routes = _.keys(this.routes);
  3067. while ((route = routes.pop()) != null) {
  3068. this.route(route, this.routes[route]);
  3069. }
  3070. },
  3071. // Convert a route string into a regular expression, suitable for matching
  3072. // against the current location hash.
  3073. _routeToRegExp: function(route) {
  3074. route = route.replace(escapeRegExp, '\\$&')
  3075. .replace(optionalParam, '(?:$1)?')
  3076. .replace(namedParam, function(match, optional) {
  3077. return optional ? match : '([^\/]+)';
  3078. })
  3079. .replace(splatParam, '(.*?)');
  3080. return new RegExp('^' + route + '$');
  3081. },
  3082. // Given a route, and a URL fragment that it matches, return the array of
  3083. // extracted decoded parameters. Empty or unmatched parameters will be
  3084. // treated as `null` to normalize cross-browser behavior.
  3085. _extractParameters: function(route, fragment) {
  3086. var params = route.exec(fragment).slice(1);
  3087. return _.map(params, function(param) {
  3088. return param ? decodeURIComponent(param) : null;
  3089. });
  3090. }
  3091. });
  3092. // Backbone.History
  3093. // ----------------
  3094. // Handles cross-browser history management, based on either
  3095. // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
  3096. // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
  3097. // and URL fragments. If the browser supports neither (old IE, natch),
  3098. // falls back to polling.
  3099. var History = Backbone.History = function() {
  3100. this.handlers = [];
  3101. _.bindAll(this, 'checkUrl');
  3102. // Ensure that `History` can be used outside of the browser.
  3103. if (typeof window !== 'undefined') {
  3104. this.location = window.location;
  3105. this.history = window.history;
  3106. }
  3107. };
  3108. // Cached regex for stripping a leading hash/slash and trailing space.
  3109. var routeStripper = /^[#\/]|\s+$/g;
  3110. // Cached regex for stripping leading and trailing slashes.
  3111. var rootStripper = /^\/+|\/+$/g;
  3112. // Cached regex for detecting MSIE.
  3113. var isExplorer = /msie [\w.]+/;
  3114. // Cached regex for removing a trailing slash.
  3115. var trailingSlash = /\/$/;
  3116. // Cached regex for stripping urls of hash and query.
  3117. var pathStripper = /[?#].*$/;
  3118. // Has the history handling already been started?
  3119. History.started = false;
  3120. // Set up all inheritable **Backbone.History** properties and methods.
  3121. _.extend(History.prototype, Events, {
  3122. // The default interval to poll for hash changes, if necessary, is
  3123. // twenty times a second.
  3124. interval: 50,
  3125. // Gets the true hash value. Cannot use location.hash directly due to bug
  3126. // in Firefox where location.hash will always be decoded.
  3127. getHash: function(window) {
  3128. var match = (window || this).location.href.match(/#(.*)$/);
  3129. return match ? match[1] : '';
  3130. },
  3131. // Get the cross-browser normalized URL fragment, either from the URL,
  3132. // the hash, or the override.
  3133. getFragment: function(fragment, forcePushState) {
  3134. if (fragment == null) {
  3135. if (this._hasPushState || !this._wantsHashChange || forcePushState) {
  3136. fragment = this.location.pathname;
  3137. var root = this.root.replace(trailingSlash, '');
  3138. if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
  3139. } else {
  3140. fragment = this.getHash();
  3141. }
  3142. }
  3143. return fragment.replace(routeStripper, '');
  3144. },
  3145. // Start the hash change handling, returning `true` if the current URL matches
  3146. // an existing route, and `false` otherwise.
  3147. start: function(options) {
  3148. if (History.started) throw new Error("Backbone.history has already been started");
  3149. History.started = true;
  3150. // Figure out the initial configuration. Do we need an iframe?
  3151. // Is pushState desired ... is it available?
  3152. this.options = _.extend({root: '/'}, this.options, options);
  3153. this.root = this.options.root;
  3154. this._wantsHashChange = this.options.hashChange !== false;
  3155. this._wantsPushState = !!this.options.pushState;
  3156. this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
  3157. var fragment = this.getFragment();
  3158. var docMode = document.documentMode;
  3159. var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
  3160. // Normalize root to always include a leading and trailing slash.
  3161. this.root = ('/' + this.root + '/').replace(rootStripper, '/');
  3162. if (oldIE && this._wantsHashChange) {
  3163. this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
  3164. this.navigate(fragment);
  3165. }
  3166. // Depending on whether we're using pushState or hashes, and whether
  3167. // 'onhashchange' is supported, determine how we check the URL state.
  3168. if (this._hasPushState) {
  3169. Backbone.$(window).on('popstate', this.checkUrl);
  3170. } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
  3171. Backbone.$(window).on('hashchange', this.checkUrl);
  3172. } else if (this._wantsHashChange) {
  3173. this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
  3174. }
  3175. // Determine if we need to change the base url, for a pushState link
  3176. // opened by a non-pushState browser.
  3177. this.fragment = fragment;
  3178. var loc = this.location;
  3179. var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
  3180. // Transition from hashChange to pushState or vice versa if both are
  3181. // requested.
  3182. if (this._wantsHashChange && this._wantsPushState) {
  3183. // If we've started off with a route from a `pushState`-enabled
  3184. // browser, but we're currently in a browser that doesn't support it...
  3185. if (!this._hasPushState && !atRoot) {
  3186. this.fragment = this.getFragment(null, true);
  3187. this.location.replace(this.root + this.location.search + '#' + this.fragment);
  3188. // Return immediately as browser will do redirect to new url
  3189. return true;
  3190. // Or if we've started out with a hash-based route, but we're currently
  3191. // in a browser where it could be `pushState`-based instead...
  3192. } else if (this._hasPushState && atRoot && loc.hash) {
  3193. this.fragment = this.getHash().replace(routeStripper, '');
  3194. this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
  3195. }
  3196. }
  3197. if (!this.options.silent) return this.loadUrl();
  3198. },
  3199. // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
  3200. // but possibly useful for unit testing Routers.
  3201. stop: function() {
  3202. Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
  3203. clearInterval(this._checkUrlInterval);
  3204. History.started = false;
  3205. },
  3206. // Add a route to be tested when the fragment changes. Routes added later
  3207. // may override previous routes.
  3208. route: function(route, callback) {
  3209. this.handlers.unshift({route: route, callback: callback});
  3210. },
  3211. // Checks the current URL to see if it has changed, and if it has,
  3212. // calls `loadUrl`, normalizing across the hidden iframe.
  3213. checkUrl: function(e) {
  3214. var current = this.getFragment();
  3215. if (current === this.fragment && this.iframe) {
  3216. current = this.getFragment(this.getHash(this.iframe));
  3217. }
  3218. if (current === this.fragment) return false;
  3219. if (this.iframe) this.navigate(current);
  3220. this.loadUrl();
  3221. },
  3222. // Attempt to load the current URL fragment. If a route succeeds with a
  3223. // match, returns `true`. If no defined routes matches the fragment,
  3224. // returns `false`.
  3225. loadUrl: function(fragment) {
  3226. fragment = this.fragment = this.getFragment(fragment);
  3227. return _.any(this.handlers, function(handler) {
  3228. if (handler.route.test(fragment)) {
  3229. handler.callback(fragment);
  3230. return true;
  3231. }
  3232. });
  3233. },
  3234. // Save a fragment into the hash history, or replace the URL state if the
  3235. // 'replace' option is passed. You are responsible for properly URL-encoding
  3236. // the fragment in advance.
  3237. //
  3238. // The options object can contain `trigger: true` if you wish to have the
  3239. // route callback be fired (not usually desirable), or `replace: true`, if
  3240. // you wish to modify the current URL without adding an entry to the history.
  3241. navigate: function(fragment, options) {
  3242. if (!History.started) return false;
  3243. if (!options || options === true) options = {trigger: !!options};
  3244. var url = this.root + (fragment = this.getFragment(fragment || ''));
  3245. // Strip the fragment of the query and hash for matching.
  3246. fragment = fragment.replace(pathStripper, '');
  3247. if (this.fragment === fragment) return;
  3248. this.fragment = fragment;
  3249. // Don't include a trailing slash on the root.
  3250. if (fragment === '' && url !== '/') url = url.slice(0, -1);
  3251. // If pushState is available, we use it to set the fragment as a real URL.
  3252. if (this._hasPushState) {
  3253. this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
  3254. // If hash changes haven't been explicitly disabled, update the hash
  3255. // fragment to store history.
  3256. } else if (this._wantsHashChange) {
  3257. this._updateHash(this.location, fragment, options.replace);
  3258. if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
  3259. // Opening and closing the iframe tricks IE7 and earlier to push a
  3260. // history entry on hash-tag change. When replace is true, we don't
  3261. // want this.
  3262. if(!options.replace) this.iframe.document.open().close();
  3263. this._updateHash(this.iframe.location, fragment, options.replace);
  3264. }
  3265. // If you've told us that you explicitly don't want fallback hashchange-
  3266. // based history, then `navigate` becomes a page refresh.
  3267. } else {
  3268. return this.location.assign(url);
  3269. }
  3270. if (options.trigger) return this.loadUrl(fragment);
  3271. },
  3272. // Update the hash location, either replacing the current entry, or adding
  3273. // a new one to the browser history.
  3274. _updateHash: function(location, fragment, replace) {
  3275. if (replace) {
  3276. var href = location.href.replace(/(javascript:|#).*$/, '');
  3277. location.replace(href + '#' + fragment);
  3278. } else {
  3279. // Some browsers require that `hash` contains a leading #.
  3280. location.hash = '#' + fragment;
  3281. }
  3282. }
  3283. });
  3284. // Create the default Backbone.history.
  3285. Backbone.history = new History;
  3286. // Helpers
  3287. // -------
  3288. // Helper function to correctly set up the prototype chain, for subclasses.
  3289. // Similar to `goog.inherits`, but uses a hash of prototype properties and
  3290. // class properties to be extended.
  3291. var extend = function(protoProps, staticProps) {
  3292. var parent = this;
  3293. var child;
  3294. // The constructor function for the new subclass is either defined by you
  3295. // (the "constructor" property in your `extend` definition), or defaulted
  3296. // by us to simply call the parent's constructor.
  3297. if (protoProps && _.has(protoProps, 'constructor')) {
  3298. child = protoProps.constructor;
  3299. } else {
  3300. child = function(){ return parent.apply(this, arguments); };
  3301. }
  3302. // Add static properties to the constructor function, if supplied.
  3303. _.extend(child, parent, staticProps);
  3304. // Set the prototype chain to inherit from `parent`, without calling
  3305. // `parent`'s constructor function.
  3306. var Surrogate = function(){ this.constructor = child; };
  3307. Surrogate.prototype = parent.prototype;
  3308. child.prototype = new Surrogate;
  3309. // Add prototype properties (instance properties) to the subclass,
  3310. // if supplied.
  3311. if (protoProps) _.extend(child.prototype, protoProps);
  3312. // Set a convenience property in case the parent's prototype is needed
  3313. // later.
  3314. child.__super__ = parent.prototype;
  3315. return child;
  3316. };
  3317. // Set up inheritance for the model, collection, router, view and history.
  3318. Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
  3319. // Throw an error when a URL is needed, and none is supplied.
  3320. var urlError = function() {
  3321. throw new Error('A "url" property or function must be specified');
  3322. };
  3323. // Wrap an optional error callback with a fallback error event.
  3324. var wrapError = function(model, options) {
  3325. var error = options.error;
  3326. options.error = function(resp) {
  3327. if (error) error(model, resp, options);
  3328. model.trigger('error', model, resp, options);
  3329. };
  3330. };
  3331. }).call(this);
  3332. ; browserify_shim__define__module__export__(typeof Backbone != "undefined" ? Backbone : window.Backbone);
  3333. }).call(global, undefined, undefined, undefined, function defineExport(ex) { module.exports = ex; });
  3334. },{"underscore":"zNh35D"}],"backbone":[function(require,module,exports){
  3335. module.exports=require('n1NM5u');
  3336. },{}],"RIh26+":[function(require,module,exports){
  3337. var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};(function browserifyShim(module, exports, define, browserify_shim__define__module__export__) {
  3338. /*!
  3339. * jQuery JavaScript Library v1.10.2
  3340. * http://jquery.com/
  3341. *
  3342. * Includes Sizzle.js
  3343. * http://sizzlejs.com/
  3344. *
  3345. * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
  3346. * Released under the MIT license
  3347. * http://jquery.org/license
  3348. *
  3349. * Date: 2013-07-03T13:48Z
  3350. */
  3351. (function( window, undefined ) {
  3352. // Can't do this because several apps including ASP.NET trace
  3353. // the stack via arguments.caller.callee and Firefox dies if
  3354. // you try to trace through "use strict" call chains. (#13335)
  3355. // Support: Firefox 18+
  3356. //"use strict";
  3357. var
  3358. // The deferred used on DOM ready
  3359. readyList,
  3360. // A central reference to the root jQuery(document)
  3361. rootjQuery,
  3362. // Support: IE<10
  3363. // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
  3364. core_strundefined = typeof undefined,
  3365. // Use the correct document accordingly with window argument (sandbox)
  3366. location = window.location,
  3367. document = window.document,
  3368. docElem = document.documentElement,
  3369. // Map over jQuery in case of overwrite
  3370. _jQuery = window.jQuery,
  3371. // Map over the $ in case of overwrite
  3372. _$ = window.$,
  3373. // [[Class]] -> type pairs
  3374. class2type = {},
  3375. // List of deleted data cache ids, so we can reuse them
  3376. core_deletedIds = [],
  3377. core_version = "1.10.2",
  3378. // Save a reference to some core methods
  3379. core_concat = core_deletedIds.concat,
  3380. core_push = core_deletedIds.push,
  3381. core_slice = core_deletedIds.slice,
  3382. core_indexOf = core_deletedIds.indexOf,
  3383. core_toString = class2type.toString,
  3384. core_hasOwn = class2type.hasOwnProperty,
  3385. core_trim = core_version.trim,
  3386. // Define a local copy of jQuery
  3387. jQuery = function( selector, context ) {
  3388. // The jQuery object is actually just the init constructor 'enhanced'
  3389. return new jQuery.fn.init( selector, context, rootjQuery );
  3390. },
  3391. // Used for matching numbers
  3392. core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
  3393. // Used for splitting on whitespace
  3394. core_rnotwhite = /\S+/g,
  3395. // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
  3396. rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  3397. // A simple way to check for HTML strings
  3398. // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  3399. // Strict HTML recognition (#11290: must start with <)
  3400. rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  3401. // Match a standalone tag
  3402. rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
  3403. // JSON RegExp
  3404. rvalidchars = /^[\],:{}\s]*$/,
  3405. rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
  3406. rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
  3407. rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
  3408. // Matches dashed string for camelizing
  3409. rmsPrefix = /^-ms-/,
  3410. rdashAlpha = /-([\da-z])/gi,
  3411. // Used by jQuery.camelCase as callback to replace()
  3412. fcamelCase = function( all, letter ) {
  3413. return letter.toUpperCase();
  3414. },
  3415. // The ready event handler
  3416. completed = function( event ) {
  3417. // readyState === "complete" is good enough for us to call the dom ready in oldIE
  3418. if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  3419. detach();
  3420. jQuery.ready();
  3421. }
  3422. },
  3423. // Clean-up method for dom ready events
  3424. detach = function() {
  3425. if ( document.addEventListener ) {
  3426. document.removeEventListener( "DOMContentLoaded", completed, false );
  3427. window.removeEventListener( "load", completed, false );
  3428. } else {
  3429. document.detachEvent( "onreadystatechange", completed );
  3430. window.detachEvent( "onload", completed );
  3431. }
  3432. };
  3433. jQuery.fn = jQuery.prototype = {
  3434. // The current version of jQuery being used
  3435. jquery: core_version,
  3436. constructor: jQuery,
  3437. init: function( selector, context, rootjQuery ) {
  3438. var match, elem;
  3439. // HANDLE: $(""), $(null), $(undefined), $(false)
  3440. if ( !selector ) {
  3441. return this;
  3442. }
  3443. // Handle HTML strings
  3444. if ( typeof selector === "string" ) {
  3445. if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
  3446. // Assume that strings that start and end with <> are HTML and skip the regex check
  3447. match = [ null, selector, null ];
  3448. } else {
  3449. match = rquickExpr.exec( selector );
  3450. }
  3451. // Match html or make sure no context is specified for #id
  3452. if ( match && (match[1] || !context) ) {
  3453. // HANDLE: $(html) -> $(array)
  3454. if ( match[1] ) {
  3455. context = context instanceof jQuery ? context[0] : context;
  3456. // scripts is true for back-compat
  3457. jQuery.merge( this, jQuery.parseHTML(
  3458. match[1],
  3459. context && context.nodeType ? context.ownerDocument || context : document,
  3460. true
  3461. ) );
  3462. // HANDLE: $(html, props)
  3463. if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
  3464. for ( match in context ) {
  3465. // Properties of context are called as methods if possible
  3466. if ( jQuery.isFunction( this[ match ] ) ) {
  3467. this[ match ]( context[ match ] );
  3468. // ...and otherwise set as attributes
  3469. } else {
  3470. this.attr( match, context[ match ] );
  3471. }
  3472. }
  3473. }
  3474. return this;
  3475. // HANDLE: $(#id)
  3476. } else {
  3477. elem = document.getElementById( match[2] );
  3478. // Check parentNode to catch when Blackberry 4.6 returns
  3479. // nodes that are no longer in the document #6963
  3480. if ( elem && elem.parentNode ) {
  3481. // Handle the case where IE and Opera return items
  3482. // by name instead of ID
  3483. if ( elem.id !== match[2] ) {
  3484. return rootjQuery.find( selector );
  3485. }
  3486. // Otherwise, we inject the element directly into the jQuery object
  3487. this.length = 1;
  3488. this[0] = elem;
  3489. }
  3490. this.context = document;
  3491. this.selector = selector;
  3492. return this;
  3493. }
  3494. // HANDLE: $(expr, $(...))
  3495. } else if ( !context || context.jquery ) {
  3496. return ( context || rootjQuery ).find( selector );
  3497. // HANDLE: $(expr, context)
  3498. // (which is just equivalent to: $(context).find(expr)
  3499. } else {
  3500. return this.constructor( context ).find( selector );
  3501. }
  3502. // HANDLE: $(DOMElement)
  3503. } else if ( selector.nodeType ) {
  3504. this.context = this[0] = selector;
  3505. this.length = 1;
  3506. return this;
  3507. // HANDLE: $(function)
  3508. // Shortcut for document ready
  3509. } else if ( jQuery.isFunction( selector ) ) {
  3510. return rootjQuery.ready( selector );
  3511. }
  3512. if ( selector.selector !== undefined ) {
  3513. this.selector = selector.selector;
  3514. this.context = selector.context;
  3515. }
  3516. return jQuery.makeArray( selector, this );
  3517. },
  3518. // Start with an empty selector
  3519. selector: "",
  3520. // The default length of a jQuery object is 0
  3521. length: 0,
  3522. toArray: function() {
  3523. return core_slice.call( this );
  3524. },
  3525. // Get the Nth element in the matched element set OR
  3526. // Get the whole matched element set as a clean array
  3527. get: function( num ) {
  3528. return num == null ?
  3529. // Return a 'clean' array
  3530. this.toArray() :
  3531. // Return just the object
  3532. ( num < 0 ? this[ this.length + num ] : this[ num ] );
  3533. },
  3534. // Take an array of elements and push it onto the stack
  3535. // (returning the new matched element set)
  3536. pushStack: function( elems ) {
  3537. // Build a new jQuery matched element set
  3538. var ret = jQuery.merge( this.constructor(), elems );
  3539. // Add the old object onto the stack (as a reference)
  3540. ret.prevObject = this;
  3541. ret.context = this.context;
  3542. // Return the newly-formed element set
  3543. return ret;
  3544. },
  3545. // Execute a callback for every element in the matched set.
  3546. // (You can seed the arguments with an array of args, but this is
  3547. // only used internally.)
  3548. each: function( callback, args ) {
  3549. return jQuery.each( this, callback, args );
  3550. },
  3551. ready: function( fn ) {
  3552. // Add the callback
  3553. jQuery.ready.promise().done( fn );
  3554. return this;
  3555. },
  3556. slice: function() {
  3557. return this.pushStack( core_slice.apply( this, arguments ) );
  3558. },
  3559. first: function() {
  3560. return this.eq( 0 );
  3561. },
  3562. last: function() {
  3563. return this.eq( -1 );
  3564. },
  3565. eq: function( i ) {
  3566. var len = this.length,
  3567. j = +i + ( i < 0 ? len : 0 );
  3568. return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
  3569. },
  3570. map: function( callback ) {
  3571. return this.pushStack( jQuery.map(this, function( elem, i ) {
  3572. return callback.call( elem, i, elem );
  3573. }));
  3574. },
  3575. end: function() {
  3576. return this.prevObject || this.constructor(null);
  3577. },
  3578. // For internal use only.
  3579. // Behaves like an Array's method, not like a jQuery method.
  3580. push: core_push,
  3581. sort: [].sort,
  3582. splice: [].splice
  3583. };
  3584. // Give the init function the jQuery prototype for later instantiation
  3585. jQuery.fn.init.prototype = jQuery.fn;
  3586. jQuery.extend = jQuery.fn.extend = function() {
  3587. var src, copyIsArray, copy, name, options, clone,
  3588. target = arguments[0] || {},
  3589. i = 1,
  3590. length = arguments.length,
  3591. deep = false;
  3592. // Handle a deep copy situation
  3593. if ( typeof target === "boolean" ) {
  3594. deep = target;
  3595. target = arguments[1] || {};
  3596. // skip the boolean and the target
  3597. i = 2;
  3598. }
  3599. // Handle case when target is a string or something (possible in deep copy)
  3600. if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
  3601. target = {};
  3602. }
  3603. // extend jQuery itself if only one argument is passed
  3604. if ( length === i ) {
  3605. target = this;
  3606. --i;
  3607. }
  3608. for ( ; i < length; i++ ) {
  3609. // Only deal with non-null/undefined values
  3610. if ( (options = arguments[ i ]) != null ) {
  3611. // Extend the base object
  3612. for ( name in options ) {
  3613. src = target[ name ];
  3614. copy = options[ name ];
  3615. // Prevent never-ending loop
  3616. if ( target === copy ) {
  3617. continue;
  3618. }
  3619. // Recurse if we're merging plain objects or arrays
  3620. if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
  3621. if ( copyIsArray ) {
  3622. copyIsArray = false;
  3623. clone = src && jQuery.isArray(src) ? src : [];
  3624. } else {
  3625. clone = src && jQuery.isPlainObject(src) ? src : {};
  3626. }
  3627. // Never move original objects, clone them
  3628. target[ name ] = jQuery.extend( deep, clone, copy );
  3629. // Don't bring in undefined values
  3630. } else if ( copy !== undefined ) {
  3631. target[ name ] = copy;
  3632. }
  3633. }
  3634. }
  3635. }
  3636. // Return the modified object
  3637. return target;
  3638. };
  3639. jQuery.extend({
  3640. // Unique for each copy of jQuery on the page
  3641. // Non-digits removed to match rinlinejQuery
  3642. expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
  3643. noConflict: function( deep ) {
  3644. if ( window.$ === jQuery ) {
  3645. window.$ = _$;
  3646. }
  3647. if ( deep && window.jQuery === jQuery ) {
  3648. window.jQuery = _jQuery;
  3649. }
  3650. return jQuery;
  3651. },
  3652. // Is the DOM ready to be used? Set to true once it occurs.
  3653. isReady: false,
  3654. // A counter to track how many items to wait for before
  3655. // the ready event fires. See #6781
  3656. readyWait: 1,
  3657. // Hold (or release) the ready event
  3658. holdReady: function( hold ) {
  3659. if ( hold ) {
  3660. jQuery.readyWait++;
  3661. } else {
  3662. jQuery.ready( true );
  3663. }
  3664. },
  3665. // Handle when the DOM is ready
  3666. ready: function( wait ) {
  3667. // Abort if there are pending holds or we're already ready
  3668. if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  3669. return;
  3670. }
  3671. // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
  3672. if ( !document.body ) {
  3673. return setTimeout( jQuery.ready );
  3674. }
  3675. // Remember that the DOM is ready
  3676. jQuery.isReady = true;
  3677. // If a normal DOM Ready event fired, decrement, and wait if need be
  3678. if ( wait !== true && --jQuery.readyWait > 0 ) {
  3679. return;
  3680. }
  3681. // If there are functions bound, to execute
  3682. readyList.resolveWith( document, [ jQuery ] );
  3683. // Trigger any bound ready events
  3684. if ( jQuery.fn.trigger ) {
  3685. jQuery( document ).trigger("ready").off("ready");
  3686. }
  3687. },
  3688. // See test/unit/core.js for details concerning isFunction.
  3689. // Since version 1.3, DOM methods and functions like alert
  3690. // aren't supported. They return false on IE (#2968).
  3691. isFunction: function( obj ) {
  3692. return jQuery.type(obj) === "function";
  3693. },
  3694. isArray: Array.isArray || function( obj ) {
  3695. return jQuery.type(obj) === "array";
  3696. },
  3697. isWindow: function( obj ) {
  3698. /* jshint eqeqeq: false */
  3699. return obj != null && obj == obj.window;
  3700. },
  3701. isNumeric: function( obj ) {
  3702. return !isNaN( parseFloat(obj) ) && isFinite( obj );
  3703. },
  3704. type: function( obj ) {
  3705. if ( obj == null ) {
  3706. return String( obj );
  3707. }
  3708. return typeof obj === "object" || typeof obj === "function" ?
  3709. class2type[ core_toString.call(obj) ] || "object" :
  3710. typeof obj;
  3711. },
  3712. isPlainObject: function( obj ) {
  3713. var key;
  3714. // Must be an Object.
  3715. // Because of IE, we also have to check the presence of the constructor property.
  3716. // Make sure that DOM nodes and window objects don't pass through, as well
  3717. if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  3718. return false;
  3719. }
  3720. try {
  3721. // Not own constructor property must be Object
  3722. if ( obj.constructor &&
  3723. !core_hasOwn.call(obj, "constructor") &&
  3724. !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
  3725. return false;
  3726. }
  3727. } catch ( e ) {
  3728. // IE8,9 Will throw exceptions on certain host objects #9897
  3729. return false;
  3730. }
  3731. // Support: IE<9
  3732. // Handle iteration over inherited properties before own properties.
  3733. if ( jQuery.support.ownLast ) {
  3734. for ( key in obj ) {
  3735. return core_hasOwn.call( obj, key );
  3736. }
  3737. }
  3738. // Own properties are enumerated firstly, so to speed up,
  3739. // if last one is own, then all properties are own.
  3740. for ( key in obj ) {}
  3741. return key === undefined || core_hasOwn.call( obj, key );
  3742. },
  3743. isEmptyObject: function( obj ) {
  3744. var name;
  3745. for ( name in obj ) {
  3746. return false;
  3747. }
  3748. return true;
  3749. },
  3750. error: function( msg ) {
  3751. throw new Error( msg );
  3752. },
  3753. // data: string of html
  3754. // context (optional): If specified, the fragment will be created in this context, defaults to document
  3755. // keepScripts (optional): If true, will include scripts passed in the html string
  3756. parseHTML: function( data, context, keepScripts ) {
  3757. if ( !data || typeof data !== "string" ) {
  3758. return null;
  3759. }
  3760. if ( typeof context === "boolean" ) {
  3761. keepScripts = context;
  3762. context = false;
  3763. }
  3764. context = context || document;
  3765. var parsed = rsingleTag.exec( data ),
  3766. scripts = !keepScripts && [];
  3767. // Single tag
  3768. if ( parsed ) {
  3769. return [ context.createElement( parsed[1] ) ];
  3770. }
  3771. parsed = jQuery.buildFragment( [ data ], context, scripts );
  3772. if ( scripts ) {
  3773. jQuery( scripts ).remove();
  3774. }
  3775. return jQuery.merge( [], parsed.childNodes );
  3776. },
  3777. parseJSON: function( data ) {
  3778. // Attempt to parse using the native JSON parser first
  3779. if ( window.JSON && window.JSON.parse ) {
  3780. return window.JSON.parse( data );
  3781. }
  3782. if ( data === null ) {
  3783. return data;
  3784. }
  3785. if ( typeof data === "string" ) {
  3786. // Make sure leading/trailing whitespace is removed (IE can't handle it)
  3787. data = jQuery.trim( data );
  3788. if ( data ) {
  3789. // Make sure the incoming data is actual JSON
  3790. // Logic borrowed from http://json.org/json2.js
  3791. if ( rvalidchars.test( data.replace( rvalidescape, "@" )
  3792. .replace( rvalidtokens, "]" )
  3793. .replace( rvalidbraces, "")) ) {
  3794. return ( new Function( "return " + data ) )();
  3795. }
  3796. }
  3797. }
  3798. jQuery.error( "Invalid JSON: " + data );
  3799. },
  3800. // Cross-browser xml parsing
  3801. parseXML: function( data ) {
  3802. var xml, tmp;
  3803. if ( !data || typeof data !== "string" ) {
  3804. return null;
  3805. }
  3806. try {
  3807. if ( window.DOMParser ) { // Standard
  3808. tmp = new DOMParser();
  3809. xml = tmp.parseFromString( data , "text/xml" );
  3810. } else { // IE
  3811. xml = new ActiveXObject( "Microsoft.XMLDOM" );
  3812. xml.async = "false";
  3813. xml.loadXML( data );
  3814. }
  3815. } catch( e ) {
  3816. xml = undefined;
  3817. }
  3818. if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
  3819. jQuery.error( "Invalid XML: " + data );
  3820. }
  3821. return xml;
  3822. },
  3823. noop: function() {},
  3824. // Evaluates a script in a global context
  3825. // Workarounds based on findings by Jim Driscoll
  3826. // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
  3827. globalEval: function( data ) {
  3828. if ( data && jQuery.trim( data ) ) {
  3829. // We use execScript on Internet Explorer
  3830. // We use an anonymous function so that context is window
  3831. // rather than jQuery in Firefox
  3832. ( window.execScript || function( data ) {
  3833. window[ "eval" ].call( window, data );
  3834. } )( data );
  3835. }
  3836. },
  3837. // Convert dashed to camelCase; used by the css and data modules
  3838. // Microsoft forgot to hump their vendor prefix (#9572)
  3839. camelCase: function( string ) {
  3840. return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  3841. },
  3842. nodeName: function( elem, name ) {
  3843. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  3844. },
  3845. // args is for internal usage only
  3846. each: function( obj, callback, args ) {
  3847. var value,
  3848. i = 0,
  3849. length = obj.length,
  3850. isArray = isArraylike( obj );
  3851. if ( args ) {
  3852. if ( isArray ) {
  3853. for ( ; i < length; i++ ) {
  3854. value = callback.apply( obj[ i ], args );
  3855. if ( value === false ) {
  3856. break;
  3857. }
  3858. }
  3859. } else {
  3860. for ( i in obj ) {
  3861. value = callback.apply( obj[ i ], args );
  3862. if ( value === false ) {
  3863. break;
  3864. }
  3865. }
  3866. }
  3867. // A special, fast, case for the most common use of each
  3868. } else {
  3869. if ( isArray ) {
  3870. for ( ; i < length; i++ ) {
  3871. value = callback.call( obj[ i ], i, obj[ i ] );
  3872. if ( value === false ) {
  3873. break;
  3874. }
  3875. }
  3876. } else {
  3877. for ( i in obj ) {
  3878. value = callback.call( obj[ i ], i, obj[ i ] );
  3879. if ( value === false ) {
  3880. break;
  3881. }
  3882. }
  3883. }
  3884. }
  3885. return obj;
  3886. },
  3887. // Use native String.trim function wherever possible
  3888. trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
  3889. function( text ) {
  3890. return text == null ?
  3891. "" :
  3892. core_trim.call( text );
  3893. } :
  3894. // Otherwise use our own trimming functionality
  3895. function( text ) {
  3896. return text == null ?
  3897. "" :
  3898. ( text + "" ).replace( rtrim, "" );
  3899. },
  3900. // results is for internal usage only
  3901. makeArray: function( arr, results ) {
  3902. var ret = results || [];
  3903. if ( arr != null ) {
  3904. if ( isArraylike( Object(arr) ) ) {
  3905. jQuery.merge( ret,
  3906. typeof arr === "string" ?
  3907. [ arr ] : arr
  3908. );
  3909. } else {
  3910. core_push.call( ret, arr );
  3911. }
  3912. }
  3913. return ret;
  3914. },
  3915. inArray: function( elem, arr, i ) {
  3916. var len;
  3917. if ( arr ) {
  3918. if ( core_indexOf ) {
  3919. return core_indexOf.call( arr, elem, i );
  3920. }
  3921. len = arr.length;
  3922. i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
  3923. for ( ; i < len; i++ ) {
  3924. // Skip accessing in sparse arrays
  3925. if ( i in arr && arr[ i ] === elem ) {
  3926. return i;
  3927. }
  3928. }
  3929. }
  3930. return -1;
  3931. },
  3932. merge: function( first, second ) {
  3933. var l = second.length,
  3934. i = first.length,
  3935. j = 0;
  3936. if ( typeof l === "number" ) {
  3937. for ( ; j < l; j++ ) {
  3938. first[ i++ ] = second[ j ];
  3939. }
  3940. } else {
  3941. while ( second[j] !== undefined ) {
  3942. first[ i++ ] = second[ j++ ];
  3943. }
  3944. }
  3945. first.length = i;
  3946. return first;
  3947. },
  3948. grep: function( elems, callback, inv ) {
  3949. var retVal,
  3950. ret = [],
  3951. i = 0,
  3952. length = elems.length;
  3953. inv = !!inv;
  3954. // Go through the array, only saving the items
  3955. // that pass the validator function
  3956. for ( ; i < length; i++ ) {
  3957. retVal = !!callback( elems[ i ], i );
  3958. if ( inv !== retVal ) {
  3959. ret.push( elems[ i ] );
  3960. }
  3961. }
  3962. return ret;
  3963. },
  3964. // arg is for internal usage only
  3965. map: function( elems, callback, arg ) {
  3966. var value,
  3967. i = 0,
  3968. length = elems.length,
  3969. isArray = isArraylike( elems ),
  3970. ret = [];
  3971. // Go through the array, translating each of the items to their
  3972. if ( isArray ) {
  3973. for ( ; i < length; i++ ) {
  3974. value = callback( elems[ i ], i, arg );
  3975. if ( value != null ) {
  3976. ret[ ret.length ] = value;
  3977. }
  3978. }
  3979. // Go through every key on the object,
  3980. } else {
  3981. for ( i in elems ) {
  3982. value = callback( elems[ i ], i, arg );
  3983. if ( value != null ) {
  3984. ret[ ret.length ] = value;
  3985. }
  3986. }
  3987. }
  3988. // Flatten any nested arrays
  3989. return core_concat.apply( [], ret );
  3990. },
  3991. // A global GUID counter for objects
  3992. guid: 1,
  3993. // Bind a function to a context, optionally partially applying any
  3994. // arguments.
  3995. proxy: function( fn, context ) {
  3996. var args, proxy, tmp;
  3997. if ( typeof context === "string" ) {
  3998. tmp = fn[ context ];
  3999. context = fn;
  4000. fn = tmp;
  4001. }
  4002. // Quick check to determine if target is callable, in the spec
  4003. // this throws a TypeError, but we will just return undefined.
  4004. if ( !jQuery.isFunction( fn ) ) {
  4005. return undefined;
  4006. }
  4007. // Simulated bind
  4008. args = core_slice.call( arguments, 2 );
  4009. proxy = function() {
  4010. return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
  4011. };
  4012. // Set the guid of unique handler to the same of original handler, so it can be removed
  4013. proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  4014. return proxy;
  4015. },
  4016. // Multifunctional method to get and set values of a collection
  4017. // The value/s can optionally be executed if it's a function
  4018. access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
  4019. var i = 0,
  4020. length = elems.length,
  4021. bulk = key == null;
  4022. // Sets many values
  4023. if ( jQuery.type( key ) === "object" ) {
  4024. chainable = true;
  4025. for ( i in key ) {
  4026. jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
  4027. }
  4028. // Sets one value
  4029. } else if ( value !== undefined ) {
  4030. chainable = true;
  4031. if ( !jQuery.isFunction( value ) ) {
  4032. raw = true;
  4033. }
  4034. if ( bulk ) {
  4035. // Bulk operations run against the entire set
  4036. if ( raw ) {
  4037. fn.call( elems, value );
  4038. fn = null;
  4039. // ...except when executing function values
  4040. } else {
  4041. bulk = fn;
  4042. fn = function( elem, key, value ) {
  4043. return bulk.call( jQuery( elem ), value );
  4044. };
  4045. }
  4046. }
  4047. if ( fn ) {
  4048. for ( ; i < length; i++ ) {
  4049. fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
  4050. }
  4051. }
  4052. }
  4053. return chainable ?
  4054. elems :
  4055. // Gets
  4056. bulk ?
  4057. fn.call( elems ) :
  4058. length ? fn( elems[0], key ) : emptyGet;
  4059. },
  4060. now: function() {
  4061. return ( new Date() ).getTime();
  4062. },
  4063. // A method for quickly swapping in/out CSS properties to get correct calculations.
  4064. // Note: this method belongs to the css module but it's needed here for the support module.
  4065. // If support gets modularized, this method should be moved back to the css module.
  4066. swap: function( elem, options, callback, args ) {
  4067. var ret, name,
  4068. old = {};
  4069. // Remember the old values, and insert the new ones
  4070. for ( name in options ) {
  4071. old[ name ] = elem.style[ name ];
  4072. elem.style[ name ] = options[ name ];
  4073. }
  4074. ret = callback.apply( elem, args || [] );
  4075. // Revert the old values
  4076. for ( name in options ) {
  4077. elem.style[ name ] = old[ name ];
  4078. }
  4079. return ret;
  4080. }
  4081. });
  4082. jQuery.ready.promise = function( obj ) {
  4083. if ( !readyList ) {
  4084. readyList = jQuery.Deferred();
  4085. // Catch cases where $(document).ready() is called after the browser event has already occurred.
  4086. // we once tried to use readyState "interactive" here, but it caused issues like the one
  4087. // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
  4088. if ( document.readyState === "complete" ) {
  4089. // Handle it asynchronously to allow scripts the opportunity to delay ready
  4090. setTimeout( jQuery.ready );
  4091. // Standards-based browsers support DOMContentLoaded
  4092. } else if ( document.addEventListener ) {
  4093. // Use the handy event callback
  4094. document.addEventListener( "DOMContentLoaded", completed, false );
  4095. // A fallback to window.onload, that will always work
  4096. window.addEventListener( "load", completed, false );
  4097. // If IE event model is used
  4098. } else {
  4099. // Ensure firing before onload, maybe late but safe also for iframes
  4100. document.attachEvent( "onreadystatechange", completed );
  4101. // A fallback to window.onload, that will always work
  4102. window.attachEvent( "onload", completed );
  4103. // If IE and not a frame
  4104. // continually check to see if the document is ready
  4105. var top = false;
  4106. try {
  4107. top = window.frameElement == null && document.documentElement;
  4108. } catch(e) {}
  4109. if ( top && top.doScroll ) {
  4110. (function doScrollCheck() {
  4111. if ( !jQuery.isReady ) {
  4112. try {
  4113. // Use the trick by Diego Perini
  4114. // http://javascript.nwbox.com/IEContentLoaded/
  4115. top.doScroll("left");
  4116. } catch(e) {
  4117. return setTimeout( doScrollCheck, 50 );
  4118. }
  4119. // detach all dom ready events
  4120. detach();
  4121. // and execute any waiting functions
  4122. jQuery.ready();
  4123. }
  4124. })();
  4125. }
  4126. }
  4127. }
  4128. return readyList.promise( obj );
  4129. };
  4130. // Populate the class2type map
  4131. jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
  4132. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  4133. });
  4134. function isArraylike( obj ) {
  4135. var length = obj.length,
  4136. type = jQuery.type( obj );
  4137. if ( jQuery.isWindow( obj ) ) {
  4138. return false;
  4139. }
  4140. if ( obj.nodeType === 1 && length ) {
  4141. return true;
  4142. }
  4143. return type === "array" || type !== "function" &&
  4144. ( length === 0 ||
  4145. typeof length === "number" && length > 0 && ( length - 1 ) in obj );
  4146. }
  4147. // All jQuery objects should point back to these
  4148. rootjQuery = jQuery(document);
  4149. /*!
  4150. * Sizzle CSS Selector Engine v1.10.2
  4151. * http://sizzlejs.com/
  4152. *
  4153. * Copyright 2013 jQuery Foundation, Inc. and other contributors
  4154. * Released under the MIT license
  4155. * http://jquery.org/license
  4156. *
  4157. * Date: 2013-07-03
  4158. */
  4159. (function( window, undefined ) {
  4160. var i,
  4161. support,
  4162. cachedruns,
  4163. Expr,
  4164. getText,
  4165. isXML,
  4166. compile,
  4167. outermostContext,
  4168. sortInput,
  4169. // Local document vars
  4170. setDocument,
  4171. document,
  4172. docElem,
  4173. documentIsHTML,
  4174. rbuggyQSA,
  4175. rbuggyMatches,
  4176. matches,
  4177. contains,
  4178. // Instance-specific data
  4179. expando = "sizzle" + -(new Date()),
  4180. preferredDoc = window.document,
  4181. dirruns = 0,
  4182. done = 0,
  4183. classCache = createCache(),
  4184. tokenCache = createCache(),
  4185. compilerCache = createCache(),
  4186. hasDuplicate = false,
  4187. sortOrder = function( a, b ) {
  4188. if ( a === b ) {
  4189. hasDuplicate = true;
  4190. return 0;
  4191. }
  4192. return 0;
  4193. },
  4194. // General-purpose constants
  4195. strundefined = typeof undefined,
  4196. MAX_NEGATIVE = 1 << 31,
  4197. // Instance methods
  4198. hasOwn = ({}).hasOwnProperty,
  4199. arr = [],
  4200. pop = arr.pop,
  4201. push_native = arr.push,
  4202. push = arr.push,
  4203. slice = arr.slice,
  4204. // Use a stripped-down indexOf if we can't use a native one
  4205. indexOf = arr.indexOf || function( elem ) {
  4206. var i = 0,
  4207. len = this.length;
  4208. for ( ; i < len; i++ ) {
  4209. if ( this[i] === elem ) {
  4210. return i;
  4211. }
  4212. }
  4213. return -1;
  4214. },
  4215. booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
  4216. // Regular expressions
  4217. // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
  4218. whitespace = "[\\x20\\t\\r\\n\\f]",
  4219. // http://www.w3.org/TR/css3-syntax/#characters
  4220. characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
  4221. // Loosely modeled on CSS identifier characters
  4222. // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
  4223. // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
  4224. identifier = characterEncoding.replace( "w", "w#" ),
  4225. // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
  4226. attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
  4227. "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
  4228. // Prefer arguments quoted,
  4229. // then not containing pseudos/brackets,
  4230. // then attribute selectors/non-parenthetical expressions,
  4231. // then anything else
  4232. // These preferences are here to reduce the number of selectors
  4233. // needing tokenize in the PSEUDO preFilter
  4234. pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
  4235. // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  4236. rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
  4237. rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  4238. rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
  4239. rsibling = new RegExp( whitespace + "*[+~]" ),
  4240. rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
  4241. rpseudo = new RegExp( pseudos ),
  4242. ridentifier = new RegExp( "^" + identifier + "$" ),
  4243. matchExpr = {
  4244. "ID": new RegExp( "^#(" + characterEncoding + ")" ),
  4245. "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
  4246. "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
  4247. "ATTR": new RegExp( "^" + attributes ),
  4248. "PSEUDO": new RegExp( "^" + pseudos ),
  4249. "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
  4250. "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
  4251. "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  4252. "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  4253. // For use in libraries implementing .is()
  4254. // We use this for POS matching in `select`
  4255. "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
  4256. whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  4257. },
  4258. rnative = /^[^{]+\{\s*\[native \w/,
  4259. // Easily-parseable/retrievable ID or TAG or CLASS selectors
  4260. rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  4261. rinputs = /^(?:input|select|textarea|button)$/i,
  4262. rheader = /^h\d$/i,
  4263. rescape = /'|\\/g,
  4264. // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  4265. runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
  4266. funescape = function( _, escaped, escapedWhitespace ) {
  4267. var high = "0x" + escaped - 0x10000;
  4268. // NaN means non-codepoint
  4269. // Support: Firefox
  4270. // Workaround erroneous numeric interpretation of +"0x"
  4271. return high !== high || escapedWhitespace ?
  4272. escaped :
  4273. // BMP codepoint
  4274. high < 0 ?
  4275. String.fromCharCode( high + 0x10000 ) :
  4276. // Supplemental Plane codepoint (surrogate pair)
  4277. String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  4278. };
  4279. // Optimize for push.apply( _, NodeList )
  4280. try {
  4281. push.apply(
  4282. (arr = slice.call( preferredDoc.childNodes )),
  4283. preferredDoc.childNodes
  4284. );
  4285. // Support: Android<4.0
  4286. // Detect silently failing push.apply
  4287. arr[ preferredDoc.childNodes.length ].nodeType;
  4288. } catch ( e ) {
  4289. push = { apply: arr.length ?
  4290. // Leverage slice if possible
  4291. function( target, els ) {
  4292. push_native.apply( target, slice.call(els) );
  4293. } :
  4294. // Support: IE<9
  4295. // Otherwise append directly
  4296. function( target, els ) {
  4297. var j = target.length,
  4298. i = 0;
  4299. // Can't trust NodeList.length
  4300. while ( (target[j++] = els[i++]) ) {}
  4301. target.length = j - 1;
  4302. }
  4303. };
  4304. }
  4305. function Sizzle( selector, context, results, seed ) {
  4306. var match, elem, m, nodeType,
  4307. // QSA vars
  4308. i, groups, old, nid, newContext, newSelector;
  4309. if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
  4310. setDocument( context );
  4311. }
  4312. context = context || document;
  4313. results = results || [];
  4314. if ( !selector || typeof selector !== "string" ) {
  4315. return results;
  4316. }
  4317. if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
  4318. return [];
  4319. }
  4320. if ( documentIsHTML && !seed ) {
  4321. // Shortcuts
  4322. if ( (match = rquickExpr.exec( selector )) ) {
  4323. // Speed-up: Sizzle("#ID")
  4324. if ( (m = match[1]) ) {
  4325. if ( nodeType === 9 ) {
  4326. elem = context.getElementById( m );
  4327. // Check parentNode to catch when Blackberry 4.6 returns
  4328. // nodes that are no longer in the document #6963
  4329. if ( elem && elem.parentNode ) {
  4330. // Handle the case where IE, Opera, and Webkit return items
  4331. // by name instead of ID
  4332. if ( elem.id === m ) {
  4333. results.push( elem );
  4334. return results;
  4335. }
  4336. } else {
  4337. return results;
  4338. }
  4339. } else {
  4340. // Context is not a document
  4341. if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
  4342. contains( context, elem ) && elem.id === m ) {
  4343. results.push( elem );
  4344. return results;
  4345. }
  4346. }
  4347. // Speed-up: Sizzle("TAG")
  4348. } else if ( match[2] ) {
  4349. push.apply( results, context.getElementsByTagName( selector ) );
  4350. return results;
  4351. // Speed-up: Sizzle(".CLASS")
  4352. } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
  4353. push.apply( results, context.getElementsByClassName( m ) );
  4354. return results;
  4355. }
  4356. }
  4357. // QSA path
  4358. if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
  4359. nid = old = expando;
  4360. newContext = context;
  4361. newSelector = nodeType === 9 && selector;
  4362. // qSA works strangely on Element-rooted queries
  4363. // We can work around this by specifying an extra ID on the root
  4364. // and working up from there (Thanks to Andrew Dupont for the technique)
  4365. // IE 8 doesn't work on object elements
  4366. if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
  4367. groups = tokenize( selector );
  4368. if ( (old = context.getAttribute("id")) ) {
  4369. nid = old.replace( rescape, "\\$&" );
  4370. } else {
  4371. context.setAttribute( "id", nid );
  4372. }
  4373. nid = "[id='" + nid + "'] ";
  4374. i = groups.length;
  4375. while ( i-- ) {
  4376. groups[i] = nid + toSelector( groups[i] );
  4377. }
  4378. newContext = rsibling.test( selector ) && context.parentNode || context;
  4379. newSelector = groups.join(",");
  4380. }
  4381. if ( newSelector ) {
  4382. try {
  4383. push.apply( results,
  4384. newContext.querySelectorAll( newSelector )
  4385. );
  4386. return results;
  4387. } catch(qsaError) {
  4388. } finally {
  4389. if ( !old ) {
  4390. context.removeAttribute("id");
  4391. }
  4392. }
  4393. }
  4394. }
  4395. }
  4396. // All others
  4397. return select( selector.replace( rtrim, "$1" ), context, results, seed );
  4398. }
  4399. /**
  4400. * Create key-value caches of limited size
  4401. * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
  4402. * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
  4403. * deleting the oldest entry
  4404. */
  4405. function createCache() {
  4406. var keys = [];
  4407. function cache( key, value ) {
  4408. // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  4409. if ( keys.push( key += " " ) > Expr.cacheLength ) {
  4410. // Only keep the most recent entries
  4411. delete cache[ keys.shift() ];
  4412. }
  4413. return (cache[ key ] = value);
  4414. }
  4415. return cache;
  4416. }
  4417. /**
  4418. * Mark a function for special use by Sizzle
  4419. * @param {Function} fn The function to mark
  4420. */
  4421. function markFunction( fn ) {
  4422. fn[ expando ] = true;
  4423. return fn;
  4424. }
  4425. /**
  4426. * Support testing using an element
  4427. * @param {Function} fn Passed the created div and expects a boolean result
  4428. */
  4429. function assert( fn ) {
  4430. var div = document.createElement("div");
  4431. try {
  4432. return !!fn( div );
  4433. } catch (e) {
  4434. return false;
  4435. } finally {
  4436. // Remove from its parent by default
  4437. if ( div.parentNode ) {
  4438. div.parentNode.removeChild( div );
  4439. }
  4440. // release memory in IE
  4441. div = null;
  4442. }
  4443. }
  4444. /**
  4445. * Adds the same handler for all of the specified attrs
  4446. * @param {String} attrs Pipe-separated list of attributes
  4447. * @param {Function} handler The method that will be applied
  4448. */
  4449. function addHandle( attrs, handler ) {
  4450. var arr = attrs.split("|"),
  4451. i = attrs.length;
  4452. while ( i-- ) {
  4453. Expr.attrHandle[ arr[i] ] = handler;
  4454. }
  4455. }
  4456. /**
  4457. * Checks document order of two siblings
  4458. * @param {Element} a
  4459. * @param {Element} b
  4460. * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
  4461. */
  4462. function siblingCheck( a, b ) {
  4463. var cur = b && a,
  4464. diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  4465. ( ~b.sourceIndex || MAX_NEGATIVE ) -
  4466. ( ~a.sourceIndex || MAX_NEGATIVE );
  4467. // Use IE sourceIndex if available on both nodes
  4468. if ( diff ) {
  4469. return diff;
  4470. }
  4471. // Check if b follows a
  4472. if ( cur ) {
  4473. while ( (cur = cur.nextSibling) ) {
  4474. if ( cur === b ) {
  4475. return -1;
  4476. }
  4477. }
  4478. }
  4479. return a ? 1 : -1;
  4480. }
  4481. /**
  4482. * Returns a function to use in pseudos for input types
  4483. * @param {String} type
  4484. */
  4485. function createInputPseudo( type ) {
  4486. return function( elem ) {
  4487. var name = elem.nodeName.toLowerCase();
  4488. return name === "input" && elem.type === type;
  4489. };
  4490. }
  4491. /**
  4492. * Returns a function to use in pseudos for buttons
  4493. * @param {String} type
  4494. */
  4495. function createButtonPseudo( type ) {
  4496. return function( elem ) {
  4497. var name = elem.nodeName.toLowerCase();
  4498. return (name === "input" || name === "button") && elem.type === type;
  4499. };
  4500. }
  4501. /**
  4502. * Returns a function to use in pseudos for positionals
  4503. * @param {Function} fn
  4504. */
  4505. function createPositionalPseudo( fn ) {
  4506. return markFunction(function( argument ) {
  4507. argument = +argument;
  4508. return markFunction(function( seed, matches ) {
  4509. var j,
  4510. matchIndexes = fn( [], seed.length, argument ),
  4511. i = matchIndexes.length;
  4512. // Match elements found at the specified indexes
  4513. while ( i-- ) {
  4514. if ( seed[ (j = matchIndexes[i]) ] ) {
  4515. seed[j] = !(matches[j] = seed[j]);
  4516. }
  4517. }
  4518. });
  4519. });
  4520. }
  4521. /**
  4522. * Detect xml
  4523. * @param {Element|Object} elem An element or a document
  4524. */
  4525. isXML = Sizzle.isXML = function( elem ) {
  4526. // documentElement is verified for cases where it doesn't yet exist
  4527. // (such as loading iframes in IE - #4833)
  4528. var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  4529. return documentElement ? documentElement.nodeName !== "HTML" : false;
  4530. };
  4531. // Expose support vars for convenience
  4532. support = Sizzle.support = {};
  4533. /**
  4534. * Sets document-related variables once based on the current document
  4535. * @param {Element|Object} [doc] An element or document object to use to set the document
  4536. * @returns {Object} Returns the current document
  4537. */
  4538. setDocument = Sizzle.setDocument = function( node ) {
  4539. var doc = node ? node.ownerDocument || node : preferredDoc,
  4540. parent = doc.defaultView;
  4541. // If no document and documentElement is available, return
  4542. if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  4543. return document;
  4544. }
  4545. // Set our document
  4546. document = doc;
  4547. docElem = doc.documentElement;
  4548. // Support tests
  4549. documentIsHTML = !isXML( doc );
  4550. // Support: IE>8
  4551. // If iframe document is assigned to "document" variable and if iframe has been reloaded,
  4552. // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
  4553. // IE6-8 do not support the defaultView property so parent will be undefined
  4554. if ( parent && parent.attachEvent && parent !== parent.top ) {
  4555. parent.attachEvent( "onbeforeunload", function() {
  4556. setDocument();
  4557. });
  4558. }
  4559. /* Attributes
  4560. ---------------------------------------------------------------------- */
  4561. // Support: IE<8
  4562. // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
  4563. support.attributes = assert(function( div ) {
  4564. div.className = "i";
  4565. return !div.getAttribute("className");
  4566. });
  4567. /* getElement(s)By*
  4568. ---------------------------------------------------------------------- */
  4569. // Check if getElementsByTagName("*") returns only elements
  4570. support.getElementsByTagName = assert(function( div ) {
  4571. div.appendChild( doc.createComment("") );
  4572. return !div.getElementsByTagName("*").length;
  4573. });
  4574. // Check if getElementsByClassName can be trusted
  4575. support.getElementsByClassName = assert(function( div ) {
  4576. div.innerHTML = "<div class='a'></div><div class='a i'></div>";
  4577. // Support: Safari<4
  4578. // Catch class over-caching
  4579. div.firstChild.className = "i";
  4580. // Support: Opera<10
  4581. // Catch gEBCN failure to find non-leading classes
  4582. return div.getElementsByClassName("i").length === 2;
  4583. });
  4584. // Support: IE<10
  4585. // Check if getElementById returns elements by name
  4586. // The broken getElementById methods don't pick up programatically-set names,
  4587. // so use a roundabout getElementsByName test
  4588. support.getById = assert(function( div ) {
  4589. docElem.appendChild( div ).id = expando;
  4590. return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
  4591. });
  4592. // ID find and filter
  4593. if ( support.getById ) {
  4594. Expr.find["ID"] = function( id, context ) {
  4595. if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
  4596. var m = context.getElementById( id );
  4597. // Check parentNode to catch when Blackberry 4.6 returns
  4598. // nodes that are no longer in the document #6963
  4599. return m && m.parentNode ? [m] : [];
  4600. }
  4601. };
  4602. Expr.filter["ID"] = function( id ) {
  4603. var attrId = id.replace( runescape, funescape );
  4604. return function( elem ) {
  4605. return elem.getAttribute("id") === attrId;
  4606. };
  4607. };
  4608. } else {
  4609. // Support: IE6/7
  4610. // getElementById is not reliable as a find shortcut
  4611. delete Expr.find["ID"];
  4612. Expr.filter["ID"] = function( id ) {
  4613. var attrId = id.replace( runescape, funescape );
  4614. return function( elem ) {
  4615. var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
  4616. return node && node.value === attrId;
  4617. };
  4618. };
  4619. }
  4620. // Tag
  4621. Expr.find["TAG"] = support.getElementsByTagName ?
  4622. function( tag, context ) {
  4623. if ( typeof context.getElementsByTagName !== strundefined ) {
  4624. return context.getElementsByTagName( tag );
  4625. }
  4626. } :
  4627. function( tag, context ) {
  4628. var elem,
  4629. tmp = [],
  4630. i = 0,
  4631. results = context.getElementsByTagName( tag );
  4632. // Filter out possible comments
  4633. if ( tag === "*" ) {
  4634. while ( (elem = results[i++]) ) {
  4635. if ( elem.nodeType === 1 ) {
  4636. tmp.push( elem );
  4637. }
  4638. }
  4639. return tmp;
  4640. }
  4641. return results;
  4642. };
  4643. // Class
  4644. Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  4645. if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
  4646. return context.getElementsByClassName( className );
  4647. }
  4648. };
  4649. /* QSA/matchesSelector
  4650. ---------------------------------------------------------------------- */
  4651. // QSA and matchesSelector support
  4652. // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  4653. rbuggyMatches = [];
  4654. // qSa(:focus) reports false when true (Chrome 21)
  4655. // We allow this because of a bug in IE8/9 that throws an error
  4656. // whenever `document.activeElement` is accessed on an iframe
  4657. // So, we allow :focus to pass through QSA all the time to avoid the IE error
  4658. // See http://bugs.jquery.com/ticket/13378
  4659. rbuggyQSA = [];
  4660. if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
  4661. // Build QSA regex
  4662. // Regex strategy adopted from Diego Perini
  4663. assert(function( div ) {
  4664. // Select is set to empty string on purpose
  4665. // This is to test IE's treatment of not explicitly
  4666. // setting a boolean content attribute,
  4667. // since its presence should be enough
  4668. // http://bugs.jquery.com/ticket/12359
  4669. div.innerHTML = "<select><option selected=''></option></select>";
  4670. // Support: IE8
  4671. // Boolean attributes and "value" are not treated correctly
  4672. if ( !div.querySelectorAll("[selected]").length ) {
  4673. rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  4674. }
  4675. // Webkit/Opera - :checked should return selected option elements
  4676. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  4677. // IE8 throws error here and will not see later tests
  4678. if ( !div.querySelectorAll(":checked").length ) {
  4679. rbuggyQSA.push(":checked");
  4680. }
  4681. });
  4682. assert(function( div ) {
  4683. // Support: Opera 10-12/IE8
  4684. // ^= $= *= and empty values
  4685. // Should not select anything
  4686. // Support: Windows 8 Native Apps
  4687. // The type attribute is restricted during .innerHTML assignment
  4688. var input = doc.createElement("input");
  4689. input.setAttribute( "type", "hidden" );
  4690. div.appendChild( input ).setAttribute( "t", "" );
  4691. if ( div.querySelectorAll("[t^='']").length ) {
  4692. rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  4693. }
  4694. // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  4695. // IE8 throws error here and will not see later tests
  4696. if ( !div.querySelectorAll(":enabled").length ) {
  4697. rbuggyQSA.push( ":enabled", ":disabled" );
  4698. }
  4699. // Opera 10-11 does not throw on post-comma invalid pseudos
  4700. div.querySelectorAll("*,:x");
  4701. rbuggyQSA.push(",.*:");
  4702. });
  4703. }
  4704. if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
  4705. docElem.mozMatchesSelector ||
  4706. docElem.oMatchesSelector ||
  4707. docElem.msMatchesSelector) )) ) {
  4708. assert(function( div ) {
  4709. // Check to see if it's possible to do matchesSelector
  4710. // on a disconnected node (IE 9)
  4711. support.disconnectedMatch = matches.call( div, "div" );
  4712. // This should fail with an exception
  4713. // Gecko does not error, returns false instead
  4714. matches.call( div, "[s!='']:x" );
  4715. rbuggyMatches.push( "!=", pseudos );
  4716. });
  4717. }
  4718. rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  4719. rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  4720. /* Contains
  4721. ---------------------------------------------------------------------- */
  4722. // Element contains another
  4723. // Purposefully does not implement inclusive descendent
  4724. // As in, an element does not contain itself
  4725. contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
  4726. function( a, b ) {
  4727. var adown = a.nodeType === 9 ? a.documentElement : a,
  4728. bup = b && b.parentNode;
  4729. return a === bup || !!( bup && bup.nodeType === 1 && (
  4730. adown.contains ?
  4731. adown.contains( bup ) :
  4732. a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  4733. ));
  4734. } :
  4735. function( a, b ) {
  4736. if ( b ) {
  4737. while ( (b = b.parentNode) ) {
  4738. if ( b === a ) {
  4739. return true;
  4740. }
  4741. }
  4742. }
  4743. return false;
  4744. };
  4745. /* Sorting
  4746. ---------------------------------------------------------------------- */
  4747. // Document order sorting
  4748. sortOrder = docElem.compareDocumentPosition ?
  4749. function( a, b ) {
  4750. // Flag for duplicate removal
  4751. if ( a === b ) {
  4752. hasDuplicate = true;
  4753. return 0;
  4754. }
  4755. var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
  4756. if ( compare ) {
  4757. // Disconnected nodes
  4758. if ( compare & 1 ||
  4759. (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  4760. // Choose the first element that is related to our preferred document
  4761. if ( a === doc || contains(preferredDoc, a) ) {
  4762. return -1;
  4763. }
  4764. if ( b === doc || contains(preferredDoc, b) ) {
  4765. return 1;
  4766. }
  4767. // Maintain original order
  4768. return sortInput ?
  4769. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  4770. 0;
  4771. }
  4772. return compare & 4 ? -1 : 1;
  4773. }
  4774. // Not directly comparable, sort on existence of method
  4775. return a.compareDocumentPosition ? -1 : 1;
  4776. } :
  4777. function( a, b ) {
  4778. var cur,
  4779. i = 0,
  4780. aup = a.parentNode,
  4781. bup = b.parentNode,
  4782. ap = [ a ],
  4783. bp = [ b ];
  4784. // Exit early if the nodes are identical
  4785. if ( a === b ) {
  4786. hasDuplicate = true;
  4787. return 0;
  4788. // Parentless nodes are either documents or disconnected
  4789. } else if ( !aup || !bup ) {
  4790. return a === doc ? -1 :
  4791. b === doc ? 1 :
  4792. aup ? -1 :
  4793. bup ? 1 :
  4794. sortInput ?
  4795. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  4796. 0;
  4797. // If the nodes are siblings, we can do a quick check
  4798. } else if ( aup === bup ) {
  4799. return siblingCheck( a, b );
  4800. }
  4801. // Otherwise we need full lists of their ancestors for comparison
  4802. cur = a;
  4803. while ( (cur = cur.parentNode) ) {
  4804. ap.unshift( cur );
  4805. }
  4806. cur = b;
  4807. while ( (cur = cur.parentNode) ) {
  4808. bp.unshift( cur );
  4809. }
  4810. // Walk down the tree looking for a discrepancy
  4811. while ( ap[i] === bp[i] ) {
  4812. i++;
  4813. }
  4814. return i ?
  4815. // Do a sibling check if the nodes have a common ancestor
  4816. siblingCheck( ap[i], bp[i] ) :
  4817. // Otherwise nodes in our document sort first
  4818. ap[i] === preferredDoc ? -1 :
  4819. bp[i] === preferredDoc ? 1 :
  4820. 0;
  4821. };
  4822. return doc;
  4823. };
  4824. Sizzle.matches = function( expr, elements ) {
  4825. return Sizzle( expr, null, null, elements );
  4826. };
  4827. Sizzle.matchesSelector = function( elem, expr ) {
  4828. // Set document vars if needed
  4829. if ( ( elem.ownerDocument || elem ) !== document ) {
  4830. setDocument( elem );
  4831. }
  4832. // Make sure that attribute selectors are quoted
  4833. expr = expr.replace( rattributeQuotes, "='$1']" );
  4834. if ( support.matchesSelector && documentIsHTML &&
  4835. ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  4836. ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
  4837. try {
  4838. var ret = matches.call( elem, expr );
  4839. // IE 9's matchesSelector returns false on disconnected nodes
  4840. if ( ret || support.disconnectedMatch ||
  4841. // As well, disconnected nodes are said to be in a document
  4842. // fragment in IE 9
  4843. elem.document && elem.document.nodeType !== 11 ) {
  4844. return ret;
  4845. }
  4846. } catch(e) {}
  4847. }
  4848. return Sizzle( expr, document, null, [elem] ).length > 0;
  4849. };
  4850. Sizzle.contains = function( context, elem ) {
  4851. // Set document vars if needed
  4852. if ( ( context.ownerDocument || context ) !== document ) {
  4853. setDocument( context );
  4854. }
  4855. return contains( context, elem );
  4856. };
  4857. Sizzle.attr = function( elem, name ) {
  4858. // Set document vars if needed
  4859. if ( ( elem.ownerDocument || elem ) !== document ) {
  4860. setDocument( elem );
  4861. }
  4862. var fn = Expr.attrHandle[ name.toLowerCase() ],
  4863. // Don't get fooled by Object.prototype properties (jQuery #13807)
  4864. val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  4865. fn( elem, name, !documentIsHTML ) :
  4866. undefined;
  4867. return val === undefined ?
  4868. support.attributes || !documentIsHTML ?
  4869. elem.getAttribute( name ) :
  4870. (val = elem.getAttributeNode(name)) && val.specified ?
  4871. val.value :
  4872. null :
  4873. val;
  4874. };
  4875. Sizzle.error = function( msg ) {
  4876. throw new Error( "Syntax error, unrecognized expression: " + msg );
  4877. };
  4878. /**
  4879. * Document sorting and removing duplicates
  4880. * @param {ArrayLike} results
  4881. */
  4882. Sizzle.uniqueSort = function( results ) {
  4883. var elem,
  4884. duplicates = [],
  4885. j = 0,
  4886. i = 0;
  4887. // Unless we *know* we can detect duplicates, assume their presence
  4888. hasDuplicate = !support.detectDuplicates;
  4889. sortInput = !support.sortStable && results.slice( 0 );
  4890. results.sort( sortOrder );
  4891. if ( hasDuplicate ) {
  4892. while ( (elem = results[i++]) ) {
  4893. if ( elem === results[ i ] ) {
  4894. j = duplicates.push( i );
  4895. }
  4896. }
  4897. while ( j-- ) {
  4898. results.splice( duplicates[ j ], 1 );
  4899. }
  4900. }
  4901. return results;
  4902. };
  4903. /**
  4904. * Utility function for retrieving the text value of an array of DOM nodes
  4905. * @param {Array|Element} elem
  4906. */
  4907. getText = Sizzle.getText = function( elem ) {
  4908. var node,
  4909. ret = "",
  4910. i = 0,
  4911. nodeType = elem.nodeType;
  4912. if ( !nodeType ) {
  4913. // If no nodeType, this is expected to be an array
  4914. for ( ; (node = elem[i]); i++ ) {
  4915. // Do not traverse comment nodes
  4916. ret += getText( node );
  4917. }
  4918. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  4919. // Use textContent for elements
  4920. // innerText usage removed for consistency of new lines (see #11153)
  4921. if ( typeof elem.textContent === "string" ) {
  4922. return elem.textContent;
  4923. } else {
  4924. // Traverse its children
  4925. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  4926. ret += getText( elem );
  4927. }
  4928. }
  4929. } else if ( nodeType === 3 || nodeType === 4 ) {
  4930. return elem.nodeValue;
  4931. }
  4932. // Do not include comment or processing instruction nodes
  4933. return ret;
  4934. };
  4935. Expr = Sizzle.selectors = {
  4936. // Can be adjusted by the user
  4937. cacheLength: 50,
  4938. createPseudo: markFunction,
  4939. match: matchExpr,
  4940. attrHandle: {},
  4941. find: {},
  4942. relative: {
  4943. ">": { dir: "parentNode", first: true },
  4944. " ": { dir: "parentNode" },
  4945. "+": { dir: "previousSibling", first: true },
  4946. "~": { dir: "previousSibling" }
  4947. },
  4948. preFilter: {
  4949. "ATTR": function( match ) {
  4950. match[1] = match[1].replace( runescape, funescape );
  4951. // Move the given value to match[3] whether quoted or unquoted
  4952. match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
  4953. if ( match[2] === "~=" ) {
  4954. match[3] = " " + match[3] + " ";
  4955. }
  4956. return match.slice( 0, 4 );
  4957. },
  4958. "CHILD": function( match ) {
  4959. /* matches from matchExpr["CHILD"]
  4960. 1 type (only|nth|...)
  4961. 2 what (child|of-type)
  4962. 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  4963. 4 xn-component of xn+y argument ([+-]?\d*n|)
  4964. 5 sign of xn-component
  4965. 6 x of xn-component
  4966. 7 sign of y-component
  4967. 8 y of y-component
  4968. */
  4969. match[1] = match[1].toLowerCase();
  4970. if ( match[1].slice( 0, 3 ) === "nth" ) {
  4971. // nth-* requires argument
  4972. if ( !match[3] ) {
  4973. Sizzle.error( match[0] );
  4974. }
  4975. // numeric x and y parameters for Expr.filter.CHILD
  4976. // remember that false/true cast respectively to 0/1
  4977. match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  4978. match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  4979. // other types prohibit arguments
  4980. } else if ( match[3] ) {
  4981. Sizzle.error( match[0] );
  4982. }
  4983. return match;
  4984. },
  4985. "PSEUDO": function( match ) {
  4986. var excess,
  4987. unquoted = !match[5] && match[2];
  4988. if ( matchExpr["CHILD"].test( match[0] ) ) {
  4989. return null;
  4990. }
  4991. // Accept quoted arguments as-is
  4992. if ( match[3] && match[4] !== undefined ) {
  4993. match[2] = match[4];
  4994. // Strip excess characters from unquoted arguments
  4995. } else if ( unquoted && rpseudo.test( unquoted ) &&
  4996. // Get excess from tokenize (recursively)
  4997. (excess = tokenize( unquoted, true )) &&
  4998. // advance to the next closing parenthesis
  4999. (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  5000. // excess is a negative index
  5001. match[0] = match[0].slice( 0, excess );
  5002. match[2] = unquoted.slice( 0, excess );
  5003. }
  5004. // Return only captures needed by the pseudo filter method (type and argument)
  5005. return match.slice( 0, 3 );
  5006. }
  5007. },
  5008. filter: {
  5009. "TAG": function( nodeNameSelector ) {
  5010. var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  5011. return nodeNameSelector === "*" ?
  5012. function() { return true; } :
  5013. function( elem ) {
  5014. return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  5015. };
  5016. },
  5017. "CLASS": function( className ) {
  5018. var pattern = classCache[ className + " " ];
  5019. return pattern ||
  5020. (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  5021. classCache( className, function( elem ) {
  5022. return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
  5023. });
  5024. },
  5025. "ATTR": function( name, operator, check ) {
  5026. return function( elem ) {
  5027. var result = Sizzle.attr( elem, name );
  5028. if ( result == null ) {
  5029. return operator === "!=";
  5030. }
  5031. if ( !operator ) {
  5032. return true;
  5033. }
  5034. result += "";
  5035. return operator === "=" ? result === check :
  5036. operator === "!=" ? result !== check :
  5037. operator === "^=" ? check && result.indexOf( check ) === 0 :
  5038. operator === "*=" ? check && result.indexOf( check ) > -1 :
  5039. operator === "$=" ? check && result.slice( -check.length ) === check :
  5040. operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
  5041. operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  5042. false;
  5043. };
  5044. },
  5045. "CHILD": function( type, what, argument, first, last ) {
  5046. var simple = type.slice( 0, 3 ) !== "nth",
  5047. forward = type.slice( -4 ) !== "last",
  5048. ofType = what === "of-type";
  5049. return first === 1 && last === 0 ?
  5050. // Shortcut for :nth-*(n)
  5051. function( elem ) {
  5052. return !!elem.parentNode;
  5053. } :
  5054. function( elem, context, xml ) {
  5055. var cache, outerCache, node, diff, nodeIndex, start,
  5056. dir = simple !== forward ? "nextSibling" : "previousSibling",
  5057. parent = elem.parentNode,
  5058. name = ofType && elem.nodeName.toLowerCase(),
  5059. useCache = !xml && !ofType;
  5060. if ( parent ) {
  5061. // :(first|last|only)-(child|of-type)
  5062. if ( simple ) {
  5063. while ( dir ) {
  5064. node = elem;
  5065. while ( (node = node[ dir ]) ) {
  5066. if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
  5067. return false;
  5068. }
  5069. }
  5070. // Reverse direction for :only-* (if we haven't yet done so)
  5071. start = dir = type === "only" && !start && "nextSibling";
  5072. }
  5073. return true;
  5074. }
  5075. start = [ forward ? parent.firstChild : parent.lastChild ];
  5076. // non-xml :nth-child(...) stores cache data on `parent`
  5077. if ( forward && useCache ) {
  5078. // Seek `elem` from a previously-cached index
  5079. outerCache = parent[ expando ] || (parent[ expando ] = {});
  5080. cache = outerCache[ type ] || [];
  5081. nodeIndex = cache[0] === dirruns && cache[1];
  5082. diff = cache[0] === dirruns && cache[2];
  5083. node = nodeIndex && parent.childNodes[ nodeIndex ];
  5084. while ( (node = ++nodeIndex && node && node[ dir ] ||
  5085. // Fallback to seeking `elem` from the start
  5086. (diff = nodeIndex = 0) || start.pop()) ) {
  5087. // When found, cache indexes on `parent` and break
  5088. if ( node.nodeType === 1 && ++diff && node === elem ) {
  5089. outerCache[ type ] = [ dirruns, nodeIndex, diff ];
  5090. break;
  5091. }
  5092. }
  5093. // Use previously-cached element index if available
  5094. } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
  5095. diff = cache[1];
  5096. // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
  5097. } else {
  5098. // Use the same loop as above to seek `elem` from the start
  5099. while ( (node = ++nodeIndex && node && node[ dir ] ||
  5100. (diff = nodeIndex = 0) || start.pop()) ) {
  5101. if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
  5102. // Cache the index of each encountered element
  5103. if ( useCache ) {
  5104. (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
  5105. }
  5106. if ( node === elem ) {
  5107. break;
  5108. }
  5109. }
  5110. }
  5111. }
  5112. // Incorporate the offset, then check against cycle size
  5113. diff -= last;
  5114. return diff === first || ( diff % first === 0 && diff / first >= 0 );
  5115. }
  5116. };
  5117. },
  5118. "PSEUDO": function( pseudo, argument ) {
  5119. // pseudo-class names are case-insensitive
  5120. // http://www.w3.org/TR/selectors/#pseudo-classes
  5121. // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  5122. // Remember that setFilters inherits from pseudos
  5123. var args,
  5124. fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  5125. Sizzle.error( "unsupported pseudo: " + pseudo );
  5126. // The user may use createPseudo to indicate that
  5127. // arguments are needed to create the filter function
  5128. // just as Sizzle does
  5129. if ( fn[ expando ] ) {
  5130. return fn( argument );
  5131. }
  5132. // But maintain support for old signatures
  5133. if ( fn.length > 1 ) {
  5134. args = [ pseudo, pseudo, "", argument ];
  5135. return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  5136. markFunction(function( seed, matches ) {
  5137. var idx,
  5138. matched = fn( seed, argument ),
  5139. i = matched.length;
  5140. while ( i-- ) {
  5141. idx = indexOf.call( seed, matched[i] );
  5142. seed[ idx ] = !( matches[ idx ] = matched[i] );
  5143. }
  5144. }) :
  5145. function( elem ) {
  5146. return fn( elem, 0, args );
  5147. };
  5148. }
  5149. return fn;
  5150. }
  5151. },
  5152. pseudos: {
  5153. // Potentially complex pseudos
  5154. "not": markFunction(function( selector ) {
  5155. // Trim the selector passed to compile
  5156. // to avoid treating leading and trailing
  5157. // spaces as combinators
  5158. var input = [],
  5159. results = [],
  5160. matcher = compile( selector.replace( rtrim, "$1" ) );
  5161. return matcher[ expando ] ?
  5162. markFunction(function( seed, matches, context, xml ) {
  5163. var elem,
  5164. unmatched = matcher( seed, null, xml, [] ),
  5165. i = seed.length;
  5166. // Match elements unmatched by `matcher`
  5167. while ( i-- ) {
  5168. if ( (elem = unmatched[i]) ) {
  5169. seed[i] = !(matches[i] = elem);
  5170. }
  5171. }
  5172. }) :
  5173. function( elem, context, xml ) {
  5174. input[0] = elem;
  5175. matcher( input, null, xml, results );
  5176. return !results.pop();
  5177. };
  5178. }),
  5179. "has": markFunction(function( selector ) {
  5180. return function( elem ) {
  5181. return Sizzle( selector, elem ).length > 0;
  5182. };
  5183. }),
  5184. "contains": markFunction(function( text ) {
  5185. return function( elem ) {
  5186. return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  5187. };
  5188. }),
  5189. // "Whether an element is represented by a :lang() selector
  5190. // is based solely on the element's language value
  5191. // being equal to the identifier C,
  5192. // or beginning with the identifier C immediately followed by "-".
  5193. // The matching of C against the element's language value is performed case-insensitively.
  5194. // The identifier C does not have to be a valid language name."
  5195. // http://www.w3.org/TR/selectors/#lang-pseudo
  5196. "lang": markFunction( function( lang ) {
  5197. // lang value must be a valid identifier
  5198. if ( !ridentifier.test(lang || "") ) {
  5199. Sizzle.error( "unsupported lang: " + lang );
  5200. }
  5201. lang = lang.replace( runescape, funescape ).toLowerCase();
  5202. return function( elem ) {
  5203. var elemLang;
  5204. do {
  5205. if ( (elemLang = documentIsHTML ?
  5206. elem.lang :
  5207. elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  5208. elemLang = elemLang.toLowerCase();
  5209. return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  5210. }
  5211. } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  5212. return false;
  5213. };
  5214. }),
  5215. // Miscellaneous
  5216. "target": function( elem ) {
  5217. var hash = window.location && window.location.hash;
  5218. return hash && hash.slice( 1 ) === elem.id;
  5219. },
  5220. "root": function( elem ) {
  5221. return elem === docElem;
  5222. },
  5223. "focus": function( elem ) {
  5224. return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  5225. },
  5226. // Boolean properties
  5227. "enabled": function( elem ) {
  5228. return elem.disabled === false;
  5229. },
  5230. "disabled": function( elem ) {
  5231. return elem.disabled === true;
  5232. },
  5233. "checked": function( elem ) {
  5234. // In CSS3, :checked should return both checked and selected elements
  5235. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  5236. var nodeName = elem.nodeName.toLowerCase();
  5237. return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  5238. },
  5239. "selected": function( elem ) {
  5240. // Accessing this property makes selected-by-default
  5241. // options in Safari work properly
  5242. if ( elem.parentNode ) {
  5243. elem.parentNode.selectedIndex;
  5244. }
  5245. return elem.selected === true;
  5246. },
  5247. // Contents
  5248. "empty": function( elem ) {
  5249. // http://www.w3.org/TR/selectors/#empty-pseudo
  5250. // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
  5251. // not comment, processing instructions, or others
  5252. // Thanks to Diego Perini for the nodeName shortcut
  5253. // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
  5254. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  5255. if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
  5256. return false;
  5257. }
  5258. }
  5259. return true;
  5260. },
  5261. "parent": function( elem ) {
  5262. return !Expr.pseudos["empty"]( elem );
  5263. },
  5264. // Element/input types
  5265. "header": function( elem ) {
  5266. return rheader.test( elem.nodeName );
  5267. },
  5268. "input": function( elem ) {
  5269. return rinputs.test( elem.nodeName );
  5270. },
  5271. "button": function( elem ) {
  5272. var name = elem.nodeName.toLowerCase();
  5273. return name === "input" && elem.type === "button" || name === "button";
  5274. },
  5275. "text": function( elem ) {
  5276. var attr;
  5277. // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
  5278. // use getAttribute instead to test this case
  5279. return elem.nodeName.toLowerCase() === "input" &&
  5280. elem.type === "text" &&
  5281. ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
  5282. },
  5283. // Position-in-collection
  5284. "first": createPositionalPseudo(function() {
  5285. return [ 0 ];
  5286. }),
  5287. "last": createPositionalPseudo(function( matchIndexes, length ) {
  5288. return [ length - 1 ];
  5289. }),
  5290. "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  5291. return [ argument < 0 ? argument + length : argument ];
  5292. }),
  5293. "even": createPositionalPseudo(function( matchIndexes, length ) {
  5294. var i = 0;
  5295. for ( ; i < length; i += 2 ) {
  5296. matchIndexes.push( i );
  5297. }
  5298. return matchIndexes;
  5299. }),
  5300. "odd": createPositionalPseudo(function( matchIndexes, length ) {
  5301. var i = 1;
  5302. for ( ; i < length; i += 2 ) {
  5303. matchIndexes.push( i );
  5304. }
  5305. return matchIndexes;
  5306. }),
  5307. "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  5308. var i = argument < 0 ? argument + length : argument;
  5309. for ( ; --i >= 0; ) {
  5310. matchIndexes.push( i );
  5311. }
  5312. return matchIndexes;
  5313. }),
  5314. "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  5315. var i = argument < 0 ? argument + length : argument;
  5316. for ( ; ++i < length; ) {
  5317. matchIndexes.push( i );
  5318. }
  5319. return matchIndexes;
  5320. })
  5321. }
  5322. };
  5323. Expr.pseudos["nth"] = Expr.pseudos["eq"];
  5324. // Add button/input type pseudos
  5325. for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  5326. Expr.pseudos[ i ] = createInputPseudo( i );
  5327. }
  5328. for ( i in { submit: true, reset: true } ) {
  5329. Expr.pseudos[ i ] = createButtonPseudo( i );
  5330. }
  5331. // Easy API for creating new setFilters
  5332. function setFilters() {}
  5333. setFilters.prototype = Expr.filters = Expr.pseudos;
  5334. Expr.setFilters = new setFilters();
  5335. function tokenize( selector, parseOnly ) {
  5336. var matched, match, tokens, type,
  5337. soFar, groups, preFilters,
  5338. cached = tokenCache[ selector + " " ];
  5339. if ( cached ) {
  5340. return parseOnly ? 0 : cached.slice( 0 );
  5341. }
  5342. soFar = selector;
  5343. groups = [];
  5344. preFilters = Expr.preFilter;
  5345. while ( soFar ) {
  5346. // Comma and first run
  5347. if ( !matched || (match = rcomma.exec( soFar )) ) {
  5348. if ( match ) {
  5349. // Don't consume trailing commas as valid
  5350. soFar = soFar.slice( match[0].length ) || soFar;
  5351. }
  5352. groups.push( tokens = [] );
  5353. }
  5354. matched = false;
  5355. // Combinators
  5356. if ( (match = rcombinators.exec( soFar )) ) {
  5357. matched = match.shift();
  5358. tokens.push({
  5359. value: matched,
  5360. // Cast descendant combinators to space
  5361. type: match[0].replace( rtrim, " " )
  5362. });
  5363. soFar = soFar.slice( matched.length );
  5364. }
  5365. // Filters
  5366. for ( type in Expr.filter ) {
  5367. if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  5368. (match = preFilters[ type ]( match ))) ) {
  5369. matched = match.shift();
  5370. tokens.push({
  5371. value: matched,
  5372. type: type,
  5373. matches: match
  5374. });
  5375. soFar = soFar.slice( matched.length );
  5376. }
  5377. }
  5378. if ( !matched ) {
  5379. break;
  5380. }
  5381. }
  5382. // Return the length of the invalid excess
  5383. // if we're just parsing
  5384. // Otherwise, throw an error or return tokens
  5385. return parseOnly ?
  5386. soFar.length :
  5387. soFar ?
  5388. Sizzle.error( selector ) :
  5389. // Cache the tokens
  5390. tokenCache( selector, groups ).slice( 0 );
  5391. }
  5392. function toSelector( tokens ) {
  5393. var i = 0,
  5394. len = tokens.length,
  5395. selector = "";
  5396. for ( ; i < len; i++ ) {
  5397. selector += tokens[i].value;
  5398. }
  5399. return selector;
  5400. }
  5401. function addCombinator( matcher, combinator, base ) {
  5402. var dir = combinator.dir,
  5403. checkNonElements = base && dir === "parentNode",
  5404. doneName = done++;
  5405. return combinator.first ?
  5406. // Check against closest ancestor/preceding element
  5407. function( elem, context, xml ) {
  5408. while ( (elem = elem[ dir ]) ) {
  5409. if ( elem.nodeType === 1 || checkNonElements ) {
  5410. return matcher( elem, context, xml );
  5411. }
  5412. }
  5413. } :
  5414. // Check against all ancestor/preceding elements
  5415. function( elem, context, xml ) {
  5416. var data, cache, outerCache,
  5417. dirkey = dirruns + " " + doneName;
  5418. // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
  5419. if ( xml ) {
  5420. while ( (elem = elem[ dir ]) ) {
  5421. if ( elem.nodeType === 1 || checkNonElements ) {
  5422. if ( matcher( elem, context, xml ) ) {
  5423. return true;
  5424. }
  5425. }
  5426. }
  5427. } else {
  5428. while ( (elem = elem[ dir ]) ) {
  5429. if ( elem.nodeType === 1 || checkNonElements ) {
  5430. outerCache = elem[ expando ] || (elem[ expando ] = {});
  5431. if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
  5432. if ( (data = cache[1]) === true || data === cachedruns ) {
  5433. return data === true;
  5434. }
  5435. } else {
  5436. cache = outerCache[ dir ] = [ dirkey ];
  5437. cache[1] = matcher( elem, context, xml ) || cachedruns;
  5438. if ( cache[1] === true ) {
  5439. return true;
  5440. }
  5441. }
  5442. }
  5443. }
  5444. }
  5445. };
  5446. }
  5447. function elementMatcher( matchers ) {
  5448. return matchers.length > 1 ?
  5449. function( elem, context, xml ) {
  5450. var i = matchers.length;
  5451. while ( i-- ) {
  5452. if ( !matchers[i]( elem, context, xml ) ) {
  5453. return false;
  5454. }
  5455. }
  5456. return true;
  5457. } :
  5458. matchers[0];
  5459. }
  5460. function condense( unmatched, map, filter, context, xml ) {
  5461. var elem,
  5462. newUnmatched = [],
  5463. i = 0,
  5464. len = unmatched.length,
  5465. mapped = map != null;
  5466. for ( ; i < len; i++ ) {
  5467. if ( (elem = unmatched[i]) ) {
  5468. if ( !filter || filter( elem, context, xml ) ) {
  5469. newUnmatched.push( elem );
  5470. if ( mapped ) {
  5471. map.push( i );
  5472. }
  5473. }
  5474. }
  5475. }
  5476. return newUnmatched;
  5477. }
  5478. function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  5479. if ( postFilter && !postFilter[ expando ] ) {
  5480. postFilter = setMatcher( postFilter );
  5481. }
  5482. if ( postFinder && !postFinder[ expando ] ) {
  5483. postFinder = setMatcher( postFinder, postSelector );
  5484. }
  5485. return markFunction(function( seed, results, context, xml ) {
  5486. var temp, i, elem,
  5487. preMap = [],
  5488. postMap = [],
  5489. preexisting = results.length,
  5490. // Get initial elements from seed or context
  5491. elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  5492. // Prefilter to get matcher input, preserving a map for seed-results synchronization
  5493. matcherIn = preFilter && ( seed || !selector ) ?
  5494. condense( elems, preMap, preFilter, context, xml ) :
  5495. elems,
  5496. matcherOut = matcher ?
  5497. // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  5498. postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  5499. // ...intermediate processing is necessary
  5500. [] :
  5501. // ...otherwise use results directly
  5502. results :
  5503. matcherIn;
  5504. // Find primary matches
  5505. if ( matcher ) {
  5506. matcher( matcherIn, matcherOut, context, xml );
  5507. }
  5508. // Apply postFilter
  5509. if ( postFilter ) {
  5510. temp = condense( matcherOut, postMap );
  5511. postFilter( temp, [], context, xml );
  5512. // Un-match failing elements by moving them back to matcherIn
  5513. i = temp.length;
  5514. while ( i-- ) {
  5515. if ( (elem = temp[i]) ) {
  5516. matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  5517. }
  5518. }
  5519. }
  5520. if ( seed ) {
  5521. if ( postFinder || preFilter ) {
  5522. if ( postFinder ) {
  5523. // Get the final matcherOut by condensing this intermediate into postFinder contexts
  5524. temp = [];
  5525. i = matcherOut.length;
  5526. while ( i-- ) {
  5527. if ( (elem = matcherOut[i]) ) {
  5528. // Restore matcherIn since elem is not yet a final match
  5529. temp.push( (matcherIn[i] = elem) );
  5530. }
  5531. }
  5532. postFinder( null, (matcherOut = []), temp, xml );
  5533. }
  5534. // Move matched elements from seed to results to keep them synchronized
  5535. i = matcherOut.length;
  5536. while ( i-- ) {
  5537. if ( (elem = matcherOut[i]) &&
  5538. (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
  5539. seed[temp] = !(results[temp] = elem);
  5540. }
  5541. }
  5542. }
  5543. // Add elements to results, through postFinder if defined
  5544. } else {
  5545. matcherOut = condense(
  5546. matcherOut === results ?
  5547. matcherOut.splice( preexisting, matcherOut.length ) :
  5548. matcherOut
  5549. );
  5550. if ( postFinder ) {
  5551. postFinder( null, results, matcherOut, xml );
  5552. } else {
  5553. push.apply( results, matcherOut );
  5554. }
  5555. }
  5556. });
  5557. }
  5558. function matcherFromTokens( tokens ) {
  5559. var checkContext, matcher, j,
  5560. len = tokens.length,
  5561. leadingRelative = Expr.relative[ tokens[0].type ],
  5562. implicitRelative = leadingRelative || Expr.relative[" "],
  5563. i = leadingRelative ? 1 : 0,
  5564. // The foundational matcher ensures that elements are reachable from top-level context(s)
  5565. matchContext = addCombinator( function( elem ) {
  5566. return elem === checkContext;
  5567. }, implicitRelative, true ),
  5568. matchAnyContext = addCombinator( function( elem ) {
  5569. return indexOf.call( checkContext, elem ) > -1;
  5570. }, implicitRelative, true ),
  5571. matchers = [ function( elem, context, xml ) {
  5572. return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  5573. (checkContext = context).nodeType ?
  5574. matchContext( elem, context, xml ) :
  5575. matchAnyContext( elem, context, xml ) );
  5576. } ];
  5577. for ( ; i < len; i++ ) {
  5578. if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  5579. matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  5580. } else {
  5581. matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  5582. // Return special upon seeing a positional matcher
  5583. if ( matcher[ expando ] ) {
  5584. // Find the next relative operator (if any) for proper handling
  5585. j = ++i;
  5586. for ( ; j < len; j++ ) {
  5587. if ( Expr.relative[ tokens[j].type ] ) {
  5588. break;
  5589. }
  5590. }
  5591. return setMatcher(
  5592. i > 1 && elementMatcher( matchers ),
  5593. i > 1 && toSelector(
  5594. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  5595. tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  5596. ).replace( rtrim, "$1" ),
  5597. matcher,
  5598. i < j && matcherFromTokens( tokens.slice( i, j ) ),
  5599. j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  5600. j < len && toSelector( tokens )
  5601. );
  5602. }
  5603. matchers.push( matcher );
  5604. }
  5605. }
  5606. return elementMatcher( matchers );
  5607. }
  5608. function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  5609. // A counter to specify which element is currently being matched
  5610. var matcherCachedRuns = 0,
  5611. bySet = setMatchers.length > 0,
  5612. byElement = elementMatchers.length > 0,
  5613. superMatcher = function( seed, context, xml, results, expandContext ) {
  5614. var elem, j, matcher,
  5615. setMatched = [],
  5616. matchedCount = 0,
  5617. i = "0",
  5618. unmatched = seed && [],
  5619. outermost = expandContext != null,
  5620. contextBackup = outermostContext,
  5621. // We must always have either seed elements or context
  5622. elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
  5623. // Use integer dirruns iff this is the outermost matcher
  5624. dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
  5625. if ( outermost ) {
  5626. outermostContext = context !== document && context;
  5627. cachedruns = matcherCachedRuns;
  5628. }
  5629. // Add elements passing elementMatchers directly to results
  5630. // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
  5631. for ( ; (elem = elems[i]) != null; i++ ) {
  5632. if ( byElement && elem ) {
  5633. j = 0;
  5634. while ( (matcher = elementMatchers[j++]) ) {
  5635. if ( matcher( elem, context, xml ) ) {
  5636. results.push( elem );
  5637. break;
  5638. }
  5639. }
  5640. if ( outermost ) {
  5641. dirruns = dirrunsUnique;
  5642. cachedruns = ++matcherCachedRuns;
  5643. }
  5644. }
  5645. // Track unmatched elements for set filters
  5646. if ( bySet ) {
  5647. // They will have gone through all possible matchers
  5648. if ( (elem = !matcher && elem) ) {
  5649. matchedCount--;
  5650. }
  5651. // Lengthen the array for every element, matched or not
  5652. if ( seed ) {
  5653. unmatched.push( elem );
  5654. }
  5655. }
  5656. }
  5657. // Apply set filters to unmatched elements
  5658. matchedCount += i;
  5659. if ( bySet && i !== matchedCount ) {
  5660. j = 0;
  5661. while ( (matcher = setMatchers[j++]) ) {
  5662. matcher( unmatched, setMatched, context, xml );
  5663. }
  5664. if ( seed ) {
  5665. // Reintegrate element matches to eliminate the need for sorting
  5666. if ( matchedCount > 0 ) {
  5667. while ( i-- ) {
  5668. if ( !(unmatched[i] || setMatched[i]) ) {
  5669. setMatched[i] = pop.call( results );
  5670. }
  5671. }
  5672. }
  5673. // Discard index placeholder values to get only actual matches
  5674. setMatched = condense( setMatched );
  5675. }
  5676. // Add matches to results
  5677. push.apply( results, setMatched );
  5678. // Seedless set matches succeeding multiple successful matchers stipulate sorting
  5679. if ( outermost && !seed && setMatched.length > 0 &&
  5680. ( matchedCount + setMatchers.length ) > 1 ) {
  5681. Sizzle.uniqueSort( results );
  5682. }
  5683. }
  5684. // Override manipulation of globals by nested matchers
  5685. if ( outermost ) {
  5686. dirruns = dirrunsUnique;
  5687. outermostContext = contextBackup;
  5688. }
  5689. return unmatched;
  5690. };
  5691. return bySet ?
  5692. markFunction( superMatcher ) :
  5693. superMatcher;
  5694. }
  5695. compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
  5696. var i,
  5697. setMatchers = [],
  5698. elementMatchers = [],
  5699. cached = compilerCache[ selector + " " ];
  5700. if ( !cached ) {
  5701. // Generate a function of recursive functions that can be used to check each element
  5702. if ( !group ) {
  5703. group = tokenize( selector );
  5704. }
  5705. i = group.length;
  5706. while ( i-- ) {
  5707. cached = matcherFromTokens( group[i] );
  5708. if ( cached[ expando ] ) {
  5709. setMatchers.push( cached );
  5710. } else {
  5711. elementMatchers.push( cached );
  5712. }
  5713. }
  5714. // Cache the compiled function
  5715. cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  5716. }
  5717. return cached;
  5718. };
  5719. function multipleContexts( selector, contexts, results ) {
  5720. var i = 0,
  5721. len = contexts.length;
  5722. for ( ; i < len; i++ ) {
  5723. Sizzle( selector, contexts[i], results );
  5724. }
  5725. return results;
  5726. }
  5727. function select( selector, context, results, seed ) {
  5728. var i, tokens, token, type, find,
  5729. match = tokenize( selector );
  5730. if ( !seed ) {
  5731. // Try to minimize operations if there is only one group
  5732. if ( match.length === 1 ) {
  5733. // Take a shortcut and set the context if the root selector is an ID
  5734. tokens = match[0] = match[0].slice( 0 );
  5735. if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  5736. support.getById && context.nodeType === 9 && documentIsHTML &&
  5737. Expr.relative[ tokens[1].type ] ) {
  5738. context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  5739. if ( !context ) {
  5740. return results;
  5741. }
  5742. selector = selector.slice( tokens.shift().value.length );
  5743. }
  5744. // Fetch a seed set for right-to-left matching
  5745. i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  5746. while ( i-- ) {
  5747. token = tokens[i];
  5748. // Abort if we hit a combinator
  5749. if ( Expr.relative[ (type = token.type) ] ) {
  5750. break;
  5751. }
  5752. if ( (find = Expr.find[ type ]) ) {
  5753. // Search, expanding context for leading sibling combinators
  5754. if ( (seed = find(
  5755. token.matches[0].replace( runescape, funescape ),
  5756. rsibling.test( tokens[0].type ) && context.parentNode || context
  5757. )) ) {
  5758. // If seed is empty or no tokens remain, we can return early
  5759. tokens.splice( i, 1 );
  5760. selector = seed.length && toSelector( tokens );
  5761. if ( !selector ) {
  5762. push.apply( results, seed );
  5763. return results;
  5764. }
  5765. break;
  5766. }
  5767. }
  5768. }
  5769. }
  5770. }
  5771. // Compile and execute a filtering function
  5772. // Provide `match` to avoid retokenization if we modified the selector above
  5773. compile( selector, match )(
  5774. seed,
  5775. context,
  5776. !documentIsHTML,
  5777. results,
  5778. rsibling.test( selector )
  5779. );
  5780. return results;
  5781. }
  5782. // One-time assignments
  5783. // Sort stability
  5784. support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  5785. // Support: Chrome<14
  5786. // Always assume duplicates if they aren't passed to the comparison function
  5787. support.detectDuplicates = hasDuplicate;
  5788. // Initialize against the default document
  5789. setDocument();
  5790. // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  5791. // Detached nodes confoundingly follow *each other*
  5792. support.sortDetached = assert(function( div1 ) {
  5793. // Should return 1, but returns 4 (following)
  5794. return div1.compareDocumentPosition( document.createElement("div") ) & 1;
  5795. });
  5796. // Support: IE<8
  5797. // Prevent attribute/property "interpolation"
  5798. // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  5799. if ( !assert(function( div ) {
  5800. div.innerHTML = "<a href='#'></a>";
  5801. return div.firstChild.getAttribute("href") === "#" ;
  5802. }) ) {
  5803. addHandle( "type|href|height|width", function( elem, name, isXML ) {
  5804. if ( !isXML ) {
  5805. return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  5806. }
  5807. });
  5808. }
  5809. // Support: IE<9
  5810. // Use defaultValue in place of getAttribute("value")
  5811. if ( !support.attributes || !assert(function( div ) {
  5812. div.innerHTML = "<input/>";
  5813. div.firstChild.setAttribute( "value", "" );
  5814. return div.firstChild.getAttribute( "value" ) === "";
  5815. }) ) {
  5816. addHandle( "value", function( elem, name, isXML ) {
  5817. if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  5818. return elem.defaultValue;
  5819. }
  5820. });
  5821. }
  5822. // Support: IE<9
  5823. // Use getAttributeNode to fetch booleans when getAttribute lies
  5824. if ( !assert(function( div ) {
  5825. return div.getAttribute("disabled") == null;
  5826. }) ) {
  5827. addHandle( booleans, function( elem, name, isXML ) {
  5828. var val;
  5829. if ( !isXML ) {
  5830. return (val = elem.getAttributeNode( name )) && val.specified ?
  5831. val.value :
  5832. elem[ name ] === true ? name.toLowerCase() : null;
  5833. }
  5834. });
  5835. }
  5836. jQuery.find = Sizzle;
  5837. jQuery.expr = Sizzle.selectors;
  5838. jQuery.expr[":"] = jQuery.expr.pseudos;
  5839. jQuery.unique = Sizzle.uniqueSort;
  5840. jQuery.text = Sizzle.getText;
  5841. jQuery.isXMLDoc = Sizzle.isXML;
  5842. jQuery.contains = Sizzle.contains;
  5843. })( window );
  5844. // String to Object options format cache
  5845. var optionsCache = {};
  5846. // Convert String-formatted options into Object-formatted ones and store in cache
  5847. function createOptions( options ) {
  5848. var object = optionsCache[ options ] = {};
  5849. jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
  5850. object[ flag ] = true;
  5851. });
  5852. return object;
  5853. }
  5854. /*
  5855. * Create a callback list using the following parameters:
  5856. *
  5857. * options: an optional list of space-separated options that will change how
  5858. * the callback list behaves or a more traditional option object
  5859. *
  5860. * By default a callback list will act like an event callback list and can be
  5861. * "fired" multiple times.
  5862. *
  5863. * Possible options:
  5864. *
  5865. * once: will ensure the callback list can only be fired once (like a Deferred)
  5866. *
  5867. * memory: will keep track of previous values and will call any callback added
  5868. * after the list has been fired right away with the latest "memorized"
  5869. * values (like a Deferred)
  5870. *
  5871. * unique: will ensure a callback can only be added once (no duplicate in the list)
  5872. *
  5873. * stopOnFalse: interrupt callings when a callback returns false
  5874. *
  5875. */
  5876. jQuery.Callbacks = function( options ) {
  5877. // Convert options from String-formatted to Object-formatted if needed
  5878. // (we check in cache first)
  5879. options = typeof options === "string" ?
  5880. ( optionsCache[ options ] || createOptions( options ) ) :
  5881. jQuery.extend( {}, options );
  5882. var // Flag to know if list is currently firing
  5883. firing,
  5884. // Last fire value (for non-forgettable lists)
  5885. memory,
  5886. // Flag to know if list was already fired
  5887. fired,
  5888. // End of the loop when firing
  5889. firingLength,
  5890. // Index of currently firing callback (modified by remove if needed)
  5891. firingIndex,
  5892. // First callback to fire (used internally by add and fireWith)
  5893. firingStart,
  5894. // Actual callback list
  5895. list = [],
  5896. // Stack of fire calls for repeatable lists
  5897. stack = !options.once && [],
  5898. // Fire callbacks
  5899. fire = function( data ) {
  5900. memory = options.memory && data;
  5901. fired = true;
  5902. firingIndex = firingStart || 0;
  5903. firingStart = 0;
  5904. firingLength = list.length;
  5905. firing = true;
  5906. for ( ; list && firingIndex < firingLength; firingIndex++ ) {
  5907. if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
  5908. memory = false; // To prevent further calls using add
  5909. break;
  5910. }
  5911. }
  5912. firing = false;
  5913. if ( list ) {
  5914. if ( stack ) {
  5915. if ( stack.length ) {
  5916. fire( stack.shift() );
  5917. }
  5918. } else if ( memory ) {
  5919. list = [];
  5920. } else {
  5921. self.disable();
  5922. }
  5923. }
  5924. },
  5925. // Actual Callbacks object
  5926. self = {
  5927. // Add a callback or a collection of callbacks to the list
  5928. add: function() {
  5929. if ( list ) {
  5930. // First, we save the current length
  5931. var start = list.length;
  5932. (function add( args ) {
  5933. jQuery.each( args, function( _, arg ) {
  5934. var type = jQuery.type( arg );
  5935. if ( type === "function" ) {
  5936. if ( !options.unique || !self.has( arg ) ) {
  5937. list.push( arg );
  5938. }
  5939. } else if ( arg && arg.length && type !== "string" ) {
  5940. // Inspect recursively
  5941. add( arg );
  5942. }
  5943. });
  5944. })( arguments );
  5945. // Do we need to add the callbacks to the
  5946. // current firing batch?
  5947. if ( firing ) {
  5948. firingLength = list.length;
  5949. // With memory, if we're not firing then
  5950. // we should call right away
  5951. } else if ( memory ) {
  5952. firingStart = start;
  5953. fire( memory );
  5954. }
  5955. }
  5956. return this;
  5957. },
  5958. // Remove a callback from the list
  5959. remove: function() {
  5960. if ( list ) {
  5961. jQuery.each( arguments, function( _, arg ) {
  5962. var index;
  5963. while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  5964. list.splice( index, 1 );
  5965. // Handle firing indexes
  5966. if ( firing ) {
  5967. if ( index <= firingLength ) {
  5968. firingLength--;
  5969. }
  5970. if ( index <= firingIndex ) {
  5971. firingIndex--;
  5972. }
  5973. }
  5974. }
  5975. });
  5976. }
  5977. return this;
  5978. },
  5979. // Check if a given callback is in the list.
  5980. // If no argument is given, return whether or not list has callbacks attached.
  5981. has: function( fn ) {
  5982. return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
  5983. },
  5984. // Remove all callbacks from the list
  5985. empty: function() {
  5986. list = [];
  5987. firingLength = 0;
  5988. return this;
  5989. },
  5990. // Have the list do nothing anymore
  5991. disable: function() {
  5992. list = stack = memory = undefined;
  5993. return this;
  5994. },
  5995. // Is it disabled?
  5996. disabled: function() {
  5997. return !list;
  5998. },
  5999. // Lock the list in its current state
  6000. lock: function() {
  6001. stack = undefined;
  6002. if ( !memory ) {
  6003. self.disable();
  6004. }
  6005. return this;
  6006. },
  6007. // Is it locked?
  6008. locked: function() {
  6009. return !stack;
  6010. },
  6011. // Call all callbacks with the given context and arguments
  6012. fireWith: function( context, args ) {
  6013. if ( list && ( !fired || stack ) ) {
  6014. args = args || [];
  6015. args = [ context, args.slice ? args.slice() : args ];
  6016. if ( firing ) {
  6017. stack.push( args );
  6018. } else {
  6019. fire( args );
  6020. }
  6021. }
  6022. return this;
  6023. },
  6024. // Call all the callbacks with the given arguments
  6025. fire: function() {
  6026. self.fireWith( this, arguments );
  6027. return this;
  6028. },
  6029. // To know if the callbacks have already been called at least once
  6030. fired: function() {
  6031. return !!fired;
  6032. }
  6033. };
  6034. return self;
  6035. };
  6036. jQuery.extend({
  6037. Deferred: function( func ) {
  6038. var tuples = [
  6039. // action, add listener, listener list, final state
  6040. [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
  6041. [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
  6042. [ "notify", "progress", jQuery.Callbacks("memory") ]
  6043. ],
  6044. state = "pending",
  6045. promise = {
  6046. state: function() {
  6047. return state;
  6048. },
  6049. always: function() {
  6050. deferred.done( arguments ).fail( arguments );
  6051. return this;
  6052. },
  6053. then: function( /* fnDone, fnFail, fnProgress */ ) {
  6054. var fns = arguments;
  6055. return jQuery.Deferred(function( newDefer ) {
  6056. jQuery.each( tuples, function( i, tuple ) {
  6057. var action = tuple[ 0 ],
  6058. fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  6059. // deferred[ done | fail | progress ] for forwarding actions to newDefer
  6060. deferred[ tuple[1] ](function() {
  6061. var returned = fn && fn.apply( this, arguments );
  6062. if ( returned && jQuery.isFunction( returned.promise ) ) {
  6063. returned.promise()
  6064. .done( newDefer.resolve )
  6065. .fail( newDefer.reject )
  6066. .progress( newDefer.notify );
  6067. } else {
  6068. newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
  6069. }
  6070. });
  6071. });
  6072. fns = null;
  6073. }).promise();
  6074. },
  6075. // Get a promise for this deferred
  6076. // If obj is provided, the promise aspect is added to the object
  6077. promise: function( obj ) {
  6078. return obj != null ? jQuery.extend( obj, promise ) : promise;
  6079. }
  6080. },
  6081. deferred = {};
  6082. // Keep pipe for back-compat
  6083. promise.pipe = promise.then;
  6084. // Add list-specific methods
  6085. jQuery.each( tuples, function( i, tuple ) {
  6086. var list = tuple[ 2 ],
  6087. stateString = tuple[ 3 ];
  6088. // promise[ done | fail | progress ] = list.add
  6089. promise[ tuple[1] ] = list.add;
  6090. // Handle state
  6091. if ( stateString ) {
  6092. list.add(function() {
  6093. // state = [ resolved | rejected ]
  6094. state = stateString;
  6095. // [ reject_list | resolve_list ].disable; progress_list.lock
  6096. }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
  6097. }
  6098. // deferred[ resolve | reject | notify ]
  6099. deferred[ tuple[0] ] = function() {
  6100. deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
  6101. return this;
  6102. };
  6103. deferred[ tuple[0] + "With" ] = list.fireWith;
  6104. });
  6105. // Make the deferred a promise
  6106. promise.promise( deferred );
  6107. // Call given func if any
  6108. if ( func ) {
  6109. func.call( deferred, deferred );
  6110. }
  6111. // All done!
  6112. return deferred;
  6113. },
  6114. // Deferred helper
  6115. when: function( subordinate /* , ..., subordinateN */ ) {
  6116. var i = 0,
  6117. resolveValues = core_slice.call( arguments ),
  6118. length = resolveValues.length,
  6119. // the count of uncompleted subordinates
  6120. remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
  6121. // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
  6122. deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  6123. // Update function for both resolve and progress values
  6124. updateFunc = function( i, contexts, values ) {
  6125. return function( value ) {
  6126. contexts[ i ] = this;
  6127. values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
  6128. if( values === progressValues ) {
  6129. deferred.notifyWith( contexts, values );
  6130. } else if ( !( --remaining ) ) {
  6131. deferred.resolveWith( contexts, values );
  6132. }
  6133. };
  6134. },
  6135. progressValues, progressContexts, resolveContexts;
  6136. // add listeners to Deferred subordinates; treat others as resolved
  6137. if ( length > 1 ) {
  6138. progressValues = new Array( length );
  6139. progressContexts = new Array( length );
  6140. resolveContexts = new Array( length );
  6141. for ( ; i < length; i++ ) {
  6142. if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
  6143. resolveValues[ i ].promise()
  6144. .done( updateFunc( i, resolveContexts, resolveValues ) )
  6145. .fail( deferred.reject )
  6146. .progress( updateFunc( i, progressContexts, progressValues ) );
  6147. } else {
  6148. --remaining;
  6149. }
  6150. }
  6151. }
  6152. // if we're not waiting on anything, resolve the master
  6153. if ( !remaining ) {
  6154. deferred.resolveWith( resolveContexts, resolveValues );
  6155. }
  6156. return deferred.promise();
  6157. }
  6158. });
  6159. jQuery.support = (function( support ) {
  6160. var all, a, input, select, fragment, opt, eventName, isSupported, i,
  6161. div = document.createElement("div");
  6162. // Setup
  6163. div.setAttribute( "className", "t" );
  6164. div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
  6165. // Finish early in limited (non-browser) environments
  6166. all = div.getElementsByTagName("*") || [];
  6167. a = div.getElementsByTagName("a")[ 0 ];
  6168. if ( !a || !a.style || !all.length ) {
  6169. return support;
  6170. }
  6171. // First batch of tests
  6172. select = document.createElement("select");
  6173. opt = select.appendChild( document.createElement("option") );
  6174. input = div.getElementsByTagName("input")[ 0 ];
  6175. a.style.cssText = "top:1px;float:left;opacity:.5";
  6176. // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
  6177. support.getSetAttribute = div.className !== "t";
  6178. // IE strips leading whitespace when .innerHTML is used
  6179. support.leadingWhitespace = div.firstChild.nodeType === 3;
  6180. // Make sure that tbody elements aren't automatically inserted
  6181. // IE will insert them into empty tables
  6182. support.tbody = !div.getElementsByTagName("tbody").length;
  6183. // Make sure that link elements get serialized correctly by innerHTML
  6184. // This requires a wrapper element in IE
  6185. support.htmlSerialize = !!div.getElementsByTagName("link").length;
  6186. // Get the style information from getAttribute
  6187. // (IE uses .cssText instead)
  6188. support.style = /top/.test( a.getAttribute("style") );
  6189. // Make sure that URLs aren't manipulated
  6190. // (IE normalizes it by default)
  6191. support.hrefNormalized = a.getAttribute("href") === "/a";
  6192. // Make sure that element opacity exists
  6193. // (IE uses filter instead)
  6194. // Use a regex to work around a WebKit issue. See #5145
  6195. support.opacity = /^0.5/.test( a.style.opacity );
  6196. // Verify style float existence
  6197. // (IE uses styleFloat instead of cssFloat)
  6198. support.cssFloat = !!a.style.cssFloat;
  6199. // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
  6200. support.checkOn = !!input.value;
  6201. // Make sure that a selected-by-default option has a working selected property.
  6202. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
  6203. support.optSelected = opt.selected;
  6204. // Tests for enctype support on a form (#6743)
  6205. support.enctype = !!document.createElement("form").enctype;
  6206. // Makes sure cloning an html5 element does not cause problems
  6207. // Where outerHTML is undefined, this still works
  6208. support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>";
  6209. // Will be defined later
  6210. support.inlineBlockNeedsLayout = false;
  6211. support.shrinkWrapBlocks = false;
  6212. support.pixelPosition = false;
  6213. support.deleteExpando = true;
  6214. support.noCloneEvent = true;
  6215. support.reliableMarginRight = true;
  6216. support.boxSizingReliable = true;
  6217. // Make sure checked status is properly cloned
  6218. input.checked = true;
  6219. support.noCloneChecked = input.cloneNode( true ).checked;
  6220. // Make sure that the options inside disabled selects aren't marked as disabled
  6221. // (WebKit marks them as disabled)
  6222. select.disabled = true;
  6223. support.optDisabled = !opt.disabled;
  6224. // Support: IE<9
  6225. try {
  6226. delete div.test;
  6227. } catch( e ) {
  6228. support.deleteExpando = false;
  6229. }
  6230. // Check if we can trust getAttribute("value")
  6231. input = document.createElement("input");
  6232. input.setAttribute( "value", "" );
  6233. support.input = input.getAttribute( "value" ) === "";
  6234. // Check if an input maintains its value after becoming a radio
  6235. input.value = "t";
  6236. input.setAttribute( "type", "radio" );
  6237. support.radioValue = input.value === "t";
  6238. // #11217 - WebKit loses check when the name is after the checked attribute
  6239. input.setAttribute( "checked", "t" );
  6240. input.setAttribute( "name", "t" );
  6241. fragment = document.createDocumentFragment();
  6242. fragment.appendChild( input );
  6243. // Check if a disconnected checkbox will retain its checked
  6244. // value of true after appended to the DOM (IE6/7)
  6245. support.appendChecked = input.checked;
  6246. // WebKit doesn't clone checked state correctly in fragments
  6247. support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
  6248. // Support: IE<9
  6249. // Opera does not clone events (and typeof div.attachEvent === undefined).
  6250. // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
  6251. if ( div.attachEvent ) {
  6252. div.attachEvent( "onclick", function() {
  6253. support.noCloneEvent = false;
  6254. });
  6255. div.cloneNode( true ).click();
  6256. }
  6257. // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
  6258. // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
  6259. for ( i in { submit: true, change: true, focusin: true }) {
  6260. div.setAttribute( eventName = "on" + i, "t" );
  6261. support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
  6262. }
  6263. div.style.backgroundClip = "content-box";
  6264. div.cloneNode( true ).style.backgroundClip = "";
  6265. support.clearCloneStyle = div.style.backgroundClip === "content-box";
  6266. // Support: IE<9
  6267. // Iteration over object's inherited properties before its own.
  6268. for ( i in jQuery( support ) ) {
  6269. break;
  6270. }
  6271. support.ownLast = i !== "0";
  6272. // Run tests that need a body at doc ready
  6273. jQuery(function() {
  6274. var container, marginDiv, tds,
  6275. divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
  6276. body = document.getElementsByTagName("body")[0];
  6277. if ( !body ) {
  6278. // Return for frameset docs that don't have a body
  6279. return;
  6280. }
  6281. container = document.createElement("div");
  6282. container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
  6283. body.appendChild( container ).appendChild( div );
  6284. // Support: IE8
  6285. // Check if table cells still have offsetWidth/Height when they are set
  6286. // to display:none and there are still other visible table cells in a
  6287. // table row; if so, offsetWidth/Height are not reliable for use when
  6288. // determining if an element has been hidden directly using
  6289. // display:none (it is still safe to use offsets if a parent element is
  6290. // hidden; don safety goggles and see bug #4512 for more information).
  6291. div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
  6292. tds = div.getElementsByTagName("td");
  6293. tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
  6294. isSupported = ( tds[ 0 ].offsetHeight === 0 );
  6295. tds[ 0 ].style.display = "";
  6296. tds[ 1 ].style.display = "none";
  6297. // Support: IE8
  6298. // Check if empty table cells still have offsetWidth/Height
  6299. support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
  6300. // Check box-sizing and margin behavior.
  6301. div.innerHTML = "";
  6302. div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
  6303. // Workaround failing boxSizing test due to offsetWidth returning wrong value
  6304. // with some non-1 values of body zoom, ticket #13543
  6305. jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
  6306. support.boxSizing = div.offsetWidth === 4;
  6307. });
  6308. // Use window.getComputedStyle because jsdom on node.js will break without it.
  6309. if ( window.getComputedStyle ) {
  6310. support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
  6311. support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
  6312. // Check if div with explicit width and no margin-right incorrectly
  6313. // gets computed margin-right based on width of container. (#3333)
  6314. // Fails in WebKit before Feb 2011 nightlies
  6315. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  6316. marginDiv = div.appendChild( document.createElement("div") );
  6317. marginDiv.style.cssText = div.style.cssText = divReset;
  6318. marginDiv.style.marginRight = marginDiv.style.width = "0";
  6319. div.style.width = "1px";
  6320. support.reliableMarginRight =
  6321. !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
  6322. }
  6323. if ( typeof div.style.zoom !== core_strundefined ) {
  6324. // Support: IE<8
  6325. // Check if natively block-level elements act like inline-block
  6326. // elements when setting their display to 'inline' and giving
  6327. // them layout
  6328. div.innerHTML = "";
  6329. div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
  6330. support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
  6331. // Support: IE6
  6332. // Check if elements with layout shrink-wrap their children
  6333. div.style.display = "block";
  6334. div.innerHTML = "<div></div>";
  6335. div.firstChild.style.width = "5px";
  6336. support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
  6337. if ( support.inlineBlockNeedsLayout ) {
  6338. // Prevent IE 6 from affecting layout for positioned elements #11048
  6339. // Prevent IE from shrinking the body in IE 7 mode #12869
  6340. // Support: IE<8
  6341. body.style.zoom = 1;
  6342. }
  6343. }
  6344. body.removeChild( container );
  6345. // Null elements to avoid leaks in IE
  6346. container = div = tds = marginDiv = null;
  6347. });
  6348. // Null elements to avoid leaks in IE
  6349. all = select = fragment = opt = a = input = null;
  6350. return support;
  6351. })({});
  6352. var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
  6353. rmultiDash = /([A-Z])/g;
  6354. function internalData( elem, name, data, pvt /* Internal Use Only */ ){
  6355. if ( !jQuery.acceptData( elem ) ) {
  6356. return;
  6357. }
  6358. var ret, thisCache,
  6359. internalKey = jQuery.expando,
  6360. // We have to handle DOM nodes and JS objects differently because IE6-7
  6361. // can't GC object references properly across the DOM-JS boundary
  6362. isNode = elem.nodeType,
  6363. // Only DOM nodes need the global jQuery cache; JS object data is
  6364. // attached directly to the object so GC can occur automatically
  6365. cache = isNode ? jQuery.cache : elem,
  6366. // Only defining an ID for JS objects if its cache already exists allows
  6367. // the code to shortcut on the same path as a DOM node with no cache
  6368. id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
  6369. // Avoid doing any more work than we need to when trying to get data on an
  6370. // object that has no data at all
  6371. if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
  6372. return;
  6373. }
  6374. if ( !id ) {
  6375. // Only DOM nodes need a new unique ID for each element since their data
  6376. // ends up in the global cache
  6377. if ( isNode ) {
  6378. id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;
  6379. } else {
  6380. id = internalKey;
  6381. }
  6382. }
  6383. if ( !cache[ id ] ) {
  6384. // Avoid exposing jQuery metadata on plain JS objects when the object
  6385. // is serialized using JSON.stringify
  6386. cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
  6387. }
  6388. // An object can be passed to jQuery.data instead of a key/value pair; this gets
  6389. // shallow copied over onto the existing cache
  6390. if ( typeof name === "object" || typeof name === "function" ) {
  6391. if ( pvt ) {
  6392. cache[ id ] = jQuery.extend( cache[ id ], name );
  6393. } else {
  6394. cache[ id ].data = jQuery.extend( cache[ id ].data, name );
  6395. }
  6396. }
  6397. thisCache = cache[ id ];
  6398. // jQuery data() is stored in a separate object inside the object's internal data
  6399. // cache in order to avoid key collisions between internal data and user-defined
  6400. // data.
  6401. if ( !pvt ) {
  6402. if ( !thisCache.data ) {
  6403. thisCache.data = {};
  6404. }
  6405. thisCache = thisCache.data;
  6406. }
  6407. if ( data !== undefined ) {
  6408. thisCache[ jQuery.camelCase( name ) ] = data;
  6409. }
  6410. // Check for both converted-to-camel and non-converted data property names
  6411. // If a data property was specified
  6412. if ( typeof name === "string" ) {
  6413. // First Try to find as-is property data
  6414. ret = thisCache[ name ];
  6415. // Test for null|undefined property data
  6416. if ( ret == null ) {
  6417. // Try to find the camelCased property
  6418. ret = thisCache[ jQuery.camelCase( name ) ];
  6419. }
  6420. } else {
  6421. ret = thisCache;
  6422. }
  6423. return ret;
  6424. }
  6425. function internalRemoveData( elem, name, pvt ) {
  6426. if ( !jQuery.acceptData( elem ) ) {
  6427. return;
  6428. }
  6429. var thisCache, i,
  6430. isNode = elem.nodeType,
  6431. // See jQuery.data for more information
  6432. cache = isNode ? jQuery.cache : elem,
  6433. id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
  6434. // If there is already no cache entry for this object, there is no
  6435. // purpose in continuing
  6436. if ( !cache[ id ] ) {
  6437. return;
  6438. }
  6439. if ( name ) {
  6440. thisCache = pvt ? cache[ id ] : cache[ id ].data;
  6441. if ( thisCache ) {
  6442. // Support array or space separated string names for data keys
  6443. if ( !jQuery.isArray( name ) ) {
  6444. // try the string as a key before any manipulation
  6445. if ( name in thisCache ) {
  6446. name = [ name ];
  6447. } else {
  6448. // split the camel cased version by spaces unless a key with the spaces exists
  6449. name = jQuery.camelCase( name );
  6450. if ( name in thisCache ) {
  6451. name = [ name ];
  6452. } else {
  6453. name = name.split(" ");
  6454. }
  6455. }
  6456. } else {
  6457. // If "name" is an array of keys...
  6458. // When data is initially created, via ("key", "val") signature,
  6459. // keys will be converted to camelCase.
  6460. // Since there is no way to tell _how_ a key was added, remove
  6461. // both plain key and camelCase key. #12786
  6462. // This will only penalize the array argument path.
  6463. name = name.concat( jQuery.map( name, jQuery.camelCase ) );
  6464. }
  6465. i = name.length;
  6466. while ( i-- ) {
  6467. delete thisCache[ name[i] ];
  6468. }
  6469. // If there is no data left in the cache, we want to continue
  6470. // and let the cache object itself get destroyed
  6471. if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
  6472. return;
  6473. }
  6474. }
  6475. }
  6476. // See jQuery.data for more information
  6477. if ( !pvt ) {
  6478. delete cache[ id ].data;
  6479. // Don't destroy the parent cache unless the internal data object
  6480. // had been the only thing left in it
  6481. if ( !isEmptyDataObject( cache[ id ] ) ) {
  6482. return;
  6483. }
  6484. }
  6485. // Destroy the cache
  6486. if ( isNode ) {
  6487. jQuery.cleanData( [ elem ], true );
  6488. // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
  6489. /* jshint eqeqeq: false */
  6490. } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
  6491. /* jshint eqeqeq: true */
  6492. delete cache[ id ];
  6493. // When all else fails, null
  6494. } else {
  6495. cache[ id ] = null;
  6496. }
  6497. }
  6498. jQuery.extend({
  6499. cache: {},
  6500. // The following elements throw uncatchable exceptions if you
  6501. // attempt to add expando properties to them.
  6502. noData: {
  6503. "applet": true,
  6504. "embed": true,
  6505. // Ban all objects except for Flash (which handle expandos)
  6506. "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  6507. },
  6508. hasData: function( elem ) {
  6509. elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
  6510. return !!elem && !isEmptyDataObject( elem );
  6511. },
  6512. data: function( elem, name, data ) {
  6513. return internalData( elem, name, data );
  6514. },
  6515. removeData: function( elem, name ) {
  6516. return internalRemoveData( elem, name );
  6517. },
  6518. // For internal use only.
  6519. _data: function( elem, name, data ) {
  6520. return internalData( elem, name, data, true );
  6521. },
  6522. _removeData: function( elem, name ) {
  6523. return internalRemoveData( elem, name, true );
  6524. },
  6525. // A method for determining if a DOM node can handle the data expando
  6526. acceptData: function( elem ) {
  6527. // Do not set data on non-element because it will not be cleared (#8335).
  6528. if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
  6529. return false;
  6530. }
  6531. var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
  6532. // nodes accept data unless otherwise specified; rejection can be conditional
  6533. return !noData || noData !== true && elem.getAttribute("classid") === noData;
  6534. }
  6535. });
  6536. jQuery.fn.extend({
  6537. data: function( key, value ) {
  6538. var attrs, name,
  6539. data = null,
  6540. i = 0,
  6541. elem = this[0];
  6542. // Special expections of .data basically thwart jQuery.access,
  6543. // so implement the relevant behavior ourselves
  6544. // Gets all values
  6545. if ( key === undefined ) {
  6546. if ( this.length ) {
  6547. data = jQuery.data( elem );
  6548. if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
  6549. attrs = elem.attributes;
  6550. for ( ; i < attrs.length; i++ ) {
  6551. name = attrs[i].name;
  6552. if ( name.indexOf("data-") === 0 ) {
  6553. name = jQuery.camelCase( name.slice(5) );
  6554. dataAttr( elem, name, data[ name ] );
  6555. }
  6556. }
  6557. jQuery._data( elem, "parsedAttrs", true );
  6558. }
  6559. }
  6560. return data;
  6561. }
  6562. // Sets multiple values
  6563. if ( typeof key === "object" ) {
  6564. return this.each(function() {
  6565. jQuery.data( this, key );
  6566. });
  6567. }
  6568. return arguments.length > 1 ?
  6569. // Sets one value
  6570. this.each(function() {
  6571. jQuery.data( this, key, value );
  6572. }) :
  6573. // Gets one value
  6574. // Try to fetch any internally stored data first
  6575. elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
  6576. },
  6577. removeData: function( key ) {
  6578. return this.each(function() {
  6579. jQuery.removeData( this, key );
  6580. });
  6581. }
  6582. });
  6583. function dataAttr( elem, key, data ) {
  6584. // If nothing was found internally, try to fetch any
  6585. // data from the HTML5 data-* attribute
  6586. if ( data === undefined && elem.nodeType === 1 ) {
  6587. var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
  6588. data = elem.getAttribute( name );
  6589. if ( typeof data === "string" ) {
  6590. try {
  6591. data = data === "true" ? true :
  6592. data === "false" ? false :
  6593. data === "null" ? null :
  6594. // Only convert to a number if it doesn't change the string
  6595. +data + "" === data ? +data :
  6596. rbrace.test( data ) ? jQuery.parseJSON( data ) :
  6597. data;
  6598. } catch( e ) {}
  6599. // Make sure we set the data so it isn't changed later
  6600. jQuery.data( elem, key, data );
  6601. } else {
  6602. data = undefined;
  6603. }
  6604. }
  6605. return data;
  6606. }
  6607. // checks a cache object for emptiness
  6608. function isEmptyDataObject( obj ) {
  6609. var name;
  6610. for ( name in obj ) {
  6611. // if the public data object is empty, the private is still empty
  6612. if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
  6613. continue;
  6614. }
  6615. if ( name !== "toJSON" ) {
  6616. return false;
  6617. }
  6618. }
  6619. return true;
  6620. }
  6621. jQuery.extend({
  6622. queue: function( elem, type, data ) {
  6623. var queue;
  6624. if ( elem ) {
  6625. type = ( type || "fx" ) + "queue";
  6626. queue = jQuery._data( elem, type );
  6627. // Speed up dequeue by getting out quickly if this is just a lookup
  6628. if ( data ) {
  6629. if ( !queue || jQuery.isArray(data) ) {
  6630. queue = jQuery._data( elem, type, jQuery.makeArray(data) );
  6631. } else {
  6632. queue.push( data );
  6633. }
  6634. }
  6635. return queue || [];
  6636. }
  6637. },
  6638. dequeue: function( elem, type ) {
  6639. type = type || "fx";
  6640. var queue = jQuery.queue( elem, type ),
  6641. startLength = queue.length,
  6642. fn = queue.shift(),
  6643. hooks = jQuery._queueHooks( elem, type ),
  6644. next = function() {
  6645. jQuery.dequeue( elem, type );
  6646. };
  6647. // If the fx queue is dequeued, always remove the progress sentinel
  6648. if ( fn === "inprogress" ) {
  6649. fn = queue.shift();
  6650. startLength--;
  6651. }
  6652. if ( fn ) {
  6653. // Add a progress sentinel to prevent the fx queue from being
  6654. // automatically dequeued
  6655. if ( type === "fx" ) {
  6656. queue.unshift( "inprogress" );
  6657. }
  6658. // clear up the last queue stop function
  6659. delete hooks.stop;
  6660. fn.call( elem, next, hooks );
  6661. }
  6662. if ( !startLength && hooks ) {
  6663. hooks.empty.fire();
  6664. }
  6665. },
  6666. // not intended for public consumption - generates a queueHooks object, or returns the current one
  6667. _queueHooks: function( elem, type ) {
  6668. var key = type + "queueHooks";
  6669. return jQuery._data( elem, key ) || jQuery._data( elem, key, {
  6670. empty: jQuery.Callbacks("once memory").add(function() {
  6671. jQuery._removeData( elem, type + "queue" );
  6672. jQuery._removeData( elem, key );
  6673. })
  6674. });
  6675. }
  6676. });
  6677. jQuery.fn.extend({
  6678. queue: function( type, data ) {
  6679. var setter = 2;
  6680. if ( typeof type !== "string" ) {
  6681. data = type;
  6682. type = "fx";
  6683. setter--;
  6684. }
  6685. if ( arguments.length < setter ) {
  6686. return jQuery.queue( this[0], type );
  6687. }
  6688. return data === undefined ?
  6689. this :
  6690. this.each(function() {
  6691. var queue = jQuery.queue( this, type, data );
  6692. // ensure a hooks for this queue
  6693. jQuery._queueHooks( this, type );
  6694. if ( type === "fx" && queue[0] !== "inprogress" ) {
  6695. jQuery.dequeue( this, type );
  6696. }
  6697. });
  6698. },
  6699. dequeue: function( type ) {
  6700. return this.each(function() {
  6701. jQuery.dequeue( this, type );
  6702. });
  6703. },
  6704. // Based off of the plugin by Clint Helfers, with permission.
  6705. // http://blindsignals.com/index.php/2009/07/jquery-delay/
  6706. delay: function( time, type ) {
  6707. time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  6708. type = type || "fx";
  6709. return this.queue( type, function( next, hooks ) {
  6710. var timeout = setTimeout( next, time );
  6711. hooks.stop = function() {
  6712. clearTimeout( timeout );
  6713. };
  6714. });
  6715. },
  6716. clearQueue: function( type ) {
  6717. return this.queue( type || "fx", [] );
  6718. },
  6719. // Get a promise resolved when queues of a certain type
  6720. // are emptied (fx is the type by default)
  6721. promise: function( type, obj ) {
  6722. var tmp,
  6723. count = 1,
  6724. defer = jQuery.Deferred(),
  6725. elements = this,
  6726. i = this.length,
  6727. resolve = function() {
  6728. if ( !( --count ) ) {
  6729. defer.resolveWith( elements, [ elements ] );
  6730. }
  6731. };
  6732. if ( typeof type !== "string" ) {
  6733. obj = type;
  6734. type = undefined;
  6735. }
  6736. type = type || "fx";
  6737. while( i-- ) {
  6738. tmp = jQuery._data( elements[ i ], type + "queueHooks" );
  6739. if ( tmp && tmp.empty ) {
  6740. count++;
  6741. tmp.empty.add( resolve );
  6742. }
  6743. }
  6744. resolve();
  6745. return defer.promise( obj );
  6746. }
  6747. });
  6748. var nodeHook, boolHook,
  6749. rclass = /[\t\r\n\f]/g,
  6750. rreturn = /\r/g,
  6751. rfocusable = /^(?:input|select|textarea|button|object)$/i,
  6752. rclickable = /^(?:a|area)$/i,
  6753. ruseDefault = /^(?:checked|selected)$/i,
  6754. getSetAttribute = jQuery.support.getSetAttribute,
  6755. getSetInput = jQuery.support.input;
  6756. jQuery.fn.extend({
  6757. attr: function( name, value ) {
  6758. return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
  6759. },
  6760. removeAttr: function( name ) {
  6761. return this.each(function() {
  6762. jQuery.removeAttr( this, name );
  6763. });
  6764. },
  6765. prop: function( name, value ) {
  6766. return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
  6767. },
  6768. removeProp: function( name ) {
  6769. name = jQuery.propFix[ name ] || name;
  6770. return this.each(function() {
  6771. // try/catch handles cases where IE balks (such as removing a property on window)
  6772. try {
  6773. this[ name ] = undefined;
  6774. delete this[ name ];
  6775. } catch( e ) {}
  6776. });
  6777. },
  6778. addClass: function( value ) {
  6779. var classes, elem, cur, clazz, j,
  6780. i = 0,
  6781. len = this.length,
  6782. proceed = typeof value === "string" && value;
  6783. if ( jQuery.isFunction( value ) ) {
  6784. return this.each(function( j ) {
  6785. jQuery( this ).addClass( value.call( this, j, this.className ) );
  6786. });
  6787. }
  6788. if ( proceed ) {
  6789. // The disjunction here is for better compressibility (see removeClass)
  6790. classes = ( value || "" ).match( core_rnotwhite ) || [];
  6791. for ( ; i < len; i++ ) {
  6792. elem = this[ i ];
  6793. cur = elem.nodeType === 1 && ( elem.className ?
  6794. ( " " + elem.className + " " ).replace( rclass, " " ) :
  6795. " "
  6796. );
  6797. if ( cur ) {
  6798. j = 0;
  6799. while ( (clazz = classes[j++]) ) {
  6800. if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  6801. cur += clazz + " ";
  6802. }
  6803. }
  6804. elem.className = jQuery.trim( cur );
  6805. }
  6806. }
  6807. }
  6808. return this;
  6809. },
  6810. removeClass: function( value ) {
  6811. var classes, elem, cur, clazz, j,
  6812. i = 0,
  6813. len = this.length,
  6814. proceed = arguments.length === 0 || typeof value === "string" && value;
  6815. if ( jQuery.isFunction( value ) ) {
  6816. return this.each(function( j ) {
  6817. jQuery( this ).removeClass( value.call( this, j, this.className ) );
  6818. });
  6819. }
  6820. if ( proceed ) {
  6821. classes = ( value || "" ).match( core_rnotwhite ) || [];
  6822. for ( ; i < len; i++ ) {
  6823. elem = this[ i ];
  6824. // This expression is here for better compressibility (see addClass)
  6825. cur = elem.nodeType === 1 && ( elem.className ?
  6826. ( " " + elem.className + " " ).replace( rclass, " " ) :
  6827. ""
  6828. );
  6829. if ( cur ) {
  6830. j = 0;
  6831. while ( (clazz = classes[j++]) ) {
  6832. // Remove *all* instances
  6833. while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
  6834. cur = cur.replace( " " + clazz + " ", " " );
  6835. }
  6836. }
  6837. elem.className = value ? jQuery.trim( cur ) : "";
  6838. }
  6839. }
  6840. }
  6841. return this;
  6842. },
  6843. toggleClass: function( value, stateVal ) {
  6844. var type = typeof value;
  6845. if ( typeof stateVal === "boolean" && type === "string" ) {
  6846. return stateVal ? this.addClass( value ) : this.removeClass( value );
  6847. }
  6848. if ( jQuery.isFunction( value ) ) {
  6849. return this.each(function( i ) {
  6850. jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
  6851. });
  6852. }
  6853. return this.each(function() {
  6854. if ( type === "string" ) {
  6855. // toggle individual class names
  6856. var className,
  6857. i = 0,
  6858. self = jQuery( this ),
  6859. classNames = value.match( core_rnotwhite ) || [];
  6860. while ( (className = classNames[ i++ ]) ) {
  6861. // check each className given, space separated list
  6862. if ( self.hasClass( className ) ) {
  6863. self.removeClass( className );
  6864. } else {
  6865. self.addClass( className );
  6866. }
  6867. }
  6868. // Toggle whole class name
  6869. } else if ( type === core_strundefined || type === "boolean" ) {
  6870. if ( this.className ) {
  6871. // store className if set
  6872. jQuery._data( this, "__className__", this.className );
  6873. }
  6874. // If the element has a class name or if we're passed "false",
  6875. // then remove the whole classname (if there was one, the above saved it).
  6876. // Otherwise bring back whatever was previously saved (if anything),
  6877. // falling back to the empty string if nothing was stored.
  6878. this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
  6879. }
  6880. });
  6881. },
  6882. hasClass: function( selector ) {
  6883. var className = " " + selector + " ",
  6884. i = 0,
  6885. l = this.length;
  6886. for ( ; i < l; i++ ) {
  6887. if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
  6888. return true;
  6889. }
  6890. }
  6891. return false;
  6892. },
  6893. val: function( value ) {
  6894. var ret, hooks, isFunction,
  6895. elem = this[0];
  6896. if ( !arguments.length ) {
  6897. if ( elem ) {
  6898. hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  6899. if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
  6900. return ret;
  6901. }
  6902. ret = elem.value;
  6903. return typeof ret === "string" ?
  6904. // handle most common string cases
  6905. ret.replace(rreturn, "") :
  6906. // handle cases where value is null/undef or number
  6907. ret == null ? "" : ret;
  6908. }
  6909. return;
  6910. }
  6911. isFunction = jQuery.isFunction( value );
  6912. return this.each(function( i ) {
  6913. var val;
  6914. if ( this.nodeType !== 1 ) {
  6915. return;
  6916. }
  6917. if ( isFunction ) {
  6918. val = value.call( this, i, jQuery( this ).val() );
  6919. } else {
  6920. val = value;
  6921. }
  6922. // Treat null/undefined as ""; convert numbers to string
  6923. if ( val == null ) {
  6924. val = "";
  6925. } else if ( typeof val === "number" ) {
  6926. val += "";
  6927. } else if ( jQuery.isArray( val ) ) {
  6928. val = jQuery.map(val, function ( value ) {
  6929. return value == null ? "" : value + "";
  6930. });
  6931. }
  6932. hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  6933. // If set returns undefined, fall back to normal setting
  6934. if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
  6935. this.value = val;
  6936. }
  6937. });
  6938. }
  6939. });
  6940. jQuery.extend({
  6941. valHooks: {
  6942. option: {
  6943. get: function( elem ) {
  6944. // Use proper attribute retrieval(#6932, #12072)
  6945. var val = jQuery.find.attr( elem, "value" );
  6946. return val != null ?
  6947. val :
  6948. elem.text;
  6949. }
  6950. },
  6951. select: {
  6952. get: function( elem ) {
  6953. var value, option,
  6954. options = elem.options,
  6955. index = elem.selectedIndex,
  6956. one = elem.type === "select-one" || index < 0,
  6957. values = one ? null : [],
  6958. max = one ? index + 1 : options.length,
  6959. i = index < 0 ?
  6960. max :
  6961. one ? index : 0;
  6962. // Loop through all the selected options
  6963. for ( ; i < max; i++ ) {
  6964. option = options[ i ];
  6965. // oldIE doesn't update selected after form reset (#2551)
  6966. if ( ( option.selected || i === index ) &&
  6967. // Don't return options that are disabled or in a disabled optgroup
  6968. ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
  6969. ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
  6970. // Get the specific value for the option
  6971. value = jQuery( option ).val();
  6972. // We don't need an array for one selects
  6973. if ( one ) {
  6974. return value;
  6975. }
  6976. // Multi-Selects return an array
  6977. values.push( value );
  6978. }
  6979. }
  6980. return values;
  6981. },
  6982. set: function( elem, value ) {
  6983. var optionSet, option,
  6984. options = elem.options,
  6985. values = jQuery.makeArray( value ),
  6986. i = options.length;
  6987. while ( i-- ) {
  6988. option = options[ i ];
  6989. if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
  6990. optionSet = true;
  6991. }
  6992. }
  6993. // force browsers to behave consistently when non-matching value is set
  6994. if ( !optionSet ) {
  6995. elem.selectedIndex = -1;
  6996. }
  6997. return values;
  6998. }
  6999. }
  7000. },
  7001. attr: function( elem, name, value ) {
  7002. var hooks, ret,
  7003. nType = elem.nodeType;
  7004. // don't get/set attributes on text, comment and attribute nodes
  7005. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  7006. return;
  7007. }
  7008. // Fallback to prop when attributes are not supported
  7009. if ( typeof elem.getAttribute === core_strundefined ) {
  7010. return jQuery.prop( elem, name, value );
  7011. }
  7012. // All attributes are lowercase
  7013. // Grab necessary hook if one is defined
  7014. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  7015. name = name.toLowerCase();
  7016. hooks = jQuery.attrHooks[ name ] ||
  7017. ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
  7018. }
  7019. if ( value !== undefined ) {
  7020. if ( value === null ) {
  7021. jQuery.removeAttr( elem, name );
  7022. } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
  7023. return ret;
  7024. } else {
  7025. elem.setAttribute( name, value + "" );
  7026. return value;
  7027. }
  7028. } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
  7029. return ret;
  7030. } else {
  7031. ret = jQuery.find.attr( elem, name );
  7032. // Non-existent attributes return null, we normalize to undefined
  7033. return ret == null ?
  7034. undefined :
  7035. ret;
  7036. }
  7037. },
  7038. removeAttr: function( elem, value ) {
  7039. var name, propName,
  7040. i = 0,
  7041. attrNames = value && value.match( core_rnotwhite );
  7042. if ( attrNames && elem.nodeType === 1 ) {
  7043. while ( (name = attrNames[i++]) ) {
  7044. propName = jQuery.propFix[ name ] || name;
  7045. // Boolean attributes get special treatment (#10870)
  7046. if ( jQuery.expr.match.bool.test( name ) ) {
  7047. // Set corresponding property to false
  7048. if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
  7049. elem[ propName ] = false;
  7050. // Support: IE<9
  7051. // Also clear defaultChecked/defaultSelected (if appropriate)
  7052. } else {
  7053. elem[ jQuery.camelCase( "default-" + name ) ] =
  7054. elem[ propName ] = false;
  7055. }
  7056. // See #9699 for explanation of this approach (setting first, then removal)
  7057. } else {
  7058. jQuery.attr( elem, name, "" );
  7059. }
  7060. elem.removeAttribute( getSetAttribute ? name : propName );
  7061. }
  7062. }
  7063. },
  7064. attrHooks: {
  7065. type: {
  7066. set: function( elem, value ) {
  7067. if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
  7068. // Setting the type on a radio button after the value resets the value in IE6-9
  7069. // Reset value to default in case type is set after value during creation
  7070. var val = elem.value;
  7071. elem.setAttribute( "type", value );
  7072. if ( val ) {
  7073. elem.value = val;
  7074. }
  7075. return value;
  7076. }
  7077. }
  7078. }
  7079. },
  7080. propFix: {
  7081. "for": "htmlFor",
  7082. "class": "className"
  7083. },
  7084. prop: function( elem, name, value ) {
  7085. var ret, hooks, notxml,
  7086. nType = elem.nodeType;
  7087. // don't get/set properties on text, comment and attribute nodes
  7088. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  7089. return;
  7090. }
  7091. notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
  7092. if ( notxml ) {
  7093. // Fix name and attach hooks
  7094. name = jQuery.propFix[ name ] || name;
  7095. hooks = jQuery.propHooks[ name ];
  7096. }
  7097. if ( value !== undefined ) {
  7098. return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
  7099. ret :
  7100. ( elem[ name ] = value );
  7101. } else {
  7102. return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
  7103. ret :
  7104. elem[ name ];
  7105. }
  7106. },
  7107. propHooks: {
  7108. tabIndex: {
  7109. get: function( elem ) {
  7110. // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
  7111. // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  7112. // Use proper attribute retrieval(#12072)
  7113. var tabindex = jQuery.find.attr( elem, "tabindex" );
  7114. return tabindex ?
  7115. parseInt( tabindex, 10 ) :
  7116. rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
  7117. 0 :
  7118. -1;
  7119. }
  7120. }
  7121. }
  7122. });
  7123. // Hooks for boolean attributes
  7124. boolHook = {
  7125. set: function( elem, value, name ) {
  7126. if ( value === false ) {
  7127. // Remove boolean attributes when set to false
  7128. jQuery.removeAttr( elem, name );
  7129. } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
  7130. // IE<8 needs the *property* name
  7131. elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
  7132. // Use defaultChecked and defaultSelected for oldIE
  7133. } else {
  7134. elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
  7135. }
  7136. return name;
  7137. }
  7138. };
  7139. jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  7140. var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
  7141. jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
  7142. function( elem, name, isXML ) {
  7143. var fn = jQuery.expr.attrHandle[ name ],
  7144. ret = isXML ?
  7145. undefined :
  7146. /* jshint eqeqeq: false */
  7147. (jQuery.expr.attrHandle[ name ] = undefined) !=
  7148. getter( elem, name, isXML ) ?
  7149. name.toLowerCase() :
  7150. null;
  7151. jQuery.expr.attrHandle[ name ] = fn;
  7152. return ret;
  7153. } :
  7154. function( elem, name, isXML ) {
  7155. return isXML ?
  7156. undefined :
  7157. elem[ jQuery.camelCase( "default-" + name ) ] ?
  7158. name.toLowerCase() :
  7159. null;
  7160. };
  7161. });
  7162. // fix oldIE attroperties
  7163. if ( !getSetInput || !getSetAttribute ) {
  7164. jQuery.attrHooks.value = {
  7165. set: function( elem, value, name ) {
  7166. if ( jQuery.nodeName( elem, "input" ) ) {
  7167. // Does not return so that setAttribute is also used
  7168. elem.defaultValue = value;
  7169. } else {
  7170. // Use nodeHook if defined (#1954); otherwise setAttribute is fine
  7171. return nodeHook && nodeHook.set( elem, value, name );
  7172. }
  7173. }
  7174. };
  7175. }
  7176. // IE6/7 do not support getting/setting some attributes with get/setAttribute
  7177. if ( !getSetAttribute ) {
  7178. // Use this for any attribute in IE6/7
  7179. // This fixes almost every IE6/7 issue
  7180. nodeHook = {
  7181. set: function( elem, value, name ) {
  7182. // Set the existing or create a new attribute node
  7183. var ret = elem.getAttributeNode( name );
  7184. if ( !ret ) {
  7185. elem.setAttributeNode(
  7186. (ret = elem.ownerDocument.createAttribute( name ))
  7187. );
  7188. }
  7189. ret.value = value += "";
  7190. // Break association with cloned elements by also using setAttribute (#9646)
  7191. return name === "value" || value === elem.getAttribute( name ) ?
  7192. value :
  7193. undefined;
  7194. }
  7195. };
  7196. jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =
  7197. // Some attributes are constructed with empty-string values when not defined
  7198. function( elem, name, isXML ) {
  7199. var ret;
  7200. return isXML ?
  7201. undefined :
  7202. (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
  7203. ret.value :
  7204. null;
  7205. };
  7206. jQuery.valHooks.button = {
  7207. get: function( elem, name ) {
  7208. var ret = elem.getAttributeNode( name );
  7209. return ret && ret.specified ?
  7210. ret.value :
  7211. undefined;
  7212. },
  7213. set: nodeHook.set
  7214. };
  7215. // Set contenteditable to false on removals(#10429)
  7216. // Setting to empty string throws an error as an invalid value
  7217. jQuery.attrHooks.contenteditable = {
  7218. set: function( elem, value, name ) {
  7219. nodeHook.set( elem, value === "" ? false : value, name );
  7220. }
  7221. };
  7222. // Set width and height to auto instead of 0 on empty string( Bug #8150 )
  7223. // This is for removals
  7224. jQuery.each([ "width", "height" ], function( i, name ) {
  7225. jQuery.attrHooks[ name ] = {
  7226. set: function( elem, value ) {
  7227. if ( value === "" ) {
  7228. elem.setAttribute( name, "auto" );
  7229. return value;
  7230. }
  7231. }
  7232. };
  7233. });
  7234. }
  7235. // Some attributes require a special call on IE
  7236. // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  7237. if ( !jQuery.support.hrefNormalized ) {
  7238. // href/src property should get the full normalized URL (#10299/#12915)
  7239. jQuery.each([ "href", "src" ], function( i, name ) {
  7240. jQuery.propHooks[ name ] = {
  7241. get: function( elem ) {
  7242. return elem.getAttribute( name, 4 );
  7243. }
  7244. };
  7245. });
  7246. }
  7247. if ( !jQuery.support.style ) {
  7248. jQuery.attrHooks.style = {
  7249. get: function( elem ) {
  7250. // Return undefined in the case of empty string
  7251. // Note: IE uppercases css property names, but if we were to .toLowerCase()
  7252. // .cssText, that would destroy case senstitivity in URL's, like in "background"
  7253. return elem.style.cssText || undefined;
  7254. },
  7255. set: function( elem, value ) {
  7256. return ( elem.style.cssText = value + "" );
  7257. }
  7258. };
  7259. }
  7260. // Safari mis-reports the default selected property of an option
  7261. // Accessing the parent's selectedIndex property fixes it
  7262. if ( !jQuery.support.optSelected ) {
  7263. jQuery.propHooks.selected = {
  7264. get: function( elem ) {
  7265. var parent = elem.parentNode;
  7266. if ( parent ) {
  7267. parent.selectedIndex;
  7268. // Make sure that it also works with optgroups, see #5701
  7269. if ( parent.parentNode ) {
  7270. parent.parentNode.selectedIndex;
  7271. }
  7272. }
  7273. return null;
  7274. }
  7275. };
  7276. }
  7277. jQuery.each([
  7278. "tabIndex",
  7279. "readOnly",
  7280. "maxLength",
  7281. "cellSpacing",
  7282. "cellPadding",
  7283. "rowSpan",
  7284. "colSpan",
  7285. "useMap",
  7286. "frameBorder",
  7287. "contentEditable"
  7288. ], function() {
  7289. jQuery.propFix[ this.toLowerCase() ] = this;
  7290. });
  7291. // IE6/7 call enctype encoding
  7292. if ( !jQuery.support.enctype ) {
  7293. jQuery.propFix.enctype = "encoding";
  7294. }
  7295. // Radios and checkboxes getter/setter
  7296. jQuery.each([ "radio", "checkbox" ], function() {
  7297. jQuery.valHooks[ this ] = {
  7298. set: function( elem, value ) {
  7299. if ( jQuery.isArray( value ) ) {
  7300. return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
  7301. }
  7302. }
  7303. };
  7304. if ( !jQuery.support.checkOn ) {
  7305. jQuery.valHooks[ this ].get = function( elem ) {
  7306. // Support: Webkit
  7307. // "" is returned instead of "on" if a value isn't specified
  7308. return elem.getAttribute("value") === null ? "on" : elem.value;
  7309. };
  7310. }
  7311. });
  7312. var rformElems = /^(?:input|select|textarea)$/i,
  7313. rkeyEvent = /^key/,
  7314. rmouseEvent = /^(?:mouse|contextmenu)|click/,
  7315. rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  7316. rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
  7317. function returnTrue() {
  7318. return true;
  7319. }
  7320. function returnFalse() {
  7321. return false;
  7322. }
  7323. function safeActiveElement() {
  7324. try {
  7325. return document.activeElement;
  7326. } catch ( err ) { }
  7327. }
  7328. /*
  7329. * Helper functions for managing events -- not part of the public interface.
  7330. * Props to Dean Edwards' addEvent library for many of the ideas.
  7331. */
  7332. jQuery.event = {
  7333. global: {},
  7334. add: function( elem, types, handler, data, selector ) {
  7335. var tmp, events, t, handleObjIn,
  7336. special, eventHandle, handleObj,
  7337. handlers, type, namespaces, origType,
  7338. elemData = jQuery._data( elem );
  7339. // Don't attach events to noData or text/comment nodes (but allow plain objects)
  7340. if ( !elemData ) {
  7341. return;
  7342. }
  7343. // Caller can pass in an object of custom data in lieu of the handler
  7344. if ( handler.handler ) {
  7345. handleObjIn = handler;
  7346. handler = handleObjIn.handler;
  7347. selector = handleObjIn.selector;
  7348. }
  7349. // Make sure that the handler has a unique ID, used to find/remove it later
  7350. if ( !handler.guid ) {
  7351. handler.guid = jQuery.guid++;
  7352. }
  7353. // Init the element's event structure and main handler, if this is the first
  7354. if ( !(events = elemData.events) ) {
  7355. events = elemData.events = {};
  7356. }
  7357. if ( !(eventHandle = elemData.handle) ) {
  7358. eventHandle = elemData.handle = function( e ) {
  7359. // Discard the second event of a jQuery.event.trigger() and
  7360. // when an event is called after a page has unloaded
  7361. return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
  7362. jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
  7363. undefined;
  7364. };
  7365. // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
  7366. eventHandle.elem = elem;
  7367. }
  7368. // Handle multiple events separated by a space
  7369. types = ( types || "" ).match( core_rnotwhite ) || [""];
  7370. t = types.length;
  7371. while ( t-- ) {
  7372. tmp = rtypenamespace.exec( types[t] ) || [];
  7373. type = origType = tmp[1];
  7374. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  7375. // There *must* be a type, no attaching namespace-only handlers
  7376. if ( !type ) {
  7377. continue;
  7378. }
  7379. // If event changes its type, use the special event handlers for the changed type
  7380. special = jQuery.event.special[ type ] || {};
  7381. // If selector defined, determine special event api type, otherwise given type
  7382. type = ( selector ? special.delegateType : special.bindType ) || type;
  7383. // Update special based on newly reset type
  7384. special = jQuery.event.special[ type ] || {};
  7385. // handleObj is passed to all event handlers
  7386. handleObj = jQuery.extend({
  7387. type: type,
  7388. origType: origType,
  7389. data: data,
  7390. handler: handler,
  7391. guid: handler.guid,
  7392. selector: selector,
  7393. needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  7394. namespace: namespaces.join(".")
  7395. }, handleObjIn );
  7396. // Init the event handler queue if we're the first
  7397. if ( !(handlers = events[ type ]) ) {
  7398. handlers = events[ type ] = [];
  7399. handlers.delegateCount = 0;
  7400. // Only use addEventListener/attachEvent if the special events handler returns false
  7401. if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  7402. // Bind the global event handler to the element
  7403. if ( elem.addEventListener ) {
  7404. elem.addEventListener( type, eventHandle, false );
  7405. } else if ( elem.attachEvent ) {
  7406. elem.attachEvent( "on" + type, eventHandle );
  7407. }
  7408. }
  7409. }
  7410. if ( special.add ) {
  7411. special.add.call( elem, handleObj );
  7412. if ( !handleObj.handler.guid ) {
  7413. handleObj.handler.guid = handler.guid;
  7414. }
  7415. }
  7416. // Add to the element's handler list, delegates in front
  7417. if ( selector ) {
  7418. handlers.splice( handlers.delegateCount++, 0, handleObj );
  7419. } else {
  7420. handlers.push( handleObj );
  7421. }
  7422. // Keep track of which events have ever been used, for event optimization
  7423. jQuery.event.global[ type ] = true;
  7424. }
  7425. // Nullify elem to prevent memory leaks in IE
  7426. elem = null;
  7427. },
  7428. // Detach an event or set of events from an element
  7429. remove: function( elem, types, handler, selector, mappedTypes ) {
  7430. var j, handleObj, tmp,
  7431. origCount, t, events,
  7432. special, handlers, type,
  7433. namespaces, origType,
  7434. elemData = jQuery.hasData( elem ) && jQuery._data( elem );
  7435. if ( !elemData || !(events = elemData.events) ) {
  7436. return;
  7437. }
  7438. // Once for each type.namespace in types; type may be omitted
  7439. types = ( types || "" ).match( core_rnotwhite ) || [""];
  7440. t = types.length;
  7441. while ( t-- ) {
  7442. tmp = rtypenamespace.exec( types[t] ) || [];
  7443. type = origType = tmp[1];
  7444. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  7445. // Unbind all events (on this namespace, if provided) for the element
  7446. if ( !type ) {
  7447. for ( type in events ) {
  7448. jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  7449. }
  7450. continue;
  7451. }
  7452. special = jQuery.event.special[ type ] || {};
  7453. type = ( selector ? special.delegateType : special.bindType ) || type;
  7454. handlers = events[ type ] || [];
  7455. tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
  7456. // Remove matching events
  7457. origCount = j = handlers.length;
  7458. while ( j-- ) {
  7459. handleObj = handlers[ j ];
  7460. if ( ( mappedTypes || origType === handleObj.origType ) &&
  7461. ( !handler || handler.guid === handleObj.guid ) &&
  7462. ( !tmp || tmp.test( handleObj.namespace ) ) &&
  7463. ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
  7464. handlers.splice( j, 1 );
  7465. if ( handleObj.selector ) {
  7466. handlers.delegateCount--;
  7467. }
  7468. if ( special.remove ) {
  7469. special.remove.call( elem, handleObj );
  7470. }
  7471. }
  7472. }
  7473. // Remove generic event handler if we removed something and no more handlers exist
  7474. // (avoids potential for endless recursion during removal of special event handlers)
  7475. if ( origCount && !handlers.length ) {
  7476. if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  7477. jQuery.removeEvent( elem, type, elemData.handle );
  7478. }
  7479. delete events[ type ];
  7480. }
  7481. }
  7482. // Remove the expando if it's no longer used
  7483. if ( jQuery.isEmptyObject( events ) ) {
  7484. delete elemData.handle;
  7485. // removeData also checks for emptiness and clears the expando if empty
  7486. // so use it instead of delete
  7487. jQuery._removeData( elem, "events" );
  7488. }
  7489. },
  7490. trigger: function( event, data, elem, onlyHandlers ) {
  7491. var handle, ontype, cur,
  7492. bubbleType, special, tmp, i,
  7493. eventPath = [ elem || document ],
  7494. type = core_hasOwn.call( event, "type" ) ? event.type : event,
  7495. namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
  7496. cur = tmp = elem = elem || document;
  7497. // Don't do events on text and comment nodes
  7498. if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  7499. return;
  7500. }
  7501. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  7502. if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  7503. return;
  7504. }
  7505. if ( type.indexOf(".") >= 0 ) {
  7506. // Namespaced trigger; create a regexp to match event type in handle()
  7507. namespaces = type.split(".");
  7508. type = namespaces.shift();
  7509. namespaces.sort();
  7510. }
  7511. ontype = type.indexOf(":") < 0 && "on" + type;
  7512. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  7513. event = event[ jQuery.expando ] ?
  7514. event :
  7515. new jQuery.Event( type, typeof event === "object" && event );
  7516. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  7517. event.isTrigger = onlyHandlers ? 2 : 3;
  7518. event.namespace = namespaces.join(".");
  7519. event.namespace_re = event.namespace ?
  7520. new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
  7521. null;
  7522. // Clean up the event in case it is being reused
  7523. event.result = undefined;
  7524. if ( !event.target ) {
  7525. event.target = elem;
  7526. }
  7527. // Clone any incoming data and prepend the event, creating the handler arg list
  7528. data = data == null ?
  7529. [ event ] :
  7530. jQuery.makeArray( data, [ event ] );
  7531. // Allow special events to draw outside the lines
  7532. special = jQuery.event.special[ type ] || {};
  7533. if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  7534. return;
  7535. }
  7536. // Determine event propagation path in advance, per W3C events spec (#9951)
  7537. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  7538. if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  7539. bubbleType = special.delegateType || type;
  7540. if ( !rfocusMorph.test( bubbleType + type ) ) {
  7541. cur = cur.parentNode;
  7542. }
  7543. for ( ; cur; cur = cur.parentNode ) {
  7544. eventPath.push( cur );
  7545. tmp = cur;
  7546. }
  7547. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  7548. if ( tmp === (elem.ownerDocument || document) ) {
  7549. eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  7550. }
  7551. }
  7552. // Fire handlers on the event path
  7553. i = 0;
  7554. while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
  7555. event.type = i > 1 ?
  7556. bubbleType :
  7557. special.bindType || type;
  7558. // jQuery handler
  7559. handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
  7560. if ( handle ) {
  7561. handle.apply( cur, data );
  7562. }
  7563. // Native handler
  7564. handle = ontype && cur[ ontype ];
  7565. if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
  7566. event.preventDefault();
  7567. }
  7568. }
  7569. event.type = type;
  7570. // If nobody prevented the default action, do it now
  7571. if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  7572. if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
  7573. jQuery.acceptData( elem ) ) {
  7574. // Call a native DOM method on the target with the same name name as the event.
  7575. // Can't use an .isFunction() check here because IE6/7 fails that test.
  7576. // Don't do default actions on window, that's where global variables be (#6170)
  7577. if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
  7578. // Don't re-trigger an onFOO event when we call its FOO() method
  7579. tmp = elem[ ontype ];
  7580. if ( tmp ) {
  7581. elem[ ontype ] = null;
  7582. }
  7583. // Prevent re-triggering of the same event, since we already bubbled it above
  7584. jQuery.event.triggered = type;
  7585. try {
  7586. elem[ type ]();
  7587. } catch ( e ) {
  7588. // IE<9 dies on focus/blur to hidden element (#1486,#12518)
  7589. // only reproducible on winXP IE8 native, not IE9 in IE8 mode
  7590. }
  7591. jQuery.event.triggered = undefined;
  7592. if ( tmp ) {
  7593. elem[ ontype ] = tmp;
  7594. }
  7595. }
  7596. }
  7597. }
  7598. return event.result;
  7599. },
  7600. dispatch: function( event ) {
  7601. // Make a writable jQuery.Event from the native event object
  7602. event = jQuery.event.fix( event );
  7603. var i, ret, handleObj, matched, j,
  7604. handlerQueue = [],
  7605. args = core_slice.call( arguments ),
  7606. handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
  7607. special = jQuery.event.special[ event.type ] || {};
  7608. // Use the fix-ed jQuery.Event rather than the (read-only) native event
  7609. args[0] = event;
  7610. event.delegateTarget = this;
  7611. // Call the preDispatch hook for the mapped type, and let it bail if desired
  7612. if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  7613. return;
  7614. }
  7615. // Determine handlers
  7616. handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  7617. // Run delegates first; they may want to stop propagation beneath us
  7618. i = 0;
  7619. while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
  7620. event.currentTarget = matched.elem;
  7621. j = 0;
  7622. while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
  7623. // Triggered event must either 1) have no namespace, or
  7624. // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
  7625. if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
  7626. event.handleObj = handleObj;
  7627. event.data = handleObj.data;
  7628. ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
  7629. .apply( matched.elem, args );
  7630. if ( ret !== undefined ) {
  7631. if ( (event.result = ret) === false ) {
  7632. event.preventDefault();
  7633. event.stopPropagation();
  7634. }
  7635. }
  7636. }
  7637. }
  7638. }
  7639. // Call the postDispatch hook for the mapped type
  7640. if ( special.postDispatch ) {
  7641. special.postDispatch.call( this, event );
  7642. }
  7643. return event.result;
  7644. },
  7645. handlers: function( event, handlers ) {
  7646. var sel, handleObj, matches, i,
  7647. handlerQueue = [],
  7648. delegateCount = handlers.delegateCount,
  7649. cur = event.target;
  7650. // Find delegate handlers
  7651. // Black-hole SVG <use> instance trees (#13180)
  7652. // Avoid non-left-click bubbling in Firefox (#3861)
  7653. if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
  7654. /* jshint eqeqeq: false */
  7655. for ( ; cur != this; cur = cur.parentNode || this ) {
  7656. /* jshint eqeqeq: true */
  7657. // Don't check non-elements (#13208)
  7658. // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  7659. if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
  7660. matches = [];
  7661. for ( i = 0; i < delegateCount; i++ ) {
  7662. handleObj = handlers[ i ];
  7663. // Don't conflict with Object.prototype properties (#13203)
  7664. sel = handleObj.selector + " ";
  7665. if ( matches[ sel ] === undefined ) {
  7666. matches[ sel ] = handleObj.needsContext ?
  7667. jQuery( sel, this ).index( cur ) >= 0 :
  7668. jQuery.find( sel, this, null, [ cur ] ).length;
  7669. }
  7670. if ( matches[ sel ] ) {
  7671. matches.push( handleObj );
  7672. }
  7673. }
  7674. if ( matches.length ) {
  7675. handlerQueue.push({ elem: cur, handlers: matches });
  7676. }
  7677. }
  7678. }
  7679. }
  7680. // Add the remaining (directly-bound) handlers
  7681. if ( delegateCount < handlers.length ) {
  7682. handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
  7683. }
  7684. return handlerQueue;
  7685. },
  7686. fix: function( event ) {
  7687. if ( event[ jQuery.expando ] ) {
  7688. return event;
  7689. }
  7690. // Create a writable copy of the event object and normalize some properties
  7691. var i, prop, copy,
  7692. type = event.type,
  7693. originalEvent = event,
  7694. fixHook = this.fixHooks[ type ];
  7695. if ( !fixHook ) {
  7696. this.fixHooks[ type ] = fixHook =
  7697. rmouseEvent.test( type ) ? this.mouseHooks :
  7698. rkeyEvent.test( type ) ? this.keyHooks :
  7699. {};
  7700. }
  7701. copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  7702. event = new jQuery.Event( originalEvent );
  7703. i = copy.length;
  7704. while ( i-- ) {
  7705. prop = copy[ i ];
  7706. event[ prop ] = originalEvent[ prop ];
  7707. }
  7708. // Support: IE<9
  7709. // Fix target property (#1925)
  7710. if ( !event.target ) {
  7711. event.target = originalEvent.srcElement || document;
  7712. }
  7713. // Support: Chrome 23+, Safari?
  7714. // Target should not be a text node (#504, #13143)
  7715. if ( event.target.nodeType === 3 ) {
  7716. event.target = event.target.parentNode;
  7717. }
  7718. // Support: IE<9
  7719. // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
  7720. event.metaKey = !!event.metaKey;
  7721. return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
  7722. },
  7723. // Includes some event props shared by KeyEvent and MouseEvent
  7724. props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
  7725. fixHooks: {},
  7726. keyHooks: {
  7727. props: "char charCode key keyCode".split(" "),
  7728. filter: function( event, original ) {
  7729. // Add which for key events
  7730. if ( event.which == null ) {
  7731. event.which = original.charCode != null ? original.charCode : original.keyCode;
  7732. }
  7733. return event;
  7734. }
  7735. },
  7736. mouseHooks: {
  7737. props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
  7738. filter: function( event, original ) {
  7739. var body, eventDoc, doc,
  7740. button = original.button,
  7741. fromElement = original.fromElement;
  7742. // Calculate pageX/Y if missing and clientX/Y available
  7743. if ( event.pageX == null && original.clientX != null ) {
  7744. eventDoc = event.target.ownerDocument || document;
  7745. doc = eventDoc.documentElement;
  7746. body = eventDoc.body;
  7747. event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
  7748. event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
  7749. }
  7750. // Add relatedTarget, if necessary
  7751. if ( !event.relatedTarget && fromElement ) {
  7752. event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
  7753. }
  7754. // Add which for click: 1 === left; 2 === middle; 3 === right
  7755. // Note: button is not normalized, so don't use it
  7756. if ( !event.which && button !== undefined ) {
  7757. event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
  7758. }
  7759. return event;
  7760. }
  7761. },
  7762. special: {
  7763. load: {
  7764. // Prevent triggered image.load events from bubbling to window.load
  7765. noBubble: true
  7766. },
  7767. focus: {
  7768. // Fire native event if possible so blur/focus sequence is correct
  7769. trigger: function() {
  7770. if ( this !== safeActiveElement() && this.focus ) {
  7771. try {
  7772. this.focus();
  7773. return false;
  7774. } catch ( e ) {
  7775. // Support: IE<9
  7776. // If we error on focus to hidden element (#1486, #12518),
  7777. // let .trigger() run the handlers
  7778. }
  7779. }
  7780. },
  7781. delegateType: "focusin"
  7782. },
  7783. blur: {
  7784. trigger: function() {
  7785. if ( this === safeActiveElement() && this.blur ) {
  7786. this.blur();
  7787. return false;
  7788. }
  7789. },
  7790. delegateType: "focusout"
  7791. },
  7792. click: {
  7793. // For checkbox, fire native event so checked state will be right
  7794. trigger: function() {
  7795. if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
  7796. this.click();
  7797. return false;
  7798. }
  7799. },
  7800. // For cross-browser consistency, don't fire native .click() on links
  7801. _default: function( event ) {
  7802. return jQuery.nodeName( event.target, "a" );
  7803. }
  7804. },
  7805. beforeunload: {
  7806. postDispatch: function( event ) {
  7807. // Even when returnValue equals to undefined Firefox will still show alert
  7808. if ( event.result !== undefined ) {
  7809. event.originalEvent.returnValue = event.result;
  7810. }
  7811. }
  7812. }
  7813. },
  7814. simulate: function( type, elem, event, bubble ) {
  7815. // Piggyback on a donor event to simulate a different one.
  7816. // Fake originalEvent to avoid donor's stopPropagation, but if the
  7817. // simulated event prevents default then we do the same on the donor.
  7818. var e = jQuery.extend(
  7819. new jQuery.Event(),
  7820. event,
  7821. {
  7822. type: type,
  7823. isSimulated: true,
  7824. originalEvent: {}
  7825. }
  7826. );
  7827. if ( bubble ) {
  7828. jQuery.event.trigger( e, null, elem );
  7829. } else {
  7830. jQuery.event.dispatch.call( elem, e );
  7831. }
  7832. if ( e.isDefaultPrevented() ) {
  7833. event.preventDefault();
  7834. }
  7835. }
  7836. };
  7837. jQuery.removeEvent = document.removeEventListener ?
  7838. function( elem, type, handle ) {
  7839. if ( elem.removeEventListener ) {
  7840. elem.removeEventListener( type, handle, false );
  7841. }
  7842. } :
  7843. function( elem, type, handle ) {
  7844. var name = "on" + type;
  7845. if ( elem.detachEvent ) {
  7846. // #8545, #7054, preventing memory leaks for custom events in IE6-8
  7847. // detachEvent needed property on element, by name of that event, to properly expose it to GC
  7848. if ( typeof elem[ name ] === core_strundefined ) {
  7849. elem[ name ] = null;
  7850. }
  7851. elem.detachEvent( name, handle );
  7852. }
  7853. };
  7854. jQuery.Event = function( src, props ) {
  7855. // Allow instantiation without the 'new' keyword
  7856. if ( !(this instanceof jQuery.Event) ) {
  7857. return new jQuery.Event( src, props );
  7858. }
  7859. // Event object
  7860. if ( src && src.type ) {
  7861. this.originalEvent = src;
  7862. this.type = src.type;
  7863. // Events bubbling up the document may have been marked as prevented
  7864. // by a handler lower down the tree; reflect the correct value.
  7865. this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
  7866. src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
  7867. // Event type
  7868. } else {
  7869. this.type = src;
  7870. }
  7871. // Put explicitly provided properties onto the event object
  7872. if ( props ) {
  7873. jQuery.extend( this, props );
  7874. }
  7875. // Create a timestamp if incoming event doesn't have one
  7876. this.timeStamp = src && src.timeStamp || jQuery.now();
  7877. // Mark it as fixed
  7878. this[ jQuery.expando ] = true;
  7879. };
  7880. // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  7881. // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  7882. jQuery.Event.prototype = {
  7883. isDefaultPrevented: returnFalse,
  7884. isPropagationStopped: returnFalse,
  7885. isImmediatePropagationStopped: returnFalse,
  7886. preventDefault: function() {
  7887. var e = this.originalEvent;
  7888. this.isDefaultPrevented = returnTrue;
  7889. if ( !e ) {
  7890. return;
  7891. }
  7892. // If preventDefault exists, run it on the original event
  7893. if ( e.preventDefault ) {
  7894. e.preventDefault();
  7895. // Support: IE
  7896. // Otherwise set the returnValue property of the original event to false
  7897. } else {
  7898. e.returnValue = false;
  7899. }
  7900. },
  7901. stopPropagation: function() {
  7902. var e = this.originalEvent;
  7903. this.isPropagationStopped = returnTrue;
  7904. if ( !e ) {
  7905. return;
  7906. }
  7907. // If stopPropagation exists, run it on the original event
  7908. if ( e.stopPropagation ) {
  7909. e.stopPropagation();
  7910. }
  7911. // Support: IE
  7912. // Set the cancelBubble property of the original event to true
  7913. e.cancelBubble = true;
  7914. },
  7915. stopImmediatePropagation: function() {
  7916. this.isImmediatePropagationStopped = returnTrue;
  7917. this.stopPropagation();
  7918. }
  7919. };
  7920. // Create mouseenter/leave events using mouseover/out and event-time checks
  7921. jQuery.each({
  7922. mouseenter: "mouseover",
  7923. mouseleave: "mouseout"
  7924. }, function( orig, fix ) {
  7925. jQuery.event.special[ orig ] = {
  7926. delegateType: fix,
  7927. bindType: fix,
  7928. handle: function( event ) {
  7929. var ret,
  7930. target = this,
  7931. related = event.relatedTarget,
  7932. handleObj = event.handleObj;
  7933. // For mousenter/leave call the handler if related is outside the target.
  7934. // NB: No relatedTarget if the mouse left/entered the browser window
  7935. if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
  7936. event.type = handleObj.origType;
  7937. ret = handleObj.handler.apply( this, arguments );
  7938. event.type = fix;
  7939. }
  7940. return ret;
  7941. }
  7942. };
  7943. });
  7944. // IE submit delegation
  7945. if ( !jQuery.support.submitBubbles ) {
  7946. jQuery.event.special.submit = {
  7947. setup: function() {
  7948. // Only need this for delegated form submit events
  7949. if ( jQuery.nodeName( this, "form" ) ) {
  7950. return false;
  7951. }
  7952. // Lazy-add a submit handler when a descendant form may potentially be submitted
  7953. jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
  7954. // Node name check avoids a VML-related crash in IE (#9807)
  7955. var elem = e.target,
  7956. form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
  7957. if ( form && !jQuery._data( form, "submitBubbles" ) ) {
  7958. jQuery.event.add( form, "submit._submit", function( event ) {
  7959. event._submit_bubble = true;
  7960. });
  7961. jQuery._data( form, "submitBubbles", true );
  7962. }
  7963. });
  7964. // return undefined since we don't need an event listener
  7965. },
  7966. postDispatch: function( event ) {
  7967. // If form was submitted by the user, bubble the event up the tree
  7968. if ( event._submit_bubble ) {
  7969. delete event._submit_bubble;
  7970. if ( this.parentNode && !event.isTrigger ) {
  7971. jQuery.event.simulate( "submit", this.parentNode, event, true );
  7972. }
  7973. }
  7974. },
  7975. teardown: function() {
  7976. // Only need this for delegated form submit events
  7977. if ( jQuery.nodeName( this, "form" ) ) {
  7978. return false;
  7979. }
  7980. // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
  7981. jQuery.event.remove( this, "._submit" );
  7982. }
  7983. };
  7984. }
  7985. // IE change delegation and checkbox/radio fix
  7986. if ( !jQuery.support.changeBubbles ) {
  7987. jQuery.event.special.change = {
  7988. setup: function() {
  7989. if ( rformElems.test( this.nodeName ) ) {
  7990. // IE doesn't fire change on a check/radio until blur; trigger it on click
  7991. // after a propertychange. Eat the blur-change in special.change.handle.
  7992. // This still fires onchange a second time for check/radio after blur.
  7993. if ( this.type === "checkbox" || this.type === "radio" ) {
  7994. jQuery.event.add( this, "propertychange._change", function( event ) {
  7995. if ( event.originalEvent.propertyName === "checked" ) {
  7996. this._just_changed = true;
  7997. }
  7998. });
  7999. jQuery.event.add( this, "click._change", function( event ) {
  8000. if ( this._just_changed && !event.isTrigger ) {
  8001. this._just_changed = false;
  8002. }
  8003. // Allow triggered, simulated change events (#11500)
  8004. jQuery.event.simulate( "change", this, event, true );
  8005. });
  8006. }
  8007. return false;
  8008. }
  8009. // Delegated event; lazy-add a change handler on descendant inputs
  8010. jQuery.event.add( this, "beforeactivate._change", function( e ) {
  8011. var elem = e.target;
  8012. if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
  8013. jQuery.event.add( elem, "change._change", function( event ) {
  8014. if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
  8015. jQuery.event.simulate( "change", this.parentNode, event, true );
  8016. }
  8017. });
  8018. jQuery._data( elem, "changeBubbles", true );
  8019. }
  8020. });
  8021. },
  8022. handle: function( event ) {
  8023. var elem = event.target;
  8024. // Swallow native change events from checkbox/radio, we already triggered them above
  8025. if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
  8026. return event.handleObj.handler.apply( this, arguments );
  8027. }
  8028. },
  8029. teardown: function() {
  8030. jQuery.event.remove( this, "._change" );
  8031. return !rformElems.test( this.nodeName );
  8032. }
  8033. };
  8034. }
  8035. // Create "bubbling" focus and blur events
  8036. if ( !jQuery.support.focusinBubbles ) {
  8037. jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  8038. // Attach a single capturing handler while someone wants focusin/focusout
  8039. var attaches = 0,
  8040. handler = function( event ) {
  8041. jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
  8042. };
  8043. jQuery.event.special[ fix ] = {
  8044. setup: function() {
  8045. if ( attaches++ === 0 ) {
  8046. document.addEventListener( orig, handler, true );
  8047. }
  8048. },
  8049. teardown: function() {
  8050. if ( --attaches === 0 ) {
  8051. document.removeEventListener( orig, handler, true );
  8052. }
  8053. }
  8054. };
  8055. });
  8056. }
  8057. jQuery.fn.extend({
  8058. on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
  8059. var type, origFn;
  8060. // Types can be a map of types/handlers
  8061. if ( typeof types === "object" ) {
  8062. // ( types-Object, selector, data )
  8063. if ( typeof selector !== "string" ) {
  8064. // ( types-Object, data )
  8065. data = data || selector;
  8066. selector = undefined;
  8067. }
  8068. for ( type in types ) {
  8069. this.on( type, selector, data, types[ type ], one );
  8070. }
  8071. return this;
  8072. }
  8073. if ( data == null && fn == null ) {
  8074. // ( types, fn )
  8075. fn = selector;
  8076. data = selector = undefined;
  8077. } else if ( fn == null ) {
  8078. if ( typeof selector === "string" ) {
  8079. // ( types, selector, fn )
  8080. fn = data;
  8081. data = undefined;
  8082. } else {
  8083. // ( types, data, fn )
  8084. fn = data;
  8085. data = selector;
  8086. selector = undefined;
  8087. }
  8088. }
  8089. if ( fn === false ) {
  8090. fn = returnFalse;
  8091. } else if ( !fn ) {
  8092. return this;
  8093. }
  8094. if ( one === 1 ) {
  8095. origFn = fn;
  8096. fn = function( event ) {
  8097. // Can use an empty set, since event contains the info
  8098. jQuery().off( event );
  8099. return origFn.apply( this, arguments );
  8100. };
  8101. // Use same guid so caller can remove using origFn
  8102. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  8103. }
  8104. return this.each( function() {
  8105. jQuery.event.add( this, types, fn, data, selector );
  8106. });
  8107. },
  8108. one: function( types, selector, data, fn ) {
  8109. return this.on( types, selector, data, fn, 1 );
  8110. },
  8111. off: function( types, selector, fn ) {
  8112. var handleObj, type;
  8113. if ( types && types.preventDefault && types.handleObj ) {
  8114. // ( event ) dispatched jQuery.Event
  8115. handleObj = types.handleObj;
  8116. jQuery( types.delegateTarget ).off(
  8117. handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
  8118. handleObj.selector,
  8119. handleObj.handler
  8120. );
  8121. return this;
  8122. }
  8123. if ( typeof types === "object" ) {
  8124. // ( types-object [, selector] )
  8125. for ( type in types ) {
  8126. this.off( type, selector, types[ type ] );
  8127. }
  8128. return this;
  8129. }
  8130. if ( selector === false || typeof selector === "function" ) {
  8131. // ( types [, fn] )
  8132. fn = selector;
  8133. selector = undefined;
  8134. }
  8135. if ( fn === false ) {
  8136. fn = returnFalse;
  8137. }
  8138. return this.each(function() {
  8139. jQuery.event.remove( this, types, fn, selector );
  8140. });
  8141. },
  8142. trigger: function( type, data ) {
  8143. return this.each(function() {
  8144. jQuery.event.trigger( type, data, this );
  8145. });
  8146. },
  8147. triggerHandler: function( type, data ) {
  8148. var elem = this[0];
  8149. if ( elem ) {
  8150. return jQuery.event.trigger( type, data, elem, true );
  8151. }
  8152. }
  8153. });
  8154. var isSimple = /^.[^:#\[\.,]*$/,
  8155. rparentsprev = /^(?:parents|prev(?:Until|All))/,
  8156. rneedsContext = jQuery.expr.match.needsContext,
  8157. // methods guaranteed to produce a unique set when starting from a unique set
  8158. guaranteedUnique = {
  8159. children: true,
  8160. contents: true,
  8161. next: true,
  8162. prev: true
  8163. };
  8164. jQuery.fn.extend({
  8165. find: function( selector ) {
  8166. var i,
  8167. ret = [],
  8168. self = this,
  8169. len = self.length;
  8170. if ( typeof selector !== "string" ) {
  8171. return this.pushStack( jQuery( selector ).filter(function() {
  8172. for ( i = 0; i < len; i++ ) {
  8173. if ( jQuery.contains( self[ i ], this ) ) {
  8174. return true;
  8175. }
  8176. }
  8177. }) );
  8178. }
  8179. for ( i = 0; i < len; i++ ) {
  8180. jQuery.find( selector, self[ i ], ret );
  8181. }
  8182. // Needed because $( selector, context ) becomes $( context ).find( selector )
  8183. ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
  8184. ret.selector = this.selector ? this.selector + " " + selector : selector;
  8185. return ret;
  8186. },
  8187. has: function( target ) {
  8188. var i,
  8189. targets = jQuery( target, this ),
  8190. len = targets.length;
  8191. return this.filter(function() {
  8192. for ( i = 0; i < len; i++ ) {
  8193. if ( jQuery.contains( this, targets[i] ) ) {
  8194. return true;
  8195. }
  8196. }
  8197. });
  8198. },
  8199. not: function( selector ) {
  8200. return this.pushStack( winnow(this, selector || [], true) );
  8201. },
  8202. filter: function( selector ) {
  8203. return this.pushStack( winnow(this, selector || [], false) );
  8204. },
  8205. is: function( selector ) {
  8206. return !!winnow(
  8207. this,
  8208. // If this is a positional/relative selector, check membership in the returned set
  8209. // so $("p:first").is("p:last") won't return true for a doc with two "p".
  8210. typeof selector === "string" && rneedsContext.test( selector ) ?
  8211. jQuery( selector ) :
  8212. selector || [],
  8213. false
  8214. ).length;
  8215. },
  8216. closest: function( selectors, context ) {
  8217. var cur,
  8218. i = 0,
  8219. l = this.length,
  8220. ret = [],
  8221. pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
  8222. jQuery( selectors, context || this.context ) :
  8223. 0;
  8224. for ( ; i < l; i++ ) {
  8225. for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
  8226. // Always skip document fragments
  8227. if ( cur.nodeType < 11 && (pos ?
  8228. pos.index(cur) > -1 :
  8229. // Don't pass non-elements to Sizzle
  8230. cur.nodeType === 1 &&
  8231. jQuery.find.matchesSelector(cur, selectors)) ) {
  8232. cur = ret.push( cur );
  8233. break;
  8234. }
  8235. }
  8236. }
  8237. return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
  8238. },
  8239. // Determine the position of an element within
  8240. // the matched set of elements
  8241. index: function( elem ) {
  8242. // No argument, return index in parent
  8243. if ( !elem ) {
  8244. return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
  8245. }
  8246. // index in selector
  8247. if ( typeof elem === "string" ) {
  8248. return jQuery.inArray( this[0], jQuery( elem ) );
  8249. }
  8250. // Locate the position of the desired element
  8251. return jQuery.inArray(
  8252. // If it receives a jQuery object, the first element is used
  8253. elem.jquery ? elem[0] : elem, this );
  8254. },
  8255. add: function( selector, context ) {
  8256. var set = typeof selector === "string" ?
  8257. jQuery( selector, context ) :
  8258. jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
  8259. all = jQuery.merge( this.get(), set );
  8260. return this.pushStack( jQuery.unique(all) );
  8261. },
  8262. addBack: function( selector ) {
  8263. return this.add( selector == null ?
  8264. this.prevObject : this.prevObject.filter(selector)
  8265. );
  8266. }
  8267. });
  8268. function sibling( cur, dir ) {
  8269. do {
  8270. cur = cur[ dir ];
  8271. } while ( cur && cur.nodeType !== 1 );
  8272. return cur;
  8273. }
  8274. jQuery.each({
  8275. parent: function( elem ) {
  8276. var parent = elem.parentNode;
  8277. return parent && parent.nodeType !== 11 ? parent : null;
  8278. },
  8279. parents: function( elem ) {
  8280. return jQuery.dir( elem, "parentNode" );
  8281. },
  8282. parentsUntil: function( elem, i, until ) {
  8283. return jQuery.dir( elem, "parentNode", until );
  8284. },
  8285. next: function( elem ) {
  8286. return sibling( elem, "nextSibling" );
  8287. },
  8288. prev: function( elem ) {
  8289. return sibling( elem, "previousSibling" );
  8290. },
  8291. nextAll: function( elem ) {
  8292. return jQuery.dir( elem, "nextSibling" );
  8293. },
  8294. prevAll: function( elem ) {
  8295. return jQuery.dir( elem, "previousSibling" );
  8296. },
  8297. nextUntil: function( elem, i, until ) {
  8298. return jQuery.dir( elem, "nextSibling", until );
  8299. },
  8300. prevUntil: function( elem, i, until ) {
  8301. return jQuery.dir( elem, "previousSibling", until );
  8302. },
  8303. siblings: function( elem ) {
  8304. return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
  8305. },
  8306. children: function( elem ) {
  8307. return jQuery.sibling( elem.firstChild );
  8308. },
  8309. contents: function( elem ) {
  8310. return jQuery.nodeName( elem, "iframe" ) ?
  8311. elem.contentDocument || elem.contentWindow.document :
  8312. jQuery.merge( [], elem.childNodes );
  8313. }
  8314. }, function( name, fn ) {
  8315. jQuery.fn[ name ] = function( until, selector ) {
  8316. var ret = jQuery.map( this, fn, until );
  8317. if ( name.slice( -5 ) !== "Until" ) {
  8318. selector = until;
  8319. }
  8320. if ( selector && typeof selector === "string" ) {
  8321. ret = jQuery.filter( selector, ret );
  8322. }
  8323. if ( this.length > 1 ) {
  8324. // Remove duplicates
  8325. if ( !guaranteedUnique[ name ] ) {
  8326. ret = jQuery.unique( ret );
  8327. }
  8328. // Reverse order for parents* and prev-derivatives
  8329. if ( rparentsprev.test( name ) ) {
  8330. ret = ret.reverse();
  8331. }
  8332. }
  8333. return this.pushStack( ret );
  8334. };
  8335. });
  8336. jQuery.extend({
  8337. filter: function( expr, elems, not ) {
  8338. var elem = elems[ 0 ];
  8339. if ( not ) {
  8340. expr = ":not(" + expr + ")";
  8341. }
  8342. return elems.length === 1 && elem.nodeType === 1 ?
  8343. jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
  8344. jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  8345. return elem.nodeType === 1;
  8346. }));
  8347. },
  8348. dir: function( elem, dir, until ) {
  8349. var matched = [],
  8350. cur = elem[ dir ];
  8351. while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
  8352. if ( cur.nodeType === 1 ) {
  8353. matched.push( cur );
  8354. }
  8355. cur = cur[dir];
  8356. }
  8357. return matched;
  8358. },
  8359. sibling: function( n, elem ) {
  8360. var r = [];
  8361. for ( ; n; n = n.nextSibling ) {
  8362. if ( n.nodeType === 1 && n !== elem ) {
  8363. r.push( n );
  8364. }
  8365. }
  8366. return r;
  8367. }
  8368. });
  8369. // Implement the identical functionality for filter and not
  8370. function winnow( elements, qualifier, not ) {
  8371. if ( jQuery.isFunction( qualifier ) ) {
  8372. return jQuery.grep( elements, function( elem, i ) {
  8373. /* jshint -W018 */
  8374. return !!qualifier.call( elem, i, elem ) !== not;
  8375. });
  8376. }
  8377. if ( qualifier.nodeType ) {
  8378. return jQuery.grep( elements, function( elem ) {
  8379. return ( elem === qualifier ) !== not;
  8380. });
  8381. }
  8382. if ( typeof qualifier === "string" ) {
  8383. if ( isSimple.test( qualifier ) ) {
  8384. return jQuery.filter( qualifier, elements, not );
  8385. }
  8386. qualifier = jQuery.filter( qualifier, elements );
  8387. }
  8388. return jQuery.grep( elements, function( elem ) {
  8389. return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
  8390. });
  8391. }
  8392. function createSafeFragment( document ) {
  8393. var list = nodeNames.split( "|" ),
  8394. safeFrag = document.createDocumentFragment();
  8395. if ( safeFrag.createElement ) {
  8396. while ( list.length ) {
  8397. safeFrag.createElement(
  8398. list.pop()
  8399. );
  8400. }
  8401. }
  8402. return safeFrag;
  8403. }
  8404. var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
  8405. "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
  8406. rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
  8407. rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
  8408. rleadingWhitespace = /^\s+/,
  8409. rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
  8410. rtagName = /<([\w:]+)/,
  8411. rtbody = /<tbody/i,
  8412. rhtml = /<|&#?\w+;/,
  8413. rnoInnerhtml = /<(?:script|style|link)/i,
  8414. manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
  8415. // checked="checked" or checked
  8416. rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  8417. rscriptType = /^$|\/(?:java|ecma)script/i,
  8418. rscriptTypeMasked = /^true\/(.*)/,
  8419. rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
  8420. // We have to close these tags to support XHTML (#13200)
  8421. wrapMap = {
  8422. option: [ 1, "<select multiple='multiple'>", "</select>" ],
  8423. legend: [ 1, "<fieldset>", "</fieldset>" ],
  8424. area: [ 1, "<map>", "</map>" ],
  8425. param: [ 1, "<object>", "</object>" ],
  8426. thead: [ 1, "<table>", "</table>" ],
  8427. tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  8428. col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
  8429. td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  8430. // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
  8431. // unless wrapped in a div with non-breaking characters in front of it.
  8432. _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
  8433. },
  8434. safeFragment = createSafeFragment( document ),
  8435. fragmentDiv = safeFragment.appendChild( document.createElement("div") );
  8436. wrapMap.optgroup = wrapMap.option;
  8437. wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  8438. wrapMap.th = wrapMap.td;
  8439. jQuery.fn.extend({
  8440. text: function( value ) {
  8441. return jQuery.access( this, function( value ) {
  8442. return value === undefined ?
  8443. jQuery.text( this ) :
  8444. this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
  8445. }, null, value, arguments.length );
  8446. },
  8447. append: function() {
  8448. return this.domManip( arguments, function( elem ) {
  8449. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  8450. var target = manipulationTarget( this, elem );
  8451. target.appendChild( elem );
  8452. }
  8453. });
  8454. },
  8455. prepend: function() {
  8456. return this.domManip( arguments, function( elem ) {
  8457. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  8458. var target = manipulationTarget( this, elem );
  8459. target.insertBefore( elem, target.firstChild );
  8460. }
  8461. });
  8462. },
  8463. before: function() {
  8464. return this.domManip( arguments, function( elem ) {
  8465. if ( this.parentNode ) {
  8466. this.parentNode.insertBefore( elem, this );
  8467. }
  8468. });
  8469. },
  8470. after: function() {
  8471. return this.domManip( arguments, function( elem ) {
  8472. if ( this.parentNode ) {
  8473. this.parentNode.insertBefore( elem, this.nextSibling );
  8474. }
  8475. });
  8476. },
  8477. // keepData is for internal use only--do not document
  8478. remove: function( selector, keepData ) {
  8479. var elem,
  8480. elems = selector ? jQuery.filter( selector, this ) : this,
  8481. i = 0;
  8482. for ( ; (elem = elems[i]) != null; i++ ) {
  8483. if ( !keepData && elem.nodeType === 1 ) {
  8484. jQuery.cleanData( getAll( elem ) );
  8485. }
  8486. if ( elem.parentNode ) {
  8487. if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
  8488. setGlobalEval( getAll( elem, "script" ) );
  8489. }
  8490. elem.parentNode.removeChild( elem );
  8491. }
  8492. }
  8493. return this;
  8494. },
  8495. empty: function() {
  8496. var elem,
  8497. i = 0;
  8498. for ( ; (elem = this[i]) != null; i++ ) {
  8499. // Remove element nodes and prevent memory leaks
  8500. if ( elem.nodeType === 1 ) {
  8501. jQuery.cleanData( getAll( elem, false ) );
  8502. }
  8503. // Remove any remaining nodes
  8504. while ( elem.firstChild ) {
  8505. elem.removeChild( elem.firstChild );
  8506. }
  8507. // If this is a select, ensure that it displays empty (#12336)
  8508. // Support: IE<9
  8509. if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
  8510. elem.options.length = 0;
  8511. }
  8512. }
  8513. return this;
  8514. },
  8515. clone: function( dataAndEvents, deepDataAndEvents ) {
  8516. dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  8517. deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  8518. return this.map( function () {
  8519. return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  8520. });
  8521. },
  8522. html: function( value ) {
  8523. return jQuery.access( this, function( value ) {
  8524. var elem = this[0] || {},
  8525. i = 0,
  8526. l = this.length;
  8527. if ( value === undefined ) {
  8528. return elem.nodeType === 1 ?
  8529. elem.innerHTML.replace( rinlinejQuery, "" ) :
  8530. undefined;
  8531. }
  8532. // See if we can take a shortcut and just use innerHTML
  8533. if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  8534. ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
  8535. ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
  8536. !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
  8537. value = value.replace( rxhtmlTag, "<$1></$2>" );
  8538. try {
  8539. for (; i < l; i++ ) {
  8540. // Remove element nodes and prevent memory leaks
  8541. elem = this[i] || {};
  8542. if ( elem.nodeType === 1 ) {
  8543. jQuery.cleanData( getAll( elem, false ) );
  8544. elem.innerHTML = value;
  8545. }
  8546. }
  8547. elem = 0;
  8548. // If using innerHTML throws an exception, use the fallback method
  8549. } catch(e) {}
  8550. }
  8551. if ( elem ) {
  8552. this.empty().append( value );
  8553. }
  8554. }, null, value, arguments.length );
  8555. },
  8556. replaceWith: function() {
  8557. var
  8558. // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
  8559. args = jQuery.map( this, function( elem ) {
  8560. return [ elem.nextSibling, elem.parentNode ];
  8561. }),
  8562. i = 0;
  8563. // Make the changes, replacing each context element with the new content
  8564. this.domManip( arguments, function( elem ) {
  8565. var next = args[ i++ ],
  8566. parent = args[ i++ ];
  8567. if ( parent ) {
  8568. // Don't use the snapshot next if it has moved (#13810)
  8569. if ( next && next.parentNode !== parent ) {
  8570. next = this.nextSibling;
  8571. }
  8572. jQuery( this ).remove();
  8573. parent.insertBefore( elem, next );
  8574. }
  8575. // Allow new content to include elements from the context set
  8576. }, true );
  8577. // Force removal if there was no new content (e.g., from empty arguments)
  8578. return i ? this : this.remove();
  8579. },
  8580. detach: function( selector ) {
  8581. return this.remove( selector, true );
  8582. },
  8583. domManip: function( args, callback, allowIntersection ) {
  8584. // Flatten any nested arrays
  8585. args = core_concat.apply( [], args );
  8586. var first, node, hasScripts,
  8587. scripts, doc, fragment,
  8588. i = 0,
  8589. l = this.length,
  8590. set = this,
  8591. iNoClone = l - 1,
  8592. value = args[0],
  8593. isFunction = jQuery.isFunction( value );
  8594. // We can't cloneNode fragments that contain checked, in WebKit
  8595. if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
  8596. return this.each(function( index ) {
  8597. var self = set.eq( index );
  8598. if ( isFunction ) {
  8599. args[0] = value.call( this, index, self.html() );
  8600. }
  8601. self.domManip( args, callback, allowIntersection );
  8602. });
  8603. }
  8604. if ( l ) {
  8605. fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
  8606. first = fragment.firstChild;
  8607. if ( fragment.childNodes.length === 1 ) {
  8608. fragment = first;
  8609. }
  8610. if ( first ) {
  8611. scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  8612. hasScripts = scripts.length;
  8613. // Use the original fragment for the last item instead of the first because it can end up
  8614. // being emptied incorrectly in certain situations (#8070).
  8615. for ( ; i < l; i++ ) {
  8616. node = fragment;
  8617. if ( i !== iNoClone ) {
  8618. node = jQuery.clone( node, true, true );
  8619. // Keep references to cloned scripts for later restoration
  8620. if ( hasScripts ) {
  8621. jQuery.merge( scripts, getAll( node, "script" ) );
  8622. }
  8623. }
  8624. callback.call( this[i], node, i );
  8625. }
  8626. if ( hasScripts ) {
  8627. doc = scripts[ scripts.length - 1 ].ownerDocument;
  8628. // Reenable scripts
  8629. jQuery.map( scripts, restoreScript );
  8630. // Evaluate executable scripts on first document insertion
  8631. for ( i = 0; i < hasScripts; i++ ) {
  8632. node = scripts[ i ];
  8633. if ( rscriptType.test( node.type || "" ) &&
  8634. !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
  8635. if ( node.src ) {
  8636. // Hope ajax is available...
  8637. jQuery._evalUrl( node.src );
  8638. } else {
  8639. jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
  8640. }
  8641. }
  8642. }
  8643. }
  8644. // Fix #11809: Avoid leaking memory
  8645. fragment = first = null;
  8646. }
  8647. }
  8648. return this;
  8649. }
  8650. });
  8651. // Support: IE<8
  8652. // Manipulating tables requires a tbody
  8653. function manipulationTarget( elem, content ) {
  8654. return jQuery.nodeName( elem, "table" ) &&
  8655. jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
  8656. elem.getElementsByTagName("tbody")[0] ||
  8657. elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
  8658. elem;
  8659. }
  8660. // Replace/restore the type attribute of script elements for safe DOM manipulation
  8661. function disableScript( elem ) {
  8662. elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
  8663. return elem;
  8664. }
  8665. function restoreScript( elem ) {
  8666. var match = rscriptTypeMasked.exec( elem.type );
  8667. if ( match ) {
  8668. elem.type = match[1];
  8669. } else {
  8670. elem.removeAttribute("type");
  8671. }
  8672. return elem;
  8673. }
  8674. // Mark scripts as having already been evaluated
  8675. function setGlobalEval( elems, refElements ) {
  8676. var elem,
  8677. i = 0;
  8678. for ( ; (elem = elems[i]) != null; i++ ) {
  8679. jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
  8680. }
  8681. }
  8682. function cloneCopyEvent( src, dest ) {
  8683. if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
  8684. return;
  8685. }
  8686. var type, i, l,
  8687. oldData = jQuery._data( src ),
  8688. curData = jQuery._data( dest, oldData ),
  8689. events = oldData.events;
  8690. if ( events ) {
  8691. delete curData.handle;
  8692. curData.events = {};
  8693. for ( type in events ) {
  8694. for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  8695. jQuery.event.add( dest, type, events[ type ][ i ] );
  8696. }
  8697. }
  8698. }
  8699. // make the cloned public data object a copy from the original
  8700. if ( curData.data ) {
  8701. curData.data = jQuery.extend( {}, curData.data );
  8702. }
  8703. }
  8704. function fixCloneNodeIssues( src, dest ) {
  8705. var nodeName, e, data;
  8706. // We do not need to do anything for non-Elements
  8707. if ( dest.nodeType !== 1 ) {
  8708. return;
  8709. }
  8710. nodeName = dest.nodeName.toLowerCase();
  8711. // IE6-8 copies events bound via attachEvent when using cloneNode.
  8712. if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
  8713. data = jQuery._data( dest );
  8714. for ( e in data.events ) {
  8715. jQuery.removeEvent( dest, e, data.handle );
  8716. }
  8717. // Event data gets referenced instead of copied if the expando gets copied too
  8718. dest.removeAttribute( jQuery.expando );
  8719. }
  8720. // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
  8721. if ( nodeName === "script" && dest.text !== src.text ) {
  8722. disableScript( dest ).text = src.text;
  8723. restoreScript( dest );
  8724. // IE6-10 improperly clones children of object elements using classid.
  8725. // IE10 throws NoModificationAllowedError if parent is null, #12132.
  8726. } else if ( nodeName === "object" ) {
  8727. if ( dest.parentNode ) {
  8728. dest.outerHTML = src.outerHTML;
  8729. }
  8730. // This path appears unavoidable for IE9. When cloning an object
  8731. // element in IE9, the outerHTML strategy above is not sufficient.
  8732. // If the src has innerHTML and the destination does not,
  8733. // copy the src.innerHTML into the dest.innerHTML. #10324
  8734. if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
  8735. dest.innerHTML = src.innerHTML;
  8736. }
  8737. } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
  8738. // IE6-8 fails to persist the checked state of a cloned checkbox
  8739. // or radio button. Worse, IE6-7 fail to give the cloned element
  8740. // a checked appearance if the defaultChecked value isn't also set
  8741. dest.defaultChecked = dest.checked = src.checked;
  8742. // IE6-7 get confused and end up setting the value of a cloned
  8743. // checkbox/radio button to an empty string instead of "on"
  8744. if ( dest.value !== src.value ) {
  8745. dest.value = src.value;
  8746. }
  8747. // IE6-8 fails to return the selected option to the default selected
  8748. // state when cloning options
  8749. } else if ( nodeName === "option" ) {
  8750. dest.defaultSelected = dest.selected = src.defaultSelected;
  8751. // IE6-8 fails to set the defaultValue to the correct value when
  8752. // cloning other types of input fields
  8753. } else if ( nodeName === "input" || nodeName === "textarea" ) {
  8754. dest.defaultValue = src.defaultValue;
  8755. }
  8756. }
  8757. jQuery.each({
  8758. appendTo: "append",
  8759. prependTo: "prepend",
  8760. insertBefore: "before",
  8761. insertAfter: "after",
  8762. replaceAll: "replaceWith"
  8763. }, function( name, original ) {
  8764. jQuery.fn[ name ] = function( selector ) {
  8765. var elems,
  8766. i = 0,
  8767. ret = [],
  8768. insert = jQuery( selector ),
  8769. last = insert.length - 1;
  8770. for ( ; i <= last; i++ ) {
  8771. elems = i === last ? this : this.clone(true);
  8772. jQuery( insert[i] )[ original ]( elems );
  8773. // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
  8774. core_push.apply( ret, elems.get() );
  8775. }
  8776. return this.pushStack( ret );
  8777. };
  8778. });
  8779. function getAll( context, tag ) {
  8780. var elems, elem,
  8781. i = 0,
  8782. found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
  8783. typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
  8784. undefined;
  8785. if ( !found ) {
  8786. for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
  8787. if ( !tag || jQuery.nodeName( elem, tag ) ) {
  8788. found.push( elem );
  8789. } else {
  8790. jQuery.merge( found, getAll( elem, tag ) );
  8791. }
  8792. }
  8793. }
  8794. return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  8795. jQuery.merge( [ context ], found ) :
  8796. found;
  8797. }
  8798. // Used in buildFragment, fixes the defaultChecked property
  8799. function fixDefaultChecked( elem ) {
  8800. if ( manipulation_rcheckableType.test( elem.type ) ) {
  8801. elem.defaultChecked = elem.checked;
  8802. }
  8803. }
  8804. jQuery.extend({
  8805. clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  8806. var destElements, node, clone, i, srcElements,
  8807. inPage = jQuery.contains( elem.ownerDocument, elem );
  8808. if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
  8809. clone = elem.cloneNode( true );
  8810. // IE<=8 does not properly clone detached, unknown element nodes
  8811. } else {
  8812. fragmentDiv.innerHTML = elem.outerHTML;
  8813. fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
  8814. }
  8815. if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
  8816. (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
  8817. // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
  8818. destElements = getAll( clone );
  8819. srcElements = getAll( elem );
  8820. // Fix all IE cloning issues
  8821. for ( i = 0; (node = srcElements[i]) != null; ++i ) {
  8822. // Ensure that the destination node is not null; Fixes #9587
  8823. if ( destElements[i] ) {
  8824. fixCloneNodeIssues( node, destElements[i] );
  8825. }
  8826. }
  8827. }
  8828. // Copy the events from the original to the clone
  8829. if ( dataAndEvents ) {
  8830. if ( deepDataAndEvents ) {
  8831. srcElements = srcElements || getAll( elem );
  8832. destElements = destElements || getAll( clone );
  8833. for ( i = 0; (node = srcElements[i]) != null; i++ ) {
  8834. cloneCopyEvent( node, destElements[i] );
  8835. }
  8836. } else {
  8837. cloneCopyEvent( elem, clone );
  8838. }
  8839. }
  8840. // Preserve script evaluation history
  8841. destElements = getAll( clone, "script" );
  8842. if ( destElements.length > 0 ) {
  8843. setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  8844. }
  8845. destElements = srcElements = node = null;
  8846. // Return the cloned set
  8847. return clone;
  8848. },
  8849. buildFragment: function( elems, context, scripts, selection ) {
  8850. var j, elem, contains,
  8851. tmp, tag, tbody, wrap,
  8852. l = elems.length,
  8853. // Ensure a safe fragment
  8854. safe = createSafeFragment( context ),
  8855. nodes = [],
  8856. i = 0;
  8857. for ( ; i < l; i++ ) {
  8858. elem = elems[ i ];
  8859. if ( elem || elem === 0 ) {
  8860. // Add nodes directly
  8861. if ( jQuery.type( elem ) === "object" ) {
  8862. jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  8863. // Convert non-html into a text node
  8864. } else if ( !rhtml.test( elem ) ) {
  8865. nodes.push( context.createTextNode( elem ) );
  8866. // Convert html into DOM nodes
  8867. } else {
  8868. tmp = tmp || safe.appendChild( context.createElement("div") );
  8869. // Deserialize a standard representation
  8870. tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
  8871. wrap = wrapMap[ tag ] || wrapMap._default;
  8872. tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
  8873. // Descend through wrappers to the right content
  8874. j = wrap[0];
  8875. while ( j-- ) {
  8876. tmp = tmp.lastChild;
  8877. }
  8878. // Manually add leading whitespace removed by IE
  8879. if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
  8880. nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
  8881. }
  8882. // Remove IE's autoinserted <tbody> from table fragments
  8883. if ( !jQuery.support.tbody ) {
  8884. // String was a <table>, *may* have spurious <tbody>
  8885. elem = tag === "table" && !rtbody.test( elem ) ?
  8886. tmp.firstChild :
  8887. // String was a bare <thead> or <tfoot>
  8888. wrap[1] === "<table>" && !rtbody.test( elem ) ?
  8889. tmp :
  8890. 0;
  8891. j = elem && elem.childNodes.length;
  8892. while ( j-- ) {
  8893. if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
  8894. elem.removeChild( tbody );
  8895. }
  8896. }
  8897. }
  8898. jQuery.merge( nodes, tmp.childNodes );
  8899. // Fix #12392 for WebKit and IE > 9
  8900. tmp.textContent = "";
  8901. // Fix #12392 for oldIE
  8902. while ( tmp.firstChild ) {
  8903. tmp.removeChild( tmp.firstChild );
  8904. }
  8905. // Remember the top-level container for proper cleanup
  8906. tmp = safe.lastChild;
  8907. }
  8908. }
  8909. }
  8910. // Fix #11356: Clear elements from fragment
  8911. if ( tmp ) {
  8912. safe.removeChild( tmp );
  8913. }
  8914. // Reset defaultChecked for any radios and checkboxes
  8915. // about to be appended to the DOM in IE 6/7 (#8060)
  8916. if ( !jQuery.support.appendChecked ) {
  8917. jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
  8918. }
  8919. i = 0;
  8920. while ( (elem = nodes[ i++ ]) ) {
  8921. // #4087 - If origin and destination elements are the same, and this is
  8922. // that element, do not do anything
  8923. if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
  8924. continue;
  8925. }
  8926. contains = jQuery.contains( elem.ownerDocument, elem );
  8927. // Append to fragment
  8928. tmp = getAll( safe.appendChild( elem ), "script" );
  8929. // Preserve script evaluation history
  8930. if ( contains ) {
  8931. setGlobalEval( tmp );
  8932. }
  8933. // Capture executables
  8934. if ( scripts ) {
  8935. j = 0;
  8936. while ( (elem = tmp[ j++ ]) ) {
  8937. if ( rscriptType.test( elem.type || "" ) ) {
  8938. scripts.push( elem );
  8939. }
  8940. }
  8941. }
  8942. }
  8943. tmp = null;
  8944. return safe;
  8945. },
  8946. cleanData: function( elems, /* internal */ acceptData ) {
  8947. var elem, type, id, data,
  8948. i = 0,
  8949. internalKey = jQuery.expando,
  8950. cache = jQuery.cache,
  8951. deleteExpando = jQuery.support.deleteExpando,
  8952. special = jQuery.event.special;
  8953. for ( ; (elem = elems[i]) != null; i++ ) {
  8954. if ( acceptData || jQuery.acceptData( elem ) ) {
  8955. id = elem[ internalKey ];
  8956. data = id && cache[ id ];
  8957. if ( data ) {
  8958. if ( data.events ) {
  8959. for ( type in data.events ) {
  8960. if ( special[ type ] ) {
  8961. jQuery.event.remove( elem, type );
  8962. // This is a shortcut to avoid jQuery.event.remove's overhead
  8963. } else {
  8964. jQuery.removeEvent( elem, type, data.handle );
  8965. }
  8966. }
  8967. }
  8968. // Remove cache only if it was not already removed by jQuery.event.remove
  8969. if ( cache[ id ] ) {
  8970. delete cache[ id ];
  8971. // IE does not allow us to delete expando properties from nodes,
  8972. // nor does it have a removeAttribute function on Document nodes;
  8973. // we must handle all of these cases
  8974. if ( deleteExpando ) {
  8975. delete elem[ internalKey ];
  8976. } else if ( typeof elem.removeAttribute !== core_strundefined ) {
  8977. elem.removeAttribute( internalKey );
  8978. } else {
  8979. elem[ internalKey ] = null;
  8980. }
  8981. core_deletedIds.push( id );
  8982. }
  8983. }
  8984. }
  8985. }
  8986. },
  8987. _evalUrl: function( url ) {
  8988. return jQuery.ajax({
  8989. url: url,
  8990. type: "GET",
  8991. dataType: "script",
  8992. async: false,
  8993. global: false,
  8994. "throws": true
  8995. });
  8996. }
  8997. });
  8998. jQuery.fn.extend({
  8999. wrapAll: function( html ) {
  9000. if ( jQuery.isFunction( html ) ) {
  9001. return this.each(function(i) {
  9002. jQuery(this).wrapAll( html.call(this, i) );
  9003. });
  9004. }
  9005. if ( this[0] ) {
  9006. // The elements to wrap the target around
  9007. var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
  9008. if ( this[0].parentNode ) {
  9009. wrap.insertBefore( this[0] );
  9010. }
  9011. wrap.map(function() {
  9012. var elem = this;
  9013. while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
  9014. elem = elem.firstChild;
  9015. }
  9016. return elem;
  9017. }).append( this );
  9018. }
  9019. return this;
  9020. },
  9021. wrapInner: function( html ) {
  9022. if ( jQuery.isFunction( html ) ) {
  9023. return this.each(function(i) {
  9024. jQuery(this).wrapInner( html.call(this, i) );
  9025. });
  9026. }
  9027. return this.each(function() {
  9028. var self = jQuery( this ),
  9029. contents = self.contents();
  9030. if ( contents.length ) {
  9031. contents.wrapAll( html );
  9032. } else {
  9033. self.append( html );
  9034. }
  9035. });
  9036. },
  9037. wrap: function( html ) {
  9038. var isFunction = jQuery.isFunction( html );
  9039. return this.each(function(i) {
  9040. jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
  9041. });
  9042. },
  9043. unwrap: function() {
  9044. return this.parent().each(function() {
  9045. if ( !jQuery.nodeName( this, "body" ) ) {
  9046. jQuery( this ).replaceWith( this.childNodes );
  9047. }
  9048. }).end();
  9049. }
  9050. });
  9051. var iframe, getStyles, curCSS,
  9052. ralpha = /alpha\([^)]*\)/i,
  9053. ropacity = /opacity\s*=\s*([^)]*)/,
  9054. rposition = /^(top|right|bottom|left)$/,
  9055. // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
  9056. // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  9057. rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  9058. rmargin = /^margin/,
  9059. rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
  9060. rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
  9061. rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
  9062. elemdisplay = { BODY: "block" },
  9063. cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  9064. cssNormalTransform = {
  9065. letterSpacing: 0,
  9066. fontWeight: 400
  9067. },
  9068. cssExpand = [ "Top", "Right", "Bottom", "Left" ],
  9069. cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
  9070. // return a css property mapped to a potentially vendor prefixed property
  9071. function vendorPropName( style, name ) {
  9072. // shortcut for names that are not vendor prefixed
  9073. if ( name in style ) {
  9074. return name;
  9075. }
  9076. // check for vendor prefixed names
  9077. var capName = name.charAt(0).toUpperCase() + name.slice(1),
  9078. origName = name,
  9079. i = cssPrefixes.length;
  9080. while ( i-- ) {
  9081. name = cssPrefixes[ i ] + capName;
  9082. if ( name in style ) {
  9083. return name;
  9084. }
  9085. }
  9086. return origName;
  9087. }
  9088. function isHidden( elem, el ) {
  9089. // isHidden might be called from jQuery#filter function;
  9090. // in that case, element will be second argument
  9091. elem = el || elem;
  9092. return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
  9093. }
  9094. function showHide( elements, show ) {
  9095. var display, elem, hidden,
  9096. values = [],
  9097. index = 0,
  9098. length = elements.length;
  9099. for ( ; index < length; index++ ) {
  9100. elem = elements[ index ];
  9101. if ( !elem.style ) {
  9102. continue;
  9103. }
  9104. values[ index ] = jQuery._data( elem, "olddisplay" );
  9105. display = elem.style.display;
  9106. if ( show ) {
  9107. // Reset the inline display of this element to learn if it is
  9108. // being hidden by cascaded rules or not
  9109. if ( !values[ index ] && display === "none" ) {
  9110. elem.style.display = "";
  9111. }
  9112. // Set elements which have been overridden with display: none
  9113. // in a stylesheet to whatever the default browser style is
  9114. // for such an element
  9115. if ( elem.style.display === "" && isHidden( elem ) ) {
  9116. values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
  9117. }
  9118. } else {
  9119. if ( !values[ index ] ) {
  9120. hidden = isHidden( elem );
  9121. if ( display && display !== "none" || !hidden ) {
  9122. jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
  9123. }
  9124. }
  9125. }
  9126. }
  9127. // Set the display of most of the elements in a second loop
  9128. // to avoid the constant reflow
  9129. for ( index = 0; index < length; index++ ) {
  9130. elem = elements[ index ];
  9131. if ( !elem.style ) {
  9132. continue;
  9133. }
  9134. if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  9135. elem.style.display = show ? values[ index ] || "" : "none";
  9136. }
  9137. }
  9138. return elements;
  9139. }
  9140. jQuery.fn.extend({
  9141. css: function( name, value ) {
  9142. return jQuery.access( this, function( elem, name, value ) {
  9143. var len, styles,
  9144. map = {},
  9145. i = 0;
  9146. if ( jQuery.isArray( name ) ) {
  9147. styles = getStyles( elem );
  9148. len = name.length;
  9149. for ( ; i < len; i++ ) {
  9150. map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  9151. }
  9152. return map;
  9153. }
  9154. return value !== undefined ?
  9155. jQuery.style( elem, name, value ) :
  9156. jQuery.css( elem, name );
  9157. }, name, value, arguments.length > 1 );
  9158. },
  9159. show: function() {
  9160. return showHide( this, true );
  9161. },
  9162. hide: function() {
  9163. return showHide( this );
  9164. },
  9165. toggle: function( state ) {
  9166. if ( typeof state === "boolean" ) {
  9167. return state ? this.show() : this.hide();
  9168. }
  9169. return this.each(function() {
  9170. if ( isHidden( this ) ) {
  9171. jQuery( this ).show();
  9172. } else {
  9173. jQuery( this ).hide();
  9174. }
  9175. });
  9176. }
  9177. });
  9178. jQuery.extend({
  9179. // Add in style property hooks for overriding the default
  9180. // behavior of getting and setting a style property
  9181. cssHooks: {
  9182. opacity: {
  9183. get: function( elem, computed ) {
  9184. if ( computed ) {
  9185. // We should always get a number back from opacity
  9186. var ret = curCSS( elem, "opacity" );
  9187. return ret === "" ? "1" : ret;
  9188. }
  9189. }
  9190. }
  9191. },
  9192. // Don't automatically add "px" to these possibly-unitless properties
  9193. cssNumber: {
  9194. "columnCount": true,
  9195. "fillOpacity": true,
  9196. "fontWeight": true,
  9197. "lineHeight": true,
  9198. "opacity": true,
  9199. "order": true,
  9200. "orphans": true,
  9201. "widows": true,
  9202. "zIndex": true,
  9203. "zoom": true
  9204. },
  9205. // Add in properties whose names you wish to fix before
  9206. // setting or getting the value
  9207. cssProps: {
  9208. // normalize float css property
  9209. "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
  9210. },
  9211. // Get and set the style property on a DOM Node
  9212. style: function( elem, name, value, extra ) {
  9213. // Don't set styles on text and comment nodes
  9214. if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  9215. return;
  9216. }
  9217. // Make sure that we're working with the right name
  9218. var ret, type, hooks,
  9219. origName = jQuery.camelCase( name ),
  9220. style = elem.style;
  9221. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
  9222. // gets hook for the prefixed version
  9223. // followed by the unprefixed version
  9224. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  9225. // Check if we're setting a value
  9226. if ( value !== undefined ) {
  9227. type = typeof value;
  9228. // convert relative number strings (+= or -=) to relative numbers. #7345
  9229. if ( type === "string" && (ret = rrelNum.exec( value )) ) {
  9230. value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
  9231. // Fixes bug #9237
  9232. type = "number";
  9233. }
  9234. // Make sure that NaN and null values aren't set. See: #7116
  9235. if ( value == null || type === "number" && isNaN( value ) ) {
  9236. return;
  9237. }
  9238. // If a number was passed in, add 'px' to the (except for certain CSS properties)
  9239. if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
  9240. value += "px";
  9241. }
  9242. // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
  9243. // but it would mean to define eight (for every problematic property) identical functions
  9244. if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
  9245. style[ name ] = "inherit";
  9246. }
  9247. // If a hook was provided, use that value, otherwise just set the specified value
  9248. if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
  9249. // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
  9250. // Fixes bug #5509
  9251. try {
  9252. style[ name ] = value;
  9253. } catch(e) {}
  9254. }
  9255. } else {
  9256. // If a hook was provided get the non-computed value from there
  9257. if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
  9258. return ret;
  9259. }
  9260. // Otherwise just get the value from the style object
  9261. return style[ name ];
  9262. }
  9263. },
  9264. css: function( elem, name, extra, styles ) {
  9265. var num, val, hooks,
  9266. origName = jQuery.camelCase( name );
  9267. // Make sure that we're working with the right name
  9268. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
  9269. // gets hook for the prefixed version
  9270. // followed by the unprefixed version
  9271. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  9272. // If a hook was provided get the computed value from there
  9273. if ( hooks && "get" in hooks ) {
  9274. val = hooks.get( elem, true, extra );
  9275. }
  9276. // Otherwise, if a way to get the computed value exists, use that
  9277. if ( val === undefined ) {
  9278. val = curCSS( elem, name, styles );
  9279. }
  9280. //convert "normal" to computed value
  9281. if ( val === "normal" && name in cssNormalTransform ) {
  9282. val = cssNormalTransform[ name ];
  9283. }
  9284. // Return, converting to number if forced or a qualifier was provided and val looks numeric
  9285. if ( extra === "" || extra ) {
  9286. num = parseFloat( val );
  9287. return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
  9288. }
  9289. return val;
  9290. }
  9291. });
  9292. // NOTE: we've included the "window" in window.getComputedStyle
  9293. // because jsdom on node.js will break without it.
  9294. if ( window.getComputedStyle ) {
  9295. getStyles = function( elem ) {
  9296. return window.getComputedStyle( elem, null );
  9297. };
  9298. curCSS = function( elem, name, _computed ) {
  9299. var width, minWidth, maxWidth,
  9300. computed = _computed || getStyles( elem ),
  9301. // getPropertyValue is only needed for .css('filter') in IE9, see #12537
  9302. ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
  9303. style = elem.style;
  9304. if ( computed ) {
  9305. if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  9306. ret = jQuery.style( elem, name );
  9307. }
  9308. // A tribute to the "awesome hack by Dean Edwards"
  9309. // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
  9310. // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
  9311. // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
  9312. if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  9313. // Remember the original values
  9314. width = style.width;
  9315. minWidth = style.minWidth;
  9316. maxWidth = style.maxWidth;
  9317. // Put in the new values to get a computed value out
  9318. style.minWidth = style.maxWidth = style.width = ret;
  9319. ret = computed.width;
  9320. // Revert the changed values
  9321. style.width = width;
  9322. style.minWidth = minWidth;
  9323. style.maxWidth = maxWidth;
  9324. }
  9325. }
  9326. return ret;
  9327. };
  9328. } else if ( document.documentElement.currentStyle ) {
  9329. getStyles = function( elem ) {
  9330. return elem.currentStyle;
  9331. };
  9332. curCSS = function( elem, name, _computed ) {
  9333. var left, rs, rsLeft,
  9334. computed = _computed || getStyles( elem ),
  9335. ret = computed ? computed[ name ] : undefined,
  9336. style = elem.style;
  9337. // Avoid setting ret to empty string here
  9338. // so we don't default to auto
  9339. if ( ret == null && style && style[ name ] ) {
  9340. ret = style[ name ];
  9341. }
  9342. // From the awesome hack by Dean Edwards
  9343. // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  9344. // If we're not dealing with a regular pixel number
  9345. // but a number that has a weird ending, we need to convert it to pixels
  9346. // but not position css attributes, as those are proportional to the parent element instead
  9347. // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
  9348. if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
  9349. // Remember the original values
  9350. left = style.left;
  9351. rs = elem.runtimeStyle;
  9352. rsLeft = rs && rs.left;
  9353. // Put in the new values to get a computed value out
  9354. if ( rsLeft ) {
  9355. rs.left = elem.currentStyle.left;
  9356. }
  9357. style.left = name === "fontSize" ? "1em" : ret;
  9358. ret = style.pixelLeft + "px";
  9359. // Revert the changed values
  9360. style.left = left;
  9361. if ( rsLeft ) {
  9362. rs.left = rsLeft;
  9363. }
  9364. }
  9365. return ret === "" ? "auto" : ret;
  9366. };
  9367. }
  9368. function setPositiveNumber( elem, value, subtract ) {
  9369. var matches = rnumsplit.exec( value );
  9370. return matches ?
  9371. // Guard against undefined "subtract", e.g., when used as in cssHooks
  9372. Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
  9373. value;
  9374. }
  9375. function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  9376. var i = extra === ( isBorderBox ? "border" : "content" ) ?
  9377. // If we already have the right measurement, avoid augmentation
  9378. 4 :
  9379. // Otherwise initialize for horizontal or vertical properties
  9380. name === "width" ? 1 : 0,
  9381. val = 0;
  9382. for ( ; i < 4; i += 2 ) {
  9383. // both box models exclude margin, so add it if we want it
  9384. if ( extra === "margin" ) {
  9385. val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  9386. }
  9387. if ( isBorderBox ) {
  9388. // border-box includes padding, so remove it if we want content
  9389. if ( extra === "content" ) {
  9390. val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  9391. }
  9392. // at this point, extra isn't border nor margin, so remove border
  9393. if ( extra !== "margin" ) {
  9394. val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  9395. }
  9396. } else {
  9397. // at this point, extra isn't content, so add padding
  9398. val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  9399. // at this point, extra isn't content nor padding, so add border
  9400. if ( extra !== "padding" ) {
  9401. val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  9402. }
  9403. }
  9404. }
  9405. return val;
  9406. }
  9407. function getWidthOrHeight( elem, name, extra ) {
  9408. // Start with offset property, which is equivalent to the border-box value
  9409. var valueIsBorderBox = true,
  9410. val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  9411. styles = getStyles( elem ),
  9412. isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  9413. // some non-html elements return undefined for offsetWidth, so check for null/undefined
  9414. // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  9415. // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  9416. if ( val <= 0 || val == null ) {
  9417. // Fall back to computed then uncomputed css if necessary
  9418. val = curCSS( elem, name, styles );
  9419. if ( val < 0 || val == null ) {
  9420. val = elem.style[ name ];
  9421. }
  9422. // Computed unit is not pixels. Stop here and return.
  9423. if ( rnumnonpx.test(val) ) {
  9424. return val;
  9425. }
  9426. // we need the check for style in case a browser which returns unreliable values
  9427. // for getComputedStyle silently falls back to the reliable elem.style
  9428. valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
  9429. // Normalize "", auto, and prepare for extra
  9430. val = parseFloat( val ) || 0;
  9431. }
  9432. // use the active box-sizing model to add/subtract irrelevant styles
  9433. return ( val +
  9434. augmentWidthOrHeight(
  9435. elem,
  9436. name,
  9437. extra || ( isBorderBox ? "border" : "content" ),
  9438. valueIsBorderBox,
  9439. styles
  9440. )
  9441. ) + "px";
  9442. }
  9443. // Try to determine the default display value of an element
  9444. function css_defaultDisplay( nodeName ) {
  9445. var doc = document,
  9446. display = elemdisplay[ nodeName ];
  9447. if ( !display ) {
  9448. display = actualDisplay( nodeName, doc );
  9449. // If the simple way fails, read from inside an iframe
  9450. if ( display === "none" || !display ) {
  9451. // Use the already-created iframe if possible
  9452. iframe = ( iframe ||
  9453. jQuery("<iframe frameborder='0' width='0' height='0'/>")
  9454. .css( "cssText", "display:block !important" )
  9455. ).appendTo( doc.documentElement );
  9456. // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
  9457. doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
  9458. doc.write("<!doctype html><html><body>");
  9459. doc.close();
  9460. display = actualDisplay( nodeName, doc );
  9461. iframe.detach();
  9462. }
  9463. // Store the correct default display
  9464. elemdisplay[ nodeName ] = display;
  9465. }
  9466. return display;
  9467. }
  9468. // Called ONLY from within css_defaultDisplay
  9469. function actualDisplay( name, doc ) {
  9470. var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
  9471. display = jQuery.css( elem[0], "display" );
  9472. elem.remove();
  9473. return display;
  9474. }
  9475. jQuery.each([ "height", "width" ], function( i, name ) {
  9476. jQuery.cssHooks[ name ] = {
  9477. get: function( elem, computed, extra ) {
  9478. if ( computed ) {
  9479. // certain elements can have dimension info if we invisibly show them
  9480. // however, it must have a current display style that would benefit from this
  9481. return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
  9482. jQuery.swap( elem, cssShow, function() {
  9483. return getWidthOrHeight( elem, name, extra );
  9484. }) :
  9485. getWidthOrHeight( elem, name, extra );
  9486. }
  9487. },
  9488. set: function( elem, value, extra ) {
  9489. var styles = extra && getStyles( elem );
  9490. return setPositiveNumber( elem, value, extra ?
  9491. augmentWidthOrHeight(
  9492. elem,
  9493. name,
  9494. extra,
  9495. jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  9496. styles
  9497. ) : 0
  9498. );
  9499. }
  9500. };
  9501. });
  9502. if ( !jQuery.support.opacity ) {
  9503. jQuery.cssHooks.opacity = {
  9504. get: function( elem, computed ) {
  9505. // IE uses filters for opacity
  9506. return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
  9507. ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
  9508. computed ? "1" : "";
  9509. },
  9510. set: function( elem, value ) {
  9511. var style = elem.style,
  9512. currentStyle = elem.currentStyle,
  9513. opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
  9514. filter = currentStyle && currentStyle.filter || style.filter || "";
  9515. // IE has trouble with opacity if it does not have layout
  9516. // Force it by setting the zoom level
  9517. style.zoom = 1;
  9518. // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
  9519. // if value === "", then remove inline opacity #12685
  9520. if ( ( value >= 1 || value === "" ) &&
  9521. jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
  9522. style.removeAttribute ) {
  9523. // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
  9524. // if "filter:" is present at all, clearType is disabled, we want to avoid this
  9525. // style.removeAttribute is IE Only, but so apparently is this code path...
  9526. style.removeAttribute( "filter" );
  9527. // if there is no filter style applied in a css rule or unset inline opacity, we are done
  9528. if ( value === "" || currentStyle && !currentStyle.filter ) {
  9529. return;
  9530. }
  9531. }
  9532. // otherwise, set new filter values
  9533. style.filter = ralpha.test( filter ) ?
  9534. filter.replace( ralpha, opacity ) :
  9535. filter + " " + opacity;
  9536. }
  9537. };
  9538. }
  9539. // These hooks cannot be added until DOM ready because the support test
  9540. // for it is not run until after DOM ready
  9541. jQuery(function() {
  9542. if ( !jQuery.support.reliableMarginRight ) {
  9543. jQuery.cssHooks.marginRight = {
  9544. get: function( elem, computed ) {
  9545. if ( computed ) {
  9546. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  9547. // Work around by temporarily setting element display to inline-block
  9548. return jQuery.swap( elem, { "display": "inline-block" },
  9549. curCSS, [ elem, "marginRight" ] );
  9550. }
  9551. }
  9552. };
  9553. }
  9554. // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  9555. // getComputedStyle returns percent when specified for top/left/bottom/right
  9556. // rather than make the css module depend on the offset module, we just check for it here
  9557. if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
  9558. jQuery.each( [ "top", "left" ], function( i, prop ) {
  9559. jQuery.cssHooks[ prop ] = {
  9560. get: function( elem, computed ) {
  9561. if ( computed ) {
  9562. computed = curCSS( elem, prop );
  9563. // if curCSS returns percentage, fallback to offset
  9564. return rnumnonpx.test( computed ) ?
  9565. jQuery( elem ).position()[ prop ] + "px" :
  9566. computed;
  9567. }
  9568. }
  9569. };
  9570. });
  9571. }
  9572. });
  9573. if ( jQuery.expr && jQuery.expr.filters ) {
  9574. jQuery.expr.filters.hidden = function( elem ) {
  9575. // Support: Opera <= 12.12
  9576. // Opera reports offsetWidths and offsetHeights less than zero on some elements
  9577. return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
  9578. (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
  9579. };
  9580. jQuery.expr.filters.visible = function( elem ) {
  9581. return !jQuery.expr.filters.hidden( elem );
  9582. };
  9583. }
  9584. // These hooks are used by animate to expand properties
  9585. jQuery.each({
  9586. margin: "",
  9587. padding: "",
  9588. border: "Width"
  9589. }, function( prefix, suffix ) {
  9590. jQuery.cssHooks[ prefix + suffix ] = {
  9591. expand: function( value ) {
  9592. var i = 0,
  9593. expanded = {},
  9594. // assumes a single number if not a string
  9595. parts = typeof value === "string" ? value.split(" ") : [ value ];
  9596. for ( ; i < 4; i++ ) {
  9597. expanded[ prefix + cssExpand[ i ] + suffix ] =
  9598. parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  9599. }
  9600. return expanded;
  9601. }
  9602. };
  9603. if ( !rmargin.test( prefix ) ) {
  9604. jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  9605. }
  9606. });
  9607. var r20 = /%20/g,
  9608. rbracket = /\[\]$/,
  9609. rCRLF = /\r?\n/g,
  9610. rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  9611. rsubmittable = /^(?:input|select|textarea|keygen)/i;
  9612. jQuery.fn.extend({
  9613. serialize: function() {
  9614. return jQuery.param( this.serializeArray() );
  9615. },
  9616. serializeArray: function() {
  9617. return this.map(function(){
  9618. // Can add propHook for "elements" to filter or add form elements
  9619. var elements = jQuery.prop( this, "elements" );
  9620. return elements ? jQuery.makeArray( elements ) : this;
  9621. })
  9622. .filter(function(){
  9623. var type = this.type;
  9624. // Use .is(":disabled") so that fieldset[disabled] works
  9625. return this.name && !jQuery( this ).is( ":disabled" ) &&
  9626. rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  9627. ( this.checked || !manipulation_rcheckableType.test( type ) );
  9628. })
  9629. .map(function( i, elem ){
  9630. var val = jQuery( this ).val();
  9631. return val == null ?
  9632. null :
  9633. jQuery.isArray( val ) ?
  9634. jQuery.map( val, function( val ){
  9635. return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  9636. }) :
  9637. { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  9638. }).get();
  9639. }
  9640. });
  9641. //Serialize an array of form elements or a set of
  9642. //key/values into a query string
  9643. jQuery.param = function( a, traditional ) {
  9644. var prefix,
  9645. s = [],
  9646. add = function( key, value ) {
  9647. // If value is a function, invoke it and return its value
  9648. value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
  9649. s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
  9650. };
  9651. // Set traditional to true for jQuery <= 1.3.2 behavior.
  9652. if ( traditional === undefined ) {
  9653. traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  9654. }
  9655. // If an array was passed in, assume that it is an array of form elements.
  9656. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  9657. // Serialize the form elements
  9658. jQuery.each( a, function() {
  9659. add( this.name, this.value );
  9660. });
  9661. } else {
  9662. // If traditional, encode the "old" way (the way 1.3.2 or older
  9663. // did it), otherwise encode params recursively.
  9664. for ( prefix in a ) {
  9665. buildParams( prefix, a[ prefix ], traditional, add );
  9666. }
  9667. }
  9668. // Return the resulting serialization
  9669. return s.join( "&" ).replace( r20, "+" );
  9670. };
  9671. function buildParams( prefix, obj, traditional, add ) {
  9672. var name;
  9673. if ( jQuery.isArray( obj ) ) {
  9674. // Serialize array item.
  9675. jQuery.each( obj, function( i, v ) {
  9676. if ( traditional || rbracket.test( prefix ) ) {
  9677. // Treat each array item as a scalar.
  9678. add( prefix, v );
  9679. } else {
  9680. // Item is non-scalar (array or object), encode its numeric index.
  9681. buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
  9682. }
  9683. });
  9684. } else if ( !traditional && jQuery.type( obj ) === "object" ) {
  9685. // Serialize object item.
  9686. for ( name in obj ) {
  9687. buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  9688. }
  9689. } else {
  9690. // Serialize scalar item.
  9691. add( prefix, obj );
  9692. }
  9693. }
  9694. jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
  9695. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  9696. "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
  9697. // Handle event binding
  9698. jQuery.fn[ name ] = function( data, fn ) {
  9699. return arguments.length > 0 ?
  9700. this.on( name, null, data, fn ) :
  9701. this.trigger( name );
  9702. };
  9703. });
  9704. jQuery.fn.extend({
  9705. hover: function( fnOver, fnOut ) {
  9706. return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  9707. },
  9708. bind: function( types, data, fn ) {
  9709. return this.on( types, null, data, fn );
  9710. },
  9711. unbind: function( types, fn ) {
  9712. return this.off( types, null, fn );
  9713. },
  9714. delegate: function( selector, types, data, fn ) {
  9715. return this.on( types, selector, data, fn );
  9716. },
  9717. undelegate: function( selector, types, fn ) {
  9718. // ( namespace ) or ( selector, types [, fn] )
  9719. return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
  9720. }
  9721. });
  9722. var
  9723. // Document location
  9724. ajaxLocParts,
  9725. ajaxLocation,
  9726. ajax_nonce = jQuery.now(),
  9727. ajax_rquery = /\?/,
  9728. rhash = /#.*$/,
  9729. rts = /([?&])_=[^&]*/,
  9730. rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
  9731. // #7653, #8125, #8152: local protocol detection
  9732. rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  9733. rnoContent = /^(?:GET|HEAD)$/,
  9734. rprotocol = /^\/\//,
  9735. rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
  9736. // Keep a copy of the old load method
  9737. _load = jQuery.fn.load,
  9738. /* Prefilters
  9739. * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  9740. * 2) These are called:
  9741. * - BEFORE asking for a transport
  9742. * - AFTER param serialization (s.data is a string if s.processData is true)
  9743. * 3) key is the dataType
  9744. * 4) the catchall symbol "*" can be used
  9745. * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  9746. */
  9747. prefilters = {},
  9748. /* Transports bindings
  9749. * 1) key is the dataType
  9750. * 2) the catchall symbol "*" can be used
  9751. * 3) selection will start with transport dataType and THEN go to "*" if needed
  9752. */
  9753. transports = {},
  9754. // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  9755. allTypes = "*/".concat("*");
  9756. // #8138, IE may throw an exception when accessing
  9757. // a field from window.location if document.domain has been set
  9758. try {
  9759. ajaxLocation = location.href;
  9760. } catch( e ) {
  9761. // Use the href attribute of an A element
  9762. // since IE will modify it given document.location
  9763. ajaxLocation = document.createElement( "a" );
  9764. ajaxLocation.href = "";
  9765. ajaxLocation = ajaxLocation.href;
  9766. }
  9767. // Segment location into parts
  9768. ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
  9769. // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  9770. function addToPrefiltersOrTransports( structure ) {
  9771. // dataTypeExpression is optional and defaults to "*"
  9772. return function( dataTypeExpression, func ) {
  9773. if ( typeof dataTypeExpression !== "string" ) {
  9774. func = dataTypeExpression;
  9775. dataTypeExpression = "*";
  9776. }
  9777. var dataType,
  9778. i = 0,
  9779. dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
  9780. if ( jQuery.isFunction( func ) ) {
  9781. // For each dataType in the dataTypeExpression
  9782. while ( (dataType = dataTypes[i++]) ) {
  9783. // Prepend if requested
  9784. if ( dataType[0] === "+" ) {
  9785. dataType = dataType.slice( 1 ) || "*";
  9786. (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
  9787. // Otherwise append
  9788. } else {
  9789. (structure[ dataType ] = structure[ dataType ] || []).push( func );
  9790. }
  9791. }
  9792. }
  9793. };
  9794. }
  9795. // Base inspection function for prefilters and transports
  9796. function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  9797. var inspected = {},
  9798. seekingTransport = ( structure === transports );
  9799. function inspect( dataType ) {
  9800. var selected;
  9801. inspected[ dataType ] = true;
  9802. jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  9803. var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  9804. if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  9805. options.dataTypes.unshift( dataTypeOrTransport );
  9806. inspect( dataTypeOrTransport );
  9807. return false;
  9808. } else if ( seekingTransport ) {
  9809. return !( selected = dataTypeOrTransport );
  9810. }
  9811. });
  9812. return selected;
  9813. }
  9814. return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  9815. }
  9816. // A special extend for ajax options
  9817. // that takes "flat" options (not to be deep extended)
  9818. // Fixes #9887
  9819. function ajaxExtend( target, src ) {
  9820. var deep, key,
  9821. flatOptions = jQuery.ajaxSettings.flatOptions || {};
  9822. for ( key in src ) {
  9823. if ( src[ key ] !== undefined ) {
  9824. ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
  9825. }
  9826. }
  9827. if ( deep ) {
  9828. jQuery.extend( true, target, deep );
  9829. }
  9830. return target;
  9831. }
  9832. jQuery.fn.load = function( url, params, callback ) {
  9833. if ( typeof url !== "string" && _load ) {
  9834. return _load.apply( this, arguments );
  9835. }
  9836. var selector, response, type,
  9837. self = this,
  9838. off = url.indexOf(" ");
  9839. if ( off >= 0 ) {
  9840. selector = url.slice( off, url.length );
  9841. url = url.slice( 0, off );
  9842. }
  9843. // If it's a function
  9844. if ( jQuery.isFunction( params ) ) {
  9845. // We assume that it's the callback
  9846. callback = params;
  9847. params = undefined;
  9848. // Otherwise, build a param string
  9849. } else if ( params && typeof params === "object" ) {
  9850. type = "POST";
  9851. }
  9852. // If we have elements to modify, make the request
  9853. if ( self.length > 0 ) {
  9854. jQuery.ajax({
  9855. url: url,
  9856. // if "type" variable is undefined, then "GET" method will be used
  9857. type: type,
  9858. dataType: "html",
  9859. data: params
  9860. }).done(function( responseText ) {
  9861. // Save response for use in complete callback
  9862. response = arguments;
  9863. self.html( selector ?
  9864. // If a selector was specified, locate the right elements in a dummy div
  9865. // Exclude scripts to avoid IE 'Permission Denied' errors
  9866. jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
  9867. // Otherwise use the full result
  9868. responseText );
  9869. }).complete( callback && function( jqXHR, status ) {
  9870. self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
  9871. });
  9872. }
  9873. return this;
  9874. };
  9875. // Attach a bunch of functions for handling common AJAX events
  9876. jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
  9877. jQuery.fn[ type ] = function( fn ){
  9878. return this.on( type, fn );
  9879. };
  9880. });
  9881. jQuery.extend({
  9882. // Counter for holding the number of active queries
  9883. active: 0,
  9884. // Last-Modified header cache for next request
  9885. lastModified: {},
  9886. etag: {},
  9887. ajaxSettings: {
  9888. url: ajaxLocation,
  9889. type: "GET",
  9890. isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
  9891. global: true,
  9892. processData: true,
  9893. async: true,
  9894. contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  9895. /*
  9896. timeout: 0,
  9897. data: null,
  9898. dataType: null,
  9899. username: null,
  9900. password: null,
  9901. cache: null,
  9902. throws: false,
  9903. traditional: false,
  9904. headers: {},
  9905. */
  9906. accepts: {
  9907. "*": allTypes,
  9908. text: "text/plain",
  9909. html: "text/html",
  9910. xml: "application/xml, text/xml",
  9911. json: "application/json, text/javascript"
  9912. },
  9913. contents: {
  9914. xml: /xml/,
  9915. html: /html/,
  9916. json: /json/
  9917. },
  9918. responseFields: {
  9919. xml: "responseXML",
  9920. text: "responseText",
  9921. json: "responseJSON"
  9922. },
  9923. // Data converters
  9924. // Keys separate source (or catchall "*") and destination types with a single space
  9925. converters: {
  9926. // Convert anything to text
  9927. "* text": String,
  9928. // Text to html (true = no transformation)
  9929. "text html": true,
  9930. // Evaluate text as a json expression
  9931. "text json": jQuery.parseJSON,
  9932. // Parse text as xml
  9933. "text xml": jQuery.parseXML
  9934. },
  9935. // For options that shouldn't be deep extended:
  9936. // you can add your own custom options here if
  9937. // and when you create one that shouldn't be
  9938. // deep extended (see ajaxExtend)
  9939. flatOptions: {
  9940. url: true,
  9941. context: true
  9942. }
  9943. },
  9944. // Creates a full fledged settings object into target
  9945. // with both ajaxSettings and settings fields.
  9946. // If target is omitted, writes into ajaxSettings.
  9947. ajaxSetup: function( target, settings ) {
  9948. return settings ?
  9949. // Building a settings object
  9950. ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  9951. // Extending ajaxSettings
  9952. ajaxExtend( jQuery.ajaxSettings, target );
  9953. },
  9954. ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  9955. ajaxTransport: addToPrefiltersOrTransports( transports ),
  9956. // Main method
  9957. ajax: function( url, options ) {
  9958. // If url is an object, simulate pre-1.5 signature
  9959. if ( typeof url === "object" ) {
  9960. options = url;
  9961. url = undefined;
  9962. }
  9963. // Force options to be an object
  9964. options = options || {};
  9965. var // Cross-domain detection vars
  9966. parts,
  9967. // Loop variable
  9968. i,
  9969. // URL without anti-cache param
  9970. cacheURL,
  9971. // Response headers as string
  9972. responseHeadersString,
  9973. // timeout handle
  9974. timeoutTimer,
  9975. // To know if global events are to be dispatched
  9976. fireGlobals,
  9977. transport,
  9978. // Response headers
  9979. responseHeaders,
  9980. // Create the final options object
  9981. s = jQuery.ajaxSetup( {}, options ),
  9982. // Callbacks context
  9983. callbackContext = s.context || s,
  9984. // Context for global events is callbackContext if it is a DOM node or jQuery collection
  9985. globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
  9986. jQuery( callbackContext ) :
  9987. jQuery.event,
  9988. // Deferreds
  9989. deferred = jQuery.Deferred(),
  9990. completeDeferred = jQuery.Callbacks("once memory"),
  9991. // Status-dependent callbacks
  9992. statusCode = s.statusCode || {},
  9993. // Headers (they are sent all at once)
  9994. requestHeaders = {},
  9995. requestHeadersNames = {},
  9996. // The jqXHR state
  9997. state = 0,
  9998. // Default abort message
  9999. strAbort = "canceled",
  10000. // Fake xhr
  10001. jqXHR = {
  10002. readyState: 0,
  10003. // Builds headers hashtable if needed
  10004. getResponseHeader: function( key ) {
  10005. var match;
  10006. if ( state === 2 ) {
  10007. if ( !responseHeaders ) {
  10008. responseHeaders = {};
  10009. while ( (match = rheaders.exec( responseHeadersString )) ) {
  10010. responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
  10011. }
  10012. }
  10013. match = responseHeaders[ key.toLowerCase() ];
  10014. }
  10015. return match == null ? null : match;
  10016. },
  10017. // Raw string
  10018. getAllResponseHeaders: function() {
  10019. return state === 2 ? responseHeadersString : null;
  10020. },
  10021. // Caches the header
  10022. setRequestHeader: function( name, value ) {
  10023. var lname = name.toLowerCase();
  10024. if ( !state ) {
  10025. name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
  10026. requestHeaders[ name ] = value;
  10027. }
  10028. return this;
  10029. },
  10030. // Overrides response content-type header
  10031. overrideMimeType: function( type ) {
  10032. if ( !state ) {
  10033. s.mimeType = type;
  10034. }
  10035. return this;
  10036. },
  10037. // Status-dependent callbacks
  10038. statusCode: function( map ) {
  10039. var code;
  10040. if ( map ) {
  10041. if ( state < 2 ) {
  10042. for ( code in map ) {
  10043. // Lazy-add the new callback in a way that preserves old ones
  10044. statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  10045. }
  10046. } else {
  10047. // Execute the appropriate callbacks
  10048. jqXHR.always( map[ jqXHR.status ] );
  10049. }
  10050. }
  10051. return this;
  10052. },
  10053. // Cancel the request
  10054. abort: function( statusText ) {
  10055. var finalText = statusText || strAbort;
  10056. if ( transport ) {
  10057. transport.abort( finalText );
  10058. }
  10059. done( 0, finalText );
  10060. return this;
  10061. }
  10062. };
  10063. // Attach deferreds
  10064. deferred.promise( jqXHR ).complete = completeDeferred.add;
  10065. jqXHR.success = jqXHR.done;
  10066. jqXHR.error = jqXHR.fail;
  10067. // Remove hash character (#7531: and string promotion)
  10068. // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
  10069. // Handle falsy url in the settings object (#10093: consistency with old signature)
  10070. // We also use the url parameter if available
  10071. s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
  10072. // Alias method option to type as per ticket #12004
  10073. s.type = options.method || options.type || s.method || s.type;
  10074. // Extract dataTypes list
  10075. s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
  10076. // A cross-domain request is in order when we have a protocol:host:port mismatch
  10077. if ( s.crossDomain == null ) {
  10078. parts = rurl.exec( s.url.toLowerCase() );
  10079. s.crossDomain = !!( parts &&
  10080. ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
  10081. ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
  10082. ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
  10083. );
  10084. }
  10085. // Convert data if not already a string
  10086. if ( s.data && s.processData && typeof s.data !== "string" ) {
  10087. s.data = jQuery.param( s.data, s.traditional );
  10088. }
  10089. // Apply prefilters
  10090. inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  10091. // If request was aborted inside a prefilter, stop there
  10092. if ( state === 2 ) {
  10093. return jqXHR;
  10094. }
  10095. // We can fire global events as of now if asked to
  10096. fireGlobals = s.global;
  10097. // Watch for a new set of requests
  10098. if ( fireGlobals && jQuery.active++ === 0 ) {
  10099. jQuery.event.trigger("ajaxStart");
  10100. }
  10101. // Uppercase the type
  10102. s.type = s.type.toUpperCase();
  10103. // Determine if request has content
  10104. s.hasContent = !rnoContent.test( s.type );
  10105. // Save the URL in case we're toying with the If-Modified-Since
  10106. // and/or If-None-Match header later on
  10107. cacheURL = s.url;
  10108. // More options handling for requests with no content
  10109. if ( !s.hasContent ) {
  10110. // If data is available, append data to url
  10111. if ( s.data ) {
  10112. cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
  10113. // #9682: remove data so that it's not used in an eventual retry
  10114. delete s.data;
  10115. }
  10116. // Add anti-cache in url if needed
  10117. if ( s.cache === false ) {
  10118. s.url = rts.test( cacheURL ) ?
  10119. // If there is already a '_' parameter, set its value
  10120. cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
  10121. // Otherwise add one to the end
  10122. cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
  10123. }
  10124. }
  10125. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  10126. if ( s.ifModified ) {
  10127. if ( jQuery.lastModified[ cacheURL ] ) {
  10128. jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  10129. }
  10130. if ( jQuery.etag[ cacheURL ] ) {
  10131. jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  10132. }
  10133. }
  10134. // Set the correct header, if data is being sent
  10135. if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  10136. jqXHR.setRequestHeader( "Content-Type", s.contentType );
  10137. }
  10138. // Set the Accepts header for the server, depending on the dataType
  10139. jqXHR.setRequestHeader(
  10140. "Accept",
  10141. s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
  10142. s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  10143. s.accepts[ "*" ]
  10144. );
  10145. // Check for headers option
  10146. for ( i in s.headers ) {
  10147. jqXHR.setRequestHeader( i, s.headers[ i ] );
  10148. }
  10149. // Allow custom headers/mimetypes and early abort
  10150. if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
  10151. // Abort if not done already and return
  10152. return jqXHR.abort();
  10153. }
  10154. // aborting is no longer a cancellation
  10155. strAbort = "abort";
  10156. // Install callbacks on deferreds
  10157. for ( i in { success: 1, error: 1, complete: 1 } ) {
  10158. jqXHR[ i ]( s[ i ] );
  10159. }
  10160. // Get transport
  10161. transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  10162. // If no transport, we auto-abort
  10163. if ( !transport ) {
  10164. done( -1, "No Transport" );
  10165. } else {
  10166. jqXHR.readyState = 1;
  10167. // Send global event
  10168. if ( fireGlobals ) {
  10169. globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  10170. }
  10171. // Timeout
  10172. if ( s.async && s.timeout > 0 ) {
  10173. timeoutTimer = setTimeout(function() {
  10174. jqXHR.abort("timeout");
  10175. }, s.timeout );
  10176. }
  10177. try {
  10178. state = 1;
  10179. transport.send( requestHeaders, done );
  10180. } catch ( e ) {
  10181. // Propagate exception as error if not done
  10182. if ( state < 2 ) {
  10183. done( -1, e );
  10184. // Simply rethrow otherwise
  10185. } else {
  10186. throw e;
  10187. }
  10188. }
  10189. }
  10190. // Callback for when everything is done
  10191. function done( status, nativeStatusText, responses, headers ) {
  10192. var isSuccess, success, error, response, modified,
  10193. statusText = nativeStatusText;
  10194. // Called once
  10195. if ( state === 2 ) {
  10196. return;
  10197. }
  10198. // State is "done" now
  10199. state = 2;
  10200. // Clear timeout if it exists
  10201. if ( timeoutTimer ) {
  10202. clearTimeout( timeoutTimer );
  10203. }
  10204. // Dereference transport for early garbage collection
  10205. // (no matter how long the jqXHR object will be used)
  10206. transport = undefined;
  10207. // Cache response headers
  10208. responseHeadersString = headers || "";
  10209. // Set readyState
  10210. jqXHR.readyState = status > 0 ? 4 : 0;
  10211. // Determine if successful
  10212. isSuccess = status >= 200 && status < 300 || status === 304;
  10213. // Get response data
  10214. if ( responses ) {
  10215. response = ajaxHandleResponses( s, jqXHR, responses );
  10216. }
  10217. // Convert no matter what (that way responseXXX fields are always set)
  10218. response = ajaxConvert( s, response, jqXHR, isSuccess );
  10219. // If successful, handle type chaining
  10220. if ( isSuccess ) {
  10221. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  10222. if ( s.ifModified ) {
  10223. modified = jqXHR.getResponseHeader("Last-Modified");
  10224. if ( modified ) {
  10225. jQuery.lastModified[ cacheURL ] = modified;
  10226. }
  10227. modified = jqXHR.getResponseHeader("etag");
  10228. if ( modified ) {
  10229. jQuery.etag[ cacheURL ] = modified;
  10230. }
  10231. }
  10232. // if no content
  10233. if ( status === 204 || s.type === "HEAD" ) {
  10234. statusText = "nocontent";
  10235. // if not modified
  10236. } else if ( status === 304 ) {
  10237. statusText = "notmodified";
  10238. // If we have data, let's convert it
  10239. } else {
  10240. statusText = response.state;
  10241. success = response.data;
  10242. error = response.error;
  10243. isSuccess = !error;
  10244. }
  10245. } else {
  10246. // We extract error from statusText
  10247. // then normalize statusText and status for non-aborts
  10248. error = statusText;
  10249. if ( status || !statusText ) {
  10250. statusText = "error";
  10251. if ( status < 0 ) {
  10252. status = 0;
  10253. }
  10254. }
  10255. }
  10256. // Set data for the fake xhr object
  10257. jqXHR.status = status;
  10258. jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  10259. // Success/Error
  10260. if ( isSuccess ) {
  10261. deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  10262. } else {
  10263. deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  10264. }
  10265. // Status-dependent callbacks
  10266. jqXHR.statusCode( statusCode );
  10267. statusCode = undefined;
  10268. if ( fireGlobals ) {
  10269. globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  10270. [ jqXHR, s, isSuccess ? success : error ] );
  10271. }
  10272. // Complete
  10273. completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  10274. if ( fireGlobals ) {
  10275. globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  10276. // Handle the global AJAX counter
  10277. if ( !( --jQuery.active ) ) {
  10278. jQuery.event.trigger("ajaxStop");
  10279. }
  10280. }
  10281. }
  10282. return jqXHR;
  10283. },
  10284. getJSON: function( url, data, callback ) {
  10285. return jQuery.get( url, data, callback, "json" );
  10286. },
  10287. getScript: function( url, callback ) {
  10288. return jQuery.get( url, undefined, callback, "script" );
  10289. }
  10290. });
  10291. jQuery.each( [ "get", "post" ], function( i, method ) {
  10292. jQuery[ method ] = function( url, data, callback, type ) {
  10293. // shift arguments if data argument was omitted
  10294. if ( jQuery.isFunction( data ) ) {
  10295. type = type || callback;
  10296. callback = data;
  10297. data = undefined;
  10298. }
  10299. return jQuery.ajax({
  10300. url: url,
  10301. type: method,
  10302. dataType: type,
  10303. data: data,
  10304. success: callback
  10305. });
  10306. };
  10307. });
  10308. /* Handles responses to an ajax request:
  10309. * - finds the right dataType (mediates between content-type and expected dataType)
  10310. * - returns the corresponding response
  10311. */
  10312. function ajaxHandleResponses( s, jqXHR, responses ) {
  10313. var firstDataType, ct, finalDataType, type,
  10314. contents = s.contents,
  10315. dataTypes = s.dataTypes;
  10316. // Remove auto dataType and get content-type in the process
  10317. while( dataTypes[ 0 ] === "*" ) {
  10318. dataTypes.shift();
  10319. if ( ct === undefined ) {
  10320. ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
  10321. }
  10322. }
  10323. // Check if we're dealing with a known content-type
  10324. if ( ct ) {
  10325. for ( type in contents ) {
  10326. if ( contents[ type ] && contents[ type ].test( ct ) ) {
  10327. dataTypes.unshift( type );
  10328. break;
  10329. }
  10330. }
  10331. }
  10332. // Check to see if we have a response for the expected dataType
  10333. if ( dataTypes[ 0 ] in responses ) {
  10334. finalDataType = dataTypes[ 0 ];
  10335. } else {
  10336. // Try convertible dataTypes
  10337. for ( type in responses ) {
  10338. if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
  10339. finalDataType = type;
  10340. break;
  10341. }
  10342. if ( !firstDataType ) {
  10343. firstDataType = type;
  10344. }
  10345. }
  10346. // Or just use first one
  10347. finalDataType = finalDataType || firstDataType;
  10348. }
  10349. // If we found a dataType
  10350. // We add the dataType to the list if needed
  10351. // and return the corresponding response
  10352. if ( finalDataType ) {
  10353. if ( finalDataType !== dataTypes[ 0 ] ) {
  10354. dataTypes.unshift( finalDataType );
  10355. }
  10356. return responses[ finalDataType ];
  10357. }
  10358. }
  10359. /* Chain conversions given the request and the original response
  10360. * Also sets the responseXXX fields on the jqXHR instance
  10361. */
  10362. function ajaxConvert( s, response, jqXHR, isSuccess ) {
  10363. var conv2, current, conv, tmp, prev,
  10364. converters = {},
  10365. // Work with a copy of dataTypes in case we need to modify it for conversion
  10366. dataTypes = s.dataTypes.slice();
  10367. // Create converters map with lowercased keys
  10368. if ( dataTypes[ 1 ] ) {
  10369. for ( conv in s.converters ) {
  10370. converters[ conv.toLowerCase() ] = s.converters[ conv ];
  10371. }
  10372. }
  10373. current = dataTypes.shift();
  10374. // Convert to each sequential dataType
  10375. while ( current ) {
  10376. if ( s.responseFields[ current ] ) {
  10377. jqXHR[ s.responseFields[ current ] ] = response;
  10378. }
  10379. // Apply the dataFilter if provided
  10380. if ( !prev && isSuccess && s.dataFilter ) {
  10381. response = s.dataFilter( response, s.dataType );
  10382. }
  10383. prev = current;
  10384. current = dataTypes.shift();
  10385. if ( current ) {
  10386. // There's only work to do if current dataType is non-auto
  10387. if ( current === "*" ) {
  10388. current = prev;
  10389. // Convert response if prev dataType is non-auto and differs from current
  10390. } else if ( prev !== "*" && prev !== current ) {
  10391. // Seek a direct converter
  10392. conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  10393. // If none found, seek a pair
  10394. if ( !conv ) {
  10395. for ( conv2 in converters ) {
  10396. // If conv2 outputs current
  10397. tmp = conv2.split( " " );
  10398. if ( tmp[ 1 ] === current ) {
  10399. // If prev can be converted to accepted input
  10400. conv = converters[ prev + " " + tmp[ 0 ] ] ||
  10401. converters[ "* " + tmp[ 0 ] ];
  10402. if ( conv ) {
  10403. // Condense equivalence converters
  10404. if ( conv === true ) {
  10405. conv = converters[ conv2 ];
  10406. // Otherwise, insert the intermediate dataType
  10407. } else if ( converters[ conv2 ] !== true ) {
  10408. current = tmp[ 0 ];
  10409. dataTypes.unshift( tmp[ 1 ] );
  10410. }
  10411. break;
  10412. }
  10413. }
  10414. }
  10415. }
  10416. // Apply converter (if not an equivalence)
  10417. if ( conv !== true ) {
  10418. // Unless errors are allowed to bubble, catch and return them
  10419. if ( conv && s[ "throws" ] ) {
  10420. response = conv( response );
  10421. } else {
  10422. try {
  10423. response = conv( response );
  10424. } catch ( e ) {
  10425. return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
  10426. }
  10427. }
  10428. }
  10429. }
  10430. }
  10431. }
  10432. return { state: "success", data: response };
  10433. }
  10434. // Install script dataType
  10435. jQuery.ajaxSetup({
  10436. accepts: {
  10437. script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
  10438. },
  10439. contents: {
  10440. script: /(?:java|ecma)script/
  10441. },
  10442. converters: {
  10443. "text script": function( text ) {
  10444. jQuery.globalEval( text );
  10445. return text;
  10446. }
  10447. }
  10448. });
  10449. // Handle cache's special case and global
  10450. jQuery.ajaxPrefilter( "script", function( s ) {
  10451. if ( s.cache === undefined ) {
  10452. s.cache = false;
  10453. }
  10454. if ( s.crossDomain ) {
  10455. s.type = "GET";
  10456. s.global = false;
  10457. }
  10458. });
  10459. // Bind script tag hack transport
  10460. jQuery.ajaxTransport( "script", function(s) {
  10461. // This transport only deals with cross domain requests
  10462. if ( s.crossDomain ) {
  10463. var script,
  10464. head = document.head || jQuery("head")[0] || document.documentElement;
  10465. return {
  10466. send: function( _, callback ) {
  10467. script = document.createElement("script");
  10468. script.async = true;
  10469. if ( s.scriptCharset ) {
  10470. script.charset = s.scriptCharset;
  10471. }
  10472. script.src = s.url;
  10473. // Attach handlers for all browsers
  10474. script.onload = script.onreadystatechange = function( _, isAbort ) {
  10475. if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
  10476. // Handle memory leak in IE
  10477. script.onload = script.onreadystatechange = null;
  10478. // Remove the script
  10479. if ( script.parentNode ) {
  10480. script.parentNode.removeChild( script );
  10481. }
  10482. // Dereference the script
  10483. script = null;
  10484. // Callback if not abort
  10485. if ( !isAbort ) {
  10486. callback( 200, "success" );
  10487. }
  10488. }
  10489. };
  10490. // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
  10491. // Use native DOM manipulation to avoid our domManip AJAX trickery
  10492. head.insertBefore( script, head.firstChild );
  10493. },
  10494. abort: function() {
  10495. if ( script ) {
  10496. script.onload( undefined, true );
  10497. }
  10498. }
  10499. };
  10500. }
  10501. });
  10502. var oldCallbacks = [],
  10503. rjsonp = /(=)\?(?=&|$)|\?\?/;
  10504. // Default jsonp settings
  10505. jQuery.ajaxSetup({
  10506. jsonp: "callback",
  10507. jsonpCallback: function() {
  10508. var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
  10509. this[ callback ] = true;
  10510. return callback;
  10511. }
  10512. });
  10513. // Detect, normalize options and install callbacks for jsonp requests
  10514. jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  10515. var callbackName, overwritten, responseContainer,
  10516. jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  10517. "url" :
  10518. typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
  10519. );
  10520. // Handle iff the expected data type is "jsonp" or we have a parameter to set
  10521. if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  10522. // Get callback name, remembering preexisting value associated with it
  10523. callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  10524. s.jsonpCallback() :
  10525. s.jsonpCallback;
  10526. // Insert callback into url or form data
  10527. if ( jsonProp ) {
  10528. s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  10529. } else if ( s.jsonp !== false ) {
  10530. s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  10531. }
  10532. // Use data converter to retrieve json after script execution
  10533. s.converters["script json"] = function() {
  10534. if ( !responseContainer ) {
  10535. jQuery.error( callbackName + " was not called" );
  10536. }
  10537. return responseContainer[ 0 ];
  10538. };
  10539. // force json dataType
  10540. s.dataTypes[ 0 ] = "json";
  10541. // Install callback
  10542. overwritten = window[ callbackName ];
  10543. window[ callbackName ] = function() {
  10544. responseContainer = arguments;
  10545. };
  10546. // Clean-up function (fires after converters)
  10547. jqXHR.always(function() {
  10548. // Restore preexisting value
  10549. window[ callbackName ] = overwritten;
  10550. // Save back as free
  10551. if ( s[ callbackName ] ) {
  10552. // make sure that re-using the options doesn't screw things around
  10553. s.jsonpCallback = originalSettings.jsonpCallback;
  10554. // save the callback name for future use
  10555. oldCallbacks.push( callbackName );
  10556. }
  10557. // Call if it was a function and we have a response
  10558. if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  10559. overwritten( responseContainer[ 0 ] );
  10560. }
  10561. responseContainer = overwritten = undefined;
  10562. });
  10563. // Delegate to script
  10564. return "script";
  10565. }
  10566. });
  10567. var xhrCallbacks, xhrSupported,
  10568. xhrId = 0,
  10569. // #5280: Internet Explorer will keep connections alive if we don't abort on unload
  10570. xhrOnUnloadAbort = window.ActiveXObject && function() {
  10571. // Abort all pending requests
  10572. var key;
  10573. for ( key in xhrCallbacks ) {
  10574. xhrCallbacks[ key ]( undefined, true );
  10575. }
  10576. };
  10577. // Functions to create xhrs
  10578. function createStandardXHR() {
  10579. try {
  10580. return new window.XMLHttpRequest();
  10581. } catch( e ) {}
  10582. }
  10583. function createActiveXHR() {
  10584. try {
  10585. return new window.ActiveXObject("Microsoft.XMLHTTP");
  10586. } catch( e ) {}
  10587. }
  10588. // Create the request object
  10589. // (This is still attached to ajaxSettings for backward compatibility)
  10590. jQuery.ajaxSettings.xhr = window.ActiveXObject ?
  10591. /* Microsoft failed to properly
  10592. * implement the XMLHttpRequest in IE7 (can't request local files),
  10593. * so we use the ActiveXObject when it is available
  10594. * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
  10595. * we need a fallback.
  10596. */
  10597. function() {
  10598. return !this.isLocal && createStandardXHR() || createActiveXHR();
  10599. } :
  10600. // For all other browsers, use the standard XMLHttpRequest object
  10601. createStandardXHR;
  10602. // Determine support properties
  10603. xhrSupported = jQuery.ajaxSettings.xhr();
  10604. jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  10605. xhrSupported = jQuery.support.ajax = !!xhrSupported;
  10606. // Create transport if the browser can provide an xhr
  10607. if ( xhrSupported ) {
  10608. jQuery.ajaxTransport(function( s ) {
  10609. // Cross domain only allowed if supported through XMLHttpRequest
  10610. if ( !s.crossDomain || jQuery.support.cors ) {
  10611. var callback;
  10612. return {
  10613. send: function( headers, complete ) {
  10614. // Get a new xhr
  10615. var handle, i,
  10616. xhr = s.xhr();
  10617. // Open the socket
  10618. // Passing null username, generates a login popup on Opera (#2865)
  10619. if ( s.username ) {
  10620. xhr.open( s.type, s.url, s.async, s.username, s.password );
  10621. } else {
  10622. xhr.open( s.type, s.url, s.async );
  10623. }
  10624. // Apply custom fields if provided
  10625. if ( s.xhrFields ) {
  10626. for ( i in s.xhrFields ) {
  10627. xhr[ i ] = s.xhrFields[ i ];
  10628. }
  10629. }
  10630. // Override mime type if needed
  10631. if ( s.mimeType && xhr.overrideMimeType ) {
  10632. xhr.overrideMimeType( s.mimeType );
  10633. }
  10634. // X-Requested-With header
  10635. // For cross-domain requests, seeing as conditions for a preflight are
  10636. // akin to a jigsaw puzzle, we simply never set it to be sure.
  10637. // (it can always be set on a per-request basis or even using ajaxSetup)
  10638. // For same-domain requests, won't change header if already provided.
  10639. if ( !s.crossDomain && !headers["X-Requested-With"] ) {
  10640. headers["X-Requested-With"] = "XMLHttpRequest";
  10641. }
  10642. // Need an extra try/catch for cross domain requests in Firefox 3
  10643. try {
  10644. for ( i in headers ) {
  10645. xhr.setRequestHeader( i, headers[ i ] );
  10646. }
  10647. } catch( err ) {}
  10648. // Do send the request
  10649. // This may raise an exception which is actually
  10650. // handled in jQuery.ajax (so no try/catch here)
  10651. xhr.send( ( s.hasContent && s.data ) || null );
  10652. // Listener
  10653. callback = function( _, isAbort ) {
  10654. var status, responseHeaders, statusText, responses;
  10655. // Firefox throws exceptions when accessing properties
  10656. // of an xhr when a network error occurred
  10657. // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
  10658. try {
  10659. // Was never called and is aborted or complete
  10660. if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
  10661. // Only called once
  10662. callback = undefined;
  10663. // Do not keep as active anymore
  10664. if ( handle ) {
  10665. xhr.onreadystatechange = jQuery.noop;
  10666. if ( xhrOnUnloadAbort ) {
  10667. delete xhrCallbacks[ handle ];
  10668. }
  10669. }
  10670. // If it's an abort
  10671. if ( isAbort ) {
  10672. // Abort it manually if needed
  10673. if ( xhr.readyState !== 4 ) {
  10674. xhr.abort();
  10675. }
  10676. } else {
  10677. responses = {};
  10678. status = xhr.status;
  10679. responseHeaders = xhr.getAllResponseHeaders();
  10680. // When requesting binary data, IE6-9 will throw an exception
  10681. // on any attempt to access responseText (#11426)
  10682. if ( typeof xhr.responseText === "string" ) {
  10683. responses.text = xhr.responseText;
  10684. }
  10685. // Firefox throws an exception when accessing
  10686. // statusText for faulty cross-domain requests
  10687. try {
  10688. statusText = xhr.statusText;
  10689. } catch( e ) {
  10690. // We normalize with Webkit giving an empty statusText
  10691. statusText = "";
  10692. }
  10693. // Filter status for non standard behaviors
  10694. // If the request is local and we have data: assume a success
  10695. // (success with no data won't get notified, that's the best we
  10696. // can do given current implementations)
  10697. if ( !status && s.isLocal && !s.crossDomain ) {
  10698. status = responses.text ? 200 : 404;
  10699. // IE - #1450: sometimes returns 1223 when it should be 204
  10700. } else if ( status === 1223 ) {
  10701. status = 204;
  10702. }
  10703. }
  10704. }
  10705. } catch( firefoxAccessException ) {
  10706. if ( !isAbort ) {
  10707. complete( -1, firefoxAccessException );
  10708. }
  10709. }
  10710. // Call complete if needed
  10711. if ( responses ) {
  10712. complete( status, statusText, responses, responseHeaders );
  10713. }
  10714. };
  10715. if ( !s.async ) {
  10716. // if we're in sync mode we fire the callback
  10717. callback();
  10718. } else if ( xhr.readyState === 4 ) {
  10719. // (IE6 & IE7) if it's in cache and has been
  10720. // retrieved directly we need to fire the callback
  10721. setTimeout( callback );
  10722. } else {
  10723. handle = ++xhrId;
  10724. if ( xhrOnUnloadAbort ) {
  10725. // Create the active xhrs callbacks list if needed
  10726. // and attach the unload handler
  10727. if ( !xhrCallbacks ) {
  10728. xhrCallbacks = {};
  10729. jQuery( window ).unload( xhrOnUnloadAbort );
  10730. }
  10731. // Add to list of active xhrs callbacks
  10732. xhrCallbacks[ handle ] = callback;
  10733. }
  10734. xhr.onreadystatechange = callback;
  10735. }
  10736. },
  10737. abort: function() {
  10738. if ( callback ) {
  10739. callback( undefined, true );
  10740. }
  10741. }
  10742. };
  10743. }
  10744. });
  10745. }
  10746. var fxNow, timerId,
  10747. rfxtypes = /^(?:toggle|show|hide)$/,
  10748. rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
  10749. rrun = /queueHooks$/,
  10750. animationPrefilters = [ defaultPrefilter ],
  10751. tweeners = {
  10752. "*": [function( prop, value ) {
  10753. var tween = this.createTween( prop, value ),
  10754. target = tween.cur(),
  10755. parts = rfxnum.exec( value ),
  10756. unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  10757. // Starting value computation is required for potential unit mismatches
  10758. start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
  10759. rfxnum.exec( jQuery.css( tween.elem, prop ) ),
  10760. scale = 1,
  10761. maxIterations = 20;
  10762. if ( start && start[ 3 ] !== unit ) {
  10763. // Trust units reported by jQuery.css
  10764. unit = unit || start[ 3 ];
  10765. // Make sure we update the tween properties later on
  10766. parts = parts || [];
  10767. // Iteratively approximate from a nonzero starting point
  10768. start = +target || 1;
  10769. do {
  10770. // If previous iteration zeroed out, double until we get *something*
  10771. // Use a string for doubling factor so we don't accidentally see scale as unchanged below
  10772. scale = scale || ".5";
  10773. // Adjust and apply
  10774. start = start / scale;
  10775. jQuery.style( tween.elem, prop, start + unit );
  10776. // Update scale, tolerating zero or NaN from tween.cur()
  10777. // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
  10778. } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
  10779. }
  10780. // Update tween properties
  10781. if ( parts ) {
  10782. start = tween.start = +start || +target || 0;
  10783. tween.unit = unit;
  10784. // If a +=/-= token was provided, we're doing a relative animation
  10785. tween.end = parts[ 1 ] ?
  10786. start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
  10787. +parts[ 2 ];
  10788. }
  10789. return tween;
  10790. }]
  10791. };
  10792. // Animations created synchronously will run synchronously
  10793. function createFxNow() {
  10794. setTimeout(function() {
  10795. fxNow = undefined;
  10796. });
  10797. return ( fxNow = jQuery.now() );
  10798. }
  10799. function createTween( value, prop, animation ) {
  10800. var tween,
  10801. collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
  10802. index = 0,
  10803. length = collection.length;
  10804. for ( ; index < length; index++ ) {
  10805. if ( (tween = collection[ index ].call( animation, prop, value )) ) {
  10806. // we're done with this property
  10807. return tween;
  10808. }
  10809. }
  10810. }
  10811. function Animation( elem, properties, options ) {
  10812. var result,
  10813. stopped,
  10814. index = 0,
  10815. length = animationPrefilters.length,
  10816. deferred = jQuery.Deferred().always( function() {
  10817. // don't match elem in the :animated selector
  10818. delete tick.elem;
  10819. }),
  10820. tick = function() {
  10821. if ( stopped ) {
  10822. return false;
  10823. }
  10824. var currentTime = fxNow || createFxNow(),
  10825. remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  10826. // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
  10827. temp = remaining / animation.duration || 0,
  10828. percent = 1 - temp,
  10829. index = 0,
  10830. length = animation.tweens.length;
  10831. for ( ; index < length ; index++ ) {
  10832. animation.tweens[ index ].run( percent );
  10833. }
  10834. deferred.notifyWith( elem, [ animation, percent, remaining ]);
  10835. if ( percent < 1 && length ) {
  10836. return remaining;
  10837. } else {
  10838. deferred.resolveWith( elem, [ animation ] );
  10839. return false;
  10840. }
  10841. },
  10842. animation = deferred.promise({
  10843. elem: elem,
  10844. props: jQuery.extend( {}, properties ),
  10845. opts: jQuery.extend( true, { specialEasing: {} }, options ),
  10846. originalProperties: properties,
  10847. originalOptions: options,
  10848. startTime: fxNow || createFxNow(),
  10849. duration: options.duration,
  10850. tweens: [],
  10851. createTween: function( prop, end ) {
  10852. var tween = jQuery.Tween( elem, animation.opts, prop, end,
  10853. animation.opts.specialEasing[ prop ] || animation.opts.easing );
  10854. animation.tweens.push( tween );
  10855. return tween;
  10856. },
  10857. stop: function( gotoEnd ) {
  10858. var index = 0,
  10859. // if we are going to the end, we want to run all the tweens
  10860. // otherwise we skip this part
  10861. length = gotoEnd ? animation.tweens.length : 0;
  10862. if ( stopped ) {
  10863. return this;
  10864. }
  10865. stopped = true;
  10866. for ( ; index < length ; index++ ) {
  10867. animation.tweens[ index ].run( 1 );
  10868. }
  10869. // resolve when we played the last frame
  10870. // otherwise, reject
  10871. if ( gotoEnd ) {
  10872. deferred.resolveWith( elem, [ animation, gotoEnd ] );
  10873. } else {
  10874. deferred.rejectWith( elem, [ animation, gotoEnd ] );
  10875. }
  10876. return this;
  10877. }
  10878. }),
  10879. props = animation.props;
  10880. propFilter( props, animation.opts.specialEasing );
  10881. for ( ; index < length ; index++ ) {
  10882. result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
  10883. if ( result ) {
  10884. return result;
  10885. }
  10886. }
  10887. jQuery.map( props, createTween, animation );
  10888. if ( jQuery.isFunction( animation.opts.start ) ) {
  10889. animation.opts.start.call( elem, animation );
  10890. }
  10891. jQuery.fx.timer(
  10892. jQuery.extend( tick, {
  10893. elem: elem,
  10894. anim: animation,
  10895. queue: animation.opts.queue
  10896. })
  10897. );
  10898. // attach callbacks from options
  10899. return animation.progress( animation.opts.progress )
  10900. .done( animation.opts.done, animation.opts.complete )
  10901. .fail( animation.opts.fail )
  10902. .always( animation.opts.always );
  10903. }
  10904. function propFilter( props, specialEasing ) {
  10905. var index, name, easing, value, hooks;
  10906. // camelCase, specialEasing and expand cssHook pass
  10907. for ( index in props ) {
  10908. name = jQuery.camelCase( index );
  10909. easing = specialEasing[ name ];
  10910. value = props[ index ];
  10911. if ( jQuery.isArray( value ) ) {
  10912. easing = value[ 1 ];
  10913. value = props[ index ] = value[ 0 ];
  10914. }
  10915. if ( index !== name ) {
  10916. props[ name ] = value;
  10917. delete props[ index ];
  10918. }
  10919. hooks = jQuery.cssHooks[ name ];
  10920. if ( hooks && "expand" in hooks ) {
  10921. value = hooks.expand( value );
  10922. delete props[ name ];
  10923. // not quite $.extend, this wont overwrite keys already present.
  10924. // also - reusing 'index' from above because we have the correct "name"
  10925. for ( index in value ) {
  10926. if ( !( index in props ) ) {
  10927. props[ index ] = value[ index ];
  10928. specialEasing[ index ] = easing;
  10929. }
  10930. }
  10931. } else {
  10932. specialEasing[ name ] = easing;
  10933. }
  10934. }
  10935. }
  10936. jQuery.Animation = jQuery.extend( Animation, {
  10937. tweener: function( props, callback ) {
  10938. if ( jQuery.isFunction( props ) ) {
  10939. callback = props;
  10940. props = [ "*" ];
  10941. } else {
  10942. props = props.split(" ");
  10943. }
  10944. var prop,
  10945. index = 0,
  10946. length = props.length;
  10947. for ( ; index < length ; index++ ) {
  10948. prop = props[ index ];
  10949. tweeners[ prop ] = tweeners[ prop ] || [];
  10950. tweeners[ prop ].unshift( callback );
  10951. }
  10952. },
  10953. prefilter: function( callback, prepend ) {
  10954. if ( prepend ) {
  10955. animationPrefilters.unshift( callback );
  10956. } else {
  10957. animationPrefilters.push( callback );
  10958. }
  10959. }
  10960. });
  10961. function defaultPrefilter( elem, props, opts ) {
  10962. /* jshint validthis: true */
  10963. var prop, value, toggle, tween, hooks, oldfire,
  10964. anim = this,
  10965. orig = {},
  10966. style = elem.style,
  10967. hidden = elem.nodeType && isHidden( elem ),
  10968. dataShow = jQuery._data( elem, "fxshow" );
  10969. // handle queue: false promises
  10970. if ( !opts.queue ) {
  10971. hooks = jQuery._queueHooks( elem, "fx" );
  10972. if ( hooks.unqueued == null ) {
  10973. hooks.unqueued = 0;
  10974. oldfire = hooks.empty.fire;
  10975. hooks.empty.fire = function() {
  10976. if ( !hooks.unqueued ) {
  10977. oldfire();
  10978. }
  10979. };
  10980. }
  10981. hooks.unqueued++;
  10982. anim.always(function() {
  10983. // doing this makes sure that the complete handler will be called
  10984. // before this completes
  10985. anim.always(function() {
  10986. hooks.unqueued--;
  10987. if ( !jQuery.queue( elem, "fx" ).length ) {
  10988. hooks.empty.fire();
  10989. }
  10990. });
  10991. });
  10992. }
  10993. // height/width overflow pass
  10994. if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
  10995. // Make sure that nothing sneaks out
  10996. // Record all 3 overflow attributes because IE does not
  10997. // change the overflow attribute when overflowX and
  10998. // overflowY are set to the same value
  10999. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  11000. // Set display property to inline-block for height/width
  11001. // animations on inline elements that are having width/height animated
  11002. if ( jQuery.css( elem, "display" ) === "inline" &&
  11003. jQuery.css( elem, "float" ) === "none" ) {
  11004. // inline-level elements accept inline-block;
  11005. // block-level elements need to be inline with layout
  11006. if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
  11007. style.display = "inline-block";
  11008. } else {
  11009. style.zoom = 1;
  11010. }
  11011. }
  11012. }
  11013. if ( opts.overflow ) {
  11014. style.overflow = "hidden";
  11015. if ( !jQuery.support.shrinkWrapBlocks ) {
  11016. anim.always(function() {
  11017. style.overflow = opts.overflow[ 0 ];
  11018. style.overflowX = opts.overflow[ 1 ];
  11019. style.overflowY = opts.overflow[ 2 ];
  11020. });
  11021. }
  11022. }
  11023. // show/hide pass
  11024. for ( prop in props ) {
  11025. value = props[ prop ];
  11026. if ( rfxtypes.exec( value ) ) {
  11027. delete props[ prop ];
  11028. toggle = toggle || value === "toggle";
  11029. if ( value === ( hidden ? "hide" : "show" ) ) {
  11030. continue;
  11031. }
  11032. orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  11033. }
  11034. }
  11035. if ( !jQuery.isEmptyObject( orig ) ) {
  11036. if ( dataShow ) {
  11037. if ( "hidden" in dataShow ) {
  11038. hidden = dataShow.hidden;
  11039. }
  11040. } else {
  11041. dataShow = jQuery._data( elem, "fxshow", {} );
  11042. }
  11043. // store state if its toggle - enables .stop().toggle() to "reverse"
  11044. if ( toggle ) {
  11045. dataShow.hidden = !hidden;
  11046. }
  11047. if ( hidden ) {
  11048. jQuery( elem ).show();
  11049. } else {
  11050. anim.done(function() {
  11051. jQuery( elem ).hide();
  11052. });
  11053. }
  11054. anim.done(function() {
  11055. var prop;
  11056. jQuery._removeData( elem, "fxshow" );
  11057. for ( prop in orig ) {
  11058. jQuery.style( elem, prop, orig[ prop ] );
  11059. }
  11060. });
  11061. for ( prop in orig ) {
  11062. tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  11063. if ( !( prop in dataShow ) ) {
  11064. dataShow[ prop ] = tween.start;
  11065. if ( hidden ) {
  11066. tween.end = tween.start;
  11067. tween.start = prop === "width" || prop === "height" ? 1 : 0;
  11068. }
  11069. }
  11070. }
  11071. }
  11072. }
  11073. function Tween( elem, options, prop, end, easing ) {
  11074. return new Tween.prototype.init( elem, options, prop, end, easing );
  11075. }
  11076. jQuery.Tween = Tween;
  11077. Tween.prototype = {
  11078. constructor: Tween,
  11079. init: function( elem, options, prop, end, easing, unit ) {
  11080. this.elem = elem;
  11081. this.prop = prop;
  11082. this.easing = easing || "swing";
  11083. this.options = options;
  11084. this.start = this.now = this.cur();
  11085. this.end = end;
  11086. this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  11087. },
  11088. cur: function() {
  11089. var hooks = Tween.propHooks[ this.prop ];
  11090. return hooks && hooks.get ?
  11091. hooks.get( this ) :
  11092. Tween.propHooks._default.get( this );
  11093. },
  11094. run: function( percent ) {
  11095. var eased,
  11096. hooks = Tween.propHooks[ this.prop ];
  11097. if ( this.options.duration ) {
  11098. this.pos = eased = jQuery.easing[ this.easing ](
  11099. percent, this.options.duration * percent, 0, 1, this.options.duration
  11100. );
  11101. } else {
  11102. this.pos = eased = percent;
  11103. }
  11104. this.now = ( this.end - this.start ) * eased + this.start;
  11105. if ( this.options.step ) {
  11106. this.options.step.call( this.elem, this.now, this );
  11107. }
  11108. if ( hooks && hooks.set ) {
  11109. hooks.set( this );
  11110. } else {
  11111. Tween.propHooks._default.set( this );
  11112. }
  11113. return this;
  11114. }
  11115. };
  11116. Tween.prototype.init.prototype = Tween.prototype;
  11117. Tween.propHooks = {
  11118. _default: {
  11119. get: function( tween ) {
  11120. var result;
  11121. if ( tween.elem[ tween.prop ] != null &&
  11122. (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
  11123. return tween.elem[ tween.prop ];
  11124. }
  11125. // passing an empty string as a 3rd parameter to .css will automatically
  11126. // attempt a parseFloat and fallback to a string if the parse fails
  11127. // so, simple values such as "10px" are parsed to Float.
  11128. // complex values such as "rotate(1rad)" are returned as is.
  11129. result = jQuery.css( tween.elem, tween.prop, "" );
  11130. // Empty strings, null, undefined and "auto" are converted to 0.
  11131. return !result || result === "auto" ? 0 : result;
  11132. },
  11133. set: function( tween ) {
  11134. // use step hook for back compat - use cssHook if its there - use .style if its
  11135. // available and use plain properties where available
  11136. if ( jQuery.fx.step[ tween.prop ] ) {
  11137. jQuery.fx.step[ tween.prop ]( tween );
  11138. } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
  11139. jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  11140. } else {
  11141. tween.elem[ tween.prop ] = tween.now;
  11142. }
  11143. }
  11144. }
  11145. };
  11146. // Support: IE <=9
  11147. // Panic based approach to setting things on disconnected nodes
  11148. Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  11149. set: function( tween ) {
  11150. if ( tween.elem.nodeType && tween.elem.parentNode ) {
  11151. tween.elem[ tween.prop ] = tween.now;
  11152. }
  11153. }
  11154. };
  11155. jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
  11156. var cssFn = jQuery.fn[ name ];
  11157. jQuery.fn[ name ] = function( speed, easing, callback ) {
  11158. return speed == null || typeof speed === "boolean" ?
  11159. cssFn.apply( this, arguments ) :
  11160. this.animate( genFx( name, true ), speed, easing, callback );
  11161. };
  11162. });
  11163. jQuery.fn.extend({
  11164. fadeTo: function( speed, to, easing, callback ) {
  11165. // show any hidden elements after setting opacity to 0
  11166. return this.filter( isHidden ).css( "opacity", 0 ).show()
  11167. // animate to the value specified
  11168. .end().animate({ opacity: to }, speed, easing, callback );
  11169. },
  11170. animate: function( prop, speed, easing, callback ) {
  11171. var empty = jQuery.isEmptyObject( prop ),
  11172. optall = jQuery.speed( speed, easing, callback ),
  11173. doAnimation = function() {
  11174. // Operate on a copy of prop so per-property easing won't be lost
  11175. var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  11176. // Empty animations, or finishing resolves immediately
  11177. if ( empty || jQuery._data( this, "finish" ) ) {
  11178. anim.stop( true );
  11179. }
  11180. };
  11181. doAnimation.finish = doAnimation;
  11182. return empty || optall.queue === false ?
  11183. this.each( doAnimation ) :
  11184. this.queue( optall.queue, doAnimation );
  11185. },
  11186. stop: function( type, clearQueue, gotoEnd ) {
  11187. var stopQueue = function( hooks ) {
  11188. var stop = hooks.stop;
  11189. delete hooks.stop;
  11190. stop( gotoEnd );
  11191. };
  11192. if ( typeof type !== "string" ) {
  11193. gotoEnd = clearQueue;
  11194. clearQueue = type;
  11195. type = undefined;
  11196. }
  11197. if ( clearQueue && type !== false ) {
  11198. this.queue( type || "fx", [] );
  11199. }
  11200. return this.each(function() {
  11201. var dequeue = true,
  11202. index = type != null && type + "queueHooks",
  11203. timers = jQuery.timers,
  11204. data = jQuery._data( this );
  11205. if ( index ) {
  11206. if ( data[ index ] && data[ index ].stop ) {
  11207. stopQueue( data[ index ] );
  11208. }
  11209. } else {
  11210. for ( index in data ) {
  11211. if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  11212. stopQueue( data[ index ] );
  11213. }
  11214. }
  11215. }
  11216. for ( index = timers.length; index--; ) {
  11217. if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
  11218. timers[ index ].anim.stop( gotoEnd );
  11219. dequeue = false;
  11220. timers.splice( index, 1 );
  11221. }
  11222. }
  11223. // start the next in the queue if the last step wasn't forced
  11224. // timers currently will call their complete callbacks, which will dequeue
  11225. // but only if they were gotoEnd
  11226. if ( dequeue || !gotoEnd ) {
  11227. jQuery.dequeue( this, type );
  11228. }
  11229. });
  11230. },
  11231. finish: function( type ) {
  11232. if ( type !== false ) {
  11233. type = type || "fx";
  11234. }
  11235. return this.each(function() {
  11236. var index,
  11237. data = jQuery._data( this ),
  11238. queue = data[ type + "queue" ],
  11239. hooks = data[ type + "queueHooks" ],
  11240. timers = jQuery.timers,
  11241. length = queue ? queue.length : 0;
  11242. // enable finishing flag on private data
  11243. data.finish = true;
  11244. // empty the queue first
  11245. jQuery.queue( this, type, [] );
  11246. if ( hooks && hooks.stop ) {
  11247. hooks.stop.call( this, true );
  11248. }
  11249. // look for any active animations, and finish them
  11250. for ( index = timers.length; index--; ) {
  11251. if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  11252. timers[ index ].anim.stop( true );
  11253. timers.splice( index, 1 );
  11254. }
  11255. }
  11256. // look for any animations in the old queue and finish them
  11257. for ( index = 0; index < length; index++ ) {
  11258. if ( queue[ index ] && queue[ index ].finish ) {
  11259. queue[ index ].finish.call( this );
  11260. }
  11261. }
  11262. // turn off finishing flag
  11263. delete data.finish;
  11264. });
  11265. }
  11266. });
  11267. // Generate parameters to create a standard animation
  11268. function genFx( type, includeWidth ) {
  11269. var which,
  11270. attrs = { height: type },
  11271. i = 0;
  11272. // if we include width, step value is 1 to do all cssExpand values,
  11273. // if we don't include width, step value is 2 to skip over Left and Right
  11274. includeWidth = includeWidth? 1 : 0;
  11275. for( ; i < 4 ; i += 2 - includeWidth ) {
  11276. which = cssExpand[ i ];
  11277. attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  11278. }
  11279. if ( includeWidth ) {
  11280. attrs.opacity = attrs.width = type;
  11281. }
  11282. return attrs;
  11283. }
  11284. // Generate shortcuts for custom animations
  11285. jQuery.each({
  11286. slideDown: genFx("show"),
  11287. slideUp: genFx("hide"),
  11288. slideToggle: genFx("toggle"),
  11289. fadeIn: { opacity: "show" },
  11290. fadeOut: { opacity: "hide" },
  11291. fadeToggle: { opacity: "toggle" }
  11292. }, function( name, props ) {
  11293. jQuery.fn[ name ] = function( speed, easing, callback ) {
  11294. return this.animate( props, speed, easing, callback );
  11295. };
  11296. });
  11297. jQuery.speed = function( speed, easing, fn ) {
  11298. var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  11299. complete: fn || !fn && easing ||
  11300. jQuery.isFunction( speed ) && speed,
  11301. duration: speed,
  11302. easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  11303. };
  11304. opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
  11305. opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
  11306. // normalize opt.queue - true/undefined/null -> "fx"
  11307. if ( opt.queue == null || opt.queue === true ) {
  11308. opt.queue = "fx";
  11309. }
  11310. // Queueing
  11311. opt.old = opt.complete;
  11312. opt.complete = function() {
  11313. if ( jQuery.isFunction( opt.old ) ) {
  11314. opt.old.call( this );
  11315. }
  11316. if ( opt.queue ) {
  11317. jQuery.dequeue( this, opt.queue );
  11318. }
  11319. };
  11320. return opt;
  11321. };
  11322. jQuery.easing = {
  11323. linear: function( p ) {
  11324. return p;
  11325. },
  11326. swing: function( p ) {
  11327. return 0.5 - Math.cos( p*Math.PI ) / 2;
  11328. }
  11329. };
  11330. jQuery.timers = [];
  11331. jQuery.fx = Tween.prototype.init;
  11332. jQuery.fx.tick = function() {
  11333. var timer,
  11334. timers = jQuery.timers,
  11335. i = 0;
  11336. fxNow = jQuery.now();
  11337. for ( ; i < timers.length; i++ ) {
  11338. timer = timers[ i ];
  11339. // Checks the timer has not already been removed
  11340. if ( !timer() && timers[ i ] === timer ) {
  11341. timers.splice( i--, 1 );
  11342. }
  11343. }
  11344. if ( !timers.length ) {
  11345. jQuery.fx.stop();
  11346. }
  11347. fxNow = undefined;
  11348. };
  11349. jQuery.fx.timer = function( timer ) {
  11350. if ( timer() && jQuery.timers.push( timer ) ) {
  11351. jQuery.fx.start();
  11352. }
  11353. };
  11354. jQuery.fx.interval = 13;
  11355. jQuery.fx.start = function() {
  11356. if ( !timerId ) {
  11357. timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
  11358. }
  11359. };
  11360. jQuery.fx.stop = function() {
  11361. clearInterval( timerId );
  11362. timerId = null;
  11363. };
  11364. jQuery.fx.speeds = {
  11365. slow: 600,
  11366. fast: 200,
  11367. // Default speed
  11368. _default: 400
  11369. };
  11370. // Back Compat <1.8 extension point
  11371. jQuery.fx.step = {};
  11372. if ( jQuery.expr && jQuery.expr.filters ) {
  11373. jQuery.expr.filters.animated = function( elem ) {
  11374. return jQuery.grep(jQuery.timers, function( fn ) {
  11375. return elem === fn.elem;
  11376. }).length;
  11377. };
  11378. }
  11379. jQuery.fn.offset = function( options ) {
  11380. if ( arguments.length ) {
  11381. return options === undefined ?
  11382. this :
  11383. this.each(function( i ) {
  11384. jQuery.offset.setOffset( this, options, i );
  11385. });
  11386. }
  11387. var docElem, win,
  11388. box = { top: 0, left: 0 },
  11389. elem = this[ 0 ],
  11390. doc = elem && elem.ownerDocument;
  11391. if ( !doc ) {
  11392. return;
  11393. }
  11394. docElem = doc.documentElement;
  11395. // Make sure it's not a disconnected DOM node
  11396. if ( !jQuery.contains( docElem, elem ) ) {
  11397. return box;
  11398. }
  11399. // If we don't have gBCR, just use 0,0 rather than error
  11400. // BlackBerry 5, iOS 3 (original iPhone)
  11401. if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
  11402. box = elem.getBoundingClientRect();
  11403. }
  11404. win = getWindow( doc );
  11405. return {
  11406. top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
  11407. left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
  11408. };
  11409. };
  11410. jQuery.offset = {
  11411. setOffset: function( elem, options, i ) {
  11412. var position = jQuery.css( elem, "position" );
  11413. // set position first, in-case top/left are set even on static elem
  11414. if ( position === "static" ) {
  11415. elem.style.position = "relative";
  11416. }
  11417. var curElem = jQuery( elem ),
  11418. curOffset = curElem.offset(),
  11419. curCSSTop = jQuery.css( elem, "top" ),
  11420. curCSSLeft = jQuery.css( elem, "left" ),
  11421. calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
  11422. props = {}, curPosition = {}, curTop, curLeft;
  11423. // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
  11424. if ( calculatePosition ) {
  11425. curPosition = curElem.position();
  11426. curTop = curPosition.top;
  11427. curLeft = curPosition.left;
  11428. } else {
  11429. curTop = parseFloat( curCSSTop ) || 0;
  11430. curLeft = parseFloat( curCSSLeft ) || 0;
  11431. }
  11432. if ( jQuery.isFunction( options ) ) {
  11433. options = options.call( elem, i, curOffset );
  11434. }
  11435. if ( options.top != null ) {
  11436. props.top = ( options.top - curOffset.top ) + curTop;
  11437. }
  11438. if ( options.left != null ) {
  11439. props.left = ( options.left - curOffset.left ) + curLeft;
  11440. }
  11441. if ( "using" in options ) {
  11442. options.using.call( elem, props );
  11443. } else {
  11444. curElem.css( props );
  11445. }
  11446. }
  11447. };
  11448. jQuery.fn.extend({
  11449. position: function() {
  11450. if ( !this[ 0 ] ) {
  11451. return;
  11452. }
  11453. var offsetParent, offset,
  11454. parentOffset = { top: 0, left: 0 },
  11455. elem = this[ 0 ];
  11456. // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
  11457. if ( jQuery.css( elem, "position" ) === "fixed" ) {
  11458. // we assume that getBoundingClientRect is available when computed position is fixed
  11459. offset = elem.getBoundingClientRect();
  11460. } else {
  11461. // Get *real* offsetParent
  11462. offsetParent = this.offsetParent();
  11463. // Get correct offsets
  11464. offset = this.offset();
  11465. if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
  11466. parentOffset = offsetParent.offset();
  11467. }
  11468. // Add offsetParent borders
  11469. parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
  11470. parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
  11471. }
  11472. // Subtract parent offsets and element margins
  11473. // note: when an element has margin: auto the offsetLeft and marginLeft
  11474. // are the same in Safari causing offset.left to incorrectly be 0
  11475. return {
  11476. top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  11477. left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
  11478. };
  11479. },
  11480. offsetParent: function() {
  11481. return this.map(function() {
  11482. var offsetParent = this.offsetParent || docElem;
  11483. while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
  11484. offsetParent = offsetParent.offsetParent;
  11485. }
  11486. return offsetParent || docElem;
  11487. });
  11488. }
  11489. });
  11490. // Create scrollLeft and scrollTop methods
  11491. jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
  11492. var top = /Y/.test( prop );
  11493. jQuery.fn[ method ] = function( val ) {
  11494. return jQuery.access( this, function( elem, method, val ) {
  11495. var win = getWindow( elem );
  11496. if ( val === undefined ) {
  11497. return win ? (prop in win) ? win[ prop ] :
  11498. win.document.documentElement[ method ] :
  11499. elem[ method ];
  11500. }
  11501. if ( win ) {
  11502. win.scrollTo(
  11503. !top ? val : jQuery( win ).scrollLeft(),
  11504. top ? val : jQuery( win ).scrollTop()
  11505. );
  11506. } else {
  11507. elem[ method ] = val;
  11508. }
  11509. }, method, val, arguments.length, null );
  11510. };
  11511. });
  11512. function getWindow( elem ) {
  11513. return jQuery.isWindow( elem ) ?
  11514. elem :
  11515. elem.nodeType === 9 ?
  11516. elem.defaultView || elem.parentWindow :
  11517. false;
  11518. }
  11519. // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  11520. jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  11521. jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
  11522. // margin is only for outerHeight, outerWidth
  11523. jQuery.fn[ funcName ] = function( margin, value ) {
  11524. var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  11525. extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  11526. return jQuery.access( this, function( elem, type, value ) {
  11527. var doc;
  11528. if ( jQuery.isWindow( elem ) ) {
  11529. // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
  11530. // isn't a whole lot we can do. See pull request at this URL for discussion:
  11531. // https://github.com/jquery/jquery/pull/764
  11532. return elem.document.documentElement[ "client" + name ];
  11533. }
  11534. // Get document width or height
  11535. if ( elem.nodeType === 9 ) {
  11536. doc = elem.documentElement;
  11537. // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
  11538. // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
  11539. return Math.max(
  11540. elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  11541. elem.body[ "offset" + name ], doc[ "offset" + name ],
  11542. doc[ "client" + name ]
  11543. );
  11544. }
  11545. return value === undefined ?
  11546. // Get width or height on the element, requesting but not forcing parseFloat
  11547. jQuery.css( elem, type, extra ) :
  11548. // Set width or height on the element
  11549. jQuery.style( elem, type, value, extra );
  11550. }, type, chainable ? margin : undefined, chainable, null );
  11551. };
  11552. });
  11553. });
  11554. // Limit scope pollution from any deprecated API
  11555. // (function() {
  11556. // The number of elements contained in the matched element set
  11557. jQuery.fn.size = function() {
  11558. return this.length;
  11559. };
  11560. jQuery.fn.andSelf = jQuery.fn.addBack;
  11561. // })();
  11562. if ( typeof module === "object" && module && typeof module.exports === "object" ) {
  11563. // Expose jQuery as module.exports in loaders that implement the Node
  11564. // module pattern (including browserify). Do not create the global, since
  11565. // the user will be storing it themselves locally, and globals are frowned
  11566. // upon in the Node module world.
  11567. module.exports = jQuery;
  11568. } else {
  11569. // Otherwise expose jQuery to the global object as usual
  11570. window.jQuery = window.$ = jQuery;
  11571. // Register as a named AMD module, since jQuery can be concatenated with other
  11572. // files that may use define, but not via a proper concatenation script that
  11573. // understands anonymous AMD modules. A named AMD is safest and most robust
  11574. // way to register. Lowercase jquery is used because AMD module names are
  11575. // derived from file names, and jQuery is normally delivered in a lowercase
  11576. // file name. Do this after creating the global so that if an AMD module wants
  11577. // to call noConflict to hide this version of jQuery, it will work.
  11578. if ( typeof define === "function" && define.amd ) {
  11579. define( "jquery", [], function () { return jQuery; } );
  11580. }
  11581. }
  11582. })( window );
  11583. ; browserify_shim__define__module__export__(typeof $ != "undefined" ? $ : window.$);
  11584. }).call(global, undefined, undefined, undefined, function defineExport(ex) { module.exports = ex; });
  11585. },{}],"jquery":[function(require,module,exports){
  11586. module.exports=require('RIh26+');
  11587. },{}],"zNh35D":[function(require,module,exports){
  11588. var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};(function browserifyShim(module, exports, define, browserify_shim__define__module__export__) {
  11589. // Underscore.js 1.5.2
  11590. // http://underscorejs.org
  11591. // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  11592. // Underscore may be freely distributed under the MIT license.
  11593. (function() {
  11594. // Baseline setup
  11595. // --------------
  11596. // Establish the root object, `window` in the browser, or `exports` on the server.
  11597. var root = this;
  11598. // Save the previous value of the `_` variable.
  11599. var previousUnderscore = root._;
  11600. // Establish the object that gets returned to break out of a loop iteration.
  11601. var breaker = {};
  11602. // Save bytes in the minified (but not gzipped) version:
  11603. var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
  11604. // Create quick reference variables for speed access to core prototypes.
  11605. var
  11606. push = ArrayProto.push,
  11607. slice = ArrayProto.slice,
  11608. concat = ArrayProto.concat,
  11609. toString = ObjProto.toString,
  11610. hasOwnProperty = ObjProto.hasOwnProperty;
  11611. // All **ECMAScript 5** native function implementations that we hope to use
  11612. // are declared here.
  11613. var
  11614. nativeForEach = ArrayProto.forEach,
  11615. nativeMap = ArrayProto.map,
  11616. nativeReduce = ArrayProto.reduce,
  11617. nativeReduceRight = ArrayProto.reduceRight,
  11618. nativeFilter = ArrayProto.filter,
  11619. nativeEvery = ArrayProto.every,
  11620. nativeSome = ArrayProto.some,
  11621. nativeIndexOf = ArrayProto.indexOf,
  11622. nativeLastIndexOf = ArrayProto.lastIndexOf,
  11623. nativeIsArray = Array.isArray,
  11624. nativeKeys = Object.keys,
  11625. nativeBind = FuncProto.bind;
  11626. // Create a safe reference to the Underscore object for use below.
  11627. var _ = function(obj) {
  11628. if (obj instanceof _) return obj;
  11629. if (!(this instanceof _)) return new _(obj);
  11630. this._wrapped = obj;
  11631. };
  11632. // Export the Underscore object for **Node.js**, with
  11633. // backwards-compatibility for the old `require()` API. If we're in
  11634. // the browser, add `_` as a global object via a string identifier,
  11635. // for Closure Compiler "advanced" mode.
  11636. if (typeof exports !== 'undefined') {
  11637. if (typeof module !== 'undefined' && module.exports) {
  11638. exports = module.exports = _;
  11639. }
  11640. exports._ = _;
  11641. } else {
  11642. root._ = _;
  11643. }
  11644. // Current version.
  11645. _.VERSION = '1.5.2';
  11646. // Collection Functions
  11647. // --------------------
  11648. // The cornerstone, an `each` implementation, aka `forEach`.
  11649. // Handles objects with the built-in `forEach`, arrays, and raw objects.
  11650. // Delegates to **ECMAScript 5**'s native `forEach` if available.
  11651. var each = _.each = _.forEach = function(obj, iterator, context) {
  11652. if (obj == null) return;
  11653. if (nativeForEach && obj.forEach === nativeForEach) {
  11654. obj.forEach(iterator, context);
  11655. } else if (obj.length === +obj.length) {
  11656. for (var i = 0, length = obj.length; i < length; i++) {
  11657. if (iterator.call(context, obj[i], i, obj) === breaker) return;
  11658. }
  11659. } else {
  11660. var keys = _.keys(obj);
  11661. for (var i = 0, length = keys.length; i < length; i++) {
  11662. if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
  11663. }
  11664. }
  11665. };
  11666. // Return the results of applying the iterator to each element.
  11667. // Delegates to **ECMAScript 5**'s native `map` if available.
  11668. _.map = _.collect = function(obj, iterator, context) {
  11669. var results = [];
  11670. if (obj == null) return results;
  11671. if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
  11672. each(obj, function(value, index, list) {
  11673. results.push(iterator.call(context, value, index, list));
  11674. });
  11675. return results;
  11676. };
  11677. var reduceError = 'Reduce of empty array with no initial value';
  11678. // **Reduce** builds up a single result from a list of values, aka `inject`,
  11679. // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  11680. _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
  11681. var initial = arguments.length > 2;
  11682. if (obj == null) obj = [];
  11683. if (nativeReduce && obj.reduce === nativeReduce) {
  11684. if (context) iterator = _.bind(iterator, context);
  11685. return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
  11686. }
  11687. each(obj, function(value, index, list) {
  11688. if (!initial) {
  11689. memo = value;
  11690. initial = true;
  11691. } else {
  11692. memo = iterator.call(context, memo, value, index, list);
  11693. }
  11694. });
  11695. if (!initial) throw new TypeError(reduceError);
  11696. return memo;
  11697. };
  11698. // The right-associative version of reduce, also known as `foldr`.
  11699. // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
  11700. _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
  11701. var initial = arguments.length > 2;
  11702. if (obj == null) obj = [];
  11703. if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
  11704. if (context) iterator = _.bind(iterator, context);
  11705. return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
  11706. }
  11707. var length = obj.length;
  11708. if (length !== +length) {
  11709. var keys = _.keys(obj);
  11710. length = keys.length;
  11711. }
  11712. each(obj, function(value, index, list) {
  11713. index = keys ? keys[--length] : --length;
  11714. if (!initial) {
  11715. memo = obj[index];
  11716. initial = true;
  11717. } else {
  11718. memo = iterator.call(context, memo, obj[index], index, list);
  11719. }
  11720. });
  11721. if (!initial) throw new TypeError(reduceError);
  11722. return memo;
  11723. };
  11724. // Return the first value which passes a truth test. Aliased as `detect`.
  11725. _.find = _.detect = function(obj, iterator, context) {
  11726. var result;
  11727. any(obj, function(value, index, list) {
  11728. if (iterator.call(context, value, index, list)) {
  11729. result = value;
  11730. return true;
  11731. }
  11732. });
  11733. return result;
  11734. };
  11735. // Return all the elements that pass a truth test.
  11736. // Delegates to **ECMAScript 5**'s native `filter` if available.
  11737. // Aliased as `select`.
  11738. _.filter = _.select = function(obj, iterator, context) {
  11739. var results = [];
  11740. if (obj == null) return results;
  11741. if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
  11742. each(obj, function(value, index, list) {
  11743. if (iterator.call(context, value, index, list)) results.push(value);
  11744. });
  11745. return results;
  11746. };
  11747. // Return all the elements for which a truth test fails.
  11748. _.reject = function(obj, iterator, context) {
  11749. return _.filter(obj, function(value, index, list) {
  11750. return !iterator.call(context, value, index, list);
  11751. }, context);
  11752. };
  11753. // Determine whether all of the elements match a truth test.
  11754. // Delegates to **ECMAScript 5**'s native `every` if available.
  11755. // Aliased as `all`.
  11756. _.every = _.all = function(obj, iterator, context) {
  11757. iterator || (iterator = _.identity);
  11758. var result = true;
  11759. if (obj == null) return result;
  11760. if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
  11761. each(obj, function(value, index, list) {
  11762. if (!(result = result && iterator.call(context, value, index, list))) return breaker;
  11763. });
  11764. return !!result;
  11765. };
  11766. // Determine if at least one element in the object matches a truth test.
  11767. // Delegates to **ECMAScript 5**'s native `some` if available.
  11768. // Aliased as `any`.
  11769. var any = _.some = _.any = function(obj, iterator, context) {
  11770. iterator || (iterator = _.identity);
  11771. var result = false;
  11772. if (obj == null) return result;
  11773. if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
  11774. each(obj, function(value, index, list) {
  11775. if (result || (result = iterator.call(context, value, index, list))) return breaker;
  11776. });
  11777. return !!result;
  11778. };
  11779. // Determine if the array or object contains a given value (using `===`).
  11780. // Aliased as `include`.
  11781. _.contains = _.include = function(obj, target) {
  11782. if (obj == null) return false;
  11783. if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
  11784. return any(obj, function(value) {
  11785. return value === target;
  11786. });
  11787. };
  11788. // Invoke a method (with arguments) on every item in a collection.
  11789. _.invoke = function(obj, method) {
  11790. var args = slice.call(arguments, 2);
  11791. var isFunc = _.isFunction(method);
  11792. return _.map(obj, function(value) {
  11793. return (isFunc ? method : value[method]).apply(value, args);
  11794. });
  11795. };
  11796. // Convenience version of a common use case of `map`: fetching a property.
  11797. _.pluck = function(obj, key) {
  11798. return _.map(obj, function(value){ return value[key]; });
  11799. };
  11800. // Convenience version of a common use case of `filter`: selecting only objects
  11801. // containing specific `key:value` pairs.
  11802. _.where = function(obj, attrs, first) {
  11803. if (_.isEmpty(attrs)) return first ? void 0 : [];
  11804. return _[first ? 'find' : 'filter'](obj, function(value) {
  11805. for (var key in attrs) {
  11806. if (attrs[key] !== value[key]) return false;
  11807. }
  11808. return true;
  11809. });
  11810. };
  11811. // Convenience version of a common use case of `find`: getting the first object
  11812. // containing specific `key:value` pairs.
  11813. _.findWhere = function(obj, attrs) {
  11814. return _.where(obj, attrs, true);
  11815. };
  11816. // Return the maximum element or (element-based computation).
  11817. // Can't optimize arrays of integers longer than 65,535 elements.
  11818. // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
  11819. _.max = function(obj, iterator, context) {
  11820. if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  11821. return Math.max.apply(Math, obj);
  11822. }
  11823. if (!iterator && _.isEmpty(obj)) return -Infinity;
  11824. var result = {computed : -Infinity, value: -Infinity};
  11825. each(obj, function(value, index, list) {
  11826. var computed = iterator ? iterator.call(context, value, index, list) : value;
  11827. computed > result.computed && (result = {value : value, computed : computed});
  11828. });
  11829. return result.value;
  11830. };
  11831. // Return the minimum element (or element-based computation).
  11832. _.min = function(obj, iterator, context) {
  11833. if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  11834. return Math.min.apply(Math, obj);
  11835. }
  11836. if (!iterator && _.isEmpty(obj)) return Infinity;
  11837. var result = {computed : Infinity, value: Infinity};
  11838. each(obj, function(value, index, list) {
  11839. var computed = iterator ? iterator.call(context, value, index, list) : value;
  11840. computed < result.computed && (result = {value : value, computed : computed});
  11841. });
  11842. return result.value;
  11843. };
  11844. // Shuffle an array, using the modern version of the
  11845. // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
  11846. _.shuffle = function(obj) {
  11847. var rand;
  11848. var index = 0;
  11849. var shuffled = [];
  11850. each(obj, function(value) {
  11851. rand = _.random(index++);
  11852. shuffled[index - 1] = shuffled[rand];
  11853. shuffled[rand] = value;
  11854. });
  11855. return shuffled;
  11856. };
  11857. // Sample **n** random values from an array.
  11858. // If **n** is not specified, returns a single random element from the array.
  11859. // The internal `guard` argument allows it to work with `map`.
  11860. _.sample = function(obj, n, guard) {
  11861. if (arguments.length < 2 || guard) {
  11862. return obj[_.random(obj.length - 1)];
  11863. }
  11864. return _.shuffle(obj).slice(0, Math.max(0, n));
  11865. };
  11866. // An internal function to generate lookup iterators.
  11867. var lookupIterator = function(value) {
  11868. return _.isFunction(value) ? value : function(obj){ return obj[value]; };
  11869. };
  11870. // Sort the object's values by a criterion produced by an iterator.
  11871. _.sortBy = function(obj, value, context) {
  11872. var iterator = lookupIterator(value);
  11873. return _.pluck(_.map(obj, function(value, index, list) {
  11874. return {
  11875. value: value,
  11876. index: index,
  11877. criteria: iterator.call(context, value, index, list)
  11878. };
  11879. }).sort(function(left, right) {
  11880. var a = left.criteria;
  11881. var b = right.criteria;
  11882. if (a !== b) {
  11883. if (a > b || a === void 0) return 1;
  11884. if (a < b || b === void 0) return -1;
  11885. }
  11886. return left.index - right.index;
  11887. }), 'value');
  11888. };
  11889. // An internal function used for aggregate "group by" operations.
  11890. var group = function(behavior) {
  11891. return function(obj, value, context) {
  11892. var result = {};
  11893. var iterator = value == null ? _.identity : lookupIterator(value);
  11894. each(obj, function(value, index) {
  11895. var key = iterator.call(context, value, index, obj);
  11896. behavior(result, key, value);
  11897. });
  11898. return result;
  11899. };
  11900. };
  11901. // Groups the object's values by a criterion. Pass either a string attribute
  11902. // to group by, or a function that returns the criterion.
  11903. _.groupBy = group(function(result, key, value) {
  11904. (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
  11905. });
  11906. // Indexes the object's values by a criterion, similar to `groupBy`, but for
  11907. // when you know that your index values will be unique.
  11908. _.indexBy = group(function(result, key, value) {
  11909. result[key] = value;
  11910. });
  11911. // Counts instances of an object that group by a certain criterion. Pass
  11912. // either a string attribute to count by, or a function that returns the
  11913. // criterion.
  11914. _.countBy = group(function(result, key) {
  11915. _.has(result, key) ? result[key]++ : result[key] = 1;
  11916. });
  11917. // Use a comparator function to figure out the smallest index at which
  11918. // an object should be inserted so as to maintain order. Uses binary search.
  11919. _.sortedIndex = function(array, obj, iterator, context) {
  11920. iterator = iterator == null ? _.identity : lookupIterator(iterator);
  11921. var value = iterator.call(context, obj);
  11922. var low = 0, high = array.length;
  11923. while (low < high) {
  11924. var mid = (low + high) >>> 1;
  11925. iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
  11926. }
  11927. return low;
  11928. };
  11929. // Safely create a real, live array from anything iterable.
  11930. _.toArray = function(obj) {
  11931. if (!obj) return [];
  11932. if (_.isArray(obj)) return slice.call(obj);
  11933. if (obj.length === +obj.length) return _.map(obj, _.identity);
  11934. return _.values(obj);
  11935. };
  11936. // Return the number of elements in an object.
  11937. _.size = function(obj) {
  11938. if (obj == null) return 0;
  11939. return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
  11940. };
  11941. // Array Functions
  11942. // ---------------
  11943. // Get the first element of an array. Passing **n** will return the first N
  11944. // values in the array. Aliased as `head` and `take`. The **guard** check
  11945. // allows it to work with `_.map`.
  11946. _.first = _.head = _.take = function(array, n, guard) {
  11947. if (array == null) return void 0;
  11948. return (n == null) || guard ? array[0] : slice.call(array, 0, n);
  11949. };
  11950. // Returns everything but the last entry of the array. Especially useful on
  11951. // the arguments object. Passing **n** will return all the values in
  11952. // the array, excluding the last N. The **guard** check allows it to work with
  11953. // `_.map`.
  11954. _.initial = function(array, n, guard) {
  11955. return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
  11956. };
  11957. // Get the last element of an array. Passing **n** will return the last N
  11958. // values in the array. The **guard** check allows it to work with `_.map`.
  11959. _.last = function(array, n, guard) {
  11960. if (array == null) return void 0;
  11961. if ((n == null) || guard) {
  11962. return array[array.length - 1];
  11963. } else {
  11964. return slice.call(array, Math.max(array.length - n, 0));
  11965. }
  11966. };
  11967. // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
  11968. // Especially useful on the arguments object. Passing an **n** will return
  11969. // the rest N values in the array. The **guard**
  11970. // check allows it to work with `_.map`.
  11971. _.rest = _.tail = _.drop = function(array, n, guard) {
  11972. return slice.call(array, (n == null) || guard ? 1 : n);
  11973. };
  11974. // Trim out all falsy values from an array.
  11975. _.compact = function(array) {
  11976. return _.filter(array, _.identity);
  11977. };
  11978. // Internal implementation of a recursive `flatten` function.
  11979. var flatten = function(input, shallow, output) {
  11980. if (shallow && _.every(input, _.isArray)) {
  11981. return concat.apply(output, input);
  11982. }
  11983. each(input, function(value) {
  11984. if (_.isArray(value) || _.isArguments(value)) {
  11985. shallow ? push.apply(output, value) : flatten(value, shallow, output);
  11986. } else {
  11987. output.push(value);
  11988. }
  11989. });
  11990. return output;
  11991. };
  11992. // Flatten out an array, either recursively (by default), or just one level.
  11993. _.flatten = function(array, shallow) {
  11994. return flatten(array, shallow, []);
  11995. };
  11996. // Return a version of the array that does not contain the specified value(s).
  11997. _.without = function(array) {
  11998. return _.difference(array, slice.call(arguments, 1));
  11999. };
  12000. // Produce a duplicate-free version of the array. If the array has already
  12001. // been sorted, you have the option of using a faster algorithm.
  12002. // Aliased as `unique`.
  12003. _.uniq = _.unique = function(array, isSorted, iterator, context) {
  12004. if (_.isFunction(isSorted)) {
  12005. context = iterator;
  12006. iterator = isSorted;
  12007. isSorted = false;
  12008. }
  12009. var initial = iterator ? _.map(array, iterator, context) : array;
  12010. var results = [];
  12011. var seen = [];
  12012. each(initial, function(value, index) {
  12013. if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
  12014. seen.push(value);
  12015. results.push(array[index]);
  12016. }
  12017. });
  12018. return results;
  12019. };
  12020. // Produce an array that contains the union: each distinct element from all of
  12021. // the passed-in arrays.
  12022. _.union = function() {
  12023. return _.uniq(_.flatten(arguments, true));
  12024. };
  12025. // Produce an array that contains every item shared between all the
  12026. // passed-in arrays.
  12027. _.intersection = function(array) {
  12028. var rest = slice.call(arguments, 1);
  12029. return _.filter(_.uniq(array), function(item) {
  12030. return _.every(rest, function(other) {
  12031. return _.indexOf(other, item) >= 0;
  12032. });
  12033. });
  12034. };
  12035. // Take the difference between one array and a number of other arrays.
  12036. // Only the elements present in just the first array will remain.
  12037. _.difference = function(array) {
  12038. var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
  12039. return _.filter(array, function(value){ return !_.contains(rest, value); });
  12040. };
  12041. // Zip together multiple lists into a single array -- elements that share
  12042. // an index go together.
  12043. _.zip = function() {
  12044. var length = _.max(_.pluck(arguments, "length").concat(0));
  12045. var results = new Array(length);
  12046. for (var i = 0; i < length; i++) {
  12047. results[i] = _.pluck(arguments, '' + i);
  12048. }
  12049. return results;
  12050. };
  12051. // Converts lists into objects. Pass either a single array of `[key, value]`
  12052. // pairs, or two parallel arrays of the same length -- one of keys, and one of
  12053. // the corresponding values.
  12054. _.object = function(list, values) {
  12055. if (list == null) return {};
  12056. var result = {};
  12057. for (var i = 0, length = list.length; i < length; i++) {
  12058. if (values) {
  12059. result[list[i]] = values[i];
  12060. } else {
  12061. result[list[i][0]] = list[i][1];
  12062. }
  12063. }
  12064. return result;
  12065. };
  12066. // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
  12067. // we need this function. Return the position of the first occurrence of an
  12068. // item in an array, or -1 if the item is not included in the array.
  12069. // Delegates to **ECMAScript 5**'s native `indexOf` if available.
  12070. // If the array is large and already in sort order, pass `true`
  12071. // for **isSorted** to use binary search.
  12072. _.indexOf = function(array, item, isSorted) {
  12073. if (array == null) return -1;
  12074. var i = 0, length = array.length;
  12075. if (isSorted) {
  12076. if (typeof isSorted == 'number') {
  12077. i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
  12078. } else {
  12079. i = _.sortedIndex(array, item);
  12080. return array[i] === item ? i : -1;
  12081. }
  12082. }
  12083. if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
  12084. for (; i < length; i++) if (array[i] === item) return i;
  12085. return -1;
  12086. };
  12087. // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  12088. _.lastIndexOf = function(array, item, from) {
  12089. if (array == null) return -1;
  12090. var hasIndex = from != null;
  12091. if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
  12092. return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
  12093. }
  12094. var i = (hasIndex ? from : array.length);
  12095. while (i--) if (array[i] === item) return i;
  12096. return -1;
  12097. };
  12098. // Generate an integer Array containing an arithmetic progression. A port of
  12099. // the native Python `range()` function. See
  12100. // [the Python documentation](http://docs.python.org/library/functions.html#range).
  12101. _.range = function(start, stop, step) {
  12102. if (arguments.length <= 1) {
  12103. stop = start || 0;
  12104. start = 0;
  12105. }
  12106. step = arguments[2] || 1;
  12107. var length = Math.max(Math.ceil((stop - start) / step), 0);
  12108. var idx = 0;
  12109. var range = new Array(length);
  12110. while(idx < length) {
  12111. range[idx++] = start;
  12112. start += step;
  12113. }
  12114. return range;
  12115. };
  12116. // Function (ahem) Functions
  12117. // ------------------
  12118. // Reusable constructor function for prototype setting.
  12119. var ctor = function(){};
  12120. // Create a function bound to a given object (assigning `this`, and arguments,
  12121. // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
  12122. // available.
  12123. _.bind = function(func, context) {
  12124. var args, bound;
  12125. if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
  12126. if (!_.isFunction(func)) throw new TypeError;
  12127. args = slice.call(arguments, 2);
  12128. return bound = function() {
  12129. if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
  12130. ctor.prototype = func.prototype;
  12131. var self = new ctor;
  12132. ctor.prototype = null;
  12133. var result = func.apply(self, args.concat(slice.call(arguments)));
  12134. if (Object(result) === result) return result;
  12135. return self;
  12136. };
  12137. };
  12138. // Partially apply a function by creating a version that has had some of its
  12139. // arguments pre-filled, without changing its dynamic `this` context.
  12140. _.partial = function(func) {
  12141. var args = slice.call(arguments, 1);
  12142. return function() {
  12143. return func.apply(this, args.concat(slice.call(arguments)));
  12144. };
  12145. };
  12146. // Bind all of an object's methods to that object. Useful for ensuring that
  12147. // all callbacks defined on an object belong to it.
  12148. _.bindAll = function(obj) {
  12149. var funcs = slice.call(arguments, 1);
  12150. if (funcs.length === 0) throw new Error("bindAll must be passed function names");
  12151. each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
  12152. return obj;
  12153. };
  12154. // Memoize an expensive function by storing its results.
  12155. _.memoize = function(func, hasher) {
  12156. var memo = {};
  12157. hasher || (hasher = _.identity);
  12158. return function() {
  12159. var key = hasher.apply(this, arguments);
  12160. return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
  12161. };
  12162. };
  12163. // Delays a function for the given number of milliseconds, and then calls
  12164. // it with the arguments supplied.
  12165. _.delay = function(func, wait) {
  12166. var args = slice.call(arguments, 2);
  12167. return setTimeout(function(){ return func.apply(null, args); }, wait);
  12168. };
  12169. // Defers a function, scheduling it to run after the current call stack has
  12170. // cleared.
  12171. _.defer = function(func) {
  12172. return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  12173. };
  12174. // Returns a function, that, when invoked, will only be triggered at most once
  12175. // during a given window of time. Normally, the throttled function will run
  12176. // as much as it can, without ever going more than once per `wait` duration;
  12177. // but if you'd like to disable the execution on the leading edge, pass
  12178. // `{leading: false}`. To disable execution on the trailing edge, ditto.
  12179. _.throttle = function(func, wait, options) {
  12180. var context, args, result;
  12181. var timeout = null;
  12182. var previous = 0;
  12183. options || (options = {});
  12184. var later = function() {
  12185. previous = options.leading === false ? 0 : new Date;
  12186. timeout = null;
  12187. result = func.apply(context, args);
  12188. };
  12189. return function() {
  12190. var now = new Date;
  12191. if (!previous && options.leading === false) previous = now;
  12192. var remaining = wait - (now - previous);
  12193. context = this;
  12194. args = arguments;
  12195. if (remaining <= 0) {
  12196. clearTimeout(timeout);
  12197. timeout = null;
  12198. previous = now;
  12199. result = func.apply(context, args);
  12200. } else if (!timeout && options.trailing !== false) {
  12201. timeout = setTimeout(later, remaining);
  12202. }
  12203. return result;
  12204. };
  12205. };
  12206. // Returns a function, that, as long as it continues to be invoked, will not
  12207. // be triggered. The function will be called after it stops being called for
  12208. // N milliseconds. If `immediate` is passed, trigger the function on the
  12209. // leading edge, instead of the trailing.
  12210. _.debounce = function(func, wait, immediate) {
  12211. var timeout, args, context, timestamp, result;
  12212. return function() {
  12213. context = this;
  12214. args = arguments;
  12215. timestamp = new Date();
  12216. var later = function() {
  12217. var last = (new Date()) - timestamp;
  12218. if (last < wait) {
  12219. timeout = setTimeout(later, wait - last);
  12220. } else {
  12221. timeout = null;
  12222. if (!immediate) result = func.apply(context, args);
  12223. }
  12224. };
  12225. var callNow = immediate && !timeout;
  12226. if (!timeout) {
  12227. timeout = setTimeout(later, wait);
  12228. }
  12229. if (callNow) result = func.apply(context, args);
  12230. return result;
  12231. };
  12232. };
  12233. // Returns a function that will be executed at most one time, no matter how
  12234. // often you call it. Useful for lazy initialization.
  12235. _.once = function(func) {
  12236. var ran = false, memo;
  12237. return function() {
  12238. if (ran) return memo;
  12239. ran = true;
  12240. memo = func.apply(this, arguments);
  12241. func = null;
  12242. return memo;
  12243. };
  12244. };
  12245. // Returns the first function passed as an argument to the second,
  12246. // allowing you to adjust arguments, run code before and after, and
  12247. // conditionally execute the original function.
  12248. _.wrap = function(func, wrapper) {
  12249. return function() {
  12250. var args = [func];
  12251. push.apply(args, arguments);
  12252. return wrapper.apply(this, args);
  12253. };
  12254. };
  12255. // Returns a function that is the composition of a list of functions, each
  12256. // consuming the return value of the function that follows.
  12257. _.compose = function() {
  12258. var funcs = arguments;
  12259. return function() {
  12260. var args = arguments;
  12261. for (var i = funcs.length - 1; i >= 0; i--) {
  12262. args = [funcs[i].apply(this, args)];
  12263. }
  12264. return args[0];
  12265. };
  12266. };
  12267. // Returns a function that will only be executed after being called N times.
  12268. _.after = function(times, func) {
  12269. return function() {
  12270. if (--times < 1) {
  12271. return func.apply(this, arguments);
  12272. }
  12273. };
  12274. };
  12275. // Object Functions
  12276. // ----------------
  12277. // Retrieve the names of an object's properties.
  12278. // Delegates to **ECMAScript 5**'s native `Object.keys`
  12279. _.keys = nativeKeys || function(obj) {
  12280. if (obj !== Object(obj)) throw new TypeError('Invalid object');
  12281. var keys = [];
  12282. for (var key in obj) if (_.has(obj, key)) keys.push(key);
  12283. return keys;
  12284. };
  12285. // Retrieve the values of an object's properties.
  12286. _.values = function(obj) {
  12287. var keys = _.keys(obj);
  12288. var length = keys.length;
  12289. var values = new Array(length);
  12290. for (var i = 0; i < length; i++) {
  12291. values[i] = obj[keys[i]];
  12292. }
  12293. return values;
  12294. };
  12295. // Convert an object into a list of `[key, value]` pairs.
  12296. _.pairs = function(obj) {
  12297. var keys = _.keys(obj);
  12298. var length = keys.length;
  12299. var pairs = new Array(length);
  12300. for (var i = 0; i < length; i++) {
  12301. pairs[i] = [keys[i], obj[keys[i]]];
  12302. }
  12303. return pairs;
  12304. };
  12305. // Invert the keys and values of an object. The values must be serializable.
  12306. _.invert = function(obj) {
  12307. var result = {};
  12308. var keys = _.keys(obj);
  12309. for (var i = 0, length = keys.length; i < length; i++) {
  12310. result[obj[keys[i]]] = keys[i];
  12311. }
  12312. return result;
  12313. };
  12314. // Return a sorted list of the function names available on the object.
  12315. // Aliased as `methods`
  12316. _.functions = _.methods = function(obj) {
  12317. var names = [];
  12318. for (var key in obj) {
  12319. if (_.isFunction(obj[key])) names.push(key);
  12320. }
  12321. return names.sort();
  12322. };
  12323. // Extend a given object with all the properties in passed-in object(s).
  12324. _.extend = function(obj) {
  12325. each(slice.call(arguments, 1), function(source) {
  12326. if (source) {
  12327. for (var prop in source) {
  12328. obj[prop] = source[prop];
  12329. }
  12330. }
  12331. });
  12332. return obj;
  12333. };
  12334. // Return a copy of the object only containing the whitelisted properties.
  12335. _.pick = function(obj) {
  12336. var copy = {};
  12337. var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  12338. each(keys, function(key) {
  12339. if (key in obj) copy[key] = obj[key];
  12340. });
  12341. return copy;
  12342. };
  12343. // Return a copy of the object without the blacklisted properties.
  12344. _.omit = function(obj) {
  12345. var copy = {};
  12346. var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  12347. for (var key in obj) {
  12348. if (!_.contains(keys, key)) copy[key] = obj[key];
  12349. }
  12350. return copy;
  12351. };
  12352. // Fill in a given object with default properties.
  12353. _.defaults = function(obj) {
  12354. each(slice.call(arguments, 1), function(source) {
  12355. if (source) {
  12356. for (var prop in source) {
  12357. if (obj[prop] === void 0) obj[prop] = source[prop];
  12358. }
  12359. }
  12360. });
  12361. return obj;
  12362. };
  12363. // Create a (shallow-cloned) duplicate of an object.
  12364. _.clone = function(obj) {
  12365. if (!_.isObject(obj)) return obj;
  12366. return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  12367. };
  12368. // Invokes interceptor with the obj, and then returns obj.
  12369. // The primary purpose of this method is to "tap into" a method chain, in
  12370. // order to perform operations on intermediate results within the chain.
  12371. _.tap = function(obj, interceptor) {
  12372. interceptor(obj);
  12373. return obj;
  12374. };
  12375. // Internal recursive comparison function for `isEqual`.
  12376. var eq = function(a, b, aStack, bStack) {
  12377. // Identical objects are equal. `0 === -0`, but they aren't identical.
  12378. // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
  12379. if (a === b) return a !== 0 || 1 / a == 1 / b;
  12380. // A strict comparison is necessary because `null == undefined`.
  12381. if (a == null || b == null) return a === b;
  12382. // Unwrap any wrapped objects.
  12383. if (a instanceof _) a = a._wrapped;
  12384. if (b instanceof _) b = b._wrapped;
  12385. // Compare `[[Class]]` names.
  12386. var className = toString.call(a);
  12387. if (className != toString.call(b)) return false;
  12388. switch (className) {
  12389. // Strings, numbers, dates, and booleans are compared by value.
  12390. case '[object String]':
  12391. // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
  12392. // equivalent to `new String("5")`.
  12393. return a == String(b);
  12394. case '[object Number]':
  12395. // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
  12396. // other numeric values.
  12397. return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
  12398. case '[object Date]':
  12399. case '[object Boolean]':
  12400. // Coerce dates and booleans to numeric primitive values. Dates are compared by their
  12401. // millisecond representations. Note that invalid dates with millisecond representations
  12402. // of `NaN` are not equivalent.
  12403. return +a == +b;
  12404. // RegExps are compared by their source patterns and flags.
  12405. case '[object RegExp]':
  12406. return a.source == b.source &&
  12407. a.global == b.global &&
  12408. a.multiline == b.multiline &&
  12409. a.ignoreCase == b.ignoreCase;
  12410. }
  12411. if (typeof a != 'object' || typeof b != 'object') return false;
  12412. // Assume equality for cyclic structures. The algorithm for detecting cyclic
  12413. // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
  12414. var length = aStack.length;
  12415. while (length--) {
  12416. // Linear search. Performance is inversely proportional to the number of
  12417. // unique nested structures.
  12418. if (aStack[length] == a) return bStack[length] == b;
  12419. }
  12420. // Objects with different constructors are not equivalent, but `Object`s
  12421. // from different frames are.
  12422. var aCtor = a.constructor, bCtor = b.constructor;
  12423. if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
  12424. _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
  12425. return false;
  12426. }
  12427. // Add the first object to the stack of traversed objects.
  12428. aStack.push(a);
  12429. bStack.push(b);
  12430. var size = 0, result = true;
  12431. // Recursively compare objects and arrays.
  12432. if (className == '[object Array]') {
  12433. // Compare array lengths to determine if a deep comparison is necessary.
  12434. size = a.length;
  12435. result = size == b.length;
  12436. if (result) {
  12437. // Deep compare the contents, ignoring non-numeric properties.
  12438. while (size--) {
  12439. if (!(result = eq(a[size], b[size], aStack, bStack))) break;
  12440. }
  12441. }
  12442. } else {
  12443. // Deep compare objects.
  12444. for (var key in a) {
  12445. if (_.has(a, key)) {
  12446. // Count the expected number of properties.
  12447. size++;
  12448. // Deep compare each member.
  12449. if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
  12450. }
  12451. }
  12452. // Ensure that both objects contain the same number of properties.
  12453. if (result) {
  12454. for (key in b) {
  12455. if (_.has(b, key) && !(size--)) break;
  12456. }
  12457. result = !size;
  12458. }
  12459. }
  12460. // Remove the first object from the stack of traversed objects.
  12461. aStack.pop();
  12462. bStack.pop();
  12463. return result;
  12464. };
  12465. // Perform a deep comparison to check if two objects are equal.
  12466. _.isEqual = function(a, b) {
  12467. return eq(a, b, [], []);
  12468. };
  12469. // Is a given array, string, or object empty?
  12470. // An "empty" object has no enumerable own-properties.
  12471. _.isEmpty = function(obj) {
  12472. if (obj == null) return true;
  12473. if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
  12474. for (var key in obj) if (_.has(obj, key)) return false;
  12475. return true;
  12476. };
  12477. // Is a given value a DOM element?
  12478. _.isElement = function(obj) {
  12479. return !!(obj && obj.nodeType === 1);
  12480. };
  12481. // Is a given value an array?
  12482. // Delegates to ECMA5's native Array.isArray
  12483. _.isArray = nativeIsArray || function(obj) {
  12484. return toString.call(obj) == '[object Array]';
  12485. };
  12486. // Is a given variable an object?
  12487. _.isObject = function(obj) {
  12488. return obj === Object(obj);
  12489. };
  12490. // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
  12491. each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
  12492. _['is' + name] = function(obj) {
  12493. return toString.call(obj) == '[object ' + name + ']';
  12494. };
  12495. });
  12496. // Define a fallback version of the method in browsers (ahem, IE), where
  12497. // there isn't any inspectable "Arguments" type.
  12498. if (!_.isArguments(arguments)) {
  12499. _.isArguments = function(obj) {
  12500. return !!(obj && _.has(obj, 'callee'));
  12501. };
  12502. }
  12503. // Optimize `isFunction` if appropriate.
  12504. if (typeof (/./) !== 'function') {
  12505. _.isFunction = function(obj) {
  12506. return typeof obj === 'function';
  12507. };
  12508. }
  12509. // Is a given object a finite number?
  12510. _.isFinite = function(obj) {
  12511. return isFinite(obj) && !isNaN(parseFloat(obj));
  12512. };
  12513. // Is the given value `NaN`? (NaN is the only number which does not equal itself).
  12514. _.isNaN = function(obj) {
  12515. return _.isNumber(obj) && obj != +obj;
  12516. };
  12517. // Is a given value a boolean?
  12518. _.isBoolean = function(obj) {
  12519. return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  12520. };
  12521. // Is a given value equal to null?
  12522. _.isNull = function(obj) {
  12523. return obj === null;
  12524. };
  12525. // Is a given variable undefined?
  12526. _.isUndefined = function(obj) {
  12527. return obj === void 0;
  12528. };
  12529. // Shortcut function for checking if an object has a given property directly
  12530. // on itself (in other words, not on a prototype).
  12531. _.has = function(obj, key) {
  12532. return hasOwnProperty.call(obj, key);
  12533. };
  12534. // Utility Functions
  12535. // -----------------
  12536. // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
  12537. // previous owner. Returns a reference to the Underscore object.
  12538. _.noConflict = function() {
  12539. root._ = previousUnderscore;
  12540. return this;
  12541. };
  12542. // Keep the identity function around for default iterators.
  12543. _.identity = function(value) {
  12544. return value;
  12545. };
  12546. // Run a function **n** times.
  12547. _.times = function(n, iterator, context) {
  12548. var accum = Array(Math.max(0, n));
  12549. for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
  12550. return accum;
  12551. };
  12552. // Return a random integer between min and max (inclusive).
  12553. _.random = function(min, max) {
  12554. if (max == null) {
  12555. max = min;
  12556. min = 0;
  12557. }
  12558. return min + Math.floor(Math.random() * (max - min + 1));
  12559. };
  12560. // List of HTML entities for escaping.
  12561. var entityMap = {
  12562. escape: {
  12563. '&': '&amp;',
  12564. '<': '&lt;',
  12565. '>': '&gt;',
  12566. '"': '&quot;',
  12567. "'": '&#x27;'
  12568. }
  12569. };
  12570. entityMap.unescape = _.invert(entityMap.escape);
  12571. // Regexes containing the keys and values listed immediately above.
  12572. var entityRegexes = {
  12573. escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
  12574. unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
  12575. };
  12576. // Functions for escaping and unescaping strings to/from HTML interpolation.
  12577. _.each(['escape', 'unescape'], function(method) {
  12578. _[method] = function(string) {
  12579. if (string == null) return '';
  12580. return ('' + string).replace(entityRegexes[method], function(match) {
  12581. return entityMap[method][match];
  12582. });
  12583. };
  12584. });
  12585. // If the value of the named `property` is a function then invoke it with the
  12586. // `object` as context; otherwise, return it.
  12587. _.result = function(object, property) {
  12588. if (object == null) return void 0;
  12589. var value = object[property];
  12590. return _.isFunction(value) ? value.call(object) : value;
  12591. };
  12592. // Add your own custom functions to the Underscore object.
  12593. _.mixin = function(obj) {
  12594. each(_.functions(obj), function(name) {
  12595. var func = _[name] = obj[name];
  12596. _.prototype[name] = function() {
  12597. var args = [this._wrapped];
  12598. push.apply(args, arguments);
  12599. return result.call(this, func.apply(_, args));
  12600. };
  12601. });
  12602. };
  12603. // Generate a unique integer id (unique within the entire client session).
  12604. // Useful for temporary DOM ids.
  12605. var idCounter = 0;
  12606. _.uniqueId = function(prefix) {
  12607. var id = ++idCounter + '';
  12608. return prefix ? prefix + id : id;
  12609. };
  12610. // By default, Underscore uses ERB-style template delimiters, change the
  12611. // following template settings to use alternative delimiters.
  12612. _.templateSettings = {
  12613. evaluate : /<%([\s\S]+?)%>/g,
  12614. interpolate : /<%=([\s\S]+?)%>/g,
  12615. escape : /<%-([\s\S]+?)%>/g
  12616. };
  12617. // When customizing `templateSettings`, if you don't want to define an
  12618. // interpolation, evaluation or escaping regex, we need one that is
  12619. // guaranteed not to match.
  12620. var noMatch = /(.)^/;
  12621. // Certain characters need to be escaped so that they can be put into a
  12622. // string literal.
  12623. var escapes = {
  12624. "'": "'",
  12625. '\\': '\\',
  12626. '\r': 'r',
  12627. '\n': 'n',
  12628. '\t': 't',
  12629. '\u2028': 'u2028',
  12630. '\u2029': 'u2029'
  12631. };
  12632. var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  12633. // JavaScript micro-templating, similar to John Resig's implementation.
  12634. // Underscore templating handles arbitrary delimiters, preserves whitespace,
  12635. // and correctly escapes quotes within interpolated code.
  12636. _.template = function(text, data, settings) {
  12637. var render;
  12638. settings = _.defaults({}, settings, _.templateSettings);
  12639. // Combine delimiters into one regular expression via alternation.
  12640. var matcher = new RegExp([
  12641. (settings.escape || noMatch).source,
  12642. (settings.interpolate || noMatch).source,
  12643. (settings.evaluate || noMatch).source
  12644. ].join('|') + '|$', 'g');
  12645. // Compile the template source, escaping string literals appropriately.
  12646. var index = 0;
  12647. var source = "__p+='";
  12648. text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
  12649. source += text.slice(index, offset)
  12650. .replace(escaper, function(match) { return '\\' + escapes[match]; });
  12651. if (escape) {
  12652. source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
  12653. }
  12654. if (interpolate) {
  12655. source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
  12656. }
  12657. if (evaluate) {
  12658. source += "';\n" + evaluate + "\n__p+='";
  12659. }
  12660. index = offset + match.length;
  12661. return match;
  12662. });
  12663. source += "';\n";
  12664. // If a variable is not specified, place data values in local scope.
  12665. if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
  12666. source = "var __t,__p='',__j=Array.prototype.join," +
  12667. "print=function(){__p+=__j.call(arguments,'');};\n" +
  12668. source + "return __p;\n";
  12669. try {
  12670. render = new Function(settings.variable || 'obj', '_', source);
  12671. } catch (e) {
  12672. e.source = source;
  12673. throw e;
  12674. }
  12675. if (data) return render(data, _);
  12676. var template = function(data) {
  12677. return render.call(this, data, _);
  12678. };
  12679. // Provide the compiled function source as a convenience for precompilation.
  12680. template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
  12681. return template;
  12682. };
  12683. // Add a "chain" function, which will delegate to the wrapper.
  12684. _.chain = function(obj) {
  12685. return _(obj).chain();
  12686. };
  12687. // OOP
  12688. // ---------------
  12689. // If Underscore is called as a function, it returns a wrapped object that
  12690. // can be used OO-style. This wrapper holds altered versions of all the
  12691. // underscore functions. Wrapped objects may be chained.
  12692. // Helper function to continue chaining intermediate results.
  12693. var result = function(obj) {
  12694. return this._chain ? _(obj).chain() : obj;
  12695. };
  12696. // Add all of the Underscore functions to the wrapper object.
  12697. _.mixin(_);
  12698. // Add all mutator Array functions to the wrapper.
  12699. each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
  12700. var method = ArrayProto[name];
  12701. _.prototype[name] = function() {
  12702. var obj = this._wrapped;
  12703. method.apply(obj, arguments);
  12704. if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
  12705. return result.call(this, obj);
  12706. };
  12707. });
  12708. // Add all accessor Array functions to the wrapper.
  12709. each(['concat', 'join', 'slice'], function(name) {
  12710. var method = ArrayProto[name];
  12711. _.prototype[name] = function() {
  12712. return result.call(this, method.apply(this._wrapped, arguments));
  12713. };
  12714. });
  12715. _.extend(_.prototype, {
  12716. // Start chaining a wrapped Underscore object.
  12717. chain: function() {
  12718. this._chain = true;
  12719. return this;
  12720. },
  12721. // Extracts the result from a wrapped and chained object.
  12722. value: function() {
  12723. return this._wrapped;
  12724. }
  12725. });
  12726. }).call(this);
  12727. ; browserify_shim__define__module__export__(typeof _ != "undefined" ? _ : window._);
  12728. }).call(global, undefined, undefined, undefined, function defineExport(ex) { module.exports = ex; });
  12729. },{}],"underscore":[function(require,module,exports){
  12730. module.exports=require('zNh35D');
  12731. },{}]},{},["cy31T3","n1NM5u","RIh26+","zNh35D"])
  12732. ;
  12733. ;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  12734. var Marionette = require('backbone.marionette'),
  12735. Controller = require('./controller'),
  12736. Router = require('./router'),
  12737. ContactModel = require('./models/contact'),
  12738. ContactsCollection = require('./collections/contacts');
  12739. module.exports = App = function App() {};
  12740. App.prototype.start = function(){
  12741. App.core = new Marionette.Application();
  12742. App.core.on("initialize:before", function (options) {
  12743. App.core.vent.trigger('app:log', 'App: Initializing');
  12744. App.views = {};
  12745. App.data = {};
  12746. // load up some initial data:
  12747. var contacts = new ContactsCollection();
  12748. contacts.fetch({
  12749. success: function() {
  12750. App.data.contacts = contacts;
  12751. App.core.vent.trigger('app:start');
  12752. }
  12753. });
  12754. });
  12755. App.core.vent.bind('app:start', function(options){
  12756. App.core.vent.trigger('app:log', 'App: Starting');
  12757. if (Backbone.history) {
  12758. App.controller = new Controller();
  12759. App.router = new Router({ controller: App.controller });
  12760. App.core.vent.trigger('app:log', 'App: Backbone.history starting');
  12761. Backbone.history.start();
  12762. }
  12763. //new up and views and render for base app here...
  12764. App.core.vent.trigger('app:log', 'App: Done starting and running!');
  12765. });
  12766. App.core.vent.bind('app:log', function(msg) {
  12767. console.log(msg);
  12768. });
  12769. App.core.start();
  12770. };
  12771. },{"./collections/contacts":2,"./controller":3,"./models/contact":5,"./router":6}],2:[function(require,module,exports){
  12772. var Backbone = require('backbone'),
  12773. ContactModel = require('../models/contact');
  12774. module.exports = SampleCollection = Backbone.Collection.extend({
  12775. model: ContactModel,
  12776. url: '/api/contacts'
  12777. });
  12778. },{"../models/contact":5}],3:[function(require,module,exports){
  12779. var Marionette = require('backbone.marionette'),
  12780. ContactsView = require('./views/contacts'),
  12781. ContactDetailsView = require('./views/contact_details'),
  12782. AddContactView = require('./views/add');
  12783. module.exports = Controller = Marionette.Controller.extend({
  12784. initialize: function() {
  12785. App.core.vent.trigger('app:log', 'Controller: Initializing');
  12786. window.App.views.contactsView = new ContactsView({ collection: window.App.data.contacts });
  12787. },
  12788. home: function() {
  12789. App.core.vent.trigger('app:log', 'Controller: "Home" route hit.');
  12790. var view = window.App.views.contactsView;
  12791. this.renderView(view);
  12792. window.App.router.navigate('#');
  12793. },
  12794. details: function(id) {
  12795. App.core.vent.trigger('app:log', 'Controller: "Contact Details" route hit.');
  12796. var view = new ContactDetailsView({ model: window.App.data.contacts.get(id)});
  12797. this.renderView(view);
  12798. window.App.router.navigate('details/' + id);
  12799. },
  12800. add: function() {
  12801. App.core.vent.trigger('app:log', 'Controller: "Add Contact" route hit.');
  12802. var view = new AddContactView();
  12803. this.renderView(view);
  12804. window.App.router.navigate('add');
  12805. },
  12806. renderView: function(view) {
  12807. this.destroyCurrentView(view);
  12808. App.core.vent.trigger('app:log', 'Controller: Rendering new view.');
  12809. $('#js-boilerplate-app').html(view.render().el);
  12810. },
  12811. destroyCurrentView: function(view) {
  12812. if (!_.isUndefined(window.App.views.currentView)) {
  12813. App.core.vent.trigger('app:log', 'Controller: Destroying existing view.');
  12814. window.App.views.currentView.close();
  12815. }
  12816. window.App.views.currentView = view;
  12817. }
  12818. });
  12819. },{"./views/add":7,"./views/contact_details":8,"./views/contacts":9}],4:[function(require,module,exports){
  12820. var App = require('./app');
  12821. var myapp = new App();
  12822. myapp.start();
  12823. },{"./app":1}],5:[function(require,module,exports){
  12824. var Backbone = require('backbone');
  12825. module.exports = ContactModel = Backbone.Model.extend({
  12826. idAttribute: '_id'
  12827. });
  12828. },{}],6:[function(require,module,exports){
  12829. var Marionette = require('backbone.marionette');
  12830. module.exports = Router = Marionette.AppRouter.extend({
  12831. appRoutes: {
  12832. '' : 'home',
  12833. 'details/:id' : 'details',
  12834. 'add' : 'add'
  12835. }
  12836. });
  12837. },{}],7:[function(require,module,exports){
  12838. var Marionette = require('backbone.marionette');
  12839. module.exports = AddView = Marionette.ItemView.extend({
  12840. template: require('../../templates/add.hbs'),
  12841. events: {
  12842. 'click a.save-button': 'save'
  12843. },
  12844. save: function(e) {
  12845. e.preventDefault();
  12846. var newContact = {
  12847. name: {
  12848. first: this.$el.find('#name_first').val(),
  12849. last: this.$el.find('#name_last').val()
  12850. },
  12851. email: this.$el.find('#email').val(),
  12852. phone: this.$el.find('#phone').val()
  12853. };
  12854. window.App.data.contacts.create(newContact);
  12855. window.App.core.vent.trigger('app:log', 'Add View: Saved new contact!');
  12856. window.App.controller.home();
  12857. }
  12858. });
  12859. },{"../../templates/add.hbs":10}],8:[function(require,module,exports){
  12860. var Marionette = require('backbone.marionette');
  12861. module.exports = ContactDetailsView = Marionette.ItemView.extend({
  12862. template: require('../../templates/contact_details.hbs'),
  12863. events: {
  12864. 'click a': 'goBack'
  12865. },
  12866. goBack: function(e) {
  12867. e.preventDefault();
  12868. window.App.controller.home();
  12869. }
  12870. });
  12871. },{"../../templates/contact_details.hbs":11}],9:[function(require,module,exports){
  12872. var Marionette = require('backbone.marionette');
  12873. var itemView = Marionette.ItemView.extend({
  12874. template: require('../../templates/contact_small.hbs'),
  12875. initialize: function() {
  12876. this.listenTo(this.model, 'change', this.render);
  12877. },
  12878. events: {
  12879. 'click': 'showDetails'
  12880. },
  12881. showDetails: function() {
  12882. window.App.core.vent.trigger('app:log', 'Contacts View: showDetails hit.');
  12883. window.App.controller.details(this.model.id);
  12884. }
  12885. });
  12886. module.exports = CollectionView = Marionette.CollectionView.extend({
  12887. initialize: function() {
  12888. this.listenTo(this.collection, 'change', this.render);
  12889. },
  12890. itemView: itemView
  12891. });
  12892. },{"../../templates/contact_small.hbs":12}],10:[function(require,module,exports){
  12893. // hbsfy compiled Handlebars template
  12894. var Handlebars = require('hbsfy/runtime');
  12895. module.exports = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
  12896. this.compilerInfo = [4,'>= 1.0.0'];
  12897. helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
  12898. return "<div class=\"add_contact\">\n <label for=\"name_first\">First Name:</label> <input type=\"text\" id=\"name_first\" /><br/>\n <label for=\"name_last\">Last Name:</label> <input type=\"text\" id=\"name_last\" /><br/>\n <label for=\"email\">Email:</label> <input type=\"text\" id=\"email\" /><br/>\n <label for=\"phone\">Phone:</label> <input type=\"text\" id=\"phone\" /><br/>\n <br/>\n <a href=\"#\" class=\"save-button\">Save Contact</a> | <a href=\"#\"><< Back</a>\n</div>\n";
  12899. });
  12900. },{"hbsfy/runtime":16}],11:[function(require,module,exports){
  12901. // hbsfy compiled Handlebars template
  12902. var Handlebars = require('hbsfy/runtime');
  12903. module.exports = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
  12904. this.compilerInfo = [4,'>= 1.0.0'];
  12905. helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
  12906. var buffer = "", stack1, stack2, functionType="function", escapeExpression=this.escapeExpression;
  12907. buffer += "<div class=\"contact_full\">\n <img src=\"http://www.gravatar.com/avatar/";
  12908. if (stack1 = helpers.gravatar) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
  12909. else { stack1 = depth0.gravatar; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
  12910. buffer += escapeExpression(stack1)
  12911. + "?d=monsterid&s=250\"/>\n <br/><br/>\n <strong>Name:</strong> "
  12912. + escapeExpression(((stack1 = ((stack1 = depth0.name),stack1 == null || stack1 === false ? stack1 : stack1.first)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))
  12913. + " "
  12914. + escapeExpression(((stack1 = ((stack1 = depth0.name),stack1 == null || stack1 === false ? stack1 : stack1.last)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))
  12915. + "<br/>\n <strong>Email:</strong> ";
  12916. if (stack2 = helpers.email) { stack2 = stack2.call(depth0, {hash:{},data:data}); }
  12917. else { stack2 = depth0.email; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; }
  12918. buffer += escapeExpression(stack2)
  12919. + "<br/>\n <strong>Phone:</strong> ";
  12920. if (stack2 = helpers.phone) { stack2 = stack2.call(depth0, {hash:{},data:data}); }
  12921. else { stack2 = depth0.phone; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; }
  12922. buffer += escapeExpression(stack2)
  12923. + "<br/><br/>\n\n</div>\n\n<a href=\"#\"><< Back</a>\n";
  12924. return buffer;
  12925. });
  12926. },{"hbsfy/runtime":16}],12:[function(require,module,exports){
  12927. // hbsfy compiled Handlebars template
  12928. var Handlebars = require('hbsfy/runtime');
  12929. module.exports = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
  12930. this.compilerInfo = [4,'>= 1.0.0'];
  12931. helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
  12932. var buffer = "", stack1, stack2, functionType="function", escapeExpression=this.escapeExpression;
  12933. buffer += "<div class=\"contact_small\">\n <img src=\"http://www.gravatar.com/avatar/";
  12934. if (stack1 = helpers.gravatar) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
  12935. else { stack1 = depth0.gravatar; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
  12936. buffer += escapeExpression(stack1)
  12937. + "?d=monsterid&s=45\"/>\n <strong>"
  12938. + escapeExpression(((stack1 = ((stack1 = depth0.name),stack1 == null || stack1 === false ? stack1 : stack1.first)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))
  12939. + " "
  12940. + escapeExpression(((stack1 = ((stack1 = depth0.name),stack1 == null || stack1 === false ? stack1 : stack1.last)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))
  12941. + "</strong><br/>\n ";
  12942. if (stack2 = helpers.email) { stack2 = stack2.call(depth0, {hash:{},data:data}); }
  12943. else { stack2 = depth0.email; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; }
  12944. buffer += escapeExpression(stack2)
  12945. + "\n</div>\n";
  12946. return buffer;
  12947. });
  12948. },{"hbsfy/runtime":16}],13:[function(require,module,exports){
  12949. /*jshint eqnull: true */
  12950. module.exports.create = function() {
  12951. var Handlebars = {};
  12952. // BEGIN(BROWSER)
  12953. Handlebars.VERSION = "1.0.0";
  12954. Handlebars.COMPILER_REVISION = 4;
  12955. Handlebars.REVISION_CHANGES = {
  12956. 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
  12957. 2: '== 1.0.0-rc.3',
  12958. 3: '== 1.0.0-rc.4',
  12959. 4: '>= 1.0.0'
  12960. };
  12961. Handlebars.helpers = {};
  12962. Handlebars.partials = {};
  12963. var toString = Object.prototype.toString,
  12964. functionType = '[object Function]',
  12965. objectType = '[object Object]';
  12966. Handlebars.registerHelper = function(name, fn, inverse) {
  12967. if (toString.call(name) === objectType) {
  12968. if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
  12969. Handlebars.Utils.extend(this.helpers, name);
  12970. } else {
  12971. if (inverse) { fn.not = inverse; }
  12972. this.helpers[name] = fn;
  12973. }
  12974. };
  12975. Handlebars.registerPartial = function(name, str) {
  12976. if (toString.call(name) === objectType) {
  12977. Handlebars.Utils.extend(this.partials, name);
  12978. } else {
  12979. this.partials[name] = str;
  12980. }
  12981. };
  12982. Handlebars.registerHelper('helperMissing', function(arg) {
  12983. if(arguments.length === 2) {
  12984. return undefined;
  12985. } else {
  12986. throw new Error("Missing helper: '" + arg + "'");
  12987. }
  12988. });
  12989. Handlebars.registerHelper('blockHelperMissing', function(context, options) {
  12990. var inverse = options.inverse || function() {}, fn = options.fn;
  12991. var type = toString.call(context);
  12992. if(type === functionType) { context = context.call(this); }
  12993. if(context === true) {
  12994. return fn(this);
  12995. } else if(context === false || context == null) {
  12996. return inverse(this);
  12997. } else if(type === "[object Array]") {
  12998. if(context.length > 0) {
  12999. return Handlebars.helpers.each(context, options);
  13000. } else {
  13001. return inverse(this);
  13002. }
  13003. } else {
  13004. return fn(context);
  13005. }
  13006. });
  13007. Handlebars.K = function() {};
  13008. Handlebars.createFrame = Object.create || function(object) {
  13009. Handlebars.K.prototype = object;
  13010. var obj = new Handlebars.K();
  13011. Handlebars.K.prototype = null;
  13012. return obj;
  13013. };
  13014. Handlebars.logger = {
  13015. DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
  13016. methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
  13017. // can be overridden in the host environment
  13018. log: function(level, obj) {
  13019. if (Handlebars.logger.level <= level) {
  13020. var method = Handlebars.logger.methodMap[level];
  13021. if (typeof console !== 'undefined' && console[method]) {
  13022. console[method].call(console, obj);
  13023. }
  13024. }
  13025. }
  13026. };
  13027. Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
  13028. Handlebars.registerHelper('each', function(context, options) {
  13029. var fn = options.fn, inverse = options.inverse;
  13030. var i = 0, ret = "", data;
  13031. var type = toString.call(context);
  13032. if(type === functionType) { context = context.call(this); }
  13033. if (options.data) {
  13034. data = Handlebars.createFrame(options.data);
  13035. }
  13036. if(context && typeof context === 'object') {
  13037. if(context instanceof Array){
  13038. for(var j = context.length; i<j; i++) {
  13039. if (data) { data.index = i; }
  13040. ret = ret + fn(context[i], { data: data });
  13041. }
  13042. } else {
  13043. for(var key in context) {
  13044. if(context.hasOwnProperty(key)) {
  13045. if(data) { data.key = key; }
  13046. ret = ret + fn(context[key], {data: data});
  13047. i++;
  13048. }
  13049. }
  13050. }
  13051. }
  13052. if(i === 0){
  13053. ret = inverse(this);
  13054. }
  13055. return ret;
  13056. });
  13057. Handlebars.registerHelper('if', function(conditional, options) {
  13058. var type = toString.call(conditional);
  13059. if(type === functionType) { conditional = conditional.call(this); }
  13060. if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
  13061. return options.inverse(this);
  13062. } else {
  13063. return options.fn(this);
  13064. }
  13065. });
  13066. Handlebars.registerHelper('unless', function(conditional, options) {
  13067. return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
  13068. });
  13069. Handlebars.registerHelper('with', function(context, options) {
  13070. var type = toString.call(context);
  13071. if(type === functionType) { context = context.call(this); }
  13072. if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
  13073. });
  13074. Handlebars.registerHelper('log', function(context, options) {
  13075. var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
  13076. Handlebars.log(level, context);
  13077. });
  13078. // END(BROWSER)
  13079. return Handlebars;
  13080. };
  13081. },{}],14:[function(require,module,exports){
  13082. exports.attach = function(Handlebars) {
  13083. // BEGIN(BROWSER)
  13084. Handlebars.VM = {
  13085. template: function(templateSpec) {
  13086. // Just add water
  13087. var container = {
  13088. escapeExpression: Handlebars.Utils.escapeExpression,
  13089. invokePartial: Handlebars.VM.invokePartial,
  13090. programs: [],
  13091. program: function(i, fn, data) {
  13092. var programWrapper = this.programs[i];
  13093. if(data) {
  13094. programWrapper = Handlebars.VM.program(i, fn, data);
  13095. } else if (!programWrapper) {
  13096. programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
  13097. }
  13098. return programWrapper;
  13099. },
  13100. merge: function(param, common) {
  13101. var ret = param || common;
  13102. if (param && common) {
  13103. ret = {};
  13104. Handlebars.Utils.extend(ret, common);
  13105. Handlebars.Utils.extend(ret, param);
  13106. }
  13107. return ret;
  13108. },
  13109. programWithDepth: Handlebars.VM.programWithDepth,
  13110. noop: Handlebars.VM.noop,
  13111. compilerInfo: null
  13112. };
  13113. return function(context, options) {
  13114. options = options || {};
  13115. var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
  13116. var compilerInfo = container.compilerInfo || [],
  13117. compilerRevision = compilerInfo[0] || 1,
  13118. currentRevision = Handlebars.COMPILER_REVISION;
  13119. if (compilerRevision !== currentRevision) {
  13120. if (compilerRevision < currentRevision) {
  13121. var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
  13122. compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
  13123. throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
  13124. "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
  13125. } else {
  13126. // Use the embedded version info since the runtime doesn't know about this revision yet
  13127. throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
  13128. "Please update your runtime to a newer version ("+compilerInfo[1]+").";
  13129. }
  13130. }
  13131. return result;
  13132. };
  13133. },
  13134. programWithDepth: function(i, fn, data /*, $depth */) {
  13135. var args = Array.prototype.slice.call(arguments, 3);
  13136. var program = function(context, options) {
  13137. options = options || {};
  13138. return fn.apply(this, [context, options.data || data].concat(args));
  13139. };
  13140. program.program = i;
  13141. program.depth = args.length;
  13142. return program;
  13143. },
  13144. program: function(i, fn, data) {
  13145. var program = function(context, options) {
  13146. options = options || {};
  13147. return fn(context, options.data || data);
  13148. };
  13149. program.program = i;
  13150. program.depth = 0;
  13151. return program;
  13152. },
  13153. noop: function() { return ""; },
  13154. invokePartial: function(partial, name, context, helpers, partials, data) {
  13155. var options = { helpers: helpers, partials: partials, data: data };
  13156. if(partial === undefined) {
  13157. throw new Handlebars.Exception("The partial " + name + " could not be found");
  13158. } else if(partial instanceof Function) {
  13159. return partial(context, options);
  13160. } else if (!Handlebars.compile) {
  13161. throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
  13162. } else {
  13163. partials[name] = Handlebars.compile(partial, {data: data !== undefined});
  13164. return partials[name](context, options);
  13165. }
  13166. }
  13167. };
  13168. Handlebars.template = Handlebars.VM.template;
  13169. // END(BROWSER)
  13170. return Handlebars;
  13171. };
  13172. },{}],15:[function(require,module,exports){
  13173. exports.attach = function(Handlebars) {
  13174. var toString = Object.prototype.toString;
  13175. // BEGIN(BROWSER)
  13176. var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
  13177. Handlebars.Exception = function(message) {
  13178. var tmp = Error.prototype.constructor.apply(this, arguments);
  13179. // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
  13180. for (var idx = 0; idx < errorProps.length; idx++) {
  13181. this[errorProps[idx]] = tmp[errorProps[idx]];
  13182. }
  13183. };
  13184. Handlebars.Exception.prototype = new Error();
  13185. // Build out our basic SafeString type
  13186. Handlebars.SafeString = function(string) {
  13187. this.string = string;
  13188. };
  13189. Handlebars.SafeString.prototype.toString = function() {
  13190. return this.string.toString();
  13191. };
  13192. var escape = {
  13193. "&": "&amp;",
  13194. "<": "&lt;",
  13195. ">": "&gt;",
  13196. '"': "&quot;",
  13197. "'": "&#x27;",
  13198. "`": "&#x60;"
  13199. };
  13200. var badChars = /[&<>"'`]/g;
  13201. var possible = /[&<>"'`]/;
  13202. var escapeChar = function(chr) {
  13203. return escape[chr] || "&amp;";
  13204. };
  13205. Handlebars.Utils = {
  13206. extend: function(obj, value) {
  13207. for(var key in value) {
  13208. if(value.hasOwnProperty(key)) {
  13209. obj[key] = value[key];
  13210. }
  13211. }
  13212. },
  13213. escapeExpression: function(string) {
  13214. // don't escape SafeStrings, since they're already safe
  13215. if (string instanceof Handlebars.SafeString) {
  13216. return string.toString();
  13217. } else if (string == null || string === false) {
  13218. return "";
  13219. }
  13220. // Force a string conversion as this will be done by the append regardless and
  13221. // the regex test will do this transparently behind the scenes, causing issues if
  13222. // an object's to string has escaped characters in it.
  13223. string = string.toString();
  13224. if(!possible.test(string)) { return string; }
  13225. return string.replace(badChars, escapeChar);
  13226. },
  13227. isEmpty: function(value) {
  13228. if (!value && value !== 0) {
  13229. return true;
  13230. } else if(toString.call(value) === "[object Array]" && value.length === 0) {
  13231. return true;
  13232. } else {
  13233. return false;
  13234. }
  13235. }
  13236. };
  13237. // END(BROWSER)
  13238. return Handlebars;
  13239. };
  13240. },{}],16:[function(require,module,exports){
  13241. var hbsBase = require("handlebars/lib/handlebars/base");
  13242. var hbsUtils = require("handlebars/lib/handlebars/utils");
  13243. var hbsRuntime = require("handlebars/lib/handlebars/runtime");
  13244. var Handlebars = hbsBase.create();
  13245. hbsUtils.attach(Handlebars);
  13246. hbsRuntime.attach(Handlebars);
  13247. module.exports = Handlebars;
  13248. },{"handlebars/lib/handlebars/base":13,"handlebars/lib/handlebars/runtime":14,"handlebars/lib/handlebars/utils":15}]},{},[4])
  13249. ;