History

ModbusAdapters: Fixed security issues in Modbus configuration screen GSF.Web: Cleaned up new embedded resources

J. Ritchie Carroll committed 9 years ago

Commit 970956d1 parent 230686d36 files · +72369 −1648Browse files

Showing the changes to Source/Libraries/GSF.Web/Shared/Scripts (4 of 36 files). Show all

Unified · Split

4 files
  1. Source/Libraries/GSF.Web/Shared/Scripts/angular.js +31768 −0
  2. Source/Libraries/GSF.Web/Shared/Scripts/gsf.web.client.js +5 −5
  3. Source/Libraries/GSF.Web/Shared/Scripts/jquery-ui.js +16617 −0
  4. Source/Libraries/GSF.Web/Shared/Scripts/primeui.js +13963 −0
Source/Libraries/GSF.Web/Shared/Scripts/angular.js+31768−0
@@ -0,0 +1,31768 @@
1+/**
2+ * @license AngularJS v1.5.8
3+ * (c) 2010-2016 Google, Inc. http://angularjs.org
4+ * License: MIT
5+ */
6+(function(window) {'use strict';
7+
8+/**
9+ * @description
10+ *
11+ * This object provides a utility for producing rich Error messages within
12+ * Angular. It can be called as follows:
13+ *
14+ * var exampleMinErr = minErr('example');
15+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
16+ *
17+ * The above creates an instance of minErr in the example namespace. The
18+ * resulting error will have a namespaced error code of example.one. The
19+ * resulting error will replace {0} with the value of foo, and {1} with the
20+ * value of bar. The object is not restricted in the number of arguments it can
21+ * take.
22+ *
23+ * If fewer arguments are specified than necessary for interpolation, the extra
24+ * interpolation markers will be preserved in the final string.
25+ *
26+ * Since data will be parsed statically during a build step, some restrictions
27+ * are applied with respect to how minErr instances are created and called.
28+ * Instances should have names of the form namespaceMinErr for a minErr created
29+ * using minErr('namespace') . Error codes, namespaces and template strings
30+ * should all be static strings, not variables or general expressions.
31+ *
32+ * @param {string} module The namespace to use for the new minErr instance.
33+ * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
34+ * error from returned function, for cases when a particular type of error is useful.
35+ * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
36+ */
37+
38+function minErr(module, ErrorConstructor) {
39+ ErrorConstructor = ErrorConstructor || Error;
40+ return function() {
41+ var SKIP_INDEXES = 2;
42+
43+ var templateArgs = arguments,
44+ code = templateArgs[0],
45+ message = '[' + (module ? module + ':' : '') + code + '] ',
46+ template = templateArgs[1],
47+ paramPrefix, i;
48+
49+ message += template.replace(/\{\d+\}/g, function(match) {
50+ var index = +match.slice(1, -1),
51+ shiftedIndex = index + SKIP_INDEXES;
52+
53+ if (shiftedIndex < templateArgs.length) {
54+ return toDebugString(templateArgs[shiftedIndex]);
55+ }
56+
57+ return match;
58+ });
59+
60+ message += '\nhttp://errors.angularjs.org/1.5.8/' +
61+ (module ? module + '/' : '') + code;
62+
63+ for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
64+ message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
65+ encodeURIComponent(toDebugString(templateArgs[i]));
66+ }
67+
68+ return new ErrorConstructor(message);
69+ };
70+}
71+
72+/* We need to tell jshint what variables are being exported */
73+/* global angular: true,
74+ msie: true,
75+ jqLite: true,
76+ jQuery: true,
77+ slice: true,
78+ splice: true,
79+ push: true,
80+ toString: true,
81+ ngMinErr: true,
82+ angularModule: true,
83+ uid: true,
84+ REGEX_STRING_REGEXP: true,
85+ VALIDITY_STATE_PROPERTY: true,
86+
87+ lowercase: true,
88+ uppercase: true,
89+ manualLowercase: true,
90+ manualUppercase: true,
91+ nodeName_: true,
92+ isArrayLike: true,
93+ forEach: true,
94+ forEachSorted: true,
95+ reverseParams: true,
96+ nextUid: true,
97+ setHashKey: true,
98+ extend: true,
99+ toInt: true,
100+ inherit: true,
101+ merge: true,
102+ noop: true,
103+ identity: true,
104+ valueFn: true,
105+ isUndefined: true,
106+ isDefined: true,
107+ isObject: true,
108+ isBlankObject: true,
109+ isString: true,
110+ isNumber: true,
111+ isDate: true,
112+ isArray: true,
113+ isFunction: true,
114+ isRegExp: true,
115+ isWindow: true,
116+ isScope: true,
117+ isFile: true,
118+ isFormData: true,
119+ isBlob: true,
120+ isBoolean: true,
121+ isPromiseLike: true,
122+ trim: true,
123+ escapeForRegexp: true,
124+ isElement: true,
125+ makeMap: true,
126+ includes: true,
127+ arrayRemove: true,
128+ copy: true,
129+ equals: true,
130+ csp: true,
131+ jq: true,
132+ concat: true,
133+ sliceArgs: true,
134+ bind: true,
135+ toJsonReplacer: true,
136+ toJson: true,
137+ fromJson: true,
138+ convertTimezoneToLocal: true,
139+ timezoneToOffset: true,
140+ startingTag: true,
141+ tryDecodeURIComponent: true,
142+ parseKeyValue: true,
143+ toKeyValue: true,
144+ encodeUriSegment: true,
145+ encodeUriQuery: true,
146+ angularInit: true,
147+ bootstrap: true,
148+ getTestability: true,
149+ snake_case: true,
150+ bindJQuery: true,
151+ assertArg: true,
152+ assertArgFn: true,
153+ assertNotHasOwnProperty: true,
154+ getter: true,
155+ getBlockNodes: true,
156+ hasOwnProperty: true,
157+ createMap: true,
158+
159+ NODE_TYPE_ELEMENT: true,
160+ NODE_TYPE_ATTRIBUTE: true,
161+ NODE_TYPE_TEXT: true,
162+ NODE_TYPE_COMMENT: true,
163+ NODE_TYPE_DOCUMENT: true,
164+ NODE_TYPE_DOCUMENT_FRAGMENT: true,
165+*/
166+
167+////////////////////////////////////
168+
169+/**
170+ * @ngdoc module
171+ * @name ng
172+ * @module ng
173+ * @installation
174+ * @description
175+ *
176+ * # ng (core module)
177+ * The ng module is loaded by default when an AngularJS application is started. The module itself
178+ * contains the essential components for an AngularJS application to function. The table below
179+ * lists a high level breakdown of each of the services/factories, filters, directives and testing
180+ * components available within this core module.
181+ *
182+ * <div doc-module-components="ng"></div>
183+ */
184+
185+var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
186+
187+// The name of a form control's ValidityState property.
188+// This is used so that it's possible for internal tests to create mock ValidityStates.
189+var VALIDITY_STATE_PROPERTY = 'validity';
190+
191+var hasOwnProperty = Object.prototype.hasOwnProperty;
192+
193+var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
194+var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
195+
196+
197+var manualLowercase = function(s) {
198+ /* jshint bitwise: false */
199+ return isString(s)
200+ ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
201+ : s;
202+};
203+var manualUppercase = function(s) {
204+ /* jshint bitwise: false */
205+ return isString(s)
206+ ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
207+ : s;
208+};
209+
210+
211+// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
212+// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
213+// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
214+if ('i' !== 'I'.toLowerCase()) {
215+ lowercase = manualLowercase;
216+ uppercase = manualUppercase;
217+}
218+
219+
220+var
221+ msie, // holds major version number for IE, or NaN if UA is not IE.
222+ jqLite, // delay binding since jQuery could be loaded after us.
223+ jQuery, // delay binding
224+ slice = [].slice,
225+ splice = [].splice,
226+ push = [].push,
227+ toString = Object.prototype.toString,
228+ getPrototypeOf = Object.getPrototypeOf,
229+ ngMinErr = minErr('ng'),
230+
231+ /** @name angular */
232+ angular = window.angular || (window.angular = {}),
233+ angularModule,
234+ uid = 0;
235+
236+/**
237+ * documentMode is an IE-only property
238+ * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
239+ */
240+msie = window.document.documentMode;
241+
242+
243+/**
244+ * @private
245+ * @param {*} obj
246+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
247+ * String ...)
248+ */
249+function isArrayLike(obj) {
250+
251+ // `null`, `undefined` and `window` are not array-like
252+ if (obj == null || isWindow(obj)) return false;
253+
254+ // arrays, strings and jQuery/jqLite objects are array like
255+ // * jqLite is either the jQuery or jqLite constructor function
256+ // * we have to check the existence of jqLite first as this method is called
257+ // via the forEach method when constructing the jqLite object in the first place
258+ if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
259+
260+ // Support: iOS 8.2 (not reproducible in simulator)
261+ // "length" in obj used to prevent JIT error (gh-11508)
262+ var length = "length" in Object(obj) && obj.length;
263+
264+ // NodeList objects (with `item` method) and
265+ // other objects with suitable length characteristics are array-like
266+ return isNumber(length) &&
267+ (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item == 'function');
268+
269+}
270+
271+/**
272+ * @ngdoc function
273+ * @name angular.forEach
274+ * @module ng
275+ * @kind function
276+ *
277+ * @description
278+ * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
279+ * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
280+ * is the value of an object property or an array element, `key` is the object property key or
281+ * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
282+ *
283+ * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
284+ * using the `hasOwnProperty` method.
285+ *
286+ * Unlike ES262's
287+ * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
288+ * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
289+ * return the value provided.
290+ *
291+ ```js
292+ var values = {name: 'misko', gender: 'male'};
293+ var log = [];
294+ angular.forEach(values, function(value, key) {
295+ this.push(key + ': ' + value);
296+ }, log);
297+ expect(log).toEqual(['name: misko', 'gender: male']);
298+ ```
299+ *
300+ * @param {Object|Array} obj Object to iterate over.
301+ * @param {Function} iterator Iterator function.
302+ * @param {Object=} context Object to become context (`this`) for the iterator function.
303+ * @returns {Object|Array} Reference to `obj`.
304+ */
305+
306+function forEach(obj, iterator, context) {
307+ var key, length;
308+ if (obj) {
309+ if (isFunction(obj)) {
310+ for (key in obj) {
311+ // Need to check if hasOwnProperty exists,
312+ // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
313+ if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
314+ iterator.call(context, obj[key], key, obj);
315+ }
316+ }
317+ } else if (isArray(obj) || isArrayLike(obj)) {
318+ var isPrimitive = typeof obj !== 'object';
319+ for (key = 0, length = obj.length; key < length; key++) {
320+ if (isPrimitive || key in obj) {
321+ iterator.call(context, obj[key], key, obj);
322+ }
323+ }
324+ } else if (obj.forEach && obj.forEach !== forEach) {
325+ obj.forEach(iterator, context, obj);
326+ } else if (isBlankObject(obj)) {
327+ // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
328+ for (key in obj) {
329+ iterator.call(context, obj[key], key, obj);
330+ }
331+ } else if (typeof obj.hasOwnProperty === 'function') {
332+ // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
333+ for (key in obj) {
334+ if (obj.hasOwnProperty(key)) {
335+ iterator.call(context, obj[key], key, obj);
336+ }
337+ }
338+ } else {
339+ // Slow path for objects which do not have a method `hasOwnProperty`
340+ for (key in obj) {
341+ if (hasOwnProperty.call(obj, key)) {
342+ iterator.call(context, obj[key], key, obj);
343+ }
344+ }
345+ }
346+ }
347+ return obj;
348+}
349+
350+function forEachSorted(obj, iterator, context) {
351+ var keys = Object.keys(obj).sort();
352+ for (var i = 0; i < keys.length; i++) {
353+ iterator.call(context, obj[keys[i]], keys[i]);
354+ }
355+ return keys;
356+}
357+
358+
359+/**
360+ * when using forEach the params are value, key, but it is often useful to have key, value.
361+ * @param {function(string, *)} iteratorFn
362+ * @returns {function(*, string)}
363+ */
364+function reverseParams(iteratorFn) {
365+ return function(value, key) {iteratorFn(key, value);};
366+}
367+
368+/**
369+ * A consistent way of creating unique IDs in angular.
370+ *
371+ * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
372+ * we hit number precision issues in JavaScript.
373+ *
374+ * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
375+ *
376+ * @returns {number} an unique alpha-numeric string
377+ */
378+function nextUid() {
379+ return ++uid;
380+}
381+
382+
383+/**
384+ * Set or clear the hashkey for an object.
385+ * @param obj object
386+ * @param h the hashkey (!truthy to delete the hashkey)
387+ */
388+function setHashKey(obj, h) {
389+ if (h) {
390+ obj.$$hashKey = h;
391+ } else {
392+ delete obj.$$hashKey;
393+ }
394+}
395+
396+
397+function baseExtend(dst, objs, deep) {
398+ var h = dst.$$hashKey;
399+
400+ for (var i = 0, ii = objs.length; i < ii; ++i) {
401+ var obj = objs[i];
402+ if (!isObject(obj) && !isFunction(obj)) continue;
403+ var keys = Object.keys(obj);
404+ for (var j = 0, jj = keys.length; j < jj; j++) {
405+ var key = keys[j];
406+ var src = obj[key];
407+
408+ if (deep && isObject(src)) {
409+ if (isDate(src)) {
410+ dst[key] = new Date(src.valueOf());
411+ } else if (isRegExp(src)) {
412+ dst[key] = new RegExp(src);
413+ } else if (src.nodeName) {
414+ dst[key] = src.cloneNode(true);
415+ } else if (isElement(src)) {
416+ dst[key] = src.clone();
417+ } else {
418+ if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
419+ baseExtend(dst[key], [src], true);
420+ }
421+ } else {
422+ dst[key] = src;
423+ }
424+ }
425+ }
426+
427+ setHashKey(dst, h);
428+ return dst;
429+}
430+
431+/**
432+ * @ngdoc function
433+ * @name angular.extend
434+ * @module ng
435+ * @kind function
436+ *
437+ * @description
438+ * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
439+ * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
440+ * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
441+ *
442+ * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
443+ * {@link angular.merge} for this.
444+ *
445+ * @param {Object} dst Destination object.
446+ * @param {...Object} src Source object(s).
447+ * @returns {Object} Reference to `dst`.
448+ */
449+function extend(dst) {
450+ return baseExtend(dst, slice.call(arguments, 1), false);
451+}
452+
453+
454+/**
455+* @ngdoc function
456+* @name angular.merge
457+* @module ng
458+* @kind function
459+*
460+* @description
461+* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
462+* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
463+* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
464+*
465+* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
466+* objects, performing a deep copy.
467+*
468+* @param {Object} dst Destination object.
469+* @param {...Object} src Source object(s).
470+* @returns {Object} Reference to `dst`.
471+*/
472+function merge(dst) {
473+ return baseExtend(dst, slice.call(arguments, 1), true);
474+}
475+
476+
477+
478+function toInt(str) {
479+ return parseInt(str, 10);
480+}
481+
482+
483+function inherit(parent, extra) {
484+ return extend(Object.create(parent), extra);
485+}
486+
487+/**
488+ * @ngdoc function
489+ * @name angular.noop
490+ * @module ng
491+ * @kind function
492+ *
493+ * @description
494+ * A function that performs no operations. This function can be useful when writing code in the
495+ * functional style.
496+ ```js
497+ function foo(callback) {
498+ var result = calculateResult();
499+ (callback || angular.noop)(result);
500+ }
501+ ```
502+ */
503+function noop() {}
504+noop.$inject = [];
505+
506+
507+/**
508+ * @ngdoc function
509+ * @name angular.identity
510+ * @module ng
511+ * @kind function
512+ *
513+ * @description
514+ * A function that returns its first argument. This function is useful when writing code in the
515+ * functional style.
516+ *
517+ ```js
518+ function transformer(transformationFn, value) {
519+ return (transformationFn || angular.identity)(value);
520+ };
521+
522+ // E.g.
523+ function getResult(fn, input) {
524+ return (fn || angular.identity)(input);
525+ };
526+
527+ getResult(function(n) { return n * 2; }, 21); // returns 42
528+ getResult(null, 21); // returns 21
529+ getResult(undefined, 21); // returns 21
530+ ```
531+ *
532+ * @param {*} value to be returned.
533+ * @returns {*} the value passed in.
534+ */
535+function identity($) {return $;}
536+identity.$inject = [];
537+
538+
539+function valueFn(value) {return function valueRef() {return value;};}
540+
541+function hasCustomToString(obj) {
542+ return isFunction(obj.toString) && obj.toString !== toString;
543+}
544+
545+
546+/**
547+ * @ngdoc function
548+ * @name angular.isUndefined
549+ * @module ng
550+ * @kind function
551+ *
552+ * @description
553+ * Determines if a reference is undefined.
554+ *
555+ * @param {*} value Reference to check.
556+ * @returns {boolean} True if `value` is undefined.
557+ */
558+function isUndefined(value) {return typeof value === 'undefined';}
559+
560+
561+/**
562+ * @ngdoc function
563+ * @name angular.isDefined
564+ * @module ng
565+ * @kind function
566+ *
567+ * @description
568+ * Determines if a reference is defined.
569+ *
570+ * @param {*} value Reference to check.
571+ * @returns {boolean} True if `value` is defined.
572+ */
573+function isDefined(value) {return typeof value !== 'undefined';}
574+
575+
576+/**
577+ * @ngdoc function
578+ * @name angular.isObject
579+ * @module ng
580+ * @kind function
581+ *
582+ * @description
583+ * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
584+ * considered to be objects. Note that JavaScript arrays are objects.
585+ *
586+ * @param {*} value Reference to check.
587+ * @returns {boolean} True if `value` is an `Object` but not `null`.
588+ */
589+function isObject(value) {
590+ // http://jsperf.com/isobject4
591+ return value !== null && typeof value === 'object';
592+}
593+
594+
595+/**
596+ * Determine if a value is an object with a null prototype
597+ *
598+ * @returns {boolean} True if `value` is an `Object` with a null prototype
599+ */
600+function isBlankObject(value) {
601+ return value !== null && typeof value === 'object' && !getPrototypeOf(value);
602+}
603+
604+
605+/**
606+ * @ngdoc function
607+ * @name angular.isString
608+ * @module ng
609+ * @kind function
610+ *
611+ * @description
612+ * Determines if a reference is a `String`.
613+ *
614+ * @param {*} value Reference to check.
615+ * @returns {boolean} True if `value` is a `String`.
616+ */
617+function isString(value) {return typeof value === 'string';}
618+
619+
620+/**
621+ * @ngdoc function
622+ * @name angular.isNumber
623+ * @module ng
624+ * @kind function
625+ *
626+ * @description
627+ * Determines if a reference is a `Number`.
628+ *
629+ * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
630+ *
631+ * If you wish to exclude these then you can use the native
632+ * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
633+ * method.
634+ *
635+ * @param {*} value Reference to check.
636+ * @returns {boolean} True if `value` is a `Number`.
637+ */
638+function isNumber(value) {return typeof value === 'number';}
639+
640+
641+/**
642+ * @ngdoc function
643+ * @name angular.isDate
644+ * @module ng
645+ * @kind function
646+ *
647+ * @description
648+ * Determines if a value is a date.
649+ *
650+ * @param {*} value Reference to check.
651+ * @returns {boolean} True if `value` is a `Date`.
652+ */
653+function isDate(value) {
654+ return toString.call(value) === '[object Date]';
655+}
656+
657+
658+/**
659+ * @ngdoc function
660+ * @name angular.isArray
661+ * @module ng
662+ * @kind function
663+ *
664+ * @description
665+ * Determines if a reference is an `Array`.
666+ *
667+ * @param {*} value Reference to check.
668+ * @returns {boolean} True if `value` is an `Array`.
669+ */
670+var isArray = Array.isArray;
671+
672+/**
673+ * @ngdoc function
674+ * @name angular.isFunction
675+ * @module ng
676+ * @kind function
677+ *
678+ * @description
679+ * Determines if a reference is a `Function`.
680+ *
681+ * @param {*} value Reference to check.
682+ * @returns {boolean} True if `value` is a `Function`.
683+ */
684+function isFunction(value) {return typeof value === 'function';}
685+
686+
687+/**
688+ * Determines if a value is a regular expression object.
689+ *
690+ * @private
691+ * @param {*} value Reference to check.
692+ * @returns {boolean} True if `value` is a `RegExp`.
693+ */
694+function isRegExp(value) {
695+ return toString.call(value) === '[object RegExp]';
696+}
697+
698+
699+/**
700+ * Checks if `obj` is a window object.
701+ *
702+ * @private
703+ * @param {*} obj Object to check
704+ * @returns {boolean} True if `obj` is a window obj.
705+ */
706+function isWindow(obj) {
707+ return obj && obj.window === obj;
708+}
709+
710+
711+function isScope(obj) {
712+ return obj && obj.$evalAsync && obj.$watch;
713+}
714+
715+
716+function isFile(obj) {
717+ return toString.call(obj) === '[object File]';
718+}
719+
720+
721+function isFormData(obj) {
722+ return toString.call(obj) === '[object FormData]';
723+}
724+
725+
726+function isBlob(obj) {
727+ return toString.call(obj) === '[object Blob]';
728+}
729+
730+
731+function isBoolean(value) {
732+ return typeof value === 'boolean';
733+}
734+
735+
736+function isPromiseLike(obj) {
737+ return obj && isFunction(obj.then);
738+}
739+
740+
741+var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/;
742+function isTypedArray(value) {
743+ return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
744+}
745+
746+function isArrayBuffer(obj) {
747+ return toString.call(obj) === '[object ArrayBuffer]';
748+}
749+
750+
751+var trim = function(value) {
752+ return isString(value) ? value.trim() : value;
753+};
754+
755+// Copied from:
756+// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
757+// Prereq: s is a string.
758+var escapeForRegexp = function(s) {
759+ return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
760+ replace(/\x08/g, '\\x08');
761+};
762+
763+
764+/**
765+ * @ngdoc function
766+ * @name angular.isElement
767+ * @module ng
768+ * @kind function
769+ *
770+ * @description
771+ * Determines if a reference is a DOM element (or wrapped jQuery element).
772+ *
773+ * @param {*} value Reference to check.
774+ * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
775+ */
776+function isElement(node) {
777+ return !!(node &&
778+ (node.nodeName // We are a direct element.
779+ || (node.prop && node.attr && node.find))); // We have an on and find method part of jQuery API.
780+}
781+
782+/**
783+ * @param str 'key1,key2,...'
784+ * @returns {object} in the form of {key1:true, key2:true, ...}
785+ */
786+function makeMap(str) {
787+ var obj = {}, items = str.split(','), i;
788+ for (i = 0; i < items.length; i++) {
789+ obj[items[i]] = true;
790+ }
791+ return obj;
792+}
793+
794+
795+function nodeName_(element) {
796+ return lowercase(element.nodeName || (element[0] && element[0].nodeName));
797+}
798+
799+function includes(array, obj) {
800+ return Array.prototype.indexOf.call(array, obj) != -1;
801+}
802+
803+function arrayRemove(array, value) {
804+ var index = array.indexOf(value);
805+ if (index >= 0) {
806+ array.splice(index, 1);
807+ }
808+ return index;
809+}
810+
811+/**
812+ * @ngdoc function
813+ * @name angular.copy
814+ * @module ng
815+ * @kind function
816+ *
817+ * @description
818+ * Creates a deep copy of `source`, which should be an object or an array.
819+ *
820+ * * If no destination is supplied, a copy of the object or array is created.
821+ * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
822+ * are deleted and then all elements/properties from the source are copied to it.
823+ * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
824+ * * If `source` is identical to `destination` an exception will be thrown.
825+ *
826+ * <br />
827+ * <div class="alert alert-warning">
828+ * Only enumerable properties are taken into account. Non-enumerable properties (both on `source`
829+ * and on `destination`) will be ignored.
830+ * </div>
831+ *
832+ * @param {*} source The source that will be used to make a copy.
833+ * Can be any type, including primitives, `null`, and `undefined`.
834+ * @param {(Object|Array)=} destination Destination into which the source is copied. If
835+ * provided, must be of the same type as `source`.
836+ * @returns {*} The copy or updated `destination`, if `destination` was specified.
837+ *
838+ * @example
839+ <example module="copyExample">
840+ <file name="index.html">
841+ <div ng-controller="ExampleController">
842+ <form novalidate class="simple-form">
843+ <label>Name: <input type="text" ng-model="user.name" /></label><br />
844+ <label>Age: <input type="number" ng-model="user.age" /></label><br />
845+ Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
846+ <label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
847+ <button ng-click="reset()">RESET</button>
848+ <button ng-click="update(user)">SAVE</button>
849+ </form>
850+ <pre>form = {{user | json}}</pre>
851+ <pre>master = {{master | json}}</pre>
852+ </div>
853+ </file>
854+ <file name="script.js">
855+ // Module: copyExample
856+ angular.
857+ module('copyExample', []).
858+ controller('ExampleController', ['$scope', function($scope) {
859+ $scope.master = {};
860+
861+ $scope.reset = function() {
862+ // Example with 1 argument
863+ $scope.user = angular.copy($scope.master);
864+ };
865+
866+ $scope.update = function(user) {
867+ // Example with 2 arguments
868+ angular.copy(user, $scope.master);
869+ };
870+
871+ $scope.reset();
872+ }]);
873+ </file>
874+ </example>
875+ */
876+function copy(source, destination) {
877+ var stackSource = [];
878+ var stackDest = [];
879+
880+ if (destination) {
881+ if (isTypedArray(destination) || isArrayBuffer(destination)) {
882+ throw ngMinErr('cpta', "Can't copy! TypedArray destination cannot be mutated.");
883+ }
884+ if (source === destination) {
885+ throw ngMinErr('cpi', "Can't copy! Source and destination are identical.");
886+ }
887+
888+ // Empty the destination object
889+ if (isArray(destination)) {
890+ destination.length = 0;
891+ } else {
892+ forEach(destination, function(value, key) {
893+ if (key !== '$$hashKey') {
894+ delete destination[key];
895+ }
896+ });
897+ }
898+
899+ stackSource.push(source);
900+ stackDest.push(destination);
901+ return copyRecurse(source, destination);
902+ }
903+
904+ return copyElement(source);
905+
906+ function copyRecurse(source, destination) {
907+ var h = destination.$$hashKey;
908+ var key;
909+ if (isArray(source)) {
910+ for (var i = 0, ii = source.length; i < ii; i++) {
911+ destination.push(copyElement(source[i]));
912+ }
913+ } else if (isBlankObject(source)) {
914+ // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
915+ for (key in source) {
916+ destination[key] = copyElement(source[key]);
917+ }
918+ } else if (source && typeof source.hasOwnProperty === 'function') {
919+ // Slow path, which must rely on hasOwnProperty
920+ for (key in source) {
921+ if (source.hasOwnProperty(key)) {
922+ destination[key] = copyElement(source[key]);
923+ }
924+ }
925+ } else {
926+ // Slowest path --- hasOwnProperty can't be called as a method
927+ for (key in source) {
928+ if (hasOwnProperty.call(source, key)) {
929+ destination[key] = copyElement(source[key]);
930+ }
931+ }
932+ }
933+ setHashKey(destination, h);
934+ return destination;
935+ }
936+
937+ function copyElement(source) {
938+ // Simple values
939+ if (!isObject(source)) {
940+ return source;
941+ }
942+
943+ // Already copied values
944+ var index = stackSource.indexOf(source);
945+ if (index !== -1) {
946+ return stackDest[index];
947+ }
948+
949+ if (isWindow(source) || isScope(source)) {
950+ throw ngMinErr('cpws',
951+ "Can't copy! Making copies of Window or Scope instances is not supported.");
952+ }
953+
954+ var needsRecurse = false;
955+ var destination = copyType(source);
956+
957+ if (destination === undefined) {
958+ destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
959+ needsRecurse = true;
960+ }
961+
962+ stackSource.push(source);
963+ stackDest.push(destination);
964+
965+ return needsRecurse
966+ ? copyRecurse(source, destination)
967+ : destination;
968+ }
969+
970+ function copyType(source) {
971+ switch (toString.call(source)) {
972+ case '[object Int8Array]':
973+ case '[object Int16Array]':
974+ case '[object Int32Array]':
975+ case '[object Float32Array]':
976+ case '[object Float64Array]':
977+ case '[object Uint8Array]':
978+ case '[object Uint8ClampedArray]':
979+ case '[object Uint16Array]':
980+ case '[object Uint32Array]':
981+ return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);
982+
983+ case '[object ArrayBuffer]':
984+ //Support: IE10
985+ if (!source.slice) {
986+ var copied = new ArrayBuffer(source.byteLength);
987+ new Uint8Array(copied).set(new Uint8Array(source));
988+ return copied;
989+ }
990+ return source.slice(0);
991+
992+ case '[object Boolean]':
993+ case '[object Number]':
994+ case '[object String]':
995+ case '[object Date]':
996+ return new source.constructor(source.valueOf());
997+
998+ case '[object RegExp]':
999+ var re = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
1000+ re.lastIndex = source.lastIndex;
1001+ return re;
1002+
1003+ case '[object Blob]':
1004+ return new source.constructor([source], {type: source.type});
1005+ }
1006+
1007+ if (isFunction(source.cloneNode)) {
1008+ return source.cloneNode(true);
1009+ }
1010+ }
1011+}
1012+
1013+
1014+/**
1015+ * @ngdoc function
1016+ * @name angular.equals
1017+ * @module ng
1018+ * @kind function
1019+ *
1020+ * @description
1021+ * Determines if two objects or two values are equivalent. Supports value types, regular
1022+ * expressions, arrays and objects.
1023+ *
1024+ * Two objects or values are considered equivalent if at least one of the following is true:
1025+ *
1026+ * * Both objects or values pass `===` comparison.
1027+ * * Both objects or values are of the same type and all of their properties are equal by
1028+ * comparing them with `angular.equals`.
1029+ * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
1030+ * * Both values represent the same regular expression (In JavaScript,
1031+ * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
1032+ * representation matches).
1033+ *
1034+ * During a property comparison, properties of `function` type and properties with names
1035+ * that begin with `$` are ignored.
1036+ *
1037+ * Scope and DOMWindow objects are being compared only by identify (`===`).
1038+ *
1039+ * @param {*} o1 Object or value to compare.
1040+ * @param {*} o2 Object or value to compare.
1041+ * @returns {boolean} True if arguments are equal.
1042+ *
1043+ * @example
1044+ <example module="equalsExample" name="equalsExample">
1045+ <file name="index.html">
1046+ <div ng-controller="ExampleController">
1047+ <form novalidate>
1048+ <h3>User 1</h3>
1049+ Name: <input type="text" ng-model="user1.name">
1050+ Age: <input type="number" ng-model="user1.age">
1051+
1052+ <h3>User 2</h3>
1053+ Name: <input type="text" ng-model="user2.name">
1054+ Age: <input type="number" ng-model="user2.age">
1055+
1056+ <div>
1057+ <br/>
1058+ <input type="button" value="Compare" ng-click="compare()">
1059+ </div>
1060+ User 1: <pre>{{user1 | json}}</pre>
1061+ User 2: <pre>{{user2 | json}}</pre>
1062+ Equal: <pre>{{result}}</pre>
1063+ </form>
1064+ </div>
1065+ </file>
1066+ <file name="script.js">
1067+ angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {
1068+ $scope.user1 = {};
1069+ $scope.user2 = {};
1070+ $scope.result;
1071+ $scope.compare = function() {
1072+ $scope.result = angular.equals($scope.user1, $scope.user2);
1073+ };
1074+ }]);
1075+ </file>
1076+ </example>
1077+ */
1078+function equals(o1, o2) {
1079+ if (o1 === o2) return true;
1080+ if (o1 === null || o2 === null) return false;
1081+ if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
1082+ var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
1083+ if (t1 == t2 && t1 == 'object') {
1084+ if (isArray(o1)) {
1085+ if (!isArray(o2)) return false;
1086+ if ((length = o1.length) == o2.length) {
1087+ for (key = 0; key < length; key++) {
1088+ if (!equals(o1[key], o2[key])) return false;
1089+ }
1090+ return true;
1091+ }
1092+ } else if (isDate(o1)) {
1093+ if (!isDate(o2)) return false;
1094+ return equals(o1.getTime(), o2.getTime());
1095+ } else if (isRegExp(o1)) {
1096+ if (!isRegExp(o2)) return false;
1097+ return o1.toString() == o2.toString();
1098+ } else {
1099+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1100+ isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1101+ keySet = createMap();
1102+ for (key in o1) {
1103+ if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1104+ if (!equals(o1[key], o2[key])) return false;
1105+ keySet[key] = true;
1106+ }
1107+ for (key in o2) {
1108+ if (!(key in keySet) &&
1109+ key.charAt(0) !== '$' &&
1110+ isDefined(o2[key]) &&
1111+ !isFunction(o2[key])) return false;
1112+ }
1113+ return true;
1114+ }
1115+ }
1116+ return false;
1117+}
1118+
1119+var csp = function() {
1120+ if (!isDefined(csp.rules)) {
1121+
1122+
1123+ var ngCspElement = (window.document.querySelector('[ng-csp]') ||
1124+ window.document.querySelector('[data-ng-csp]'));
1125+
1126+ if (ngCspElement) {
1127+ var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
1128+ ngCspElement.getAttribute('data-ng-csp');
1129+ csp.rules = {
1130+ noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
1131+ noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
1132+ };
1133+ } else {
1134+ csp.rules = {
1135+ noUnsafeEval: noUnsafeEval(),
1136+ noInlineStyle: false
1137+ };
1138+ }
1139+ }
1140+
1141+ return csp.rules;
1142+
1143+ function noUnsafeEval() {
1144+ try {
1145+ /* jshint -W031, -W054 */
1146+ new Function('');
1147+ /* jshint +W031, +W054 */
1148+ return false;
1149+ } catch (e) {
1150+ return true;
1151+ }
1152+ }
1153+};
1154+
1155+/**
1156+ * @ngdoc directive
1157+ * @module ng
1158+ * @name ngJq
1159+ *
1160+ * @element ANY
1161+ * @param {string=} ngJq the name of the library available under `window`
1162+ * to be used for angular.element
1163+ * @description
1164+ * Use this directive to force the angular.element library. This should be
1165+ * used to force either jqLite by leaving ng-jq blank or setting the name of
1166+ * the jquery variable under window (eg. jQuery).
1167+ *
1168+ * Since angular looks for this directive when it is loaded (doesn't wait for the
1169+ * DOMContentLoaded event), it must be placed on an element that comes before the script
1170+ * which loads angular. Also, only the first instance of `ng-jq` will be used and all
1171+ * others ignored.
1172+ *
1173+ * @example
1174+ * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
1175+ ```html
1176+ <!doctype html>
1177+ <html ng-app ng-jq>
1178+ ...
1179+ ...
1180+ </html>
1181+ ```
1182+ * @example
1183+ * This example shows how to use a jQuery based library of a different name.
1184+ * The library name must be available at the top most 'window'.
1185+ ```html
1186+ <!doctype html>
1187+ <html ng-app ng-jq="jQueryLib">
1188+ ...
1189+ ...
1190+ </html>
1191+ ```
1192+ */
1193+var jq = function() {
1194+ if (isDefined(jq.name_)) return jq.name_;
1195+ var el;
1196+ var i, ii = ngAttrPrefixes.length, prefix, name;
1197+ for (i = 0; i < ii; ++i) {
1198+ prefix = ngAttrPrefixes[i];
1199+ if (el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
1200+ name = el.getAttribute(prefix + 'jq');
1201+ break;
1202+ }
1203+ }
1204+
1205+ return (jq.name_ = name);
1206+};
1207+
1208+function concat(array1, array2, index) {
1209+ return array1.concat(slice.call(array2, index));
1210+}
1211+
1212+function sliceArgs(args, startIndex) {
1213+ return slice.call(args, startIndex || 0);
1214+}
1215+
1216+
1217+/* jshint -W101 */
1218+/**
1219+ * @ngdoc function
1220+ * @name angular.bind
1221+ * @module ng
1222+ * @kind function
1223+ *
1224+ * @description
1225+ * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
1226+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
1227+ * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
1228+ * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
1229+ *
1230+ * @param {Object} self Context which `fn` should be evaluated in.
1231+ * @param {function()} fn Function to be bound.
1232+ * @param {...*} args Optional arguments to be prebound to the `fn` function call.
1233+ * @returns {function()} Function that wraps the `fn` with all the specified bindings.
1234+ */
1235+/* jshint +W101 */
1236+function bind(self, fn) {
1237+ var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
1238+ if (isFunction(fn) && !(fn instanceof RegExp)) {
1239+ return curryArgs.length
1240+ ? function() {
1241+ return arguments.length
1242+ ? fn.apply(self, concat(curryArgs, arguments, 0))
1243+ : fn.apply(self, curryArgs);
1244+ }
1245+ : function() {
1246+ return arguments.length
1247+ ? fn.apply(self, arguments)
1248+ : fn.call(self);
1249+ };
1250+ } else {
1251+ // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).
1252+ return fn;
1253+ }
1254+}
1255+
1256+
1257+function toJsonReplacer(key, value) {
1258+ var val = value;
1259+
1260+ if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
1261+ val = undefined;
1262+ } else if (isWindow(value)) {
1263+ val = '$WINDOW';
1264+ } else if (value && window.document === value) {
1265+ val = '$DOCUMENT';
1266+ } else if (isScope(value)) {
1267+ val = '$SCOPE';
1268+ }
1269+
1270+ return val;
1271+}
1272+
1273+
1274+/**
1275+ * @ngdoc function
1276+ * @name angular.toJson
1277+ * @module ng
1278+ * @kind function
1279+ *
1280+ * @description
1281+ * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
1282+ * stripped since angular uses this notation internally.
1283+ *
1284+ * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
1285+ * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
1286+ * If set to an integer, the JSON output will contain that many spaces per indentation.
1287+ * @returns {string|undefined} JSON-ified string representing `obj`.
1288+ * @knownIssue
1289+ *
1290+ * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`
1291+ * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the
1292+ * `Date.prototype.toJSON` method as follows:
1293+ *
1294+ * ```
1295+ * var _DatetoJSON = Date.prototype.toJSON;
1296+ * Date.prototype.toJSON = function() {
1297+ * try {
1298+ * return _DatetoJSON.call(this);
1299+ * } catch(e) {
1300+ * if (e instanceof RangeError) {
1301+ * return null;
1302+ * }
1303+ * throw e;
1304+ * }
1305+ * };
1306+ * ```
1307+ *
1308+ * See https://github.com/angular/angular.js/pull/14221 for more information.
1309+ */
1310+function toJson(obj, pretty) {
1311+ if (isUndefined(obj)) return undefined;
1312+ if (!isNumber(pretty)) {
1313+ pretty = pretty ? 2 : null;
1314+ }
1315+ return JSON.stringify(obj, toJsonReplacer, pretty);
1316+}
1317+
1318+
1319+/**
1320+ * @ngdoc function
1321+ * @name angular.fromJson
1322+ * @module ng
1323+ * @kind function
1324+ *
1325+ * @description
1326+ * Deserializes a JSON string.
1327+ *
1328+ * @param {string} json JSON string to deserialize.
1329+ * @returns {Object|Array|string|number} Deserialized JSON string.
1330+ */
1331+function fromJson(json) {
1332+ return isString(json)
1333+ ? JSON.parse(json)
1334+ : json;
1335+}
1336+
1337+
1338+var ALL_COLONS = /:/g;
1339+function timezoneToOffset(timezone, fallback) {
1340+ // IE/Edge do not "understand" colon (`:`) in timezone
1341+ timezone = timezone.replace(ALL_COLONS, '');
1342+ var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
1343+ return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
1344+}
1345+
1346+
1347+function addDateMinutes(date, minutes) {
1348+ date = new Date(date.getTime());
1349+ date.setMinutes(date.getMinutes() + minutes);
1350+ return date;
1351+}
1352+
1353+
1354+function convertTimezoneToLocal(date, timezone, reverse) {
1355+ reverse = reverse ? -1 : 1;
1356+ var dateTimezoneOffset = date.getTimezoneOffset();
1357+ var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
1358+ return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
1359+}
1360+
1361+
1362+/**
1363+ * @returns {string} Returns the string representation of the element.
1364+ */
1365+function startingTag(element) {
1366+ element = jqLite(element).clone();
1367+ try {
1368+ // turns out IE does not let you set .html() on elements which
1369+ // are not allowed to have children. So we just ignore it.
1370+ element.empty();
1371+ } catch (e) {}
1372+ var elemHtml = jqLite('<div>').append(element).html();
1373+ try {
1374+ return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
1375+ elemHtml.
1376+ match(/^(<[^>]+>)/)[1].
1377+ replace(/^<([\w\-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});
1378+ } catch (e) {
1379+ return lowercase(elemHtml);
1380+ }
1381+
1382+}
1383+
1384+
1385+/////////////////////////////////////////////////
1386+
1387+/**
1388+ * Tries to decode the URI component without throwing an exception.
1389+ *
1390+ * @private
1391+ * @param str value potential URI component to check.
1392+ * @returns {boolean} True if `value` can be decoded
1393+ * with the decodeURIComponent function.
1394+ */
1395+function tryDecodeURIComponent(value) {
1396+ try {
1397+ return decodeURIComponent(value);
1398+ } catch (e) {
1399+ // Ignore any invalid uri component.
1400+ }
1401+}
1402+
1403+
1404+/**
1405+ * Parses an escaped url query string into key-value pairs.
1406+ * @returns {Object.<string,boolean|Array>}
1407+ */
1408+function parseKeyValue(/**string*/keyValue) {
1409+ var obj = {};
1410+ forEach((keyValue || "").split('&'), function(keyValue) {
1411+ var splitPoint, key, val;
1412+ if (keyValue) {
1413+ key = keyValue = keyValue.replace(/\+/g,'%20');
1414+ splitPoint = keyValue.indexOf('=');
1415+ if (splitPoint !== -1) {
1416+ key = keyValue.substring(0, splitPoint);
1417+ val = keyValue.substring(splitPoint + 1);
1418+ }
1419+ key = tryDecodeURIComponent(key);
1420+ if (isDefined(key)) {
1421+ val = isDefined(val) ? tryDecodeURIComponent(val) : true;
1422+ if (!hasOwnProperty.call(obj, key)) {
1423+ obj[key] = val;
1424+ } else if (isArray(obj[key])) {
1425+ obj[key].push(val);
1426+ } else {
1427+ obj[key] = [obj[key],val];
1428+ }
1429+ }
1430+ }
1431+ });
1432+ return obj;
1433+}
1434+
1435+function toKeyValue(obj) {
1436+ var parts = [];
1437+ forEach(obj, function(value, key) {
1438+ if (isArray(value)) {
1439+ forEach(value, function(arrayValue) {
1440+ parts.push(encodeUriQuery(key, true) +
1441+ (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
1442+ });
1443+ } else {
1444+ parts.push(encodeUriQuery(key, true) +
1445+ (value === true ? '' : '=' + encodeUriQuery(value, true)));
1446+ }
1447+ });
1448+ return parts.length ? parts.join('&') : '';
1449+}
1450+
1451+
1452+/**
1453+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
1454+ * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
1455+ * segments:
1456+ * segment = *pchar
1457+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
1458+ * pct-encoded = "%" HEXDIG HEXDIG
1459+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1460+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1461+ * / "*" / "+" / "," / ";" / "="
1462+ */
1463+function encodeUriSegment(val) {
1464+ return encodeUriQuery(val, true).
1465+ replace(/%26/gi, '&').
1466+ replace(/%3D/gi, '=').
1467+ replace(/%2B/gi, '+');
1468+}
1469+
1470+
1471+/**
1472+ * This method is intended for encoding *key* or *value* parts of query component. We need a custom
1473+ * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
1474+ * encoded per http://tools.ietf.org/html/rfc3986:
1475+ * query = *( pchar / "/" / "?" )
1476+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
1477+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1478+ * pct-encoded = "%" HEXDIG HEXDIG
1479+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1480+ * / "*" / "+" / "," / ";" / "="
1481+ */
1482+function encodeUriQuery(val, pctEncodeSpaces) {
1483+ return encodeURIComponent(val).
1484+ replace(/%40/gi, '@').
1485+ replace(/%3A/gi, ':').
1486+ replace(/%24/g, '$').
1487+ replace(/%2C/gi, ',').
1488+ replace(/%3B/gi, ';').
1489+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
1490+}
1491+
1492+var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
1493+
1494+function getNgAttribute(element, ngAttr) {
1495+ var attr, i, ii = ngAttrPrefixes.length;
1496+ for (i = 0; i < ii; ++i) {
1497+ attr = ngAttrPrefixes[i] + ngAttr;
1498+ if (isString(attr = element.getAttribute(attr))) {
1499+ return attr;
1500+ }
1501+ }
1502+ return null;
1503+}
1504+
1505+/**
1506+ * @ngdoc directive
1507+ * @name ngApp
1508+ * @module ng
1509+ *
1510+ * @element ANY
1511+ * @param {angular.Module} ngApp an optional application
1512+ * {@link angular.module module} name to load.
1513+ * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
1514+ * created in "strict-di" mode. This means that the application will fail to invoke functions which
1515+ * do not use explicit function annotation (and are thus unsuitable for minification), as described
1516+ * in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
1517+ * tracking down the root of these bugs.
1518+ *
1519+ * @description
1520+ *
1521+ * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
1522+ * designates the **root element** of the application and is typically placed near the root element
1523+ * of the page - e.g. on the `<body>` or `<html>` tags.
1524+ *
1525+ * There are a few things to keep in mind when using `ngApp`:
1526+ * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
1527+ * found in the document will be used to define the root element to auto-bootstrap as an
1528+ * application. To run multiple applications in an HTML document you must manually bootstrap them using
1529+ * {@link angular.bootstrap} instead.
1530+ * - AngularJS applications cannot be nested within each other.
1531+ * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.
1532+ * This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and
1533+ * {@link ngRoute.ngView `ngView`}.
1534+ * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
1535+ * causing animations to stop working and making the injector inaccessible from outside the app.
1536+ *
1537+ * You can specify an **AngularJS module** to be used as the root module for the application. This
1538+ * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
1539+ * should contain the application code needed or have dependencies on other modules that will
1540+ * contain the code. See {@link angular.module} for more information.
1541+ *
1542+ * In the example below if the `ngApp` directive were not placed on the `html` element then the
1543+ * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
1544+ * would not be resolved to `3`.
1545+ *
1546+ * `ngApp` is the easiest, and most common way to bootstrap an application.
1547+ *
1548+ <example module="ngAppDemo">
1549+ <file name="index.html">
1550+ <div ng-controller="ngAppDemoController">
1551+ I can add: {{a}} + {{b}} = {{ a+b }}
1552+ </div>
1553+ </file>
1554+ <file name="script.js">
1555+ angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
1556+ $scope.a = 1;
1557+ $scope.b = 2;
1558+ });
1559+ </file>
1560+ </example>
1561+ *
1562+ * Using `ngStrictDi`, you would see something like this:
1563+ *
1564+ <example ng-app-included="true">
1565+ <file name="index.html">
1566+ <div ng-app="ngAppStrictDemo" ng-strict-di>
1567+ <div ng-controller="GoodController1">
1568+ I can add: {{a}} + {{b}} = {{ a+b }}
1569+
1570+ <p>This renders because the controller does not fail to
1571+ instantiate, by using explicit annotation style (see
1572+ script.js for details)
1573+ </p>
1574+ </div>
1575+
1576+ <div ng-controller="GoodController2">
1577+ Name: <input ng-model="name"><br />
1578+ Hello, {{name}}!
1579+
1580+ <p>This renders because the controller does not fail to
1581+ instantiate, by using explicit annotation style
1582+ (see script.js for details)
1583+ </p>
1584+ </div>
1585+
1586+ <div ng-controller="BadController">
1587+ I can add: {{a}} + {{b}} = {{ a+b }}
1588+
1589+ <p>The controller could not be instantiated, due to relying
1590+ on automatic function annotations (which are disabled in
1591+ strict mode). As such, the content of this section is not
1592+ interpolated, and there should be an error in your web console.
1593+ </p>
1594+ </div>
1595+ </div>
1596+ </file>
1597+ <file name="script.js">
1598+ angular.module('ngAppStrictDemo', [])
1599+ // BadController will fail to instantiate, due to relying on automatic function annotation,
1600+ // rather than an explicit annotation
1601+ .controller('BadController', function($scope) {
1602+ $scope.a = 1;
1603+ $scope.b = 2;
1604+ })
1605+ // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
1606+ // due to using explicit annotations using the array style and $inject property, respectively.
1607+ .controller('GoodController1', ['$scope', function($scope) {
1608+ $scope.a = 1;
1609+ $scope.b = 2;
1610+ }])
1611+ .controller('GoodController2', GoodController2);
1612+ function GoodController2($scope) {
1613+ $scope.name = "World";
1614+ }
1615+ GoodController2.$inject = ['$scope'];
1616+ </file>
1617+ <file name="style.css">
1618+ div[ng-controller] {
1619+ margin-bottom: 1em;
1620+ -webkit-border-radius: 4px;
1621+ border-radius: 4px;
1622+ border: 1px solid;
1623+ padding: .5em;
1624+ }
1625+ div[ng-controller^=Good] {
1626+ border-color: #d6e9c6;
1627+ background-color: #dff0d8;
1628+ color: #3c763d;
1629+ }
1630+ div[ng-controller^=Bad] {
1631+ border-color: #ebccd1;
1632+ background-color: #f2dede;
1633+ color: #a94442;
1634+ margin-bottom: 0;
1635+ }
1636+ </file>
1637+ </example>
1638+ */
1639+function angularInit(element, bootstrap) {
1640+ var appElement,
1641+ module,
1642+ config = {};
1643+
1644+ // The element `element` has priority over any other element.
1645+ forEach(ngAttrPrefixes, function(prefix) {
1646+ var name = prefix + 'app';
1647+
1648+ if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
1649+ appElement = element;
1650+ module = element.getAttribute(name);
1651+ }
1652+ });
1653+ forEach(ngAttrPrefixes, function(prefix) {
1654+ var name = prefix + 'app';
1655+ var candidate;
1656+
1657+ if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
1658+ appElement = candidate;
1659+ module = candidate.getAttribute(name);
1660+ }
1661+ });
1662+ if (appElement) {
1663+ config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
1664+ bootstrap(appElement, module ? [module] : [], config);
1665+ }
1666+}
1667+
1668+/**
1669+ * @ngdoc function
1670+ * @name angular.bootstrap
1671+ * @module ng
1672+ * @description
1673+ * Use this function to manually start up angular application.
1674+ *
1675+ * For more information, see the {@link guide/bootstrap Bootstrap guide}.
1676+ *
1677+ * Angular will detect if it has been loaded into the browser more than once and only allow the
1678+ * first loaded script to be bootstrapped and will report a warning to the browser console for
1679+ * each of the subsequent scripts. This prevents strange results in applications, where otherwise
1680+ * multiple instances of Angular try to work on the DOM.
1681+ *
1682+ * <div class="alert alert-warning">
1683+ * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
1684+ * They must use {@link ng.directive:ngApp ngApp}.
1685+ * </div>
1686+ *
1687+ * <div class="alert alert-warning">
1688+ * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
1689+ * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
1690+ * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
1691+ * causing animations to stop working and making the injector inaccessible from outside the app.
1692+ * </div>
1693+ *
1694+ * ```html
1695+ * <!doctype html>
1696+ * <html>
1697+ * <body>
1698+ * <div ng-controller="WelcomeController">
1699+ * {{greeting}}
1700+ * </div>
1701+ *
1702+ * <script src="angular.js"></script>
1703+ * <script>
1704+ * var app = angular.module('demo', [])
1705+ * .controller('WelcomeController', function($scope) {
1706+ * $scope.greeting = 'Welcome!';
1707+ * });
1708+ * angular.bootstrap(document, ['demo']);
1709+ * </script>
1710+ * </body>
1711+ * </html>
1712+ * ```
1713+ *
1714+ * @param {DOMElement} element DOM element which is the root of angular application.
1715+ * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
1716+ * Each item in the array should be the name of a predefined module or a (DI annotated)
1717+ * function that will be invoked by the injector as a `config` block.
1718+ * See: {@link angular.module modules}
1719+ * @param {Object=} config an object for defining configuration options for the application. The
1720+ * following keys are supported:
1721+ *
1722+ * * `strictDi` - disable automatic function annotation for the application. This is meant to
1723+ * assist in finding bugs which break minified code. Defaults to `false`.
1724+ *
1725+ * @returns {auto.$injector} Returns the newly created injector for this app.
1726+ */
1727+function bootstrap(element, modules, config) {
1728+ if (!isObject(config)) config = {};
1729+ var defaultConfig = {
1730+ strictDi: false
1731+ };
1732+ config = extend(defaultConfig, config);
1733+ var doBootstrap = function() {
1734+ element = jqLite(element);
1735+
1736+ if (element.injector()) {
1737+ var tag = (element[0] === window.document) ? 'document' : startingTag(element);
1738+ // Encode angle brackets to prevent input from being sanitized to empty string #8683.
1739+ throw ngMinErr(
1740+ 'btstrpd',
1741+ "App already bootstrapped with this element '{0}'",
1742+ tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
1743+ }
1744+
1745+ modules = modules || [];
1746+ modules.unshift(['$provide', function($provide) {
1747+ $provide.value('$rootElement', element);
1748+ }]);
1749+
1750+ if (config.debugInfoEnabled) {
1751+ // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
1752+ modules.push(['$compileProvider', function($compileProvider) {
1753+ $compileProvider.debugInfoEnabled(true);
1754+ }]);
1755+ }
1756+
1757+ modules.unshift('ng');
1758+ var injector = createInjector(modules, config.strictDi);
1759+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
1760+ function bootstrapApply(scope, element, compile, injector) {
1761+ scope.$apply(function() {
1762+ element.data('$injector', injector);
1763+ compile(element)(scope);
1764+ });
1765+ }]
1766+ );
1767+ return injector;
1768+ };
1769+
1770+ var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
1771+ var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
1772+
1773+ if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
1774+ config.debugInfoEnabled = true;
1775+ window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
1776+ }
1777+
1778+ if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
1779+ return doBootstrap();
1780+ }
1781+
1782+ window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
1783+ angular.resumeBootstrap = function(extraModules) {
1784+ forEach(extraModules, function(module) {
1785+ modules.push(module);
1786+ });
1787+ return doBootstrap();
1788+ };
1789+
1790+ if (isFunction(angular.resumeDeferredBootstrap)) {
1791+ angular.resumeDeferredBootstrap();
1792+ }
1793+}
1794+
1795+/**
1796+ * @ngdoc function
1797+ * @name angular.reloadWithDebugInfo
1798+ * @module ng
1799+ * @description
1800+ * Use this function to reload the current application with debug information turned on.
1801+ * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
1802+ *
1803+ * See {@link ng.$compileProvider#debugInfoEnabled} for more.
1804+ */
1805+function reloadWithDebugInfo() {
1806+ window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
1807+ window.location.reload();
1808+}
1809+
1810+/**
1811+ * @name angular.getTestability
1812+ * @module ng
1813+ * @description
1814+ * Get the testability service for the instance of Angular on the given
1815+ * element.
1816+ * @param {DOMElement} element DOM element which is the root of angular application.
1817+ */
1818+function getTestability(rootElement) {
1819+ var injector = angular.element(rootElement).injector();
1820+ if (!injector) {
1821+ throw ngMinErr('test',
1822+ 'no injector found for element argument to getTestability');
1823+ }
1824+ return injector.get('$$testability');
1825+}
1826+
1827+var SNAKE_CASE_REGEXP = /[A-Z]/g;
1828+function snake_case(name, separator) {
1829+ separator = separator || '_';
1830+ return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
1831+ return (pos ? separator : '') + letter.toLowerCase();
1832+ });
1833+}
1834+
1835+var bindJQueryFired = false;
1836+function bindJQuery() {
1837+ var originalCleanData;
1838+
1839+ if (bindJQueryFired) {
1840+ return;
1841+ }
1842+
1843+ // bind to jQuery if present;
1844+ var jqName = jq();
1845+ jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present)
1846+ !jqName ? undefined : // use jqLite
1847+ window[jqName]; // use jQuery specified by `ngJq`
1848+
1849+ // Use jQuery if it exists with proper functionality, otherwise default to us.
1850+ // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
1851+ // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
1852+ // versions. It will not work for sure with jQuery <1.7, though.
1853+ if (jQuery && jQuery.fn.on) {
1854+ jqLite = jQuery;
1855+ extend(jQuery.fn, {
1856+ scope: JQLitePrototype.scope,
1857+ isolateScope: JQLitePrototype.isolateScope,
1858+ controller: JQLitePrototype.controller,
1859+ injector: JQLitePrototype.injector,
1860+ inheritedData: JQLitePrototype.inheritedData
1861+ });
1862+
1863+ // All nodes removed from the DOM via various jQuery APIs like .remove()
1864+ // are passed through jQuery.cleanData. Monkey-patch this method to fire
1865+ // the $destroy event on all removed nodes.
1866+ originalCleanData = jQuery.cleanData;
1867+ jQuery.cleanData = function(elems) {
1868+ var events;
1869+ for (var i = 0, elem; (elem = elems[i]) != null; i++) {
1870+ events = jQuery._data(elem, "events");
1871+ if (events && events.$destroy) {
1872+ jQuery(elem).triggerHandler('$destroy');
1873+ }
1874+ }
1875+ originalCleanData(elems);
1876+ };
1877+ } else {
1878+ jqLite = JQLite;
1879+ }
1880+
1881+ angular.element = jqLite;
1882+
1883+ // Prevent double-proxying.
1884+ bindJQueryFired = true;
1885+}
1886+
1887+/**
1888+ * throw error if the argument is falsy.
1889+ */
1890+function assertArg(arg, name, reason) {
1891+ if (!arg) {
1892+ throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
1893+ }
1894+ return arg;
1895+}
1896+
1897+function assertArgFn(arg, name, acceptArrayAnnotation) {
1898+ if (acceptArrayAnnotation && isArray(arg)) {
1899+ arg = arg[arg.length - 1];
1900+ }
1901+
1902+ assertArg(isFunction(arg), name, 'not a function, got ' +
1903+ (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
1904+ return arg;
1905+}
1906+
1907+/**
1908+ * throw error if the name given is hasOwnProperty
1909+ * @param {String} name the name to test
1910+ * @param {String} context the context in which the name is used, such as module or directive
1911+ */
1912+function assertNotHasOwnProperty(name, context) {
1913+ if (name === 'hasOwnProperty') {
1914+ throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
1915+ }
1916+}
1917+
1918+/**
1919+ * Return the value accessible from the object by path. Any undefined traversals are ignored
1920+ * @param {Object} obj starting object
1921+ * @param {String} path path to traverse
1922+ * @param {boolean} [bindFnToScope=true]
1923+ * @returns {Object} value as accessible by path
1924+ */
1925+//TODO(misko): this function needs to be removed
1926+function getter(obj, path, bindFnToScope) {
1927+ if (!path) return obj;
1928+ var keys = path.split('.');
1929+ var key;
1930+ var lastInstance = obj;
1931+ var len = keys.length;
1932+
1933+ for (var i = 0; i < len; i++) {
1934+ key = keys[i];
1935+ if (obj) {
1936+ obj = (lastInstance = obj)[key];
1937+ }
1938+ }
1939+ if (!bindFnToScope && isFunction(obj)) {
1940+ return bind(lastInstance, obj);
1941+ }
1942+ return obj;
1943+}
1944+
1945+/**
1946+ * Return the DOM siblings between the first and last node in the given array.
1947+ * @param {Array} array like object
1948+ * @returns {Array} the inputted object or a jqLite collection containing the nodes
1949+ */
1950+function getBlockNodes(nodes) {
1951+ // TODO(perf): update `nodes` instead of creating a new object?
1952+ var node = nodes[0];
1953+ var endNode = nodes[nodes.length - 1];
1954+ var blockNodes;
1955+
1956+ for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
1957+ if (blockNodes || nodes[i] !== node) {
1958+ if (!blockNodes) {
1959+ blockNodes = jqLite(slice.call(nodes, 0, i));
1960+ }
1961+ blockNodes.push(node);
1962+ }
1963+ }
1964+
1965+ return blockNodes || nodes;
1966+}
1967+
1968+
1969+/**
1970+ * Creates a new object without a prototype. This object is useful for lookup without having to
1971+ * guard against prototypically inherited properties via hasOwnProperty.
1972+ *
1973+ * Related micro-benchmarks:
1974+ * - http://jsperf.com/object-create2
1975+ * - http://jsperf.com/proto-map-lookup/2
1976+ * - http://jsperf.com/for-in-vs-object-keys2
1977+ *
1978+ * @returns {Object}
1979+ */
1980+function createMap() {
1981+ return Object.create(null);
1982+}
1983+
1984+var NODE_TYPE_ELEMENT = 1;
1985+var NODE_TYPE_ATTRIBUTE = 2;
1986+var NODE_TYPE_TEXT = 3;
1987+var NODE_TYPE_COMMENT = 8;
1988+var NODE_TYPE_DOCUMENT = 9;
1989+var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
1990+
1991+/**
1992+ * @ngdoc type
1993+ * @name angular.Module
1994+ * @module ng
1995+ * @description
1996+ *
1997+ * Interface for configuring angular {@link angular.module modules}.
1998+ */
1999+
2000+function setupModuleLoader(window) {
2001+
2002+ var $injectorMinErr = minErr('$injector');
2003+ var ngMinErr = minErr('ng');
2004+
2005+ function ensure(obj, name, factory) {
2006+ return obj[name] || (obj[name] = factory());
2007+ }
2008+
2009+ var angular = ensure(window, 'angular', Object);
2010+
2011+ // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
2012+ angular.$$minErr = angular.$$minErr || minErr;
2013+
2014+ return ensure(angular, 'module', function() {
2015+ /** @type {Object.<string, angular.Module>} */
2016+ var modules = {};
2017+
2018+ /**
2019+ * @ngdoc function
2020+ * @name angular.module
2021+ * @module ng
2022+ * @description
2023+ *
2024+ * The `angular.module` is a global place for creating, registering and retrieving Angular
2025+ * modules.
2026+ * All modules (angular core or 3rd party) that should be available to an application must be
2027+ * registered using this mechanism.
2028+ *
2029+ * Passing one argument retrieves an existing {@link angular.Module},
2030+ * whereas passing more than one argument creates a new {@link angular.Module}
2031+ *
2032+ *
2033+ * # Module
2034+ *
2035+ * A module is a collection of services, directives, controllers, filters, and configuration information.
2036+ * `angular.module` is used to configure the {@link auto.$injector $injector}.
2037+ *
2038+ * ```js
2039+ * // Create a new module
2040+ * var myModule = angular.module('myModule', []);
2041+ *
2042+ * // register a new service
2043+ * myModule.value('appName', 'MyCoolApp');
2044+ *
2045+ * // configure existing services inside initialization blocks.
2046+ * myModule.config(['$locationProvider', function($locationProvider) {
2047+ * // Configure existing providers
2048+ * $locationProvider.hashPrefix('!');
2049+ * }]);
2050+ * ```
2051+ *
2052+ * Then you can create an injector and load your modules like this:
2053+ *
2054+ * ```js
2055+ * var injector = angular.injector(['ng', 'myModule'])
2056+ * ```
2057+ *
2058+ * However it's more likely that you'll just use
2059+ * {@link ng.directive:ngApp ngApp} or
2060+ * {@link angular.bootstrap} to simplify this process for you.
2061+ *
2062+ * @param {!string} name The name of the module to create or retrieve.
2063+ * @param {!Array.<string>=} requires If specified then new module is being created. If
2064+ * unspecified then the module is being retrieved for further configuration.
2065+ * @param {Function=} configFn Optional configuration function for the module. Same as
2066+ * {@link angular.Module#config Module#config()}.
2067+ * @returns {angular.Module} new module with the {@link angular.Module} api.
2068+ */
2069+ return function module(name, requires, configFn) {
2070+ var assertNotHasOwnProperty = function(name, context) {
2071+ if (name === 'hasOwnProperty') {
2072+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
2073+ }
2074+ };
2075+
2076+ assertNotHasOwnProperty(name, 'module');
2077+ if (requires && modules.hasOwnProperty(name)) {
2078+ modules[name] = null;
2079+ }
2080+ return ensure(modules, name, function() {
2081+ if (!requires) {
2082+ throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
2083+ "the module name or forgot to load it. If registering a module ensure that you " +
2084+ "specify the dependencies as the second argument.", name);
2085+ }
2086+
2087+ /** @type {!Array.<Array.<*>>} */
2088+ var invokeQueue = [];
2089+
2090+ /** @type {!Array.<Function>} */
2091+ var configBlocks = [];
2092+
2093+ /** @type {!Array.<Function>} */
2094+ var runBlocks = [];
2095+
2096+ var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
2097+
2098+ /** @type {angular.Module} */
2099+ var moduleInstance = {
2100+ // Private state
2101+ _invokeQueue: invokeQueue,
2102+ _configBlocks: configBlocks,
2103+ _runBlocks: runBlocks,
2104+
2105+ /**
2106+ * @ngdoc property
2107+ * @name angular.Module#requires
2108+ * @module ng
2109+ *
2110+ * @description
2111+ * Holds the list of modules which the injector will load before the current module is
2112+ * loaded.
2113+ */
2114+ requires: requires,
2115+
2116+ /**
2117+ * @ngdoc property
2118+ * @name angular.Module#name
2119+ * @module ng
2120+ *
2121+ * @description
2122+ * Name of the module.
2123+ */
2124+ name: name,
2125+
2126+
2127+ /**
2128+ * @ngdoc method
2129+ * @name angular.Module#provider
2130+ * @module ng
2131+ * @param {string} name service name
2132+ * @param {Function} providerType Construction function for creating new instance of the
2133+ * service.
2134+ * @description
2135+ * See {@link auto.$provide#provider $provide.provider()}.
2136+ */
2137+ provider: invokeLaterAndSetModuleName('$provide', 'provider'),
2138+
2139+ /**
2140+ * @ngdoc method
2141+ * @name angular.Module#factory
2142+ * @module ng
2143+ * @param {string} name service name
2144+ * @param {Function} providerFunction Function for creating new instance of the service.
2145+ * @description
2146+ * See {@link auto.$provide#factory $provide.factory()}.
2147+ */
2148+ factory: invokeLaterAndSetModuleName('$provide', 'factory'),
2149+
2150+ /**
2151+ * @ngdoc method
2152+ * @name angular.Module#service
2153+ * @module ng
2154+ * @param {string} name service name
2155+ * @param {Function} constructor A constructor function that will be instantiated.
2156+ * @description
2157+ * See {@link auto.$provide#service $provide.service()}.
2158+ */
2159+ service: invokeLaterAndSetModuleName('$provide', 'service'),
2160+
2161+ /**
2162+ * @ngdoc method
2163+ * @name angular.Module#value
2164+ * @module ng
2165+ * @param {string} name service name
2166+ * @param {*} object Service instance object.
2167+ * @description
2168+ * See {@link auto.$provide#value $provide.value()}.
2169+ */
2170+ value: invokeLater('$provide', 'value'),
2171+
2172+ /**
2173+ * @ngdoc method
2174+ * @name angular.Module#constant
2175+ * @module ng
2176+ * @param {string} name constant name
2177+ * @param {*} object Constant value.
2178+ * @description
2179+ * Because the constants are fixed, they get applied before other provide methods.
2180+ * See {@link auto.$provide#constant $provide.constant()}.
2181+ */
2182+ constant: invokeLater('$provide', 'constant', 'unshift'),
2183+
2184+ /**
2185+ * @ngdoc method
2186+ * @name angular.Module#decorator
2187+ * @module ng
2188+ * @param {string} name The name of the service to decorate.
2189+ * @param {Function} decorFn This function will be invoked when the service needs to be
2190+ * instantiated and should return the decorated service instance.
2191+ * @description
2192+ * See {@link auto.$provide#decorator $provide.decorator()}.
2193+ */
2194+ decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
2195+
2196+ /**
2197+ * @ngdoc method
2198+ * @name angular.Module#animation
2199+ * @module ng
2200+ * @param {string} name animation name
2201+ * @param {Function} animationFactory Factory function for creating new instance of an
2202+ * animation.
2203+ * @description
2204+ *
2205+ * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
2206+ *
2207+ *
2208+ * Defines an animation hook that can be later used with
2209+ * {@link $animate $animate} service and directives that use this service.
2210+ *
2211+ * ```js
2212+ * module.animation('.animation-name', function($inject1, $inject2) {
2213+ * return {
2214+ * eventName : function(element, done) {
2215+ * //code to run the animation
2216+ * //once complete, then run done()
2217+ * return function cancellationFunction(element) {
2218+ * //code to cancel the animation
2219+ * }
2220+ * }
2221+ * }
2222+ * })
2223+ * ```
2224+ *
2225+ * See {@link ng.$animateProvider#register $animateProvider.register()} and
2226+ * {@link ngAnimate ngAnimate module} for more information.
2227+ */
2228+ animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
2229+
2230+ /**
2231+ * @ngdoc method
2232+ * @name angular.Module#filter
2233+ * @module ng
2234+ * @param {string} name Filter name - this must be a valid angular expression identifier
2235+ * @param {Function} filterFactory Factory function for creating new instance of filter.
2236+ * @description
2237+ * See {@link ng.$filterProvider#register $filterProvider.register()}.
2238+ *
2239+ * <div class="alert alert-warning">
2240+ * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
2241+ * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
2242+ * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
2243+ * (`myapp_subsection_filterx`).
2244+ * </div>
2245+ */
2246+ filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
2247+
2248+ /**
2249+ * @ngdoc method
2250+ * @name angular.Module#controller
2251+ * @module ng
2252+ * @param {string|Object} name Controller name, or an object map of controllers where the
2253+ * keys are the names and the values are the constructors.
2254+ * @param {Function} constructor Controller constructor function.
2255+ * @description
2256+ * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
2257+ */
2258+ controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
2259+
2260+ /**
2261+ * @ngdoc method
2262+ * @name angular.Module#directive
2263+ * @module ng
2264+ * @param {string|Object} name Directive name, or an object map of directives where the
2265+ * keys are the names and the values are the factories.
2266+ * @param {Function} directiveFactory Factory function for creating new instance of
2267+ * directives.
2268+ * @description
2269+ * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
2270+ */
2271+ directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
2272+
2273+ /**
2274+ * @ngdoc method
2275+ * @name angular.Module#component
2276+ * @module ng
2277+ * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
2278+ * @param {Object} options Component definition object (a simplified
2279+ * {@link ng.$compile#directive-definition-object directive definition object})
2280+ *
2281+ * @description
2282+ * See {@link ng.$compileProvider#component $compileProvider.component()}.
2283+ */
2284+ component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
2285+
2286+ /**
2287+ * @ngdoc method
2288+ * @name angular.Module#config
2289+ * @module ng
2290+ * @param {Function} configFn Execute this function on module load. Useful for service
2291+ * configuration.
2292+ * @description
2293+ * Use this method to register work which needs to be performed on module loading.
2294+ * For more about how to configure services, see
2295+ * {@link providers#provider-recipe Provider Recipe}.
2296+ */
2297+ config: config,
2298+
2299+ /**
2300+ * @ngdoc method
2301+ * @name angular.Module#run
2302+ * @module ng
2303+ * @param {Function} initializationFn Execute this function after injector creation.
2304+ * Useful for application initialization.
2305+ * @description
2306+ * Use this method to register work which should be performed when the injector is done
2307+ * loading all modules.
2308+ */
2309+ run: function(block) {
2310+ runBlocks.push(block);
2311+ return this;
2312+ }
2313+ };
2314+
2315+ if (configFn) {
2316+ config(configFn);
2317+ }
2318+
2319+ return moduleInstance;
2320+
2321+ /**
2322+ * @param {string} provider
2323+ * @param {string} method
2324+ * @param {String=} insertMethod
2325+ * @returns {angular.Module}
2326+ */
2327+ function invokeLater(provider, method, insertMethod, queue) {
2328+ if (!queue) queue = invokeQueue;
2329+ return function() {
2330+ queue[insertMethod || 'push']([provider, method, arguments]);
2331+ return moduleInstance;
2332+ };
2333+ }
2334+
2335+ /**
2336+ * @param {string} provider
2337+ * @param {string} method
2338+ * @returns {angular.Module}
2339+ */
2340+ function invokeLaterAndSetModuleName(provider, method) {
2341+ return function(recipeName, factoryFunction) {
2342+ if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
2343+ invokeQueue.push([provider, method, arguments]);
2344+ return moduleInstance;
2345+ };
2346+ }
2347+ });
2348+ };
2349+ });
2350+
2351+}
2352+
2353+/* global shallowCopy: true */
2354+
2355+/**
2356+ * Creates a shallow copy of an object, an array or a primitive.
2357+ *
2358+ * Assumes that there are no proto properties for objects.
2359+ */
2360+function shallowCopy(src, dst) {
2361+ if (isArray(src)) {
2362+ dst = dst || [];
2363+
2364+ for (var i = 0, ii = src.length; i < ii; i++) {
2365+ dst[i] = src[i];
2366+ }
2367+ } else if (isObject(src)) {
2368+ dst = dst || {};
2369+
2370+ for (var key in src) {
2371+ if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
2372+ dst[key] = src[key];
2373+ }
2374+ }
2375+ }
2376+
2377+ return dst || src;
2378+}
2379+
2380+/* global toDebugString: true */
2381+
2382+function serializeObject(obj) {
2383+ var seen = [];
2384+
2385+ return JSON.stringify(obj, function(key, val) {
2386+ val = toJsonReplacer(key, val);
2387+ if (isObject(val)) {
2388+
2389+ if (seen.indexOf(val) >= 0) return '...';
2390+
2391+ seen.push(val);
2392+ }
2393+ return val;
2394+ });
2395+}
2396+
2397+function toDebugString(obj) {
2398+ if (typeof obj === 'function') {
2399+ return obj.toString().replace(/ \{[\s\S]*$/, '');
2400+ } else if (isUndefined(obj)) {
2401+ return 'undefined';
2402+ } else if (typeof obj !== 'string') {
2403+ return serializeObject(obj);
2404+ }
2405+ return obj;
2406+}
2407+
2408+/* global angularModule: true,
2409+ version: true,
2410+
2411+ $CompileProvider,
2412+
2413+ htmlAnchorDirective,
2414+ inputDirective,
2415+ inputDirective,
2416+ formDirective,
2417+ scriptDirective,
2418+ selectDirective,
2419+ styleDirective,
2420+ optionDirective,
2421+ ngBindDirective,
2422+ ngBindHtmlDirective,
2423+ ngBindTemplateDirective,
2424+ ngClassDirective,
2425+ ngClassEvenDirective,
2426+ ngClassOddDirective,
2427+ ngCloakDirective,
2428+ ngControllerDirective,
2429+ ngFormDirective,
2430+ ngHideDirective,
2431+ ngIfDirective,
2432+ ngIncludeDirective,
2433+ ngIncludeFillContentDirective,
2434+ ngInitDirective,
2435+ ngNonBindableDirective,
2436+ ngPluralizeDirective,
2437+ ngRepeatDirective,
2438+ ngShowDirective,
2439+ ngStyleDirective,
2440+ ngSwitchDirective,
2441+ ngSwitchWhenDirective,
2442+ ngSwitchDefaultDirective,
2443+ ngOptionsDirective,
2444+ ngTranscludeDirective,
2445+ ngModelDirective,
2446+ ngListDirective,
2447+ ngChangeDirective,
2448+ patternDirective,
2449+ patternDirective,
2450+ requiredDirective,
2451+ requiredDirective,
2452+ minlengthDirective,
2453+ minlengthDirective,
2454+ maxlengthDirective,
2455+ maxlengthDirective,
2456+ ngValueDirective,
2457+ ngModelOptionsDirective,
2458+ ngAttributeAliasDirectives,
2459+ ngEventDirectives,
2460+
2461+ $AnchorScrollProvider,
2462+ $AnimateProvider,
2463+ $CoreAnimateCssProvider,
2464+ $$CoreAnimateJsProvider,
2465+ $$CoreAnimateQueueProvider,
2466+ $$AnimateRunnerFactoryProvider,
2467+ $$AnimateAsyncRunFactoryProvider,
2468+ $BrowserProvider,
2469+ $CacheFactoryProvider,
2470+ $ControllerProvider,
2471+ $DateProvider,
2472+ $DocumentProvider,
2473+ $ExceptionHandlerProvider,
2474+ $FilterProvider,
2475+ $$ForceReflowProvider,
2476+ $InterpolateProvider,
2477+ $IntervalProvider,
2478+ $$HashMapProvider,
2479+ $HttpProvider,
2480+ $HttpParamSerializerProvider,
2481+ $HttpParamSerializerJQLikeProvider,
2482+ $HttpBackendProvider,
2483+ $xhrFactoryProvider,
2484+ $jsonpCallbacksProvider,
2485+ $LocationProvider,
2486+ $LogProvider,
2487+ $ParseProvider,
2488+ $RootScopeProvider,
2489+ $QProvider,
2490+ $$QProvider,
2491+ $$SanitizeUriProvider,
2492+ $SceProvider,
2493+ $SceDelegateProvider,
2494+ $SnifferProvider,
2495+ $TemplateCacheProvider,
2496+ $TemplateRequestProvider,
2497+ $$TestabilityProvider,
2498+ $TimeoutProvider,
2499+ $$RAFProvider,
2500+ $WindowProvider,
2501+ $$jqLiteProvider,
2502+ $$CookieReaderProvider
2503+*/
2504+
2505+
2506+/**
2507+ * @ngdoc object
2508+ * @name angular.version
2509+ * @module ng
2510+ * @description
2511+ * An object that contains information about the current AngularJS version.
2512+ *
2513+ * This object has the following properties:
2514+ *
2515+ * - `full` – `{string}` – Full version string, such as "0.9.18".
2516+ * - `major` – `{number}` – Major version number, such as "0".
2517+ * - `minor` – `{number}` – Minor version number, such as "9".
2518+ * - `dot` – `{number}` – Dot version number, such as "18".
2519+ * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2520+ */
2521+var version = {
2522+ full: '1.5.8', // all of these placeholder strings will be replaced by grunt's
2523+ major: 1, // package task
2524+ minor: 5,
2525+ dot: 8,
2526+ codeName: 'arbitrary-fallbacks'
2527+};
2528+
2529+
2530+function publishExternalAPI(angular) {
2531+ extend(angular, {
2532+ 'bootstrap': bootstrap,
2533+ 'copy': copy,
2534+ 'extend': extend,
2535+ 'merge': merge,
2536+ 'equals': equals,
2537+ 'element': jqLite,
2538+ 'forEach': forEach,
2539+ 'injector': createInjector,
2540+ 'noop': noop,
2541+ 'bind': bind,
2542+ 'toJson': toJson,
2543+ 'fromJson': fromJson,
2544+ 'identity': identity,
2545+ 'isUndefined': isUndefined,
2546+ 'isDefined': isDefined,
2547+ 'isString': isString,
2548+ 'isFunction': isFunction,
2549+ 'isObject': isObject,
2550+ 'isNumber': isNumber,
2551+ 'isElement': isElement,
2552+ 'isArray': isArray,
2553+ 'version': version,
2554+ 'isDate': isDate,
2555+ 'lowercase': lowercase,
2556+ 'uppercase': uppercase,
2557+ 'callbacks': {$$counter: 0},
2558+ 'getTestability': getTestability,
2559+ '$$minErr': minErr,
2560+ '$$csp': csp,
2561+ 'reloadWithDebugInfo': reloadWithDebugInfo
2562+ });
2563+
2564+ angularModule = setupModuleLoader(window);
2565+
2566+ angularModule('ng', ['ngLocale'], ['$provide',
2567+ function ngModule($provide) {
2568+ // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
2569+ $provide.provider({
2570+ $$sanitizeUri: $$SanitizeUriProvider
2571+ });
2572+ $provide.provider('$compile', $CompileProvider).
2573+ directive({
2574+ a: htmlAnchorDirective,
2575+ input: inputDirective,
2576+ textarea: inputDirective,
2577+ form: formDirective,
2578+ script: scriptDirective,
2579+ select: selectDirective,
2580+ style: styleDirective,
2581+ option: optionDirective,
2582+ ngBind: ngBindDirective,
2583+ ngBindHtml: ngBindHtmlDirective,
2584+ ngBindTemplate: ngBindTemplateDirective,
2585+ ngClass: ngClassDirective,
2586+ ngClassEven: ngClassEvenDirective,
2587+ ngClassOdd: ngClassOddDirective,
2588+ ngCloak: ngCloakDirective,
2589+ ngController: ngControllerDirective,
2590+ ngForm: ngFormDirective,
2591+ ngHide: ngHideDirective,
2592+ ngIf: ngIfDirective,
2593+ ngInclude: ngIncludeDirective,
2594+ ngInit: ngInitDirective,
2595+ ngNonBindable: ngNonBindableDirective,
2596+ ngPluralize: ngPluralizeDirective,
2597+ ngRepeat: ngRepeatDirective,
2598+ ngShow: ngShowDirective,
2599+ ngStyle: ngStyleDirective,
2600+ ngSwitch: ngSwitchDirective,
2601+ ngSwitchWhen: ngSwitchWhenDirective,
2602+ ngSwitchDefault: ngSwitchDefaultDirective,
2603+ ngOptions: ngOptionsDirective,
2604+ ngTransclude: ngTranscludeDirective,
2605+ ngModel: ngModelDirective,
2606+ ngList: ngListDirective,
2607+ ngChange: ngChangeDirective,
2608+ pattern: patternDirective,
2609+ ngPattern: patternDirective,
2610+ required: requiredDirective,
2611+ ngRequired: requiredDirective,
2612+ minlength: minlengthDirective,
2613+ ngMinlength: minlengthDirective,
2614+ maxlength: maxlengthDirective,
2615+ ngMaxlength: maxlengthDirective,
2616+ ngValue: ngValueDirective,
2617+ ngModelOptions: ngModelOptionsDirective
2618+ }).
2619+ directive({
2620+ ngInclude: ngIncludeFillContentDirective
2621+ }).
2622+ directive(ngAttributeAliasDirectives).
2623+ directive(ngEventDirectives);
2624+ $provide.provider({
2625+ $anchorScroll: $AnchorScrollProvider,
2626+ $animate: $AnimateProvider,
2627+ $animateCss: $CoreAnimateCssProvider,
2628+ $$animateJs: $$CoreAnimateJsProvider,
2629+ $$animateQueue: $$CoreAnimateQueueProvider,
2630+ $$AnimateRunner: $$AnimateRunnerFactoryProvider,
2631+ $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,
2632+ $browser: $BrowserProvider,
2633+ $cacheFactory: $CacheFactoryProvider,
2634+ $controller: $ControllerProvider,
2635+ $document: $DocumentProvider,
2636+ $exceptionHandler: $ExceptionHandlerProvider,
2637+ $filter: $FilterProvider,
2638+ $$forceReflow: $$ForceReflowProvider,
2639+ $interpolate: $InterpolateProvider,
2640+ $interval: $IntervalProvider,
2641+ $http: $HttpProvider,
2642+ $httpParamSerializer: $HttpParamSerializerProvider,
2643+ $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
2644+ $httpBackend: $HttpBackendProvider,
2645+ $xhrFactory: $xhrFactoryProvider,
2646+ $jsonpCallbacks: $jsonpCallbacksProvider,
2647+ $location: $LocationProvider,
2648+ $log: $LogProvider,
2649+ $parse: $ParseProvider,
2650+ $rootScope: $RootScopeProvider,
2651+ $q: $QProvider,
2652+ $$q: $$QProvider,
2653+ $sce: $SceProvider,
2654+ $sceDelegate: $SceDelegateProvider,
2655+ $sniffer: $SnifferProvider,
2656+ $templateCache: $TemplateCacheProvider,
2657+ $templateRequest: $TemplateRequestProvider,
2658+ $$testability: $$TestabilityProvider,
2659+ $timeout: $TimeoutProvider,
2660+ $window: $WindowProvider,
2661+ $$rAF: $$RAFProvider,
2662+ $$jqLite: $$jqLiteProvider,
2663+ $$HashMap: $$HashMapProvider,
2664+ $$cookieReader: $$CookieReaderProvider
2665+ });
2666+ }
2667+ ]);
2668+}
2669+
2670+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2671+ * Any commits to this file should be reviewed with security in mind. *
2672+ * Changes to this file can potentially create security vulnerabilities. *
2673+ * An approval from 2 Core members with history of modifying *
2674+ * this file is required. *
2675+ * *
2676+ * Does the change somehow allow for arbitrary javascript to be executed? *
2677+ * Or allows for someone to change the prototype of built-in objects? *
2678+ * Or gives undesired access to variables likes document or window? *
2679+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2680+
2681+/* global JQLitePrototype: true,
2682+ addEventListenerFn: true,
2683+ removeEventListenerFn: true,
2684+ BOOLEAN_ATTR: true,
2685+ ALIASED_ATTR: true,
2686+*/
2687+
2688+//////////////////////////////////
2689+//JQLite
2690+//////////////////////////////////
2691+
2692+/**
2693+ * @ngdoc function
2694+ * @name angular.element
2695+ * @module ng
2696+ * @kind function
2697+ *
2698+ * @description
2699+ * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
2700+ *
2701+ * If jQuery is available, `angular.element` is an alias for the
2702+ * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
2703+ * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or **jqLite**.
2704+ *
2705+ * jqLite is a tiny, API-compatible subset of jQuery that allows
2706+ * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most
2707+ * commonly needed functionality with the goal of having a very small footprint.
2708+ *
2709+ * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the
2710+ * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a
2711+ * specific version of jQuery if multiple versions exist on the page.
2712+ *
2713+ * <div class="alert alert-info">**Note:** All element references in Angular are always wrapped with jQuery or
2714+ * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
2715+ *
2716+ * <div class="alert alert-warning">**Note:** Keep in mind that this function will not find elements
2717+ * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`
2718+ * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>
2719+ *
2720+ * ## Angular's jqLite
2721+ * jqLite provides only the following jQuery methods:
2722+ *
2723+ * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument
2724+ * - [`after()`](http://api.jquery.com/after/)
2725+ * - [`append()`](http://api.jquery.com/append/)
2726+ * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
2727+ * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
2728+ * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
2729+ * - [`clone()`](http://api.jquery.com/clone/)
2730+ * - [`contents()`](http://api.jquery.com/contents/)
2731+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`.
2732+ * As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing.
2733+ * - [`data()`](http://api.jquery.com/data/)
2734+ * - [`detach()`](http://api.jquery.com/detach/)
2735+ * - [`empty()`](http://api.jquery.com/empty/)
2736+ * - [`eq()`](http://api.jquery.com/eq/)
2737+ * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
2738+ * - [`hasClass()`](http://api.jquery.com/hasClass/)
2739+ * - [`html()`](http://api.jquery.com/html/)
2740+ * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
2741+ * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
2742+ * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
2743+ * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
2744+ * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
2745+ * - [`prepend()`](http://api.jquery.com/prepend/)
2746+ * - [`prop()`](http://api.jquery.com/prop/)
2747+ * - [`ready()`](http://api.jquery.com/ready/)
2748+ * - [`remove()`](http://api.jquery.com/remove/)
2749+ * - [`removeAttr()`](http://api.jquery.com/removeAttr/)
2750+ * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument
2751+ * - [`removeData()`](http://api.jquery.com/removeData/)
2752+ * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
2753+ * - [`text()`](http://api.jquery.com/text/)
2754+ * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument
2755+ * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers
2756+ * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces or event object as parameter
2757+ * - [`val()`](http://api.jquery.com/val/)
2758+ * - [`wrap()`](http://api.jquery.com/wrap/)
2759+ *
2760+ * ## jQuery/jqLite Extras
2761+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
2762+ *
2763+ * ### Events
2764+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
2765+ * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM
2766+ * element before it is removed.
2767+ *
2768+ * ### Methods
2769+ * - `controller(name)` - retrieves the controller of the current element or its parent. By default
2770+ * retrieves controller associated with the `ngController` directive. If `name` is provided as
2771+ * camelCase directive name, then the controller for this directive will be retrieved (e.g.
2772+ * `'ngModel'`).
2773+ * - `injector()` - retrieves the injector of the current element or its parent.
2774+ * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
2775+ * element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
2776+ * be enabled.
2777+ * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
2778+ * current element. This getter should be used only on elements that contain a directive which starts a new isolate
2779+ * scope. Calling `scope()` on this element always returns the original non-isolate scope.
2780+ * Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
2781+ * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
2782+ * parent element is reached.
2783+ *
2784+ * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See
2785+ * https://github.com/angular/angular.js/issues/14251 for more information.
2786+ *
2787+ * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
2788+ * @returns {Object} jQuery object.
2789+ */
2790+
2791+JQLite.expando = 'ng339';
2792+
2793+var jqCache = JQLite.cache = {},
2794+ jqId = 1,
2795+ addEventListenerFn = function(element, type, fn) {
2796+ element.addEventListener(type, fn, false);
2797+ },
2798+ removeEventListenerFn = function(element, type, fn) {
2799+ element.removeEventListener(type, fn, false);
2800+ };
2801+
2802+/*
2803+ * !!! This is an undocumented "private" function !!!
2804+ */
2805+JQLite._data = function(node) {
2806+ //jQuery always returns an object on cache miss
2807+ return this.cache[node[this.expando]] || {};
2808+};
2809+
2810+function jqNextId() { return ++jqId; }
2811+
2812+
2813+var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
2814+var MOZ_HACK_REGEXP = /^moz([A-Z])/;
2815+var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
2816+var jqLiteMinErr = minErr('jqLite');
2817+
2818+/**
2819+ * Converts snake_case to camelCase.
2820+ * Also there is special case for Moz prefix starting with upper case letter.
2821+ * @param name Name to normalize
2822+ */
2823+function camelCase(name) {
2824+ return name.
2825+ replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
2826+ return offset ? letter.toUpperCase() : letter;
2827+ }).
2828+ replace(MOZ_HACK_REGEXP, 'Moz$1');
2829+}
2830+
2831+var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
2832+var HTML_REGEXP = /<|&#?\w+;/;
2833+var TAG_NAME_REGEXP = /<([\w:-]+)/;
2834+var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
2835+
2836+var wrapMap = {
2837+ 'option': [1, '<select multiple="multiple">', '</select>'],
2838+
2839+ 'thead': [1, '<table>', '</table>'],
2840+ 'col': [2, '<table><colgroup>', '</colgroup></table>'],
2841+ 'tr': [2, '<table><tbody>', '</tbody></table>'],
2842+ 'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
2843+ '_default': [0, "", ""]
2844+};
2845+
2846+wrapMap.optgroup = wrapMap.option;
2847+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
2848+wrapMap.th = wrapMap.td;
2849+
2850+
2851+function jqLiteIsTextNode(html) {
2852+ return !HTML_REGEXP.test(html);
2853+}
2854+
2855+function jqLiteAcceptsData(node) {
2856+ // The window object can accept data but has no nodeType
2857+ // Otherwise we are only interested in elements (1) and documents (9)
2858+ var nodeType = node.nodeType;
2859+ return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
2860+}
2861+
2862+function jqLiteHasData(node) {
2863+ for (var key in jqCache[node.ng339]) {
2864+ return true;
2865+ }
2866+ return false;
2867+}
2868+
2869+function jqLiteCleanData(nodes) {
2870+ for (var i = 0, ii = nodes.length; i < ii; i++) {
2871+ jqLiteRemoveData(nodes[i]);
2872+ }
2873+}
2874+
2875+function jqLiteBuildFragment(html, context) {
2876+ var tmp, tag, wrap,
2877+ fragment = context.createDocumentFragment(),
2878+ nodes = [], i;
2879+
2880+ if (jqLiteIsTextNode(html)) {
2881+ // Convert non-html into a text node
2882+ nodes.push(context.createTextNode(html));
2883+ } else {
2884+ // Convert html into DOM nodes
2885+ tmp = fragment.appendChild(context.createElement("div"));
2886+ tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
2887+ wrap = wrapMap[tag] || wrapMap._default;
2888+ tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1></$2>") + wrap[2];
2889+
2890+ // Descend through wrappers to the right content
2891+ i = wrap[0];
2892+ while (i--) {
2893+ tmp = tmp.lastChild;
2894+ }
2895+
2896+ nodes = concat(nodes, tmp.childNodes);
2897+
2898+ tmp = fragment.firstChild;
2899+ tmp.textContent = "";
2900+ }
2901+
2902+ // Remove wrapper from fragment
2903+ fragment.textContent = "";
2904+ fragment.innerHTML = ""; // Clear inner HTML
2905+ forEach(nodes, function(node) {
2906+ fragment.appendChild(node);
2907+ });
2908+
2909+ return fragment;
2910+}
2911+
2912+function jqLiteParseHTML(html, context) {
2913+ context = context || window.document;
2914+ var parsed;
2915+
2916+ if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
2917+ return [context.createElement(parsed[1])];
2918+ }
2919+
2920+ if ((parsed = jqLiteBuildFragment(html, context))) {
2921+ return parsed.childNodes;
2922+ }
2923+
2924+ return [];
2925+}
2926+
2927+function jqLiteWrapNode(node, wrapper) {
2928+ var parent = node.parentNode;
2929+
2930+ if (parent) {
2931+ parent.replaceChild(wrapper, node);
2932+ }
2933+
2934+ wrapper.appendChild(node);
2935+}
2936+
2937+
2938+// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
2939+var jqLiteContains = window.Node.prototype.contains || function(arg) {
2940+ // jshint bitwise: false
2941+ return !!(this.compareDocumentPosition(arg) & 16);
2942+ // jshint bitwise: true
2943+};
2944+
2945+/////////////////////////////////////////////
2946+function JQLite(element) {
2947+ if (element instanceof JQLite) {
2948+ return element;
2949+ }
2950+
2951+ var argIsString;
2952+
2953+ if (isString(element)) {
2954+ element = trim(element);
2955+ argIsString = true;
2956+ }
2957+ if (!(this instanceof JQLite)) {
2958+ if (argIsString && element.charAt(0) != '<') {
2959+ throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
2960+ }
2961+ return new JQLite(element);
2962+ }
2963+
2964+ if (argIsString) {
2965+ jqLiteAddNodes(this, jqLiteParseHTML(element));
2966+ } else {
2967+ jqLiteAddNodes(this, element);
2968+ }
2969+}
2970+
2971+function jqLiteClone(element) {
2972+ return element.cloneNode(true);
2973+}
2974+
2975+function jqLiteDealoc(element, onlyDescendants) {
2976+ if (!onlyDescendants) jqLiteRemoveData(element);
2977+
2978+ if (element.querySelectorAll) {
2979+ var descendants = element.querySelectorAll('*');
2980+ for (var i = 0, l = descendants.length; i < l; i++) {
2981+ jqLiteRemoveData(descendants[i]);
2982+ }
2983+ }
2984+}
2985+
2986+function jqLiteOff(element, type, fn, unsupported) {
2987+ if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
2988+
2989+ var expandoStore = jqLiteExpandoStore(element);
2990+ var events = expandoStore && expandoStore.events;
2991+ var handle = expandoStore && expandoStore.handle;
2992+
2993+ if (!handle) return; //no listeners registered
2994+
2995+ if (!type) {
2996+ for (type in events) {
2997+ if (type !== '$destroy') {
2998+ removeEventListenerFn(element, type, handle);
2999+ }
3000+ delete events[type];
3001+ }
3002+ } else {
3003+
3004+ var removeHandler = function(type) {
3005+ var listenerFns = events[type];
3006+ if (isDefined(fn)) {
3007+ arrayRemove(listenerFns || [], fn);
3008+ }
3009+ if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {
3010+ removeEventListenerFn(element, type, handle);
3011+ delete events[type];
3012+ }
3013+ };
3014+
3015+ forEach(type.split(' '), function(type) {
3016+ removeHandler(type);
3017+ if (MOUSE_EVENT_MAP[type]) {
3018+ removeHandler(MOUSE_EVENT_MAP[type]);
3019+ }
3020+ });
3021+ }
3022+}
3023+
3024+function jqLiteRemoveData(element, name) {
3025+ var expandoId = element.ng339;
3026+ var expandoStore = expandoId && jqCache[expandoId];
3027+
3028+ if (expandoStore) {
3029+ if (name) {
3030+ delete expandoStore.data[name];
3031+ return;
3032+ }
3033+
3034+ if (expandoStore.handle) {
3035+ if (expandoStore.events.$destroy) {
3036+ expandoStore.handle({}, '$destroy');
3037+ }
3038+ jqLiteOff(element);
3039+ }
3040+ delete jqCache[expandoId];
3041+ element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
3042+ }
3043+}
3044+
3045+
3046+function jqLiteExpandoStore(element, createIfNecessary) {
3047+ var expandoId = element.ng339,
3048+ expandoStore = expandoId && jqCache[expandoId];
3049+
3050+ if (createIfNecessary && !expandoStore) {
3051+ element.ng339 = expandoId = jqNextId();
3052+ expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
3053+ }
3054+
3055+ return expandoStore;
3056+}
3057+
3058+
3059+function jqLiteData(element, key, value) {
3060+ if (jqLiteAcceptsData(element)) {
3061+
3062+ var isSimpleSetter = isDefined(value);
3063+ var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
3064+ var massGetter = !key;
3065+ var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
3066+ var data = expandoStore && expandoStore.data;
3067+
3068+ if (isSimpleSetter) { // data('key', value)
3069+ data[key] = value;
3070+ } else {
3071+ if (massGetter) { // data()
3072+ return data;
3073+ } else {
3074+ if (isSimpleGetter) { // data('key')
3075+ // don't force creation of expandoStore if it doesn't exist yet
3076+ return data && data[key];
3077+ } else { // mass-setter: data({key1: val1, key2: val2})
3078+ extend(data, key);
3079+ }
3080+ }
3081+ }
3082+ }
3083+}
3084+
3085+function jqLiteHasClass(element, selector) {
3086+ if (!element.getAttribute) return false;
3087+ return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
3088+ indexOf(" " + selector + " ") > -1);
3089+}
3090+
3091+function jqLiteRemoveClass(element, cssClasses) {
3092+ if (cssClasses && element.setAttribute) {
3093+ forEach(cssClasses.split(' '), function(cssClass) {
3094+ element.setAttribute('class', trim(
3095+ (" " + (element.getAttribute('class') || '') + " ")
3096+ .replace(/[\n\t]/g, " ")
3097+ .replace(" " + trim(cssClass) + " ", " "))
3098+ );
3099+ });
3100+ }
3101+}
3102+
3103+function jqLiteAddClass(element, cssClasses) {
3104+ if (cssClasses && element.setAttribute) {
3105+ var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
3106+ .replace(/[\n\t]/g, " ");
3107+
3108+ forEach(cssClasses.split(' '), function(cssClass) {
3109+ cssClass = trim(cssClass);
3110+ if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
3111+ existingClasses += cssClass + ' ';
3112+ }
3113+ });
3114+
3115+ element.setAttribute('class', trim(existingClasses));
3116+ }
3117+}
3118+
3119+
3120+function jqLiteAddNodes(root, elements) {
3121+ // THIS CODE IS VERY HOT. Don't make changes without benchmarking.
3122+
3123+ if (elements) {
3124+
3125+ // if a Node (the most common case)
3126+ if (elements.nodeType) {
3127+ root[root.length++] = elements;
3128+ } else {
3129+ var length = elements.length;
3130+
3131+ // if an Array or NodeList and not a Window
3132+ if (typeof length === 'number' && elements.window !== elements) {
3133+ if (length) {
3134+ for (var i = 0; i < length; i++) {
3135+ root[root.length++] = elements[i];
3136+ }
3137+ }
3138+ } else {
3139+ root[root.length++] = elements;
3140+ }
3141+ }
3142+ }
3143+}
3144+
3145+
3146+function jqLiteController(element, name) {
3147+ return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
3148+}
3149+
3150+function jqLiteInheritedData(element, name, value) {
3151+ // if element is the document object work with the html element instead
3152+ // this makes $(document).scope() possible
3153+ if (element.nodeType == NODE_TYPE_DOCUMENT) {
3154+ element = element.documentElement;
3155+ }
3156+ var names = isArray(name) ? name : [name];
3157+
3158+ while (element) {
3159+ for (var i = 0, ii = names.length; i < ii; i++) {
3160+ if (isDefined(value = jqLite.data(element, names[i]))) return value;
3161+ }
3162+
3163+ // If dealing with a document fragment node with a host element, and no parent, use the host
3164+ // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
3165+ // to lookup parent controllers.
3166+ element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
3167+ }
3168+}
3169+
3170+function jqLiteEmpty(element) {
3171+ jqLiteDealoc(element, true);
3172+ while (element.firstChild) {
3173+ element.removeChild(element.firstChild);
3174+ }
3175+}
3176+
3177+function jqLiteRemove(element, keepData) {
3178+ if (!keepData) jqLiteDealoc(element);
3179+ var parent = element.parentNode;
3180+ if (parent) parent.removeChild(element);
3181+}
3182+
3183+
3184+function jqLiteDocumentLoaded(action, win) {
3185+ win = win || window;
3186+ if (win.document.readyState === 'complete') {
3187+ // Force the action to be run async for consistent behavior
3188+ // from the action's point of view
3189+ // i.e. it will definitely not be in a $apply
3190+ win.setTimeout(action);
3191+ } else {
3192+ // No need to unbind this handler as load is only ever called once
3193+ jqLite(win).on('load', action);
3194+ }
3195+}
3196+
3197+//////////////////////////////////////////
3198+// Functions which are declared directly.
3199+//////////////////////////////////////////
3200+var JQLitePrototype = JQLite.prototype = {
3201+ ready: function(fn) {
3202+ var fired = false;
3203+
3204+ function trigger() {
3205+ if (fired) return;
3206+ fired = true;
3207+ fn();
3208+ }
3209+
3210+ // check if document is already loaded
3211+ if (window.document.readyState === 'complete') {
3212+ window.setTimeout(trigger);
3213+ } else {
3214+ this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
3215+ // we can not use jqLite since we are not done loading and jQuery could be loaded later.
3216+ // jshint -W064
3217+ JQLite(window).on('load', trigger); // fallback to window.onload for others
3218+ // jshint +W064
3219+ }
3220+ },
3221+ toString: function() {
3222+ var value = [];
3223+ forEach(this, function(e) { value.push('' + e);});
3224+ return '[' + value.join(', ') + ']';
3225+ },
3226+
3227+ eq: function(index) {
3228+ return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
3229+ },
3230+
3231+ length: 0,
3232+ push: push,
3233+ sort: [].sort,
3234+ splice: [].splice
3235+};
3236+
3237+//////////////////////////////////////////
3238+// Functions iterating getter/setters.
3239+// these functions return self on setter and
3240+// value on get.
3241+//////////////////////////////////////////
3242+var BOOLEAN_ATTR = {};
3243+forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
3244+ BOOLEAN_ATTR[lowercase(value)] = value;
3245+});
3246+var BOOLEAN_ELEMENTS = {};
3247+forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
3248+ BOOLEAN_ELEMENTS[value] = true;
3249+});
3250+var ALIASED_ATTR = {
3251+ 'ngMinlength': 'minlength',
3252+ 'ngMaxlength': 'maxlength',
3253+ 'ngMin': 'min',
3254+ 'ngMax': 'max',
3255+ 'ngPattern': 'pattern'
3256+};
3257+
3258+function getBooleanAttrName(element, name) {
3259+ // check dom last since we will most likely fail on name
3260+ var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
3261+
3262+ // booleanAttr is here twice to minimize DOM access
3263+ return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
3264+}
3265+
3266+function getAliasedAttrName(name) {
3267+ return ALIASED_ATTR[name];
3268+}
3269+
3270+forEach({
3271+ data: jqLiteData,
3272+ removeData: jqLiteRemoveData,
3273+ hasData: jqLiteHasData,
3274+ cleanData: jqLiteCleanData
3275+}, function(fn, name) {
3276+ JQLite[name] = fn;
3277+});
3278+
3279+forEach({
3280+ data: jqLiteData,
3281+ inheritedData: jqLiteInheritedData,
3282+
3283+ scope: function(element) {
3284+ // Can't use jqLiteData here directly so we stay compatible with jQuery!
3285+ return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
3286+ },
3287+
3288+ isolateScope: function(element) {
3289+ // Can't use jqLiteData here directly so we stay compatible with jQuery!
3290+ return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
3291+ },
3292+
3293+ controller: jqLiteController,
3294+
3295+ injector: function(element) {
3296+ return jqLiteInheritedData(element, '$injector');
3297+ },
3298+
3299+ removeAttr: function(element, name) {
3300+ element.removeAttribute(name);
3301+ },
3302+
3303+ hasClass: jqLiteHasClass,
3304+
3305+ css: function(element, name, value) {
3306+ name = camelCase(name);
3307+
3308+ if (isDefined(value)) {
3309+ element.style[name] = value;
3310+ } else {
3311+ return element.style[name];
3312+ }
3313+ },
3314+
3315+ attr: function(element, name, value) {
3316+ var nodeType = element.nodeType;
3317+ if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) {
3318+ return;
3319+ }
3320+ var lowercasedName = lowercase(name);
3321+ if (BOOLEAN_ATTR[lowercasedName]) {
3322+ if (isDefined(value)) {
3323+ if (!!value) {
3324+ element[name] = true;
3325+ element.setAttribute(name, lowercasedName);
3326+ } else {
3327+ element[name] = false;
3328+ element.removeAttribute(lowercasedName);
3329+ }
3330+ } else {
3331+ return (element[name] ||
3332+ (element.attributes.getNamedItem(name) || noop).specified)
3333+ ? lowercasedName
3334+ : undefined;
3335+ }
3336+ } else if (isDefined(value)) {
3337+ element.setAttribute(name, value);
3338+ } else if (element.getAttribute) {
3339+ // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
3340+ // some elements (e.g. Document) don't have get attribute, so return undefined
3341+ var ret = element.getAttribute(name, 2);
3342+ // normalize non-existing attributes to undefined (as jQuery)
3343+ return ret === null ? undefined : ret;
3344+ }
3345+ },
3346+
3347+ prop: function(element, name, value) {
3348+ if (isDefined(value)) {
3349+ element[name] = value;
3350+ } else {
3351+ return element[name];
3352+ }
3353+ },
3354+
3355+ text: (function() {
3356+ getText.$dv = '';
3357+ return getText;
3358+
3359+ function getText(element, value) {
3360+ if (isUndefined(value)) {
3361+ var nodeType = element.nodeType;
3362+ return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
3363+ }
3364+ element.textContent = value;
3365+ }
3366+ })(),
3367+
3368+ val: function(element, value) {
3369+ if (isUndefined(value)) {
3370+ if (element.multiple && nodeName_(element) === 'select') {
3371+ var result = [];
3372+ forEach(element.options, function(option) {
3373+ if (option.selected) {
3374+ result.push(option.value || option.text);
3375+ }
3376+ });
3377+ return result.length === 0 ? null : result;
3378+ }
3379+ return element.value;
3380+ }
3381+ element.value = value;
3382+ },
3383+
3384+ html: function(element, value) {
3385+ if (isUndefined(value)) {
3386+ return element.innerHTML;
3387+ }
3388+ jqLiteDealoc(element, true);
3389+ element.innerHTML = value;
3390+ },
3391+
3392+ empty: jqLiteEmpty
3393+}, function(fn, name) {
3394+ /**
3395+ * Properties: writes return selection, reads return first value
3396+ */
3397+ JQLite.prototype[name] = function(arg1, arg2) {
3398+ var i, key;
3399+ var nodeCount = this.length;
3400+
3401+ // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
3402+ // in a way that survives minification.
3403+ // jqLiteEmpty takes no arguments but is a setter.
3404+ if (fn !== jqLiteEmpty &&
3405+ (isUndefined((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {
3406+ if (isObject(arg1)) {
3407+
3408+ // we are a write, but the object properties are the key/values
3409+ for (i = 0; i < nodeCount; i++) {
3410+ if (fn === jqLiteData) {
3411+ // data() takes the whole object in jQuery
3412+ fn(this[i], arg1);
3413+ } else {
3414+ for (key in arg1) {
3415+ fn(this[i], key, arg1[key]);
3416+ }
3417+ }
3418+ }
3419+ // return self for chaining
3420+ return this;
3421+ } else {
3422+ // we are a read, so read the first child.
3423+ // TODO: do we still need this?
3424+ var value = fn.$dv;
3425+ // Only if we have $dv do we iterate over all, otherwise it is just the first element.
3426+ var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;
3427+ for (var j = 0; j < jj; j++) {
3428+ var nodeValue = fn(this[j], arg1, arg2);
3429+ value = value ? value + nodeValue : nodeValue;
3430+ }
3431+ return value;
3432+ }
3433+ } else {
3434+ // we are a write, so apply to all children
3435+ for (i = 0; i < nodeCount; i++) {
3436+ fn(this[i], arg1, arg2);
3437+ }
3438+ // return self for chaining
3439+ return this;
3440+ }
3441+ };
3442+});
3443+
3444+function createEventHandler(element, events) {
3445+ var eventHandler = function(event, type) {
3446+ // jQuery specific api
3447+ event.isDefaultPrevented = function() {
3448+ return event.defaultPrevented;
3449+ };
3450+
3451+ var eventFns = events[type || event.type];
3452+ var eventFnsLength = eventFns ? eventFns.length : 0;
3453+
3454+ if (!eventFnsLength) return;
3455+
3456+ if (isUndefined(event.immediatePropagationStopped)) {
3457+ var originalStopImmediatePropagation = event.stopImmediatePropagation;
3458+ event.stopImmediatePropagation = function() {
3459+ event.immediatePropagationStopped = true;
3460+
3461+ if (event.stopPropagation) {
3462+ event.stopPropagation();
3463+ }
3464+
3465+ if (originalStopImmediatePropagation) {
3466+ originalStopImmediatePropagation.call(event);
3467+ }
3468+ };
3469+ }
3470+
3471+ event.isImmediatePropagationStopped = function() {
3472+ return event.immediatePropagationStopped === true;
3473+ };
3474+
3475+ // Some events have special handlers that wrap the real handler
3476+ var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;
3477+
3478+ // Copy event handlers in case event handlers array is modified during execution.
3479+ if ((eventFnsLength > 1)) {
3480+ eventFns = shallowCopy(eventFns);
3481+ }
3482+
3483+ for (var i = 0; i < eventFnsLength; i++) {
3484+ if (!event.isImmediatePropagationStopped()) {
3485+ handlerWrapper(element, event, eventFns[i]);
3486+ }
3487+ }
3488+ };
3489+
3490+ // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
3491+ // events on `element`
3492+ eventHandler.elem = element;
3493+ return eventHandler;
3494+}
3495+
3496+function defaultHandlerWrapper(element, event, handler) {
3497+ handler.call(element, event);
3498+}
3499+
3500+function specialMouseHandlerWrapper(target, event, handler) {
3501+ // Refer to jQuery's implementation of mouseenter & mouseleave
3502+ // Read about mouseenter and mouseleave:
3503+ // http://www.quirksmode.org/js/events_mouse.html#link8
3504+ var related = event.relatedTarget;
3505+ // For mousenter/leave call the handler if related is outside the target.
3506+ // NB: No relatedTarget if the mouse left/entered the browser window
3507+ if (!related || (related !== target && !jqLiteContains.call(target, related))) {
3508+ handler.call(target, event);
3509+ }
3510+}
3511+
3512+//////////////////////////////////////////
3513+// Functions iterating traversal.
3514+// These functions chain results into a single
3515+// selector.
3516+//////////////////////////////////////////
3517+forEach({
3518+ removeData: jqLiteRemoveData,
3519+
3520+ on: function jqLiteOn(element, type, fn, unsupported) {
3521+ if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
3522+
3523+ // Do not add event handlers to non-elements because they will not be cleaned up.
3524+ if (!jqLiteAcceptsData(element)) {
3525+ return;
3526+ }
3527+
3528+ var expandoStore = jqLiteExpandoStore(element, true);
3529+ var events = expandoStore.events;
3530+ var handle = expandoStore.handle;
3531+
3532+ if (!handle) {
3533+ handle = expandoStore.handle = createEventHandler(element, events);
3534+ }
3535+
3536+ // http://jsperf.com/string-indexof-vs-split
3537+ var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
3538+ var i = types.length;
3539+
3540+ var addHandler = function(type, specialHandlerWrapper, noEventListener) {
3541+ var eventFns = events[type];
3542+
3543+ if (!eventFns) {
3544+ eventFns = events[type] = [];
3545+ eventFns.specialHandlerWrapper = specialHandlerWrapper;
3546+ if (type !== '$destroy' && !noEventListener) {
3547+ addEventListenerFn(element, type, handle);
3548+ }
3549+ }
3550+
3551+ eventFns.push(fn);
3552+ };
3553+
3554+ while (i--) {
3555+ type = types[i];
3556+ if (MOUSE_EVENT_MAP[type]) {
3557+ addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
3558+ addHandler(type, undefined, true);
3559+ } else {
3560+ addHandler(type);
3561+ }
3562+ }
3563+ },
3564+
3565+ off: jqLiteOff,
3566+
3567+ one: function(element, type, fn) {
3568+ element = jqLite(element);
3569+
3570+ //add the listener twice so that when it is called
3571+ //you can remove the original function and still be
3572+ //able to call element.off(ev, fn) normally
3573+ element.on(type, function onFn() {
3574+ element.off(type, fn);
3575+ element.off(type, onFn);
3576+ });
3577+ element.on(type, fn);
3578+ },
3579+
3580+ replaceWith: function(element, replaceNode) {
3581+ var index, parent = element.parentNode;
3582+ jqLiteDealoc(element);
3583+ forEach(new JQLite(replaceNode), function(node) {
3584+ if (index) {
3585+ parent.insertBefore(node, index.nextSibling);
3586+ } else {
3587+ parent.replaceChild(node, element);
3588+ }
3589+ index = node;
3590+ });
3591+ },
3592+
3593+ children: function(element) {
3594+ var children = [];
3595+ forEach(element.childNodes, function(element) {
3596+ if (element.nodeType === NODE_TYPE_ELEMENT) {
3597+ children.push(element);
3598+ }
3599+ });
3600+ return children;
3601+ },
3602+
3603+ contents: function(element) {
3604+ return element.contentDocument || element.childNodes || [];
3605+ },
3606+
3607+ append: function(element, node) {
3608+ var nodeType = element.nodeType;
3609+ if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;
3610+
3611+ node = new JQLite(node);
3612+
3613+ for (var i = 0, ii = node.length; i < ii; i++) {
3614+ var child = node[i];
3615+ element.appendChild(child);
3616+ }
3617+ },
3618+
3619+ prepend: function(element, node) {
3620+ if (element.nodeType === NODE_TYPE_ELEMENT) {
3621+ var index = element.firstChild;
3622+ forEach(new JQLite(node), function(child) {
3623+ element.insertBefore(child, index);
3624+ });
3625+ }
3626+ },
3627+
3628+ wrap: function(element, wrapNode) {
3629+ jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
3630+ },
3631+
3632+ remove: jqLiteRemove,
3633+
3634+ detach: function(element) {
3635+ jqLiteRemove(element, true);
3636+ },
3637+
3638+ after: function(element, newElement) {
3639+ var index = element, parent = element.parentNode;
3640+ newElement = new JQLite(newElement);
3641+
3642+ for (var i = 0, ii = newElement.length; i < ii; i++) {
3643+ var node = newElement[i];
3644+ parent.insertBefore(node, index.nextSibling);
3645+ index = node;
3646+ }
3647+ },
3648+
3649+ addClass: jqLiteAddClass,
3650+ removeClass: jqLiteRemoveClass,
3651+
3652+ toggleClass: function(element, selector, condition) {
3653+ if (selector) {
3654+ forEach(selector.split(' '), function(className) {
3655+ var classCondition = condition;
3656+ if (isUndefined(classCondition)) {
3657+ classCondition = !jqLiteHasClass(element, className);
3658+ }
3659+ (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
3660+ });
3661+ }
3662+ },
3663+
3664+ parent: function(element) {
3665+ var parent = element.parentNode;
3666+ return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
3667+ },
3668+
3669+ next: function(element) {
3670+ return element.nextElementSibling;
3671+ },
3672+
3673+ find: function(element, selector) {
3674+ if (element.getElementsByTagName) {
3675+ return element.getElementsByTagName(selector);
3676+ } else {
3677+ return [];
3678+ }
3679+ },
3680+
3681+ clone: jqLiteClone,
3682+
3683+ triggerHandler: function(element, event, extraParameters) {
3684+
3685+ var dummyEvent, eventFnsCopy, handlerArgs;
3686+ var eventName = event.type || event;
3687+ var expandoStore = jqLiteExpandoStore(element);
3688+ var events = expandoStore && expandoStore.events;
3689+ var eventFns = events && events[eventName];
3690+
3691+ if (eventFns) {
3692+ // Create a dummy event to pass to the handlers
3693+ dummyEvent = {
3694+ preventDefault: function() { this.defaultPrevented = true; },
3695+ isDefaultPrevented: function() { return this.defaultPrevented === true; },
3696+ stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
3697+ isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
3698+ stopPropagation: noop,
3699+ type: eventName,
3700+ target: element
3701+ };
3702+
3703+ // If a custom event was provided then extend our dummy event with it
3704+ if (event.type) {
3705+ dummyEvent = extend(dummyEvent, event);
3706+ }
3707+
3708+ // Copy event handlers in case event handlers array is modified during execution.
3709+ eventFnsCopy = shallowCopy(eventFns);
3710+ handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
3711+
3712+ forEach(eventFnsCopy, function(fn) {
3713+ if (!dummyEvent.isImmediatePropagationStopped()) {
3714+ fn.apply(element, handlerArgs);
3715+ }
3716+ });
3717+ }
3718+ }
3719+}, function(fn, name) {
3720+ /**
3721+ * chaining functions
3722+ */
3723+ JQLite.prototype[name] = function(arg1, arg2, arg3) {
3724+ var value;
3725+
3726+ for (var i = 0, ii = this.length; i < ii; i++) {
3727+ if (isUndefined(value)) {
3728+ value = fn(this[i], arg1, arg2, arg3);
3729+ if (isDefined(value)) {
3730+ // any function which returns a value needs to be wrapped
3731+ value = jqLite(value);
3732+ }
3733+ } else {
3734+ jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
3735+ }
3736+ }
3737+ return isDefined(value) ? value : this;
3738+ };
3739+
3740+ // bind legacy bind/unbind to on/off
3741+ JQLite.prototype.bind = JQLite.prototype.on;
3742+ JQLite.prototype.unbind = JQLite.prototype.off;
3743+});
3744+
3745+
3746+// Provider for private $$jqLite service
3747+function $$jqLiteProvider() {
3748+ this.$get = function $$jqLite() {
3749+ return extend(JQLite, {
3750+ hasClass: function(node, classes) {
3751+ if (node.attr) node = node[0];
3752+ return jqLiteHasClass(node, classes);
3753+ },
3754+ addClass: function(node, classes) {
3755+ if (node.attr) node = node[0];
3756+ return jqLiteAddClass(node, classes);
3757+ },
3758+ removeClass: function(node, classes) {
3759+ if (node.attr) node = node[0];
3760+ return jqLiteRemoveClass(node, classes);
3761+ }
3762+ });
3763+ };
3764+}
3765+
3766+/**
3767+ * Computes a hash of an 'obj'.
3768+ * Hash of a:
3769+ * string is string
3770+ * number is number as string
3771+ * object is either result of calling $$hashKey function on the object or uniquely generated id,
3772+ * that is also assigned to the $$hashKey property of the object.
3773+ *
3774+ * @param obj
3775+ * @returns {string} hash string such that the same input will have the same hash string.
3776+ * The resulting string key is in 'type:hashKey' format.
3777+ */
3778+function hashKey(obj, nextUidFn) {
3779+ var key = obj && obj.$$hashKey;
3780+
3781+ if (key) {
3782+ if (typeof key === 'function') {
3783+ key = obj.$$hashKey();
3784+ }
3785+ return key;
3786+ }
3787+
3788+ var objType = typeof obj;
3789+ if (objType == 'function' || (objType == 'object' && obj !== null)) {
3790+ key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
3791+ } else {
3792+ key = objType + ':' + obj;
3793+ }
3794+
3795+ return key;
3796+}
3797+
3798+/**
3799+ * HashMap which can use objects as keys
3800+ */
3801+function HashMap(array, isolatedUid) {
3802+ if (isolatedUid) {
3803+ var uid = 0;
3804+ this.nextUid = function() {
3805+ return ++uid;
3806+ };
3807+ }
3808+ forEach(array, this.put, this);
3809+}
3810+HashMap.prototype = {
3811+ /**
3812+ * Store key value pair
3813+ * @param key key to store can be any type
3814+ * @param value value to store can be any type
3815+ */
3816+ put: function(key, value) {
3817+ this[hashKey(key, this.nextUid)] = value;
3818+ },
3819+
3820+ /**
3821+ * @param key
3822+ * @returns {Object} the value for the key
3823+ */
3824+ get: function(key) {
3825+ return this[hashKey(key, this.nextUid)];
3826+ },
3827+
3828+ /**
3829+ * Remove the key/value pair
3830+ * @param key
3831+ */
3832+ remove: function(key) {
3833+ var value = this[key = hashKey(key, this.nextUid)];
3834+ delete this[key];
3835+ return value;
3836+ }
3837+};
3838+
3839+var $$HashMapProvider = [function() {
3840+ this.$get = [function() {
3841+ return HashMap;
3842+ }];
3843+}];
3844+
3845+/**
3846+ * @ngdoc function
3847+ * @module ng
3848+ * @name angular.injector
3849+ * @kind function
3850+ *
3851+ * @description
3852+ * Creates an injector object that can be used for retrieving services as well as for
3853+ * dependency injection (see {@link guide/di dependency injection}).
3854+ *
3855+ * @param {Array.<string|Function>} modules A list of module functions or their aliases. See
3856+ * {@link angular.module}. The `ng` module must be explicitly added.
3857+ * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
3858+ * disallows argument name annotation inference.
3859+ * @returns {injector} Injector object. See {@link auto.$injector $injector}.
3860+ *
3861+ * @example
3862+ * Typical usage
3863+ * ```js
3864+ * // create an injector
3865+ * var $injector = angular.injector(['ng']);
3866+ *
3867+ * // use the injector to kick off your application
3868+ * // use the type inference to auto inject arguments, or use implicit injection
3869+ * $injector.invoke(function($rootScope, $compile, $document) {
3870+ * $compile($document)($rootScope);
3871+ * $rootScope.$digest();
3872+ * });
3873+ * ```
3874+ *
3875+ * Sometimes you want to get access to the injector of a currently running Angular app
3876+ * from outside Angular. Perhaps, you want to inject and compile some markup after the
3877+ * application has been bootstrapped. You can do this using the extra `injector()` added
3878+ * to JQuery/jqLite elements. See {@link angular.element}.
3879+ *
3880+ * *This is fairly rare but could be the case if a third party library is injecting the
3881+ * markup.*
3882+ *
3883+ * In the following example a new block of HTML containing a `ng-controller`
3884+ * directive is added to the end of the document body by JQuery. We then compile and link
3885+ * it into the current AngularJS scope.
3886+ *
3887+ * ```js
3888+ * var $div = $('<div ng-controller="MyCtrl">{{content.label}}</div>');
3889+ * $(document.body).append($div);
3890+ *
3891+ * angular.element(document).injector().invoke(function($compile) {
3892+ * var scope = angular.element($div).scope();
3893+ * $compile($div)(scope);
3894+ * });
3895+ * ```
3896+ */
3897+
3898+
3899+/**
3900+ * @ngdoc module
3901+ * @name auto
3902+ * @installation
3903+ * @description
3904+ *
3905+ * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
3906+ */
3907+
3908+var ARROW_ARG = /^([^\(]+?)=>/;
3909+var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
3910+var FN_ARG_SPLIT = /,/;
3911+var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
3912+var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
3913+var $injectorMinErr = minErr('$injector');
3914+
3915+function stringifyFn(fn) {
3916+ // Support: Chrome 50-51 only
3917+ // Creating a new string by adding `' '` at the end, to hack around some bug in Chrome v50/51
3918+ // (See https://github.com/angular/angular.js/issues/14487.)
3919+ // TODO (gkalpak): Remove workaround when Chrome v52 is released
3920+ return Function.prototype.toString.call(fn) + ' ';
3921+}
3922+
3923+function extractArgs(fn) {
3924+ var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''),
3925+ args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
3926+ return args;
3927+}
3928+
3929+function anonFn(fn) {
3930+ // For anonymous functions, showing at the very least the function signature can help in
3931+ // debugging.
3932+ var args = extractArgs(fn);
3933+ if (args) {
3934+ return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
3935+ }
3936+ return 'fn';
3937+}
3938+
3939+function annotate(fn, strictDi, name) {
3940+ var $inject,
3941+ argDecl,
3942+ last;
3943+
3944+ if (typeof fn === 'function') {
3945+ if (!($inject = fn.$inject)) {
3946+ $inject = [];
3947+ if (fn.length) {
3948+ if (strictDi) {
3949+ if (!isString(name) || !name) {
3950+ name = fn.name || anonFn(fn);
3951+ }
3952+ throw $injectorMinErr('strictdi',
3953+ '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
3954+ }
3955+ argDecl = extractArgs(fn);
3956+ forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
3957+ arg.replace(FN_ARG, function(all, underscore, name) {
3958+ $inject.push(name);
3959+ });
3960+ });
3961+ }
3962+ fn.$inject = $inject;
3963+ }
3964+ } else if (isArray(fn)) {
3965+ last = fn.length - 1;
3966+ assertArgFn(fn[last], 'fn');
3967+ $inject = fn.slice(0, last);
3968+ } else {
3969+ assertArgFn(fn, 'fn', true);
3970+ }
3971+ return $inject;
3972+}
3973+
3974+///////////////////////////////////////
3975+
3976+/**
3977+ * @ngdoc service
3978+ * @name $injector
3979+ *
3980+ * @description
3981+ *
3982+ * `$injector` is used to retrieve object instances as defined by
3983+ * {@link auto.$provide provider}, instantiate types, invoke methods,
3984+ * and load modules.
3985+ *
3986+ * The following always holds true:
3987+ *
3988+ * ```js
3989+ * var $injector = angular.injector();
3990+ * expect($injector.get('$injector')).toBe($injector);
3991+ * expect($injector.invoke(function($injector) {
3992+ * return $injector;
3993+ * })).toBe($injector);
3994+ * ```
3995+ *
3996+ * # Injection Function Annotation
3997+ *
3998+ * JavaScript does not have annotations, and annotations are needed for dependency injection. The
3999+ * following are all valid ways of annotating function with injection arguments and are equivalent.
4000+ *
4001+ * ```js
4002+ * // inferred (only works if code not minified/obfuscated)
4003+ * $injector.invoke(function(serviceA){});
4004+ *
4005+ * // annotated
4006+ * function explicit(serviceA) {};
4007+ * explicit.$inject = ['serviceA'];
4008+ * $injector.invoke(explicit);
4009+ *
4010+ * // inline
4011+ * $injector.invoke(['serviceA', function(serviceA){}]);
4012+ * ```
4013+ *
4014+ * ## Inference
4015+ *
4016+ * In JavaScript calling `toString()` on a function returns the function definition. The definition
4017+ * can then be parsed and the function arguments can be extracted. This method of discovering
4018+ * annotations is disallowed when the injector is in strict mode.
4019+ * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
4020+ * argument names.
4021+ *
4022+ * ## `$inject` Annotation
4023+ * By adding an `$inject` property onto a function the injection parameters can be specified.
4024+ *
4025+ * ## Inline
4026+ * As an array of injection names, where the last item in the array is the function to call.
4027+ */
4028+
4029+/**
4030+ * @ngdoc method
4031+ * @name $injector#get
4032+ *
4033+ * @description
4034+ * Return an instance of the service.
4035+ *
4036+ * @param {string} name The name of the instance to retrieve.
4037+ * @param {string=} caller An optional string to provide the origin of the function call for error messages.
4038+ * @return {*} The instance.
4039+ */
4040+
4041+/**
4042+ * @ngdoc method
4043+ * @name $injector#invoke
4044+ *
4045+ * @description
4046+ * Invoke the method and supply the method arguments from the `$injector`.
4047+ *
4048+ * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
4049+ * injected according to the {@link guide/di $inject Annotation} rules.
4050+ * @param {Object=} self The `this` for the invoked method.
4051+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
4052+ * object first, before the `$injector` is consulted.
4053+ * @returns {*} the value returned by the invoked `fn` function.
4054+ */
4055+
4056+/**
4057+ * @ngdoc method
4058+ * @name $injector#has
4059+ *
4060+ * @description
4061+ * Allows the user to query if the particular service exists.
4062+ *
4063+ * @param {string} name Name of the service to query.
4064+ * @returns {boolean} `true` if injector has given service.
4065+ */
4066+
4067+/**
4068+ * @ngdoc method
4069+ * @name $injector#instantiate
4070+ * @description
4071+ * Create a new instance of JS type. The method takes a constructor function, invokes the new
4072+ * operator, and supplies all of the arguments to the constructor function as specified by the
4073+ * constructor annotation.
4074+ *
4075+ * @param {Function} Type Annotated constructor function.
4076+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
4077+ * object first, before the `$injector` is consulted.
4078+ * @returns {Object} new instance of `Type`.
4079+ */
4080+
4081+/**
4082+ * @ngdoc method
4083+ * @name $injector#annotate
4084+ *
4085+ * @description
4086+ * Returns an array of service names which the function is requesting for injection. This API is
4087+ * used by the injector to determine which services need to be injected into the function when the
4088+ * function is invoked. There are three ways in which the function can be annotated with the needed
4089+ * dependencies.
4090+ *
4091+ * # Argument names
4092+ *
4093+ * The simplest form is to extract the dependencies from the arguments of the function. This is done
4094+ * by converting the function into a string using `toString()` method and extracting the argument
4095+ * names.
4096+ * ```js
4097+ * // Given
4098+ * function MyController($scope, $route) {
4099+ * // ...
4100+ * }
4101+ *
4102+ * // Then
4103+ * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
4104+ * ```
4105+ *
4106+ * You can disallow this method by using strict injection mode.
4107+ *
4108+ * This method does not work with code minification / obfuscation. For this reason the following
4109+ * annotation strategies are supported.
4110+ *
4111+ * # The `$inject` property
4112+ *
4113+ * If a function has an `$inject` property and its value is an array of strings, then the strings
4114+ * represent names of services to be injected into the function.
4115+ * ```js
4116+ * // Given
4117+ * var MyController = function(obfuscatedScope, obfuscatedRoute) {
4118+ * // ...
4119+ * }
4120+ * // Define function dependencies
4121+ * MyController['$inject'] = ['$scope', '$route'];
4122+ *
4123+ * // Then
4124+ * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
4125+ * ```
4126+ *
4127+ * # The array notation
4128+ *
4129+ * It is often desirable to inline Injected functions and that's when setting the `$inject` property
4130+ * is very inconvenient. In these situations using the array notation to specify the dependencies in
4131+ * a way that survives minification is a better choice:
4132+ *
4133+ * ```js
4134+ * // We wish to write this (not minification / obfuscation safe)
4135+ * injector.invoke(function($compile, $rootScope) {
4136+ * // ...
4137+ * });
4138+ *
4139+ * // We are forced to write break inlining
4140+ * var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
4141+ * // ...
4142+ * };
4143+ * tmpFn.$inject = ['$compile', '$rootScope'];
4144+ * injector.invoke(tmpFn);
4145+ *
4146+ * // To better support inline function the inline annotation is supported
4147+ * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
4148+ * // ...
4149+ * }]);
4150+ *
4151+ * // Therefore
4152+ * expect(injector.annotate(
4153+ * ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
4154+ * ).toEqual(['$compile', '$rootScope']);
4155+ * ```
4156+ *
4157+ * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
4158+ * be retrieved as described above.
4159+ *
4160+ * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
4161+ *
4162+ * @returns {Array.<string>} The names of the services which the function requires.
4163+ */
4164+
4165+
4166+
4167+
4168+/**
4169+ * @ngdoc service
4170+ * @name $provide
4171+ *
4172+ * @description
4173+ *
4174+ * The {@link auto.$provide $provide} service has a number of methods for registering components
4175+ * with the {@link auto.$injector $injector}. Many of these functions are also exposed on
4176+ * {@link angular.Module}.
4177+ *
4178+ * An Angular **service** is a singleton object created by a **service factory**. These **service
4179+ * factories** are functions which, in turn, are created by a **service provider**.
4180+ * The **service providers** are constructor functions. When instantiated they must contain a
4181+ * property called `$get`, which holds the **service factory** function.
4182+ *
4183+ * When you request a service, the {@link auto.$injector $injector} is responsible for finding the
4184+ * correct **service provider**, instantiating it and then calling its `$get` **service factory**
4185+ * function to get the instance of the **service**.
4186+ *
4187+ * Often services have no configuration options and there is no need to add methods to the service
4188+ * provider. The provider will be no more than a constructor function with a `$get` property. For
4189+ * these cases the {@link auto.$provide $provide} service has additional helper methods to register
4190+ * services without specifying a provider.
4191+ *
4192+ * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the
4193+ * {@link auto.$injector $injector}
4194+ * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by
4195+ * providers and services.
4196+ * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by
4197+ * services, not providers.
4198+ * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function**
4199+ * that will be wrapped in a **service provider** object, whose `$get` property will contain the
4200+ * given factory function.
4201+ * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function**
4202+ * that will be wrapped in a **service provider** object, whose `$get` property will instantiate
4203+ * a new object using the given constructor function.
4204+ * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that
4205+ * will be able to modify or replace the implementation of another service.
4206+ *
4207+ * See the individual methods for more information and examples.
4208+ */
4209+
4210+/**
4211+ * @ngdoc method
4212+ * @name $provide#provider
4213+ * @description
4214+ *
4215+ * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions
4216+ * are constructor functions, whose instances are responsible for "providing" a factory for a
4217+ * service.
4218+ *
4219+ * Service provider names start with the name of the service they provide followed by `Provider`.
4220+ * For example, the {@link ng.$log $log} service has a provider called
4221+ * {@link ng.$logProvider $logProvider}.
4222+ *
4223+ * Service provider objects can have additional methods which allow configuration of the provider
4224+ * and its service. Importantly, you can configure what kind of service is created by the `$get`
4225+ * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a
4226+ * method {@link ng.$logProvider#debugEnabled debugEnabled}
4227+ * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
4228+ * console or not.
4229+ *
4230+ * @param {string} name The name of the instance. NOTE: the provider will be available under `name +
4231+ 'Provider'` key.
4232+ * @param {(Object|function())} provider If the provider is:
4233+ *
4234+ * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
4235+ * {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.
4236+ * - `Constructor`: a new instance of the provider will be created using
4237+ * {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.
4238+ *
4239+ * @returns {Object} registered provider instance
4240+
4241+ * @example
4242+ *
4243+ * The following example shows how to create a simple event tracking service and register it using
4244+ * {@link auto.$provide#provider $provide.provider()}.
4245+ *
4246+ * ```js
4247+ * // Define the eventTracker provider
4248+ * function EventTrackerProvider() {
4249+ * var trackingUrl = '/track';
4250+ *
4251+ * // A provider method for configuring where the tracked events should been saved
4252+ * this.setTrackingUrl = function(url) {
4253+ * trackingUrl = url;
4254+ * };
4255+ *
4256+ * // The service factory function
4257+ * this.$get = ['$http', function($http) {
4258+ * var trackedEvents = {};
4259+ * return {
4260+ * // Call this to track an event
4261+ * event: function(event) {
4262+ * var count = trackedEvents[event] || 0;
4263+ * count += 1;
4264+ * trackedEvents[event] = count;
4265+ * return count;
4266+ * },
4267+ * // Call this to save the tracked events to the trackingUrl
4268+ * save: function() {
4269+ * $http.post(trackingUrl, trackedEvents);
4270+ * }
4271+ * };
4272+ * }];
4273+ * }
4274+ *
4275+ * describe('eventTracker', function() {
4276+ * var postSpy;
4277+ *
4278+ * beforeEach(module(function($provide) {
4279+ * // Register the eventTracker provider
4280+ * $provide.provider('eventTracker', EventTrackerProvider);
4281+ * }));
4282+ *
4283+ * beforeEach(module(function(eventTrackerProvider) {
4284+ * // Configure eventTracker provider
4285+ * eventTrackerProvider.setTrackingUrl('/custom-track');
4286+ * }));
4287+ *
4288+ * it('tracks events', inject(function(eventTracker) {
4289+ * expect(eventTracker.event('login')).toEqual(1);
4290+ * expect(eventTracker.event('login')).toEqual(2);
4291+ * }));
4292+ *
4293+ * it('saves to the tracking url', inject(function(eventTracker, $http) {
4294+ * postSpy = spyOn($http, 'post');
4295+ * eventTracker.event('login');
4296+ * eventTracker.save();
4297+ * expect(postSpy).toHaveBeenCalled();
4298+ * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
4299+ * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
4300+ * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
4301+ * }));
4302+ * });
4303+ * ```
4304+ */
4305+
4306+/**
4307+ * @ngdoc method
4308+ * @name $provide#factory
4309+ * @description
4310+ *
4311+ * Register a **service factory**, which will be called to return the service instance.
4312+ * This is short for registering a service where its provider consists of only a `$get` property,
4313+ * which is the given service factory function.
4314+ * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
4315+ * configure your service in a provider.
4316+ *
4317+ * @param {string} name The name of the instance.
4318+ * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
4319+ * Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
4320+ * @returns {Object} registered provider instance
4321+ *
4322+ * @example
4323+ * Here is an example of registering a service
4324+ * ```js
4325+ * $provide.factory('ping', ['$http', function($http) {
4326+ * return function ping() {
4327+ * return $http.send('/ping');
4328+ * };
4329+ * }]);
4330+ * ```
4331+ * You would then inject and use this service like this:
4332+ * ```js
4333+ * someModule.controller('Ctrl', ['ping', function(ping) {
4334+ * ping();
4335+ * }]);
4336+ * ```
4337+ */
4338+
4339+
4340+/**
4341+ * @ngdoc method
4342+ * @name $provide#service
4343+ * @description
4344+ *
4345+ * Register a **service constructor**, which will be invoked with `new` to create the service
4346+ * instance.
4347+ * This is short for registering a service where its provider's `$get` property is a factory
4348+ * function that returns an instance instantiated by the injector from the service constructor
4349+ * function.
4350+ *
4351+ * Internally it looks a bit like this:
4352+ *
4353+ * ```
4354+ * {
4355+ * $get: function() {
4356+ * return $injector.instantiate(constructor);
4357+ * }
4358+ * }
4359+ * ```
4360+ *
4361+ *
4362+ * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
4363+ * as a type/class.
4364+ *
4365+ * @param {string} name The name of the instance.
4366+ * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
4367+ * that will be instantiated.
4368+ * @returns {Object} registered provider instance
4369+ *
4370+ * @example
4371+ * Here is an example of registering a service using
4372+ * {@link auto.$provide#service $provide.service(class)}.
4373+ * ```js
4374+ * var Ping = function($http) {
4375+ * this.$http = $http;
4376+ * };
4377+ *
4378+ * Ping.$inject = ['$http'];
4379+ *
4380+ * Ping.prototype.send = function() {
4381+ * return this.$http.get('/ping');
4382+ * };
4383+ * $provide.service('ping', Ping);
4384+ * ```
4385+ * You would then inject and use this service like this:
4386+ * ```js
4387+ * someModule.controller('Ctrl', ['ping', function(ping) {
4388+ * ping.send();
4389+ * }]);
4390+ * ```
4391+ */
4392+
4393+
4394+/**
4395+ * @ngdoc method
4396+ * @name $provide#value
4397+ * @description
4398+ *
4399+ * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
4400+ * number, an array, an object or a function. This is short for registering a service where its
4401+ * provider's `$get` property is a factory function that takes no arguments and returns the **value
4402+ * service**. That also means it is not possible to inject other services into a value service.
4403+ *
4404+ * Value services are similar to constant services, except that they cannot be injected into a
4405+ * module configuration function (see {@link angular.Module#config}) but they can be overridden by
4406+ * an Angular {@link auto.$provide#decorator decorator}.
4407+ *
4408+ * @param {string} name The name of the instance.
4409+ * @param {*} value The value.
4410+ * @returns {Object} registered provider instance
4411+ *
4412+ * @example
4413+ * Here are some examples of creating value services.
4414+ * ```js
4415+ * $provide.value('ADMIN_USER', 'admin');
4416+ *
4417+ * $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
4418+ *
4419+ * $provide.value('halfOf', function(value) {
4420+ * return value / 2;
4421+ * });
4422+ * ```
4423+ */
4424+
4425+
4426+/**
4427+ * @ngdoc method
4428+ * @name $provide#constant
4429+ * @description
4430+ *
4431+ * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,
4432+ * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not
4433+ * possible to inject other services into a constant.
4434+ *
4435+ * But unlike {@link auto.$provide#value value}, a constant can be
4436+ * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
4437+ * be overridden by an Angular {@link auto.$provide#decorator decorator}.
4438+ *
4439+ * @param {string} name The name of the constant.
4440+ * @param {*} value The constant value.
4441+ * @returns {Object} registered instance
4442+ *
4443+ * @example
4444+ * Here a some examples of creating constants:
4445+ * ```js
4446+ * $provide.constant('SHARD_HEIGHT', 306);
4447+ *
4448+ * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
4449+ *
4450+ * $provide.constant('double', function(value) {
4451+ * return value * 2;
4452+ * });
4453+ * ```
4454+ */
4455+
4456+
4457+/**
4458+ * @ngdoc method
4459+ * @name $provide#decorator
4460+ * @description
4461+ *
4462+ * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function
4463+ * intercepts the creation of a service, allowing it to override or modify the behavior of the
4464+ * service. The return value of the decorator function may be the original service, or a new service
4465+ * that replaces (or wraps and delegates to) the original service.
4466+ *
4467+ * You can find out more about using decorators in the {@link guide/decorators} guide.
4468+ *
4469+ * @param {string} name The name of the service to decorate.
4470+ * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
4471+ * provided and should return the decorated service instance. The function is called using
4472+ * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
4473+ * Local injection arguments:
4474+ *
4475+ * * `$delegate` - The original service instance, which can be replaced, monkey patched, configured,
4476+ * decorated or delegated to.
4477+ *
4478+ * @example
4479+ * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
4480+ * calls to {@link ng.$log#error $log.warn()}.
4481+ * ```js
4482+ * $provide.decorator('$log', ['$delegate', function($delegate) {
4483+ * $delegate.warn = $delegate.error;
4484+ * return $delegate;
4485+ * }]);
4486+ * ```
4487+ */
4488+
4489+
4490+function createInjector(modulesToLoad, strictDi) {
4491+ strictDi = (strictDi === true);
4492+ var INSTANTIATING = {},
4493+ providerSuffix = 'Provider',
4494+ path = [],
4495+ loadedModules = new HashMap([], true),
4496+ providerCache = {
4497+ $provide: {
4498+ provider: supportObject(provider),
4499+ factory: supportObject(factory),
4500+ service: supportObject(service),
4501+ value: supportObject(value),
4502+ constant: supportObject(constant),
4503+ decorator: decorator
4504+ }
4505+ },
4506+ providerInjector = (providerCache.$injector =
4507+ createInternalInjector(providerCache, function(serviceName, caller) {
4508+ if (angular.isString(caller)) {
4509+ path.push(caller);
4510+ }
4511+ throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
4512+ })),
4513+ instanceCache = {},
4514+ protoInstanceInjector =
4515+ createInternalInjector(instanceCache, function(serviceName, caller) {
4516+ var provider = providerInjector.get(serviceName + providerSuffix, caller);
4517+ return instanceInjector.invoke(
4518+ provider.$get, provider, undefined, serviceName);
4519+ }),
4520+ instanceInjector = protoInstanceInjector;
4521+
4522+ providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
4523+ var runBlocks = loadModules(modulesToLoad);
4524+ instanceInjector = protoInstanceInjector.get('$injector');
4525+ instanceInjector.strictDi = strictDi;
4526+ forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
4527+
4528+ return instanceInjector;
4529+
4530+ ////////////////////////////////////
4531+ // $provider
4532+ ////////////////////////////////////
4533+
4534+ function supportObject(delegate) {
4535+ return function(key, value) {
4536+ if (isObject(key)) {
4537+ forEach(key, reverseParams(delegate));
4538+ } else {
4539+ return delegate(key, value);
4540+ }
4541+ };
4542+ }
4543+
4544+ function provider(name, provider_) {
4545+ assertNotHasOwnProperty(name, 'service');
4546+ if (isFunction(provider_) || isArray(provider_)) {
4547+ provider_ = providerInjector.instantiate(provider_);
4548+ }
4549+ if (!provider_.$get) {
4550+ throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
4551+ }
4552+ return providerCache[name + providerSuffix] = provider_;
4553+ }
4554+
4555+ function enforceReturnValue(name, factory) {
4556+ return function enforcedReturnValue() {
4557+ var result = instanceInjector.invoke(factory, this);
4558+ if (isUndefined(result)) {
4559+ throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
4560+ }
4561+ return result;
4562+ };
4563+ }
4564+
4565+ function factory(name, factoryFn, enforce) {
4566+ return provider(name, {
4567+ $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
4568+ });
4569+ }
4570+
4571+ function service(name, constructor) {
4572+ return factory(name, ['$injector', function($injector) {
4573+ return $injector.instantiate(constructor);
4574+ }]);
4575+ }
4576+
4577+ function value(name, val) { return factory(name, valueFn(val), false); }
4578+
4579+ function constant(name, value) {
4580+ assertNotHasOwnProperty(name, 'constant');
4581+ providerCache[name] = value;
4582+ instanceCache[name] = value;
4583+ }
4584+
4585+ function decorator(serviceName, decorFn) {
4586+ var origProvider = providerInjector.get(serviceName + providerSuffix),
4587+ orig$get = origProvider.$get;
4588+
4589+ origProvider.$get = function() {
4590+ var origInstance = instanceInjector.invoke(orig$get, origProvider);
4591+ return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
4592+ };
4593+ }
4594+
4595+ ////////////////////////////////////
4596+ // Module Loading
4597+ ////////////////////////////////////
4598+ function loadModules(modulesToLoad) {
4599+ assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
4600+ var runBlocks = [], moduleFn;
4601+ forEach(modulesToLoad, function(module) {
4602+ if (loadedModules.get(module)) return;
4603+ loadedModules.put(module, true);
4604+
4605+ function runInvokeQueue(queue) {
4606+ var i, ii;
4607+ for (i = 0, ii = queue.length; i < ii; i++) {
4608+ var invokeArgs = queue[i],
4609+ provider = providerInjector.get(invokeArgs[0]);
4610+
4611+ provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
4612+ }
4613+ }
4614+
4615+ try {
4616+ if (isString(module)) {
4617+ moduleFn = angularModule(module);
4618+ runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
4619+ runInvokeQueue(moduleFn._invokeQueue);
4620+ runInvokeQueue(moduleFn._configBlocks);
4621+ } else if (isFunction(module)) {
4622+ runBlocks.push(providerInjector.invoke(module));
4623+ } else if (isArray(module)) {
4624+ runBlocks.push(providerInjector.invoke(module));
4625+ } else {
4626+ assertArgFn(module, 'module');
4627+ }
4628+ } catch (e) {
4629+ if (isArray(module)) {
4630+ module = module[module.length - 1];
4631+ }
4632+ if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
4633+ // Safari & FF's stack traces don't contain error.message content
4634+ // unlike those of Chrome and IE
4635+ // So if stack doesn't contain message, we create a new string that contains both.
4636+ // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
4637+ /* jshint -W022 */
4638+ e = e.message + '\n' + e.stack;
4639+ }
4640+ throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}",
4641+ module, e.stack || e.message || e);
4642+ }
4643+ });
4644+ return runBlocks;
4645+ }
4646+
4647+ ////////////////////////////////////
4648+ // internal Injector
4649+ ////////////////////////////////////
4650+
4651+ function createInternalInjector(cache, factory) {
4652+
4653+ function getService(serviceName, caller) {
4654+ if (cache.hasOwnProperty(serviceName)) {
4655+ if (cache[serviceName] === INSTANTIATING) {
4656+ throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
4657+ serviceName + ' <- ' + path.join(' <- '));
4658+ }
4659+ return cache[serviceName];
4660+ } else {
4661+ try {
4662+ path.unshift(serviceName);
4663+ cache[serviceName] = INSTANTIATING;
4664+ return cache[serviceName] = factory(serviceName, caller);
4665+ } catch (err) {
4666+ if (cache[serviceName] === INSTANTIATING) {
4667+ delete cache[serviceName];
4668+ }
4669+ throw err;
4670+ } finally {
4671+ path.shift();
4672+ }
4673+ }
4674+ }
4675+
4676+
4677+ function injectionArgs(fn, locals, serviceName) {
4678+ var args = [],
4679+ $inject = createInjector.$$annotate(fn, strictDi, serviceName);
4680+
4681+ for (var i = 0, length = $inject.length; i < length; i++) {
4682+ var key = $inject[i];
4683+ if (typeof key !== 'string') {
4684+ throw $injectorMinErr('itkn',
4685+ 'Incorrect injection token! Expected service name as string, got {0}', key);
4686+ }
4687+ args.push(locals && locals.hasOwnProperty(key) ? locals[key] :
4688+ getService(key, serviceName));
4689+ }
4690+ return args;
4691+ }
4692+
4693+ function isClass(func) {
4694+ // IE 9-11 do not support classes and IE9 leaks with the code below.
4695+ if (msie <= 11) {
4696+ return false;
4697+ }
4698+ // Support: Edge 12-13 only
4699+ // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6156135/
4700+ return typeof func === 'function'
4701+ && /^(?:class\b|constructor\()/.test(stringifyFn(func));
4702+ }
4703+
4704+ function invoke(fn, self, locals, serviceName) {
4705+ if (typeof locals === 'string') {
4706+ serviceName = locals;
4707+ locals = null;
4708+ }
4709+
4710+ var args = injectionArgs(fn, locals, serviceName);
4711+ if (isArray(fn)) {
4712+ fn = fn[fn.length - 1];
4713+ }
4714+
4715+ if (!isClass(fn)) {
4716+ // http://jsperf.com/angularjs-invoke-apply-vs-switch
4717+ // #5388
4718+ return fn.apply(self, args);
4719+ } else {
4720+ args.unshift(null);
4721+ return new (Function.prototype.bind.apply(fn, args))();
4722+ }
4723+ }
4724+
4725+
4726+ function instantiate(Type, locals, serviceName) {
4727+ // Check if Type is annotated and use just the given function at n-1 as parameter
4728+ // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
4729+ var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
4730+ var args = injectionArgs(Type, locals, serviceName);
4731+ // Empty object at position 0 is ignored for invocation with `new`, but required.
4732+ args.unshift(null);
4733+ return new (Function.prototype.bind.apply(ctor, args))();
4734+ }
4735+
4736+
4737+ return {
4738+ invoke: invoke,
4739+ instantiate: instantiate,
4740+ get: getService,
4741+ annotate: createInjector.$$annotate,
4742+ has: function(name) {
4743+ return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
4744+ }
4745+ };
4746+ }
4747+}
4748+
4749+createInjector.$$annotate = annotate;
4750+
4751+/**
4752+ * @ngdoc provider
4753+ * @name $anchorScrollProvider
4754+ *
4755+ * @description
4756+ * Use `$anchorScrollProvider` to disable automatic scrolling whenever
4757+ * {@link ng.$location#hash $location.hash()} changes.
4758+ */
4759+function $AnchorScrollProvider() {
4760+
4761+ var autoScrollingEnabled = true;
4762+
4763+ /**
4764+ * @ngdoc method
4765+ * @name $anchorScrollProvider#disableAutoScrolling
4766+ *
4767+ * @description
4768+ * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
4769+ * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
4770+ * Use this method to disable automatic scrolling.
4771+ *
4772+ * If automatic scrolling is disabled, one must explicitly call
4773+ * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
4774+ * current hash.
4775+ */
4776+ this.disableAutoScrolling = function() {
4777+ autoScrollingEnabled = false;
4778+ };
4779+
4780+ /**
4781+ * @ngdoc service
4782+ * @name $anchorScroll
4783+ * @kind function
4784+ * @requires $window
4785+ * @requires $location
4786+ * @requires $rootScope
4787+ *
4788+ * @description
4789+ * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the
4790+ * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified
4791+ * in the
4792+ * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document).
4793+ *
4794+ * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
4795+ * match any anchor whenever it changes. This can be disabled by calling
4796+ * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
4797+ *
4798+ * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
4799+ * vertical scroll-offset (either fixed or dynamic).
4800+ *
4801+ * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of
4802+ * {@link ng.$location#hash $location.hash()} will be used.
4803+ *
4804+ * @property {(number|function|jqLite)} yOffset
4805+ * If set, specifies a vertical scroll-offset. This is often useful when there are fixed
4806+ * positioned elements at the top of the page, such as navbars, headers etc.
4807+ *
4808+ * `yOffset` can be specified in various ways:
4809+ * - **number**: A fixed number of pixels to be used as offset.<br /><br />
4810+ * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
4811+ * a number representing the offset (in pixels).<br /><br />
4812+ * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
4813+ * the top of the page to the element's bottom will be used as offset.<br />
4814+ * **Note**: The element will be taken into account only as long as its `position` is set to
4815+ * `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
4816+ * their height and/or positioning according to the viewport's size.
4817+ *
4818+ * <br />
4819+ * <div class="alert alert-warning">
4820+ * In order for `yOffset` to work properly, scrolling should take place on the document's root and
4821+ * not some child element.
4822+ * </div>
4823+ *
4824+ * @example
4825+ <example module="anchorScrollExample">
4826+ <file name="index.html">
4827+ <div id="scrollArea" ng-controller="ScrollController">
4828+ <a ng-click="gotoBottom()">Go to bottom</a>
4829+ <a id="bottom"></a> You're at the bottom!
4830+ </div>
4831+ </file>
4832+ <file name="script.js">
4833+ angular.module('anchorScrollExample', [])
4834+ .controller('ScrollController', ['$scope', '$location', '$anchorScroll',
4835+ function ($scope, $location, $anchorScroll) {
4836+ $scope.gotoBottom = function() {
4837+ // set the location.hash to the id of
4838+ // the element you wish to scroll to.
4839+ $location.hash('bottom');
4840+
4841+ // call $anchorScroll()
4842+ $anchorScroll();
4843+ };
4844+ }]);
4845+ </file>
4846+ <file name="style.css">
4847+ #scrollArea {
4848+ height: 280px;
4849+ overflow: auto;
4850+ }
4851+
4852+ #bottom {
4853+ display: block;
4854+ margin-top: 2000px;
4855+ }
4856+ </file>
4857+ </example>
4858+ *
4859+ * <hr />
4860+ * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).
4861+ * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.
4862+ *
4863+ * @example
4864+ <example module="anchorScrollOffsetExample">
4865+ <file name="index.html">
4866+ <div class="fixed-header" ng-controller="headerCtrl">
4867+ <a href="" ng-click="gotoAnchor(x)" ng-repeat="x in [1,2,3,4,5]">
4868+ Go to anchor {{x}}
4869+ </a>
4870+ </div>
4871+ <div id="anchor{{x}}" class="anchor" ng-repeat="x in [1,2,3,4,5]">
4872+ Anchor {{x}} of 5
4873+ </div>
4874+ </file>
4875+ <file name="script.js">
4876+ angular.module('anchorScrollOffsetExample', [])
4877+ .run(['$anchorScroll', function($anchorScroll) {
4878+ $anchorScroll.yOffset = 50; // always scroll by 50 extra pixels
4879+ }])
4880+ .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
4881+ function ($anchorScroll, $location, $scope) {
4882+ $scope.gotoAnchor = function(x) {
4883+ var newHash = 'anchor' + x;
4884+ if ($location.hash() !== newHash) {
4885+ // set the $location.hash to `newHash` and
4886+ // $anchorScroll will automatically scroll to it
4887+ $location.hash('anchor' + x);
4888+ } else {
4889+ // call $anchorScroll() explicitly,
4890+ // since $location.hash hasn't changed
4891+ $anchorScroll();
4892+ }
4893+ };
4894+ }
4895+ ]);
4896+ </file>
4897+ <file name="style.css">
4898+ body {
4899+ padding-top: 50px;
4900+ }
4901+
4902+ .anchor {
4903+ border: 2px dashed DarkOrchid;
4904+ padding: 10px 10px 200px 10px;
4905+ }
4906+
4907+ .fixed-header {
4908+ background-color: rgba(0, 0, 0, 0.2);
4909+ height: 50px;
4910+ position: fixed;
4911+ top: 0; left: 0; right: 0;
4912+ }
4913+
4914+ .fixed-header > a {
4915+ display: inline-block;
4916+ margin: 5px 15px;
4917+ }
4918+ </file>
4919+ </example>
4920+ */
4921+ this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
4922+ var document = $window.document;
4923+
4924+ // Helper function to get first anchor from a NodeList
4925+ // (using `Array#some()` instead of `angular#forEach()` since it's more performant
4926+ // and working in all supported browsers.)
4927+ function getFirstAnchor(list) {
4928+ var result = null;
4929+ Array.prototype.some.call(list, function(element) {
4930+ if (nodeName_(element) === 'a') {
4931+ result = element;
4932+ return true;
4933+ }
4934+ });
4935+ return result;
4936+ }
4937+
4938+ function getYOffset() {
4939+
4940+ var offset = scroll.yOffset;
4941+
4942+ if (isFunction(offset)) {
4943+ offset = offset();
4944+ } else if (isElement(offset)) {
4945+ var elem = offset[0];
4946+ var style = $window.getComputedStyle(elem);
4947+ if (style.position !== 'fixed') {
4948+ offset = 0;
4949+ } else {
4950+ offset = elem.getBoundingClientRect().bottom;
4951+ }
4952+ } else if (!isNumber(offset)) {
4953+ offset = 0;
4954+ }
4955+
4956+ return offset;
4957+ }
4958+
4959+ function scrollTo(elem) {
4960+ if (elem) {
4961+ elem.scrollIntoView();
4962+
4963+ var offset = getYOffset();
4964+
4965+ if (offset) {
4966+ // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
4967+ // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
4968+ // top of the viewport.
4969+ //
4970+ // IF the number of pixels from the top of `elem` to the end of the page's content is less
4971+ // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
4972+ // way down the page.
4973+ //
4974+ // This is often the case for elements near the bottom of the page.
4975+ //
4976+ // In such cases we do not need to scroll the whole `offset` up, just the difference between
4977+ // the top of the element and the offset, which is enough to align the top of `elem` at the
4978+ // desired position.
4979+ var elemTop = elem.getBoundingClientRect().top;
4980+ $window.scrollBy(0, elemTop - offset);
4981+ }
4982+ } else {
4983+ $window.scrollTo(0, 0);
4984+ }
4985+ }
4986+
4987+ function scroll(hash) {
4988+ hash = isString(hash) ? hash : $location.hash();
4989+ var elm;
4990+
4991+ // empty hash, scroll to the top of the page
4992+ if (!hash) scrollTo(null);
4993+
4994+ // element with given id
4995+ else if ((elm = document.getElementById(hash))) scrollTo(elm);
4996+
4997+ // first anchor with given name :-D
4998+ else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
4999+

26769 more lines aren’t shown here.

Source/Libraries/GSF.Web/Shared/Scripts/gsf.web.client.js+5−5
@@ -786,25 +786,25 @@ $.fn.disable = function() { · 785 unmodified lines
786786
787787 $.fn.visible = function() {
788788 return this.each(function() {
789− this.css("visibility", "visible");
789+ $(this).css("visibility", "visible");
790790 });
791791 }
792792
793793 $.fn.invisible = function() {
794794 return this.each(function() {
795− this.css("visibility", "hidden");
795+ $(this).css("visibility", "hidden");
796796 });
797797 }
798798
799799 $.fn.readCookie = function(name) {
800− this.val(Cookies.get(name));
800+ $(this).val(Cookies.get(name));
801801 }
802802
803803 $.fn.writeCookie = function(name, expiration) {
804804 if (expiration) // Date or number of days
805− Cookies.set(name, this.val(), { expires: expiration });
805+ Cookies.set(name, $(this).val(), { expires: expiration });
806806 else
807− Cookies.set(name, this.val());
807+ Cookies.set(name, $(this).val());
808808 }
809809
810810 $.fn.removeCookie = function(name) {
Source/Libraries/GSF.Web/Shared/Scripts/jquery-ui.js+16617−0
@@ -0,0 +1,16617 @@
1+/*! jQuery UI - v1.11.4 - 2016-03-31
2+* http://jqueryui.com
3+* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4+* Copyright jQuery Foundation and other contributors; Licensed MIT */
5+
6+(function( factory ) {
7+ if ( typeof define === "function" && define.amd ) {
8+
9+ // AMD. Register as an anonymous module.
10+ define([ "jquery" ], factory );
11+ } else {
12+
13+ // Browser globals
14+ factory( jQuery );
15+ }
16+}(function( $ ) {
17+/*!
18+ * jQuery UI Core 1.11.4
19+ * http://jqueryui.com
20+ *
21+ * Copyright jQuery Foundation and other contributors
22+ * Released under the MIT license.
23+ * http://jquery.org/license
24+ *
25+ * http://api.jqueryui.com/category/ui-core/
26+ */
27+
28+
29+// $.ui might exist from components with no dependencies, e.g., $.ui.position
30+$.ui = $.ui || {};
31+
32+$.extend( $.ui, {
33+ version: "1.11.4",
34+
35+ keyCode: {
36+ BACKSPACE: 8,
37+ COMMA: 188,
38+ DELETE: 46,
39+ DOWN: 40,
40+ END: 35,
41+ ENTER: 13,
42+ ESCAPE: 27,
43+ HOME: 36,
44+ LEFT: 37,
45+ PAGE_DOWN: 34,
46+ PAGE_UP: 33,
47+ PERIOD: 190,
48+ RIGHT: 39,
49+ SPACE: 32,
50+ TAB: 9,
51+ UP: 38
52+ }
53+});
54+
55+// plugins
56+$.fn.extend({
57+ scrollParent: function( includeHidden ) {
58+ var position = this.css( "position" ),
59+ excludeStaticParent = position === "absolute",
60+ overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61+ scrollParent = this.parents().filter( function() {
62+ var parent = $( this );
63+ if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64+ return false;
65+ }
66+ return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67+ }).eq( 0 );
68+
69+ return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70+ },
71+
72+ uniqueId: (function() {
73+ var uuid = 0;
74+
75+ return function() {
76+ return this.each(function() {
77+ if ( !this.id ) {
78+ this.id = "ui-id-" + ( ++uuid );
79+ }
80+ });
81+ };
82+ })(),
83+
84+ removeUniqueId: function() {
85+ return this.each(function() {
86+ if ( /^ui-id-\d+$/.test( this.id ) ) {
87+ $( this ).removeAttr( "id" );
88+ }
89+ });
90+ }
91+});
92+
93+// selectors
94+function focusable( element, isTabIndexNotNaN ) {
95+ var map, mapName, img,
96+ nodeName = element.nodeName.toLowerCase();
97+ if ( "area" === nodeName ) {
98+ map = element.parentNode;
99+ mapName = map.name;
100+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101+ return false;
102+ }
103+ img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104+ return !!img && visible( img );
105+ }
106+ return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107+ !element.disabled :
108+ "a" === nodeName ?
109+ element.href || isTabIndexNotNaN :
110+ isTabIndexNotNaN) &&
111+ // the element and all of its ancestors must be visible
112+ visible( element );
113+}
114+
115+function visible( element ) {
116+ return $.expr.filters.visible( element ) &&
117+ !$( element ).parents().addBack().filter(function() {
118+ return $.css( this, "visibility" ) === "hidden";
119+ }).length;
120+}
121+
122+$.extend( $.expr[ ":" ], {
123+ data: $.expr.createPseudo ?
124+ $.expr.createPseudo(function( dataName ) {
125+ return function( elem ) {
126+ return !!$.data( elem, dataName );
127+ };
128+ }) :
129+ // support: jQuery <1.8
130+ function( elem, i, match ) {
131+ return !!$.data( elem, match[ 3 ] );
132+ },
133+
134+ focusable: function( element ) {
135+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136+ },
137+
138+ tabbable: function( element ) {
139+ var tabIndex = $.attr( element, "tabindex" ),
140+ isTabIndexNaN = isNaN( tabIndex );
141+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142+ }
143+});
144+
145+// support: jQuery <1.8
146+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147+ $.each( [ "Width", "Height" ], function( i, name ) {
148+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149+ type = name.toLowerCase(),
150+ orig = {
151+ innerWidth: $.fn.innerWidth,
152+ innerHeight: $.fn.innerHeight,
153+ outerWidth: $.fn.outerWidth,
154+ outerHeight: $.fn.outerHeight
155+ };
156+
157+ function reduce( elem, size, border, margin ) {
158+ $.each( side, function() {
159+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160+ if ( border ) {
161+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162+ }
163+ if ( margin ) {
164+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165+ }
166+ });
167+ return size;
168+ }
169+
170+ $.fn[ "inner" + name ] = function( size ) {
171+ if ( size === undefined ) {
172+ return orig[ "inner" + name ].call( this );
173+ }
174+
175+ return this.each(function() {
176+ $( this ).css( type, reduce( this, size ) + "px" );
177+ });
178+ };
179+
180+ $.fn[ "outer" + name] = function( size, margin ) {
181+ if ( typeof size !== "number" ) {
182+ return orig[ "outer" + name ].call( this, size );
183+ }
184+
185+ return this.each(function() {
186+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
187+ });
188+ };
189+ });
190+}
191+
192+// support: jQuery <1.8
193+if ( !$.fn.addBack ) {
194+ $.fn.addBack = function( selector ) {
195+ return this.add( selector == null ?
196+ this.prevObject : this.prevObject.filter( selector )
197+ );
198+ };
199+}
200+
201+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203+ $.fn.removeData = (function( removeData ) {
204+ return function( key ) {
205+ if ( arguments.length ) {
206+ return removeData.call( this, $.camelCase( key ) );
207+ } else {
208+ return removeData.call( this );
209+ }
210+ };
211+ })( $.fn.removeData );
212+}
213+
214+// deprecated
215+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216+
217+$.fn.extend({
218+ focus: (function( orig ) {
219+ return function( delay, fn ) {
220+ return typeof delay === "number" ?
221+ this.each(function() {
222+ var elem = this;
223+ setTimeout(function() {
224+ $( elem ).focus();
225+ if ( fn ) {
226+ fn.call( elem );
227+ }
228+ }, delay );
229+ }) :
230+ orig.apply( this, arguments );
231+ };
232+ })( $.fn.focus ),
233+
234+ disableSelection: (function() {
235+ var eventType = "onselectstart" in document.createElement( "div" ) ?
236+ "selectstart" :
237+ "mousedown";
238+
239+ return function() {
240+ return this.bind( eventType + ".ui-disableSelection", function( event ) {
241+ event.preventDefault();
242+ });
243+ };
244+ })(),
245+
246+ enableSelection: function() {
247+ return this.unbind( ".ui-disableSelection" );
248+ },
249+
250+ zIndex: function( zIndex ) {
251+ if ( zIndex !== undefined ) {
252+ return this.css( "zIndex", zIndex );
253+ }
254+
255+ if ( this.length ) {
256+ var elem = $( this[ 0 ] ), position, value;
257+ while ( elem.length && elem[ 0 ] !== document ) {
258+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
259+ // This makes behavior of this function consistent across browsers
260+ // WebKit always returns auto if the element is positioned
261+ position = elem.css( "position" );
262+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263+ // IE returns 0 when zIndex is not specified
264+ // other browsers return a string
265+ // we ignore the case of nested elements with an explicit value of 0
266+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267+ value = parseInt( elem.css( "zIndex" ), 10 );
268+ if ( !isNaN( value ) && value !== 0 ) {
269+ return value;
270+ }
271+ }
272+ elem = elem.parent();
273+ }
274+ }
275+
276+ return 0;
277+ }
278+});
279+
280+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
281+$.ui.plugin = {
282+ add: function( module, option, set ) {
283+ var i,
284+ proto = $.ui[ module ].prototype;
285+ for ( i in set ) {
286+ proto.plugins[ i ] = proto.plugins[ i ] || [];
287+ proto.plugins[ i ].push( [ option, set[ i ] ] );
288+ }
289+ },
290+ call: function( instance, name, args, allowDisconnected ) {
291+ var i,
292+ set = instance.plugins[ name ];
293+
294+ if ( !set ) {
295+ return;
296+ }
297+
298+ if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299+ return;
300+ }
301+
302+ for ( i = 0; i < set.length; i++ ) {
303+ if ( instance.options[ set[ i ][ 0 ] ] ) {
304+ set[ i ][ 1 ].apply( instance.element, args );
305+ }
306+ }
307+ }
308+};
309+
310+
311+/*!
312+ * jQuery UI Widget 1.11.4
313+ * http://jqueryui.com
314+ *
315+ * Copyright jQuery Foundation and other contributors
316+ * Released under the MIT license.
317+ * http://jquery.org/license
318+ *
319+ * http://api.jqueryui.com/jQuery.widget/
320+ */
321+
322+
323+var widget_uuid = 0,
324+ widget_slice = Array.prototype.slice;
325+
326+$.cleanData = (function( orig ) {
327+ return function( elems ) {
328+ var events, elem, i;
329+ for ( i = 0; (elem = elems[i]) != null; i++ ) {
330+ try {
331+
332+ // Only trigger remove when necessary to save time
333+ events = $._data( elem, "events" );
334+ if ( events && events.remove ) {
335+ $( elem ).triggerHandler( "remove" );
336+ }
337+
338+ // http://bugs.jquery.com/ticket/8235
339+ } catch ( e ) {}
340+ }
341+ orig( elems );
342+ };
343+})( $.cleanData );
344+
345+$.widget = function( name, base, prototype ) {
346+ var fullName, existingConstructor, constructor, basePrototype,
347+ // proxiedPrototype allows the provided prototype to remain unmodified
348+ // so that it can be used as a mixin for multiple widgets (#8876)
349+ proxiedPrototype = {},
350+ namespace = name.split( "." )[ 0 ];
351+
352+ name = name.split( "." )[ 1 ];
353+ fullName = namespace + "-" + name;
354+
355+ if ( !prototype ) {
356+ prototype = base;
357+ base = $.Widget;
358+ }
359+
360+ // create selector for plugin
361+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362+ return !!$.data( elem, fullName );
363+ };
364+
365+ $[ namespace ] = $[ namespace ] || {};
366+ existingConstructor = $[ namespace ][ name ];
367+ constructor = $[ namespace ][ name ] = function( options, element ) {
368+ // allow instantiation without "new" keyword
369+ if ( !this._createWidget ) {
370+ return new constructor( options, element );
371+ }
372+
373+ // allow instantiation without initializing for simple inheritance
374+ // must use "new" keyword (the code above always passes args)
375+ if ( arguments.length ) {
376+ this._createWidget( options, element );
377+ }
378+ };
379+ // extend with the existing constructor to carry over any static properties
380+ $.extend( constructor, existingConstructor, {
381+ version: prototype.version,
382+ // copy the object used to create the prototype in case we need to
383+ // redefine the widget later
384+ _proto: $.extend( {}, prototype ),
385+ // track widgets that inherit from this widget in case this widget is
386+ // redefined after a widget inherits from it
387+ _childConstructors: []
388+ });
389+
390+ basePrototype = new base();
391+ // we need to make the options hash a property directly on the new instance
392+ // otherwise we'll modify the options hash on the prototype that we're
393+ // inheriting from
394+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
395+ $.each( prototype, function( prop, value ) {
396+ if ( !$.isFunction( value ) ) {
397+ proxiedPrototype[ prop ] = value;
398+ return;
399+ }
400+ proxiedPrototype[ prop ] = (function() {
401+ var _super = function() {
402+ return base.prototype[ prop ].apply( this, arguments );
403+ },
404+ _superApply = function( args ) {
405+ return base.prototype[ prop ].apply( this, args );
406+ };
407+ return function() {
408+ var __super = this._super,
409+ __superApply = this._superApply,
410+ returnValue;
411+
412+ this._super = _super;
413+ this._superApply = _superApply;
414+
415+ returnValue = value.apply( this, arguments );
416+
417+ this._super = __super;
418+ this._superApply = __superApply;
419+
420+ return returnValue;
421+ };
422+ })();
423+ });
424+ constructor.prototype = $.widget.extend( basePrototype, {
425+ // TODO: remove support for widgetEventPrefix
426+ // always use the name + a colon as the prefix, e.g., draggable:start
427+ // don't prefix for widgets that aren't DOM-based
428+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429+ }, proxiedPrototype, {
430+ constructor: constructor,
431+ namespace: namespace,
432+ widgetName: name,
433+ widgetFullName: fullName
434+ });
435+
436+ // If this widget is being redefined then we need to find all widgets that
437+ // are inheriting from it and redefine all of them so that they inherit from
438+ // the new version of this widget. We're essentially trying to replace one
439+ // level in the prototype chain.
440+ if ( existingConstructor ) {
441+ $.each( existingConstructor._childConstructors, function( i, child ) {
442+ var childPrototype = child.prototype;
443+
444+ // redefine the child widget using the same prototype that was
445+ // originally used, but inherit from the new version of the base
446+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447+ });
448+ // remove the list of existing child constructors from the old constructor
449+ // so the old child constructors can be garbage collected
450+ delete existingConstructor._childConstructors;
451+ } else {
452+ base._childConstructors.push( constructor );
453+ }
454+
455+ $.widget.bridge( name, constructor );
456+
457+ return constructor;
458+};
459+
460+$.widget.extend = function( target ) {
461+ var input = widget_slice.call( arguments, 1 ),
462+ inputIndex = 0,
463+ inputLength = input.length,
464+ key,
465+ value;
466+ for ( ; inputIndex < inputLength; inputIndex++ ) {
467+ for ( key in input[ inputIndex ] ) {
468+ value = input[ inputIndex ][ key ];
469+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470+ // Clone objects
471+ if ( $.isPlainObject( value ) ) {
472+ target[ key ] = $.isPlainObject( target[ key ] ) ?
473+ $.widget.extend( {}, target[ key ], value ) :
474+ // Don't extend strings, arrays, etc. with objects
475+ $.widget.extend( {}, value );
476+ // Copy everything else by reference
477+ } else {
478+ target[ key ] = value;
479+ }
480+ }
481+ }
482+ }
483+ return target;
484+};
485+
486+$.widget.bridge = function( name, object ) {
487+ var fullName = object.prototype.widgetFullName || name;
488+ $.fn[ name ] = function( options ) {
489+ var isMethodCall = typeof options === "string",
490+ args = widget_slice.call( arguments, 1 ),
491+ returnValue = this;
492+
493+ if ( isMethodCall ) {
494+ this.each(function() {
495+ var methodValue,
496+ instance = $.data( this, fullName );
497+ if ( options === "instance" ) {
498+ returnValue = instance;
499+ return false;
500+ }
501+ if ( !instance ) {
502+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
503+ "attempted to call method '" + options + "'" );
504+ }
505+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507+ }
508+ methodValue = instance[ options ].apply( instance, args );
509+ if ( methodValue !== instance && methodValue !== undefined ) {
510+ returnValue = methodValue && methodValue.jquery ?
511+ returnValue.pushStack( methodValue.get() ) :
512+ methodValue;
513+ return false;
514+ }
515+ });
516+ } else {
517+
518+ // Allow multiple hashes to be passed on init
519+ if ( args.length ) {
520+ options = $.widget.extend.apply( null, [ options ].concat(args) );
521+ }
522+
523+ this.each(function() {
524+ var instance = $.data( this, fullName );
525+ if ( instance ) {
526+ instance.option( options || {} );
527+ if ( instance._init ) {
528+ instance._init();
529+ }
530+ } else {
531+ $.data( this, fullName, new object( options, this ) );
532+ }
533+ });
534+ }
535+
536+ return returnValue;
537+ };
538+};
539+
540+$.Widget = function( /* options, element */ ) {};
541+$.Widget._childConstructors = [];
542+
543+$.Widget.prototype = {
544+ widgetName: "widget",
545+ widgetEventPrefix: "",
546+ defaultElement: "<div>",
547+ options: {
548+ disabled: false,
549+
550+ // callbacks
551+ create: null
552+ },
553+ _createWidget: function( options, element ) {
554+ element = $( element || this.defaultElement || this )[ 0 ];
555+ this.element = $( element );
556+ this.uuid = widget_uuid++;
557+ this.eventNamespace = "." + this.widgetName + this.uuid;
558+
559+ this.bindings = $();
560+ this.hoverable = $();
561+ this.focusable = $();
562+
563+ if ( element !== this ) {
564+ $.data( element, this.widgetFullName, this );
565+ this._on( true, this.element, {
566+ remove: function( event ) {
567+ if ( event.target === element ) {
568+ this.destroy();
569+ }
570+ }
571+ });
572+ this.document = $( element.style ?
573+ // element within the document
574+ element.ownerDocument :
575+ // element is window or document
576+ element.document || element );
577+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578+ }
579+
580+ this.options = $.widget.extend( {},
581+ this.options,
582+ this._getCreateOptions(),
583+ options );
584+
585+ this._create();
586+ this._trigger( "create", null, this._getCreateEventData() );
587+ this._init();
588+ },
589+ _getCreateOptions: $.noop,
590+ _getCreateEventData: $.noop,
591+ _create: $.noop,
592+ _init: $.noop,
593+
594+ destroy: function() {
595+ this._destroy();
596+ // we can probably remove the unbind calls in 2.0
597+ // all event bindings should go through this._on()
598+ this.element
599+ .unbind( this.eventNamespace )
600+ .removeData( this.widgetFullName )
601+ // support: jquery <1.6.3
602+ // http://bugs.jquery.com/ticket/9413
603+ .removeData( $.camelCase( this.widgetFullName ) );
604+ this.widget()
605+ .unbind( this.eventNamespace )
606+ .removeAttr( "aria-disabled" )
607+ .removeClass(
608+ this.widgetFullName + "-disabled " +
609+ "ui-state-disabled" );
610+
611+ // clean up events and states
612+ this.bindings.unbind( this.eventNamespace );
613+ this.hoverable.removeClass( "ui-state-hover" );
614+ this.focusable.removeClass( "ui-state-focus" );
615+ },
616+ _destroy: $.noop,
617+
618+ widget: function() {
619+ return this.element;
620+ },
621+
622+ option: function( key, value ) {
623+ var options = key,
624+ parts,
625+ curOption,
626+ i;
627+
628+ if ( arguments.length === 0 ) {
629+ // don't return a reference to the internal hash
630+ return $.widget.extend( {}, this.options );
631+ }
632+
633+ if ( typeof key === "string" ) {
634+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635+ options = {};
636+ parts = key.split( "." );
637+ key = parts.shift();
638+ if ( parts.length ) {
639+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640+ for ( i = 0; i < parts.length - 1; i++ ) {
641+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642+ curOption = curOption[ parts[ i ] ];
643+ }
644+ key = parts.pop();
645+ if ( arguments.length === 1 ) {
646+ return curOption[ key ] === undefined ? null : curOption[ key ];
647+ }
648+ curOption[ key ] = value;
649+ } else {
650+ if ( arguments.length === 1 ) {
651+ return this.options[ key ] === undefined ? null : this.options[ key ];
652+ }
653+ options[ key ] = value;
654+ }
655+ }
656+
657+ this._setOptions( options );
658+
659+ return this;
660+ },
661+ _setOptions: function( options ) {
662+ var key;
663+
664+ for ( key in options ) {
665+ this._setOption( key, options[ key ] );
666+ }
667+
668+ return this;
669+ },
670+ _setOption: function( key, value ) {
671+ this.options[ key ] = value;
672+
673+ if ( key === "disabled" ) {
674+ this.widget()
675+ .toggleClass( this.widgetFullName + "-disabled", !!value );
676+
677+ // If the widget is becoming disabled, then nothing is interactive
678+ if ( value ) {
679+ this.hoverable.removeClass( "ui-state-hover" );
680+ this.focusable.removeClass( "ui-state-focus" );
681+ }
682+ }
683+
684+ return this;
685+ },
686+
687+ enable: function() {
688+ return this._setOptions({ disabled: false });
689+ },
690+ disable: function() {
691+ return this._setOptions({ disabled: true });
692+ },
693+
694+ _on: function( suppressDisabledCheck, element, handlers ) {
695+ var delegateElement,
696+ instance = this;
697+
698+ // no suppressDisabledCheck flag, shuffle arguments
699+ if ( typeof suppressDisabledCheck !== "boolean" ) {
700+ handlers = element;
701+ element = suppressDisabledCheck;
702+ suppressDisabledCheck = false;
703+ }
704+
705+ // no element argument, shuffle and use this.element
706+ if ( !handlers ) {
707+ handlers = element;
708+ element = this.element;
709+ delegateElement = this.widget();
710+ } else {
711+ element = delegateElement = $( element );
712+ this.bindings = this.bindings.add( element );
713+ }
714+
715+ $.each( handlers, function( event, handler ) {
716+ function handlerProxy() {
717+ // allow widgets to customize the disabled handling
718+ // - disabled as an array instead of boolean
719+ // - disabled class as method for disabling individual parts
720+ if ( !suppressDisabledCheck &&
721+ ( instance.options.disabled === true ||
722+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
723+ return;
724+ }
725+ return ( typeof handler === "string" ? instance[ handler ] : handler )
726+ .apply( instance, arguments );
727+ }
728+
729+ // copy the guid so direct unbinding works
730+ if ( typeof handler !== "string" ) {
731+ handlerProxy.guid = handler.guid =
732+ handler.guid || handlerProxy.guid || $.guid++;
733+ }
734+
735+ var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736+ eventName = match[1] + instance.eventNamespace,
737+ selector = match[2];
738+ if ( selector ) {
739+ delegateElement.delegate( selector, eventName, handlerProxy );
740+ } else {
741+ element.bind( eventName, handlerProxy );
742+ }
743+ });
744+ },
745+
746+ _off: function( element, eventName ) {
747+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748+ this.eventNamespace;
749+ element.unbind( eventName ).undelegate( eventName );
750+
751+ // Clear the stack to avoid memory leaks (#10056)
752+ this.bindings = $( this.bindings.not( element ).get() );
753+ this.focusable = $( this.focusable.not( element ).get() );
754+ this.hoverable = $( this.hoverable.not( element ).get() );
755+ },
756+
757+ _delay: function( handler, delay ) {
758+ function handlerProxy() {
759+ return ( typeof handler === "string" ? instance[ handler ] : handler )
760+ .apply( instance, arguments );
761+ }
762+ var instance = this;
763+ return setTimeout( handlerProxy, delay || 0 );
764+ },
765+
766+ _hoverable: function( element ) {
767+ this.hoverable = this.hoverable.add( element );
768+ this._on( element, {
769+ mouseenter: function( event ) {
770+ $( event.currentTarget ).addClass( "ui-state-hover" );
771+ },
772+ mouseleave: function( event ) {
773+ $( event.currentTarget ).removeClass( "ui-state-hover" );
774+ }
775+ });
776+ },
777+
778+ _focusable: function( element ) {
779+ this.focusable = this.focusable.add( element );
780+ this._on( element, {
781+ focusin: function( event ) {
782+ $( event.currentTarget ).addClass( "ui-state-focus" );
783+ },
784+ focusout: function( event ) {
785+ $( event.currentTarget ).removeClass( "ui-state-focus" );
786+ }
787+ });
788+ },
789+
790+ _trigger: function( type, event, data ) {
791+ var prop, orig,
792+ callback = this.options[ type ];
793+
794+ data = data || {};
795+ event = $.Event( event );
796+ event.type = ( type === this.widgetEventPrefix ?
797+ type :
798+ this.widgetEventPrefix + type ).toLowerCase();
799+ // the original event may come from any element
800+ // so we need to reset the target on the new event
801+ event.target = this.element[ 0 ];
802+
803+ // copy original event properties over to the new event
804+ orig = event.originalEvent;
805+ if ( orig ) {
806+ for ( prop in orig ) {
807+ if ( !( prop in event ) ) {
808+ event[ prop ] = orig[ prop ];
809+ }
810+ }
811+ }
812+
813+ this.element.trigger( event, data );
814+ return !( $.isFunction( callback ) &&
815+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816+ event.isDefaultPrevented() );
817+ }
818+};
819+
820+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822+ if ( typeof options === "string" ) {
823+ options = { effect: options };
824+ }
825+ var hasOptions,
826+ effectName = !options ?
827+ method :
828+ options === true || typeof options === "number" ?
829+ defaultEffect :
830+ options.effect || defaultEffect;
831+ options = options || {};
832+ if ( typeof options === "number" ) {
833+ options = { duration: options };
834+ }
835+ hasOptions = !$.isEmptyObject( options );
836+ options.complete = callback;
837+ if ( options.delay ) {
838+ element.delay( options.delay );
839+ }
840+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841+ element[ method ]( options );
842+ } else if ( effectName !== method && element[ effectName ] ) {
843+ element[ effectName ]( options.duration, options.easing, callback );
844+ } else {
845+ element.queue(function( next ) {
846+ $( this )[ method ]();
847+ if ( callback ) {
848+ callback.call( element[ 0 ] );
849+ }
850+ next();
851+ });
852+ }
853+ };
854+});
855+
856+var widget = $.widget;
857+
858+
859+/*!
860+ * jQuery UI Mouse 1.11.4
861+ * http://jqueryui.com
862+ *
863+ * Copyright jQuery Foundation and other contributors
864+ * Released under the MIT license.
865+ * http://jquery.org/license
866+ *
867+ * http://api.jqueryui.com/mouse/
868+ */
869+
870+
871+var mouseHandled = false;
872+$( document ).mouseup( function() {
873+ mouseHandled = false;
874+});
875+
876+var mouse = $.widget("ui.mouse", {
877+ version: "1.11.4",
878+ options: {
879+ cancel: "input,textarea,button,select,option",
880+ distance: 1,
881+ delay: 0
882+ },
883+ _mouseInit: function() {
884+ var that = this;
885+
886+ this.element
887+ .bind("mousedown." + this.widgetName, function(event) {
888+ return that._mouseDown(event);
889+ })
890+ .bind("click." + this.widgetName, function(event) {
891+ if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892+ $.removeData(event.target, that.widgetName + ".preventClickEvent");
893+ event.stopImmediatePropagation();
894+ return false;
895+ }
896+ });
897+
898+ this.started = false;
899+ },
900+
901+ // TODO: make sure destroying one instance of mouse doesn't mess with
902+ // other instances of mouse
903+ _mouseDestroy: function() {
904+ this.element.unbind("." + this.widgetName);
905+ if ( this._mouseMoveDelegate ) {
906+ this.document
907+ .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908+ .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909+ }
910+ },
911+
912+ _mouseDown: function(event) {
913+ // don't let more than one widget handle mouseStart
914+ if ( mouseHandled ) {
915+ return;
916+ }
917+
918+ this._mouseMoved = false;
919+
920+ // we may have missed mouseup (out of window)
921+ (this._mouseStarted && this._mouseUp(event));
922+
923+ this._mouseDownEvent = event;
924+
925+ var that = this,
926+ btnIsLeft = (event.which === 1),
927+ // event.target.nodeName works around a bug in IE 8 with
928+ // disabled inputs (#7620)
929+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931+ return true;
932+ }
933+
934+ this.mouseDelayMet = !this.options.delay;
935+ if (!this.mouseDelayMet) {
936+ this._mouseDelayTimer = setTimeout(function() {
937+ that.mouseDelayMet = true;
938+ }, this.options.delay);
939+ }
940+
941+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942+ this._mouseStarted = (this._mouseStart(event) !== false);
943+ if (!this._mouseStarted) {
944+ event.preventDefault();
945+ return true;
946+ }
947+ }
948+
949+ // Click event may never have fired (Gecko & Opera)
950+ if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951+ $.removeData(event.target, this.widgetName + ".preventClickEvent");
952+ }
953+
954+ // these delegates are required to keep context
955+ this._mouseMoveDelegate = function(event) {
956+ return that._mouseMove(event);
957+ };
958+ this._mouseUpDelegate = function(event) {
959+ return that._mouseUp(event);
960+ };
961+
962+ this.document
963+ .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964+ .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965+
966+ event.preventDefault();
967+
968+ mouseHandled = true;
969+ return true;
970+ },
971+
972+ _mouseMove: function(event) {
973+ // Only check for mouseups outside the document if you've moved inside the document
974+ // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975+ // fire a mousemove event if content is placed under the cursor. See #7778
976+ // Support: IE <9
977+ if ( this._mouseMoved ) {
978+ // IE mouseup check - mouseup happened when mouse was out of window
979+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980+ return this._mouseUp(event);
981+
982+ // Iframe mouseup check - mouseup occurred in another document
983+ } else if ( !event.which ) {
984+ return this._mouseUp( event );
985+ }
986+ }
987+
988+ if ( event.which || event.button ) {
989+ this._mouseMoved = true;
990+ }
991+
992+ if (this._mouseStarted) {
993+ this._mouseDrag(event);
994+ return event.preventDefault();
995+ }
996+
997+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998+ this._mouseStarted =
999+ (this._mouseStart(this._mouseDownEvent, event) !== false);
1000+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001+ }
1002+
1003+ return !this._mouseStarted;
1004+ },
1005+
1006+ _mouseUp: function(event) {
1007+ this.document
1008+ .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009+ .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010+
1011+ if (this._mouseStarted) {
1012+ this._mouseStarted = false;
1013+
1014+ if (event.target === this._mouseDownEvent.target) {
1015+ $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016+ }
1017+
1018+ this._mouseStop(event);
1019+ }
1020+
1021+ mouseHandled = false;
1022+ return false;
1023+ },
1024+
1025+ _mouseDistanceMet: function(event) {
1026+ return (Math.max(
1027+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029+ ) >= this.options.distance
1030+ );
1031+ },
1032+
1033+ _mouseDelayMet: function(/* event */) {
1034+ return this.mouseDelayMet;
1035+ },
1036+
1037+ // These are placeholder methods, to be overriden by extending plugin
1038+ _mouseStart: function(/* event */) {},
1039+ _mouseDrag: function(/* event */) {},
1040+ _mouseStop: function(/* event */) {},
1041+ _mouseCapture: function(/* event */) { return true; }
1042+});
1043+
1044+
1045+/*!
1046+ * jQuery UI Position 1.11.4
1047+ * http://jqueryui.com
1048+ *
1049+ * Copyright jQuery Foundation and other contributors
1050+ * Released under the MIT license.
1051+ * http://jquery.org/license
1052+ *
1053+ * http://api.jqueryui.com/position/
1054+ */
1055+
1056+(function() {
1057+
1058+$.ui = $.ui || {};
1059+
1060+var cachedScrollbarWidth, supportsOffsetFractions,
1061+ max = Math.max,
1062+ abs = Math.abs,
1063+ round = Math.round,
1064+ rhorizontal = /left|center|right/,
1065+ rvertical = /top|center|bottom/,
1066+ roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067+ rposition = /^\w+/,
1068+ rpercent = /%$/,
1069+ _position = $.fn.position;
1070+
1071+function getOffsets( offsets, width, height ) {
1072+ return [
1073+ parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074+ parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075+ ];
1076+}
1077+
1078+function parseCss( element, property ) {
1079+ return parseInt( $.css( element, property ), 10 ) || 0;
1080+}
1081+
1082+function getDimensions( elem ) {
1083+ var raw = elem[0];
1084+ if ( raw.nodeType === 9 ) {
1085+ return {
1086+ width: elem.width(),
1087+ height: elem.height(),
1088+ offset: { top: 0, left: 0 }
1089+ };
1090+ }
1091+ if ( $.isWindow( raw ) ) {
1092+ return {
1093+ width: elem.width(),
1094+ height: elem.height(),
1095+ offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096+ };
1097+ }
1098+ if ( raw.preventDefault ) {
1099+ return {
1100+ width: 0,
1101+ height: 0,
1102+ offset: { top: raw.pageY, left: raw.pageX }
1103+ };
1104+ }
1105+ return {
1106+ width: elem.outerWidth(),
1107+ height: elem.outerHeight(),
1108+ offset: elem.offset()
1109+ };
1110+}
1111+
1112+$.position = {
1113+ scrollbarWidth: function() {
1114+ if ( cachedScrollbarWidth !== undefined ) {
1115+ return cachedScrollbarWidth;
1116+ }
1117+ var w1, w2,
1118+ div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119+ innerDiv = div.children()[0];
1120+
1121+ $( "body" ).append( div );
1122+ w1 = innerDiv.offsetWidth;
1123+ div.css( "overflow", "scroll" );
1124+
1125+ w2 = innerDiv.offsetWidth;
1126+
1127+ if ( w1 === w2 ) {
1128+ w2 = div[0].clientWidth;
1129+ }
1130+
1131+ div.remove();
1132+
1133+ return (cachedScrollbarWidth = w1 - w2);
1134+ },
1135+ getScrollInfo: function( within ) {
1136+ var overflowX = within.isWindow || within.isDocument ? "" :
1137+ within.element.css( "overflow-x" ),
1138+ overflowY = within.isWindow || within.isDocument ? "" :
1139+ within.element.css( "overflow-y" ),
1140+ hasOverflowX = overflowX === "scroll" ||
1141+ ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142+ hasOverflowY = overflowY === "scroll" ||
1143+ ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144+ return {
1145+ width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146+ height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147+ };
1148+ },
1149+ getWithinInfo: function( element ) {
1150+ var withinElement = $( element || window ),
1151+ isWindow = $.isWindow( withinElement[0] ),
1152+ isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153+ return {
1154+ element: withinElement,
1155+ isWindow: isWindow,
1156+ isDocument: isDocument,
1157+ offset: withinElement.offset() || { left: 0, top: 0 },
1158+ scrollLeft: withinElement.scrollLeft(),
1159+ scrollTop: withinElement.scrollTop(),
1160+
1161+ // support: jQuery 1.6.x
1162+ // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163+ width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164+ height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165+ };
1166+ }
1167+};
1168+
1169+$.fn.position = function( options ) {
1170+ if ( !options || !options.of ) {
1171+ return _position.apply( this, arguments );
1172+ }
1173+
1174+ // make a copy, we don't want to modify arguments
1175+ options = $.extend( {}, options );
1176+
1177+ var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178+ target = $( options.of ),
1179+ within = $.position.getWithinInfo( options.within ),
1180+ scrollInfo = $.position.getScrollInfo( within ),
1181+ collision = ( options.collision || "flip" ).split( " " ),
1182+ offsets = {};
1183+
1184+ dimensions = getDimensions( target );
1185+ if ( target[0].preventDefault ) {
1186+ // force left top to allow flipping
1187+ options.at = "left top";
1188+ }
1189+ targetWidth = dimensions.width;
1190+ targetHeight = dimensions.height;
1191+ targetOffset = dimensions.offset;
1192+ // clone to reuse original targetOffset later
1193+ basePosition = $.extend( {}, targetOffset );
1194+
1195+ // force my and at to have valid horizontal and vertical positions
1196+ // if a value is missing or invalid, it will be converted to center
1197+ $.each( [ "my", "at" ], function() {
1198+ var pos = ( options[ this ] || "" ).split( " " ),
1199+ horizontalOffset,
1200+ verticalOffset;
1201+
1202+ if ( pos.length === 1) {
1203+ pos = rhorizontal.test( pos[ 0 ] ) ?
1204+ pos.concat( [ "center" ] ) :
1205+ rvertical.test( pos[ 0 ] ) ?
1206+ [ "center" ].concat( pos ) :
1207+ [ "center", "center" ];
1208+ }
1209+ pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210+ pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211+
1212+ // calculate offsets
1213+ horizontalOffset = roffset.exec( pos[ 0 ] );
1214+ verticalOffset = roffset.exec( pos[ 1 ] );
1215+ offsets[ this ] = [
1216+ horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217+ verticalOffset ? verticalOffset[ 0 ] : 0
1218+ ];
1219+
1220+ // reduce to just the positions without the offsets
1221+ options[ this ] = [
1222+ rposition.exec( pos[ 0 ] )[ 0 ],
1223+ rposition.exec( pos[ 1 ] )[ 0 ]
1224+ ];
1225+ });
1226+
1227+ // normalize collision option
1228+ if ( collision.length === 1 ) {
1229+ collision[ 1 ] = collision[ 0 ];
1230+ }
1231+
1232+ if ( options.at[ 0 ] === "right" ) {
1233+ basePosition.left += targetWidth;
1234+ } else if ( options.at[ 0 ] === "center" ) {
1235+ basePosition.left += targetWidth / 2;
1236+ }
1237+
1238+ if ( options.at[ 1 ] === "bottom" ) {
1239+ basePosition.top += targetHeight;
1240+ } else if ( options.at[ 1 ] === "center" ) {
1241+ basePosition.top += targetHeight / 2;
1242+ }
1243+
1244+ atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245+ basePosition.left += atOffset[ 0 ];
1246+ basePosition.top += atOffset[ 1 ];
1247+
1248+ return this.each(function() {
1249+ var collisionPosition, using,
1250+ elem = $( this ),
1251+ elemWidth = elem.outerWidth(),
1252+ elemHeight = elem.outerHeight(),
1253+ marginLeft = parseCss( this, "marginLeft" ),
1254+ marginTop = parseCss( this, "marginTop" ),
1255+ collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256+ collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257+ position = $.extend( {}, basePosition ),
1258+ myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259+
1260+ if ( options.my[ 0 ] === "right" ) {
1261+ position.left -= elemWidth;
1262+ } else if ( options.my[ 0 ] === "center" ) {
1263+ position.left -= elemWidth / 2;
1264+ }
1265+
1266+ if ( options.my[ 1 ] === "bottom" ) {
1267+ position.top -= elemHeight;
1268+ } else if ( options.my[ 1 ] === "center" ) {
1269+ position.top -= elemHeight / 2;
1270+ }
1271+
1272+ position.left += myOffset[ 0 ];
1273+ position.top += myOffset[ 1 ];
1274+
1275+ // if the browser doesn't support fractions, then round for consistent results
1276+ if ( !supportsOffsetFractions ) {
1277+ position.left = round( position.left );
1278+ position.top = round( position.top );
1279+ }
1280+
1281+ collisionPosition = {
1282+ marginLeft: marginLeft,
1283+ marginTop: marginTop
1284+ };
1285+
1286+ $.each( [ "left", "top" ], function( i, dir ) {
1287+ if ( $.ui.position[ collision[ i ] ] ) {
1288+ $.ui.position[ collision[ i ] ][ dir ]( position, {
1289+ targetWidth: targetWidth,
1290+ targetHeight: targetHeight,
1291+ elemWidth: elemWidth,
1292+ elemHeight: elemHeight,
1293+ collisionPosition: collisionPosition,
1294+ collisionWidth: collisionWidth,
1295+ collisionHeight: collisionHeight,
1296+ offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297+ my: options.my,
1298+ at: options.at,
1299+ within: within,
1300+ elem: elem
1301+ });
1302+ }
1303+ });
1304+
1305+ if ( options.using ) {
1306+ // adds feedback as second argument to using callback, if present
1307+ using = function( props ) {
1308+ var left = targetOffset.left - position.left,
1309+ right = left + targetWidth - elemWidth,
1310+ top = targetOffset.top - position.top,
1311+ bottom = top + targetHeight - elemHeight,
1312+ feedback = {
1313+ target: {
1314+ element: target,
1315+ left: targetOffset.left,
1316+ top: targetOffset.top,
1317+ width: targetWidth,
1318+ height: targetHeight
1319+ },
1320+ element: {
1321+ element: elem,
1322+ left: position.left,
1323+ top: position.top,
1324+ width: elemWidth,
1325+ height: elemHeight
1326+ },
1327+ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328+ vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329+ };
1330+ if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331+ feedback.horizontal = "center";
1332+ }
1333+ if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334+ feedback.vertical = "middle";
1335+ }
1336+ if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337+ feedback.important = "horizontal";
1338+ } else {
1339+ feedback.important = "vertical";
1340+ }
1341+ options.using.call( this, props, feedback );
1342+ };
1343+ }
1344+
1345+ elem.offset( $.extend( position, { using: using } ) );
1346+ });
1347+};
1348+
1349+$.ui.position = {
1350+ fit: {
1351+ left: function( position, data ) {
1352+ var within = data.within,
1353+ withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354+ outerWidth = within.width,
1355+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356+ overLeft = withinOffset - collisionPosLeft,
1357+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358+ newOverRight;
1359+
1360+ // element is wider than within
1361+ if ( data.collisionWidth > outerWidth ) {
1362+ // element is initially over the left side of within
1363+ if ( overLeft > 0 && overRight <= 0 ) {
1364+ newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365+ position.left += overLeft - newOverRight;
1366+ // element is initially over right side of within
1367+ } else if ( overRight > 0 && overLeft <= 0 ) {
1368+ position.left = withinOffset;
1369+ // element is initially over both left and right sides of within
1370+ } else {
1371+ if ( overLeft > overRight ) {
1372+ position.left = withinOffset + outerWidth - data.collisionWidth;
1373+ } else {
1374+ position.left = withinOffset;
1375+ }
1376+ }
1377+ // too far left -> align with left edge
1378+ } else if ( overLeft > 0 ) {
1379+ position.left += overLeft;
1380+ // too far right -> align with right edge
1381+ } else if ( overRight > 0 ) {
1382+ position.left -= overRight;
1383+ // adjust based on position and margin
1384+ } else {
1385+ position.left = max( position.left - collisionPosLeft, position.left );
1386+ }
1387+ },
1388+ top: function( position, data ) {
1389+ var within = data.within,
1390+ withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391+ outerHeight = data.within.height,
1392+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1393+ overTop = withinOffset - collisionPosTop,
1394+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395+ newOverBottom;
1396+
1397+ // element is taller than within
1398+ if ( data.collisionHeight > outerHeight ) {
1399+ // element is initially over the top of within
1400+ if ( overTop > 0 && overBottom <= 0 ) {
1401+ newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402+ position.top += overTop - newOverBottom;
1403+ // element is initially over bottom of within
1404+ } else if ( overBottom > 0 && overTop <= 0 ) {
1405+ position.top = withinOffset;
1406+ // element is initially over both top and bottom of within
1407+ } else {
1408+ if ( overTop > overBottom ) {
1409+ position.top = withinOffset + outerHeight - data.collisionHeight;
1410+ } else {
1411+ position.top = withinOffset;
1412+ }
1413+ }
1414+ // too far up -> align with top
1415+ } else if ( overTop > 0 ) {
1416+ position.top += overTop;
1417+ // too far down -> align with bottom edge
1418+ } else if ( overBottom > 0 ) {
1419+ position.top -= overBottom;
1420+ // adjust based on position and margin
1421+ } else {
1422+ position.top = max( position.top - collisionPosTop, position.top );
1423+ }
1424+ }
1425+ },
1426+ flip: {
1427+ left: function( position, data ) {
1428+ var within = data.within,
1429+ withinOffset = within.offset.left + within.scrollLeft,
1430+ outerWidth = within.width,
1431+ offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433+ overLeft = collisionPosLeft - offsetLeft,
1434+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435+ myOffset = data.my[ 0 ] === "left" ?
1436+ -data.elemWidth :
1437+ data.my[ 0 ] === "right" ?
1438+ data.elemWidth :
1439+ 0,
1440+ atOffset = data.at[ 0 ] === "left" ?
1441+ data.targetWidth :
1442+ data.at[ 0 ] === "right" ?
1443+ -data.targetWidth :
1444+ 0,
1445+ offset = -2 * data.offset[ 0 ],
1446+ newOverRight,
1447+ newOverLeft;
1448+
1449+ if ( overLeft < 0 ) {
1450+ newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451+ if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452+ position.left += myOffset + atOffset + offset;
1453+ }
1454+ } else if ( overRight > 0 ) {
1455+ newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456+ if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457+ position.left += myOffset + atOffset + offset;
1458+ }
1459+ }
1460+ },
1461+ top: function( position, data ) {
1462+ var within = data.within,
1463+ withinOffset = within.offset.top + within.scrollTop,
1464+ outerHeight = within.height,
1465+ offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1467+ overTop = collisionPosTop - offsetTop,
1468+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469+ top = data.my[ 1 ] === "top",
1470+ myOffset = top ?
1471+ -data.elemHeight :
1472+ data.my[ 1 ] === "bottom" ?
1473+ data.elemHeight :
1474+ 0,
1475+ atOffset = data.at[ 1 ] === "top" ?
1476+ data.targetHeight :
1477+ data.at[ 1 ] === "bottom" ?
1478+ -data.targetHeight :
1479+ 0,
1480+ offset = -2 * data.offset[ 1 ],
1481+ newOverTop,
1482+ newOverBottom;
1483+ if ( overTop < 0 ) {
1484+ newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485+ if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486+ position.top += myOffset + atOffset + offset;
1487+ }
1488+ } else if ( overBottom > 0 ) {
1489+ newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490+ if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491+ position.top += myOffset + atOffset + offset;
1492+ }
1493+ }
1494+ }
1495+ },
1496+ flipfit: {
1497+ left: function() {
1498+ $.ui.position.flip.left.apply( this, arguments );
1499+ $.ui.position.fit.left.apply( this, arguments );
1500+ },
1501+ top: function() {
1502+ $.ui.position.flip.top.apply( this, arguments );
1503+ $.ui.position.fit.top.apply( this, arguments );
1504+ }
1505+ }
1506+};
1507+
1508+// fraction support test
1509+(function() {
1510+ var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511+ body = document.getElementsByTagName( "body" )[ 0 ],
1512+ div = document.createElement( "div" );
1513+
1514+ //Create a "fake body" for testing based on method used in jQuery.support
1515+ testElement = document.createElement( body ? "div" : "body" );
1516+ testElementStyle = {
1517+ visibility: "hidden",
1518+ width: 0,
1519+ height: 0,
1520+ border: 0,
1521+ margin: 0,
1522+ background: "none"
1523+ };
1524+ if ( body ) {
1525+ $.extend( testElementStyle, {
1526+ position: "absolute",
1527+ left: "-1000px",
1528+ top: "-1000px"
1529+ });
1530+ }
1531+ for ( i in testElementStyle ) {
1532+ testElement.style[ i ] = testElementStyle[ i ];
1533+ }
1534+ testElement.appendChild( div );
1535+ testElementParent = body || document.documentElement;
1536+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537+
1538+ div.style.cssText = "position: absolute; left: 10.7432222px;";
1539+
1540+ offsetLeft = $( div ).offset().left;
1541+ supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542+
1543+ testElement.innerHTML = "";
1544+ testElementParent.removeChild( testElement );
1545+})();
1546+
1547+})();
1548+
1549+var position = $.ui.position;
1550+
1551+
1552+/*!
1553+ * jQuery UI Draggable 1.11.4
1554+ * http://jqueryui.com
1555+ *
1556+ * Copyright jQuery Foundation and other contributors
1557+ * Released under the MIT license.
1558+ * http://jquery.org/license
1559+ *
1560+ * http://api.jqueryui.com/draggable/
1561+ */
1562+
1563+
1564+$.widget("ui.draggable", $.ui.mouse, {
1565+ version: "1.11.4",
1566+ widgetEventPrefix: "drag",
1567+ options: {
1568+ addClasses: true,
1569+ appendTo: "parent",
1570+ axis: false,
1571+ connectToSortable: false,
1572+ containment: false,
1573+ cursor: "auto",
1574+ cursorAt: false,
1575+ grid: false,
1576+ handle: false,
1577+ helper: "original",
1578+ iframeFix: false,
1579+ opacity: false,
1580+ refreshPositions: false,
1581+ revert: false,
1582+ revertDuration: 500,
1583+ scope: "default",
1584+ scroll: true,
1585+ scrollSensitivity: 20,
1586+ scrollSpeed: 20,
1587+ snap: false,
1588+ snapMode: "both",
1589+ snapTolerance: 20,
1590+ stack: false,
1591+ zIndex: false,
1592+
1593+ // callbacks
1594+ drag: null,
1595+ start: null,
1596+ stop: null
1597+ },
1598+ _create: function() {
1599+
1600+ if ( this.options.helper === "original" ) {
1601+ this._setPositionRelative();
1602+ }
1603+ if (this.options.addClasses){
1604+ this.element.addClass("ui-draggable");
1605+ }
1606+ if (this.options.disabled){
1607+ this.element.addClass("ui-draggable-disabled");
1608+ }
1609+ this._setHandleClassName();
1610+
1611+ this._mouseInit();
1612+ },
1613+
1614+ _setOption: function( key, value ) {
1615+ this._super( key, value );
1616+ if ( key === "handle" ) {
1617+ this._removeHandleClassName();
1618+ this._setHandleClassName();
1619+ }
1620+ },
1621+
1622+ _destroy: function() {
1623+ if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624+ this.destroyOnClear = true;
1625+ return;
1626+ }
1627+ this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628+ this._removeHandleClassName();
1629+ this._mouseDestroy();
1630+ },
1631+
1632+ _mouseCapture: function(event) {
1633+ var o = this.options;
1634+
1635+ this._blurActiveElement( event );
1636+
1637+ // among others, prevent a drag on a resizable-handle
1638+ if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639+ return false;
1640+ }
1641+
1642+ //Quit if we're not on a valid handle
1643+ this.handle = this._getHandle(event);
1644+ if (!this.handle) {
1645+ return false;
1646+ }
1647+
1648+ this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649+
1650+ return true;
1651+
1652+ },
1653+
1654+ _blockFrames: function( selector ) {
1655+ this.iframeBlocks = this.document.find( selector ).map(function() {
1656+ var iframe = $( this );
1657+
1658+ return $( "<div>" )
1659+ .css( "position", "absolute" )
1660+ .appendTo( iframe.parent() )
1661+ .outerWidth( iframe.outerWidth() )
1662+ .outerHeight( iframe.outerHeight() )
1663+ .offset( iframe.offset() )[ 0 ];
1664+ });
1665+ },
1666+
1667+ _unblockFrames: function() {
1668+ if ( this.iframeBlocks ) {
1669+ this.iframeBlocks.remove();
1670+ delete this.iframeBlocks;
1671+ }
1672+ },
1673+
1674+ _blurActiveElement: function( event ) {
1675+ var document = this.document[ 0 ];
1676+
1677+ // Only need to blur if the event occurred on the draggable itself, see #10527
1678+ if ( !this.handleElement.is( event.target ) ) {
1679+ return;
1680+ }
1681+
1682+ // support: IE9
1683+ // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684+ try {
1685+
1686+ // Support: IE9, IE10
1687+ // If the <body> is blurred, IE will switch windows, see #9520
1688+ if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689+
1690+ // Blur any element that currently has focus, see #4261
1691+ $( document.activeElement ).blur();
1692+ }
1693+ } catch ( error ) {}
1694+ },
1695+
1696+ _mouseStart: function(event) {
1697+
1698+ var o = this.options;
1699+
1700+ //Create and append the visible helper
1701+ this.helper = this._createHelper(event);
1702+
1703+ this.helper.addClass("ui-draggable-dragging");
1704+
1705+ //Cache the helper size
1706+ this._cacheHelperProportions();
1707+
1708+ //If ddmanager is used for droppables, set the global draggable
1709+ if ($.ui.ddmanager) {
1710+ $.ui.ddmanager.current = this;
1711+ }
1712+
1713+ /*
1714+ * - Position generation -
1715+ * This block generates everything position related - it's the core of draggables.
1716+ */
1717+
1718+ //Cache the margins of the original element
1719+ this._cacheMargins();
1720+
1721+ //Store the helper's css position
1722+ this.cssPosition = this.helper.css( "position" );
1723+ this.scrollParent = this.helper.scrollParent( true );
1724+ this.offsetParent = this.helper.offsetParent();
1725+ this.hasFixedAncestor = this.helper.parents().filter(function() {
1726+ return $( this ).css( "position" ) === "fixed";
1727+ }).length > 0;
1728+
1729+ //The element's absolute position on the page minus margins
1730+ this.positionAbs = this.element.offset();
1731+ this._refreshOffsets( event );
1732+
1733+ //Generate the original position
1734+ this.originalPosition = this.position = this._generatePosition( event, false );
1735+ this.originalPageX = event.pageX;
1736+ this.originalPageY = event.pageY;
1737+
1738+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740+
1741+ //Set a containment if given in the options
1742+ this._setContainment();
1743+
1744+ //Trigger event + callbacks
1745+ if (this._trigger("start", event) === false) {
1746+ this._clear();
1747+ return false;
1748+ }
1749+
1750+ //Recache the helper size
1751+ this._cacheHelperProportions();
1752+
1753+ //Prepare the droppable offsets
1754+ if ($.ui.ddmanager && !o.dropBehaviour) {
1755+ $.ui.ddmanager.prepareOffsets(this, event);
1756+ }
1757+
1758+ // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759+ // as this prevents resizing of elements with right/bottom set (see #7772)
1760+ this._normalizeRightBottom();
1761+
1762+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763+
1764+ //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765+ if ( $.ui.ddmanager ) {
1766+ $.ui.ddmanager.dragStart(this, event);
1767+ }
1768+
1769+ return true;
1770+ },
1771+
1772+ _refreshOffsets: function( event ) {
1773+ this.offset = {
1774+ top: this.positionAbs.top - this.margins.top,
1775+ left: this.positionAbs.left - this.margins.left,
1776+ scroll: false,
1777+ parent: this._getParentOffset(),
1778+ relative: this._getRelativeOffset()
1779+ };
1780+
1781+ this.offset.click = {
1782+ left: event.pageX - this.offset.left,
1783+ top: event.pageY - this.offset.top
1784+ };
1785+ },
1786+
1787+ _mouseDrag: function(event, noPropagation) {
1788+ // reset any necessary cached properties (see #5009)
1789+ if ( this.hasFixedAncestor ) {
1790+ this.offset.parent = this._getParentOffset();
1791+ }
1792+
1793+ //Compute the helpers position
1794+ this.position = this._generatePosition( event, true );
1795+ this.positionAbs = this._convertPositionTo("absolute");
1796+
1797+ //Call plugins and callbacks and use the resulting position if something is returned
1798+ if (!noPropagation) {
1799+ var ui = this._uiHash();
1800+ if (this._trigger("drag", event, ui) === false) {
1801+ this._mouseUp({});
1802+ return false;
1803+ }
1804+ this.position = ui.position;
1805+ }
1806+
1807+ this.helper[ 0 ].style.left = this.position.left + "px";
1808+ this.helper[ 0 ].style.top = this.position.top + "px";
1809+
1810+ if ($.ui.ddmanager) {
1811+ $.ui.ddmanager.drag(this, event);
1812+ }
1813+
1814+ return false;
1815+ },
1816+
1817+ _mouseStop: function(event) {
1818+
1819+ //If we are using droppables, inform the manager about the drop
1820+ var that = this,
1821+ dropped = false;
1822+ if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823+ dropped = $.ui.ddmanager.drop(this, event);
1824+ }
1825+
1826+ //if a drop comes from outside (a sortable)
1827+ if (this.dropped) {
1828+ dropped = this.dropped;
1829+ this.dropped = false;
1830+ }
1831+
1832+ if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1833+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834+ if (that._trigger("stop", event) !== false) {
1835+ that._clear();
1836+ }
1837+ });
1838+ } else {
1839+ if (this._trigger("stop", event) !== false) {
1840+ this._clear();
1841+ }
1842+ }
1843+
1844+ return false;
1845+ },
1846+
1847+ _mouseUp: function( event ) {
1848+ this._unblockFrames();
1849+
1850+ //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851+ if ( $.ui.ddmanager ) {
1852+ $.ui.ddmanager.dragStop(this, event);
1853+ }
1854+
1855+ // Only need to focus if the event occurred on the draggable itself, see #10527
1856+ if ( this.handleElement.is( event.target ) ) {
1857+ // The interaction is over; whether or not the click resulted in a drag, focus the element
1858+ this.element.focus();
1859+ }
1860+
1861+ return $.ui.mouse.prototype._mouseUp.call(this, event);
1862+ },
1863+
1864+ cancel: function() {
1865+
1866+ if (this.helper.is(".ui-draggable-dragging")) {
1867+ this._mouseUp({});
1868+ } else {
1869+ this._clear();
1870+ }
1871+
1872+ return this;
1873+
1874+ },
1875+
1876+ _getHandle: function(event) {
1877+ return this.options.handle ?
1878+ !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879+ true;
1880+ },
1881+
1882+ _setHandleClassName: function() {
1883+ this.handleElement = this.options.handle ?
1884+ this.element.find( this.options.handle ) : this.element;
1885+ this.handleElement.addClass( "ui-draggable-handle" );
1886+ },
1887+
1888+ _removeHandleClassName: function() {
1889+ this.handleElement.removeClass( "ui-draggable-handle" );
1890+ },
1891+
1892+ _createHelper: function(event) {
1893+
1894+ var o = this.options,
1895+ helperIsFunction = $.isFunction( o.helper ),
1896+ helper = helperIsFunction ?
1897+ $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898+ ( o.helper === "clone" ?
1899+ this.element.clone().removeAttr( "id" ) :
1900+ this.element );
1901+
1902+ if (!helper.parents("body").length) {
1903+ helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904+ }
1905+
1906+ // http://bugs.jqueryui.com/ticket/9446
1907+ // a helper function can return the original element
1908+ // which wouldn't have been set to relative in _create
1909+ if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910+ this._setPositionRelative();
1911+ }
1912+
1913+ if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914+ helper.css("position", "absolute");
1915+ }
1916+
1917+ return helper;
1918+
1919+ },
1920+
1921+ _setPositionRelative: function() {
1922+ if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923+ this.element[ 0 ].style.position = "relative";
1924+ }
1925+ },
1926+
1927+ _adjustOffsetFromHelper: function(obj) {
1928+ if (typeof obj === "string") {
1929+ obj = obj.split(" ");
1930+ }
1931+ if ($.isArray(obj)) {
1932+ obj = { left: +obj[0], top: +obj[1] || 0 };
1933+ }
1934+ if ("left" in obj) {
1935+ this.offset.click.left = obj.left + this.margins.left;
1936+ }
1937+ if ("right" in obj) {
1938+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939+ }
1940+ if ("top" in obj) {
1941+ this.offset.click.top = obj.top + this.margins.top;
1942+ }
1943+ if ("bottom" in obj) {
1944+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945+ }
1946+ },
1947+
1948+ _isRootNode: function( element ) {
1949+ return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950+ },
1951+
1952+ _getParentOffset: function() {
1953+
1954+ //Get the offsetParent and cache its position
1955+ var po = this.offsetParent.offset(),
1956+ document = this.document[ 0 ];
1957+
1958+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962+ if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963+ po.left += this.scrollParent.scrollLeft();
1964+ po.top += this.scrollParent.scrollTop();
1965+ }
1966+
1967+ if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968+ po = { top: 0, left: 0 };
1969+ }
1970+
1971+ return {
1972+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974+ };
1975+
1976+ },
1977+
1978+ _getRelativeOffset: function() {
1979+ if ( this.cssPosition !== "relative" ) {
1980+ return { top: 0, left: 0 };
1981+ }
1982+
1983+ var p = this.element.position(),
1984+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985+
1986+ return {
1987+ top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988+ left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989+ };
1990+
1991+ },
1992+
1993+ _cacheMargins: function() {
1994+ this.margins = {
1995+ left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996+ top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997+ right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998+ bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999+ };
2000+ },
2001+
2002+ _cacheHelperProportions: function() {
2003+ this.helperProportions = {
2004+ width: this.helper.outerWidth(),
2005+ height: this.helper.outerHeight()
2006+ };
2007+ },
2008+
2009+ _setContainment: function() {
2010+
2011+ var isUserScrollable, c, ce,
2012+ o = this.options,
2013+ document = this.document[ 0 ];
2014+
2015+ this.relativeContainer = null;
2016+
2017+ if ( !o.containment ) {
2018+ this.containment = null;
2019+ return;
2020+ }
2021+
2022+ if ( o.containment === "window" ) {
2023+ this.containment = [
2024+ $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025+ $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026+ $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027+ $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028+ ];
2029+ return;
2030+ }
2031+
2032+ if ( o.containment === "document") {
2033+ this.containment = [
2034+ 0,
2035+ 0,
2036+ $( document ).width() - this.helperProportions.width - this.margins.left,
2037+ ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038+ ];
2039+ return;
2040+ }
2041+
2042+ if ( o.containment.constructor === Array ) {
2043+ this.containment = o.containment;
2044+ return;
2045+ }
2046+
2047+ if ( o.containment === "parent" ) {
2048+ o.containment = this.helper[ 0 ].parentNode;
2049+ }
2050+
2051+ c = $( o.containment );
2052+ ce = c[ 0 ];
2053+
2054+ if ( !ce ) {
2055+ return;
2056+ }
2057+
2058+ isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059+
2060+ this.containment = [
2061+ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062+ ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063+ ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064+ ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065+ ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066+ this.helperProportions.width -
2067+ this.margins.left -
2068+ this.margins.right,
2069+ ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070+ ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071+ ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072+ this.helperProportions.height -
2073+ this.margins.top -
2074+ this.margins.bottom
2075+ ];
2076+ this.relativeContainer = c;
2077+ },
2078+
2079+ _convertPositionTo: function(d, pos) {
2080+
2081+ if (!pos) {
2082+ pos = this.position;
2083+ }
2084+
2085+ var mod = d === "absolute" ? 1 : -1,
2086+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087+
2088+ return {
2089+ top: (
2090+ pos.top + // The absolute mouse position
2091+ this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2092+ this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
2093+ ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094+ ),
2095+ left: (
2096+ pos.left + // The absolute mouse position
2097+ this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2098+ this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
2099+ ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100+ )
2101+ };
2102+
2103+ },
2104+
2105+ _generatePosition: function( event, constrainPosition ) {
2106+
2107+ var containment, co, top, left,
2108+ o = this.options,
2109+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110+ pageX = event.pageX,
2111+ pageY = event.pageY;
2112+
2113+ // Cache the scroll
2114+ if ( !scrollIsRootNode || !this.offset.scroll ) {
2115+ this.offset.scroll = {
2116+ top: this.scrollParent.scrollTop(),
2117+ left: this.scrollParent.scrollLeft()
2118+ };
2119+ }
2120+
2121+ /*
2122+ * - Position constraining -
2123+ * Constrain the position to a mix of grid, containment.
2124+ */
2125+
2126+ // If we are not dragging yet, we won't check for options
2127+ if ( constrainPosition ) {
2128+ if ( this.containment ) {
2129+ if ( this.relativeContainer ){
2130+ co = this.relativeContainer.offset();
2131+ containment = [
2132+ this.containment[ 0 ] + co.left,
2133+ this.containment[ 1 ] + co.top,
2134+ this.containment[ 2 ] + co.left,
2135+ this.containment[ 3 ] + co.top
2136+ ];
2137+ } else {
2138+ containment = this.containment;
2139+ }
2140+
2141+ if (event.pageX - this.offset.click.left < containment[0]) {
2142+ pageX = containment[0] + this.offset.click.left;
2143+ }
2144+ if (event.pageY - this.offset.click.top < containment[1]) {
2145+ pageY = containment[1] + this.offset.click.top;
2146+ }
2147+ if (event.pageX - this.offset.click.left > containment[2]) {
2148+ pageX = containment[2] + this.offset.click.left;
2149+ }
2150+ if (event.pageY - this.offset.click.top > containment[3]) {
2151+ pageY = containment[3] + this.offset.click.top;
2152+ }
2153+ }
2154+
2155+ if (o.grid) {
2156+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157+ top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158+ pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2159+
2160+ left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161+ pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2162+ }
2163+
2164+ if ( o.axis === "y" ) {
2165+ pageX = this.originalPageX;
2166+ }
2167+
2168+ if ( o.axis === "x" ) {
2169+ pageY = this.originalPageY;
2170+ }
2171+ }
2172+
2173+ return {
2174+ top: (
2175+ pageY - // The absolute mouse position
2176+ this.offset.click.top - // Click offset (relative to the element)
2177+ this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
2178+ this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
2179+ ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180+ ),
2181+ left: (
2182+ pageX - // The absolute mouse position
2183+ this.offset.click.left - // Click offset (relative to the element)
2184+ this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
2185+ this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
2186+ ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187+ )
2188+ };
2189+
2190+ },
2191+
2192+ _clear: function() {
2193+ this.helper.removeClass("ui-draggable-dragging");
2194+ if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195+ this.helper.remove();
2196+ }
2197+ this.helper = null;
2198+ this.cancelHelperRemoval = false;
2199+ if ( this.destroyOnClear ) {
2200+ this.destroy();
2201+ }
2202+ },
2203+
2204+ _normalizeRightBottom: function() {
2205+ if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206+ this.helper.width( this.helper.width() );
2207+ this.helper.css( "right", "auto" );
2208+ }
2209+ if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210+ this.helper.height( this.helper.height() );
2211+ this.helper.css( "bottom", "auto" );
2212+ }
2213+ },
2214+
2215+ // From now on bulk stuff - mainly helpers
2216+
2217+ _trigger: function( type, event, ui ) {
2218+ ui = ui || this._uiHash();
2219+ $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220+
2221+ // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222+ if ( /^(drag|start|stop)/.test( type ) ) {
2223+ this.positionAbs = this._convertPositionTo( "absolute" );
2224+ ui.offset = this.positionAbs;
2225+ }
2226+ return $.Widget.prototype._trigger.call( this, type, event, ui );
2227+ },
2228+
2229+ plugins: {},
2230+
2231+ _uiHash: function() {
2232+ return {
2233+ helper: this.helper,
2234+ position: this.position,
2235+ originalPosition: this.originalPosition,
2236+ offset: this.positionAbs
2237+ };
2238+ }
2239+
2240+});
2241+
2242+$.ui.plugin.add( "draggable", "connectToSortable", {
2243+ start: function( event, ui, draggable ) {
2244+ var uiSortable = $.extend( {}, ui, {
2245+ item: draggable.element
2246+ });
2247+
2248+ draggable.sortables = [];
2249+ $( draggable.options.connectToSortable ).each(function() {
2250+ var sortable = $( this ).sortable( "instance" );
2251+
2252+ if ( sortable && !sortable.options.disabled ) {
2253+ draggable.sortables.push( sortable );
2254+
2255+ // refreshPositions is called at drag start to refresh the containerCache
2256+ // which is used in drag. This ensures it's initialized and synchronized
2257+ // with any changes that might have happened on the page since initialization.
2258+ sortable.refreshPositions();
2259+ sortable._trigger("activate", event, uiSortable);
2260+ }
2261+ });
2262+ },
2263+ stop: function( event, ui, draggable ) {
2264+ var uiSortable = $.extend( {}, ui, {
2265+ item: draggable.element
2266+ });
2267+
2268+ draggable.cancelHelperRemoval = false;
2269+
2270+ $.each( draggable.sortables, function() {
2271+ var sortable = this;
2272+
2273+ if ( sortable.isOver ) {
2274+ sortable.isOver = 0;
2275+
2276+ // Allow this sortable to handle removing the helper
2277+ draggable.cancelHelperRemoval = true;
2278+ sortable.cancelHelperRemoval = false;
2279+
2280+ // Use _storedCSS To restore properties in the sortable,
2281+ // as this also handles revert (#9675) since the draggable
2282+ // may have modified them in unexpected ways (#8809)
2283+ sortable._storedCSS = {
2284+ position: sortable.placeholder.css( "position" ),
2285+ top: sortable.placeholder.css( "top" ),
2286+ left: sortable.placeholder.css( "left" )
2287+ };
2288+
2289+ sortable._mouseStop(event);
2290+
2291+ // Once drag has ended, the sortable should return to using
2292+ // its original helper, not the shared helper from draggable
2293+ sortable.options.helper = sortable.options._helper;
2294+ } else {
2295+ // Prevent this Sortable from removing the helper.
2296+ // However, don't set the draggable to remove the helper
2297+ // either as another connected Sortable may yet handle the removal.
2298+ sortable.cancelHelperRemoval = true;
2299+
2300+ sortable._trigger( "deactivate", event, uiSortable );
2301+ }
2302+ });
2303+ },
2304+ drag: function( event, ui, draggable ) {
2305+ $.each( draggable.sortables, function() {
2306+ var innermostIntersecting = false,
2307+ sortable = this;
2308+
2309+ // Copy over variables that sortable's _intersectsWith uses
2310+ sortable.positionAbs = draggable.positionAbs;
2311+ sortable.helperProportions = draggable.helperProportions;
2312+ sortable.offset.click = draggable.offset.click;
2313+
2314+ if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315+ innermostIntersecting = true;
2316+
2317+ $.each( draggable.sortables, function() {
2318+ // Copy over variables that sortable's _intersectsWith uses
2319+ this.positionAbs = draggable.positionAbs;
2320+ this.helperProportions = draggable.helperProportions;
2321+ this.offset.click = draggable.offset.click;
2322+
2323+ if ( this !== sortable &&
2324+ this._intersectsWith( this.containerCache ) &&
2325+ $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326+ innermostIntersecting = false;
2327+ }
2328+
2329+ return innermostIntersecting;
2330+ });
2331+ }
2332+
2333+ if ( innermostIntersecting ) {
2334+ // If it intersects, we use a little isOver variable and set it once,
2335+ // so that the move-in stuff gets fired only once.
2336+ if ( !sortable.isOver ) {
2337+ sortable.isOver = 1;
2338+
2339+ // Store draggable's parent in case we need to reappend to it later.
2340+ draggable._parent = ui.helper.parent();
2341+
2342+ sortable.currentItem = ui.helper
2343+ .appendTo( sortable.element )
2344+ .data( "ui-sortable-item", true );
2345+
2346+ // Store helper option to later restore it
2347+ sortable.options._helper = sortable.options.helper;
2348+
2349+ sortable.options.helper = function() {
2350+ return ui.helper[ 0 ];
2351+ };
2352+
2353+ // Fire the start events of the sortable with our passed browser event,
2354+ // and our own helper (so it doesn't create a new one)
2355+ event.target = sortable.currentItem[ 0 ];
2356+ sortable._mouseCapture( event, true );
2357+ sortable._mouseStart( event, true, true );
2358+
2359+ // Because the browser event is way off the new appended portlet,
2360+ // modify necessary variables to reflect the changes
2361+ sortable.offset.click.top = draggable.offset.click.top;
2362+ sortable.offset.click.left = draggable.offset.click.left;
2363+ sortable.offset.parent.left -= draggable.offset.parent.left -
2364+ sortable.offset.parent.left;
2365+ sortable.offset.parent.top -= draggable.offset.parent.top -
2366+ sortable.offset.parent.top;
2367+
2368+ draggable._trigger( "toSortable", event );
2369+
2370+ // Inform draggable that the helper is in a valid drop zone,
2371+ // used solely in the revert option to handle "valid/invalid".
2372+ draggable.dropped = sortable.element;
2373+
2374+ // Need to refreshPositions of all sortables in the case that
2375+ // adding to one sortable changes the location of the other sortables (#9675)
2376+ $.each( draggable.sortables, function() {
2377+ this.refreshPositions();
2378+ });
2379+
2380+ // hack so receive/update callbacks work (mostly)
2381+ draggable.currentItem = draggable.element;
2382+ sortable.fromOutside = draggable;
2383+ }
2384+
2385+ if ( sortable.currentItem ) {
2386+ sortable._mouseDrag( event );
2387+ // Copy the sortable's position because the draggable's can potentially reflect
2388+ // a relative position, while sortable is always absolute, which the dragged
2389+ // element has now become. (#8809)
2390+ ui.position = sortable.position;
2391+ }
2392+ } else {
2393+ // If it doesn't intersect with the sortable, and it intersected before,
2394+ // we fake the drag stop of the sortable, but make sure it doesn't remove
2395+ // the helper by using cancelHelperRemoval.
2396+ if ( sortable.isOver ) {
2397+
2398+ sortable.isOver = 0;
2399+ sortable.cancelHelperRemoval = true;
2400+
2401+ // Calling sortable's mouseStop would trigger a revert,
2402+ // so revert must be temporarily false until after mouseStop is called.
2403+ sortable.options._revert = sortable.options.revert;
2404+ sortable.options.revert = false;
2405+
2406+ sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407+ sortable._mouseStop( event, true );
2408+
2409+ // restore sortable behaviors that were modfied
2410+ // when the draggable entered the sortable area (#9481)
2411+ sortable.options.revert = sortable.options._revert;
2412+ sortable.options.helper = sortable.options._helper;
2413+
2414+ if ( sortable.placeholder ) {
2415+ sortable.placeholder.remove();
2416+ }
2417+
2418+ // Restore and recalculate the draggable's offset considering the sortable
2419+ // may have modified them in unexpected ways. (#8809, #10669)
2420+ ui.helper.appendTo( draggable._parent );
2421+ draggable._refreshOffsets( event );
2422+ ui.position = draggable._generatePosition( event, true );
2423+
2424+ draggable._trigger( "fromSortable", event );
2425+
2426+ // Inform draggable that the helper is no longer in a valid drop zone
2427+ draggable.dropped = false;
2428+
2429+ // Need to refreshPositions of all sortables just in case removing
2430+ // from one sortable changes the location of other sortables (#9675)
2431+ $.each( draggable.sortables, function() {
2432+ this.refreshPositions();
2433+ });
2434+ }
2435+ }
2436+ });
2437+ }
2438+});
2439+
2440+$.ui.plugin.add("draggable", "cursor", {
2441+ start: function( event, ui, instance ) {
2442+ var t = $( "body" ),
2443+ o = instance.options;
2444+
2445+ if (t.css("cursor")) {
2446+ o._cursor = t.css("cursor");
2447+ }
2448+ t.css("cursor", o.cursor);
2449+ },
2450+ stop: function( event, ui, instance ) {
2451+ var o = instance.options;
2452+ if (o._cursor) {
2453+ $("body").css("cursor", o._cursor);
2454+ }
2455+ }
2456+});
2457+
2458+$.ui.plugin.add("draggable", "opacity", {
2459+ start: function( event, ui, instance ) {
2460+ var t = $( ui.helper ),
2461+ o = instance.options;
2462+ if (t.css("opacity")) {
2463+ o._opacity = t.css("opacity");
2464+ }
2465+ t.css("opacity", o.opacity);
2466+ },
2467+ stop: function( event, ui, instance ) {
2468+ var o = instance.options;
2469+ if (o._opacity) {
2470+ $(ui.helper).css("opacity", o._opacity);
2471+ }
2472+ }
2473+});
2474+
2475+$.ui.plugin.add("draggable", "scroll", {
2476+ start: function( event, ui, i ) {
2477+ if ( !i.scrollParentNotHidden ) {
2478+ i.scrollParentNotHidden = i.helper.scrollParent( false );
2479+ }
2480+
2481+ if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482+ i.overflowOffset = i.scrollParentNotHidden.offset();
2483+ }
2484+ },
2485+ drag: function( event, ui, i ) {
2486+
2487+ var o = i.options,
2488+ scrolled = false,
2489+ scrollParent = i.scrollParentNotHidden[ 0 ],
2490+ document = i.document[ 0 ];
2491+
2492+ if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493+ if ( !o.axis || o.axis !== "x" ) {
2494+ if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496+ } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498+ }
2499+ }
2500+
2501+ if ( !o.axis || o.axis !== "y" ) {
2502+ if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504+ } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506+ }
2507+ }
2508+
2509+ } else {
2510+
2511+ if (!o.axis || o.axis !== "x") {
2512+ if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514+ } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516+ }
2517+ }
2518+
2519+ if (!o.axis || o.axis !== "y") {
2520+ if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522+ } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524+ }
2525+ }
2526+
2527+ }
2528+
2529+ if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530+ $.ui.ddmanager.prepareOffsets(i, event);
2531+ }
2532+
2533+ }
2534+});
2535+
2536+$.ui.plugin.add("draggable", "snap", {
2537+ start: function( event, ui, i ) {
2538+
2539+ var o = i.options;
2540+
2541+ i.snapElements = [];
2542+
2543+ $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544+ var $t = $(this),
2545+ $o = $t.offset();
2546+ if (this !== i.element[0]) {
2547+ i.snapElements.push({
2548+ item: this,
2549+ width: $t.outerWidth(), height: $t.outerHeight(),
2550+ top: $o.top, left: $o.left
2551+ });
2552+ }
2553+ });
2554+
2555+ },
2556+ drag: function( event, ui, inst ) {
2557+
2558+ var ts, bs, ls, rs, l, r, t, b, i, first,
2559+ o = inst.options,
2560+ d = o.snapTolerance,
2561+ x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563+
2564+ for (i = inst.snapElements.length - 1; i >= 0; i--){
2565+
2566+ l = inst.snapElements[i].left - inst.margins.left;
2567+ r = l + inst.snapElements[i].width;
2568+ t = inst.snapElements[i].top - inst.margins.top;
2569+ b = t + inst.snapElements[i].height;
2570+
2571+ if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572+ if (inst.snapElements[i].snapping) {
2573+ (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574+ }
2575+ inst.snapElements[i].snapping = false;
2576+ continue;
2577+ }
2578+
2579+ if (o.snapMode !== "inner") {
2580+ ts = Math.abs(t - y2) <= d;
2581+ bs = Math.abs(b - y1) <= d;
2582+ ls = Math.abs(l - x2) <= d;
2583+ rs = Math.abs(r - x1) <= d;
2584+ if (ts) {
2585+ ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586+ }
2587+ if (bs) {
2588+ ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589+ }
2590+ if (ls) {
2591+ ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592+ }
2593+ if (rs) {
2594+ ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595+ }
2596+ }
2597+
2598+ first = (ts || bs || ls || rs);
2599+
2600+ if (o.snapMode !== "outer") {
2601+ ts = Math.abs(t - y1) <= d;
2602+ bs = Math.abs(b - y2) <= d;
2603+ ls = Math.abs(l - x1) <= d;
2604+ rs = Math.abs(r - x2) <= d;
2605+ if (ts) {
2606+ ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607+ }
2608+ if (bs) {
2609+ ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610+ }
2611+ if (ls) {
2612+ ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613+ }
2614+ if (rs) {
2615+ ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616+ }
2617+ }
2618+
2619+ if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621+ }
2622+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623+
2624+ }
2625+
2626+ }
2627+});
2628+
2629+$.ui.plugin.add("draggable", "stack", {
2630+ start: function( event, ui, instance ) {
2631+ var min,
2632+ o = instance.options,
2633+ group = $.makeArray($(o.stack)).sort(function(a, b) {
2634+ return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635+ });
2636+
2637+ if (!group.length) { return; }
2638+
2639+ min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640+ $(group).each(function(i) {
2641+ $(this).css("zIndex", min + i);
2642+ });
2643+ this.css("zIndex", (min + group.length));
2644+ }
2645+});
2646+
2647+$.ui.plugin.add("draggable", "zIndex", {
2648+ start: function( event, ui, instance ) {
2649+ var t = $( ui.helper ),
2650+ o = instance.options;
2651+
2652+ if (t.css("zIndex")) {
2653+ o._zIndex = t.css("zIndex");
2654+ }
2655+ t.css("zIndex", o.zIndex);
2656+ },
2657+ stop: function( event, ui, instance ) {
2658+ var o = instance.options;
2659+
2660+ if (o._zIndex) {
2661+ $(ui.helper).css("zIndex", o._zIndex);
2662+ }
2663+ }
2664+});
2665+
2666+var draggable = $.ui.draggable;
2667+
2668+
2669+/*!
2670+ * jQuery UI Droppable 1.11.4
2671+ * http://jqueryui.com
2672+ *
2673+ * Copyright jQuery Foundation and other contributors
2674+ * Released under the MIT license.
2675+ * http://jquery.org/license
2676+ *
2677+ * http://api.jqueryui.com/droppable/
2678+ */
2679+
2680+
2681+$.widget( "ui.droppable", {
2682+ version: "1.11.4",
2683+ widgetEventPrefix: "drop",
2684+ options: {
2685+ accept: "*",
2686+ activeClass: false,
2687+ addClasses: true,
2688+ greedy: false,
2689+ hoverClass: false,
2690+ scope: "default",
2691+ tolerance: "intersect",
2692+
2693+ // callbacks
2694+ activate: null,
2695+ deactivate: null,
2696+ drop: null,
2697+ out: null,
2698+ over: null
2699+ },
2700+ _create: function() {
2701+
2702+ var proportions,
2703+ o = this.options,
2704+ accept = o.accept;
2705+
2706+ this.isover = false;
2707+ this.isout = true;
2708+
2709+ this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710+ return d.is( accept );
2711+ };
2712+
2713+ this.proportions = function( /* valueToWrite */ ) {
2714+ if ( arguments.length ) {
2715+ // Store the droppable's proportions
2716+ proportions = arguments[ 0 ];
2717+ } else {
2718+ // Retrieve or derive the droppable's proportions
2719+ return proportions ?
2720+ proportions :
2721+ proportions = {
2722+ width: this.element[ 0 ].offsetWidth,
2723+ height: this.element[ 0 ].offsetHeight
2724+ };
2725+ }
2726+ };
2727+
2728+ this._addToManager( o.scope );
2729+
2730+ o.addClasses && this.element.addClass( "ui-droppable" );
2731+
2732+ },
2733+
2734+ _addToManager: function( scope ) {
2735+ // Add the reference and positions to the manager
2736+ $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737+ $.ui.ddmanager.droppables[ scope ].push( this );
2738+ },
2739+
2740+ _splice: function( drop ) {
2741+ var i = 0;
2742+ for ( ; i < drop.length; i++ ) {
2743+ if ( drop[ i ] === this ) {
2744+ drop.splice( i, 1 );
2745+ }
2746+ }
2747+ },
2748+
2749+ _destroy: function() {
2750+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751+
2752+ this._splice( drop );
2753+
2754+ this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755+ },
2756+
2757+ _setOption: function( key, value ) {
2758+
2759+ if ( key === "accept" ) {
2760+ this.accept = $.isFunction( value ) ? value : function( d ) {
2761+ return d.is( value );
2762+ };
2763+ } else if ( key === "scope" ) {
2764+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765+
2766+ this._splice( drop );
2767+ this._addToManager( value );
2768+ }
2769+
2770+ this._super( key, value );
2771+ },
2772+
2773+ _activate: function( event ) {
2774+ var draggable = $.ui.ddmanager.current;
2775+ if ( this.options.activeClass ) {
2776+ this.element.addClass( this.options.activeClass );
2777+ }
2778+ if ( draggable ){
2779+ this._trigger( "activate", event, this.ui( draggable ) );
2780+ }
2781+ },
2782+
2783+ _deactivate: function( event ) {
2784+ var draggable = $.ui.ddmanager.current;
2785+ if ( this.options.activeClass ) {
2786+ this.element.removeClass( this.options.activeClass );
2787+ }
2788+ if ( draggable ){
2789+ this._trigger( "deactivate", event, this.ui( draggable ) );
2790+ }
2791+ },
2792+
2793+ _over: function( event ) {
2794+
2795+ var draggable = $.ui.ddmanager.current;
2796+
2797+ // Bail if draggable and droppable are same element
2798+ if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799+ return;
2800+ }
2801+
2802+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803+ if ( this.options.hoverClass ) {
2804+ this.element.addClass( this.options.hoverClass );
2805+ }
2806+ this._trigger( "over", event, this.ui( draggable ) );
2807+ }
2808+
2809+ },
2810+
2811+ _out: function( event ) {
2812+
2813+ var draggable = $.ui.ddmanager.current;
2814+
2815+ // Bail if draggable and droppable are same element
2816+ if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817+ return;
2818+ }
2819+
2820+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821+ if ( this.options.hoverClass ) {
2822+ this.element.removeClass( this.options.hoverClass );
2823+ }
2824+ this._trigger( "out", event, this.ui( draggable ) );
2825+ }
2826+
2827+ },
2828+
2829+ _drop: function( event, custom ) {
2830+
2831+ var draggable = custom || $.ui.ddmanager.current,
2832+ childrenIntersection = false;
2833+
2834+ // Bail if draggable and droppable are same element
2835+ if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836+ return false;
2837+ }
2838+
2839+ this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840+ var inst = $( this ).droppable( "instance" );
2841+ if (
2842+ inst.options.greedy &&
2843+ !inst.options.disabled &&
2844+ inst.options.scope === draggable.options.scope &&
2845+ inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846+ $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847+ ) { childrenIntersection = true; return false; }
2848+ });
2849+ if ( childrenIntersection ) {
2850+ return false;
2851+ }
2852+
2853+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854+ if ( this.options.activeClass ) {
2855+ this.element.removeClass( this.options.activeClass );
2856+ }
2857+ if ( this.options.hoverClass ) {
2858+ this.element.removeClass( this.options.hoverClass );
2859+ }
2860+ this._trigger( "drop", event, this.ui( draggable ) );
2861+ return this.element;
2862+ }
2863+
2864+ return false;
2865+
2866+ },
2867+
2868+ ui: function( c ) {
2869+ return {
2870+ draggable: ( c.currentItem || c.element ),
2871+ helper: c.helper,
2872+ position: c.position,
2873+ offset: c.positionAbs
2874+ };
2875+ }
2876+
2877+});
2878+
2879+$.ui.intersect = (function() {
2880+ function isOverAxis( x, reference, size ) {
2881+ return ( x >= reference ) && ( x < ( reference + size ) );
2882+ }
2883+
2884+ return function( draggable, droppable, toleranceMode, event ) {
2885+
2886+ if ( !droppable.offset ) {
2887+ return false;
2888+ }
2889+
2890+ var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891+ y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892+ x2 = x1 + draggable.helperProportions.width,
2893+ y2 = y1 + draggable.helperProportions.height,
2894+ l = droppable.offset.left,
2895+ t = droppable.offset.top,
2896+ r = l + droppable.proportions().width,
2897+ b = t + droppable.proportions().height;
2898+
2899+ switch ( toleranceMode ) {
2900+ case "fit":
2901+ return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902+ case "intersect":
2903+ return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904+ x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905+ t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906+ y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907+ case "pointer":
2908+ return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909+ case "touch":
2910+ return (
2911+ ( y1 >= t && y1 <= b ) || // Top edge touching
2912+ ( y2 >= t && y2 <= b ) || // Bottom edge touching
2913+ ( y1 < t && y2 > b ) // Surrounded vertically
2914+ ) && (
2915+ ( x1 >= l && x1 <= r ) || // Left edge touching
2916+ ( x2 >= l && x2 <= r ) || // Right edge touching
2917+ ( x1 < l && x2 > r ) // Surrounded horizontally
2918+ );
2919+ default:
2920+ return false;
2921+ }
2922+ };
2923+})();
2924+
2925+/*
2926+ This manager tracks offsets of draggables and droppables
2927+*/
2928+$.ui.ddmanager = {
2929+ current: null,
2930+ droppables: { "default": [] },
2931+ prepareOffsets: function( t, event ) {
2932+
2933+ var i, j,
2934+ m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935+ type = event ? event.type : null, // workaround for #2317
2936+ list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937+
2938+ droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939+
2940+ // No disabled and non-accepted
2941+ if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942+ continue;
2943+ }
2944+
2945+ // Filter out elements in the current dragged item
2946+ for ( j = 0; j < list.length; j++ ) {
2947+ if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948+ m[ i ].proportions().height = 0;
2949+ continue droppablesLoop;
2950+ }
2951+ }
2952+
2953+ m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954+ if ( !m[ i ].visible ) {
2955+ continue;
2956+ }
2957+
2958+ // Activate the droppable if used directly from draggables
2959+ if ( type === "mousedown" ) {
2960+ m[ i ]._activate.call( m[ i ], event );
2961+ }
2962+
2963+ m[ i ].offset = m[ i ].element.offset();
2964+ m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965+
2966+ }
2967+
2968+ },
2969+ drop: function( draggable, event ) {
2970+
2971+ var dropped = false;
2972+ // Create a copy of the droppables in case the list changes during the drop (#9116)
2973+ $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974+
2975+ if ( !this.options ) {
2976+ return;
2977+ }
2978+ if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979+ dropped = this._drop.call( this, event ) || dropped;
2980+ }
2981+
2982+ if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983+ this.isout = true;
2984+ this.isover = false;
2985+ this._deactivate.call( this, event );
2986+ }
2987+
2988+ });
2989+ return dropped;
2990+
2991+ },
2992+ dragStart: function( draggable, event ) {
2993+ // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994+ draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995+ if ( !draggable.options.refreshPositions ) {
2996+ $.ui.ddmanager.prepareOffsets( draggable, event );
2997+ }
2998+ });
2999+ },
3000+ drag: function( draggable, event ) {
3001+
3002+ // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003+ if ( draggable.options.refreshPositions ) {
3004+ $.ui.ddmanager.prepareOffsets( draggable, event );
3005+ }
3006+
3007+ // Run through all droppables and check their positions based on specific tolerance options
3008+ $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009+
3010+ if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011+ return;
3012+ }
3013+
3014+ var parentInstance, scope, parent,
3015+ intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016+ c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017+ if ( !c ) {
3018+ return;
3019+ }
3020+
3021+ if ( this.options.greedy ) {
3022+ // find droppable parents with same scope
3023+ scope = this.options.scope;
3024+ parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025+ return $( this ).droppable( "instance" ).options.scope === scope;
3026+ });
3027+
3028+ if ( parent.length ) {
3029+ parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030+ parentInstance.greedyChild = ( c === "isover" );
3031+ }
3032+ }
3033+
3034+ // we just moved into a greedy child
3035+ if ( parentInstance && c === "isover" ) {
3036+ parentInstance.isover = false;
3037+ parentInstance.isout = true;
3038+ parentInstance._out.call( parentInstance, event );
3039+ }
3040+
3041+ this[ c ] = true;
3042+ this[c === "isout" ? "isover" : "isout"] = false;
3043+ this[c === "isover" ? "_over" : "_out"].call( this, event );
3044+
3045+ // we just moved out of a greedy child
3046+ if ( parentInstance && c === "isout" ) {
3047+ parentInstance.isout = false;
3048+ parentInstance.isover = true;
3049+ parentInstance._over.call( parentInstance, event );
3050+ }
3051+ });
3052+
3053+ },
3054+ dragStop: function( draggable, event ) {
3055+ draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056+ // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057+ if ( !draggable.options.refreshPositions ) {
3058+ $.ui.ddmanager.prepareOffsets( draggable, event );
3059+ }
3060+ }
3061+};
3062+
3063+var droppable = $.ui.droppable;
3064+
3065+
3066+/*!
3067+ * jQuery UI Resizable 1.11.4
3068+ * http://jqueryui.com
3069+ *
3070+ * Copyright jQuery Foundation and other contributors
3071+ * Released under the MIT license.
3072+ * http://jquery.org/license
3073+ *
3074+ * http://api.jqueryui.com/resizable/
3075+ */
3076+
3077+
3078+$.widget("ui.resizable", $.ui.mouse, {
3079+ version: "1.11.4",
3080+ widgetEventPrefix: "resize",
3081+ options: {
3082+ alsoResize: false,
3083+ animate: false,
3084+ animateDuration: "slow",
3085+ animateEasing: "swing",
3086+ aspectRatio: false,
3087+ autoHide: false,
3088+ containment: false,
3089+ ghost: false,
3090+ grid: false,
3091+ handles: "e,s,se",
3092+ helper: false,
3093+ maxHeight: null,
3094+ maxWidth: null,
3095+ minHeight: 10,
3096+ minWidth: 10,
3097+ // See #7960
3098+ zIndex: 90,
3099+
3100+ // callbacks
3101+ resize: null,
3102+ start: null,
3103+ stop: null
3104+ },
3105+
3106+ _num: function( value ) {
3107+ return parseInt( value, 10 ) || 0;
3108+ },
3109+
3110+ _isNumber: function( value ) {
3111+ return !isNaN( parseInt( value, 10 ) );
3112+ },
3113+
3114+ _hasScroll: function( el, a ) {
3115+
3116+ if ( $( el ).css( "overflow" ) === "hidden") {
3117+ return false;
3118+ }
3119+
3120+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3121+ has = false;
3122+
3123+ if ( el[ scroll ] > 0 ) {
3124+ return true;
3125+ }
3126+
3127+ // TODO: determine which cases actually cause this to happen
3128+ // if the element doesn't have the scroll set, see if it's possible to
3129+ // set the scroll
3130+ el[ scroll ] = 1;
3131+ has = ( el[ scroll ] > 0 );
3132+ el[ scroll ] = 0;
3133+ return has;
3134+ },
3135+
3136+ _create: function() {
3137+
3138+ var n, i, handle, axis, hname,
3139+ that = this,
3140+ o = this.options;
3141+ this.element.addClass("ui-resizable");
3142+
3143+ $.extend(this, {
3144+ _aspectRatio: !!(o.aspectRatio),
3145+ aspectRatio: o.aspectRatio,
3146+ originalElement: this.element,
3147+ _proportionallyResizeElements: [],
3148+ _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3149+ });
3150+
3151+ // Wrap the element if it cannot hold child nodes
3152+ if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3153+
3154+ this.element.wrap(
3155+ $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3156+ position: this.element.css("position"),
3157+ width: this.element.outerWidth(),
3158+ height: this.element.outerHeight(),
3159+ top: this.element.css("top"),
3160+ left: this.element.css("left")
3161+ })
3162+ );
3163+
3164+ this.element = this.element.parent().data(
3165+ "ui-resizable", this.element.resizable( "instance" )
3166+ );
3167+
3168+ this.elementIsWrapper = true;
3169+
3170+ this.element.css({
3171+ marginLeft: this.originalElement.css("marginLeft"),
3172+ marginTop: this.originalElement.css("marginTop"),
3173+ marginRight: this.originalElement.css("marginRight"),
3174+ marginBottom: this.originalElement.css("marginBottom")
3175+ });
3176+ this.originalElement.css({
3177+ marginLeft: 0,
3178+ marginTop: 0,
3179+ marginRight: 0,
3180+ marginBottom: 0
3181+ });
3182+ // support: Safari
3183+ // Prevent Safari textarea resize
3184+ this.originalResizeStyle = this.originalElement.css("resize");
3185+ this.originalElement.css("resize", "none");
3186+
3187+ this._proportionallyResizeElements.push( this.originalElement.css({
3188+ position: "static",
3189+ zoom: 1,
3190+ display: "block"
3191+ }) );
3192+
3193+ // support: IE9
3194+ // avoid IE jump (hard set the margin)
3195+ this.originalElement.css({ margin: this.originalElement.css("margin") });
3196+
3197+ this._proportionallyResize();
3198+ }
3199+
3200+ this.handles = o.handles ||
3201+ ( !$(".ui-resizable-handle", this.element).length ?
3202+ "e,s,se" : {
3203+ n: ".ui-resizable-n",
3204+ e: ".ui-resizable-e",
3205+ s: ".ui-resizable-s",
3206+ w: ".ui-resizable-w",
3207+ se: ".ui-resizable-se",
3208+ sw: ".ui-resizable-sw",
3209+ ne: ".ui-resizable-ne",
3210+ nw: ".ui-resizable-nw"
3211+ } );
3212+
3213+ this._handles = $();
3214+ if ( this.handles.constructor === String ) {
3215+
3216+ if ( this.handles === "all") {
3217+ this.handles = "n,e,s,w,se,sw,ne,nw";
3218+ }
3219+
3220+ n = this.handles.split(",");
3221+ this.handles = {};
3222+
3223+ for (i = 0; i < n.length; i++) {
3224+
3225+ handle = $.trim(n[i]);
3226+ hname = "ui-resizable-" + handle;
3227+ axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3228+
3229+ axis.css({ zIndex: o.zIndex });
3230+
3231+ // TODO : What's going on here?
3232+ if ("se" === handle) {
3233+ axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3234+ }
3235+
3236+ this.handles[handle] = ".ui-resizable-" + handle;
3237+ this.element.append(axis);
3238+ }
3239+
3240+ }
3241+
3242+ this._renderAxis = function(target) {
3243+
3244+ var i, axis, padPos, padWrapper;
3245+
3246+ target = target || this.element;
3247+
3248+ for (i in this.handles) {
3249+
3250+ if (this.handles[i].constructor === String) {
3251+ this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3252+ } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3253+ this.handles[ i ] = $( this.handles[ i ] );
3254+ this._on( this.handles[ i ], { "mousedown": that._mouseDown });
3255+ }
3256+
3257+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3258+
3259+ axis = $(this.handles[i], this.element);
3260+
3261+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3262+
3263+ padPos = [ "padding",
3264+ /ne|nw|n/.test(i) ? "Top" :
3265+ /se|sw|s/.test(i) ? "Bottom" :
3266+ /^e$/.test(i) ? "Right" : "Left" ].join("");
3267+
3268+ target.css(padPos, padWrapper);
3269+
3270+ this._proportionallyResize();
3271+ }
3272+
3273+ this._handles = this._handles.add( this.handles[ i ] );
3274+ }
3275+ };
3276+
3277+ // TODO: make renderAxis a prototype function
3278+ this._renderAxis(this.element);
3279+
3280+ this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3281+ this._handles.disableSelection();
3282+
3283+ this._handles.mouseover(function() {
3284+ if (!that.resizing) {
3285+ if (this.className) {
3286+ axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3287+ }
3288+ that.axis = axis && axis[1] ? axis[1] : "se";
3289+ }
3290+ });
3291+
3292+ if (o.autoHide) {
3293+ this._handles.hide();
3294+ $(this.element)
3295+ .addClass("ui-resizable-autohide")
3296+ .mouseenter(function() {
3297+ if (o.disabled) {
3298+ return;
3299+ }
3300+ $(this).removeClass("ui-resizable-autohide");
3301+ that._handles.show();
3302+ })
3303+ .mouseleave(function() {
3304+ if (o.disabled) {
3305+ return;
3306+ }
3307+ if (!that.resizing) {
3308+ $(this).addClass("ui-resizable-autohide");
3309+ that._handles.hide();
3310+ }
3311+ });
3312+ }
3313+
3314+ this._mouseInit();
3315+ },
3316+
3317+ _destroy: function() {
3318+
3319+ this._mouseDestroy();
3320+
3321+ var wrapper,
3322+ _destroy = function(exp) {
3323+ $(exp)
3324+ .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3325+ .removeData("resizable")
3326+ .removeData("ui-resizable")
3327+ .unbind(".resizable")
3328+ .find(".ui-resizable-handle")
3329+ .remove();
3330+ };
3331+
3332+ // TODO: Unwrap at same DOM position
3333+ if (this.elementIsWrapper) {
3334+ _destroy(this.element);
3335+ wrapper = this.element;
3336+ this.originalElement.css({
3337+ position: wrapper.css("position"),
3338+ width: wrapper.outerWidth(),
3339+ height: wrapper.outerHeight(),
3340+ top: wrapper.css("top"),
3341+ left: wrapper.css("left")
3342+ }).insertAfter( wrapper );
3343+ wrapper.remove();
3344+ }
3345+
3346+ this.originalElement.css("resize", this.originalResizeStyle);
3347+ _destroy(this.originalElement);
3348+
3349+ return this;
3350+ },
3351+
3352+ _mouseCapture: function(event) {
3353+ var i, handle,
3354+ capture = false;
3355+
3356+ for (i in this.handles) {
3357+ handle = $(this.handles[i])[0];
3358+ if (handle === event.target || $.contains(handle, event.target)) {
3359+ capture = true;
3360+ }
3361+ }
3362+
3363+ return !this.options.disabled && capture;
3364+ },
3365+
3366+ _mouseStart: function(event) {
3367+
3368+ var curleft, curtop, cursor,
3369+ o = this.options,
3370+ el = this.element;
3371+
3372+ this.resizing = true;
3373+
3374+ this._renderProxy();
3375+
3376+ curleft = this._num(this.helper.css("left"));
3377+ curtop = this._num(this.helper.css("top"));
3378+
3379+ if (o.containment) {
3380+ curleft += $(o.containment).scrollLeft() || 0;
3381+ curtop += $(o.containment).scrollTop() || 0;
3382+ }
3383+
3384+ this.offset = this.helper.offset();
3385+ this.position = { left: curleft, top: curtop };
3386+
3387+ this.size = this._helper ? {
3388+ width: this.helper.width(),
3389+ height: this.helper.height()
3390+ } : {
3391+ width: el.width(),
3392+ height: el.height()
3393+ };
3394+
3395+ this.originalSize = this._helper ? {
3396+ width: el.outerWidth(),
3397+ height: el.outerHeight()
3398+ } : {
3399+ width: el.width(),
3400+ height: el.height()
3401+ };
3402+
3403+ this.sizeDiff = {
3404+ width: el.outerWidth() - el.width(),
3405+ height: el.outerHeight() - el.height()
3406+ };
3407+
3408+ this.originalPosition = { left: curleft, top: curtop };
3409+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
3410+
3411+ this.aspectRatio = (typeof o.aspectRatio === "number") ?
3412+ o.aspectRatio :
3413+ ((this.originalSize.width / this.originalSize.height) || 1);
3414+
3415+ cursor = $(".ui-resizable-" + this.axis).css("cursor");
3416+ $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3417+
3418+ el.addClass("ui-resizable-resizing");
3419+ this._propagate("start", event);
3420+ return true;
3421+ },
3422+
3423+ _mouseDrag: function(event) {
3424+
3425+ var data, props,
3426+ smp = this.originalMousePosition,
3427+ a = this.axis,
3428+ dx = (event.pageX - smp.left) || 0,
3429+ dy = (event.pageY - smp.top) || 0,
3430+ trigger = this._change[a];
3431+
3432+ this._updatePrevProperties();
3433+
3434+ if (!trigger) {
3435+ return false;
3436+ }
3437+
3438+ data = trigger.apply(this, [ event, dx, dy ]);
3439+
3440+ this._updateVirtualBoundaries(event.shiftKey);
3441+ if (this._aspectRatio || event.shiftKey) {
3442+ data = this._updateRatio(data, event);
3443+ }
3444+
3445+ data = this._respectSize(data, event);
3446+
3447+ this._updateCache(data);
3448+
3449+ this._propagate("resize", event);
3450+
3451+ props = this._applyChanges();
3452+
3453+ if ( !this._helper && this._proportionallyResizeElements.length ) {
3454+ this._proportionallyResize();
3455+ }
3456+
3457+ if ( !$.isEmptyObject( props ) ) {
3458+ this._updatePrevProperties();
3459+ this._trigger( "resize", event, this.ui() );
3460+ this._applyChanges();
3461+ }
3462+
3463+ return false;
3464+ },
3465+
3466+ _mouseStop: function(event) {
3467+
3468+ this.resizing = false;
3469+ var pr, ista, soffseth, soffsetw, s, left, top,
3470+ o = this.options, that = this;
3471+
3472+ if (this._helper) {
3473+
3474+ pr = this._proportionallyResizeElements;
3475+ ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3476+ soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3477+ soffsetw = ista ? 0 : that.sizeDiff.width;
3478+
3479+ s = {
3480+ width: (that.helper.width() - soffsetw),
3481+ height: (that.helper.height() - soffseth)
3482+ };
3483+ left = (parseInt(that.element.css("left"), 10) +
3484+ (that.position.left - that.originalPosition.left)) || null;
3485+ top = (parseInt(that.element.css("top"), 10) +
3486+ (that.position.top - that.originalPosition.top)) || null;
3487+
3488+ if (!o.animate) {
3489+ this.element.css($.extend(s, { top: top, left: left }));
3490+ }
3491+
3492+ that.helper.height(that.size.height);
3493+ that.helper.width(that.size.width);
3494+
3495+ if (this._helper && !o.animate) {
3496+ this._proportionallyResize();
3497+ }
3498+ }
3499+
3500+ $("body").css("cursor", "auto");
3501+
3502+ this.element.removeClass("ui-resizable-resizing");
3503+
3504+ this._propagate("stop", event);
3505+
3506+ if (this._helper) {
3507+ this.helper.remove();
3508+ }
3509+
3510+ return false;
3511+
3512+ },
3513+
3514+ _updatePrevProperties: function() {
3515+ this.prevPosition = {
3516+ top: this.position.top,
3517+ left: this.position.left
3518+ };
3519+ this.prevSize = {
3520+ width: this.size.width,
3521+ height: this.size.height
3522+ };
3523+ },
3524+
3525+ _applyChanges: function() {
3526+ var props = {};
3527+
3528+ if ( this.position.top !== this.prevPosition.top ) {
3529+ props.top = this.position.top + "px";
3530+ }
3531+ if ( this.position.left !== this.prevPosition.left ) {
3532+ props.left = this.position.left + "px";
3533+ }
3534+ if ( this.size.width !== this.prevSize.width ) {
3535+ props.width = this.size.width + "px";
3536+ }
3537+ if ( this.size.height !== this.prevSize.height ) {
3538+ props.height = this.size.height + "px";
3539+ }
3540+
3541+ this.helper.css( props );
3542+
3543+ return props;
3544+ },
3545+
3546+ _updateVirtualBoundaries: function(forceAspectRatio) {
3547+ var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3548+ o = this.options;
3549+
3550+ b = {
3551+ minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3552+ maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3553+ minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3554+ maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3555+ };
3556+
3557+ if (this._aspectRatio || forceAspectRatio) {
3558+ pMinWidth = b.minHeight * this.aspectRatio;
3559+ pMinHeight = b.minWidth / this.aspectRatio;
3560+ pMaxWidth = b.maxHeight * this.aspectRatio;
3561+ pMaxHeight = b.maxWidth / this.aspectRatio;
3562+
3563+ if (pMinWidth > b.minWidth) {
3564+ b.minWidth = pMinWidth;
3565+ }
3566+ if (pMinHeight > b.minHeight) {
3567+ b.minHeight = pMinHeight;
3568+ }
3569+ if (pMaxWidth < b.maxWidth) {
3570+ b.maxWidth = pMaxWidth;
3571+ }
3572+ if (pMaxHeight < b.maxHeight) {
3573+ b.maxHeight = pMaxHeight;
3574+ }
3575+ }
3576+ this._vBoundaries = b;
3577+ },
3578+
3579+ _updateCache: function(data) {
3580+ this.offset = this.helper.offset();
3581+ if (this._isNumber(data.left)) {
3582+ this.position.left = data.left;
3583+ }
3584+ if (this._isNumber(data.top)) {
3585+ this.position.top = data.top;
3586+ }
3587+ if (this._isNumber(data.height)) {
3588+ this.size.height = data.height;
3589+ }
3590+ if (this._isNumber(data.width)) {
3591+ this.size.width = data.width;
3592+ }
3593+ },
3594+
3595+ _updateRatio: function( data ) {
3596+
3597+ var cpos = this.position,
3598+ csize = this.size,
3599+ a = this.axis;
3600+
3601+ if (this._isNumber(data.height)) {
3602+ data.width = (data.height * this.aspectRatio);
3603+ } else if (this._isNumber(data.width)) {
3604+ data.height = (data.width / this.aspectRatio);
3605+ }
3606+
3607+ if (a === "sw") {
3608+ data.left = cpos.left + (csize.width - data.width);
3609+ data.top = null;
3610+ }
3611+ if (a === "nw") {
3612+ data.top = cpos.top + (csize.height - data.height);
3613+ data.left = cpos.left + (csize.width - data.width);
3614+ }
3615+
3616+ return data;
3617+ },
3618+
3619+ _respectSize: function( data ) {
3620+
3621+ var o = this._vBoundaries,
3622+ a = this.axis,
3623+ ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3624+ ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3625+ isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3626+ isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3627+ dw = this.originalPosition.left + this.originalSize.width,
3628+ dh = this.position.top + this.size.height,
3629+ cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3630+ if (isminw) {
3631+ data.width = o.minWidth;
3632+ }
3633+ if (isminh) {
3634+ data.height = o.minHeight;
3635+ }
3636+ if (ismaxw) {
3637+ data.width = o.maxWidth;
3638+ }
3639+ if (ismaxh) {
3640+ data.height = o.maxHeight;
3641+ }
3642+
3643+ if (isminw && cw) {
3644+ data.left = dw - o.minWidth;
3645+ }
3646+ if (ismaxw && cw) {
3647+ data.left = dw - o.maxWidth;
3648+ }
3649+ if (isminh && ch) {
3650+ data.top = dh - o.minHeight;
3651+ }
3652+ if (ismaxh && ch) {
3653+ data.top = dh - o.maxHeight;
3654+ }
3655+
3656+ // Fixing jump error on top/left - bug #2330
3657+ if (!data.width && !data.height && !data.left && data.top) {
3658+ data.top = null;
3659+ } else if (!data.width && !data.height && !data.top && data.left) {
3660+ data.left = null;
3661+ }
3662+
3663+ return data;
3664+ },
3665+
3666+ _getPaddingPlusBorderDimensions: function( element ) {
3667+ var i = 0,
3668+ widths = [],
3669+ borders = [
3670+ element.css( "borderTopWidth" ),
3671+ element.css( "borderRightWidth" ),
3672+ element.css( "borderBottomWidth" ),
3673+ element.css( "borderLeftWidth" )
3674+ ],
3675+ paddings = [
3676+ element.css( "paddingTop" ),
3677+ element.css( "paddingRight" ),
3678+ element.css( "paddingBottom" ),
3679+ element.css( "paddingLeft" )
3680+ ];
3681+
3682+ for ( ; i < 4; i++ ) {
3683+ widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3684+ widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3685+ }
3686+
3687+ return {
3688+ height: widths[ 0 ] + widths[ 2 ],
3689+ width: widths[ 1 ] + widths[ 3 ]
3690+ };
3691+ },
3692+
3693+ _proportionallyResize: function() {
3694+
3695+ if (!this._proportionallyResizeElements.length) {
3696+ return;
3697+ }
3698+
3699+ var prel,
3700+ i = 0,
3701+ element = this.helper || this.element;
3702+
3703+ for ( ; i < this._proportionallyResizeElements.length; i++) {
3704+
3705+ prel = this._proportionallyResizeElements[i];
3706+
3707+ // TODO: Seems like a bug to cache this.outerDimensions
3708+ // considering that we are in a loop.
3709+ if (!this.outerDimensions) {
3710+ this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3711+ }
3712+
3713+ prel.css({
3714+ height: (element.height() - this.outerDimensions.height) || 0,
3715+ width: (element.width() - this.outerDimensions.width) || 0
3716+ });
3717+
3718+ }
3719+
3720+ },
3721+
3722+ _renderProxy: function() {
3723+
3724+ var el = this.element, o = this.options;
3725+ this.elementOffset = el.offset();
3726+
3727+ if (this._helper) {
3728+
3729+ this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3730+
3731+ this.helper.addClass(this._helper).css({
3732+ width: this.element.outerWidth() - 1,
3733+ height: this.element.outerHeight() - 1,
3734+ position: "absolute",
3735+ left: this.elementOffset.left + "px",
3736+ top: this.elementOffset.top + "px",
3737+ zIndex: ++o.zIndex //TODO: Don't modify option
3738+ });
3739+
3740+ this.helper
3741+ .appendTo("body")
3742+ .disableSelection();
3743+
3744+ } else {
3745+ this.helper = this.element;
3746+ }
3747+
3748+ },
3749+
3750+ _change: {
3751+ e: function(event, dx) {
3752+ return { width: this.originalSize.width + dx };
3753+ },
3754+ w: function(event, dx) {
3755+ var cs = this.originalSize, sp = this.originalPosition;
3756+ return { left: sp.left + dx, width: cs.width - dx };
3757+ },
3758+ n: function(event, dx, dy) {
3759+ var cs = this.originalSize, sp = this.originalPosition;
3760+ return { top: sp.top + dy, height: cs.height - dy };
3761+ },
3762+ s: function(event, dx, dy) {
3763+ return { height: this.originalSize.height + dy };
3764+ },
3765+ se: function(event, dx, dy) {
3766+ return $.extend(this._change.s.apply(this, arguments),
3767+ this._change.e.apply(this, [ event, dx, dy ]));
3768+ },
3769+ sw: function(event, dx, dy) {
3770+ return $.extend(this._change.s.apply(this, arguments),
3771+ this._change.w.apply(this, [ event, dx, dy ]));
3772+ },
3773+ ne: function(event, dx, dy) {
3774+ return $.extend(this._change.n.apply(this, arguments),
3775+ this._change.e.apply(this, [ event, dx, dy ]));
3776+ },
3777+ nw: function(event, dx, dy) {
3778+ return $.extend(this._change.n.apply(this, arguments),
3779+ this._change.w.apply(this, [ event, dx, dy ]));
3780+ }
3781+ },
3782+
3783+ _propagate: function(n, event) {
3784+ $.ui.plugin.call(this, n, [ event, this.ui() ]);
3785+ (n !== "resize" && this._trigger(n, event, this.ui()));
3786+ },
3787+
3788+ plugins: {},
3789+
3790+ ui: function() {
3791+ return {
3792+ originalElement: this.originalElement,
3793+ element: this.element,
3794+ helper: this.helper,
3795+ position: this.position,
3796+ size: this.size,
3797+ originalSize: this.originalSize,
3798+ originalPosition: this.originalPosition
3799+ };
3800+ }
3801+
3802+});
3803+
3804+/*
3805+ * Resizable Extensions
3806+ */
3807+
3808+$.ui.plugin.add("resizable", "animate", {
3809+
3810+ stop: function( event ) {
3811+ var that = $(this).resizable( "instance" ),
3812+ o = that.options,
3813+ pr = that._proportionallyResizeElements,
3814+ ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3815+ soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3816+ soffsetw = ista ? 0 : that.sizeDiff.width,
3817+ style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3818+ left = (parseInt(that.element.css("left"), 10) +
3819+ (that.position.left - that.originalPosition.left)) || null,
3820+ top = (parseInt(that.element.css("top"), 10) +
3821+ (that.position.top - that.originalPosition.top)) || null;
3822+
3823+ that.element.animate(
3824+ $.extend(style, top && left ? { top: top, left: left } : {}), {
3825+ duration: o.animateDuration,
3826+ easing: o.animateEasing,
3827+ step: function() {
3828+
3829+ var data = {
3830+ width: parseInt(that.element.css("width"), 10),
3831+ height: parseInt(that.element.css("height"), 10),
3832+ top: parseInt(that.element.css("top"), 10),
3833+ left: parseInt(that.element.css("left"), 10)
3834+ };
3835+
3836+ if (pr && pr.length) {
3837+ $(pr[0]).css({ width: data.width, height: data.height });
3838+ }
3839+
3840+ // propagating resize, and updating values for each animation step
3841+ that._updateCache(data);
3842+ that._propagate("resize", event);
3843+
3844+ }
3845+ }
3846+ );
3847+ }
3848+
3849+});
3850+
3851+$.ui.plugin.add( "resizable", "containment", {
3852+
3853+ start: function() {
3854+ var element, p, co, ch, cw, width, height,
3855+ that = $( this ).resizable( "instance" ),
3856+ o = that.options,
3857+ el = that.element,
3858+ oc = o.containment,
3859+ ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3860+
3861+ if ( !ce ) {
3862+ return;
3863+ }
3864+
3865+ that.containerElement = $( ce );
3866+
3867+ if ( /document/.test( oc ) || oc === document ) {
3868+ that.containerOffset = {
3869+ left: 0,
3870+ top: 0
3871+ };
3872+ that.containerPosition = {
3873+ left: 0,
3874+ top: 0
3875+ };
3876+
3877+ that.parentData = {
3878+ element: $( document ),
3879+ left: 0,
3880+ top: 0,
3881+ width: $( document ).width(),
3882+ height: $( document ).height() || document.body.parentNode.scrollHeight
3883+ };
3884+ } else {
3885+ element = $( ce );
3886+ p = [];
3887+ $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3888+ p[ i ] = that._num( element.css( "padding" + name ) );
3889+ });
3890+
3891+ that.containerOffset = element.offset();
3892+ that.containerPosition = element.position();
3893+ that.containerSize = {
3894+ height: ( element.innerHeight() - p[ 3 ] ),
3895+ width: ( element.innerWidth() - p[ 1 ] )
3896+ };
3897+
3898+ co = that.containerOffset;
3899+ ch = that.containerSize.height;
3900+ cw = that.containerSize.width;
3901+ width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3902+ height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3903+
3904+ that.parentData = {
3905+ element: ce,
3906+ left: co.left,
3907+ top: co.top,
3908+ width: width,
3909+ height: height
3910+ };
3911+ }
3912+ },
3913+
3914+ resize: function( event ) {
3915+ var woset, hoset, isParent, isOffsetRelative,
3916+ that = $( this ).resizable( "instance" ),
3917+ o = that.options,
3918+ co = that.containerOffset,
3919+ cp = that.position,
3920+ pRatio = that._aspectRatio || event.shiftKey,
3921+ cop = {
3922+ top: 0,
3923+ left: 0
3924+ },
3925+ ce = that.containerElement,
3926+ continueResize = true;
3927+
3928+ if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3929+ cop = co;
3930+ }
3931+
3932+ if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3933+ that.size.width = that.size.width +
3934+ ( that._helper ?
3935+ ( that.position.left - co.left ) :
3936+ ( that.position.left - cop.left ) );
3937+
3938+ if ( pRatio ) {
3939+ that.size.height = that.size.width / that.aspectRatio;
3940+ continueResize = false;
3941+ }
3942+ that.position.left = o.helper ? co.left : 0;
3943+ }
3944+
3945+ if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3946+ that.size.height = that.size.height +
3947+ ( that._helper ?
3948+ ( that.position.top - co.top ) :
3949+ that.position.top );
3950+
3951+ if ( pRatio ) {
3952+ that.size.width = that.size.height * that.aspectRatio;
3953+ continueResize = false;
3954+ }
3955+ that.position.top = that._helper ? co.top : 0;
3956+ }
3957+
3958+ isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3959+ isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3960+
3961+ if ( isParent && isOffsetRelative ) {
3962+ that.offset.left = that.parentData.left + that.position.left;
3963+ that.offset.top = that.parentData.top + that.position.top;
3964+ } else {
3965+ that.offset.left = that.element.offset().left;
3966+ that.offset.top = that.element.offset().top;
3967+ }
3968+
3969+ woset = Math.abs( that.sizeDiff.width +
3970+ (that._helper ?
3971+ that.offset.left - cop.left :
3972+ (that.offset.left - co.left)) );
3973+
3974+ hoset = Math.abs( that.sizeDiff.height +
3975+ (that._helper ?
3976+ that.offset.top - cop.top :
3977+ (that.offset.top - co.top)) );
3978+
3979+ if ( woset + that.size.width >= that.parentData.width ) {
3980+ that.size.width = that.parentData.width - woset;
3981+ if ( pRatio ) {
3982+ that.size.height = that.size.width / that.aspectRatio;
3983+ continueResize = false;
3984+ }
3985+ }
3986+
3987+ if ( hoset + that.size.height >= that.parentData.height ) {
3988+ that.size.height = that.parentData.height - hoset;
3989+ if ( pRatio ) {
3990+ that.size.width = that.size.height * that.aspectRatio;
3991+ continueResize = false;
3992+ }
3993+ }
3994+
3995+ if ( !continueResize ) {
3996+ that.position.left = that.prevPosition.left;
3997+ that.position.top = that.prevPosition.top;
3998+ that.size.width = that.prevSize.width;
3999+ that.size.height = that.prevSize.height;
4000+ }
4001+ },
4002+
4003+ stop: function() {
4004+ var that = $( this ).resizable( "instance" ),
4005+ o = that.options,
4006+ co = that.containerOffset,
4007+ cop = that.containerPosition,
4008+ ce = that.containerElement,
4009+ helper = $( that.helper ),
4010+ ho = helper.offset(),
4011+ w = helper.outerWidth() - that.sizeDiff.width,
4012+ h = helper.outerHeight() - that.sizeDiff.height;
4013+
4014+ if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4015+ $( this ).css({
4016+ left: ho.left - cop.left - co.left,
4017+ width: w,
4018+ height: h
4019+ });
4020+ }
4021+
4022+ if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4023+ $( this ).css({
4024+ left: ho.left - cop.left - co.left,
4025+ width: w,
4026+ height: h
4027+ });
4028+ }
4029+ }
4030+});
4031+
4032+$.ui.plugin.add("resizable", "alsoResize", {
4033+
4034+ start: function() {
4035+ var that = $(this).resizable( "instance" ),
4036+ o = that.options;
4037+
4038+ $(o.alsoResize).each(function() {
4039+ var el = $(this);
4040+ el.data("ui-resizable-alsoresize", {
4041+ width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4042+ left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4043+ });
4044+ });
4045+ },
4046+
4047+ resize: function(event, ui) {
4048+ var that = $(this).resizable( "instance" ),
4049+ o = that.options,
4050+ os = that.originalSize,
4051+ op = that.originalPosition,
4052+ delta = {
4053+ height: (that.size.height - os.height) || 0,
4054+ width: (that.size.width - os.width) || 0,
4055+ top: (that.position.top - op.top) || 0,
4056+ left: (that.position.left - op.left) || 0
4057+ };
4058+
4059+ $(o.alsoResize).each(function() {
4060+ var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4061+ css = el.parents(ui.originalElement[0]).length ?
4062+ [ "width", "height" ] :
4063+ [ "width", "height", "top", "left" ];
4064+
4065+ $.each(css, function(i, prop) {
4066+ var sum = (start[prop] || 0) + (delta[prop] || 0);
4067+ if (sum && sum >= 0) {
4068+ style[prop] = sum || null;
4069+ }
4070+ });
4071+
4072+ el.css(style);
4073+ });
4074+ },
4075+
4076+ stop: function() {
4077+ $(this).removeData("resizable-alsoresize");
4078+ }
4079+});
4080+
4081+$.ui.plugin.add("resizable", "ghost", {
4082+
4083+ start: function() {
4084+
4085+ var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4086+
4087+ that.ghost = that.originalElement.clone();
4088+ that.ghost
4089+ .css({
4090+ opacity: 0.25,
4091+ display: "block",
4092+ position: "relative",
4093+ height: cs.height,
4094+ width: cs.width,
4095+ margin: 0,
4096+ left: 0,
4097+ top: 0
4098+ })
4099+ .addClass("ui-resizable-ghost")
4100+ .addClass(typeof o.ghost === "string" ? o.ghost : "");
4101+
4102+ that.ghost.appendTo(that.helper);
4103+
4104+ },
4105+
4106+ resize: function() {
4107+ var that = $(this).resizable( "instance" );
4108+ if (that.ghost) {
4109+ that.ghost.css({
4110+ position: "relative",
4111+ height: that.size.height,
4112+ width: that.size.width
4113+ });
4114+ }
4115+ },
4116+
4117+ stop: function() {
4118+ var that = $(this).resizable( "instance" );
4119+ if (that.ghost && that.helper) {
4120+ that.helper.get(0).removeChild(that.ghost.get(0));
4121+ }
4122+ }
4123+
4124+});
4125+
4126+$.ui.plugin.add("resizable", "grid", {
4127+
4128+ resize: function() {
4129+ var outerDimensions,
4130+ that = $(this).resizable( "instance" ),
4131+ o = that.options,
4132+ cs = that.size,
4133+ os = that.originalSize,
4134+ op = that.originalPosition,
4135+ a = that.axis,
4136+ grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4137+ gridX = (grid[0] || 1),
4138+ gridY = (grid[1] || 1),
4139+ ox = Math.round((cs.width - os.width) / gridX) * gridX,
4140+ oy = Math.round((cs.height - os.height) / gridY) * gridY,
4141+ newWidth = os.width + ox,
4142+ newHeight = os.height + oy,
4143+ isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4144+ isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4145+ isMinWidth = o.minWidth && (o.minWidth > newWidth),
4146+ isMinHeight = o.minHeight && (o.minHeight > newHeight);
4147+
4148+ o.grid = grid;
4149+
4150+ if (isMinWidth) {
4151+ newWidth += gridX;
4152+ }
4153+ if (isMinHeight) {
4154+ newHeight += gridY;
4155+ }
4156+ if (isMaxWidth) {
4157+ newWidth -= gridX;
4158+ }
4159+ if (isMaxHeight) {
4160+ newHeight -= gridY;
4161+ }
4162+
4163+ if (/^(se|s|e)$/.test(a)) {
4164+ that.size.width = newWidth;
4165+ that.size.height = newHeight;
4166+ } else if (/^(ne)$/.test(a)) {
4167+ that.size.width = newWidth;
4168+ that.size.height = newHeight;
4169+ that.position.top = op.top - oy;
4170+ } else if (/^(sw)$/.test(a)) {
4171+ that.size.width = newWidth;
4172+ that.size.height = newHeight;
4173+ that.position.left = op.left - ox;
4174+ } else {
4175+ if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4176+ outerDimensions = that._getPaddingPlusBorderDimensions( this );
4177+ }
4178+
4179+ if ( newHeight - gridY > 0 ) {
4180+ that.size.height = newHeight;
4181+ that.position.top = op.top - oy;
4182+ } else {
4183+ newHeight = gridY - outerDimensions.height;
4184+ that.size.height = newHeight;
4185+ that.position.top = op.top + os.height - newHeight;
4186+ }
4187+ if ( newWidth - gridX > 0 ) {
4188+ that.size.width = newWidth;
4189+ that.position.left = op.left - ox;
4190+ } else {
4191+ newWidth = gridX - outerDimensions.width;
4192+ that.size.width = newWidth;
4193+ that.position.left = op.left + os.width - newWidth;
4194+ }
4195+ }
4196+ }
4197+
4198+});
4199+
4200+var resizable = $.ui.resizable;
4201+
4202+
4203+/*!
4204+ * jQuery UI Selectable 1.11.4
4205+ * http://jqueryui.com
4206+ *
4207+ * Copyright jQuery Foundation and other contributors
4208+ * Released under the MIT license.
4209+ * http://jquery.org/license
4210+ *
4211+ * http://api.jqueryui.com/selectable/
4212+ */
4213+
4214+
4215+var selectable = $.widget("ui.selectable", $.ui.mouse, {
4216+ version: "1.11.4",
4217+ options: {
4218+ appendTo: "body",
4219+ autoRefresh: true,
4220+ distance: 0,
4221+ filter: "*",
4222+ tolerance: "touch",
4223+
4224+ // callbacks
4225+ selected: null,
4226+ selecting: null,
4227+ start: null,
4228+ stop: null,
4229+ unselected: null,
4230+ unselecting: null
4231+ },
4232+ _create: function() {
4233+ var selectees,
4234+ that = this;
4235+
4236+ this.element.addClass("ui-selectable");
4237+
4238+ this.dragged = false;
4239+
4240+ // cache selectee children based on filter
4241+ this.refresh = function() {
4242+ selectees = $(that.options.filter, that.element[0]);
4243+ selectees.addClass("ui-selectee");
4244+ selectees.each(function() {
4245+ var $this = $(this),
4246+ pos = $this.offset();
4247+ $.data(this, "selectable-item", {
4248+ element: this,
4249+ $element: $this,
4250+ left: pos.left,
4251+ top: pos.top,
4252+ right: pos.left + $this.outerWidth(),
4253+ bottom: pos.top + $this.outerHeight(),
4254+ startselected: false,
4255+ selected: $this.hasClass("ui-selected"),
4256+ selecting: $this.hasClass("ui-selecting"),
4257+ unselecting: $this.hasClass("ui-unselecting")
4258+ });
4259+ });
4260+ };
4261+ this.refresh();
4262+
4263+ this.selectees = selectees.addClass("ui-selectee");
4264+
4265+ this._mouseInit();
4266+
4267+ this.helper = $("<div class='ui-selectable-helper'></div>");
4268+ },
4269+
4270+ _destroy: function() {
4271+ this.selectees
4272+ .removeClass("ui-selectee")
4273+ .removeData("selectable-item");
4274+ this.element
4275+ .removeClass("ui-selectable ui-selectable-disabled");
4276+ this._mouseDestroy();
4277+ },
4278+
4279+ _mouseStart: function(event) {
4280+ var that = this,
4281+ options = this.options;
4282+
4283+ this.opos = [ event.pageX, event.pageY ];
4284+
4285+ if (this.options.disabled) {
4286+ return;
4287+ }
4288+
4289+ this.selectees = $(options.filter, this.element[0]);
4290+
4291+ this._trigger("start", event);
4292+
4293+ $(options.appendTo).append(this.helper);
4294+ // position helper (lasso)
4295+ this.helper.css({
4296+ "left": event.pageX,
4297+ "top": event.pageY,
4298+ "width": 0,
4299+ "height": 0
4300+ });
4301+
4302+ if (options.autoRefresh) {
4303+ this.refresh();
4304+ }
4305+
4306+ this.selectees.filter(".ui-selected").each(function() {
4307+ var selectee = $.data(this, "selectable-item");
4308+ selectee.startselected = true;
4309+ if (!event.metaKey && !event.ctrlKey) {
4310+ selectee.$element.removeClass("ui-selected");
4311+ selectee.selected = false;
4312+ selectee.$element.addClass("ui-unselecting");
4313+ selectee.unselecting = true;
4314+ // selectable UNSELECTING callback
4315+ that._trigger("unselecting", event, {
4316+ unselecting: selectee.element
4317+ });
4318+ }
4319+ });
4320+
4321+ $(event.target).parents().addBack().each(function() {
4322+ var doSelect,
4323+ selectee = $.data(this, "selectable-item");
4324+ if (selectee) {
4325+ doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4326+ selectee.$element
4327+ .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4328+ .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4329+ selectee.unselecting = !doSelect;
4330+ selectee.selecting = doSelect;
4331+ selectee.selected = doSelect;
4332+ // selectable (UN)SELECTING callback
4333+ if (doSelect) {
4334+ that._trigger("selecting", event, {
4335+ selecting: selectee.element
4336+ });
4337+ } else {
4338+ that._trigger("unselecting", event, {
4339+ unselecting: selectee.element
4340+ });
4341+ }
4342+ return false;
4343+ }
4344+ });
4345+
4346+ },
4347+
4348+ _mouseDrag: function(event) {
4349+
4350+ this.dragged = true;
4351+
4352+ if (this.options.disabled) {
4353+ return;
4354+ }
4355+
4356+ var tmp,
4357+ that = this,
4358+ options = this.options,
4359+ x1 = this.opos[0],
4360+ y1 = this.opos[1],
4361+ x2 = event.pageX,
4362+ y2 = event.pageY;
4363+
4364+ if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4365+ if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4366+ this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4367+
4368+ this.selectees.each(function() {
4369+ var selectee = $.data(this, "selectable-item"),
4370+ hit = false;
4371+
4372+ //prevent helper from being selected if appendTo: selectable
4373+ if (!selectee || selectee.element === that.element[0]) {
4374+ return;
4375+ }
4376+
4377+ if (options.tolerance === "touch") {
4378+ hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4379+ } else if (options.tolerance === "fit") {
4380+ hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4381+ }
4382+
4383+ if (hit) {
4384+ // SELECT
4385+ if (selectee.selected) {
4386+ selectee.$element.removeClass("ui-selected");
4387+ selectee.selected = false;
4388+ }
4389+ if (selectee.unselecting) {
4390+ selectee.$element.removeClass("ui-unselecting");
4391+ selectee.unselecting = false;
4392+ }
4393+ if (!selectee.selecting) {
4394+ selectee.$element.addClass("ui-selecting");
4395+ selectee.selecting = true;
4396+ // selectable SELECTING callback
4397+ that._trigger("selecting", event, {
4398+ selecting: selectee.element
4399+ });
4400+ }
4401+ } else {
4402+ // UNSELECT
4403+ if (selectee.selecting) {
4404+ if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4405+ selectee.$element.removeClass("ui-selecting");
4406+ selectee.selecting = false;
4407+ selectee.$element.addClass("ui-selected");
4408+ selectee.selected = true;
4409+ } else {
4410+ selectee.$element.removeClass("ui-selecting");
4411+ selectee.selecting = false;
4412+ if (selectee.startselected) {
4413+ selectee.$element.addClass("ui-unselecting");
4414+ selectee.unselecting = true;
4415+ }
4416+ // selectable UNSELECTING callback
4417+ that._trigger("unselecting", event, {
4418+ unselecting: selectee.element
4419+ });
4420+ }
4421+ }
4422+ if (selectee.selected) {
4423+ if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4424+ selectee.$element.removeClass("ui-selected");
4425+ selectee.selected = false;
4426+
4427+ selectee.$element.addClass("ui-unselecting");
4428+ selectee.unselecting = true;
4429+ // selectable UNSELECTING callback
4430+ that._trigger("unselecting", event, {
4431+ unselecting: selectee.element
4432+ });
4433+ }
4434+ }
4435+ }
4436+ });
4437+
4438+ return false;
4439+ },
4440+
4441+ _mouseStop: function(event) {
4442+ var that = this;
4443+
4444+ this.dragged = false;
4445+
4446+ $(".ui-unselecting", this.element[0]).each(function() {
4447+ var selectee = $.data(this, "selectable-item");
4448+ selectee.$element.removeClass("ui-unselecting");
4449+ selectee.unselecting = false;
4450+ selectee.startselected = false;
4451+ that._trigger("unselected", event, {
4452+ unselected: selectee.element
4453+ });
4454+ });
4455+ $(".ui-selecting", this.element[0]).each(function() {
4456+ var selectee = $.data(this, "selectable-item");
4457+ selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4458+ selectee.selecting = false;
4459+ selectee.selected = true;
4460+ selectee.startselected = true;
4461+ that._trigger("selected", event, {
4462+ selected: selectee.element
4463+ });
4464+ });
4465+ this._trigger("stop", event);
4466+
4467+ this.helper.remove();
4468+
4469+ return false;
4470+ }
4471+
4472+});
4473+
4474+
4475+/*!
4476+ * jQuery UI Sortable 1.11.4
4477+ * http://jqueryui.com
4478+ *
4479+ * Copyright jQuery Foundation and other contributors
4480+ * Released under the MIT license.
4481+ * http://jquery.org/license
4482+ *
4483+ * http://api.jqueryui.com/sortable/
4484+ */
4485+
4486+
4487+var sortable = $.widget("ui.sortable", $.ui.mouse, {
4488+ version: "1.11.4",
4489+ widgetEventPrefix: "sort",
4490+ ready: false,
4491+ options: {
4492+ appendTo: "parent",
4493+ axis: false,
4494+ connectWith: false,
4495+ containment: false,
4496+ cursor: "auto",
4497+ cursorAt: false,
4498+ dropOnEmpty: true,
4499+ forcePlaceholderSize: false,
4500+ forceHelperSize: false,
4501+ grid: false,
4502+ handle: false,
4503+ helper: "original",
4504+ items: "> *",
4505+ opacity: false,
4506+ placeholder: false,
4507+ revert: false,
4508+ scroll: true,
4509+ scrollSensitivity: 20,
4510+ scrollSpeed: 20,
4511+ scope: "default",
4512+ tolerance: "intersect",
4513+ zIndex: 1000,
4514+
4515+ // callbacks
4516+ activate: null,
4517+ beforeStop: null,
4518+ change: null,
4519+ deactivate: null,
4520+ out: null,
4521+ over: null,
4522+ receive: null,
4523+ remove: null,
4524+ sort: null,
4525+ start: null,
4526+ stop: null,
4527+ update: null
4528+ },
4529+
4530+ _isOverAxis: function( x, reference, size ) {
4531+ return ( x >= reference ) && ( x < ( reference + size ) );
4532+ },
4533+
4534+ _isFloating: function( item ) {
4535+ return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4536+ },
4537+
4538+ _create: function() {
4539+ this.containerCache = {};
4540+ this.element.addClass("ui-sortable");
4541+
4542+ //Get the items
4543+ this.refresh();
4544+
4545+ //Let's determine the parent's offset
4546+ this.offset = this.element.offset();
4547+
4548+ //Initialize mouse events for interaction
4549+ this._mouseInit();
4550+
4551+ this._setHandleClassName();
4552+
4553+ //We're ready to go
4554+ this.ready = true;
4555+
4556+ },
4557+
4558+ _setOption: function( key, value ) {
4559+ this._super( key, value );
4560+
4561+ if ( key === "handle" ) {
4562+ this._setHandleClassName();
4563+ }
4564+ },
4565+
4566+ _setHandleClassName: function() {
4567+ this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4568+ $.each( this.items, function() {
4569+ ( this.instance.options.handle ?
4570+ this.item.find( this.instance.options.handle ) : this.item )
4571+ .addClass( "ui-sortable-handle" );
4572+ });
4573+ },
4574+
4575+ _destroy: function() {
4576+ this.element
4577+ .removeClass( "ui-sortable ui-sortable-disabled" )
4578+ .find( ".ui-sortable-handle" )
4579+ .removeClass( "ui-sortable-handle" );
4580+ this._mouseDestroy();
4581+
4582+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
4583+ this.items[i].item.removeData(this.widgetName + "-item");
4584+ }
4585+
4586+ return this;
4587+ },
4588+
4589+ _mouseCapture: function(event, overrideHandle) {
4590+ var currentItem = null,
4591+ validHandle = false,
4592+ that = this;
4593+
4594+ if (this.reverting) {
4595+ return false;
4596+ }
4597+
4598+ if(this.options.disabled || this.options.type === "static") {
4599+ return false;
4600+ }
4601+
4602+ //We have to refresh the items data once first
4603+ this._refreshItems(event);
4604+
4605+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
4606+ $(event.target).parents().each(function() {
4607+ if($.data(this, that.widgetName + "-item") === that) {
4608+ currentItem = $(this);
4609+ return false;
4610+ }
4611+ });
4612+ if($.data(event.target, that.widgetName + "-item") === that) {
4613+ currentItem = $(event.target);
4614+ }
4615+
4616+ if(!currentItem) {
4617+ return false;
4618+ }
4619+ if(this.options.handle && !overrideHandle) {
4620+ $(this.options.handle, currentItem).find("*").addBack().each(function() {
4621+ if(this === event.target) {
4622+ validHandle = true;
4623+ }
4624+ });
4625+ if(!validHandle) {
4626+ return false;
4627+ }
4628+ }
4629+
4630+ this.currentItem = currentItem;
4631+ this._removeCurrentsFromItems();
4632+ return true;
4633+
4634+ },
4635+
4636+ _mouseStart: function(event, overrideHandle, noActivation) {
4637+
4638+ var i, body,
4639+ o = this.options;
4640+
4641+ this.currentContainer = this;
4642+
4643+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4644+ this.refreshPositions();
4645+
4646+ //Create and append the visible helper
4647+ this.helper = this._createHelper(event);
4648+
4649+ //Cache the helper size
4650+ this._cacheHelperProportions();
4651+
4652+ /*
4653+ * - Position generation -
4654+ * This block generates everything position related - it's the core of draggables.
4655+ */
4656+
4657+ //Cache the margins of the original element
4658+ this._cacheMargins();
4659+
4660+ //Get the next scrolling parent
4661+ this.scrollParent = this.helper.scrollParent();
4662+
4663+ //The element's absolute position on the page minus margins
4664+ this.offset = this.currentItem.offset();
4665+ this.offset = {
4666+ top: this.offset.top - this.margins.top,
4667+ left: this.offset.left - this.margins.left
4668+ };
4669+
4670+ $.extend(this.offset, {
4671+ click: { //Where the click happened, relative to the element
4672+ left: event.pageX - this.offset.left,
4673+ top: event.pageY - this.offset.top
4674+ },
4675+ parent: this._getParentOffset(),
4676+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4677+ });
4678+
4679+ // Only after we got the offset, we can change the helper's position to absolute
4680+ // TODO: Still need to figure out a way to make relative sorting possible
4681+ this.helper.css("position", "absolute");
4682+ this.cssPosition = this.helper.css("position");
4683+
4684+ //Generate the original position
4685+ this.originalPosition = this._generatePosition(event);
4686+ this.originalPageX = event.pageX;
4687+ this.originalPageY = event.pageY;
4688+
4689+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4690+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4691+
4692+ //Cache the former DOM position
4693+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4694+
4695+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
4696+ if(this.helper[0] !== this.currentItem[0]) {
4697+ this.currentItem.hide();
4698+ }
4699+
4700+ //Create the placeholder
4701+ this._createPlaceholder();
4702+
4703+ //Set a containment if given in the options
4704+ if(o.containment) {
4705+ this._setContainment();
4706+ }
4707+
4708+ if( o.cursor && o.cursor !== "auto" ) { // cursor option
4709+ body = this.document.find( "body" );
4710+
4711+ // support: IE
4712+ this.storedCursor = body.css( "cursor" );
4713+ body.css( "cursor", o.cursor );
4714+
4715+ this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4716+ }
4717+
4718+ if(o.opacity) { // opacity option
4719+ if (this.helper.css("opacity")) {
4720+ this._storedOpacity = this.helper.css("opacity");
4721+ }
4722+ this.helper.css("opacity", o.opacity);
4723+ }
4724+
4725+ if(o.zIndex) { // zIndex option
4726+ if (this.helper.css("zIndex")) {
4727+ this._storedZIndex = this.helper.css("zIndex");
4728+ }
4729+ this.helper.css("zIndex", o.zIndex);
4730+ }
4731+
4732+ //Prepare scrolling
4733+ if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4734+ this.overflowOffset = this.scrollParent.offset();
4735+ }
4736+
4737+ //Call callbacks
4738+ this._trigger("start", event, this._uiHash());
4739+
4740+ //Recache the helper size
4741+ if(!this._preserveHelperProportions) {
4742+ this._cacheHelperProportions();
4743+ }
4744+
4745+
4746+ //Post "activate" events to possible containers
4747+ if( !noActivation ) {
4748+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
4749+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4750+ }
4751+ }
4752+
4753+ //Prepare possible droppables
4754+ if($.ui.ddmanager) {
4755+ $.ui.ddmanager.current = this;
4756+ }
4757+
4758+ if ($.ui.ddmanager && !o.dropBehaviour) {
4759+ $.ui.ddmanager.prepareOffsets(this, event);
4760+ }
4761+
4762+ this.dragging = true;
4763+
4764+ this.helper.addClass("ui-sortable-helper");
4765+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4766+ return true;
4767+
4768+ },
4769+
4770+ _mouseDrag: function(event) {
4771+ var i, item, itemElement, intersection,
4772+ o = this.options,
4773+ scrolled = false;
4774+
4775+ //Compute the helpers position
4776+ this.position = this._generatePosition(event);
4777+ this.positionAbs = this._convertPositionTo("absolute");
4778+
4779+ if (!this.lastPositionAbs) {
4780+ this.lastPositionAbs = this.positionAbs;
4781+ }
4782+
4783+ //Do scrolling
4784+ if(this.options.scroll) {
4785+ if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4786+
4787+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4788+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4789+ } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4790+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4791+ }
4792+
4793+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4794+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4795+ } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4796+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4797+ }
4798+
4799+ } else {
4800+
4801+ if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4802+ scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4803+ } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4804+ scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4805+ }
4806+
4807+ if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4808+ scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4809+ } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4810+ scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4811+ }
4812+
4813+ }
4814+
4815+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4816+ $.ui.ddmanager.prepareOffsets(this, event);
4817+ }
4818+ }
4819+
4820+ //Regenerate the absolute position used for position checks
4821+ this.positionAbs = this._convertPositionTo("absolute");
4822+
4823+ //Set the helper position
4824+ if(!this.options.axis || this.options.axis !== "y") {
4825+ this.helper[0].style.left = this.position.left+"px";
4826+ }
4827+ if(!this.options.axis || this.options.axis !== "x") {
4828+ this.helper[0].style.top = this.position.top+"px";
4829+ }
4830+
4831+ //Rearrange
4832+ for (i = this.items.length - 1; i >= 0; i--) {
4833+
4834+ //Cache variables and intersection, continue if no intersection
4835+ item = this.items[i];
4836+ itemElement = item.item[0];
4837+ intersection = this._intersectsWithPointer(item);
4838+ if (!intersection) {
4839+ continue;
4840+ }
4841+
4842+ // Only put the placeholder inside the current Container, skip all
4843+ // items from other containers. This works because when moving
4844+ // an item from one container to another the
4845+ // currentContainer is switched before the placeholder is moved.
4846+ //
4847+ // Without this, moving items in "sub-sortables" can cause
4848+ // the placeholder to jitter between the outer and inner container.
4849+ if (item.instance !== this.currentContainer) {
4850+ continue;
4851+ }
4852+
4853+ // cannot intersect with itself
4854+ // no useless actions that have been done before
4855+ // no action if the item moved is the parent of the item checked
4856+ if (itemElement !== this.currentItem[0] &&
4857+ this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4858+ !$.contains(this.placeholder[0], itemElement) &&
4859+ (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4860+ ) {
4861+
4862+ this.direction = intersection === 1 ? "down" : "up";
4863+
4864+ if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4865+ this._rearrange(event, item);
4866+ } else {
4867+ break;
4868+ }
4869+
4870+ this._trigger("change", event, this._uiHash());
4871+ break;
4872+ }
4873+ }
4874+
4875+ //Post events to containers
4876+ this._contactContainers(event);
4877+
4878+ //Interconnect with droppables
4879+ if($.ui.ddmanager) {
4880+ $.ui.ddmanager.drag(this, event);
4881+ }
4882+
4883+ //Call callbacks
4884+ this._trigger("sort", event, this._uiHash());
4885+
4886+ this.lastPositionAbs = this.positionAbs;
4887+ return false;
4888+
4889+ },
4890+
4891+ _mouseStop: function(event, noPropagation) {
4892+
4893+ if(!event) {
4894+ return;
4895+ }
4896+
4897+ //If we are using droppables, inform the manager about the drop
4898+ if ($.ui.ddmanager && !this.options.dropBehaviour) {
4899+ $.ui.ddmanager.drop(this, event);
4900+ }
4901+
4902+ if(this.options.revert) {
4903+ var that = this,
4904+ cur = this.placeholder.offset(),
4905+ axis = this.options.axis,
4906+ animation = {};
4907+
4908+ if ( !axis || axis === "x" ) {
4909+ animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4910+ }
4911+ if ( !axis || axis === "y" ) {
4912+ animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4913+ }
4914+ this.reverting = true;
4915+ $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4916+ that._clear(event);
4917+ });
4918+ } else {
4919+ this._clear(event, noPropagation);
4920+ }
4921+
4922+ return false;
4923+
4924+ },
4925+
4926+ cancel: function() {
4927+
4928+ if(this.dragging) {
4929+
4930+ this._mouseUp({ target: null });
4931+
4932+ if(this.options.helper === "original") {
4933+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4934+ } else {
4935+ this.currentItem.show();
4936+ }
4937+
4938+ //Post deactivating events to containers
4939+ for (var i = this.containers.length - 1; i >= 0; i--){
4940+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4941+ if(this.containers[i].containerCache.over) {
4942+ this.containers[i]._trigger("out", null, this._uiHash(this));
4943+ this.containers[i].containerCache.over = 0;
4944+ }
4945+ }
4946+
4947+ }
4948+
4949+ if (this.placeholder) {
4950+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4951+ if(this.placeholder[0].parentNode) {
4952+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4953+ }
4954+ if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4955+ this.helper.remove();
4956+ }
4957+
4958+ $.extend(this, {
4959+ helper: null,
4960+ dragging: false,
4961+ reverting: false,
4962+ _noFinalSort: null
4963+ });
4964+
4965+ if(this.domPosition.prev) {
4966+ $(this.domPosition.prev).after(this.currentItem);
4967+ } else {
4968+ $(this.domPosition.parent).prepend(this.currentItem);
4969+ }
4970+ }
4971+
4972+ return this;
4973+
4974+ },
4975+
4976+ serialize: function(o) {
4977+
4978+ var items = this._getItemsAsjQuery(o && o.connected),
4979+ str = [];
4980+ o = o || {};
4981+
4982+ $(items).each(function() {
4983+ var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4984+ if (res) {
4985+ str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4986+ }
4987+ });
4988+
4989+ if(!str.length && o.key) {
4990+ str.push(o.key + "=");
4991+ }
4992+
4993+ return str.join("&");
4994+
4995+ },
4996+
4997+ toArray: function(o) {
4998+
4999+ var items = this._getItemsAsjQuery(o && o.connected),

11618 more lines aren’t shown here.

Source/Libraries/GSF.Web/Shared/Scripts/primeui.js+13963−0
@@ -0,0 +1,13963 @@
1+/**
2+ * PUI Object
3+ */
4+var PUI = {
5+
6+ zindex : 1000,
7+
8+ gridColumns: {
9+ '1': 'ui-grid-col-12',
10+ '2': 'ui-grid-col-6',
11+ '3': 'ui-grid-col-4',
12+ '4': 'ui-grid-col-3',
13+ '6': 'ui-grid-col-2',
14+ '12': 'ui-grid-col-11'
15+ },
16+
17+ charSet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
18+
19+ /**
20+ * Aligns container scrollbar to keep item in container viewport, algorithm copied from jquery-ui menu widget
21+ */
22+ scrollInView: function(container, item) {
23+ var borderTop = parseFloat(container.css('borderTopWidth')) || 0,
24+ paddingTop = parseFloat(container.css('paddingTop')) || 0,
25+ offset = item.offset().top - container.offset().top - borderTop - paddingTop,
26+ scroll = container.scrollTop(),
27+ elementHeight = container.height(),
28+ itemHeight = item.outerHeight(true);
29+
30+ if(offset < 0) {
31+ container.scrollTop(scroll + offset);
32+ }
33+ else if((offset + itemHeight) > elementHeight) {
34+ container.scrollTop(scroll + offset - elementHeight + itemHeight);
35+ }
36+ },
37+
38+ generateRandomId: function() {
39+ var id = '';
40+ for (var i = 1; i <= 10; i++) {
41+ var randPos = Math.floor(Math.random() * this.charSet.length);
42+ id += this.charSet[randPos];
43+ }
44+ return id;
45+ },
46+
47+ isIE: function(version) {
48+ return (this.browser.msie && parseInt(this.browser.version, 10) === version);
49+ },
50+
51+ escapeRegExp: function(text) {
52+ return text.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
53+ },
54+
55+ escapeHTML: function(value) {
56+ return value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
57+ },
58+
59+ escapeClientId: function(id) {
60+ return "#" + id.replace(/:/g,"\\:");
61+ },
62+
63+ clearSelection: function() {
64+ if(window.getSelection) {
65+ if(window.getSelection().empty) {
66+ window.getSelection().empty();
67+ } else if(window.getSelection().removeAllRanges) {
68+ window.getSelection().removeAllRanges();
69+ }
70+ } else if(document.selection && document.selection.empty) {
71+ document.selection.empty();
72+ }
73+ },
74+
75+ inArray: function(arr, item) {
76+ for(var i = 0; i < arr.length; i++) {
77+ if(arr[i] === item) {
78+ return true;
79+ }
80+ }
81+
82+ return false;
83+ },
84+
85+ calculateScrollbarWidth: function() {
86+ if(!this.scrollbarWidth) {
87+ if(this.browser.msie) {
88+ var $textarea1 = $('<textarea cols="10" rows="2"></textarea>')
89+ .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body'),
90+ $textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>')
91+ .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body');
92+ this.scrollbarWidth = $textarea1.width() - $textarea2.width();
93+ $textarea1.add($textarea2).remove();
94+ }
95+ else {
96+ var $div = $('<div />')
97+ .css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
98+ .prependTo('body').append('<div />').find('div')
99+ .css({ width: '100%', height: 200 });
100+ this.scrollbarWidth = 100 - $div.width();
101+ $div.parent().remove();
102+ }
103+ }
104+
105+ return this.scrollbarWidth;
106+ },
107+
108+ //adapted from jquery browser plugin
109+ resolveUserAgent: function() {
110+ var matched, browser;
111+
112+ jQuery.uaMatch = function( ua ) {
113+ ua = ua.toLowerCase();
114+
115+ var match = /(opr)[\/]([\w.]+)/.exec( ua ) ||
116+ /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
117+ /(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
118+ /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
119+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
120+ /(msie) ([\w.]+)/.exec( ua ) ||
121+ ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) ||
122+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
123+ [];
124+
125+ var platform_match = /(ipad)/.exec( ua ) ||
126+ /(iphone)/.exec( ua ) ||
127+ /(android)/.exec( ua ) ||
128+ /(windows phone)/.exec( ua ) ||
129+ /(win)/.exec( ua ) ||
130+ /(mac)/.exec( ua ) ||
131+ /(linux)/.exec( ua ) ||
132+ /(cros)/i.exec( ua ) ||
133+ [];
134+
135+ return {
136+ browser: match[ 3 ] || match[ 1 ] || "",
137+ version: match[ 2 ] || "0",
138+ platform: platform_match[ 0 ] || ""
139+ };
140+ };
141+
142+ matched = jQuery.uaMatch( window.navigator.userAgent );
143+ browser = {};
144+
145+ if ( matched.browser ) {
146+ browser[ matched.browser ] = true;
147+ browser.version = matched.version;
148+ browser.versionNumber = parseInt(matched.version);
149+ }
150+
151+ if ( matched.platform ) {
152+ browser[ matched.platform ] = true;
153+ }
154+
155+ // These are all considered mobile platforms, meaning they run a mobile browser
156+ if ( browser.android || browser.ipad || browser.iphone || browser[ "windows phone" ] ) {
157+ browser.mobile = true;
158+ }
159+
160+ // These are all considered desktop platforms, meaning they run a desktop browser
161+ if ( browser.cros || browser.mac || browser.linux || browser.win ) {
162+ browser.desktop = true;
163+ }
164+
165+ // Chrome, Opera 15+ and Safari are webkit based browsers
166+ if ( browser.chrome || browser.opr || browser.safari ) {
167+ browser.webkit = true;
168+ }
169+
170+ // IE11 has a new token so we will assign it msie to avoid breaking changes
171+ if ( browser.rv )
172+ {
173+ var ie = "msie";
174+
175+ matched.browser = ie;
176+ browser[ie] = true;
177+ }
178+
179+ // Opera 15+ are identified as opr
180+ if ( browser.opr )
181+ {
182+ var opera = "opera";
183+
184+ matched.browser = opera;
185+ browser[opera] = true;
186+ }
187+
188+ // Stock Android browsers are marked as Safari on Android.
189+ if ( browser.safari && browser.android )
190+ {
191+ var android = "android";
192+
193+ matched.browser = android;
194+ browser[android] = true;
195+ }
196+
197+ // Assign the name and platform variable
198+ browser.name = matched.browser;
199+ browser.platform = matched.platform;
200+
201+ this.browser = browser;
202+ $.browser = browser;
203+ },
204+
205+ getGridColumn: function(number) {
206+ return this.gridColumns[number + ''];
207+ },
208+
209+ executeFunctionByName: function(functionName /*, args */) {
210+ var args = [].slice.call(arguments).splice(1),
211+ context = window,
212+ namespaces = functionName.split("."),
213+ func = namespaces.pop();
214+ for(var i = 0; i < namespaces.length; i++) {
215+ context = context[namespaces[i]];
216+ }
217+ return context[func].apply(this, args);
218+ },
219+
220+ resolveObjectByName: function(name) {
221+ if(name) {
222+ var parts = name.split(".");
223+ for(var i = 0, len = parts.length, obj = window; i < len; ++i) {
224+ obj = obj[parts[i]];
225+ }
226+ return obj;
227+ }
228+ else {
229+ return null;
230+ }
231+ },
232+
233+ getCookie : function(name) {
234+ return $.cookie(name);
235+ },
236+
237+ setCookie : function(name, value, cfg) {
238+ $.cookie(name, value, cfg);
239+ },
240+
241+ deleteCookie: function(name, cfg) {
242+ $.removeCookie(name, cfg);
243+ }
244+
245+};
246+
247+PUI.resolveUserAgent();
248+/**
249+ * PrimeUI Accordion widget
250+ */
251+(function() {
252+
253+ $.widget("primeui.puiaccordion", {
254+
255+ options: {
256+ activeIndex: 0,
257+ multiple: false
258+ },
259+
260+ _create: function() {
261+ if(this.options.multiple) {
262+ this.options.activeIndex = this.options.activeIndex||[0];
263+ }
264+
265+ var $this = this;
266+ this.element.addClass('ui-accordion ui-widget ui-helper-reset');
267+
268+ var tabContainers = this.element.children();
269+
270+ //primeui
271+ if(tabContainers.is('div')) {
272+ this.panelMode = 'native';
273+ this.headers = this.element.children('h3');
274+ this.panels = this.element.children('div');
275+ }
276+ //primeng
277+ else {
278+ this.panelMode = 'wrapped';
279+ this.headers = tabContainers.children('h3');
280+ this.panels = tabContainers.children('div');
281+ }
282+
283+ this.headers.addClass('ui-accordion-header ui-helper-reset ui-state-default').each(function(i) {
284+ var header = $(this),
285+ title = header.html(),
286+ active = $this.options.multiple ? ($.inArray(i, $this.options.activeIndex) !== -1) : (i == $this.options.activeIndex),
287+ headerClass = (active) ? 'ui-state-active ui-corner-top' : 'ui-corner-all',
288+ iconClass = (active) ? 'fa fa-fw fa-caret-down' : 'fa fa-fw fa-caret-right';
289+
290+ header.addClass(headerClass).html('<span class="' + iconClass + '"></span><a href="#">' + title + '</a>');
291+ });
292+
293+ this.panels.each(function(i) {
294+ var content = $(this);
295+ content.addClass('ui-accordion-content ui-helper-reset ui-widget-content'),
296+ active = $this.options.multiple ? ($.inArray(i, $this.options.activeIndex) !== -1) : (i == $this.options.activeIndex);
297+
298+ if(!active) {
299+ content.addClass('ui-helper-hidden');
300+ }
301+ });
302+
303+ this.headers.children('a').disableSelection();
304+
305+ this._bindEvents();
306+ },
307+
308+ _destroy: function() {
309+ this._unbindEvents();
310+ this.element.removeClass('ui-accordion ui-widget ui-helper-reset');
311+ this.headers.removeClass('ui-accordion-header ui-helper-reset ui-state-default ui-state-hover ui-state-active ui-state-disabled ui-corner-all ui-corner-top');
312+ this.panels.removeClass('ui-accordion-content ui-helper-reset ui-widget-content ui-helper-hidden');
313+ this.headers.children('.fa').remove();
314+ this.headers.children('a').contents().unwrap();
315+ },
316+
317+ _bindEvents: function() {
318+ var $this = this;
319+
320+ this.headers.on('mouseover.puiaccordion', function() {
321+ var element = $(this);
322+ if(!element.hasClass('ui-state-active')&&!element.hasClass('ui-state-disabled')) {
323+ element.addClass('ui-state-hover');
324+ }
325+ }).on('mouseout.puiaccordion', function() {
326+ var element = $(this);
327+ if(!element.hasClass('ui-state-active')&&!element.hasClass('ui-state-disabled')) {
328+ element.removeClass('ui-state-hover');
329+ }
330+ }).on('click.puiaccordion', function(e) {
331+ var element = $(this);
332+ if(!element.hasClass('ui-state-disabled')) {
333+ var tabIndex = ($this.panelMode === 'native') ? element.index() / 2 : element.parent().index();
334+
335+ if(element.hasClass('ui-state-active')) {
336+ $this.unselect(tabIndex);
337+ }
338+ else {
339+ $this.select(tabIndex, false);
340+ }
341+ }
342+
343+ e.preventDefault();
344+ });
345+ },
346+
347+ _unbindEvents: function() {
348+ this.headers.off('mouseover.puiaccordion mouseout.puiaccordion click.puiaccordion');
349+ },
350+
351+ /**
352+ * Activates a tab with given index
353+ */
354+ select: function(index, silent) {
355+ var panel = this.panels.eq(index);
356+
357+ if(!silent) {
358+ this._trigger('change', null, {'index': index});
359+ }
360+
361+ //update state
362+ if(this.options.multiple) {
363+ this._addToSelection(index);
364+ }
365+ else {
366+ this.options.activeIndex = index;
367+ }
368+ this._show(panel);
369+ },
370+
371+ /**
372+ * Deactivates a tab with given index
373+ */
374+ unselect: function(index) {
375+ var panel = this.panels.eq(index),
376+ header = panel.prev();
377+
378+ header.attr('aria-expanded', false).children('.fa').removeClass('fa-caret-down').addClass('fa-caret-right');
379+ header.removeClass('ui-state-active ui-corner-top').addClass('ui-corner-all');
380+ panel.attr('aria-hidden', true).slideUp();
381+
382+ this._removeFromSelection(index);
383+ },
384+
385+ _show: function(panel) {
386+ //deactivate current
387+ if(!this.options.multiple) {
388+ var oldHeader = this.headers.filter('.ui-state-active');
389+ oldHeader.children('.fa').removeClass('fa-caret-down').addClass('fa-caret-right');
390+ oldHeader.attr('aria-expanded', false).removeClass('ui-state-active ui-corner-top').addClass('ui-corner-all').next().attr('aria-hidden', true).slideUp();
391+ }
392+
393+ //activate selected
394+ var newHeader = panel.prev();
395+ newHeader.attr('aria-expanded', true).addClass('ui-state-active ui-corner-top').removeClass('ui-state-hover ui-corner-all')
396+ .children('.fa').removeClass('fa-caret-right').addClass('fa-caret-down');
397+
398+ panel.attr('aria-hidden', false).slideDown('normal');
399+ },
400+
401+ _addToSelection: function(nodeId) {
402+ this.options.activeIndex.push(nodeId);
403+ },
404+
405+ _removeFromSelection: function(index) {
406+ this.options.activeIndex = $.grep(this.options.activeIndex, function(r) {
407+ return r != index;
408+ });
409+ },
410+
411+ _setOption: function(key, value) {
412+ if(key === 'activeIndex') {
413+ this.select(value, true);
414+ }
415+ else {
416+ $.Widget.prototype._setOption.apply(this, arguments);
417+ }
418+ }
419+
420+ });
421+})();
422+/**
423+ * PrimeUI autocomplete widget
424+ */
425+(function() {
426+
427+ $.widget("primeui.puiautocomplete", {
428+
429+ options: {
430+ delay: 300,
431+ minQueryLength: 1,
432+ multiple: false,
433+ dropdown: false,
434+ scrollHeight: 200,
435+ forceSelection: false,
436+ effect:null,
437+ effectOptions: {},
438+ effectSpeed: 'normal',
439+ content: null,
440+ caseSensitive: false
441+ },
442+
443+ _create: function() {
444+ this.element.wrap('<span class="ui-autocomplete ui-widget" />');
445+ this.element.puiinputtext();
446+ this.panel = $('<div class="ui-autocomplete-panel ui-widget-content ui-corner-all ui-helper-hidden ui-shadow"></div>').appendTo('body');
447+
448+ if(this.options.multiple) {
449+ this.element.wrap('<ul class="ui-autocomplete-multiple ui-widget ui-inputtext ui-state-default ui-corner-all">' +
450+ '<li class="ui-autocomplete-input-token"></li></ul>');
451+ this.inputContainer = this.element.parent();
452+ this.multiContainer = this.inputContainer.parent();
453+ }
454+ else {
455+ if(this.options.dropdown) {
456+ this.dropdown = $('<button type="button" class="ui-autocomplete-dropdown ui-button ui-widget ui-state-default ui-corner-right ui-button-icon-only">' +
457+ '<span class="fa fa-fw fa-caret-down"></span><span class="ui-button-text">&nbsp;</span></button>')
458+ .insertAfter(this.element);
459+ this.element.removeClass('ui-corner-all').addClass('ui-corner-left');
460+ }
461+ }
462+
463+ this._bindEvents();
464+ },
465+
466+ _bindEvents: function() {
467+ var $this = this;
468+
469+ this._bindKeyEvents();
470+
471+ if(this.options.dropdown) {
472+ this.dropdown.on('mouseenter.puiautocomplete', function() {
473+ if(!$this.element.prop('disabled')) {
474+ $this.dropdown.addClass('ui-state-hover');
475+ }
476+ })
477+ .on('mouseleave.puiautocomplete', function() {
478+ $this.dropdown.removeClass('ui-state-hover');
479+ })
480+ .on('mousedown.puiautocomplete', function() {
481+ if(!$this.element.prop('disabled')) {
482+ $this.dropdown.addClass('ui-state-active');
483+ }
484+ })
485+ .on('mouseup.puiautocomplete', function() {
486+ if(!$this.element.prop('disabled')) {
487+ $this.dropdown.removeClass('ui-state-active');
488+ $this.search('');
489+ $this.element.focus();
490+ }
491+ })
492+ .on('focus.puiautocomplete', function() {
493+ $this.dropdown.addClass('ui-state-focus');
494+ })
495+ .on('blur.puiautocomplete', function() {
496+ $this.dropdown.removeClass('ui-state-focus');
497+ })
498+ .on('keydown.puiautocomplete', function(e) {
499+ var keyCode = $.ui.keyCode;
500+
501+ if(e.which == keyCode.ENTER || e.which == keyCode.NUMPAD_ENTER) {
502+ $this.search('');
503+ $this.input.focus();
504+
505+ e.preventDefault();
506+ }
507+ });
508+ }
509+
510+ if(this.options.multiple) {
511+ this.multiContainer.on('hover.puiautocomplete', function() {
512+ $(this).toggleClass('ui-state-hover');
513+ })
514+ .on('click.puiautocomplete', function() {
515+ $this.element.trigger('focus');
516+ });
517+
518+ this.element.on('focus.ui-autocomplete', function() {
519+ $this.multiContainer.addClass('ui-state-focus');
520+ })
521+ .on('blur.ui-autocomplete', function(e) {
522+ $this.multiContainer.removeClass('ui-state-focus');
523+ });
524+ }
525+
526+ if(this.options.forceSelection) {
527+ this.currentItems = [this.element.val()];
528+
529+ this.element.on('blur.puiautocomplete', function() {
530+ var value = $(this).val(),
531+ valid = false;
532+
533+ for(var i = 0; i < $this.currentItems.length; i++) {
534+ if($this.currentItems[i] === value) {
535+ valid = true;
536+ break;
537+ }
538+ }
539+
540+ if(!valid) {
541+ $this.element.val('');
542+ }
543+ });
544+ }
545+
546+ $(document.body).bind('mousedown.puiautocomplete', function (e) {
547+ if($this.panel.is(":hidden")) {
548+ return;
549+ }
550+
551+ if(e.target === $this.element.get(0)) {
552+ return;
553+ }
554+
555+ var offset = $this.panel.offset();
556+ if (e.pageX < offset.left ||
557+ e.pageX > offset.left + $this.panel.width() ||
558+ e.pageY < offset.top ||
559+ e.pageY > offset.top + $this.panel.height()) {
560+ $this.hide();
561+ }
562+ });
563+
564+ $(window).bind('resize.' + this.element.id, function() {
565+ if($this.panel.is(':visible')) {
566+ $this._alignPanel();
567+ }
568+ });
569+ },
570+
571+ _bindKeyEvents: function() {
572+ var $this = this;
573+
574+ this.element.on('keyup.puiautocomplete', function(e) {
575+ var keyCode = $.ui.keyCode,
576+ key = e.which,
577+ shouldSearch = true;
578+
579+ if(key == keyCode.UP ||
580+ key == keyCode.LEFT ||
581+ key == keyCode.DOWN ||
582+ key == keyCode.RIGHT ||
583+ key == keyCode.TAB ||
584+ key == keyCode.SHIFT ||
585+ key == keyCode.ENTER ||
586+ key == keyCode.NUMPAD_ENTER) {
587+ shouldSearch = false;
588+ }
589+
590+ if(shouldSearch) {
591+ var value = $this.element.val();
592+
593+ if(!value.length) {
594+ $this.hide();
595+ }
596+
597+ if(value.length >= $this.options.minQueryLength) {
598+ if($this.timeout) {
599+ window.clearTimeout($this.timeout);
600+ }
601+
602+ $this.timeout = window.setTimeout(function() {
603+ $this.search(value);
604+ },
605+ $this.options.delay);
606+ }
607+ }
608+
609+ }).on('keydown.puiautocomplete', function(e) {
610+ if($this.panel.is(':visible')) {
611+ var keyCode = $.ui.keyCode,
612+ highlightedItem = $this.items.filter('.ui-state-highlight');
613+
614+ switch(e.which) {
615+ case keyCode.UP:
616+ case keyCode.LEFT:
617+ var prev = highlightedItem.prev();
618+
619+ if(prev.length == 1) {
620+ highlightedItem.removeClass('ui-state-highlight');
621+ prev.addClass('ui-state-highlight');
622+
623+ if($this.options.scrollHeight) {
624+ PUI.scrollInView($this.panel, prev);
625+ }
626+ }
627+
628+ e.preventDefault();
629+ break;
630+
631+ case keyCode.DOWN:
632+ case keyCode.RIGHT:
633+ var next = highlightedItem.next();
634+
635+ if(next.length == 1) {
636+ highlightedItem.removeClass('ui-state-highlight');
637+ next.addClass('ui-state-highlight');
638+
639+ if($this.options.scrollHeight) {
640+ PUI.scrollInView($this.panel, next);
641+ }
642+ }
643+
644+ e.preventDefault();
645+ break;
646+
647+ case keyCode.ENTER:
648+ case keyCode.NUMPAD_ENTER:
649+ highlightedItem.trigger('click');
650+
651+ e.preventDefault();
652+ break;
653+
654+ case keyCode.ALT:
655+ case 224:
656+ break;
657+
658+ case keyCode.TAB:
659+ highlightedItem.trigger('click');
660+ $this.hide();
661+ break;
662+ }
663+ }
664+
665+ });
666+ },
667+
668+ _bindDynamicEvents: function() {
669+ var $this = this;
670+
671+ this.items.on('mouseover.puiautocomplete', function() {
672+ var item = $(this);
673+
674+ if(!item.hasClass('ui-state-highlight')) {
675+ $this.items.filter('.ui-state-highlight').removeClass('ui-state-highlight');
676+ item.addClass('ui-state-highlight');
677+ }
678+ })
679+ .on('click.puiautocomplete', function(event) {
680+ var item = $(this);
681+
682+ if($this.options.multiple) {
683+ var tokenMarkup = '<li class="ui-autocomplete-token ui-state-active ui-corner-all ui-helper-hidden">';
684+ tokenMarkup += '<span class="ui-autocomplete-token-icon fa fa-fw fa-close" />';
685+ tokenMarkup += '<span class="ui-autocomplete-token-label">' + item.data('label') + '</span></li>';
686+
687+ $(tokenMarkup).data(item.data())
688+ .insertBefore($this.inputContainer).fadeIn()
689+ .children('.ui-autocomplete-token-icon').on('click.ui-autocomplete', function(e) {
690+ var token = $(this).parent();
691+ $this._removeItem(token);
692+ $this._trigger('unselect', e, token);
693+ });
694+
695+ $this.element.val('').trigger('focus');
696+ }
697+ else {
698+ $this.element.val(item.data('label')).focus();
699+ }
700+
701+ $this._trigger('select', event, item);
702+ $this.hide();
703+ });
704+ },
705+
706+ search: function(q) {
707+ this.query = this.options.caseSensitive ? q : q.toLowerCase();
708+
709+ var request = {
710+ query: this.query
711+ };
712+
713+ if(this.options.completeSource) {
714+ if($.isArray(this.options.completeSource)) {
715+ var sourceArr = this.options.completeSource,
716+ data = [],
717+ emptyQuery = ($.trim(q) === '');
718+
719+ for(var i = 0 ; i < sourceArr.length; i++) {
720+ var item = sourceArr[i],
721+ itemLabel = item.label||item;
722+
723+ if(!this.options.caseSensitive) {
724+ itemLabel = itemLabel.toLowerCase();
725+ }
726+
727+ if(emptyQuery||itemLabel.indexOf(this.query) === 0) {
728+ data.push({label:sourceArr[i], value: item});
729+ }
730+ }
731+
732+ this._handleData(data);
733+ }
734+ else {
735+ this.options.completeSource.call(this, request, this._handleData);
736+ }
737+ }
738+ },
739+
740+ _handleData: function(data) {
741+ var $this = this;
742+ this.panel.html('');
743+ this.listContainer = $('<ul class="ui-autocomplete-items ui-autocomplete-list ui-widget-content ui-widget ui-corner-all ui-helper-reset"></ul>').appendTo(this.panel);
744+
745+ for(var i = 0; i < data.length; i++) {
746+ var item = $('<li class="ui-autocomplete-item ui-autocomplete-list-item ui-corner-all"></li>');
747+ item.data(data[i]);
748+
749+ if(this.options.content)
750+ item.html(this.options.content.call(this, data[i]));
751+ else
752+ item.text(data[i].label);
753+
754+ this.listContainer.append(item);
755+ }
756+
757+ this.items = this.listContainer.children('.ui-autocomplete-item');
758+
759+ this._bindDynamicEvents();
760+
761+ if(this.items.length > 0) {
762+ var firstItem = $this.items.eq(0),
763+ hidden = this.panel.is(':hidden');
764+ firstItem.addClass('ui-state-highlight');
765+
766+ if($this.query.length > 0 && !$this.options.content) {
767+ $this.items.each(function() {
768+ var item = $(this),
769+ text = item.html(),
770+ re = new RegExp(PUI.escapeRegExp($this.query), 'gi'),
771+ highlighedText = text.replace(re, '<span class="ui-autocomplete-query">$&</span>');
772+
773+ item.html(highlighedText);
774+ });
775+ }
776+
777+ if(this.options.forceSelection) {
778+ this.currentItems = [];
779+ $.each(data, function(i, item) {
780+ $this.currentItems.push(item.label);
781+ });
782+ }
783+
784+ //adjust height
785+ if($this.options.scrollHeight) {
786+ var heightConstraint = hidden ? $this.panel.height() : $this.panel.children().height();
787+
788+ if(heightConstraint > $this.options.scrollHeight)
789+ $this.panel.height($this.options.scrollHeight);
790+ else
791+ $this.panel.css('height', 'auto');
792+
793+ }
794+
795+ if(hidden) {
796+ $this.show();
797+ }
798+ else {
799+ $this._alignPanel();
800+ }
801+ }
802+ else {
803+ this.panel.hide();
804+ }
805+ },
806+
807+ show: function() {
808+ this._alignPanel();
809+
810+ if(this.options.effect)
811+ this.panel.show(this.options.effect, {}, this.options.effectSpeed);
812+ else
813+ this.panel.show();
814+ },
815+
816+ hide: function() {
817+ this.panel.hide();
818+ this.panel.css('height', 'auto');
819+ },
820+
821+ _removeItem: function(item) {
822+ item.fadeOut('fast', function() {
823+ var token = $(this);
824+
825+ token.remove();
826+ });
827+ },
828+
829+ _alignPanel: function() {
830+ var panelWidth = null;
831+
832+ if(this.options.multiple) {
833+ panelWidth = this.multiContainer.innerWidth() - (this.element.position().left - this.multiContainer.position().left);
834+ }
835+ else {
836+ if(this.panel.is(':visible')) {
837+ panelWidth = this.panel.children('.ui-autocomplete-items').outerWidth();
838+ }
839+ else {
840+ this.panel.css({'visibility':'hidden','display':'block'});
841+ panelWidth = this.panel.children('.ui-autocomplete-items').outerWidth();
842+ this.panel.css({'visibility':'visible','display':'none'});
843+ }
844+
845+ var inputWidth = this.element.outerWidth();
846+ if(panelWidth < inputWidth) {
847+ panelWidth = inputWidth;
848+ }
849+ }
850+
851+ this.panel.css({
852+ 'left':'',
853+ 'top':'',
854+ 'width': panelWidth,
855+ 'z-index': ++PUI.zindex
856+ })
857+ .position({
858+ my: 'left top',
859+ at: 'left bottom',
860+ of: this.element
861+ });
862+ }
863+ });
864+
865+})();
866+/**
867+ * PrimeFaces Button Widget
868+ */
869+(function() {
870+
871+ $.widget("primeui.puibutton", {
872+
873+ options: {
874+ value: null,
875+ icon: null,
876+ iconPos: 'left',
877+ click: null
878+ },
879+
880+ _create: function() {
881+ var element = this.element;
882+ this.elementText = this.element.text();
883+
884+ var value = this.options.value||(this.elementText === '' ? 'ui-button' : this.elementText),
885+ disabled = element.prop('disabled'),
886+ styleClass = null;
887+
888+ if(this.options.icon) {
889+ styleClass = (value === 'ui-button') ? 'ui-button-icon-only' : 'ui-button-text-icon-' + this.options.iconPos;
890+ }
891+ else {
892+ styleClass = 'ui-button-text-only';
893+ }
894+
895+ if(disabled) {
896+ styleClass += ' ui-state-disabled';
897+ }
898+
899+ this.element.addClass('ui-button ui-widget ui-state-default ui-corner-all ' + styleClass).text('');
900+
901+ if(this.options.icon) {
902+ this.element.append('<span class="ui-button-icon-' + this.options.iconPos + ' ui-c fa fa-fw ' + this.options.icon + '" />');
903+ }
904+
905+ this.element.append('<span class="ui-button-text ui-c">' + value + '</span>');
906+
907+ if(!disabled) {
908+ this._bindEvents();
909+ }
910+ },
911+
912+ _destroy: function() {
913+ this.element.removeClass('ui-button ui-widget ui-state-default ui-state-hover ui-state-active ui-state-disabled ui-state-focus ui-corner-all ' +
914+ 'ui-button-text-only ui-button-icon-only ui-button-text-icon-right ui-button-text-icon-left');
915+ this._unbindEvents();
916+ this.element.children('.fa').remove();
917+ this.element.children('.ui-button-text').remove();
918+ this.element.text(this.elementText);
919+ },
920+
921+ _bindEvents: function() {
922+ var element = this.element,
923+ $this = this;
924+
925+ element.on('mouseover.puibutton', function(){
926+ if(!element.prop('disabled')) {
927+ element.addClass('ui-state-hover');
928+ }
929+ }).on('mouseout.puibutton', function() {
930+ $(this).removeClass('ui-state-active ui-state-hover');
931+ }).on('mousedown.puibutton', function() {
932+ if(!element.hasClass('ui-state-disabled')) {
933+ element.addClass('ui-state-active').removeClass('ui-state-hover');
934+ }
935+ }).on('mouseup.puibutton', function(e) {
936+ element.removeClass('ui-state-active').addClass('ui-state-hover');
937+
938+ $this._trigger('click', e);
939+ }).on('focus.puibutton', function() {
940+ element.addClass('ui-state-focus');
941+ }).on('blur.puibutton', function() {
942+ element.removeClass('ui-state-focus');
943+ }).on('keydown.puibutton',function(e) {
944+ if(e.keyCode == $.ui.keyCode.SPACE || e.keyCode == $.ui.keyCode.ENTER || e.keyCode == $.ui.keyCode.NUMPAD_ENTER) {
945+ element.addClass('ui-state-active');
946+ }
947+ }).on('keyup.puibutton', function() {
948+ element.removeClass('ui-state-active');
949+ });
950+
951+ return this;
952+ },
953+
954+ _unbindEvents: function() {
955+ this.element.off('mouseover.puibutton mouseout.puibutton mousedown.puibutton mouseup.puibutton focus.puibutton blur.puibutton keydown.puibutton keyup.puibutton');
956+ },
957+
958+ disable: function() {
959+ this._unbindEvents();
960+ this.element.addClass('ui-state-disabled').prop('disabled',true);
961+ },
962+
963+ enable: function() {
964+ if(this.element.prop('disabled')) {
965+ this._bindEvents();
966+ this.element.prop('disabled', false).removeClass('ui-state-disabled');
967+ }
968+ },
969+
970+ _setOption: function(key, value) {
971+ if(key === 'disabled') {
972+ if(value)
973+ this.disable();
974+ else
975+ this.enable();
976+ }
977+ else {
978+ $.Widget.prototype._setOption.apply(this, arguments);
979+ }
980+ }
981+
982+ });
983+})();
984+/**
985+ * PrimeUI Carousel widget
986+ */
987+(function() {
988+
989+ $.widget("primeui.puicarousel", {
990+
991+ options: {
992+ datasource: null,
993+ numVisible: 3,
994+ firstVisible: 0,
995+ headerText: null,
996+ effectDuration: 500,
997+ circular :false,
998+ breakpoint: 560,
999+ itemContent: null,
1000+ responsive: true,
1001+ autoplayInterval: 0,
1002+ easing: 'easeInOutCirc',
1003+ pageLinks: 3,
1004+ style: null,
1005+ styleClass: null,
1006+ template: null,
1007+ enhanced: false
1008+ },
1009+
1010+ _create: function() {
1011+ this.id = this.element.attr('id');
1012+ if(!this.id) {
1013+ this.id = this.element.uniqueId().attr('id');
1014+ }
1015+
1016+ if(!this.options.enhanced) {
1017+ this.element.wrap('<div class="ui-carousel ui-widget ui-widget-content ui-corner-all"><div class="ui-carousel-viewport"></div></div>');
1018+ }
1019+
1020+ this.container = this.element.parent().parent();
1021+ this.element.addClass('ui-carousel-items');
1022+ this.viewport = this.element.parent();
1023+ this.container.prepend('<div class="ui-carousel-header ui-widget-header"><div class="ui-carousel-header-title"></div></div>');
1024+ this.header = this.container.children('.ui-carousel-header');
1025+ this.header.append('<span class="ui-carousel-button ui-carousel-next-button fa fa-arrow-circle-right"></span>' +
1026+ '<span class="ui-carousel-button ui-carousel-prev-button fa fa-arrow-circle-left"></span>');
1027+
1028+ if(this.options.headerText) {
1029+ this.header.children('.ui-carousel-header-title').html(this.options.headerText);
1030+ }
1031+
1032+ if(this.options.styleClass) {
1033+ this.container.addClass(this.options.styleClass);
1034+ }
1035+
1036+ if(this.options.style) {
1037+ this.container.attr('style', this.options.style);
1038+ }
1039+
1040+ if(this.options.datasource)
1041+ this._loadData();
1042+ else
1043+ this._render();
1044+ },
1045+
1046+ _destroy: function() {
1047+ this._unbindEvents();
1048+ this.header.remove();
1049+ this.items.removeClass('ui-carousel-item ui-widget-content ui-corner-all').css('width','auto');
1050+ this.element.removeClass('ui-carousel-items').css('left','auto');
1051+
1052+ if(!this.options.enhanced) {
1053+ this.element.unwrap().unwrap();
1054+ }
1055+
1056+ if(this.options.datasource) {
1057+ this.items.remove();
1058+ }
1059+ },
1060+
1061+ _loadData: function() {
1062+ if($.isArray(this.options.datasource))
1063+ this._render(this.options.datasource);
1064+ else if($.type(this.options.datasource) === 'function')
1065+ this.options.datasource.call(this, this._render);
1066+ },
1067+
1068+ _updateDatasource: function(value) {
1069+ this.options.datasource = value;
1070+ this.element.children().remove();
1071+ this.header.children('.ui-carousel-page-links').remove();
1072+ this.header.children('select').remove();
1073+ this._loadData();
1074+ },
1075+
1076+ _render: function(data) {
1077+ this.data = data;
1078+
1079+ if(this.data) {
1080+ for(var i = 0; i < data.length; i++) {
1081+ var itemContent = this._createItemContent(data[i]);
1082+ if($.type(itemContent) === 'string')
1083+ this.element.append('<li>' + itemContent + '</li>');
1084+ else
1085+ this.element.append($('<li></li>').wrapInner(itemContent));
1086+ }
1087+ }
1088+
1089+ this.items = this.element.children('li');
1090+ this.items.addClass('ui-carousel-item ui-widget-content ui-corner-all');
1091+ this.itemsCount = this.items.length;
1092+ this.columns = this.options.numVisible;
1093+ this.first = this.options.firstVisible;
1094+ this.page = parseInt(this.first/this.columns);
1095+ this.totalPages = Math.ceil(this.itemsCount/this.options.numVisible);
1096+
1097+ this._renderPageLinks();
1098+
1099+ this.prevNav = this.header.children('.ui-carousel-prev-button');
1100+ this.nextNav = this.header.children('.ui-carousel-next-button');
1101+ this.pageLinks = this.header.find('> .ui-carousel-page-links > .ui-carousel-page-link');
1102+ this.dropdown = this.header.children('.ui-carousel-dropdown');
1103+ this.mobileDropdown = this.header.children('.ui-carousel-mobiledropdown');
1104+
1105+ this._bindEvents();
1106+
1107+ if(this.options.responsive) {
1108+ this.refreshDimensions();
1109+ }
1110+ else {
1111+ this.calculateItemWidths();
1112+ this.container.width(this.container.width());
1113+ this.updateNavigators();
1114+ }
1115+ },
1116+
1117+ _renderPageLinks: function() {
1118+ if(this.totalPages <= this.options.pageLinks) {
1119+ this.pageLinksContainer = $('<div class="ui-carousel-page-links"></div>');
1120+ for(var i = 0; i < this.totalPages; i++) {
1121+ this.pageLinksContainer.append('<a href="#" class="ui-carousel-page-link fa fa-circle-o"></a>');
1122+ }
1123+ this.header.append(this.pageLinksContainer);
1124+ }
1125+ else {
1126+ this.dropdown = $('<select class="ui-carousel-dropdown ui-widget ui-state-default ui-corner-left"></select>');
1127+ for(var i = 0; i < this.totalPages; i++) {
1128+ var pageNumber = (i+1);
1129+ this.dropdown.append('<option value="' + pageNumber + '">' + pageNumber + '</option>');
1130+ }
1131+ this.header.append(this.dropdown);
1132+ }
1133+
1134+ if(this.options.responsive) {
1135+ this.mobileDropdown = $('<select class="ui-carousel-mobiledropdown ui-widget ui-state-default ui-corner-left"></select>');
1136+ for(var i = 0; i < this.itemsCount; i++) {
1137+ var pageNumber = (i+1);
1138+ this.mobileDropdown.append('<option value="' + pageNumber + '">' + pageNumber + '</option>');
1139+ }
1140+ this.header.append(this.mobileDropdown);
1141+ }
1142+ },
1143+
1144+ calculateItemWidths: function() {
1145+ var firstItem = this.items.eq(0);
1146+ if(firstItem.length) {
1147+ var itemFrameWidth = firstItem.outerWidth(true) - firstItem.width(); //sum of margin, border and padding
1148+ this.items.width((this.viewport.innerWidth() - itemFrameWidth * this.columns) / this.columns);
1149+ }
1150+ },
1151+
1152+ refreshDimensions: function() {
1153+ var win = $(window);
1154+ if(win.width() <= this.options.breakpoint) {
1155+ this.columns = 1;
1156+ this.calculateItemWidths(this.columns);
1157+ this.totalPages = this.itemsCount;
1158+ this.mobileDropdown.show();
1159+ this.pageLinks.hide();
1160+ }
1161+ else {
1162+ this.columns = this.options.numVisible;
1163+ this.calculateItemWidths();
1164+ this.totalPages = Math.ceil(this.itemsCount / this.options.numVisible);
1165+ this.mobileDropdown.hide();
1166+ this.pageLinks.show();
1167+ }
1168+
1169+ this.page = parseInt(this.first / this.columns);
1170+ this.updateNavigators();
1171+ this.element.css('left', (-1 * (this.viewport.innerWidth() * this.page)));
1172+ },
1173+
1174+ _bindEvents: function() {
1175+ var $this = this;
1176+
1177+ if(this.eventsBound) {
1178+ return;
1179+ }
1180+
1181+ this.prevNav.on('click.puicarousel', function() {
1182+ if($this.page !== 0) {
1183+ $this.setPage($this.page - 1);
1184+ }
1185+ else if($this.options.circular) {
1186+ $this.setPage($this.totalPages - 1);
1187+ }
1188+ });
1189+
1190+ this.nextNav.on('click.puicarousel', function() {
1191+ var lastPage = ($this.page === ($this.totalPages - 1));
1192+
1193+ if(!lastPage) {
1194+ $this.setPage($this.page + 1);
1195+ }
1196+ else if($this.options.circular) {
1197+ $this.setPage(0);
1198+ }
1199+ });
1200+
1201+ if($.swipe) {
1202+ this.element.swipe({
1203+ swipe:function(event, direction) {
1204+ if(direction === 'left') {
1205+ if($this.page === ($this.totalPages - 1)) {
1206+ if($this.options.circular)
1207+ $this.setPage(0);
1208+ }
1209+ else {
1210+ $this.setPage($this.page + 1);
1211+ }
1212+ }
1213+ else if(direction === 'right') {
1214+ if($this.page === 0) {
1215+ if($this.options.circular)
1216+ $this.setPage($this.totalPages - 1);
1217+ }
1218+ else {
1219+ $this.setPage($this.page - 1);
1220+ }
1221+ }
1222+ }
1223+ });
1224+ }
1225+
1226+ if(this.pageLinks.length) {
1227+ this.pageLinks.on('click.puicarousel', function(e) {
1228+ $this.setPage($(this).index());
1229+ e.preventDefault();
1230+ });
1231+ }
1232+
1233+ this.header.children('select').on('change.puicarousel', function() {
1234+ $this.setPage(parseInt($(this).val()) - 1);
1235+ });
1236+
1237+ if(this.options.autoplayInterval) {
1238+ this.options.circular = true;
1239+ this.startAutoplay();
1240+ }
1241+
1242+ if(this.options.responsive) {
1243+ var resizeNS = 'resize.' + this.id;
1244+ $(window).off(resizeNS).on(resizeNS, function() {
1245+ $this.refreshDimensions();
1246+ });
1247+ }
1248+
1249+ this.eventsBound = true;
1250+ },
1251+
1252+ _unbindEvents: function() {
1253+ this.prevNav.off('click.puicarousel');
1254+ this.nextNav.off('click.puicarousel');
1255+ if(this.pageLinks.length) {
1256+ this.pageLinks.off('click.puicarousel');
1257+ }
1258+ this.header.children('select').off('change.puicarousel');
1259+
1260+ if(this.options.autoplayInterval) {
1261+ this.stopAutoplay();
1262+ }
1263+
1264+ if(this.options.responsive) {
1265+ $(window).off('resize.' + this.id)
1266+ }
1267+ },
1268+
1269+ updateNavigators: function() {
1270+ if(!this.options.circular) {
1271+ if(this.page === 0) {
1272+ this.prevNav.addClass('ui-state-disabled');
1273+ this.nextNav.removeClass('ui-state-disabled');
1274+ }
1275+ else if(this.page === (this.totalPages - 1)) {
1276+ this.prevNav.removeClass('ui-state-disabled');
1277+ this.nextNav.addClass('ui-state-disabled');
1278+ }
1279+ else {
1280+ this.prevNav.removeClass('ui-state-disabled');
1281+ this.nextNav.removeClass('ui-state-disabled');
1282+ }
1283+ }
1284+
1285+ if(this.pageLinks.length) {
1286+ this.pageLinks.filter('.fa-dot-circle-o').removeClass('fa-dot-circle-o');
1287+ this.pageLinks.eq(this.page).addClass('fa-dot-circle-o');
1288+ }
1289+
1290+ if(this.dropdown.length) {
1291+ this.dropdown.val(this.page + 1);
1292+ }
1293+
1294+ if(this.mobileDropdown.length) {
1295+ this.mobileDropdown.val(this.page + 1);
1296+ }
1297+ },
1298+
1299+ setPage: function(p) {
1300+ if(p !== this.page && !this.element.is(':animated')) {
1301+ var $this = this;
1302+
1303+ this.element.animate({
1304+ left: -1 * (this.viewport.innerWidth() * p)
1305+ ,easing: this.options.easing
1306+ },
1307+ {
1308+ duration: this.options.effectDuration,
1309+ easing: this.options.easing,
1310+ complete: function() {
1311+ $this.page = p;
1312+ $this.first = $this.page * $this.columns;
1313+ $this.updateNavigators();
1314+ $this._trigger('pageChange', null, {'page':p});
1315+ }
1316+ });
1317+ }
1318+ },
1319+
1320+ startAutoplay: function() {
1321+ var $this = this;
1322+
1323+ this.interval = setInterval(function() {
1324+ if($this.page === ($this.totalPages - 1))
1325+ $this.setPage(0);
1326+ else
1327+ $this.setPage($this.page + 1);
1328+ }, this.options.autoplayInterval);
1329+ },
1330+
1331+ stopAutoplay: function() {
1332+ clearInterval(this.interval);
1333+ },
1334+
1335+ _setOption: function(key, value) {
1336+ if(key === 'datasource')
1337+ this._updateDatasource(value);
1338+ else
1339+ $.Widget.prototype._setOption.apply(this, arguments);
1340+ },
1341+
1342+ _createItemContent: function(obj) {
1343+ if(this.options.template) {
1344+ var template = this.options.template.html();
1345+ Mustache.parse(template);
1346+ return Mustache.render(template, obj);
1347+ }
1348+ else {
1349+ return this.options.itemContent.call(this, obj);
1350+ }
1351+ }
1352+
1353+ });
1354+
1355+})();
1356+/**
1357+ * PrimeUI checkbox widget
1358+ */
1359+(function() {
1360+
1361+ $.widget("primeui.puicheckbox", {
1362+
1363+ _create: function() {
1364+ this.element.wrap('<div class="ui-chkbox ui-widget"><div class="ui-helper-hidden-accessible"></div></div>');
1365+ this.container = this.element.parent().parent();
1366+ this.box = $('<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">').appendTo(this.container);
1367+ this.icon = $('<span class="ui-chkbox-icon ui-c"></span>').appendTo(this.box);
1368+ this.disabled = this.element.prop('disabled');
1369+ this.label = $('label[for="' + this.element.attr('id') + '"]');
1370+
1371+ if(this.isChecked()) {
1372+ this.box.addClass('ui-state-active');
1373+ this.icon.addClass('fa fa-fw fa-check');
1374+ }
1375+
1376+ if(this.disabled) {
1377+ this.box.addClass('ui-state-disabled');
1378+ } else {
1379+ this._bindEvents();
1380+ }
1381+ },
1382+
1383+ _bindEvents: function() {
1384+ var $this = this;
1385+
1386+ this.box.on('mouseover.puicheckbox', function() {
1387+ if(!$this.isChecked())
1388+ $this.box.addClass('ui-state-hover');
1389+ })
1390+ .on('mouseout.puicheckbox', function() {
1391+ $this.box.removeClass('ui-state-hover');
1392+ })
1393+ .on('click.puicheckbox', function() {
1394+ $this.toggle();
1395+ });
1396+
1397+ this.element.on('focus.puicheckbox', function() {
1398+ if($this.isChecked()) {
1399+ $this.box.removeClass('ui-state-active');
1400+ }
1401+
1402+ $this.box.addClass('ui-state-focus');
1403+ })
1404+ .on('blur.puicheckbox', function() {
1405+ if($this.isChecked()) {
1406+ $this.box.addClass('ui-state-active');
1407+ }
1408+
1409+ $this.box.removeClass('ui-state-focus');
1410+ })
1411+ .on('keydown.puicheckbox', function(e) {
1412+ var keyCode = $.ui.keyCode;
1413+ if(e.which == keyCode.SPACE) {
1414+ e.preventDefault();
1415+ }
1416+ })
1417+ .on('keyup.puicheckbox', function(e) {
1418+ var keyCode = $.ui.keyCode;
1419+ if(e.which == keyCode.SPACE) {
1420+ $this.toggle(true);
1421+
1422+ e.preventDefault();
1423+ }
1424+ });
1425+
1426+ this.label.on('click.puicheckbox', function(e) {
1427+ $this.toggle();
1428+ e.preventDefault();
1429+ });
1430+ },
1431+
1432+ toggle: function(keypress) {
1433+ if(this.isChecked()) {
1434+ this.uncheck(keypress);
1435+ } else {
1436+ this.check(keypress);
1437+ }
1438+
1439+ this._trigger('change', null, this.isChecked());
1440+ },
1441+
1442+ isChecked: function() {
1443+ return this.element.prop('checked');
1444+ },
1445+
1446+ check: function(activate, silent) {
1447+ if(!this.isChecked()) {
1448+ this.element.prop('checked', true);
1449+ this.icon.addClass('fa fa-fw fa-check');
1450+
1451+ if(!activate) {
1452+ this.box.addClass('ui-state-active');
1453+ }
1454+
1455+ if(!silent) {
1456+ this.element.trigger('change');
1457+ }
1458+ }
1459+ },
1460+
1461+ uncheck: function() {
1462+ if(this.isChecked()) {
1463+ this.element.prop('checked', false);
1464+ this.box.removeClass('ui-state-active');
1465+ this.icon.removeClass('fa fa-fw fa-check');
1466+
1467+ this.element.trigger('change');
1468+ }
1469+ },
1470+
1471+ _unbindEvents: function() {
1472+ this.box.off('mouseover.puicheckbox mouseout.puicheckbox click.puicheckbox');
1473+ this.element.off('focus.puicheckbox blur.puicheckbox keydown.puicheckbox keyup.puicheckbox');
1474+
1475+ if (this.label.length) {
1476+ this.label.off('click.puicheckbox');
1477+ }
1478+ },
1479+
1480+ disable: function() {
1481+ this.box.prop('disabled', true);
1482+ this.box.attr('aria-disabled', true);
1483+ this.box.addClass('ui-state-disabled').removeClass('ui-state-hover');
1484+ this._unbindEvents();
1485+ },
1486+
1487+ enable: function() {
1488+ this.box.prop('disabled', false);
1489+ this.box.attr('aria-disabled', false);
1490+ this.box.removeClass('ui-state-disabled');
1491+ this._bindEvents();
1492+ },
1493+
1494+ _destroy: function() {
1495+ this._unbindEvents();
1496+ this.container.removeClass('ui-chkbox ui-widget');
1497+ this.box.remove();
1498+ this.element.unwrap().unwrap();
1499+ }
1500+
1501+ });
1502+
1503+})();
1504+/**
1505+ * PrimeUI Datagrid Widget
1506+ */
1507+(function() {
1508+
1509+ $.widget("primeui.puidatagrid", {
1510+
1511+ options: {
1512+ columns: 3,
1513+ datasource: null,
1514+ paginator: null,
1515+ header: null,
1516+ footer: null,
1517+ content: null,
1518+ lazy: false,
1519+ template: null
1520+ },
1521+
1522+ _create: function() {
1523+ this.id = this.element.attr('id');
1524+ if(!this.id) {
1525+ this.id = this.element.uniqueId().attr('id');
1526+ }
1527+
1528+ this.element.addClass('ui-datagrid ui-widget');
1529+
1530+ //header
1531+ if(this.options.header) {
1532+ this.element.append('<div class="ui-datagrid-header ui-widget-header ui-corner-top">' + this.options.header + '</div>');
1533+ }
1534+
1535+ //content
1536+ this.content = $('<div class="ui-datagrid-content ui-widget-content ui-datagrid-col-' + this.options.columns + '"></div>').appendTo(this.element);
1537+
1538+ //footer
1539+ if(this.options.footer) {
1540+ this.element.append('<div class="ui-datagrid-footer ui-widget-header ui-corner-top">' + this.options.footer + '</div>');
1541+ }
1542+
1543+ //data
1544+ if(this.options.datasource) {
1545+ this._initDatasource();
1546+ }
1547+ },
1548+
1549+ _onDataInit: function(data) {
1550+ this._onDataUpdate(data);
1551+ this._initPaginator();
1552+ },
1553+
1554+ _onDataUpdate: function(data) {
1555+ this.data = data;
1556+ if(!this.data) {
1557+ this.data = [];
1558+ }
1559+
1560+ this.reset();
1561+
1562+ this._renderData();
1563+ },
1564+
1565+ _onLazyLoad: function(data) {
1566+ this.data = data;
1567+ if(!this.data) {
1568+ this.data = [];
1569+ }
1570+
1571+ this._renderData();
1572+ },
1573+
1574+ reset: function() {
1575+ if(this.paginator) {
1576+ this.paginator.puipaginator('setState', {
1577+ page: 0,
1578+ totalRecords: this.options.lazy ? this.options.paginator.totalRecords : this.data.length
1579+ });
1580+ }
1581+ },
1582+
1583+ paginate: function() {
1584+ if(this.options.lazy) {
1585+ this.options.datasource.call(this, this._onLazyLoad, this._createStateMeta());
1586+ }
1587+ else {
1588+ this._renderData();
1589+ }
1590+ },
1591+
1592+ _renderData: function() {
1593+ if(this.data) {
1594+ this.content.html('');
1595+
1596+ var firstNonLazy = this._getFirst(),
1597+ first = this.options.lazy ? 0 : firstNonLazy,
1598+ rows = this._getRows(),
1599+ gridRow = null;
1600+
1601+ for(var i = first; i < (first + rows); i++) {
1602+ var dataValue = this.data[i];
1603+
1604+ if(dataValue) {
1605+ var gridColumn = $('<div></div>').appendTo(this.content),
1606+ markup = this._createItemContent(dataValue);
1607+ gridColumn.append(markup);
1608+ }
1609+ }
1610+ }
1611+ },
1612+
1613+ _getFirst: function() {
1614+ if(this.paginator) {
1615+ var page = this.paginator.puipaginator('option', 'page'),
1616+ rows = this.paginator.puipaginator('option', 'rows');
1617+
1618+ return (page * rows);
1619+ }
1620+ else {
1621+ return 0;
1622+ }
1623+ },
1624+
1625+ _getRows: function() {
1626+ if(this.options.paginator)
1627+ return this.paginator ? this.paginator.puipaginator('option', 'rows') : this.options.paginator.rows;
1628+ else
1629+ return this.data ? this.data.length : 0;
1630+ },
1631+
1632+ _createStateMeta: function() {
1633+ var state = {
1634+ first: this._getFirst(),
1635+ rows: this._getRows()
1636+ };
1637+
1638+ return state;
1639+ },
1640+
1641+ _initPaginator: function() {
1642+ var $this = this;
1643+ if(this.options.paginator) {
1644+ this.options.paginator.paginate = function(event, state) {
1645+ $this.paginate();
1646+ };
1647+
1648+ this.options.paginator.totalRecords = this.options.lazy ? this.options.paginator.totalRecords : this.data.length;
1649+ this.paginator = $('<div></div>').insertAfter(this.content).puipaginator(this.options.paginator);
1650+ }
1651+ },
1652+
1653+ _initDatasource: function() {
1654+ if($.isArray(this.options.datasource)) {
1655+ this._onDataInit(this.options.datasource);
1656+ }
1657+ else {
1658+ if($.type(this.options.datasource) === 'string') {
1659+ var $this = this,
1660+ dataURL = this.options.datasource;
1661+
1662+ this.options.datasource = function() {
1663+ $.ajax({
1664+ type: 'GET',
1665+ url: dataURL,
1666+ dataType: "json",
1667+ context: $this,
1668+ success: function (response) {
1669+ this._onDataInit(response);
1670+ }
1671+ });
1672+ };
1673+ }
1674+
1675+ if($.type(this.options.datasource) === 'function') {
1676+ if(this.options.lazy)
1677+ this.options.datasource.call(this, this._onDataInit, {first:0, rows: this._getRows()});
1678+ else
1679+ this.options.datasource.call(this, this._onDataInit);
1680+ }
1681+ }
1682+ },
1683+
1684+ _updateDatasource: function(datasource) {
1685+ this.options.datasource = datasource;
1686+
1687+ if($.isArray(this.options.datasource)) {
1688+ this._onDataUpdate(this.options.datasource);
1689+ }
1690+ else if($.type(this.options.datasource) === 'function') {
1691+ if(this.options.lazy)
1692+ this.options.datasource.call(this, this._onDataUpdate, {first:0, rows: this._getRows()});
1693+ else
1694+ this.options.datasource.call(this, this._onDataUpdate);
1695+ }
1696+ },
1697+
1698+ _setOption: function(key, value) {
1699+ if(key === 'datasource') {
1700+ this._updateDatasource(value);
1701+ }
1702+ else {
1703+ $.Widget.prototype._setOption.apply(this, arguments);
1704+ }
1705+ },
1706+
1707+ _createItemContent: function(obj) {
1708+ if(this.options.template) {
1709+ var templateContent = this.options.template.html();
1710+ Mustache.parse(templateContent);
1711+ return Mustache.render(templateContent, obj);
1712+ }
1713+ else {
1714+ return this.options.content.call(this, obj);
1715+ }
1716+ }
1717+
1718+ });
1719+})();
1720+/**
1721+ * PrimeUI Datascroller Widget
1722+ */
1723+(function() {
1724+
1725+ $.widget("primeui.puidatascroller", {
1726+
1727+ options: {
1728+ header: null,
1729+ buffer: 0.9,
1730+ chunkSize: 10,
1731+ datasource: null,
1732+ lazy: false,
1733+ content: null,
1734+ template: null,
1735+ mode: 'document',
1736+ loader: null,
1737+ scrollHeight: null,
1738+ totalSize: null
1739+ },
1740+
1741+ _create: function() {
1742+ this.id = this.element.attr('id');
1743+ if(!this.id) {
1744+ this.id = this.element.uniqueId().attr('id');
1745+ }
1746+
1747+ this.element.addClass('ui-datascroller ui-widget');
1748+ if(this.options.header) {
1749+ this.header = this.element.append('<div class="ui-datascroller-header ui-widget-header ui-corner-top">' + this.options.header + '</div>').children('.ui-datascroller-header');
1750+ }
1751+
1752+ this.content = this.element.append('<div class="ui-datascroller-content ui-widget-content ui-corner-bottom"></div>').children('.ui-datascroller-content');
1753+ this.list = this.content.append('<ul class="ui-datascroller-list"></ul>').children('.ui-datascroller-list');
1754+ this.loaderContainer = this.content.append('<div class="ui-datascroller-loader"></div>').children('.ui-datascroller-loader');
1755+ this.loadStatus = $('<div class="ui-datascroller-loading"></div>');
1756+ this.loading = false;
1757+ this.allLoaded = false;
1758+ this.offset = 0;
1759+
1760+ if(this.options.mode === 'self') {
1761+ this.element.addClass('ui-datascroller-inline');
1762+
1763+ if(this.options.scrollHeight) {
1764+ this.content.css('height', this.options.scrollHeight);
1765+ }
1766+ }
1767+
1768+ if(this.options.loader) {
1769+ this.bindManualLoader();
1770+ }
1771+ else {
1772+ this.bindScrollListener();
1773+ }
1774+
1775+ if(this.options.datasource) {
1776+ if($.isArray(this.options.datasource)) {
1777+ this._onDataInit(this.options.datasource);
1778+ }
1779+ else {
1780+ if($.type(this.options.datasource) === 'string') {
1781+ var $this = this,
1782+ dataURL = this.options.datasource;
1783+
1784+ this.options.datasource = function() {
1785+ $.ajax({
1786+ type: 'GET',
1787+ url: dataURL,
1788+ dataType: "json",
1789+ context: $this,
1790+ success: function (response) {
1791+ this._onDataInit(response);
1792+ }
1793+ });
1794+ };
1795+ }
1796+
1797+ if($.type(this.options.datasource) === 'function') {
1798+ if(this.options.lazy)
1799+ this.options.datasource.call(this, this._onLazyLoad, {first:this.offset});
1800+ else
1801+ this.options.datasource.call(this, this._onDataInit);
1802+ }
1803+ }
1804+ }
1805+ },
1806+
1807+ _onDataInit: function(data) {
1808+ this.data = data||[];
1809+ this.options.totalSize = this.data.length;
1810+
1811+ this._load();
1812+ },
1813+
1814+ _onLazyLoad: function(data) {
1815+ this._renderData(data, 0, this.options.chunkSize);
1816+
1817+ this._onloadComplete();
1818+ },
1819+
1820+ bindScrollListener: function() {
1821+ var $this = this;
1822+
1823+ if(this.options.mode === 'document') {
1824+ var win = $(window),
1825+ doc = $(document),
1826+ $this = this,
1827+ NS = 'scroll.' + this.id;
1828+
1829+ win.off(NS).on(NS, function () {
1830+ if(win.scrollTop() >= ((doc.height() * $this.options.buffer) - win.height()) && $this.shouldLoad()) {
1831+ $this._load();
1832+ }
1833+ });
1834+ }
1835+ else {
1836+ this.content.on('scroll', function () {
1837+ var scrollTop = this.scrollTop,
1838+ scrollHeight = this.scrollHeight,
1839+ viewportHeight = this.clientHeight;
1840+
1841+ if((scrollTop >= ((scrollHeight * $this.options.buffer) - (viewportHeight))) && $this.shouldLoad()) {
1842+ $this._load();
1843+ }
1844+ });
1845+ }
1846+ },
1847+
1848+ bindManualLoader: function() {
1849+ var $this = this;
1850+
1851+ this.options.loader.on('click.dataScroller', function(e) {
1852+ $this._load();
1853+ e.preventDefault();
1854+ });
1855+ },
1856+
1857+ _load: function() {
1858+ this.loading = true;
1859+ this.loadStatus.appendTo(this.loaderContainer);
1860+ if(this.options.loader) {
1861+ this.options.loader.hide();
1862+ }
1863+
1864+ if(this.options.lazy) {
1865+ this.options.datasource.call(this, this._onLazyLoad, {first: this.offset});
1866+ }
1867+ else {
1868+ this._renderData(this.data, this.offset, (this.offset + this.options.chunkSize));
1869+ this._onloadComplete();
1870+ }
1871+ },
1872+
1873+ _renderData: function(data, start, end) {
1874+ if(data && data.length) {
1875+ for(var i = start; i < end; i++) {
1876+ var listItem = $('<li class="ui-datascroller-item"></li>'),
1877+ content = this._createItemContent(data[i]);
1878+ listItem.append(content);
1879+
1880+ this.list.append(listItem);
1881+ }
1882+ }
1883+ },
1884+
1885+ shouldLoad: function() {
1886+ return (!this.loading && !this.allLoaded);
1887+ },
1888+
1889+ _createItemContent: function(obj) {
1890+ if(this.options.template) {
1891+ var template = this.options.template.html();
1892+ Mustache.parse(template);
1893+ return Mustache.render(template, obj);
1894+ }
1895+ else {
1896+ return this.options.content.call(this, obj);
1897+ }
1898+ },
1899+
1900+ _onloadComplete: function() {
1901+ this.offset += this.options.chunkSize;
1902+ this.loading = false;
1903+ this.allLoaded = this.offset >= this.options.totalSize;
1904+
1905+ this.loadStatus.remove();
1906+
1907+ if(this.options.loader && !this.allLoaded) {
1908+ this.options.loader.show();
1909+ }
1910+ }
1911+
1912+ });
1913+
1914+})();
1915+/**
1916+ * PrimeUI Datatable Widget
1917+ */
1918+(function() {
1919+
1920+ $.widget("primeui.puidatatable", {
1921+
1922+ options: {
1923+ columns: null,
1924+ datasource: null,
1925+ paginator: null,
1926+ globalFilter:null,
1927+ selectionMode: null,
1928+ caption: null,
1929+ footer: null,
1930+ sortField: null,
1931+ sortOrder: 1,
1932+ sortMeta: [],
1933+ sortMode: null,
1934+ scrollable: false,
1935+ scrollHeight: null,
1936+ scrollWidth: null,
1937+ responsive: false,
1938+ expandableRows: false,
1939+ expandedRowContent: null,
1940+ rowExpandMode: 'multiple',
1941+ draggableColumns: false,
1942+ resizableColumns: false,
1943+ columnResizeMode: 'fit',
1944+ draggableRows: false,
1945+ filterDelay: 300,
1946+ stickyHeader: false,
1947+ editMode: null,
1948+ tabindex: 0,
1949+ emptyMessage: 'No records found',
1950+ sort: null,
1951+ rowSelect: null,
1952+ rowUnselect: null,
1953+ rowSelectContextMenu: null,
1954+ rowCollapse: null,
1955+ rowExpand: null,
1956+ colReorder: null,
1957+ colResize: null,
1958+ rowReorder: null,
1959+ cellEdit: null
1960+ },
1961+
1962+ _create: function() {
1963+ this.id = this.element.attr('id');
1964+ if(!this.id) {
1965+ this.id = this.element.uniqueId().attr('id');
1966+ }
1967+
1968+ this.element.addClass('ui-datatable ui-widget');
1969+ if(this.options.responsive) {
1970+ this.element.addClass('ui-datatable-reflow');
1971+ }
1972+
1973+ if(this.options.scrollable) {
1974+ this._createScrollableDatatable();
1975+ }
1976+ else {
1977+ this._createRegularDatatable();
1978+ }
1979+
1980+ if(this.options.datasource) {
1981+ if($.isArray(this.options.datasource)) {
1982+ this._onDataInit(this.options.datasource);
1983+ }
1984+ else {
1985+ if($.type(this.options.datasource) === 'string') {
1986+ var $this = this,
1987+ dataURL = this.options.datasource;
1988+
1989+ this.options.datasource = function() {
1990+ $.ajax({
1991+ type: 'GET',
1992+ url: dataURL,
1993+ dataType: "json",
1994+ context: $this,
1995+ success: function (response) {
1996+ this._onDataInit(response);
1997+ }
1998+ });
1999+ };
2000+ }
2001+
2002+ if($.type(this.options.datasource) === 'function') {
2003+ if(this.options.lazy)
2004+ this.options.datasource.call(this, this._onDataInit, {first:0, rows:this._getRows(), sortField:this.options.sortField, sortOrder:this.options.sortOrder, filters: this._createFilterMap()});
2005+ else
2006+ this.options.datasource.call(this, this._onDataInit);
2007+ }
2008+ }
2009+ }
2010+ },
2011+
2012+ _createRegularDatatable: function() {
2013+ this.tableWrapper = $('<div class="ui-datatable-tablewrapper" />').appendTo(this.element);
2014+ this.table = $('<table><thead></thead><tbody></tbody></table>').appendTo(this.tableWrapper);
2015+ this.thead = this.table.children('thead');
2016+ this.tbody = this.table.children('tbody').addClass('ui-datatable-data ui-widget-content');
2017+
2018+ if(this.containsFooter()) {
2019+ this.tfoot = this.thead.after('<tfoot></tfoot>').next();
2020+ }
2021+ },
2022+
2023+ _createScrollableDatatable: function() {
2024+ this.element.append('<div class="ui-widget-header ui-datatable-scrollable-header"><div class="ui-datatable-scrollable-header-box"><table><thead></thead></table></div></div>')
2025+ .append('<div class="ui-datatable-scrollable-body"><table><tbody></tbody></table></div>');
2026+
2027+ this.thead = this.element.find('> .ui-datatable-scrollable-header > .ui-datatable-scrollable-header-box > table > thead');
2028+ this.tbody = this.element.find('> .ui-datatable-scrollable-body > table > tbody');
2029+
2030+ if(this.containsFooter()) {
2031+ this.element.append('<div class="ui-widget-header ui-datatable-scrollable-footer"><div class="ui-datatable-scrollable-footer-box"><table><tfoot></tfoot></table></div></div>');
2032+ this.tfoot = this.element.find('> .ui-datatable-scrollable-footer > .ui-datatable-scrollable-footer-box > table > tfoot');
2033+ }
2034+ },
2035+
2036+ _initialize: function() {
2037+ var $this = this;
2038+
2039+ this._initHeader();
2040+ this._initFooter();
2041+
2042+ if(this.options.caption) {
2043+ this.element.prepend('<div class="ui-datatable-header ui-widget-header">' + this.options.caption + '</div>');
2044+ }
2045+
2046+ if(this.options.paginator) {
2047+ this.options.paginator.paginate = function(event, state) {
2048+ $this.paginate();
2049+ };
2050+
2051+ this.options.paginator.totalRecords = this.options.lazy ? this.options.paginator.totalRecords : this.data.length;
2052+ this.paginator = $('<div></div>').insertAfter(this.tableWrapper).puipaginator(this.options.paginator);
2053+ if(this.options.paginator.contentLeft) {
2054+ this.paginator.prepend(this.options.paginator.contentLeft.call());
2055+ }
2056+ if(this.options.paginator.contentRight) {
2057+ this.paginator.append(this.options.paginator.contentRight.call());
2058+ }
2059+ }
2060+
2061+ if(this.options.footer) {
2062+ this.element.append('<div class="ui-datatable-footer ui-widget-header">' + this.options.footer + '</div>');
2063+ }
2064+
2065+ if(this._isSortingEnabled()) {
2066+ this._initSorting();
2067+ }
2068+
2069+ if(this.hasFiltering) {
2070+ this._initFiltering();
2071+ }
2072+
2073+ if(this.options.selectionMode) {
2074+ this._initSelection();
2075+ }
2076+
2077+ if(this.options.expandableRows) {
2078+ this._initExpandableRows();
2079+ }
2080+
2081+ if(this.options.draggableColumns) {
2082+ this._initDraggableColumns();
2083+ }
2084+
2085+ if(this.options.stickyHeader) {
2086+ this._initStickyHeader();
2087+ }
2088+
2089+ if ((this.options.sortField && this.options.sortOrder) || this.options.sortMeta.length) {
2090+ this.sortByDefault();
2091+ }
2092+ else {
2093+ this._renderData();
2094+ }
2095+
2096+ if(this.options.scrollable) {
2097+ this._initScrolling();
2098+ }
2099+
2100+ if(this.options.resizableColumns) {
2101+ this._initResizableColumns();
2102+ }
2103+
2104+ if(this.options.draggableRows) {
2105+ this._initDraggableRows();
2106+ }
2107+
2108+ if(this.options.editMode) {
2109+ this._initEditing();
2110+ }
2111+
2112+ },
2113+
2114+ _initHeader: function() {
2115+ if(this.options.headerRows) {
2116+ for(var i = 0; i < this.options.headerRows.length; i++) {
2117+ this._initHeaderColumns(this.options.headerRows[i].columns);
2118+ }
2119+ }
2120+ else if(this.options.columns) {
2121+ this._initHeaderColumns(this.options.columns);
2122+ }
2123+ },
2124+
2125+ _initFooter: function() {
2126+ if(this.containsFooter()) {
2127+ if(this.options.footerRows) {
2128+ for(var i = 0; i < this.options.footerRows.length; i++) {
2129+ this._initFooterColumns(this.options.footerRows[i].columns);
2130+ }
2131+ }
2132+ else if(this.options.columns) {
2133+ this._initFooterColumns(this.options.columns);
2134+ }
2135+ }
2136+ },
2137+
2138+ _initHeaderColumns: function(columns) {
2139+ var headerRow = $('<tr class="ui-state-default"></tr>').appendTo(this.thead),
2140+ $this = this;
2141+
2142+ $.each(columns, function(i, col) {
2143+ var cell = $('<th class="ui-state-default"><span class="ui-column-title"></span></th>').data('field', col.field).uniqueId().appendTo(headerRow);
2144+
2145+ if(col.headerClass) {
2146+ cell.addClass(col.headerClass);
2147+ }
2148+
2149+ if(col.headerStyle) {
2150+ cell.attr('style', col.headerStyle);
2151+ }
2152+
2153+ if(col.headerText)
2154+ cell.children('.ui-column-title').text(col.headerText);
2155+ else if(col.headerContent)
2156+ cell.children('.ui-column-title').append(col.headerContent.call(this, col));
2157+
2158+ if(col.rowspan) {
2159+ cell.attr('rowspan', col.rowspan);
2160+ }
2161+
2162+ if(col.colspan) {
2163+ cell.attr('colspan', col.colspan);
2164+ }
2165+
2166+ if(col.sortable) {
2167+ cell.addClass('ui-sortable-column')
2168+ .data('order', 0)
2169+ .append('<span class="ui-sortable-column-icon fa fa-fw fa-sort"></span>');
2170+ }
2171+
2172+ if(col.filter) {
2173+ $this.hasFiltering = true;
2174+
2175+ var filterElement = $('<input type="text" class="ui-column-filter" />').puiinputtext().data({
2176+ 'field': col.field,
2177+ 'filtermatchmode': col.filterMatchMode||'startsWith'
2178+ }).appendTo(cell);
2179+
2180+ if(col.filterFunction) {
2181+ filterElement.on('filter', function(event, dataValue, filterValue) {
2182+ return col.filterFunction.call($this, dataValue, filterValue);
2183+ });
2184+ }
2185+ }
2186+ });
2187+ },
2188+
2189+ _initFooterColumns: function(columns) {
2190+ var footerRow = $('<tr></tr>').appendTo(this.tfoot);
2191+ $.each(columns, function(i, col) {
2192+ var cell = $('<td class="ui-state-default"></td>');
2193+ if(col.footerText) {
2194+ cell.text(col.footerText);
2195+ }
2196+
2197+ if(col.rowspan) {
2198+ cell.attr('rowspan', col.rowspan);
2199+ }
2200+
2201+ if(col.colspan) {
2202+ cell.attr('colspan', col.colspan);
2203+ }
2204+
2205+ cell.appendTo(footerRow);
2206+ });
2207+ },
2208+
2209+ _indicateInitialSortColumn: function(sortField, sortOrder) {
2210+ var $this = this;
2211+
2212+ $.each(this.sortableColumns, function(i, column) {
2213+ var $column = $(column),
2214+ data = $column.data();
2215+
2216+ if (sortField === data.field) {
2217+ var sortIcon = $column.children('.ui-sortable-column-icon');
2218+ $column.data('order', sortOrder).removeClass('ui-state-hover').addClass('ui-state-active');
2219+
2220+ if(sortOrder == -1)
2221+ sortIcon.removeClass('fa-sort fa-sort-asc').addClass('fa-sort-desc');
2222+ else if(sortOrder == 1)
2223+ sortIcon.removeClass('fa-sort fa-sort-desc').addClass('fa-sort-asc');
2224+ }
2225+ });
2226+ },
2227+
2228+ _indicateInitialSortColumns: function() {
2229+ var $this = this;
2230+
2231+ for(var i = 0; i < this.options.sortMeta.length; i++) {
2232+ var meta = this.options.sortMeta[i];
2233+ this._indicateInitialSortColumn(meta.field, meta.order);
2234+ }
2235+ },
2236+
2237+ _onDataInit: function(data) {
2238+ this.data = data;
2239+ if(!this.data) {
2240+ this.data = [];
2241+ }
2242+
2243+ this._initialize();
2244+ },
2245+
2246+ _onDataUpdate: function(data) {
2247+ this.data = data;
2248+ if(!this.data) {
2249+ this.data = [];
2250+ }
2251+
2252+ this.reset();
2253+
2254+ this._renderData();
2255+ },
2256+
2257+ _onLazyLoad: function(data) {
2258+ this.data = data;
2259+ if(!this.data) {
2260+ this.data = [];
2261+ }
2262+
2263+ this._renderData();
2264+ },
2265+
2266+ reset: function() {
2267+ if(this.options.selectionMode) {
2268+ this.selection = [];
2269+ }
2270+
2271+ if(this.paginator) {
2272+ this.paginator.puipaginator('setState', {
2273+ page: 0,
2274+ totalRecords: this.options.lazy ? this.options.paginator.totalRecords : this.data.length
2275+ });
2276+ }
2277+
2278+ this.thead.find('> tr > th.ui-sortable-column').data('order', 0).filter('.ui-state-active').removeClass('ui-state-active')
2279+ .children('span.ui-sortable-column-icon').removeClass('fa-sort-asc fa-sort-desc').addClass('fa-sort');
2280+ },
2281+
2282+ _isMultiSort: function() {
2283+ if(this.options.sortMode === 'multiple')
2284+ return true;
2285+ else
2286+ return false;
2287+ },
2288+
2289+ _resetSortState: function(column) {
2290+ this.sortableColumns.filter('.ui-state-active').data('order', 0).removeClass('ui-state-active').children('span.ui-sortable-column-icon')
2291+ .removeClass('fa-sort-asc fa-sort-desc').addClass('fa-sort');
2292+ },
2293+
2294+ _initSorting: function() {
2295+ var $this = this;
2296+ this.sortableColumns = this.thead.find('> tr > th.ui-sortable-column');
2297+
2298+ this.sortableColumns.on('mouseover.puidatatable', function() {
2299+ var column = $(this);
2300+
2301+ if(!column.hasClass('ui-state-active'))
2302+ column.addClass('ui-state-hover');
2303+ })
2304+ .on('mouseout.puidatatable', function() {
2305+ var column = $(this);
2306+
2307+ if(!column.hasClass('ui-state-active'))
2308+ column.removeClass('ui-state-hover');
2309+ })
2310+ .on('click.puidatatable', function(event) {
2311+ if(!$(event.target).is('th,span')) {
2312+ return;
2313+ }
2314+
2315+ var column = $(this),
2316+ sortField = column.data('field'),
2317+ order = column.data('order'),
2318+ sortOrder = (order === 0) ? 1 : (order * -1),
2319+ sortIcon = column.children('.ui-sortable-column-icon'),
2320+ metaKey = event.metaKey||event.ctrlKey;
2321+
2322+ if($this._isMultiSort()) {
2323+ if(metaKey) {
2324+ $this._addSortMeta({field: sortField, order: sortOrder});
2325+ $this.sort();
2326+ }
2327+ else {
2328+ $this.options.sortMeta = [];
2329+ $this._addSortMeta({field: sortField, order: sortOrder});
2330+ $this._resetSortState(column);
2331+ $this.sort();
2332+ }
2333+ }
2334+ else {
2335+ //update state
2336+ $this.options.sortField = sortField;
2337+ $this.options.sortOrder = sortOrder;
2338+
2339+ $this._resetSortState(column);
2340+ $this.sort();
2341+ }
2342+
2343+ //update visuals
2344+ column.data('order', sortOrder).removeClass('ui-state-hover').addClass('ui-state-active');
2345+ if(sortOrder === -1)
2346+ sortIcon.removeClass('fa-sort fa-sort-asc').addClass('fa-sort-desc');
2347+ else if(sortOrder === 1)
2348+ sortIcon.removeClass('fa-sort fa-sort-desc').addClass('fa-sort-asc');
2349+
2350+ $this._trigger('sort', event, {'sortOrder': sortOrder, 'sortField': sortField});
2351+ });
2352+ },
2353+
2354+ _addSortMeta: function(meta) {
2355+ var index = -1;
2356+ for(var i = 0; i < this.options.sortMeta.length; i++) {
2357+ if(this.options.sortMeta[i].field === meta.field) {
2358+ index = i;
2359+ }
2360+ }
2361+
2362+ if(index >= 0)
2363+ this.options.sortMeta[index] = meta;
2364+ else
2365+ this.options.sortMeta.push(meta);
2366+ },
2367+
2368+ paginate: function() {
2369+ if(this.options.lazy) {
2370+ this.options.datasource.call(this, this._onLazyLoad, this._createStateMeta());
2371+ }
2372+ else {
2373+ this._renderData();
2374+ }
2375+ },
2376+
2377+ _multipleSort: function() {
2378+ var $this = this;
2379+
2380+ function multisort(data1,data2,sortMeta,index) {
2381+ var value1 = data1[sortMeta[index].field],
2382+ value2 = data2[sortMeta[index].field],
2383+ result = null;
2384+
2385+ if (typeof value1 == 'string' || value1 instanceof String) {
2386+ if (value1.localeCompare && (value1 != value2)) {
2387+ return (sortMeta[index].order * value1.localeCompare(value2));
2388+ }
2389+ }
2390+ else {
2391+ result = (value1 < value2) ? -1 : 1;
2392+ }
2393+
2394+ if(value1 == value2) {
2395+ return (sortMeta.length - 1) > (index) ? (multisort(data1, data2, sortMeta, index + 1)) : 0;
2396+ }
2397+
2398+ return (sortMeta[index].order * result);
2399+ }
2400+
2401+ this.data.sort(function (data1,data2) {
2402+ return multisort(data1, data2, $this.options.sortMeta, 0);
2403+ });
2404+
2405+ this._renderData();
2406+ },
2407+
2408+ sort: function() {
2409+ if(this.options.lazy) {
2410+ this.options.datasource.call(this, this._onLazyLoad, this._createStateMeta());
2411+ }
2412+ else {
2413+ if(this._isMultiSort())
2414+ this._multipleSort();
2415+ else
2416+ this._singleSort();
2417+ }
2418+ },
2419+
2420+ _singleSort: function() {
2421+ var $this = this;
2422+
2423+ this.data.sort(function(data1, data2) {
2424+ var value1 = data1[$this.options.sortField], value2 = data2[$this.options.sortField],
2425+ result = null;
2426+
2427+ if (typeof value1 == 'string' || value1 instanceof String) {
2428+ if ( value1.localeCompare ) {
2429+ return ($this.options.sortOrder * value1.localeCompare(value2));
2430+ }
2431+ else {
2432+ if (value1.toLowerCase) {
2433+ value1 = value1.toLowerCase();
2434+ }
2435+ if (value2.toLowerCase) {
2436+ value2 = value2.toLowerCase();
2437+ }
2438+ result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
2439+
2440+ }
2441+ }
2442+ else {
2443+ result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
2444+ }
2445+
2446+ return ($this.options.sortOrder * result);
2447+ });
2448+
2449+ if(this.paginator) {
2450+ this.paginator.puipaginator('option', 'page', 0);
2451+ }
2452+
2453+ this._renderData();
2454+ },
2455+
2456+ sortByField: function(a, b) {
2457+ var aName = a.name.toLowerCase();
2458+ var bName = b.name.toLowerCase();
2459+ return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
2460+ },
2461+
2462+ sortByDefault: function() {
2463+ if(this._isMultiSort()) {
2464+ if(this.options.sortMeta) {
2465+ this._indicateInitialSortColumns();
2466+ this.sort();
2467+ }
2468+ }
2469+ else {
2470+ this._indicateInitialSortColumn(this.options.sortField, this.options.sortOrder);
2471+ this.sort();
2472+ }
2473+ },
2474+
2475+ _renderData: function() {
2476+ this.tbody.html('');
2477+
2478+ var dataToRender = this.filteredData||this.data;
2479+ if(dataToRender && dataToRender.length) {
2480+ var firstNonLazy = this._getFirst(),
2481+ first = this.options.lazy ? 0 : firstNonLazy,
2482+ rows = this._getRows();
2483+
2484+ for(var i = first; i < (first + rows); i++) {
2485+ var rowData = dataToRender[i];
2486+
2487+ if(rowData) {
2488+ var row = $('<tr class="ui-widget-content" />').appendTo(this.tbody),
2489+ zebraStyle = (i%2 === 0) ? 'ui-datatable-even' : 'ui-datatable-odd',
2490+ rowIndex = i;
2491+
2492+ row.addClass(zebraStyle);
2493+ row.data('rowdata', rowData);
2494+
2495+ if(this.options.selectionMode && this._isSelected(rowData)) {
2496+ row.addClass("ui-state-highlight");
2497+ }
2498+
2499+ for(var j = 0; j < this.options.columns.length; j++) {
2500+ var column = $('<td />').appendTo(row),
2501+ columnOptions = this.options.columns[j];
2502+
2503+ if(columnOptions.bodyClass) {
2504+ column.addClass(columnOptions.bodyClass);
2505+ }
2506+
2507+ if(columnOptions.bodyStyle) {
2508+ column.attr('style', columnOptions.bodyStyle);
2509+ }
2510+
2511+ if(columnOptions.editor) {
2512+ column.addClass('ui-editable-column').data({
2513+ 'editor': columnOptions.editor,
2514+ 'rowdata': rowData,
2515+ 'field': columnOptions.field
2516+ });
2517+ }
2518+
2519+ if(columnOptions.content) {
2520+ var content = columnOptions.content.call(this, rowData, columnOptions);
2521+ if($.type(content) === 'string')
2522+ column.html(content);
2523+ else
2524+ column.append(content);
2525+ }
2526+ else if(columnOptions.rowToggler) {
2527+ column.append('<div class="ui-row-toggler fa fa-fw fa-chevron-circle-right ui-c"></div>');
2528+ }
2529+ else if(columnOptions.field) {
2530+ column.text(rowData[columnOptions.field]);
2531+ }
2532+
2533+ if(this.options.responsive && columnOptions.headerText) {
2534+ column.prepend('<span class="ui-column-title">' + columnOptions.headerText + '</span>');
2535+ }
2536+ }
2537+ }
2538+ }
2539+ }
2540+ else {
2541+ var emptyRow = $('<tr class="ui-widget-content"></tr>').appendTo(this.tbody);
2542+ var emptyColumn = $('<td></td>').attr('colspan',this.options.columns.length).appendTo(emptyRow);
2543+ emptyColumn.html(this.options.emptyMessage);
2544+ }
2545+ },
2546+
2547+ _getFirst: function() {
2548+ if(this.paginator) {
2549+ var page = this.paginator.puipaginator('option', 'page'),
2550+ rows = this.paginator.puipaginator('option', 'rows');
2551+
2552+ return (page * rows);
2553+ }
2554+ else {
2555+ return 0;
2556+ }
2557+ },
2558+
2559+ _getRows: function() {
2560+ return this.paginator ? this.paginator.puipaginator('option', 'rows') : (this.data ? this.data.length : 0);
2561+ },
2562+
2563+ _isSortingEnabled: function() {
2564+ var cols = this.options.columns;
2565+ if(cols) {
2566+ for(var i = 0; i < cols.length; i++) {
2567+ if(cols[i].sortable) {
2568+ return true;
2569+ }
2570+ }
2571+ }
2572+
2573+ return false;
2574+ },
2575+
2576+ _initSelection: function() {
2577+ var $this = this;
2578+ this.selection = [];
2579+ this.rowSelector = '> tr.ui-widget-content:not(.ui-datatable-empty-message,.ui-datatable-unselectable)';
2580+
2581+ //shift key based range selection
2582+ if(this._isMultipleSelection()) {
2583+ this.originRowIndex = 0;
2584+ this.cursorIndex = null;
2585+ }
2586+
2587+ this.tbody.off('mouseover.puidatatable mouseout.puidatatable mousedown.puidatatable click.puidatatable', this.rowSelector)
2588+ .on('mouseover.datatable', this.rowSelector, null, function() {
2589+ var element = $(this);
2590+
2591+ if(!element.hasClass('ui-state-highlight')) {
2592+ element.addClass('ui-state-hover');
2593+ }
2594+ })
2595+ .on('mouseout.datatable', this.rowSelector, null, function() {
2596+ var element = $(this);
2597+
2598+ if(!element.hasClass('ui-state-highlight')) {
2599+ element.removeClass('ui-state-hover');
2600+ }
2601+ })
2602+ .on('mousedown.datatable', this.rowSelector, null, function() {
2603+ $this.mousedownOnRow = true;
2604+ })
2605+ .on('click.datatable', this.rowSelector, null, function(e) {
2606+ $this._onRowClick(e, this);
2607+ $this.mousedownOnRow = false;
2608+ });
2609+
2610+ this._bindSelectionKeyEvents();
2611+ },
2612+
2613+ _onRowClick: function(event, rowElement) {
2614+ if(!$(event.target).is(':input,:button,a,.ui-c')) {
2615+ var row = $(rowElement),
2616+ selected = row.hasClass('ui-state-highlight'),
2617+ metaKey = event.metaKey||event.ctrlKey,
2618+ shiftKey = event.shiftKey;
2619+
2620+ this.focusedRow = row;
2621+
2622+ //unselect a selected row if metakey is on
2623+ if(selected && metaKey) {
2624+ this.unselectRow(row);
2625+ }
2626+ else {
2627+ //unselect previous selection if this is single selection or multiple one with no keys
2628+ if(this._isSingleSelection() || (this._isMultipleSelection() && !metaKey && !shiftKey)) {
2629+ if (this._isMultipleSelection()) {
2630+ var selections = this.getSelection();
2631+ for (var i = 0; i < selections.length; i++) {
2632+ this._trigger('rowUnselect', null, selections[i]);
2633+ }
2634+ }
2635+
2636+ this.unselectAllRows();
2637+ }
2638+
2639+ this.selectRow(row, false, event);
2640+ }
2641+
2642+ PUI.clearSelection();
2643+ }
2644+ },
2645+
2646+ onRowRightClick: function(event, rowElement) {
2647+ var row = $(rowElement),
2648+ selectedData = row.data('rowdata'),
2649+ selected = row.hasClass('ui-state-highlight');
2650+
2651+ if(this._isSingleSelection() || !selected) {
2652+ this.unselectAllRows();
2653+ }
2654+
2655+ this.selectRow(row, true);
2656+ this.dataSelectedByContextMenu = selectedData;
2657+ this._trigger('rowSelectContextMenu', event, selectedData);
2658+
2659+ PUI.clearSelection();
2660+ },
2661+
2662+ _bindSelectionKeyEvents: function() {
2663+ var $this = this;
2664+
2665+ this.tbody.attr('tabindex', this.options.tabindex).on('focus', function(e) {
2666+ //ignore mouse click on row
2667+ if(!$this.mousedownOnRow) {
2668+ $this.focusedRow = $this.tbody.children('tr.ui-widget-content').eq(0);
2669+ $this.focusedRow.addClass('ui-state-hover');
2670+ }
2671+ })
2672+ .on('blur', function() {
2673+ if($this.focusedRow) {
2674+ $this.focusedRow.removeClass('ui-state-hover');
2675+ $this.focusedRow = null;
2676+ }
2677+ })
2678+ .on('keydown', function(e) {
2679+ var keyCode = $.ui.keyCode,
2680+ key = e.which;
2681+
2682+ if($this.focusedRow) {
2683+ switch(key) {
2684+ case keyCode.UP:
2685+ var prevRow = $this.focusedRow.prev('tr.ui-widget-content');
2686+ if(prevRow.length) {
2687+ $this.focusedRow.removeClass('ui-state-hover');
2688+ $this.focusedRow = prevRow;
2689+ $this.focusedRow.addClass('ui-state-hover');
2690+ }
2691+ e.preventDefault();
2692+ break;
2693+
2694+ case keyCode.DOWN:
2695+ var nextRow = $this.focusedRow.next('tr.ui-widget-content');
2696+ if(nextRow.length) {
2697+ $this.focusedRow.removeClass('ui-state-hover');
2698+ $this.focusedRow = nextRow;
2699+ $this.focusedRow.addClass('ui-state-hover');
2700+ }
2701+ e.preventDefault();
2702+ break;
2703+
2704+ case keyCode.ENTER:
2705+ case keyCode.NUMPAD_ENTER:
2706+ case keyCode.SPACE:
2707+ e.target = $this.focusedRow.children().eq(0).get(0);
2708+ $this._onRowClick(e, $this.focusedRow.get(0));
2709+ e.preventDefault();
2710+ break;
2711+
2712+ default:
2713+ break;
2714+ };
2715+ }
2716+ });
2717+
2718+ },
2719+
2720+ _isSingleSelection: function() {
2721+ return this.options.selectionMode === 'single';
2722+ },
2723+
2724+ _isMultipleSelection: function() {
2725+ return this.options.selectionMode === 'multiple';
2726+ },
2727+
2728+ unselectAllRows: function() {
2729+ this.tbody.children('tr.ui-state-highlight').removeClass('ui-state-highlight').attr('aria-selected', false);
2730+ this.selection = [];
2731+ },
2732+
2733+ unselectRow: function(row, silent) {
2734+ var unselectedData = row.data('rowdata');
2735+ row.removeClass('ui-state-highlight').attr('aria-selected', false);
2736+
2737+ this._removeSelection(unselectedData);
2738+
2739+ if(!silent) {
2740+ this._trigger('rowUnselect', null, unselectedData);
2741+ }
2742+ },
2743+
2744+ selectRow: function(row, silent, event) {
2745+ var selectedData = row.data('rowdata');
2746+ row.removeClass('ui-state-hover').addClass('ui-state-highlight').attr('aria-selected', true);
2747+
2748+ this._addSelection(selectedData);
2749+
2750+ if(!silent) {
2751+ this._trigger('rowSelect', event, selectedData);
2752+ }
2753+ },
2754+
2755+ getSelection: function() {
2756+ return this.selection;
2757+ },
2758+
2759+ _removeSelection: function(rowData) {
2760+ this.selection = $.grep(this.selection, function(value) {
2761+ return value !== rowData;
2762+ });
2763+ },
2764+
2765+ _addSelection: function(rowData) {
2766+ if(!this._isSelected(rowData)) {
2767+ this.selection.push(rowData);
2768+ }
2769+ },
2770+
2771+ _isSelected: function(rowData) {
2772+ return PUI.inArray(this.selection, rowData);
2773+ },
2774+
2775+ _initExpandableRows: function() {
2776+ var $this = this,
2777+ togglerSelector = '> tr > td > div.ui-row-toggler';
2778+
2779+ this.tbody.off('click', togglerSelector)
2780+ .on('click', togglerSelector, null, function() {
2781+ $this.toggleExpansion($(this));
2782+ })
2783+ .on('keydown', togglerSelector, null, function(e) {
2784+ var key = e.which,
2785+ keyCode = $.ui.keyCode;
2786+
2787+ if((key === keyCode.ENTER||key === keyCode.NUMPAD_ENTER)) {
2788+ $this.toggleExpansion($(this));
2789+ e.preventDefault();
2790+ }
2791+ });
2792+ },
2793+
2794+ toggleExpansion: function(toggler) {
2795+ var row = toggler.closest('tr'),
2796+ expanded = toggler.hasClass('fa-chevron-circle-down');
2797+
2798+ if(expanded) {
2799+ toggler.addClass('fa-chevron-circle-right').removeClass('fa-chevron-circle-down').attr('aria-expanded', false);
2800+
2801+ this.collapseRow(row);
2802+ this._trigger('rowCollapse', null, row.data('rowdata'));
2803+ }
2804+ else {
2805+ if(this.options.rowExpandMode === 'single') {
2806+ this.collapseAllRows();
2807+ }
2808+
2809+ toggler.addClass('fa-chevron-circle-down').removeClass('fa-chevron-circle-right').attr('aria-expanded', true);
2810+
2811+ this.loadExpandedRowContent(row);
2812+ }
2813+ },
2814+
2815+ loadExpandedRowContent: function(row) {
2816+ var expandedRow = $('<tr class="ui-expanded-row-content ui-datatable-unselectable ui-widget-content"><td colspan="' + this.options.columns.length + '"></td></tr>');
2817+ expandedRow.children('td').append(this.options.expandedRowContent.call(this, row.data('rowdata')));
2818+
2819+ row.addClass('ui-expanded-row').after(expandedRow);
2820+ this._trigger('rowExpand', null, row.data('rowdata'));
2821+ },
2822+
2823+ collapseRow: function(row) {
2824+ row.removeClass('ui-expanded-row').next('.ui-expanded-row-content').remove();
2825+ },
2826+
2827+ collapseAllRows: function() {
2828+ var $this = this;
2829+
2830+ this.getExpandedRows().each(function () {
2831+ var expandedRow = $(this);
2832+ $this.collapseRow(expandedRow);
2833+
2834+ var columns = expandedRow.children('td');
2835+ for (var i = 0; i < columns.length; i++) {
2836+ var column = columns.eq(i),
2837+ toggler = column.children('.ui-row-toggler');
2838+
2839+ if (toggler.length) {
2840+ toggler.addClass('fa-chevron-circle-right').removeClass('fa-chevron-circle-down');
2841+ }
2842+ }
2843+ });
2844+ },
2845+
2846+ getExpandedRows: function () {
2847+ return this.tbody.children('.ui-expanded-row');
2848+ },
2849+
2850+ _createStateMeta: function() {
2851+ var state = {
2852+ first: this._getFirst(),
2853+ rows: this._getRows(),
2854+ sortField: this.options.sortField,
2855+ sortOrder: this.options.sortOrder,
2856+ sortMeta: this.options.sortMeta,
2857+ filters: this.filterMetaMap
2858+ };
2859+
2860+ return state;
2861+ },
2862+
2863+ _updateDatasource: function(datasource) {
2864+ this.options.datasource = datasource;
2865+
2866+ if($.isArray(this.options.datasource)) {
2867+ this._onDataUpdate(this.options.datasource);
2868+ }
2869+ else if($.type(this.options.datasource) === 'function') {
2870+ if(this.options.lazy)
2871+ this.options.datasource.call(this, this._onDataUpdate, {first:0, rows: this._getRows(), sortField:this.options.sortField, sortorder:this.options.sortOrder, filters: this._createFilterMap()});
2872+ else
2873+ this.options.datasource.call(this, this._onDataUpdate);
2874+ }
2875+ },
2876+
2877+ _setOption: function(key, value) {
2878+ if(key === 'datasource') {
2879+ this._updateDatasource(value);
2880+ }
2881+ else {
2882+ $.Widget.prototype._setOption.apply(this, arguments);
2883+ }
2884+ },
2885+
2886+ _initScrolling: function() {
2887+ this.scrollHeader = this.element.children('.ui-datatable-scrollable-header');
2888+ this.scrollBody = this.element.children('.ui-datatable-scrollable-body');
2889+ this.scrollHeaderBox = this.scrollHeader.children('.ui-datatable-scrollable-header-box');
2890+ this.headerTable = this.scrollHeaderBox.children('table');
2891+ this.bodyTable = this.scrollBody.children('table');
2892+ this.percentageScrollHeight = this.options.scrollHeight && (this.options.scrollHeight.indexOf('%') !== -1);
2893+ this.percentageScrollWidth = this.options.scrollWidth && (this.options.scrollWidth.indexOf('%') !== -1);
2894+ var $this = this,
2895+ scrollBarWidth = this.getScrollbarWidth() + 'px';
2896+
2897+ if(this.options.scrollHeight) {
2898+ if(this.percentageScrollHeight)
2899+ this.adjustScrollHeight();
2900+ else
2901+ this.scrollBody.css('max-height', this.options.scrollHeight + 'px');
2902+
2903+ if(this.hasVerticalOverflow()) {
2904+ this.scrollHeaderBox.css('margin-right', scrollBarWidth);
2905+ }
2906+ }
2907+
2908+ this.fixColumnWidths();
2909+
2910+ if(this.options.scrollWidth) {
2911+ if(this.percentageScrollWidth)
2912+ this.adjustScrollWidth();
2913+ else
2914+ this.setScrollWidth(parseInt(this.options.scrollWidth));
2915+ }
2916+
2917+ this.cloneHead();
2918+
2919+ this.scrollBody.on('scroll.dataTable', function() {
2920+ var scrollLeft = $this.scrollBody.scrollLeft();
2921+ $this.scrollHeaderBox.css('margin-left', -scrollLeft);
2922+ });
2923+
2924+ this.scrollHeader.on('scroll.dataTable', function() {
2925+ $this.scrollHeader.scrollLeft(0);
2926+ });
2927+
2928+ var resizeNS = 'resize.' + this.id;
2929+ $(window).off(resizeNS).on(resizeNS, function() {
2930+ if($this.element.is(':visible')) {
2931+ if($this.percentageScrollHeight)
2932+ $this.adjustScrollHeight();
2933+
2934+ if($this.percentageScrollWidth)
2935+ $this.adjustScrollWidth();
2936+ }
2937+ });
2938+ },
2939+
2940+ cloneHead: function() {
2941+ this.theadClone = this.thead.clone();
2942+ this.theadClone.find('th').each(function() {
2943+ var header = $(this);
2944+ header.attr('id', header.attr('id') + '_clone');
2945+ $(this).children().not('.ui-column-title').remove();
2946+ });
2947+ this.theadClone.removeAttr('id').addClass('ui-datatable-scrollable-theadclone').height(0).prependTo(this.bodyTable);
2948+
2949+ //align horizontal scroller on keyboard tab
2950+ if(this.options.scrollWidth) {
2951+ var clonedSortableColumns = this.theadClone.find('> tr > th.ui-sortable-column');
2952+ clonedSortableColumns.each(function() {
2953+ $(this).data('original', $(this).attr('id').split('_clone')[0]);
2954+ });
2955+
2956+ clonedSortableColumns.on('blur.dataTable', function() {
2957+ $(PUI.escapeClientId($(this).data('original'))).removeClass('ui-state-focus');
2958+ })
2959+ .on('focus.dataTable', function() {
2960+ $(PUI.escapeClientId($(this).data('original'))).addClass('ui-state-focus');
2961+ })
2962+ .on('keydown.dataTable', function(e) {
2963+ var key = e.which,
2964+ keyCode = $.ui.keyCode;
2965+
2966+ if((key === keyCode.ENTER||key === keyCode.NUMPAD_ENTER) && $(e.target).is(':not(:input)')) {
2967+ $(PUI.escapeClientId($(this).data('original'))).trigger('click.dataTable', (e.metaKey||e.ctrlKey));
2968+ e.preventDefault();
2969+ }
2970+ });
2971+ }
2972+ },
2973+
2974+ adjustScrollHeight: function() {
2975+ var relativeHeight = this.element.parent().innerHeight() * (parseInt(this.options.scrollHeight) / 100),
2976+ tableHeaderHeight = this.element.children('.ui-datatable-header').outerHeight(true),
2977+ tableFooterHeight = this.element.children('.ui-datatable-footer').outerHeight(true),
2978+ scrollersHeight = (this.scrollHeader.outerHeight(true) + this.scrollFooter.outerHeight(true)),
2979+ paginatorsHeight = this.paginator ? this.paginator.getContainerHeight(true) : 0,
2980+ height = (relativeHeight - (scrollersHeight + paginatorsHeight + tableHeaderHeight + tableFooterHeight));
2981+
2982+ this.scrollBody.css('max-height', height + 'px');
2983+ },
2984+
2985+ adjustScrollWidth: function() {
2986+ var width = parseInt((this.element.parent().innerWidth() * (parseInt(this.options.scrollWidth) / 100)));
2987+ this.setScrollWidth(width);
2988+ },
2989+
2990+ setOuterWidth: function(element, width) {
2991+ var diff = element.outerWidth() - element.width();
2992+ element.width(width - diff);
2993+ },
2994+
2995+ setScrollWidth: function(width) {
2996+ var $this = this;
2997+ this.element.children('.ui-widget-header').each(function() {
2998+ $this.setOuterWidth($(this), width);
2999+ });
3000+ this.scrollHeader.width(width);
3001+ this.scrollBody.css('margin-right', 0).width(width);
3002+ },
3003+
3004+ alignScrollBody: function() {
3005+ var marginRight = this.hasVerticalOverflow() ? this.getScrollbarWidth() + 'px' : '0px';
3006+
3007+ this.scrollHeaderBox.css('margin-right', marginRight);
3008+ },
3009+
3010+ getScrollbarWidth: function() {
3011+ if(!this.scrollbarWidth) {
3012+ this.scrollbarWidth = PUI.browser.webkit ? '15' : PUI.calculateScrollbarWidth();
3013+ }
3014+
3015+ return this.scrollbarWidth;
3016+ },
3017+
3018+ hasVerticalOverflow: function() {
3019+ return (this.options.scrollHeight && this.bodyTable.outerHeight() > this.scrollBody.outerHeight())
3020+ },
3021+
3022+ restoreScrollState: function() {
3023+ var scrollState = this.scrollStateHolder.val(),
3024+ scrollValues = scrollState.split(',');
3025+
3026+ this.scrollBody.scrollLeft(scrollValues[0]);
3027+ this.scrollBody.scrollTop(scrollValues[1]);
3028+ },
3029+
3030+ saveScrollState: function() {
3031+ var scrollState = this.scrollBody.scrollLeft() + ',' + this.scrollBody.scrollTop();
3032+
3033+ this.scrollStateHolder.val(scrollState);
3034+ },
3035+
3036+ clearScrollState: function() {
3037+ this.scrollStateHolder.val('0,0');
3038+ },
3039+
3040+ fixColumnWidths: function() {
3041+ if(!this.columnWidthsFixed) {
3042+ if(this.options.scrollable) {
3043+ this.scrollHeaderBox.find('> table > thead > tr > th').each(function() {
3044+ var headerCol = $(this),
3045+ width = headerCol.width();
3046+ headerCol.width(width);
3047+ });
3048+ }
3049+ else {
3050+ this.element.find('> .ui-datatable-tablewrapper > table > thead > tr > th').each(function() {
3051+ var col = $(this);
3052+ col.width(col.width());
3053+ });
3054+ }
3055+
3056+ this.columnWidthsFixed = true;
3057+ }
3058+ },
3059+
3060+ _initDraggableColumns: function() {
3061+ var $this = this;
3062+
3063+ this.dragIndicatorTop = $('<span class="fa fa-arrow-down" style="position:absolute"/></span>').hide().appendTo(this.element);
3064+ this.dragIndicatorBottom = $('<span class="fa fa-arrow-up" style="position:absolute"/></span>').hide().appendTo(this.element);
3065+
3066+ this.thead.find('> tr > th').draggable({
3067+ appendTo: 'body',
3068+ opacity: 0.75,
3069+ cursor: 'move',
3070+ scope: this.id,
3071+ cancel: ':input,.ui-column-resizer',
3072+ drag: function(event, ui) {
3073+ var droppable = ui.helper.data('droppable-column');
3074+
3075+ if(droppable) {
3076+ var droppableOffset = droppable.offset(),
3077+ topArrowY = droppableOffset.top - 10,
3078+ bottomArrowY = droppableOffset.top + droppable.height() + 8,
3079+ arrowX = null;
3080+
3081+ //calculate coordinates of arrow depending on mouse location
3082+ if(event.originalEvent.pageX >= droppableOffset.left + (droppable.width() / 2)) {
3083+ var nextDroppable = droppable.next();
3084+ if(nextDroppable.length == 1)
3085+ arrowX = nextDroppable.offset().left - 9;
3086+ else
3087+ arrowX = droppable.offset().left + droppable.innerWidth() - 9;
3088+
3089+ ui.helper.data('drop-location', 1); //right
3090+ }
3091+ else {
3092+ arrowX = droppableOffset.left - 9;
3093+ ui.helper.data('drop-location', -1); //left
3094+ }
3095+
3096+ $this.dragIndicatorTop.offset({
3097+ 'left': arrowX,
3098+ 'top': topArrowY - 3
3099+ }).show();
3100+
3101+ $this.dragIndicatorBottom.offset({
3102+ 'left': arrowX,
3103+ 'top': bottomArrowY - 3
3104+ }).show();
3105+ }
3106+ },
3107+ stop: function(event, ui) {
3108+ //hide dnd arrows
3109+ $this.dragIndicatorTop.css({
3110+ 'left':0,
3111+ 'top':0
3112+ }).hide();
3113+
3114+ $this.dragIndicatorBottom.css({
3115+ 'left':0,
3116+ 'top':0
3117+ }).hide();
3118+ },
3119+ helper: function() {
3120+ var header = $(this),
3121+ helper = $('<div class="ui-widget ui-state-default" style="padding:4px 10px;text-align:center;"></div>');
3122+
3123+ helper.width(header.width());
3124+ helper.height(header.height());
3125+
3126+ helper.html(header.html());
3127+
3128+ return helper.get(0);
3129+ }
3130+ }).droppable({
3131+ hoverClass:'ui-state-highlight',
3132+ tolerance:'pointer',
3133+ scope: this.id,
3134+ over: function(event, ui) {
3135+ ui.helper.data('droppable-column', $(this));
3136+ },
3137+ drop: function(event, ui) {
3138+ var draggedColumnHeader = ui.draggable,
3139+ dropLocation = ui.helper.data('drop-location'),
3140+ droppedColumnHeader = $(this),
3141+ draggedColumnFooter = null,
3142+ droppedColumnFooter = null;
3143+
3144+ var draggedCells = $this.tbody.find('> tr:not(.ui-expanded-row-content) > td:nth-child(' + (draggedColumnHeader.index() + 1) + ')'),
3145+ droppedCells = $this.tbody.find('> tr:not(.ui-expanded-row-content) > td:nth-child(' + (droppedColumnHeader.index() + 1) + ')');
3146+
3147+ if($this.containsFooter()) {
3148+ var footerColumns = $this.tfoot.find('> tr > td'),
3149+ draggedColumnFooter = footerColumns.eq(draggedColumnHeader.index()),
3150+ droppedColumnFooter = footerColumns.eq(droppedColumnHeader.index());
3151+ }
3152+
3153+ //drop right
3154+ if(dropLocation > 0) {
3155+ /* TODO :Resizable columns
3156+ * if($this.options.resizableColumns) {
3157+ if(droppedColumnHeader.next().length) {
3158+ droppedColumnHeader.children('span.ui-column-resizer').show();
3159+ draggedColumnHeader.children('span.ui-column-resizer').hide();
3160+ }
3161+ }*/
3162+
3163+ draggedColumnHeader.insertAfter(droppedColumnHeader);
3164+
3165+ draggedCells.each(function(i, item) {
3166+ $(this).insertAfter(droppedCells.eq(i));
3167+ });
3168+
3169+ if(draggedColumnFooter && droppedColumnFooter) {
3170+ draggedColumnFooter.insertAfter(droppedColumnFooter);
3171+ }
3172+
3173+ //sync clone
3174+ if($this.options.scrollable) {
3175+ var draggedColumnClone = $(document.getElementById(draggedColumnHeader.attr('id') + '_clone')),
3176+ droppedColumnClone = $(document.getElementById(droppedColumnHeader.attr('id') + '_clone'));
3177+ draggedColumnClone.insertAfter(droppedColumnClone);
3178+ }
3179+ }
3180+ //drop left
3181+ else {
3182+ draggedColumnHeader.insertBefore(droppedColumnHeader);
3183+
3184+ draggedCells.each(function(i, item) {
3185+ $(this).insertBefore(droppedCells.eq(i));
3186+ });
3187+
3188+ if(draggedColumnFooter && droppedColumnFooter) {
3189+ draggedColumnFooter.insertBefore(droppedColumnFooter);
3190+ }
3191+
3192+ //sync clone
3193+ if($this.options.scrollable) {
3194+ var draggedColumnClone = $(document.getElementById(draggedColumnHeader.attr('id') + '_clone')),
3195+ droppedColumnClone = $(document.getElementById(droppedColumnHeader.attr('id') + '_clone'));
3196+ draggedColumnClone.insertBefore(droppedColumnClone);
3197+ }
3198+ }
3199+
3200+ //fire colReorder event
3201+ $this._trigger('colReorder', null, {
3202+ dragIndex: draggedColumnHeader.index(),
3203+ dropIndex: droppedColumnHeader.index()
3204+ });
3205+ }
3206+ });
3207+ },
3208+
3209+ containsFooter: function() {
3210+ if(this.hasFooter === undefined) {
3211+ this.hasFooter = this.options.footerRows !== undefined;
3212+ if(!this.hasFooter) {
3213+ if(this.options.columns) {
3214+ for(var i = 0; i < this.options.columns.length; i++) {
3215+ if(this.options.columns[i].footerText !== undefined) {
3216+ this.hasFooter = true;
3217+ break;
3218+ }
3219+ }
3220+ }
3221+ }
3222+ }
3223+
3224+ return this.hasFooter;
3225+ },
3226+
3227+ _initResizableColumns: function() {
3228+ this.element.addClass('ui-datatable-resizable');
3229+ this.thead.find('> tr > th').addClass('ui-resizable-column');
3230+ this.resizerHelper = $('<div class="ui-column-resizer-helper ui-state-highlight"></div>').appendTo(this.element);
3231+ this.addResizers();
3232+ var resizers = this.thead.find('> tr > th > span.ui-column-resizer'),
3233+ $this = this;
3234+
3235+ setTimeout(function() {
3236+ $this.fixColumnWidths();
3237+ }, 5);
3238+
3239+ resizers.draggable({
3240+ axis: 'x',
3241+ start: function(event, ui) {
3242+ ui.helper.data('originalposition', ui.helper.offset());
3243+
3244+ var height = $this.options.scrollable ? $this.scrollBody.height() : $this.thead.parent().height() - $this.thead.height() - 1;
3245+ $this.resizerHelper.height(height);
3246+ $this.resizerHelper.show();
3247+ },
3248+ drag: function(event, ui) {
3249+ $this.resizerHelper.offset({
3250+ left: ui.helper.offset().left + ui.helper.width() / 2,
3251+ top: $this.thead.offset().top + $this.thead.height()
3252+ });
3253+ },
3254+ stop: function(event, ui) {
3255+ ui.helper.css({
3256+ 'left': '',
3257+ 'top': '0px',
3258+ 'right': '0px'
3259+ });
3260+
3261+ $this.resize(event, ui);
3262+ $this.resizerHelper.hide();
3263+
3264+ if($this.options.columnResizeMode === 'expand') {
3265+ setTimeout(function() {
3266+ $this._trigger('colResize', null, {element: ui.helper.parent()});
3267+ }, 5);
3268+ }
3269+ else {
3270+ $this._trigger('colResize', null, {element: ui.helper.parent()});
3271+ }
3272+
3273+ if($this.options.stickyHeader) {
3274+ $this.thead.find('.ui-column-filter').prop('disabled', false);
3275+ $this.clone = $this.thead.clone(true);
3276+ $this.cloneContainer.find('thead').remove();
3277+ $this.cloneContainer.children('table').append($this.clone);
3278+ $this.thead.find('.ui-column-filter').prop('disabled', true);
3279+ }
3280+ },
3281+ containment: this.element
3282+ });
3283+ },
3284+
3285+ resize: function(event, ui) {
3286+ var columnHeader, nextColumnHeader, change = null, newWidth = null, nextColumnWidth = null,
3287+ expandMode = (this.options.columnResizeMode === 'expand'),
3288+ table = this.thead.parent(),
3289+ columnHeader = ui.helper.parent(),
3290+ nextColumnHeader = columnHeader.next();
3291+
3292+ change = (ui.position.left - ui.originalPosition.left),
3293+ newWidth = (columnHeader.width() + change),
3294+ nextColumnWidth = (nextColumnHeader.width() - change);
3295+
3296+ if((newWidth > 15 && nextColumnWidth > 15) || (expandMode && newWidth > 15)) {
3297+ if(expandMode) {
3298+ table.width(table.width() + change);
3299+ setTimeout(function() {
3300+ columnHeader.width(newWidth);
3301+ }, 1);
3302+ }
3303+ else {
3304+ columnHeader.width(newWidth);
3305+ nextColumnHeader.width(nextColumnWidth);
3306+ }
3307+
3308+ if(this.options.scrollable) {
3309+ var cloneTable = this.theadClone.parent(),
3310+ colIndex = columnHeader.index();
3311+
3312+ if(expandMode) {
3313+ var $this = this;
3314+
3315+ //body
3316+ cloneTable.width(cloneTable.width() + change);
3317+
3318+ //footer
3319+ this.footerTable.width(this.footerTable.width() + change);
3320+
3321+ setTimeout(function() {
3322+ if($this.hasColumnGroup) {
3323+ $this.theadClone.find('> tr:first').children('th').eq(colIndex).width(newWidth); //body
3324+ $this.footerTable.find('> tfoot > tr:first').children('th').eq(colIndex).width(newWidth); //footer
3325+ }
3326+ else {
3327+ $this.theadClone.find(PUI.escapeClientId(columnHeader.attr('id') + '_clone')).width(newWidth); //body
3328+ $this.footerCols.eq(colIndex).width(newWidth); //footer
3329+ }
3330+ }, 1);
3331+ }
3332+ else {
3333+ //body
3334+ this.theadClone.find(PUI.escapeClientId(columnHeader.attr('id') + '_clone')).width(newWidth);
3335+ this.theadClone.find(PUI.escapeClientId(nextColumnHeader.attr('id') + '_clone')).width(nextColumnWidth);
3336+
3337+ //footer
3338+ /*if(this.footerCols.length > 0) {
3339+ var footerCol = this.footerCols.eq(colIndex),
3340+ nextFooterCol = footerCol.next();
3341+
3342+ footerCol.width(newWidth);
3343+ nextFooterCol.width(nextColumnWidth);
3344+ }*/
3345+ }
3346+ }
3347+ }
3348+ },
3349+
3350+ addResizers: function() {
3351+ var resizableColumns = this.thead.find('> tr > th.ui-resizable-column');
3352+ resizableColumns.prepend('<span class="ui-column-resizer">&nbsp;</span>');
3353+
3354+ if(this.options.columnResizeMode === 'fit') {
3355+ resizableColumns.filter(':last-child').children('span.ui-column-resizer').hide();
3356+ }
3357+ },
3358+
3359+ _initDraggableRows: function() {
3360+ var $this = this;
3361+
3362+ this.tbody.sortable({
3363+ placeholder: 'ui-datatable-rowordering ui-state-active',
3364+ cursor: 'move',
3365+ handle: 'td,span:not(.ui-c)',
3366+ appendTo: document.body,
3367+ helper: function(event, ui) {
3368+ var cells = ui.children(),
3369+ helper = $('<div class="ui-datatable ui-widget"><table><tbody></tbody></table></div>'),
3370+ helperRow = ui.clone(),
3371+ helperCells = helperRow.children();
3372+
3373+ for(var i = 0; i < helperCells.length; i++) {
3374+ helperCells.eq(i).width(cells.eq(i).width());
3375+ }
3376+
3377+ helperRow.appendTo(helper.find('tbody'));
3378+
3379+ return helper;
3380+ },
3381+ update: function(event, ui) {
3382+ $this.syncRowParity();
3383+
3384+ $this._trigger('rowReorder', null, {
3385+ fromIndex: ui.item.data('ri'),
3386+ toIndex: $this._getFirst() + ui.item.index()
3387+ });
3388+ },
3389+ change: function(event, ui) {
3390+ if($this.options.scrollable) {
3391+ PUI.scrollInView($this.scrollBody, ui.placeholder);
3392+ }
3393+ }
3394+ });
3395+ },
3396+
3397+ syncRowParity: function() {
3398+ var rows = this.tbody.children('tr.ui-widget-content');
3399+
3400+ for(var i = this._getFirst(); i < rows.length; i++) {
3401+ var row = rows.eq(i);
3402+
3403+ row.data('ri', i).removeClass('ui-datatable-even ui-datatable-odd');
3404+
3405+ if(i % 2 === 0)
3406+ row.addClass('ui-datatable-even');
3407+ else
3408+ row.addClass('ui-datatable-odd');
3409+
3410+ }
3411+ },
3412+
3413+ getContextMenuSelection: function(data) {
3414+ return this.dataSelectedByContextMenu;
3415+ },
3416+
3417+ _initFiltering: function() {
3418+ var $this = this;
3419+ this.filterElements = this.thead.find('.ui-column-filter');
3420+
3421+ this.filterElements.on('keyup', function() {
3422+ if($this.filterTimeout) {
3423+ clearTimeout($this.filterTimeout);
3424+ }
3425+
3426+ $this.filterTimeout = setTimeout(function() {
3427+ $this.filter();
3428+ $this.filterTimeout = null;
3429+ },
3430+ $this.options.filterDelay);
3431+ });
3432+
3433+ if(this.options.globalFilter) {
3434+ $(this.options.globalFilter).on('keyup.puidatatable', function() {
3435+ $this.filter();
3436+ });
3437+ }
3438+ },
3439+
3440+ filter: function() {
3441+ this.filterMetaMap = [];
3442+
3443+ for(var i = 0; i < this.filterElements.length; i++) {
3444+ var filterElement = this.filterElements.eq(i),
3445+ filterElementValue = filterElement.val();
3446+
3447+ this.filterMetaMap.push({
3448+ field: filterElement.data('field'),
3449+ filterMatchMode: filterElement.data('filtermatchmode'),
3450+ value: filterElementValue.toLowerCase(),
3451+ element: filterElement
3452+ });
3453+ }
3454+
3455+ if(this.options.lazy) {
3456+ this.options.datasource.call(this, this._onLazyLoad, this._createStateMeta());
3457+ }
3458+ else {
3459+ var globalFilterValue = $(this.options.globalFilter).val();
3460+ this.filteredData = [];
3461+
3462+ for(var i = 0; i < this.data.length; i++) {
3463+ var localMatch = true;
3464+ var globalMatch = false;
3465+
3466+ for(var j = 0; j < this.filterMetaMap.length; j++) {
3467+ var filterMeta = this.filterMetaMap[j],
3468+ filterValue = filterMeta.value,
3469+ filterField = filterMeta.field,
3470+ dataFieldValue = this.data[i][filterField];
3471+
3472+ var filterConstraint = this.filterConstraints[filterMeta.filterMatchMode];
3473+
3474+ //global
3475+ if(this.options.globalFilter && !globalMatch) {
3476+ var filterConstraint = this.filterConstraints['contains'];
3477+ globalMatch = filterConstraint(dataFieldValue, globalFilterValue);
3478+
3479+ }
3480+
3481+ //local
3482+ if(filterMeta.filterMatchMode === 'custom') {
3483+ localMatch = filterMeta.element.triggerHandler('filter', [dataFieldValue, filterValue]);
3484+ }
3485+ else {
3486+ var filterConstraint = this.filterConstraints[filterMeta.filterMatchMode];
3487+ if(!filterConstraint(dataFieldValue, filterValue)) {
3488+ localMatch = false;
3489+ }
3490+ }
3491+
3492+ if(!localMatch) {
3493+ break;
3494+ }
3495+ }
3496+
3497+ var matches = localMatch;
3498+
3499+ if(this.options.globalFilter) {
3500+ matches = localMatch && globalMatch;
3501+ }
3502+
3503+ if(matches) {
3504+ this.filteredData.push(this.data[i]);
3505+ }
3506+ }
3507+
3508+ if(this.filteredData.length === this.data.length) {
3509+ this.filteredData = null;
3510+ }
3511+
3512+ if(this.paginator) {
3513+ this.paginator.puipaginator('option', 'totalRecords', this.filteredData ? this.filteredData.length : this.data ? this.data.length : 0);
3514+ }
3515+
3516+ this._renderData();
3517+ }
3518+ },
3519+
3520+ filterConstraints: {
3521+
3522+ startsWith: function(value, filter) {
3523+ if(filter === undefined || filter === null || $.trim(filter) === '') {
3524+ return true;
3525+ }
3526+
3527+ if(value === undefined || value === null) {
3528+ return false;
3529+ }
3530+
3531+ return value.toString().toLowerCase().slice(0, filter.length) === filter;
3532+ },
3533+
3534+ contains: function(value, filter) {
3535+ if(filter === undefined || filter === null || $.trim(filter) === '') {
3536+ return true;
3537+ }
3538+
3539+ if(value === undefined || value === null) {
3540+ return false;
3541+ }
3542+
3543+ return value.toString().toLowerCase().indexOf(filter) !== -1;
3544+ }
3545+
3546+ },
3547+
3548+ _initStickyHeader: function() {
3549+ var table = this.thead.parent(),
3550+ offset = table.offset(),
3551+ win = $(window),
3552+ $this = this,
3553+ stickyNS = 'scroll.' + this.id,
3554+ resizeNS = 'resize.sticky-' + this.id;
3555+
3556+ this.cloneContainer = $('<div class="ui-datatable ui-datatable-sticky ui-widget"><table></table></div>');
3557+ this.clone = this.thead.clone(true);
3558+ this.cloneContainer.children('table').append(this.clone);
3559+
3560+ this.cloneContainer.css({
3561+ position: 'absolute',
3562+ width: table.outerWidth(),
3563+ top: offset.top,
3564+ left: offset.left,
3565+ 'z-index': ++PUI.zindex
3566+ })
3567+ .appendTo(this.element);
3568+
3569+ win.off(stickyNS).on(stickyNS, function() {
3570+ var scrollTop = win.scrollTop(),
3571+ tableOffset = table.offset();
3572+
3573+ if(scrollTop > tableOffset.top) {
3574+ $this.cloneContainer.css({
3575+ 'position': 'fixed',
3576+ 'top': '0px'
3577+ })
3578+ .addClass('ui-shadow ui-sticky');
3579+
3580+ if(scrollTop >= (tableOffset.top + $this.tbody.height()))
3581+ $this.cloneContainer.hide();
3582+ else
3583+ $this.cloneContainer.show();
3584+ }
3585+ else {
3586+ $this.cloneContainer.css({
3587+ 'position': 'absolute',
3588+ 'top': tableOffset.top
3589+ })
3590+ .removeClass('ui-shadow ui-sticky');
3591+ }
3592+ })
3593+ .off(resizeNS).on(resizeNS, function() {
3594+ $this.cloneContainer.width(table.outerWidth());
3595+ });
3596+
3597+ //filter support
3598+ this.thead.find('.ui-column-filter').prop('disabled', true);
3599+ },
3600+
3601+ _initEditing: function() {
3602+ var cellSelector = '> tr > td.ui-editable-column',
3603+ $this = this;
3604+
3605+ this.tbody.off('click', cellSelector)
3606+ .on('click', cellSelector, null, function(e) {
3607+ var cell = $(this);
3608+ if(!cell.hasClass('ui-cell-editing')) {
3609+ $this._showCellEditor(cell);
3610+ e.stopPropagation();
3611+ }
3612+ });
3613+ },
3614+
3615+ _showCellEditor: function(cell) {
3616+ var editor = this.editors[cell.data('editor')].call(),
3617+ $this = this;
3618+
3619+ editor.val(cell.data('rowdata')[cell.data('field')]);
3620+
3621+ cell.addClass('ui-cell-editing').html('').append(editor);
3622+
3623+ editor.focus().on('change', function() {
3624+ $this._onCellEditorChange(cell);
3625+ })
3626+ .on('blur', function() {
3627+ $this._onCellEditorBlur(cell);
3628+ })
3629+ .on('keydown', function(e) {
3630+ var key = e.which,
3631+ keyCode = $.ui.keyCode;
3632+
3633+ if((key === keyCode.ENTER||key === keyCode.NUMPAD_ENTER)) {
3634+ $(this).trigger('change').trigger('blur');
3635+ e.preventDefault();
3636+ }
3637+ else if(key === keyCode.TAB) {
3638+ if(e.shiftKey) {
3639+ var prevCell = cell.prevAll('td.ui-editable-column').eq(0);
3640+ if(!prevCell.length) {
3641+ prevCell = cell.parent().prev('tr').children('td.ui-editable-column:last');
3642+ }
3643+ if(prevCell.length) {
3644+ $this._showCellEditor(prevCell);
3645+ }
3646+ }
3647+ else {
3648+ var nextCell = cell.nextAll('td.ui-editable-column').eq(0);
3649+ if(!nextCell.length) {
3650+ nextCell = cell.parent().next('tr').children('td.ui-editable-column').eq(0);
3651+ }
3652+ if(nextCell.length) {
3653+ $this._showCellEditor(nextCell);
3654+ }
3655+ }
3656+
3657+ e.preventDefault();
3658+ } else if(key === keyCode.ESCAPE) {
3659+ $this._onCellEditorBlur(cell);
3660+ }
3661+
3662+ });
3663+ },
3664+
3665+ _onCellEditorChange: function(cell) {
3666+ var newCellValue = cell.children('.ui-cell-editor').val();
3667+
3668+ var retVal = this._trigger('cellEdit', null, {
3669+ oldValue: cell.data('rowdata')[cell.data('field')],
3670+ newValue: newCellValue,
3671+ data: cell.data('rowdata'),
3672+ field: cell.data('field')
3673+ });
3674+
3675+ if(retVal !== false) {
3676+ cell.data('rowdata')[cell.data('field')] = newCellValue;
3677+ }
3678+ },
3679+
3680+ _onCellEditorBlur: function(cell) {
3681+ cell.removeClass('ui-cell-editing').text(cell.data('rowdata')[cell.data('field')])
3682+ .children('.ui-cell-editor').remove();
3683+ },
3684+
3685+ reload: function() {
3686+ this._updateDatasource(this.options.datasource);
3687+ },
3688+
3689+ getPaginator: function() {
3690+ return this.paginator;
3691+ },
3692+
3693+ setTotalRecords: function(val) {
3694+ this.paginator.puipaginator('option','totalRecords', val);
3695+ },
3696+
3697+ _createFilterMap: function() {
3698+ var filters = null;
3699+ if(this.filterElements) {
3700+ filters = {};
3701+ for(var i = 0; i < this.filterElements.length; i++) {
3702+ var filterElement = this.filterElements.eq(i),
3703+ value = filterElement.val();
3704+ if($.trim(value).length) {
3705+ filters[filterElement.data('field')] = value;
3706+ }
3707+ }
3708+ }
3709+
3710+ return filters;
3711+ },
3712+
3713+ editors: {
3714+
3715+ 'input': function() {
3716+ return $('<input type="text" class="ui-cell-editor"/>');
3717+ }
3718+ }
3719+
3720+ });
3721+})();
3722+
3723+/**
3724+ * PrimeUI Dialog Widget
3725+ */
3726+(function() {
3727+
3728+ $.widget("primeui.puidialog", {
3729+
3730+ options: {
3731+ draggable: true,
3732+ resizable: true,
3733+ location: 'center',
3734+ minWidth: 150,
3735+ minHeight: 25,
3736+ height: 'auto',
3737+ width: '300px',
3738+ visible: false,
3739+ modal: false,
3740+ showEffect: null,
3741+ hideEffect: null,
3742+ effectOptions: {},
3743+ effectSpeed: 'normal',
3744+ closeOnEscape: true,
3745+ rtl: false,
3746+ closable: true,
3747+ minimizable: false,
3748+ maximizable: false,
3749+ appendTo: null,
3750+ buttons: null,
3751+ responsive: false,
3752+ title: null,
3753+ enhanced: false
3754+ },
3755+
3756+ _create: function() {
3757+ this.id = this.element.attr('id');
3758+ if(!this.id) {
3759+ this.id = this.element.uniqueId().attr('id');
3760+ }
3761+
3762+ //container
3763+ if(!this.options.enhanced) {
3764+ this.element.addClass('ui-dialog ui-widget ui-widget-content ui-helper-hidden ui-corner-all ui-shadow')
3765+ .contents().wrapAll('<div class="ui-dialog-content ui-widget-content" />');
3766+
3767+ //header
3768+ var title = this.options.title||this.element.attr('title');
3769+ this.element.prepend('<div class="ui-dialog-titlebar ui-widget-header ui-helper-clearfix ui-corner-top">' +
3770+ '<span id="' + this.element.attr('id') + '_label" class="ui-dialog-title">' + title + '</span>')
3771+ .removeAttr('title');
3772+
3773+ //footer
3774+ if(this.options.buttons) {
3775+ this.footer = $('<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"></div>').appendTo(this.element);
3776+ for(var i = 0; i < this.options.buttons.length; i++) {
3777+ var buttonMeta = this.options.buttons[i],
3778+ button = $('<button type="button"></button>').appendTo(this.footer);
3779+ if(buttonMeta.text) {
3780+ button.text(buttonMeta.text);
3781+ }
3782+
3783+ button.puibutton(buttonMeta);
3784+ }
3785+ }
3786+
3787+ if(this.options.rtl) {
3788+ this.element.addClass('ui-dialog-rtl');
3789+ }
3790+ }
3791+
3792+ //elements
3793+ this.content = this.element.children('.ui-dialog-content');
3794+ this.titlebar = this.element.children('.ui-dialog-titlebar');
3795+
3796+ if(!this.options.enhanced) {
3797+ if(this.options.closable) {
3798+ this._renderHeaderIcon('ui-dialog-titlebar-close', 'fa-close');
3799+ }
3800+
3801+ if(this.options.maximizable) {
3802+ this._renderHeaderIcon('ui-dialog-titlebar-maximize', 'fa-sort');
3803+ }
3804+
3805+ if(this.options.minimizable) {
3806+ this._renderHeaderIcon('ui-dialog-titlebar-minimize', 'fa-minus');
3807+ }
3808+ }
3809+
3810+ //icons
3811+ this.icons = this.titlebar.children('.ui-dialog-titlebar-icon');
3812+ this.closeIcon = this.titlebar.children('.ui-dialog-titlebar-close');
3813+ this.minimizeIcon = this.titlebar.children('.ui-dialog-titlebar-minimize');
3814+ this.maximizeIcon = this.titlebar.children('.ui-dialog-titlebar-maximize');
3815+
3816+ this.blockEvents = 'focus.puidialog mousedown.puidialog mouseup.puidialog keydown.puidialog keyup.puidialog';
3817+ this.parent = this.element.parent();
3818+
3819+ //size
3820+ this.element.css({'width': this.options.width, 'height': 'auto'});
3821+ this.content.height(this.options.height);
3822+
3823+ //events
3824+ this._bindEvents();
3825+
3826+ if(this.options.draggable) {
3827+ this._setupDraggable();
3828+ }
3829+
3830+ if(this.options.resizable) {
3831+ this._setupResizable();
3832+ }
3833+
3834+ if(this.options.appendTo) {
3835+ this.element.appendTo(this.options.appendTo);
3836+ }
3837+
3838+ if(this.options.responsive) {
3839+ this.resizeNS = 'resize.' + this.id;
3840+ }
3841+
3842+ //docking zone
3843+ if($(document.body).children('.ui-dialog-docking-zone').length === 0) {
3844+ $(document.body).append('<div class="ui-dialog-docking-zone"></div>');
3845+ }
3846+
3847+ //aria
3848+ this._applyARIA();
3849+
3850+ if(this.options.visible) {
3851+ this.show();
3852+ }
3853+ },
3854+
3855+ _destroy: function() {
3856+ //restore dom
3857+ if(!this.options.enhanced) {
3858+ this.element.removeClass('ui-dialog ui-widget ui-widget-content ui-helper-hidden ui-corner-all ui-shadow');
3859+
3860+ if(this.options.buttons) {
3861+ this.footer.children('button').puibutton('destroy');
3862+ this.footer.remove();
3863+ }
3864+
3865+ if(this.options.rtl) {
3866+ this.element.removeClass('ui-dialog-rtl');
3867+ }
3868+
3869+ var title = this.titlebar.children('.ui-dialog-title').text()||this.options.title;
3870+ if(title) {
3871+ this.element.attr('title', title);
3872+ }
3873+ this.titlebar.remove();
3874+
3875+ this.content.contents().unwrap();
3876+ }
3877+
3878+ //remove events
3879+ this._unbindEvents();
3880+
3881+ if(this.options.draggable) {
3882+ this.element.draggable('destroy');
3883+ }
3884+
3885+ if(this.options.resizable) {
3886+ this.element.resizable('destroy');
3887+ }
3888+
3889+ if(this.options.appendTo) {
3890+ this.element.appendTo(this.parent);
3891+ }
3892+
3893+ this._unbindResizeListener();
3894+
3895+ if(this.options.modal) {
3896+ this._disableModality();
3897+ }
3898+
3899+ this._removeARIA();
3900+ this.element.css({
3901+ 'width': 'auto',
3902+ 'height': 'auto'
3903+ });
3904+ },
3905+
3906+ _renderHeaderIcon: function(styleClass, icon) {
3907+ this.titlebar.append('<a class="ui-dialog-titlebar-icon ' + styleClass + ' ui-corner-all" href="#" role="button">' +
3908+ '<span class="fa fa-fw ' + icon + '"></span></a>');
3909+ },
3910+
3911+ _enableModality: function() {
3912+ var $this = this,
3913+ doc = $(document);
3914+
3915+ this.modality = $('<div id="' + this.element.attr('id') + '_modal" class="ui-widget-overlay ui-dialog-mask"></div>').appendTo(document.body)
3916+ .css('z-index', this.element.css('z-index') - 1);
3917+
3918+ //Disable tabbing out of modal dialog and stop events from targets outside of dialog
3919+ doc.on('keydown.puidialog',
3920+ function(event) {
3921+ if(event.keyCode == $.ui.keyCode.TAB) {
3922+ var tabbables = $this.content.find(':tabbable'),
3923+ first = tabbables.filter(':first'),
3924+ last = tabbables.filter(':last');
3925+
3926+ if(event.target === last[0] && !event.shiftKey) {
3927+ first.focus(1);
3928+ return false;
3929+ }
3930+ else if (event.target === first[0] && event.shiftKey) {
3931+ last.focus(1);
3932+ return false;
3933+ }
3934+ }
3935+ })
3936+ .bind(this.blockEvents, function(event) {
3937+ if ($(event.target).zIndex() < $this.element.zIndex()) {
3938+ return false;
3939+ }
3940+ });
3941+ },
3942+
3943+ _disableModality: function() {
3944+ if(this.modality) {
3945+ this.modality.remove();
3946+ this.modality = null;
3947+ }
3948+
3949+ $(document).off(this.blockEvents).off('keydown.dialog');
3950+ },
3951+
3952+ show: function() {
3953+ if(this.element.is(':visible')) {
3954+ return;
3955+ }
3956+
3957+ if(!this.positionInitialized) {
3958+ this._initPosition();
3959+ }
3960+
3961+ this._trigger('beforeShow', null);
3962+
3963+ if(this.options.showEffect) {
3964+ var $this = this;
3965+
3966+ this.element.show(this.options.showEffect, this.options.effectOptions, this.options.effectSpeed, function() {
3967+ $this._postShow();
3968+ });
3969+ }
3970+ else {
3971+ this.element.show();
3972+
3973+ this._postShow();
3974+ }
3975+
3976+ this._moveToTop();
3977+
3978+ if(this.options.modal) {
3979+ this._enableModality();
3980+ }
3981+ },
3982+
3983+ _postShow: function() {
3984+ //execute user defined callback
3985+ this._trigger('afterShow', null);
3986+
3987+ this.element.attr({
3988+ 'aria-hidden': false,
3989+ 'aria-live': 'polite'
3990+ });
3991+
3992+ this._applyFocus();
3993+
3994+ if(this.options.responsive) {
3995+ this._bindResizeListener();
3996+ }
3997+ },
3998+
3999+ hide: function() {
4000+ if(this.element.is(':hidden')) {
4001+ return;
4002+ }
4003+
4004+ this._trigger('beforeHide', null);
4005+
4006+ if(this.options.hideEffect) {
4007+ var _self = this;
4008+
4009+ this.element.hide(this.options.hideEffect, this.options.effectOptions, this.options.effectSpeed, function() {
4010+ _self._postHide();
4011+ });
4012+ }
4013+ else {
4014+ this.element.hide();
4015+
4016+ this._postHide();
4017+ }
4018+
4019+ if(this.options.modal) {
4020+ this._disableModality();
4021+ }
4022+ },
4023+
4024+ _postHide: function() {
4025+ //execute user defined callback
4026+ this._trigger('afterHide', null);
4027+
4028+ this.element.attr({
4029+ 'aria-hidden': true,
4030+ 'aria-live': 'off'
4031+ });
4032+
4033+ if(this.options.responsive) {
4034+ this._unbindResizeListener();
4035+ }
4036+ },
4037+
4038+ _applyFocus: function() {
4039+ this.element.find(':not(:submit):not(:button):input:visible:enabled:first').focus();
4040+ },
4041+
4042+ _bindEvents: function() {
4043+ var $this = this;
4044+ this.element.on('mousedown.puidialog', function(e) {
4045+ if(!$(e.target).data('ui-widget-overlay')) {
4046+ $this._moveToTop();
4047+ }
4048+ });
4049+
4050+ this.icons.mouseover(function() {
4051+ $(this).addClass('ui-state-hover');
4052+ }).mouseout(function() {
4053+ $(this).removeClass('ui-state-hover');
4054+ });
4055+
4056+ this.closeIcon.on('click.puidialog', function(e) {
4057+ $this.hide();
4058+ $this._trigger('clickClose');
4059+ e.preventDefault();
4060+ });
4061+
4062+ this.maximizeIcon.click(function(e) {
4063+ $this.toggleMaximize();
4064+ e.preventDefault();
4065+ });
4066+
4067+ this.minimizeIcon.click(function(e) {
4068+ $this.toggleMinimize();
4069+ e.preventDefault();
4070+ });
4071+
4072+ if(this.options.closeOnEscape) {
4073+ $(document).on('keydown.dialog_' + this.id, function(e) {
4074+ var keyCode = $.ui.keyCode,
4075+ active = parseInt($this.element.css('z-index'), 10) === PUI.zindex;
4076+
4077+ if(e.which === keyCode.ESCAPE && $this.element.is(':visible') && active) {
4078+ $this.hide();
4079+ $this._trigger('hideWithEscape');
4080+ }
4081+ });
4082+ }
4083+ },
4084+
4085+ _unbindEvents: function() {
4086+ this.element.off('mousedown.puidialog');
4087+ this.icons.off();
4088+ $(document).off('keydown.dialog_' + this.id);
4089+ },
4090+
4091+ _setupDraggable: function() {
4092+ this.element.draggable({
4093+ cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
4094+ handle: '.ui-dialog-titlebar',
4095+ containment : 'document'
4096+ });
4097+ },
4098+
4099+ _setupResizable: function() {
4100+ var $this = this;
4101+
4102+ this.element.resizable({
4103+ minWidth : this.options.minWidth,
4104+ minHeight : this.options.minHeight,
4105+ alsoResize : this.content,
4106+ containment: 'document',
4107+ start: function(event, ui) {
4108+ $this.element.data('offset', $this.element.offset());
4109+ },
4110+ stop: function(event, ui) {
4111+ var offset = $this.element.data('offset');
4112+
4113+ $this.element.css('position', 'fixed');
4114+ $this.element.offset(offset);
4115+ }
4116+ });
4117+
4118+ this.resizers = this.element.children('.ui-resizable-handle');
4119+ },
4120+
4121+ _initPosition: function() {
4122+ //reset
4123+ this.element.css({left:0,top:0});
4124+
4125+ if(/(center|left|top|right|bottom)/.test(this.options.location)) {
4126+ this.options.location = this.options.location.replace(',', ' ');
4127+
4128+ this.element.position({
4129+ my: 'center',
4130+ at: this.options.location,
4131+ collision: 'fit',
4132+ of: window,
4133+ //make sure dialog stays in viewport
4134+ using: function(pos) {
4135+ var l = pos.left < 0 ? 0 : pos.left,
4136+ t = pos.top < 0 ? 0 : pos.top;
4137+
4138+ $(this).css({
4139+ left: l,
4140+ top: t
4141+ });
4142+ }
4143+ });
4144+ }
4145+ else {
4146+ var coords = this.options.position.split(','),
4147+ x = $.trim(coords[0]),
4148+ y = $.trim(coords[1]);
4149+
4150+ this.element.offset({
4151+ left: x,
4152+ top: y
4153+ });
4154+ }
4155+
4156+ this.positionInitialized = true;
4157+ },
4158+
4159+ _moveToTop: function() {
4160+ this.element.css('z-index',++PUI.zindex);
4161+ },
4162+
4163+ toggleMaximize: function() {
4164+ if(this.minimized) {
4165+ this.toggleMinimize();
4166+ }
4167+
4168+ if(this.maximized) {
4169+ this.element.removeClass('ui-dialog-maximized');
4170+ this._restoreState();
4171+
4172+ this.maximizeIcon.removeClass('ui-state-hover');
4173+ this.maximized = false;
4174+ }
4175+ else {
4176+ this._saveState();
4177+
4178+ var win = $(window);
4179+
4180+ this.element.addClass('ui-dialog-maximized').css({
4181+ 'width': win.width() - 6,
4182+ 'height': win.height()
4183+ }).offset({
4184+ top: win.scrollTop(),
4185+ left: win.scrollLeft()
4186+ });
4187+
4188+ //maximize content
4189+ this.content.css({
4190+ width: 'auto',
4191+ height: 'auto'
4192+ });
4193+
4194+ this.maximizeIcon.removeClass('ui-state-hover');
4195+ this.maximized = true;
4196+ this._trigger('maximize');
4197+ }
4198+ },
4199+
4200+ toggleMinimize: function() {
4201+ var animate = true,
4202+ dockingZone = $(document.body).children('.ui-dialog-docking-zone');
4203+
4204+ if(this.maximized) {
4205+ this.toggleMaximize();
4206+ animate = false;
4207+ }
4208+
4209+ var $this = this;
4210+
4211+ if(this.minimized) {
4212+ this.element.appendTo(this.parent).removeClass('ui-dialog-minimized').css({'position':'fixed', 'float':'none'});
4213+ this._restoreState();
4214+ this.content.show();
4215+ this.minimizeIcon.removeClass('ui-state-hover').children('.fa').removeClass('fa-plus').addClass('fa-minus');
4216+ this.minimized = false;
4217+
4218+ if(this.options.resizable) {
4219+ this.resizers.show();
4220+ }
4221+
4222+ if(this.footer) {
4223+ this.footer.show();
4224+ }
4225+ }
4226+ else {
4227+ this._saveState();
4228+
4229+ if(animate) {
4230+ this.element.effect('transfer', {
4231+ to: dockingZone,
4232+ className: 'ui-dialog-minimizing'
4233+ }, 500,
4234+ function() {
4235+ $this._dock(dockingZone);
4236+ $this.element.addClass('ui-dialog-minimized');
4237+ });
4238+ }
4239+ else {
4240+ this._dock(dockingZone);
4241+ }
4242+ }
4243+ },
4244+
4245+ _dock: function(zone) {
4246+ this.element.appendTo(zone).css('position', 'static');
4247+ this.element.css({'height':'auto', 'width':'auto', 'float': 'left'});
4248+ this.content.hide();
4249+ this.minimizeIcon.removeClass('ui-state-hover').children('.fa').removeClass('fa-minus').addClass('fa-plus');
4250+ this.minimized = true;
4251+
4252+ if(this.options.resizable) {
4253+ this.resizers.hide();
4254+ }
4255+
4256+ if(this.footer) {
4257+ this.footer.hide();
4258+ }
4259+
4260+ zone.css('z-index',++PUI.zindex);
4261+
4262+ this._trigger('minimize');
4263+ },
4264+
4265+ _saveState: function() {
4266+ this.state = {
4267+ width: this.element.width(),
4268+ height: this.element.height()
4269+ };
4270+
4271+ var win = $(window);
4272+ this.state.offset = this.element.offset();
4273+ this.state.windowScrollLeft = win.scrollLeft();
4274+ this.state.windowScrollTop = win.scrollTop();
4275+ },
4276+
4277+ _restoreState: function() {
4278+ this.element.width(this.state.width).height(this.state.height);
4279+
4280+ var win = $(window);
4281+ this.element.offset({
4282+ top: this.state.offset.top + (win.scrollTop() - this.state.windowScrollTop),
4283+ left: this.state.offset.left + (win.scrollLeft() - this.state.windowScrollLeft)
4284+ });
4285+ },
4286+
4287+ _applyARIA: function() {
4288+ this.element.attr({
4289+ 'role': 'dialog',
4290+ 'aria-labelledby': this.element.attr('id') + '_title',
4291+ 'aria-hidden': !this.options.visible
4292+ });
4293+
4294+ this.titlebar.children('a.ui-dialog-titlebar-icon').attr('role', 'button');
4295+ },
4296+
4297+ _removeARIA: function() {
4298+ this.element.removeAttr('role').removeAttr('aria-labelledby').removeAttr('aria-hidden')
4299+ .removeAttr('aria-live').removeAttr('aria-hidden');
4300+ },
4301+
4302+ _bindResizeListener: function() {
4303+ var $this = this;
4304+ $(window).on(this.resizeNS, function(e) {
4305+ if(e.target === window) {
4306+ $this._initPosition();
4307+ }
4308+ });
4309+ },
4310+
4311+ _unbindResizeListener: function() {
4312+ $(window).off(this.resizeNS);
4313+ },
4314+
4315+ _setOption: function(key, value) {
4316+ if(key === 'visible') {
4317+ if(value)
4318+ this.show();
4319+ else
4320+ this.hide();
4321+ }
4322+ else {
4323+ $.Widget.prototype._setOption.apply(this, arguments);
4324+ }
4325+ }
4326+ });
4327+})();
4328+/**
4329+ * PrimeUI dropdown widget
4330+ */
4331+(function() {
4332+
4333+ $.widget("primeui.puidropdown", {
4334+
4335+ options: {
4336+ effect: 'fade',
4337+ effectSpeed: 'normal',
4338+ filter: false,
4339+ filterMatchMode: 'startsWith',
4340+ caseSensitiveFilter: false,
4341+ filterFunction: null,
4342+ data: null,
4343+ content: null,
4344+ scrollHeight: 200,
4345+ appendTo: 'body',
4346+ editable: false,
4347+ value: null,
4348+ style: null,
4349+ styleClass: null
4350+ },
4351+
4352+ _create: function() {
4353+ this.id = this.element.attr('id');
4354+ if(!this.id) {
4355+ this.id = this.element.uniqueId().attr('id');
4356+ }
4357+
4358+ if(!this.options.enhanced) {
4359+ if(this.options.data) {
4360+ if($.isArray(this.options.data)) {
4361+ this._generateOptionElements(this.options.data);
4362+ }
4363+ else {
4364+ if($.type(this.options.data) === 'function') {
4365+ this.options.data.call(this, this._onRemoteOptionsLoad);
4366+ return;
4367+ }
4368+ else {
4369+ if($.type(this.options.data) === 'string') {
4370+ var $this = this,
4371+ dataURL = this.options.data;
4372+
4373+ var loader = function() {
4374+ $.ajax({
4375+ type: 'GET',
4376+ url: dataURL,
4377+ dataType: "json",
4378+ context: $this,
4379+ success: function (response) {
4380+ this._onRemoteOptionsLoad(response);
4381+ }
4382+ });
4383+ };
4384+ loader.call(this);
4385+ }
4386+ }
4387+ return;
4388+ }
4389+ }
4390+
4391+ this._render();
4392+ }
4393+ else {
4394+ this.choices = this.element.children('option');
4395+ this.container = this.element.closest('.ui-dropdown');
4396+ this.focusElementContainer = this.container.children('.ui-helper-hidden-accessible:last');
4397+ this.focusElement = this.focusElementContainer.children('input');
4398+ this.label = this.container.children('.ui-dropdown-label');
4399+ this.menuIcon = this.container.children('.ui-dropdown-trigger');
4400+ this.panel = this.container.children('.ui-dropdown-panel');
4401+ this.itemsWrapper = this.panel.children('.ui-dropdown-items-wrapper');
4402+ this.itemsContainer = this.itemsWrapper.children('ul');
4403+ this.itemsContainer.addClass('ui-dropdown-items ui-dropdown-list ui-widget-content ui-widget ui-corner-all ui-helper-reset');
4404+ this.items = this.itemsContainer.children('li').addClass('ui-dropdown-item ui-dropdown-list-item ui-corner-all');
4405+
4406+ var $this = this;
4407+ this.items.each(function(i) {
4408+ $(this).data('label', $this.choices.eq(i).text());
4409+ });
4410+
4411+ if(this.options.filter) {
4412+ this.filterContainer = this.panel.children('.ui-dropdown-filter-container');
4413+ this.filterInput = this.filterContainer.children('input');
4414+ }
4415+ }
4416+
4417+ this._postRender();
4418+ },
4419+
4420+ _render: function() {
4421+ this.choices = this.element.children('option');
4422+ this.element.attr('tabindex', '-1').wrap('<div class="ui-dropdown ui-widget ui-state-default ui-corner-all ui-helper-clearfix" />')
4423+ .wrap('<div class="ui-helper-hidden-accessible" />');
4424+
4425+ this.container = this.element.closest('.ui-dropdown');
4426+ this.focusElementContainer = $('<div class="ui-helper-hidden-accessible"><input type="text" /></div>').appendTo(this.container);
4427+ this.focusElement = this.focusElementContainer.children('input');
4428+ this.label = this.options.editable ? $('<input type="text" class="ui-dropdown-label ui-inputtext ui-corner-all"">')
4429+ : $('<label class="ui-dropdown-label ui-inputtext ui-corner-all"/>');
4430+ this.label.appendTo(this.container);
4431+ this.menuIcon = $('<div class="ui-dropdown-trigger ui-state-default ui-corner-right"><span class="fa fa-fw fa-caret-down"></span></div>')
4432+ .appendTo(this.container);
4433+
4434+ //panel
4435+ this.panel = $('<div class="ui-dropdown-panel ui-widget-content ui-corner-all ui-helper-hidden ui-shadow" />');
4436+ this.itemsWrapper = $('<div class="ui-dropdown-items-wrapper" />').appendTo(this.panel);
4437+ this.itemsContainer = $('<ul class="ui-dropdown-items ui-dropdown-list ui-widget-content ui-widget ui-corner-all ui-helper-reset"></ul>')
4438+ .appendTo(this.itemsWrapper);
4439+
4440+ this.optGroupsSize = this.itemsContainer.children('li.puiselectonemenu-item-group').length;
4441+
4442+ if(this.options.filter) {
4443+ this.filterContainer = $('<div class="ui-dropdown-filter-container" />').prependTo(this.panel);
4444+ this.filterInput = $('<input type="text" autocomplete="off" class="ui-dropdown-filter ui-inputtext ui-widget ui-state-default ui-corner-all" />')
4445+ .appendTo(this.filterContainer);
4446+ this.filterContainer.append('<span class="fa fa-search"></span>');
4447+ }
4448+
4449+ this._generateItems();
4450+ },
4451+
4452+ _postRender: function() {
4453+ if(this.options.style) {
4454+ this.container.attr('style', this.options.style);
4455+ }
4456+
4457+ if(this.options.styleClass) {
4458+ this.container.addClass(this.options.styleClass);
4459+ }
4460+
4461+ this.disabled = this.element.prop('disabled')||this.options.disabled;
4462+
4463+ if(this.options.appendTo === 'self')
4464+ this.panel.appendTo(this.container);
4465+ else
4466+ this.panel.appendTo(this.options.appendTo);
4467+
4468+ if(this.options.scrollHeight && this.panel.outerHeight() > this.options.scrollHeight) {
4469+ this.itemsWrapper.height(this.options.scrollHeight);
4470+ }
4471+
4472+ var $this = this;
4473+
4474+ //preselection via value option
4475+ if(this.options.value) {
4476+ this.choices.filter('[value="'+this.options.value+'"]').prop('selected', true);
4477+ }
4478+
4479+ var selectedOption = this.choices.filter(':selected');
4480+
4481+ //disable options
4482+ this.choices.filter(':disabled').each(function() {
4483+ $this.items.eq($(this).index()).addClass('ui-state-disabled');
4484+ });
4485+
4486+ //triggers
4487+ this.triggers = this.options.editable ? this.menuIcon : this.container.children('.ui-dropdown-trigger, .ui-dropdown-label');
4488+
4489+ //activate selected
4490+ if(this.options.editable) {
4491+ var customInputVal = this.label.val();
4492+
4493+ //predefined input
4494+ if(customInputVal === selectedOption.text()) {
4495+ this._highlightItem(this.items.eq(selectedOption.index()));
4496+ }
4497+ //custom input
4498+ else {
4499+ this.items.eq(0).addClass('ui-state-highlight');
4500+ this.customInput = true;
4501+ this.customInputVal = customInputVal;
4502+ }
4503+ }
4504+ else {
4505+ this._highlightItem(this.items.eq(selectedOption.index()));
4506+ }
4507+
4508+ if(!this.disabled) {
4509+ this._bindEvents();
4510+ this._bindConstantEvents();
4511+ }
4512+ },
4513+
4514+ _onRemoteOptionsLoad: function(data) {
4515+ this._generateOptionElements(data);
4516+ this._render();
4517+ this._postRender();
4518+ },
4519+
4520+ _generateOptionElements: function(data) {
4521+ for(var i = 0; i < data.length; i++) {
4522+ var choice = data[i];
4523+ if(choice.label)
4524+ this.element.append('<option value="' + choice.value + '">' + choice.label + '</option>');
4525+ else
4526+ this.element.append('<option value="' + choice + '">' + choice + '</option>');
4527+ }
4528+ },
4529+
4530+ _generateItems: function() {
4531+ for(var i = 0; i < this.choices.length; i++) {
4532+ var option = this.choices.eq(i),
4533+ optionLabel = option.text(),
4534+ content = this.options.content ? this.options.content.call(this, this.options.data[i]) : optionLabel;
4535+
4536+ this.itemsContainer.append('<li data-label="' + optionLabel + '" class="ui-dropdown-item ui-dropdown-list-item ui-corner-all">' + content + '</li>');
4537+ }
4538+
4539+ this.items = this.itemsContainer.children('.ui-dropdown-item');
4540+ },
4541+
4542+ _bindEvents: function() {
4543+ var $this = this;
4544+
4545+ this.items.filter(':not(.ui-state-disabled)').each(function(i, item) {
4546+ $this._bindItemEvents($(item));
4547+ });
4548+
4549+ this.triggers.on('mouseenter.puidropdown', function() {
4550+ if(!$this.container.hasClass('ui-state-focus')) {
4551+ $this.container.addClass('ui-state-hover');
4552+ $this.menuIcon.addClass('ui-state-hover');
4553+ }
4554+ })
4555+ .on('mouseleave.puidropdown', function() {
4556+ $this.container.removeClass('ui-state-hover');
4557+ $this.menuIcon.removeClass('ui-state-hover');
4558+ })
4559+ .on('click.puidropdown', function(e) {
4560+ if($this.panel.is(":hidden")) {
4561+ $this._show();
4562+ }
4563+ else {
4564+ $this._hide();
4565+
4566+ $this._revert();
4567+ }
4568+
4569+ $this.container.removeClass('ui-state-hover');
4570+ $this.menuIcon.removeClass('ui-state-hover');
4571+ $this.focusElement.trigger('focus.puidropdown');
4572+ e.preventDefault();
4573+ });
4574+
4575+ this.focusElement.on('focus.puidropdown', function() {
4576+ $this.container.addClass('ui-state-focus');
4577+ $this.menuIcon.addClass('ui-state-focus');
4578+ })
4579+ .on('blur.puidropdown', function() {
4580+ $this.container.removeClass('ui-state-focus');
4581+ $this.menuIcon.removeClass('ui-state-focus');
4582+ });
4583+
4584+ if(this.options.editable) {
4585+ this.label.on('change.ui-dropdown', function() {
4586+ $this._triggerChange(true);
4587+ $this.customInput = true;
4588+ $this.customInputVal = $(this).val();
4589+ $this.items.filter('.ui-state-highlight').removeClass('ui-state-highlight');
4590+ $this.items.eq(0).addClass('ui-state-highlight');
4591+ });
4592+ }
4593+
4594+ this._bindKeyEvents();
4595+
4596+ if(this.options.filter) {
4597+ this._setupFilterMatcher();
4598+
4599+ this.filterInput.puiinputtext();
4600+
4601+ this.filterInput.on('keyup.ui-dropdown', function() {
4602+ $this._filter($(this).val());
4603+ });
4604+ }
4605+ },
4606+
4607+ _bindItemEvents: function(item) {
4608+ var $this = this;
4609+
4610+ item.on('mouseover.puidropdown', function() {
4611+ var el = $(this);
4612+
4613+ if(!el.hasClass('ui-state-highlight'))
4614+ $(this).addClass('ui-state-hover');
4615+ })
4616+ .on('mouseout.puidropdown', function() {
4617+ $(this).removeClass('ui-state-hover');
4618+ })
4619+ .on('click.puidropdown', function() {
4620+ $this._selectItem($(this));
4621+ });
4622+ },
4623+
4624+ _bindConstantEvents: function() {
4625+ var $this = this;
4626+
4627+ $(document.body).on('mousedown.ui-dropdown-' + this.id, function (e) {
4628+ if($this.panel.is(":hidden")) {
4629+ return;
4630+ }
4631+
4632+ var offset = $this.panel.offset();
4633+ if (e.target === $this.label.get(0) ||
4634+ e.target === $this.menuIcon.get(0) ||
4635+ e.target === $this.menuIcon.children().get(0)) {
4636+ return;
4637+ }
4638+
4639+ if (e.pageX < offset.left ||
4640+ e.pageX > offset.left + $this.panel.width() ||
4641+ e.pageY < offset.top ||
4642+ e.pageY > offset.top + $this.panel.height()) {
4643+
4644+ $this._hide();
4645+ $this._revert();
4646+ }
4647+ });
4648+
4649+ this.resizeNS = 'resize.' + this.id;
4650+ this._unbindResize();
4651+ this._bindResize();
4652+ },
4653+
4654+ _bindKeyEvents: function() {
4655+ var $this = this;
4656+
4657+ this.focusElement.on('keydown.puidropdown', function(e) {
4658+ var keyCode = $.ui.keyCode,
4659+ key = e.which,
4660+ activeItem;
4661+
4662+ switch(key) {
4663+ case keyCode.UP:
4664+ case keyCode.LEFT:
4665+ activeItem = $this._getActiveItem();
4666+ var prev = activeItem.prevAll(':not(.ui-state-disabled,.ui-selectonemenu-item-group):first');
4667+
4668+ if(prev.length == 1) {
4669+ if($this.panel.is(':hidden')) {
4670+ $this._selectItem(prev);
4671+ }
4672+ else {
4673+ $this._highlightItem(prev);
4674+ PUI.scrollInView($this.itemsWrapper, prev);
4675+ }
4676+ }
4677+
4678+ e.preventDefault();
4679+ break;
4680+
4681+ case keyCode.DOWN:
4682+ case keyCode.RIGHT:
4683+ activeItem = $this._getActiveItem();
4684+ var next = activeItem.nextAll(':not(.ui-state-disabled,.ui-selectonemenu-item-group):first');
4685+
4686+ if(next.length == 1) {
4687+ if($this.panel.is(':hidden')) {
4688+ if(e.altKey) {
4689+ $this._show();
4690+ } else {
4691+ $this._selectItem(next);
4692+ }
4693+ }
4694+ else {
4695+ $this._highlightItem(next);
4696+ PUI.scrollInView($this.itemsWrapper, next);
4697+ }
4698+ }
4699+
4700+ e.preventDefault();
4701+ break;
4702+
4703+ case keyCode.ENTER:
4704+ case keyCode.NUMPAD_ENTER:
4705+ if($this.panel.is(':hidden')) {
4706+ $this._show();
4707+ }
4708+ else {
4709+ $this._selectItem($this._getActiveItem());
4710+ }
4711+
4712+ e.preventDefault();
4713+ break;
4714+
4715+ case keyCode.TAB:
4716+ if($this.panel.is(':visible')) {
4717+ $this._revert();
4718+ $this._hide();
4719+ }
4720+ break;
4721+
4722+ case keyCode.ESCAPE:
4723+ if($this.panel.is(':visible')) {
4724+ $this._revert();
4725+ $this._hide();
4726+ }
4727+ break;
4728+
4729+ default:
4730+ var k = String.fromCharCode((96 <= key && key <= 105)? key-48 : key),
4731+ currentItem = $this.items.filter('.ui-state-highlight');
4732+
4733+ //Search items forward from current to end and on no result, search from start until current
4734+ var highlightItem = $this._search(k, currentItem.index() + 1, $this.options.length);
4735+ if(!highlightItem) {
4736+ highlightItem = $this._search(k, 0, currentItem.index());
4737+ }
4738+
4739+ if(highlightItem) {
4740+ if($this.panel.is(':hidden')) {
4741+ $this._selectItem(highlightItem);
4742+ }
4743+ else {
4744+ $this._highlightItem(highlightItem);
4745+ PUI.scrollInView($this.itemsWrapper, highlightItem);
4746+ }
4747+ }
4748+
4749+ break;
4750+ }
4751+ });
4752+ },
4753+
4754+ _unbindEvents: function() {
4755+ this.items.off('mouseover.puidropdown mouseout.puidropdown click.puidropdown');
4756+ this.triggers.off('mouseenter.puidropdown mouseleave.puidropdown click.puidropdown');
4757+ this.focusElement.off('keydown.puidropdown focus.puidropdown blur.puidropdown');
4758+
4759+ if(this.options.editable) {
4760+ this.label.off('change.puidropdown');
4761+ }
4762+
4763+ if(this.options.filter) {
4764+ this.filterInput.off('keyup.ui-dropdown');
4765+ }
4766+
4767+ $(document.body).off('mousedown.ui-dropdown-' + this.id);
4768+ this._unbindResize();
4769+ },
4770+
4771+ _selectItem: function(item, silent) {
4772+ var selectedOption = this.choices.eq(this._resolveItemIndex(item)),
4773+ currentOption = this.choices.filter(':selected'),
4774+ sameOption = selectedOption.val() == currentOption.val(),
4775+ shouldChange = null;
4776+
4777+ if(this.options.editable) {
4778+ shouldChange = (!sameOption)||(selectedOption.text() != this.label.val());
4779+ }
4780+ else {
4781+ shouldChange = !sameOption;
4782+ }
4783+
4784+ if(shouldChange) {
4785+ this._highlightItem(item);
4786+ this.element.val(selectedOption.val());
4787+
4788+ this._triggerChange();
4789+
4790+ if(this.options.editable) {
4791+ this.customInput = false;
4792+ }
4793+ }
4794+
4795+ if(!silent) {
4796+ this.focusElement.trigger('focus.puidropdown');
4797+ }
4798+
4799+ if(this.panel.is(':visible')) {
4800+ this._hide();
4801+ }
4802+ },
4803+
4804+ _highlightItem: function(item) {
4805+ this.items.filter('.ui-state-highlight').removeClass('ui-state-highlight');
4806+
4807+ if(item.length) {
4808+ item.addClass('ui-state-highlight');
4809+
4810+ this._setLabel(item.data('label'));
4811+ }
4812+ else {
4813+ this._setLabel('&nbsp;');
4814+ }
4815+ },
4816+
4817+ _triggerChange: function(edited) {
4818+ this.changed = false;
4819+ var selectedOption = this.choices.filter(':selected');
4820+
4821+ if(this.options.change) {
4822+ this._trigger('change', null, {
4823+ value: selectedOption.val(),
4824+ index: selectedOption.index()
4825+ });
4826+ }
4827+
4828+ if(!edited) {
4829+ this.value = this.choices.filter(':selected').val();
4830+ }
4831+ },
4832+
4833+ _resolveItemIndex: function(item) {
4834+ if(this.optGroupsSize === 0) {
4835+ return item.index();
4836+ }
4837+ else {
4838+ return item.index() - item.prevAll('li.ui-dropdown-item-group').length;
4839+ }
4840+ },
4841+
4842+ _setLabel: function(value) {
4843+ if(this.options.editable) {
4844+ this.label.val(value);
4845+ }
4846+ else {
4847+ if(value === '&nbsp;') {
4848+ this.label.html('&nbsp;');
4849+ }
4850+ else {
4851+ this.label.text(value);
4852+ }
4853+ }
4854+ },
4855+
4856+ _bindResize: function() {
4857+ var $this = this;
4858+
4859+ $(window).bind(this.resizeNS, function(e) {
4860+ if($this.panel.is(':visible')) {
4861+ $this._alignPanel();
4862+ }
4863+ });
4864+ },
4865+
4866+ _unbindResize: function() {
4867+ $(window).unbind(this.resizeNS);
4868+ },
4869+
4870+ _alignPanelWidth: function() {
4871+ if(!this.panelWidthAdjusted) {
4872+ var jqWidth = this.container.outerWidth();
4873+ if(this.panel.outerWidth() < jqWidth) {
4874+ this.panel.width(jqWidth);
4875+ }
4876+
4877+ this.panelWidthAdjusted = true;
4878+ }
4879+ },
4880+
4881+ _alignPanel: function() {
4882+ if(this.panel.parent().is(this.container)) {
4883+ this.panel.css({
4884+ left: '0px',
4885+ top: this.container.outerHeight() + 'px'
4886+ })
4887+ .width(this.container.outerWidth());
4888+ }
4889+ else {
4890+ this._alignPanelWidth();
4891+ this.panel.css({left:'', top:''}).position({
4892+ my: 'left top',
4893+ at: 'left bottom',
4894+ of: this.container,
4895+ collision: 'flipfit'
4896+ });
4897+ }
4898+ },
4899+
4900+ _show: function() {
4901+ this._alignPanel();
4902+
4903+ this.panel.css('z-index', ++PUI.zindex);
4904+
4905+ if(this.options.effect !== 'none') {
4906+ this.panel.show(this.options.effect, {}, this.options.effectSpeed);
4907+ }
4908+ else {
4909+ this.panel.show();
4910+ }
4911+ this.preShowValue = this.choices.filter(':selected');
4912+ },
4913+
4914+ _hide: function() {
4915+ this.panel.hide();
4916+ },
4917+
4918+ _revert: function() {
4919+ if(this.options.editable && this.customInput) {
4920+ this._setLabel(this.customInputVal);
4921+ this.items.filter('.ui-state-active').removeClass('ui-state-active');
4922+ this.items.eq(0).addClass('ui-state-active');
4923+ }
4924+ else {
4925+ this._highlightItem(this.items.eq(this.preShowValue.index()));
4926+ }
4927+ },
4928+
4929+ _getActiveItem: function() {
4930+ return this.items.filter('.ui-state-highlight');
4931+ },
4932+
4933+ _setupFilterMatcher: function() {
4934+ this.filterMatchers = {
4935+ 'startsWith': this._startsWithFilter,
4936+ 'contains': this._containsFilter,
4937+ 'endsWith': this._endsWithFilter,
4938+ 'custom': this.options.filterFunction
4939+ };
4940+
4941+ this.filterMatcher = this.filterMatchers[this.options.filterMatchMode];
4942+ },
4943+
4944+ _startsWithFilter: function(value, filter) {
4945+ return value.indexOf(filter) === 0;
4946+ },
4947+
4948+ _containsFilter: function(value, filter) {
4949+ return value.indexOf(filter) !== -1;
4950+ },
4951+
4952+ _endsWithFilter: function(value, filter) {
4953+ return value.indexOf(filter, value.length - filter.length) !== -1;
4954+ },
4955+
4956+ _filter: function(value) {
4957+ this.initialHeight = this.initialHeight||this.itemsWrapper.height();
4958+ var filterValue = this.options.caseSensitiveFilter ? $.trim(value) : $.trim(value).toLowerCase();
4959+
4960+ if(filterValue === '') {
4961+ this.items.filter(':hidden').show();
4962+ }
4963+ else {
4964+ for(var i = 0; i < this.choices.length; i++) {
4965+ var option = this.choices.eq(i),
4966+ itemLabel = this.options.caseSensitiveFilter ? option.text() : option.text().toLowerCase(),
4967+ item = this.items.eq(i);
4968+
4969+ if(this.filterMatcher(itemLabel, filterValue))
4970+ item.show();
4971+ else
4972+ item.hide();
4973+ }
4974+ }
4975+
4976+ if(this.itemsContainer.height() < this.initialHeight) {
4977+ this.itemsWrapper.css('height', 'auto');
4978+ }
4979+ else {
4980+ this.itemsWrapper.height(this.initialHeight);
4981+ }
4982+
4983+ this._alignPanel();
4984+ },
4985+
4986+ _search: function(text, start, end) {
4987+ for(var i = start; i < end; i++) {
4988+ var option = this.choices.eq(i);
4989+
4990+ if(option.text().indexOf(text) === 0) {
4991+ return this.items.eq(i);
4992+ }
4993+ }
4994+
4995+ return null;
4996+ },
4997+
4998+ getSelectedValue: function() {
4999+ return this.element.val();

8964 more lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t