Merge ~blr/maas:bug-1787628-node-listing into maas:master

Proposed by Kit Randel
Status: Merged
Approved by: Kit Randel
Approved revision: b2d861d22d18384f05af87bc24602d0eb0795d29
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~blr/maas:bug-1787628-node-listing
Merge into: maas:master
Diff against target: 1415 lines (+593/-641)
11 files modified
src/maasserver/static/js/angular/3rdparty/vs-repeat.js (+580/-628)
src/maasserver/static/js/bundle/vendor-min.js (+1/-1)
src/maasserver/static/js/bundle/vendor-min.js.map (+1/-1)
src/maasserver/static/partials/dashboard.html (+1/-1)
src/maasserver/static/partials/machines-table.html (+1/-1)
src/maasserver/static/partials/networks-list.html (+2/-2)
src/maasserver/static/partials/node-events.html (+1/-1)
src/maasserver/static/partials/nodes-list.html (+3/-3)
src/maasserver/static/partials/pods-list.html (+1/-1)
src/maasserver/static/partials/switches-table.html (+1/-1)
src/maasserver/static/partials/zones-list.html (+1/-1)
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
MAAS Lander unittests Pending
Review via email: mp+353376@code.launchpad.net

Commit message

LP: #1787628 - Downgrade angular-vs-repeat to v1.1.11.

Description of the change

Unfortunately the 2.x series of angular-vs-repeat suffers from a bug (https://github.com/kamilkp/angular-vs-repeat/issues/192) which in certain cases will only display the first element of an ng-repeat until a scroll event is triggered.

This branch reverts to the latest release on 1.x which does not have this issue.

To post a comment you must log in.
Revision history for this message
Andres Rodriguez (andreserl) wrote :

lgtm!

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/static/js/angular/3rdparty/vs-repeat.js b/src/maasserver/static/js/angular/3rdparty/vs-repeat.js
0old mode 1007550old mode 100755
1new mode 1006441new mode 100644
index e789333..b42a6e0
--- a/src/maasserver/static/js/angular/3rdparty/vs-repeat.js
+++ b/src/maasserver/static/js/angular/3rdparty/vs-repeat.js
@@ -1,5 +1,5 @@
1/*!1/*!
2 * Angular Virtual Scroll Repeat v2.0.92 * Angular Virtual Scroll Repeat v1.1.11
3 * https://github.com/kamilkp/angular-vs-repeat/3 * https://github.com/kamilkp/angular-vs-repeat/
4 *4 *
5 * Copyright Kamil Pękala5 * Copyright Kamil Pękala
@@ -8,672 +8,624 @@
8 * Released under the MIT License8 * Released under the MIT License
9 * https://opensource.org/licenses/MIT9 * https://opensource.org/licenses/MIT
10 *10 *
11 * Date: 2018/04/0211 * Date: 2018/03/09
12 *
12 */13 */
1314
14function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }15(function(window, angular) {
1516 'use strict';
16function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }17 /* jshint eqnull:true */
1718 /* jshint -W038 */
18function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }19
1920 // DESCRIPTION:
20function _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }21 // vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container
2122 // into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of
22function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }23 // pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.
2324 // The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.
24/* global console, setTimeout, module */25
25(function (window, angular) {26 // LIMITATIONS:
26 /**27 // - current version only supports an Array as a right-hand-side object for ngRepeat
27 * DESCRIPTION:28 // - all rendered elements must have the same height/width or the sizes of the elements must be known up front
28 * vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container29
29 * into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of30 // USAGE:
30 * pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.31 // In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat
31 * The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.32 // example:
32 * LIMITATIONS:33 // <div vs-repeat>
33 * - current version only supports an Array as a right-hand-side object for ngRepeat34 // <div ng-repeat="item in someArray">
34 * - all rendered elements must have the same height/width or the sizes of the elements must be known up front35 // <!-- content -->
35 * USAGE:36 // </div>
36 * In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat37 // </div>
37 * example:38 //
38 * <div vs-repeat="options">39 // or:
39 * <div ng-repeat="item in someArray">40 // <div vs-repeat>
40 * <!-- content -->41 // <div ng-repeat-start="item in someArray">
41 * </div>42 // <!-- content -->
42 * </div>43 // </div>
43 * or:44 // <div>
44 * <div vs-repeat="options">45 // <!-- something in the middle -->
45 * <div ng-repeat-start="item in someArray">46 // </div>
46 * <!-- content -->47 // <div ng-repeat-end>
47 * </div>48 // <!-- content -->
48 * <div>49 // </div>
49 * <!-- something in the middle -->50 // </div>
50 * </div>51 //
51 * <div ng-repeat-end>52 // You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value
52 * <!-- content -->53 // of the attribute 'vs-repeat'. This can be used if one wants to override the automatically computed element size.
53 * </div>54 // example:
54 * </div>55 // <div vs-repeat="50"> <!-- the specified element height is 50px -->
55 * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value56 // <div ng-repeat="item in someArray">
56 * of the option's `size` property. This can be used if one wants to override the automatically computed element size.57 // <!-- content -->
57 * example:58 // </div>
58 * <div vs-repeat="{size: 50}"> <!-- the specified element height is 50px -->59 // </div>
59 * <div ng-repeat="item in someArray">60 //
60 * <!-- content -->61 // IMPORTANT!
61 * </div>62 //
62 * </div>63 // - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat
63 * IMPORTANT!64 // - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive
64 * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat65 // will compute it automatically
65 * - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive66
66 * will compute it automatically67 // OPTIONAL PARAMETERS (attributes):
67 * OPTIONAL PARAMETERS (attributes):68 // vs-repeat-container="selector" - selector for element containing ng-repeat. (defaults to the current element)
68 * vs-repeat-container="selector" - selector for element containing ng-repeat. (defaults to the current element)69 // vs-scroll-parent="selector" - selector to the scrollable container. The directive will look for a closest parent matching
69 * OPTIONS:70 // the given selector (defaults to the current element)
70 * Options shall be passed as an object to the `vs-repeat` attribute e.g.: `<div vs-repeat="{scrollParent: 'window', size: 20}"></div>`71 // vs-horizontal - stack repeated elements horizontally instead of vertically
71 *72 // vs-offset-before="value" - top/left offset in pixels (defaults to 0)
72 * Available options:73 // vs-offset-after="value" - bottom/right offset in pixels (defaults to 0)
73 * `horizontal` - stack repeated elements horizontally instead of vertically74 // vs-excess="value" - an integer number representing the number of elements to be rendered outside of the current container's viewport
74 * `offset-before` - top/left offset in pixels (defaults to 0)75 // (defaults to 2)
75 * `offset-after` - bottom/right offset in pixels (defaults to 0)76 // vs-size - a property name of the items in collection that is a number denoting the element size (in pixels)
76 * `scroll-margin` - how many pixels ahead should elements be rendered while scrolling77 // vs-autoresize - use this attribute without vs-size and without specifying element's size. The automatically computed element style will
77 * `latch` - if true, elements will be rendered gradually but won't be removed when scrolled away (defaults to false)78 // readjust upon window resize if the size is dependable on the viewport size
78 * `size` - a property name of the items in collection that is a number denoting the element size (in pixels)79 // vs-scrolled-to-end="callback" - callback will be called when the last item of the list is rendered
79 * `autoresize` - use this attribute without vs-size and without specifying element's size. The automatically computed element style will80 // vs-scrolled-to-end-offset="integer" - set this number to trigger the scrolledToEnd callback n items before the last gets rendered
80 * readjust upon window resize if the size is dependable on the viewport size81 // vs-scrolled-to-beginning="callback" - callback will be called when the first item of the list is rendered
81 * `scrolled-to-end` - callback will be called when the last item of the list is rendered82 // vs-scrolled-to-beginning-offset="integer" - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered
82 * `scrolled-to-end-offset` - set this number to trigger the scrolledToEnd callback n items before the last gets rendered83
83 * `scrolled-to-beginning` - callback will be called when the first item of the list is rendered84 // EVENTS:
84 * `scrolled-to-beginning-offset` - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered85 // - 'vsRepeatTrigger' - an event the directive listens for to manually trigger reinitialization
85 * EVENTS:86 // - 'vsRepeatReinitialized' - an event the directive emits upon reinitialization done
86 * - `vsRepeatTrigger` - an event the directive listens for to manually trigger reinitialization87
87 * - `vsRepeatReinitialized` - an event the directive emits upon reinitialization done88 var dde = document.documentElement,
88 */89 matchingFunction = dde.matches ? 'matches' :
89 var closestElement = angular.element.prototype.closest;90 dde.matchesSelector ? 'matchesSelector' :
9091 dde.webkitMatches ? 'webkitMatches' :
91 if (!closestElement) {92 dde.webkitMatchesSelector ? 'webkitMatchesSelector' :
92 var matchingFunction = ['matches', 'matchesSelector', 'webkitMatches', 'webkitMatchesSelector', 'msMatches', 'msMatchesSelector', 'mozMatches', 'mozMatchesSelector'].reduce(function (res, prop) {93 dde.msMatches ? 'msMatches' :
93 var _res;94 dde.msMatchesSelector ? 'msMatchesSelector' :
9495 dde.mozMatches ? 'mozMatches' :
95 return (_res = res) !== null && _res !== void 0 ? _res : prop in document.documentElement ? prop : null;96 dde.mozMatchesSelector ? 'mozMatchesSelector' : null;
96 }, null);97
9798 var closestElement = angular.element.prototype.closest || function (selector) {
98 closestElement = function closestElement(selector) {99 var el = this[0].parentNode;
99 var _el;100 while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {
100101 el = el.parentNode;
101 var el = this[0].parentNode;102 }
102
103 while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {
104 el = el.parentNode;
105 }
106
107 if ((_el = el) === null || _el === void 0 ? void 0 : _el[matchingFunction](selector)) {
108 return angular.element(el);
109 }
110
111 return angular.element();
112 };
113 }
114
115 function getWindowScroll() {
116 var _ref, _document$documentEle, _ref2, _document$documentEle2;
117
118 if ('pageYOffset' in window) {
119 return {
120 scrollTop: window.pageYOffset,
121 scrollLeft: window.pageXOffset
122 };
123 }
124103
125 return {104 if (el && el[matchingFunction](selector)) {
126 scrollTop: (_ref = (_document$documentEle = document.documentElement.scrollTop) !== null && _document$documentEle !== void 0 ? _document$documentEle : document.body.scrollTop) !== null && _ref !== void 0 ? _ref : 0,105 return angular.element(el);
127 scrollLeft: (_ref2 = (_document$documentEle2 = document.documentElement.scrollLeft) !== null && _document$documentEle2 !== void 0 ? _document$documentEle2 : document.body.scrollLeft) !== null && _ref2 !== void 0 ? _ref2 : 0106 }
107 else {
108 return angular.element();
109 }
128 };110 };
129 }
130111
131 function getClientSize(element, sizeProp) {112 function getWindowScroll() {
132 if (element === window) {113 if ('pageYOffset' in window) {
133 return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;114 return {
115 scrollTop: pageYOffset,
116 scrollLeft: pageXOffset
117 };
118 }
119 else {
120 var sx, sy, d = document, r = d.documentElement, b = d.body;
121 sx = r.scrollLeft || b.scrollLeft || 0;
122 sy = r.scrollTop || b.scrollTop || 0;
123 return {
124 scrollTop: sy,
125 scrollLeft: sx
126 };
127 }
134 }128 }
135129
136 return element[sizeProp];130 function getClientSize(element, sizeProp) {
137 }131 if (element === window) {
138132 return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;
139 function getScrollPos(element, scrollProp) {133 }
140 return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];134 else {
141 }135 return element[sizeProp];
142136 }
143 function getScrollOffset(vsElement, scrollElement, isHorizontal) {137 }
144 var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];
145 var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];
146 var scrollValue = (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];
147 return vsPos - scrollPos + scrollValue;
148 }
149138
150 function analyzeNgRepeatUsage(element) {139 function getScrollPos(element, scrollProp) {
151 var options = ['ng-repeat', 'data-ng-repeat', 'ng-repeat-start', 'data-ng-repeat-start'];140 return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];
141 }
152142
153 for (var _i = 0; _i < options.length; _i++) {143 function getScrollOffset(vsElement, scrollElement, isHorizontal) {
154 var opt = options[_i];144 var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];
145 var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];
146 var correction = vsPos - scrollPos +
147 (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];
155148
156 if (element.attr(opt)) {149 return correction;
157 return [opt, element.attr(opt), opt.indexOf('-start') >= 0];
158 }
159 }150 }
160151
161 throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');152 var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function($compile, $parse) {
162 }
163
164 function printDeprecationWarning($element, message) {
165 console.warn("vs-repeat deprecation: ".concat(message), $element[0]);
166 }
167
168 function attrDeprecated(attrname, $element) {
169 printDeprecationWarning($element, "".concat(attrname, " attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options"));
170 }
171
172 var defaultOptions = {
173 latch: false,
174 container: null,
175 scrollParent: null,
176 size: null,
177 offsetBefore: 0,
178 offsetAfter: 0,
179 scrolledToBeginning: angular.noop,
180 scrolledToEnd: angular.noop,
181 scrolledToBeginningOffset: 0,
182 scrolledToEndOffset: 0,
183 scrollMargin: 0,
184 horizontal: false,
185 autoresize: false,
186 hunked: false,
187 hunkSize: 0
188 };
189 var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function ($compile, $parse) {
190 return {
191 restrict: 'A',
192 scope: true,
193 compile: function compile(compileElement, compileAttrs) {
194 var compileRepeatContainer = 'vsRepeatContainer' in compileAttrs ? angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)) : compileElement;
195 var repeatContainerChildren = compileRepeatContainer.children();
196 var ngRepeatChild = repeatContainerChildren.eq(0);
197 var childCloneHtml = ngRepeatChild[0].outerHTML;
198 var collectionName = '$vs_collection'; // TODO: make configurable?
199
200 ['vsSize', 'vsScrollParent', 'vsSizeProperty', 'vsHorizontal', 'vsOffsetBefore', 'vsOffsetAfter', 'vsScrolledToEndOffset', 'vsScrolledToBeginningOffset', 'vsExcess', 'vsScrollMargin'].forEach(function (attrname) {
201 if (attrname in compileAttrs) {
202 attrDeprecated(attrname, compileElement);
203 }
204 });
205
206 var _analyzeNgRepeatUsage = analyzeNgRepeatUsage(ngRepeatChild),
207 _analyzeNgRepeatUsage2 = _slicedToArray(_analyzeNgRepeatUsage, 3),
208 originalNgRepeatAttr = _analyzeNgRepeatUsage2[0],
209 ngRepeatExpression = _analyzeNgRepeatUsage2[1],
210 isNgRepeatStart = _analyzeNgRepeatUsage2[2];
211
212 var expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression);
213
214 var _expressionMatches = _slicedToArray(expressionMatches, 4),
215 lhs = _expressionMatches[1],
216 rhs = _expressionMatches[2],
217 rhsSuffix = _expressionMatches[3];
218
219 if (isNgRepeatStart) {
220 var index = 0;
221 var repeaterElement = repeatContainerChildren.eq(index);
222
223 while (repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {
224 index++;
225 repeaterElement = repeatContainerChildren.eq(index);
226 childCloneHtml += repeaterElement[0].outerHTML;
227 }
228 }
229
230 compileRepeatContainer.empty();
231 return {153 return {
232 pre: function pre($scope, $element, $attrs) {154 restrict: 'A',
233 var _$scope$$eval;155 scope: true,
234156 compile: function($element, $attrs) {
235 function _parseSize(options) {157 var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,
236 if (typeof options.size === 'number') {158 ngRepeatChild = repeatContainer.children().eq(0),
237 options.getSize = function () {159 ngRepeatExpression,
238 return options.size;160 childCloneHtml = ngRepeatChild[0].outerHTML,
239 };161 expressionMatches,
240 } else {162 lhs,
241 var parsed = $parse(String(options.size));163 rhs,
242164 rhsSuffix,
243 options.getSize = function (item) {165 originalNgRepeatAttr,
244 return parsed($scope, _defineProperty({}, lhs, item));166 collectionName = '$vs_collection',
245 };167 isNgRepeatStart = false,
246 }168 attributesDictionary = {
247 }169 'vsRepeat': 'elementSize',
248170 'vsOffsetBefore': 'offsetBefore',
249 $scope.vsRepeat = {171 'vsOffsetAfter': 'offsetAfter',
250 options: _extends({}, defaultOptions, (_$scope$$eval = $scope.$eval($attrs.vsRepeat)) !== null && _$scope$$eval !== void 0 ? _$scope$$eval : {})172 'vsScrolledToEndOffset': 'scrolledToEndOffset',
251 };173 'vsScrolledToBeginningOffset': 'scrolledToBeginningOffset',
252 var options = $scope.vsRepeat.options;174 'vsExcess': 'excess',
253175 'vsScrollMargin': 'scrollMargin'
254 _parseSize(options);176 };
255177
256 var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element;178 if (ngRepeatChild.attr('ng-repeat')) {
257 var childClone = angular.element(childCloneHtml);179 originalNgRepeatAttr = 'ng-repeat';
258 var childTagName = childClone[0].tagName.toLowerCase();180 ngRepeatExpression = ngRepeatChild.attr('ng-repeat');
259 var originalCollection = [];
260 var originalLength;
261 var $beforeContent = angular.element('<' + childTagName + ' class="vs-repeat-before-content"></' + childTagName + '>');
262 var $afterContent = angular.element('<' + childTagName + ' class="vs-repeat-after-content"></' + childTagName + '>');
263 var autosizingRequired = options.size === null;
264 var $scrollParent = options.scrollParent ? options.scrollParent === 'window' ? angular.element(window) : closestElement.call(repeatContainer, options.scrollParent) : repeatContainer;
265 var clientSize = options.horizontal ? 'clientWidth' : 'clientHeight';
266 var offsetSize = options.horizontal ? 'offsetWidth' : 'offsetHeight';
267 var scrollSize = options.horizontal ? 'scrollWidth' : 'scrollHeight';
268 var scrollPos = options.horizontal ? 'scrollLeft' : 'scrollTop';
269 $scope.vsRepeat.totalSize = 0;
270
271 if ($scrollParent.length === 0) {
272 throw 'Specified scroll parent selector did not match any element';
273 }
274
275 $scope.vsRepeat.$scrollParent = $scrollParent;
276 $scope.vsRepeat.sizesCumulative = [];
277
278 if (options.debug) {
279 var $debugParent = options.scrollParent === 'window' ? angular.element(document.body) : $scrollParent;
280 var $debug = angular.element('<div class="vs-repeat-debug-element"></div>');
281 $debug.css('position', options.scrollParent === 'window' ? 'fixed' : 'absolute');
282 $debugParent.append($debug);
283 $scope.$on('$destroy', function () {
284 $debug.remove();
285 });
286 }
287
288 var measuredSize = getClientSize($scrollParent[0], clientSize) || 50;
289
290 if (options.horizontal) {
291 $beforeContent.css('height', '100%');
292 $afterContent.css('height', '100%');
293 } else {
294 $beforeContent.css('width', '100%');
295 $afterContent.css('width', '100%');
296 }
297
298 if ($attrs.vsRepeatOptions) {
299 $scope.$watchCollection($attrs.vsRepeatOptions, function (newOpts) {
300 var mergedOptions = _extends({}, options, newOpts);
301
302 if (JSON.stringify(mergedOptions) !== JSON.stringify(options)) {
303 Object.assign(options, newOpts);
304
305 _parseSize(options);
306
307 reinitialize();
308 }181 }
309 });182 else if (ngRepeatChild.attr('data-ng-repeat')) {
310 }183 originalNgRepeatAttr = 'data-ng-repeat';
311184 ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat');
312 $scope.$watchCollection(rhs, function () {
313 var coll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
314 originalCollection = coll;
315 refresh();
316 });
317
318 function refresh() {
319 if (!originalCollection || originalCollection.length < 1) {
320 $scope[collectionName] = [];
321 originalLength = 0;
322 $scope.vsRepeat.sizesCumulative = [0];
323 } else {
324 originalLength = originalCollection.length;
325
326 if (options.size) {
327 _mapSize();
328 } else {
329 getFromMeasured();
330 }
331 }
332
333 reinitialize();
334 }
335
336 function _mapSize() {
337 var hardSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
338 var sizes = originalCollection.map(function (item) {
339 var _hardSize;
340
341 return (_hardSize = hardSize) !== null && _hardSize !== void 0 ? _hardSize : options.getSize(item);
342 });
343 var sum = 0;
344 $scope.vsRepeat.sizesCumulative = [0].concat(_toConsumableArray(sizes.map(function (size) {
345 return sum += size;
346 })));
347 }
348
349 function getFromMeasured() {
350 if (autosizingRequired) {
351 $scope.$$postDigest(function () {
352 if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {
353 // element is visible
354 var children = repeatContainer.children();
355 var i = 0;
356 var gotSomething = false;
357 var insideStartEndSequence = false;
358
359 while (i < children.length) {
360 if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {
361 if (!gotSomething) {
362 measuredSize = 0;
363 }
364
365 gotSomething = true;
366
367 if (children[i][offsetSize]) {
368 measuredSize += children[i][offsetSize];
369 }
370
371 if (isNgRepeatStart) {
372 if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {
373 break;
374 } else {
375 insideStartEndSequence = true;
376 }
377 } else {
378 break;
379 }
380 }
381
382 i++;
383 }
384
385 if (gotSomething) {
386 _mapSize(measuredSize);
387
388 reinitialize();
389 autosizingRequired = false;
390
391 if ($scope.$root && !$scope.$root.$$phase) {
392 $scope.$digest();
393 }
394 }
395 } else {
396 var dereg = $scope.$watch(function () {
397 if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {
398 dereg();
399 getFromMeasured();
400 }
401 });
402 }
403 });
404 } else {
405 _mapSize(measuredSize);
406 }
407 }
408
409 function getLayoutProps(value) {
410 var layoutProp = options.horizontal ? 'width' : 'height';
411 return ['', 'min-', 'max-'].reduce(function (acc, prop) {
412 return acc["".concat(prop).concat(layoutProp)] = value, acc;
413 }, {});
414 }
415
416 childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));
417 childClone.addClass('vs-repeat-repeated-element');
418 repeatContainer.append($beforeContent);
419 repeatContainer.append(childClone);
420 $compile(childClone)($scope);
421 repeatContainer.append($afterContent);
422 $scope.vsRepeat.startIndex = 0;
423 $scope.vsRepeat.endIndex = 0;
424
425 function scrollHandler() {
426 var pos = $scrollParent[0][scrollPos];
427
428 if (updateInnerCollection()) {
429 $scope.$digest();
430
431 if (options._ensureScrollIntegrity) {
432 $scrollParent[0][scrollPos] = pos;
433 }185 }
434 }186 else if (ngRepeatChild.attr('ng-repeat-start')) {
435 }187 isNgRepeatStart = true;
436188 originalNgRepeatAttr = 'ng-repeat-start';
437 $scrollParent.on('scroll', scrollHandler);189 ngRepeatExpression = ngRepeatChild.attr('ng-repeat-start');
438
439 function onWindowResize() {
440 if (options.autoresize) {
441 autosizingRequired = true;
442 getFromMeasured();
443
444 if ($scope.$root && !$scope.$root.$$phase) {
445 $scope.$digest();
446 }190 }
447 }191 else if (ngRepeatChild.attr('data-ng-repeat-start')) {
448192 isNgRepeatStart = true;
449 if (updateInnerCollection()) {193 originalNgRepeatAttr = 'data-ng-repeat-start';
450 $scope.$digest();194 ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat-start');
451 }
452 }
453
454 angular.element(window).on('resize', onWindowResize);
455 $scope.$on('$destroy', function () {
456 angular.element(window).off('resize', onWindowResize);
457 $scrollParent.off('scroll', scrollHandler);
458 });
459 $scope.$on('vsRepeatTrigger', refresh);
460 $scope.$on('vsRepeatResize', function () {
461 autosizingRequired = true;
462 getFromMeasured();
463 });
464
465 var _prevStartIndex, _prevEndIndex, _minStartIndex, _maxEndIndex;
466
467 $scope.$on('vsRenderAll', function () {
468 if (!options.latch) {
469 return;
470 }
471
472 if ($scope.vsRepeat.endIndex === originalLength) {
473 $scope.$emit('vsRenderAllDone');
474 return;
475 }
476
477 setTimeout(function () {
478 // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength);
479 var __endIndex = originalLength;
480 _maxEndIndex = Math.max(__endIndex, _maxEndIndex);
481 $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex;
482 $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);
483 _prevEndIndex = $scope.vsRepeat.endIndex;
484 $beforeContent.css(getLayoutProps(0));
485 $afterContent.css(getLayoutProps(0));
486 $scope.$emit('vsRenderAllDone');
487
488 if ($scope.$root && !$scope.$root.$$phase) {
489 $scope.$digest();
490 }195 }
491 });196 else {
492 });197 throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');
493
494 function reinitialize() {
495 _prevStartIndex = void 0;
496 _prevEndIndex = void 0;
497 _minStartIndex = originalLength;
498 _maxEndIndex = 0;
499 updateTotalSize($scope.vsRepeat.sizesCumulative[originalLength]);
500 updateInnerCollection();
501 $scope.$emit('vsRepeatReinitialized', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);
502 }
503
504 function updateTotalSize(size) {
505 $scope.vsRepeat.totalSize = options.offsetBefore + size + options.offsetAfter;
506 }
507
508 var _prevClientSize;
509
510 function reinitOnClientHeightChange() {
511 var ch = getClientSize($scrollParent[0], clientSize);
512
513 if (ch !== _prevClientSize) {
514 reinitialize();
515
516 if ($scope.$root && !$scope.$root.$$phase) {
517 $scope.$digest();
518 }198 }
519 }
520
521 _prevClientSize = ch;
522 }
523199
524 $scope.$watch(function () {200 expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression);
525 if (typeof window.requestAnimationFrame === 'function') {201 lhs = expressionMatches[1];
526 window.requestAnimationFrame(reinitOnClientHeightChange);202 rhs = expressionMatches[2];
527 } else {203 rhsSuffix = expressionMatches[3];
528 reinitOnClientHeightChange();204
529 }205 if (isNgRepeatStart) {
530 });206 var index = 0;
531207 var repeaterElement = repeatContainer.children().eq(0);
532 function binaryFind(array, threshold) {208 while(repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {
533 var a = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;209 index++;
534 var b = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length - 1;210 repeaterElement = repeatContainer.children().eq(index);
535 var d = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;211 childCloneHtml += repeaterElement[0].outerHTML;
536212 }
537 if (array[a] === threshold) {
538 return [a, a, d];
539 }
540
541 if (array[b] === threshold) {
542 return [b, b, d];
543 }
544
545 if (b - a > 1) {
546 var m = Math.floor((a + b) / 2);
547
548 if (array[m] > threshold) {
549 return binaryFind(array, threshold, a, m, d + 1);
550 }213 }
551214
552 return binaryFind(array, threshold, m, b, d + 1);215 repeatContainer.empty();
553 }216 return {
554217 pre: function($scope, $element, $attrs) {
555 return [threshold > array[b] ? b : a, threshold < array[a] ? a : b, d];218 var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,
556 }219 childClone = angular.element(childCloneHtml),
557220 childTagName = childClone[0].tagName.toLowerCase(),
558 function updateInnerCollection() {221 originalCollection = [],
559 var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);222 originalLength,
560 var $clientSize = getClientSize($scrollParent[0], clientSize);223 $$horizontal = typeof $attrs.vsHorizontal !== 'undefined',
561224 $beforeContent = angular.element('<' + childTagName + ' class="vs-repeat-before-content"></' + childTagName + '>'),
562 if (options.debug) {225 $afterContent = angular.element('<' + childTagName + ' class="vs-repeat-after-content"></' + childTagName + '>'),
563 $clientSize /= 2;226 autoSize = !$attrs.vsRepeat,
564 }227 sizesPropertyExists = !!$attrs.vsSize || !!$attrs.vsSizeProperty,
565228 $scrollParent = $attrs.vsScrollParent ?
566 var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(repeatContainer[0], $scrollParent[0], options.horizontal);229 $attrs.vsScrollParent === 'window' ? angular.element(window) :
567 var __startIndex = $scope.vsRepeat.startIndex;230 closestElement.call(repeatContainer, $attrs.vsScrollParent) : repeatContainer,
568 var __endIndex = $scope.vsRepeat.endIndex;231 $$options = 'vsOptions' in $attrs ? $scope.$eval($attrs.vsOptions) : {},
569232 clientSize = $$horizontal ? 'clientWidth' : 'clientHeight',
570 if (autosizingRequired && !options.size) {233 offsetSize = $$horizontal ? 'offsetWidth' : 'offsetHeight',
571 __startIndex = 0;234 scrollPos = $$horizontal ? 'scrollLeft' : 'scrollTop';
572 __endIndex = 1;235
573 } else {236 $scope.totalSize = 0;
574 _warnMismatch();237 if (!('vsSize' in $attrs) && 'vsSizeProperty' in $attrs) {
575238 console.warn('vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions.');
576 var relativeScroll = $scrollPosition - options.offsetBefore - scrollOffset;239 }
577240
578 var _binaryFind = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll - options.scrollMargin);241 if ($scrollParent.length === 0) {
242 throw 'Specified scroll parent selector did not match any element';
243 }
244 $scope.$scrollParent = $scrollParent;
579245
580 var _binaryFind2 = _slicedToArray(_binaryFind, 1);246 if (sizesPropertyExists) {
247 $scope.sizesCumulative = [];
248 }
581249
582 __startIndex = _binaryFind2[0];250 //initial defaults
583 __startIndex = Math.max(__startIndex, 0);251 $scope.elementSize = (+$attrs.vsRepeat) || getClientSize($scrollParent[0], clientSize) || 50;
252 $scope.offsetBefore = 0;
253 $scope.offsetAfter = 0;
254 $scope.scrollMargin = 0;
255 $scope.excess = 2;
584256
585 var _binaryFind3 = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll + options.scrollMargin + $clientSize, __startIndex);257 if ($$horizontal) {
258 $beforeContent.css('height', '100%');
259 $afterContent.css('height', '100%');
260 }
261 else {
262 $beforeContent.css('width', '100%');
263 $afterContent.css('width', '100%');
264 }
586265
587 var _binaryFind4 = _slicedToArray(_binaryFind3, 2);266 Object.keys(attributesDictionary).forEach(function(key) {
267 if ($attrs[key]) {
268 $attrs.$observe(key, function(value) {
269 // '+' serves for getting a number from the string as the attributes are always strings
270 $scope[attributesDictionary[key]] = +value;
271 reinitialize();
272 });
273 }
274 });
275
276
277 $scope.$watchCollection(rhs, function(coll) {
278 originalCollection = coll || [];
279 refresh();
280 });
281
282 function refresh() {
283 if (!originalCollection || originalCollection.length < 1) {
284 $scope[collectionName] = [];
285 originalLength = 0;
286 $scope.sizesCumulative = [0];
287 }
288 else {
289 originalLength = originalCollection.length;
290 if (sizesPropertyExists) {
291 $scope.sizes = originalCollection.map(function(item) {
292 var s = $scope.$new(false);
293 angular.extend(s, item);
294 s[lhs] = item;
295 var size = ($attrs.vsSize || $attrs.vsSizeProperty) ?
296 s.$eval($attrs.vsSize || $attrs.vsSizeProperty) :
297 $scope.elementSize;
298 s.$destroy();
299 return size;
300 });
301 var sum = 0;
302 $scope.sizesCumulative = $scope.sizes.map(function(size) {
303 var res = sum;
304 sum += size;
305 return res;
306 });
307 $scope.sizesCumulative.push(sum);
308 }
309 else {
310 setAutoSize();
311 }
312 }
313
314 reinitialize();
315 }
588316
589 __endIndex = _binaryFind4[1];317 function setAutoSize() {
590 __endIndex = Math.min(__endIndex, originalLength);318 if (autoSize) {
591 }319 $scope.$$postDigest(function() {
320 if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { // element is visible
321 var children = repeatContainer.children(),
322 i = 0,
323 gotSomething = false,
324 insideStartEndSequence = false;
325
326 while (i < children.length) {
327 if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {
328 if (!gotSomething) {
329 $scope.elementSize = 0;
330 }
331
332 gotSomething = true;
333 if (children[i][offsetSize]) {
334 $scope.elementSize += children[i][offsetSize];
335 }
336
337 if (isNgRepeatStart) {
338 if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {
339 break;
340 }
341 else {
342 insideStartEndSequence = true;
343 }
344 }
345 else {
346 break;
347 }
348 }
349 i++;
350 }
351
352 if (gotSomething) {
353 reinitialize();
354 autoSize = false;
355 if ($scope.$root && !$scope.$root.$$phase) {
356 $scope.$apply();
357 }
358 }
359 }
360 else {
361 var dereg = $scope.$watch(function() {
362 if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {
363 dereg();
364 setAutoSize();
365 }
366 });
367 }
368 });
369 }
370 }
592371
593 _minStartIndex = Math.min(__startIndex, _minStartIndex);372 function getLayoutProp() {
594 _maxEndIndex = Math.max(__endIndex, _maxEndIndex);373 var layoutPropPrefix = childTagName === 'tr' ? '' : 'min-';
595 $scope.vsRepeat.startIndex = options.latch ? _minStartIndex : __startIndex;374 var layoutProp = $$horizontal ? layoutPropPrefix + 'width' : layoutPropPrefix + 'height';
596 $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; // Move to the end of the collection if we are now past it375 return layoutProp;
376 }
597377
598 if (_maxEndIndex < $scope.vsRepeat.startIndex) $scope.vsRepeat.startIndex = _maxEndIndex;378 childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));
599 var digestRequired = false;379 childClone.addClass('vs-repeat-repeated-element');
600380
601 if (_prevStartIndex == null) {381 repeatContainer.append($beforeContent);
602 digestRequired = true;382 repeatContainer.append(childClone);
603 } else if (_prevEndIndex == null) {383 $compile(childClone)($scope);
604 digestRequired = true;384 repeatContainer.append($afterContent);
605 }
606385
607 if (!digestRequired) {386 $scope.startIndex = 0;
608 if (options.hunked) {387 $scope.endIndex = 0;
609 if (Math.abs($scope.vsRepeat.startIndex - _prevStartIndex) >= options.hunkSize || $scope.vsRepeat.startIndex === 0 && _prevStartIndex !== 0) {
610 digestRequired = true;
611 } else if (Math.abs($scope.vsRepeat.endIndex - _prevEndIndex) >= options.hunkSize || $scope.vsRepeat.endIndex === originalLength && _prevEndIndex !== originalLength) {
612 digestRequired = true;
613 }
614 } else {
615 digestRequired = $scope.vsRepeat.startIndex !== _prevStartIndex || $scope.vsRepeat.endIndex !== _prevEndIndex;
616 }
617 }
618388
619 if (digestRequired) {389 function scrollHandler() {
620 $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); // Emit the event390 if (updateInnerCollection()) {
391 $scope.$digest();
621392
622 $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex, _prevStartIndex, _prevEndIndex);393 var expectedSize = sizesPropertyExists ?
623 var triggerIndex;394 $scope.sizesCumulative[originalLength] :
395 $scope.elementSize * originalLength;
624396
625 if (options.scrolledToEnd) {397 if (expectedSize !== $element[0].clientHeight) {
626 triggerIndex = originalCollection.length - options.scrolledToEndOffset;398 console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + $element[0].clientHeight + 'px. Fix vsSize on element:', $element[0]);
627399 }
628 if ($scope.vsRepeat.endIndex >= triggerIndex && _prevEndIndex < triggerIndex || originalCollection.length && $scope.vsRepeat.endIndex === originalCollection.length) {400 }
629 $scope.$eval(options.scrolledToEnd);401 }
630 }
631 }
632402
633 if (options.scrolledToBeginning) {403 $scrollParent.on('scroll', scrollHandler);
634 triggerIndex = options.scrolledToBeginningOffset;404
405 function onWindowResize() {
406 if (typeof $attrs.vsAutoresize !== 'undefined') {
407 autoSize = true;
408 setAutoSize();
409 if ($scope.$root && !$scope.$root.$$phase) {
410 $scope.$apply();
411 }
412 }
413 if (updateInnerCollection()) {
414 $scope.$apply();
415 }
416 }
635417
636 if ($scope.vsRepeat.startIndex <= triggerIndex && _prevStartIndex > $scope.vsRepeat.startIndex) {418 angular.element(window).on('resize', onWindowResize);
637 $scope.$eval(options.scrolledToBeginning);419 $scope.$on('$destroy', function() {
638 }420 angular.element(window).off('resize', onWindowResize);
639 }421 $scrollParent.off('scroll', scrollHandler);
422 });
423
424 $scope.$on('vsRepeatTrigger', refresh);
425
426 $scope.$on('vsRepeatResize', function() {
427 autoSize = true;
428 setAutoSize();
429 });
430
431 var _prevStartIndex,
432 _prevEndIndex,
433 _minStartIndex,
434 _maxEndIndex;
435
436 $scope.$on('vsRenderAll', function() {//e , quantum) {
437 if($$options.latch) {
438 setTimeout(function() {
439 // var __endIndex = Math.min($scope.endIndex + (quantum || 1), originalLength);
440 var __endIndex = originalLength;
441 _maxEndIndex = Math.max(__endIndex, _maxEndIndex);
442 $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;
443 $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);
444 _prevEndIndex = $scope.endIndex;
445
446 $scope.$$postDigest(function() {
447 $beforeContent.css(getLayoutProp(), 0);
448 $afterContent.css(getLayoutProp(), 0);
449 });
450
451 $scope.$apply(function() {
452 $scope.$emit('vsRenderAllDone');
453 });
454 });
455 }
456 });
457
458 function reinitialize() {
459 _prevStartIndex = void 0;
460 _prevEndIndex = void 0;
461 _minStartIndex = originalLength;
462 _maxEndIndex = 0;
463 updateTotalSize(sizesPropertyExists ?
464 $scope.sizesCumulative[originalLength] :
465 $scope.elementSize * originalLength
466 );
467 updateInnerCollection();
468
469 $scope.$emit('vsRepeatReinitialized', $scope.startIndex, $scope.endIndex);
470 }
640471
641 _prevStartIndex = $scope.vsRepeat.startIndex;472 function updateTotalSize(size) {
642 _prevEndIndex = $scope.vsRepeat.endIndex;473 $scope.totalSize = $scope.offsetBefore + size + $scope.offsetAfter;
643 var o1 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex] + options.offsetBefore;474 }
644 var o2 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex + $scope[collectionName].length] + options.offsetBefore;
645 var total = $scope.vsRepeat.totalSize;
646 $beforeContent.css(getLayoutProps(o1 + 'px'));
647 $afterContent.css(getLayoutProps(total - o2 + 'px'));
648 }
649475
650 return digestRequired;476 var _prevClientSize;
651 }477 function reinitOnClientHeightChange() {
478 var ch = getClientSize($scrollParent[0], clientSize);
479 if (ch !== _prevClientSize) {
480 reinitialize();
481 if ($scope.$root && !$scope.$root.$$phase) {
482 $scope.$apply();
483 }
484 }
485 _prevClientSize = ch;
486 }
652487
653 function _warnMismatch() {488 $scope.$watch(function() {
654 $scope.$$postDigest(function () {489 if (typeof window.requestAnimationFrame === 'function') {
655 window.requestAnimationFrame(function () {490 window.requestAnimationFrame(reinitOnClientHeightChange);
656 var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength];491 }
657 var compStyle = window.getComputedStyle(repeatContainer[0]);492 else {
658 var paddings = options.horizontal ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom'];493 reinitOnClientHeightChange();
659 var containerSize = repeatContainer[0][scrollSize] - paddings.reduce(function (acc, prop) {494 }
660 return acc + Number(compStyle[prop].slice(0, -2));495 });
661 }, 0);496
662497 function updateInnerCollection() {
663 if (repeatContainer[0][scrollSize] && expectedSize !== containerSize) {498 var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);
664 console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + containerSize + 'px. Fix vsSize on element:', $element[0]);499 var $clientSize = getClientSize($scrollParent[0], clientSize);
665 }500
666 });501 var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(
667 });502 repeatContainer[0],
503 $scrollParent[0],
504 $$horizontal
505 );
506
507 var __startIndex = $scope.startIndex;
508 var __endIndex = $scope.endIndex;
509
510 if (sizesPropertyExists) {
511 __startIndex = 0;
512 while ($scope.sizesCumulative[__startIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset - $scope.scrollMargin) {
513 __startIndex++;
514 }
515 if (__startIndex > 0) { __startIndex--; }
516
517 // Adjust the start index according to the excess
518 __startIndex = Math.max(
519 Math.floor(__startIndex - $scope.excess / 2),
520 0
521 );
522
523 __endIndex = __startIndex;
524 while ($scope.sizesCumulative[__endIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset + $scope.scrollMargin + $clientSize) {
525 __endIndex++;
526 }
527
528 // Adjust the end index according to the excess
529 __endIndex = Math.min(
530 Math.ceil(__endIndex + $scope.excess / 2),
531 originalLength
532 );
533 }
534 else {
535 __startIndex = Math.max(
536 Math.floor(
537 ($scrollPosition - $scope.offsetBefore - scrollOffset) / $scope.elementSize
538 ) - $scope.excess / 2,
539 0
540 );
541
542 __endIndex = Math.min(
543 __startIndex + Math.ceil(
544 $clientSize / $scope.elementSize
545 ) + $scope.excess,
546 originalLength
547 );
548 }
549
550 _minStartIndex = Math.min(__startIndex, _minStartIndex);
551 _maxEndIndex = Math.max(__endIndex, _maxEndIndex);
552
553 $scope.startIndex = $$options.latch ? _minStartIndex : __startIndex;
554 $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;
555
556 // Move to the end of the collection if we are now past it
557 if (_maxEndIndex < $scope.startIndex)
558 $scope.startIndex = _maxEndIndex;
559
560 var digestRequired = false;
561 if (_prevStartIndex == null) {
562 digestRequired = true;
563 }
564 else if (_prevEndIndex == null) {
565 digestRequired = true;
566 }
567
568 if (!digestRequired) {
569 if ($$options.hunked) {
570 if (Math.abs($scope.startIndex - _prevStartIndex) >= $scope.excess / 2 ||
571 ($scope.startIndex === 0 && _prevStartIndex !== 0)) {
572 digestRequired = true;
573 }
574 else if (Math.abs($scope.endIndex - _prevEndIndex) >= $scope.excess / 2 ||
575 ($scope.endIndex === originalLength && _prevEndIndex !== originalLength)) {
576 digestRequired = true;
577 }
578 }
579 else {
580 digestRequired = $scope.startIndex !== _prevStartIndex ||
581 $scope.endIndex !== _prevEndIndex;
582 }
583 }
584
585 if (digestRequired) {
586 $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);
587
588 // Emit the event
589 $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.startIndex, $scope.endIndex, _prevStartIndex, _prevEndIndex);
590 var triggerIndex;
591 if ($attrs.vsScrolledToEnd) {
592 triggerIndex = originalCollection.length - ($scope.scrolledToEndOffset || 0);
593 if (($scope.endIndex >= triggerIndex && _prevEndIndex < triggerIndex) || (originalCollection.length && $scope.endIndex === originalCollection.length)) {
594 $scope.$eval($attrs.vsScrolledToEnd);
595 }
596 }
597 if ($attrs.vsScrolledToBeginning) {
598 triggerIndex = $scope.scrolledToBeginningOffset || 0;
599 if (($scope.startIndex <= triggerIndex && _prevStartIndex > $scope.startIndex)) {
600 $scope.$eval($attrs.vsScrolledToBeginning);
601 }
602 }
603
604 _prevStartIndex = $scope.startIndex;
605 _prevEndIndex = $scope.endIndex;
606
607 var offsetCalculationString = sizesPropertyExists ?
608 '(sizesCumulative[$index + startIndex] + offsetBefore)' :
609 '(($index + startIndex) * elementSize + offsetBefore)';
610
611 var parsed = $parse(offsetCalculationString);
612 var o1 = parsed($scope, {$index: 0});
613 var o2 = parsed($scope, {$index: $scope[collectionName].length});
614 var total = $scope.totalSize;
615
616 $beforeContent.css(getLayoutProp(), o1 + 'px');
617 $afterContent.css(getLayoutProp(), (total - o2) + 'px');
618 }
619
620 return digestRequired;
621 }
622 }
623 };
668 }624 }
669 }
670 };625 };
671 }626 }]);
672 };
673 }]);
674 angular.element(document.head).append("<style id=\"angular-vs-repeat-style\">\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\n }\n </style>");
675627
676 if (typeof module !== 'undefined' && module.exports) {
677 module.exports = vsRepeatModule.name;
678 }
679})(window, window.angular);
680\ No newline at end of file628\ No newline at end of file
629 if (typeof module !== 'undefined' && module.exports) {
630 module.exports = vsRepeatModule.name;
631 }
632})(window, window.angular);
diff --git a/src/maasserver/static/js/bundle/vendor-min.js b/src/maasserver/static/js/bundle/vendor-min.js
index 26725ae..36bca11 100644
--- a/src/maasserver/static/js/bundle/vendor-min.js
+++ b/src/maasserver/static/js/bundle/vendor-min.js
@@ -1,2 +1,2 @@
1!function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=0)}({"./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js":function(module,exports){!function(){"use strict";var KEYS_backspace=8,KEYS_tab=9,KEYS_enter=13,KEYS_escape=27,KEYS_space=32,KEYS_up=38,KEYS_down=40,KEYS_left=37,KEYS_right=39,KEYS_delete=46,KEYS_comma=188,SUPPORTED_INPUT_TYPES=["text","email","url"],tagsInput=angular.module("ngTagsInput",[]);tagsInput.directive("tagsInput",["$timeout","$document","$window","tagsInputConfig","tiUtil",function($timeout,$document,$window,tagsInputConfig,tiUtil){function validateType(type){return-1!==SUPPORTED_INPUT_TYPES.indexOf(type)}return{restrict:"E",require:"ngModel",scope:{tags:"=ngModel",onTagAdding:"&",onTagAdded:"&",onInvalidTag:"&",onTagRemoving:"&",onTagRemoved:"&"},replace:!1,transclude:!0,templateUrl:"ngTagsInput/tags-input.html",controller:["$scope","$attrs","$element",function($scope,$attrs,$element){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("tagsInput",$scope,$attrs,{template:[String,"ngTagsInput/tag-item.html"],type:[String,"text",validateType],placeholder:[String,"Add a tag"],tabindex:[Number,null],removeTagSymbol:[String,String.fromCharCode(215)],replaceSpacesWithDashes:[Boolean,!0],minLength:[Number,3],maxLength:[Number,9007199254740991],addOnEnter:[Boolean,!0],addOnSpace:[Boolean,!1],addOnComma:[Boolean,!0],addOnBlur:[Boolean,!0],addOnPaste:[Boolean,!1],pasteSplitPattern:[RegExp,/,/],allowedTagsPattern:[RegExp,/.+/],enableEditingLastTag:[Boolean,!1],minTags:[Number,0],maxTags:[Number,9007199254740991],displayProperty:[String,"text"],keyProperty:[String,""],allowLeftoverText:[Boolean,!1],addFromAutocompleteOnly:[Boolean,!1],spellcheck:[Boolean,!0]}),$scope.tagList=new function(options,events,onTagAdding,onTagRemoving){var getTagText,setTagText,tagIsValid,self={};return getTagText=function(tag){return tiUtil.safeToString(tag[options.displayProperty])},setTagText=function(tag,text){tag[options.displayProperty]=text},tagIsValid=function(tag){var tagText=getTagText(tag);return tagText&&tagText.length>=options.minLength&&tagText.length<=options.maxLength&&options.allowedTagsPattern.test(tagText)&&!tiUtil.findInObjectArray(self.items,tag,options.keyProperty||options.displayProperty)&&onTagAdding({$tag:tag})},self.items=[],self.addText=function(text){var tag={};return setTagText(tag,text),self.add(tag)},self.add=function(tag){var tagText=getTagText(tag);return options.replaceSpacesWithDashes&&(tagText=tiUtil.replaceSpacesWithDashes(tagText)),setTagText(tag,tagText),tagIsValid(tag)?(self.items.push(tag),events.trigger("tag-added",{$tag:tag})):tagText&&events.trigger("invalid-tag",{$tag:tag}),tag},self.remove=function(index){var tag=self.items[index];if(onTagRemoving({$tag:tag}))return self.items.splice(index,1),self.clearSelection(),events.trigger("tag-removed",{$tag:tag}),tag},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index]},self.selectPrior=function(){self.select(--self.index)},self.selectNext=function(){self.select(++self.index)},self.removeSelected=function(){return self.remove(self.index)},self.clearSelection=function(){self.selected=null,self.index=-1},self.clearSelection(),self}($scope.options,$scope.events,tiUtil.handleUndefinedResult($scope.onTagAdding,!0),tiUtil.handleUndefinedResult($scope.onTagRemoving,!0)),this.registerAutocomplete=function(){$element.find("input");return{addTag:function(tag){return $scope.tagList.add(tag)},focusInput:function(){},getTags:function(){return $scope.tags},getCurrentTagText:function(){return $scope.newTag.text},getOptions:function(){return $scope.options},on:function(name,handler){return $scope.events.on(name,handler),this}}},this.registerTagItem=function(){return{getOptions:function(){return $scope.options},removeTag:function(index){$scope.disabled||$scope.tagList.remove(index)}}}}],link:function(scope,element,attrs,ngModelCtrl){var setElementValidity,hotkeys=[KEYS_enter,KEYS_comma,KEYS_space,KEYS_backspace,KEYS_delete,KEYS_left,KEYS_right],tagList=scope.tagList,events=scope.events,options=scope.options,input=element.find("input"),validationOptions=["minTags","maxTags","allowLeftoverText"];setElementValidity=function(){ngModelCtrl.$setValidity("maxTags",scope.tags.length<=options.maxTags),ngModelCtrl.$setValidity("minTags",scope.tags.length>=options.minTags),ngModelCtrl.$setValidity("leftoverText",!(!scope.hasFocus&&!options.allowLeftoverText)||!scope.newTag.text)},ngModelCtrl.$isEmpty=function(value){return!value||!value.length},scope.newTag={text:"",invalid:null,setText:function(value){this.text=value,events.trigger("input-change",value)}},scope.track=function(tag){return tag[options.keyProperty||options.displayProperty]},scope.$watch("tags",function(value){scope.tags=tiUtil.makeObjectArray(value,options.displayProperty),tagList.items=scope.tags}),scope.$watch("tags.length",function(){setElementValidity()}),attrs.$observe("disabled",function(value){scope.disabled=value}),scope.eventHandlers={input:{change:function(text){events.trigger("input-change",text)},keydown:function($event){events.trigger("input-keydown",$event)},focus:function(){scope.hasFocus||(scope.hasFocus=!0,events.trigger("input-focus"))},blur:function(){$timeout(function(){var activeElement=$document.prop("activeElement"),lostFocusToBrowserWindow=activeElement===input[0],lostFocusToChildElement=element[0].contains(activeElement);!lostFocusToBrowserWindow&&lostFocusToChildElement||(scope.hasFocus=!1,events.trigger("input-blur"))})},paste:function($event){$event.getTextData=function(){var clipboardData=$event.clipboardData||$event.originalEvent&&$event.originalEvent.clipboardData;return clipboardData?clipboardData.getData("text/plain"):$window.clipboardData.getData("Text")},events.trigger("input-paste",$event)}},host:{click:function(){scope.disabled}}},events.on("tag-added",scope.onTagAdded).on("invalid-tag",scope.onInvalidTag).on("tag-removed",scope.onTagRemoved).on("tag-added",function(){scope.newTag.setText("")}).on("tag-added tag-removed",function(){ngModelCtrl.$setViewValue(scope.tags)}).on("invalid-tag",function(){scope.newTag.invalid=!0}).on("option-change",function(e){-1!==validationOptions.indexOf(e.name)&&setElementValidity()}).on("input-change",function(){tagList.clearSelection(),scope.newTag.invalid=null}).on("input-focus",function(){element.triggerHandler("focus"),ngModelCtrl.$setValidity("leftoverText",!0)}).on("input-blur",function(){options.addOnBlur&&!options.addFromAutocompleteOnly&&tagList.addText(scope.newTag.text),element.triggerHandler("blur"),setElementValidity()}).on("input-keydown",function(event){var shouldAdd,shouldRemove,shouldSelect,shouldEditLastTag,key=event.keyCode,addKeys={};if(!(event.shiftKey||event.altKey||event.ctrlKey||event.metaKey)&&-1!==hotkeys.indexOf(key)){if(addKeys[KEYS_enter]=options.addOnEnter,addKeys[KEYS_comma]=options.addOnComma,addKeys[KEYS_space]=options.addOnSpace,shouldAdd=!options.addFromAutocompleteOnly&&addKeys[key],shouldRemove=(key===KEYS_backspace||key===KEYS_delete)&&tagList.selected,shouldEditLastTag=key===KEYS_backspace&&0===scope.newTag.text.length&&options.enableEditingLastTag,shouldSelect=(key===KEYS_backspace||key===KEYS_left||key===KEYS_right)&&0===scope.newTag.text.length&&!options.enableEditingLastTag,shouldAdd)tagList.addText(scope.newTag.text);else if(shouldEditLastTag){var tag;tagList.selectPrior(),(tag=tagList.removeSelected())&&scope.newTag.setText(tag[options.displayProperty])}else shouldRemove?tagList.removeSelected():shouldSelect&&(key===KEYS_left||key===KEYS_backspace?tagList.selectPrior():key===KEYS_right&&tagList.selectNext());(shouldAdd||shouldSelect||shouldRemove||shouldEditLastTag)&&event.preventDefault()}}).on("input-paste",function(event){if(options.addOnPaste){var tags=event.getTextData().split(options.pasteSplitPattern);tags.length>1&&(tags.forEach(function(tag){tagList.addText(tag)}),event.preventDefault())}})}}}]),tagsInput.directive("tiTagItem",["tiUtil",function(tiUtil){return{restrict:"E",require:"^tagsInput",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,tagsInputCtrl){var tagsInput=tagsInputCtrl.registerTagItem(),options=tagsInput.getOptions();scope.$$template=options.template,scope.$$removeTagSymbol=options.removeTagSymbol,scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty])},scope.$removeTag=function(){tagsInput.removeTag(scope.$index)},scope.$watch("$parent.$index",function(value){scope.$index=value})}}}]),tagsInput.directive("autoComplete",["$document","$timeout","$sce","$q","tagsInputConfig","tiUtil",function($document,$timeout,$sce,$q,tagsInputConfig,tiUtil){return{restrict:"E",require:"^tagsInput",scope:{source:"&"},templateUrl:"ngTagsInput/auto-complete.html",controller:["$scope","$element","$attrs",function($scope,$element,$attrs){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("autoComplete",$scope,$attrs,{template:[String,"ngTagsInput/auto-complete-match.html"],debounceDelay:[Number,100],minLength:[Number,3],highlightMatchedText:[Boolean,!0],maxResultsToShow:[Number,10],loadOnDownArrow:[Boolean,!1],loadOnEmpty:[Boolean,!1],loadOnFocus:[Boolean,!1],selectFirstMatch:[Boolean,!0],displayProperty:[String,""]}),$scope.suggestionList=new function(loadFn,options,events){var getDifference,lastPromise,getTagId,self={};return getTagId=function(){return options.tagsInput.keyProperty||options.tagsInput.displayProperty},getDifference=function(array1,array2){return array1.filter(function(item){return!tiUtil.findInObjectArray(array2,item,getTagId(),function(a,b){return options.tagsInput.replaceSpacesWithDashes&&(a=tiUtil.replaceSpacesWithDashes(a),b=tiUtil.replaceSpacesWithDashes(b)),tiUtil.defaultComparer(a,b)})})},self.reset=function(){lastPromise=null,self.items=[],self.visible=!1,self.index=-1,self.selected=null,self.query=null},self.show=function(){options.selectFirstMatch?self.select(0):self.selected=null,self.visible=!0},self.load=tiUtil.debounce(function(query,tags){self.query=query;var promise=$q.when(loadFn({$query:query}));lastPromise=promise,promise.then(function(items){promise===lastPromise&&(items=tiUtil.makeObjectArray(items.data||items,getTagId()),items=getDifference(items,tags),self.items=items.slice(0,options.maxResultsToShow),self.items.length>0?self.show():self.reset())})},options.debounceDelay),self.selectNext=function(){self.select(++self.index)},self.selectPrior=function(){self.select(--self.index)},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index],events.trigger("suggestion-selected",index)},self.reset(),self}($scope.source,$scope.options,$scope.events),this.registerAutocompleteMatch=function(){return{getOptions:function(){return $scope.options},getQuery:function(){return $scope.suggestionList.query}}}}],link:function(scope,element,attrs,tagsInputCtrl){var shouldLoadSuggestions,hotkeys=[KEYS_enter,KEYS_tab,KEYS_escape,KEYS_up,KEYS_down],suggestionList=scope.suggestionList,tagsInput=tagsInputCtrl.registerAutocomplete(),options=scope.options,events=scope.events;options.tagsInput=tagsInput.getOptions(),shouldLoadSuggestions=function(value){return value&&value.length>=options.minLength||!value&&options.loadOnEmpty},scope.addSuggestionByIndex=function(index){suggestionList.select(index),scope.addSuggestion()},scope.addSuggestion=function(){var added=!1;return suggestionList.selected&&(tagsInput.addTag(angular.copy(suggestionList.selected)),suggestionList.reset(),tagsInput.focusInput(),added=!0),added},scope.track=function(item){return item[options.tagsInput.keyProperty||options.tagsInput.displayProperty]},tagsInput.on("tag-added invalid-tag input-blur",function(){suggestionList.reset()}).on("input-change",function(value){shouldLoadSuggestions(value)?suggestionList.load(value,tagsInput.getTags()):suggestionList.reset()}).on("input-focus",function(){var value=tagsInput.getCurrentTagText();options.loadOnFocus&&shouldLoadSuggestions(value)&&suggestionList.load(value,tagsInput.getTags())}).on("input-keydown",function(event){var key=event.keyCode,handled=!1;if(-1!==hotkeys.indexOf(key))return suggestionList.visible?key===KEYS_down?(suggestionList.selectNext(),handled=!0):key===KEYS_up?(suggestionList.selectPrior(),handled=!0):key===KEYS_escape?(suggestionList.reset(),handled=!0):key!==KEYS_enter&&key!==KEYS_tab||(handled=scope.addSuggestion()):key===KEYS_down&&scope.options.loadOnDownArrow&&(suggestionList.load(tagsInput.getCurrentTagText(),tagsInput.getTags()),handled=!0),handled?(event.preventDefault(),event.stopImmediatePropagation(),!1):void 0}),events.on("suggestion-selected",function(index){!function(root,index){var element=root.find("li").eq(index),parent=element.parent(),elementTop=element.prop("offsetTop"),elementHeight=element.prop("offsetHeight"),parentHeight=parent.prop("clientHeight"),parentScrollTop=parent.prop("scrollTop");elementTop<parentScrollTop?parent.prop("scrollTop",elementTop):elementTop+elementHeight>parentHeight+parentScrollTop&&parent.prop("scrollTop",elementTop+elementHeight-parentHeight)}(element,index)})}}}]),tagsInput.directive("tiAutocompleteMatch",["$sce","tiUtil",function($sce,tiUtil){return{restrict:"E",require:"^autoComplete",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,autoCompleteCtrl){var autoComplete=autoCompleteCtrl.registerAutocompleteMatch(),options=autoComplete.getOptions();scope.$$template=options.template,scope.$index=scope.$parent.$index,scope.$highlight=function(text){return options.highlightMatchedText&&(text=tiUtil.safeHighlight(text,autoComplete.getQuery())),$sce.trustAsHtml(text)},scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty||options.tagsInput.displayProperty])}}}}]),tagsInput.directive("tiTranscludeAppend",function(){return function(scope,element,attrs,ctrl,transcludeFn){transcludeFn(function(clone){element.append(clone)})}}),tagsInput.directive("tiAutosize",["tagsInputConfig",function(tagsInputConfig){return{restrict:"A",require:"ngModel",link:function(scope,element,attrs,ctrl){var span,resize,threshold=tagsInputConfig.getTextAutosizeThreshold();(span=angular.element('<span class="input"></span>')).css("display","none").css("visibility","hidden").css("width","auto").css("white-space","pre"),element.parent().append(span),resize=function(originalValue){var width,value=originalValue;return angular.isString(value)&&0===value.length&&(value=attrs.placeholder),value&&(span.text(value),span.css("display",""),width=span.prop("offsetWidth"),span.css("display","none")),element.css("width",width?width+threshold+"px":""),originalValue},ctrl.$parsers.unshift(resize),ctrl.$formatters.unshift(resize),attrs.$observe("placeholder",function(value){ctrl.$modelValue||resize(value)})}}}]),tagsInput.directive("tiBindAttrs",function(){return function(scope,element,attrs){scope.$watch(attrs.tiBindAttrs,function(value){angular.forEach(value,function(value,key){"type"===key?element[0].type=value:attrs.$set(key,value)})},!0)}}),tagsInput.provider("tagsInputConfig",function(){var globalDefaults={},interpolationStatus={},autosizeThreshold=3;this.setDefaults=function(directive,defaults){return globalDefaults[directive]=defaults,this},this.setActiveInterpolation=function(directive,options){return interpolationStatus[directive]=options,this},this.setTextAutosizeThreshold=function(threshold){return autosizeThreshold=threshold,this},this.$get=["$interpolate",function($interpolate){var converters={};return converters[String]=function(value){return value},converters[Number]=function(value){return parseInt(value,10)},converters[Boolean]=function(value){return"true"===value.toLowerCase()},converters[RegExp]=function(value){return new RegExp(value)},{load:function(directive,scope,attrs,options){var defaultValidator=function(){return!0};scope.options={},angular.forEach(options,function(value,key){var type,localDefault,validator,converter,getDefault,updateValue;type=value[0],localDefault=value[1],validator=value[2]||defaultValidator,converter=converters[type],getDefault=function(){var globalValue=globalDefaults[directive]&&globalDefaults[directive][key];return angular.isDefined(globalValue)?globalValue:localDefault},updateValue=function(value){scope.options[key]=value&&validator(value)?converter(value):getDefault()},interpolationStatus[directive]&&interpolationStatus[directive][key]?attrs.$observe(key,function(value){updateValue(value),scope.events.trigger("option-change",{name:key,newValue:value})}):updateValue(attrs[key]&&$interpolate(attrs[key])(scope.$parent))})},getTextAutosizeThreshold:function(){return autosizeThreshold}}}]}),tagsInput.factory("tiUtil",["$timeout",function($timeout){var self={debounce:function(fn,delay){var timeoutId;return function(){var args=arguments;$timeout.cancel(timeoutId),timeoutId=$timeout(function(){fn.apply(null,args)},delay)}},makeObjectArray:function(array,key){return(array=array||[]).length>0&&!angular.isObject(array[0])&&array.forEach(function(item,index){array[index]={},array[index][key]=item}),array},findInObjectArray:function(array,obj,key,comparer){var item=null;return comparer=comparer||self.defaultComparer,array.some(function(element){if(comparer(element[key],obj[key]))return item=element,!0}),item},defaultComparer:function(a,b){return self.safeToString(a).toLowerCase()===self.safeToString(b).toLowerCase()},safeHighlight:function(str,value){if(!value)return str;str=self.encodeHTML(str),value=self.encodeHTML(value);var expression=new RegExp("&[^;]+;|"+function(str){return str.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}(value),"gi");return str.replace(expression,function(match){return match.toLowerCase()===value.toLowerCase()?"<em>"+match+"</em>":match})},safeToString:function(value){return angular.isUndefined(value)||null==value?"":value.toString().trim()},encodeHTML:function(value){return self.safeToString(value).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},handleUndefinedResult:function(fn,valueIfUndefined){return function(){var result=fn.apply(null,arguments);return angular.isUndefined(result)?valueIfUndefined:result}},replaceSpacesWithDashes:function(str){return self.safeToString(str).replace(/\s/g,"-")},simplePubSub:function(){var events={};return{on:function(names,handler){return names.split(" ").forEach(function(name){events[name]||(events[name]=[]),events[name].push(handler)}),this},trigger:function(name,args){return(events[name]||[]).every(function(handler){return self.handleUndefinedResult(handler,!0)(args)}),this}}}};return self}]),tagsInput.run(["$templateCache",function($templateCache){$templateCache.put("ngTagsInput/tags-input.html",'<div class="host" tabindex="-1" data-ng-click="eventHandlers.host.click()" ti-transclude-append=""><div class="tags" data-ng-class="{focused: hasFocus}"><ul class="tag-list"><li class="tag-item" data-ng-repeat="tag in tagList.items track by track(tag)" data-ng-class="{ selected: tag == tagList.selected }"><ti-tag-item data="tag"></ti-tag-item></li></ul><input class="input u-no-margin--top" autocomplete="off" data-ng-model="newTag.text" data-ng-change="eventHandlers.input.change(newTag.text)" data-ng-keydown="eventHandlers.input.keydown($event)" data-ng-focus="eventHandlers.input.focus($event)" data-ng-blur="eventHandlers.input.blur($event)" data-ng-paste="eventHandlers.input.paste($event)" data-ng-trim="false" data-ng-class="{\'invalid-tag\': newTag.invalid}" data-ng-disabled="disabled" ti-bind-attrs="{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}" ti-autosize=""></div></div>'),$templateCache.put("ngTagsInput/tag-item.html",'<span ng-bind="$getDisplayText()"></span> <a class="p-icon--close" data-ng-click="$removeTag()" data-ng-bind="$$removeTagSymbol">Remove tag</a>'),$templateCache.put("ngTagsInput/auto-complete.html",'<div class="autocomplete" data-ng-if="suggestionList.visible"><ul class="p-list suggestion-list"><li class="suggestion-item" data-ng-repeat="item in suggestionList.items track by track(item)" data-ng-class="{selected: item == suggestionList.selected}" data-ng-click="addSuggestionByIndex($index)" data-ng-mouseenter="suggestionList.select($index)"><ti-autocomplete-match data="item"></ti-autocomplete-match></li></ul></div>'),$templateCache.put("ngTagsInput/auto-complete-match.html",'<span data-ng-bind-html="$highlight($getDisplayText())"></span>')}])}()},"./src/maasserver/static/js/angular/3rdparty/vs-repeat.js":function(module,exports){function _extends(){return(_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source)Object.prototype.hasOwnProperty.call(source,key)&&(target[key]=source[key])}return target}).apply(this,arguments)}function _slicedToArray(arr,i){if(Array.isArray(arr))return arr;if(Symbol.iterator in Object(arr))return function(arr,i){var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{_n||null==_i.return||_i.return()}finally{if(_d)throw _e}}return _arr}(arr,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}!function(window,angular){var closestElement=angular.element.prototype.closest;if(!closestElement){var matchingFunction=["matches","matchesSelector","webkitMatches","webkitMatchesSelector","msMatches","msMatchesSelector","mozMatches","mozMatchesSelector"].reduce(function(res,prop){var _res;return null!==(_res=res)&&void 0!==_res?_res:prop in document.documentElement?prop:null},null);closestElement=function(selector){for(var _el,el=this[0].parentNode;el!==document.documentElement&&null!=el&&!el[matchingFunction](selector);)el=el.parentNode;return(null===(_el=el)||void 0===_el?void 0:_el[matchingFunction](selector))?angular.element(el):angular.element()}}function getWindowScroll(){var _ref,_document$documentEle,_ref2,_document$documentEle2;return"pageYOffset"in window?{scrollTop:window.pageYOffset,scrollLeft:window.pageXOffset}:{scrollTop:null!==(_ref=null!==(_document$documentEle=document.documentElement.scrollTop)&&void 0!==_document$documentEle?_document$documentEle:document.body.scrollTop)&&void 0!==_ref?_ref:0,scrollLeft:null!==(_ref2=null!==(_document$documentEle2=document.documentElement.scrollLeft)&&void 0!==_document$documentEle2?_document$documentEle2:document.body.scrollLeft)&&void 0!==_ref2?_ref2:0}}function getClientSize(element,sizeProp){return element===window?"clientWidth"===sizeProp?window.innerWidth:window.innerHeight:element[sizeProp]}function attrDeprecated(attrname,$element){!function($element,message){console.warn("vs-repeat deprecation: ".concat(message),$element[0])}($element,"".concat(attrname," attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options"))}var defaultOptions={latch:!1,container:null,scrollParent:null,size:null,offsetBefore:0,offsetAfter:0,scrolledToBeginning:angular.noop,scrolledToEnd:angular.noop,scrolledToBeginningOffset:0,scrolledToEndOffset:0,scrollMargin:0,horizontal:!1,autoresize:!1,hunked:!1,hunkSize:0},vsRepeatModule=angular.module("vs-repeat",[]).directive("vsRepeat",["$compile","$parse",function($compile,$parse){return{restrict:"A",scope:!0,compile:function(compileElement,compileAttrs){var compileRepeatContainer="vsRepeatContainer"in compileAttrs?angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)):compileElement,repeatContainerChildren=compileRepeatContainer.children(),ngRepeatChild=repeatContainerChildren.eq(0),childCloneHtml=ngRepeatChild[0].outerHTML,collectionName="$vs_collection";["vsSize","vsScrollParent","vsSizeProperty","vsHorizontal","vsOffsetBefore","vsOffsetAfter","vsScrolledToEndOffset","vsScrolledToBeginningOffset","vsExcess","vsScrollMargin"].forEach(function(attrname){attrname in compileAttrs&&attrDeprecated(attrname,compileElement)});var _analyzeNgRepeatUsage2=_slicedToArray(function(element){for(var options=["ng-repeat","data-ng-repeat","ng-repeat-start","data-ng-repeat-start"],_i=0;_i<options.length;_i++){var opt=options[_i];if(element.attr(opt))return[opt,element.attr(opt),opt.indexOf("-start")>=0]}throw new Error("angular-vs-repeat: no ng-repeat directive on a child element")}(ngRepeatChild),3),originalNgRepeatAttr=_analyzeNgRepeatUsage2[0],ngRepeatExpression=_analyzeNgRepeatUsage2[1],isNgRepeatStart=_analyzeNgRepeatUsage2[2],_expressionMatches=_slicedToArray(/^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression),4),lhs=_expressionMatches[1],rhs=_expressionMatches[2],rhsSuffix=_expressionMatches[3];if(isNgRepeatStart)for(var index=0,repeaterElement=repeatContainerChildren.eq(index);null==repeaterElement.attr("ng-repeat-end")&&null==repeaterElement.attr("data-ng-repeat-end");)index++,repeaterElement=repeatContainerChildren.eq(index),childCloneHtml+=repeaterElement[0].outerHTML;return compileRepeatContainer.empty(),{pre:function($scope,$element,$attrs){var _$scope$$eval;function _parseSize(options){if("number"==typeof options.size)options.getSize=function(){return options.size};else{var parsed=$parse(String(options.size));options.getSize=function(item){return parsed($scope,(value=item,(key=lhs)in(obj={})?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj));var obj,key,value}}}$scope.vsRepeat={options:_extends({},defaultOptions,null!==(_$scope$$eval=$scope.$eval($attrs.vsRepeat))&&void 0!==_$scope$$eval?_$scope$$eval:{})};var options=$scope.vsRepeat.options;_parseSize(options);var originalLength,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,childClone=angular.element(childCloneHtml),childTagName=childClone[0].tagName.toLowerCase(),originalCollection=[],$beforeContent=angular.element("<"+childTagName+' class="vs-repeat-before-content"></'+childTagName+">"),$afterContent=angular.element("<"+childTagName+' class="vs-repeat-after-content"></'+childTagName+">"),autosizingRequired=null===options.size,$scrollParent=options.scrollParent?"window"===options.scrollParent?angular.element(window):closestElement.call(repeatContainer,options.scrollParent):repeatContainer,clientSize=options.horizontal?"clientWidth":"clientHeight",offsetSize=options.horizontal?"offsetWidth":"offsetHeight",scrollSize=options.horizontal?"scrollWidth":"scrollHeight",scrollPos=options.horizontal?"scrollLeft":"scrollTop";if($scope.vsRepeat.totalSize=0,0===$scrollParent.length)throw"Specified scroll parent selector did not match any element";if($scope.vsRepeat.$scrollParent=$scrollParent,$scope.vsRepeat.sizesCumulative=[],options.debug){var $debugParent="window"===options.scrollParent?angular.element(document.body):$scrollParent,$debug=angular.element('<div class="vs-repeat-debug-element"></div>');$debug.css("position","window"===options.scrollParent?"fixed":"absolute"),$debugParent.append($debug),$scope.$on("$destroy",function(){$debug.remove()})}var _prevStartIndex,_prevEndIndex,_minStartIndex,_maxEndIndex,_prevClientSize,measuredSize=getClientSize($scrollParent[0],clientSize)||50;function refresh(){!originalCollection||originalCollection.length<1?($scope[collectionName]=[],originalLength=0,$scope.vsRepeat.sizesCumulative=[0]):(originalLength=originalCollection.length,options.size?_mapSize():getFromMeasured()),reinitialize()}function _mapSize(){var hardSize=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,sizes=originalCollection.map(function(item){var _hardSize;return null!==(_hardSize=hardSize)&&void 0!==_hardSize?_hardSize:options.getSize(item)}),sum=0;$scope.vsRepeat.sizesCumulative=[0].concat(function(arr){if(Array.isArray(arr)){for(var i=0,arr2=new Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}return Array.from(arr)}(sizes.map(function(size){return sum+=size})))}function getFromMeasured(){autosizingRequired?$scope.$$postDigest(function(){if(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth){for(var children=repeatContainer.children(),i=0,gotSomething=!1,insideStartEndSequence=!1;i<children.length;){if(null!=children[i].attributes[originalNgRepeatAttr]||insideStartEndSequence){if(gotSomething||(measuredSize=0),gotSomething=!0,children[i][offsetSize]&&(measuredSize+=children[i][offsetSize]),!isNgRepeatStart)break;if(null!=children[i].attributes["ng-repeat-end"]||null!=children[i].attributes["data-ng-repeat-end"])break;insideStartEndSequence=!0}i++}gotSomething&&(_mapSize(measuredSize),reinitialize(),autosizingRequired=!1,$scope.$root&&!$scope.$root.$$phase&&$scope.$digest())}else var dereg=$scope.$watch(function(){(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth)&&(dereg(),getFromMeasured())})}):_mapSize(measuredSize)}function getLayoutProps(value){var layoutProp=options.horizontal?"width":"height";return["","min-","max-"].reduce(function(acc,prop){return acc["".concat(prop).concat(layoutProp)]=value,acc},{})}function scrollHandler(){var pos=$scrollParent[0][scrollPos];updateInnerCollection()&&($scope.$digest(),options._ensureScrollIntegrity&&($scrollParent[0][scrollPos]=pos))}function onWindowResize(){options.autoresize&&(autosizingRequired=!0,getFromMeasured(),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()),updateInnerCollection()&&$scope.$digest()}function reinitialize(){var size;_prevStartIndex=void 0,_prevEndIndex=void 0,_minStartIndex=originalLength,_maxEndIndex=0,size=$scope.vsRepeat.sizesCumulative[originalLength],$scope.vsRepeat.totalSize=options.offsetBefore+size+options.offsetAfter,updateInnerCollection(),$scope.$emit("vsRepeatReinitialized",$scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex)}function reinitOnClientHeightChange(){var ch=getClientSize($scrollParent[0],clientSize);ch!==_prevClientSize&&(reinitialize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()),_prevClientSize=ch}function binaryFind(array,threshold){var a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,b=arguments.length>3&&void 0!==arguments[3]?arguments[3]:array.length-1,d=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;if(array[a]===threshold)return[a,a,d];if(array[b]===threshold)return[b,b,d];if(b-a>1){var m=Math.floor((a+b)/2);return array[m]>threshold?binaryFind(array,threshold,a,m,d+1):binaryFind(array,threshold,m,b,d+1)}return[threshold>array[b]?b:a,threshold<array[a]?a:b,d]}function updateInnerCollection(){var element,scrollProp,$scrollPosition=(element=$scrollParent[0],scrollProp=scrollPos,element===window?getWindowScroll()[scrollProp]:element[scrollProp]),$clientSize=getClientSize($scrollParent[0],clientSize);options.debug&&($clientSize/=2);var vsElement,scrollElement,isHorizontal,scrollOffset=repeatContainer[0]===$scrollParent[0]?0:(vsElement=repeatContainer[0],scrollElement=$scrollParent[0],isHorizontal=options.horizontal,vsElement.getBoundingClientRect()[isHorizontal?"left":"top"]-(scrollElement===window?0:scrollElement.getBoundingClientRect()[isHorizontal?"left":"top"])+(scrollElement===window?getWindowScroll():scrollElement)[isHorizontal?"scrollLeft":"scrollTop"]),__startIndex=$scope.vsRepeat.startIndex,__endIndex=$scope.vsRepeat.endIndex;if(autosizingRequired&&!options.size)__startIndex=0,__endIndex=1;else{$scope.$$postDigest(function(){window.requestAnimationFrame(function(){var expectedSize=$scope.vsRepeat.sizesCumulative[originalLength],compStyle=window.getComputedStyle(repeatContainer[0]),paddings=options.horizontal?["paddingLeft","paddingRight"]:["paddingTop","paddingBottom"],containerSize=repeatContainer[0][scrollSize]-paddings.reduce(function(acc,prop){return acc+Number(compStyle[prop].slice(0,-2))},0);repeatContainer[0][scrollSize]&&expectedSize!==containerSize&&console.warn("vsRepeat: size mismatch. Expected size "+expectedSize+"px whereas actual size is "+containerSize+"px. Fix vsSize on element:",$element[0])})});var relativeScroll=$scrollPosition-options.offsetBefore-scrollOffset;__startIndex=_slicedToArray(binaryFind($scope.vsRepeat.sizesCumulative,relativeScroll-options.scrollMargin),1)[0],__startIndex=Math.max(__startIndex,0),__endIndex=_slicedToArray(binaryFind($scope.vsRepeat.sizesCumulative,relativeScroll+options.scrollMargin+$clientSize,__startIndex),2)[1],__endIndex=Math.min(__endIndex,originalLength)}_minStartIndex=Math.min(__startIndex,_minStartIndex),_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.vsRepeat.startIndex=options.latch?_minStartIndex:__startIndex,$scope.vsRepeat.endIndex=options.latch?_maxEndIndex:__endIndex,_maxEndIndex<$scope.vsRepeat.startIndex&&($scope.vsRepeat.startIndex=_maxEndIndex);var digestRequired=!1;if(null==_prevStartIndex?digestRequired=!0:null==_prevEndIndex&&(digestRequired=!0),digestRequired||(options.hunked?Math.abs($scope.vsRepeat.startIndex-_prevStartIndex)>=options.hunkSize||0===$scope.vsRepeat.startIndex&&0!==_prevStartIndex?digestRequired=!0:(Math.abs($scope.vsRepeat.endIndex-_prevEndIndex)>=options.hunkSize||$scope.vsRepeat.endIndex===originalLength&&_prevEndIndex!==originalLength)&&(digestRequired=!0):digestRequired=$scope.vsRepeat.startIndex!==_prevStartIndex||$scope.vsRepeat.endIndex!==_prevEndIndex),digestRequired){var triggerIndex;$scope[collectionName]=originalCollection.slice($scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex),$scope.$emit("vsRepeatInnerCollectionUpdated",$scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex,_prevStartIndex,_prevEndIndex),options.scrolledToEnd&&(triggerIndex=originalCollection.length-options.scrolledToEndOffset,($scope.vsRepeat.endIndex>=triggerIndex&&_prevEndIndex<triggerIndex||originalCollection.length&&$scope.vsRepeat.endIndex===originalCollection.length)&&$scope.$eval(options.scrolledToEnd)),options.scrolledToBeginning&&(triggerIndex=options.scrolledToBeginningOffset,$scope.vsRepeat.startIndex<=triggerIndex&&_prevStartIndex>$scope.vsRepeat.startIndex&&$scope.$eval(options.scrolledToBeginning)),_prevStartIndex=$scope.vsRepeat.startIndex,_prevEndIndex=$scope.vsRepeat.endIndex;var o1=$scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex]+options.offsetBefore,o2=$scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex+$scope[collectionName].length]+options.offsetBefore,total=$scope.vsRepeat.totalSize;$beforeContent.css(getLayoutProps(o1+"px")),$afterContent.css(getLayoutProps(total-o2+"px"))}return digestRequired}options.horizontal?($beforeContent.css("height","100%"),$afterContent.css("height","100%")):($beforeContent.css("width","100%"),$afterContent.css("width","100%")),$attrs.vsRepeatOptions&&$scope.$watchCollection($attrs.vsRepeatOptions,function(newOpts){var mergedOptions=_extends({},options,newOpts);JSON.stringify(mergedOptions)!==JSON.stringify(options)&&(Object.assign(options,newOpts),_parseSize(options),reinitialize())}),$scope.$watchCollection(rhs,function(){var coll=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];originalCollection=coll,refresh()}),childClone.eq(0).attr(originalNgRepeatAttr,lhs+" in "+collectionName+(rhsSuffix?" "+rhsSuffix:"")),childClone.addClass("vs-repeat-repeated-element"),repeatContainer.append($beforeContent),repeatContainer.append(childClone),$compile(childClone)($scope),repeatContainer.append($afterContent),$scope.vsRepeat.startIndex=0,$scope.vsRepeat.endIndex=0,$scrollParent.on("scroll",scrollHandler),angular.element(window).on("resize",onWindowResize),$scope.$on("$destroy",function(){angular.element(window).off("resize",onWindowResize),$scrollParent.off("scroll",scrollHandler)}),$scope.$on("vsRepeatTrigger",refresh),$scope.$on("vsRepeatResize",function(){autosizingRequired=!0,getFromMeasured()}),$scope.$on("vsRenderAll",function(){options.latch&&($scope.vsRepeat.endIndex!==originalLength?setTimeout(function(){var __endIndex=originalLength;_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.vsRepeat.endIndex=options.latch?_maxEndIndex:__endIndex,$scope[collectionName]=originalCollection.slice($scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex),_prevEndIndex=$scope.vsRepeat.endIndex,$beforeContent.css(getLayoutProps(0)),$afterContent.css(getLayoutProps(0)),$scope.$emit("vsRenderAllDone"),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()}):$scope.$emit("vsRenderAllDone"))}),$scope.$watch(function(){"function"==typeof window.requestAnimationFrame?window.requestAnimationFrame(reinitOnClientHeightChange):reinitOnClientHeightChange()})}}}}}]);angular.element(document.head).append('<style id="angular-vs-repeat-style">\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\n }\n </style>'),void 0!==module&&module.exports&&(module.exports=vsRepeatModule.name)}(window,window.angular)},0:function(module,exports,__webpack_require__){__webpack_require__("./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js"),module.exports=__webpack_require__("./src/maasserver/static/js/angular/3rdparty/vs-repeat.js")}});1!function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=0)}({"./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js":function(module,exports){!function(){"use strict";var KEYS_backspace=8,KEYS_tab=9,KEYS_enter=13,KEYS_escape=27,KEYS_space=32,KEYS_up=38,KEYS_down=40,KEYS_left=37,KEYS_right=39,KEYS_delete=46,KEYS_comma=188,SUPPORTED_INPUT_TYPES=["text","email","url"],tagsInput=angular.module("ngTagsInput",[]);tagsInput.directive("tagsInput",["$timeout","$document","$window","tagsInputConfig","tiUtil",function($timeout,$document,$window,tagsInputConfig,tiUtil){function validateType(type){return-1!==SUPPORTED_INPUT_TYPES.indexOf(type)}return{restrict:"E",require:"ngModel",scope:{tags:"=ngModel",onTagAdding:"&",onTagAdded:"&",onInvalidTag:"&",onTagRemoving:"&",onTagRemoved:"&"},replace:!1,transclude:!0,templateUrl:"ngTagsInput/tags-input.html",controller:["$scope","$attrs","$element",function($scope,$attrs,$element){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("tagsInput",$scope,$attrs,{template:[String,"ngTagsInput/tag-item.html"],type:[String,"text",validateType],placeholder:[String,"Add a tag"],tabindex:[Number,null],removeTagSymbol:[String,String.fromCharCode(215)],replaceSpacesWithDashes:[Boolean,!0],minLength:[Number,3],maxLength:[Number,9007199254740991],addOnEnter:[Boolean,!0],addOnSpace:[Boolean,!1],addOnComma:[Boolean,!0],addOnBlur:[Boolean,!0],addOnPaste:[Boolean,!1],pasteSplitPattern:[RegExp,/,/],allowedTagsPattern:[RegExp,/.+/],enableEditingLastTag:[Boolean,!1],minTags:[Number,0],maxTags:[Number,9007199254740991],displayProperty:[String,"text"],keyProperty:[String,""],allowLeftoverText:[Boolean,!1],addFromAutocompleteOnly:[Boolean,!1],spellcheck:[Boolean,!0]}),$scope.tagList=new function(options,events,onTagAdding,onTagRemoving){var getTagText,setTagText,tagIsValid,self={};return getTagText=function(tag){return tiUtil.safeToString(tag[options.displayProperty])},setTagText=function(tag,text){tag[options.displayProperty]=text},tagIsValid=function(tag){var tagText=getTagText(tag);return tagText&&tagText.length>=options.minLength&&tagText.length<=options.maxLength&&options.allowedTagsPattern.test(tagText)&&!tiUtil.findInObjectArray(self.items,tag,options.keyProperty||options.displayProperty)&&onTagAdding({$tag:tag})},self.items=[],self.addText=function(text){var tag={};return setTagText(tag,text),self.add(tag)},self.add=function(tag){var tagText=getTagText(tag);return options.replaceSpacesWithDashes&&(tagText=tiUtil.replaceSpacesWithDashes(tagText)),setTagText(tag,tagText),tagIsValid(tag)?(self.items.push(tag),events.trigger("tag-added",{$tag:tag})):tagText&&events.trigger("invalid-tag",{$tag:tag}),tag},self.remove=function(index){var tag=self.items[index];if(onTagRemoving({$tag:tag}))return self.items.splice(index,1),self.clearSelection(),events.trigger("tag-removed",{$tag:tag}),tag},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index]},self.selectPrior=function(){self.select(--self.index)},self.selectNext=function(){self.select(++self.index)},self.removeSelected=function(){return self.remove(self.index)},self.clearSelection=function(){self.selected=null,self.index=-1},self.clearSelection(),self}($scope.options,$scope.events,tiUtil.handleUndefinedResult($scope.onTagAdding,!0),tiUtil.handleUndefinedResult($scope.onTagRemoving,!0)),this.registerAutocomplete=function(){$element.find("input");return{addTag:function(tag){return $scope.tagList.add(tag)},focusInput:function(){},getTags:function(){return $scope.tags},getCurrentTagText:function(){return $scope.newTag.text},getOptions:function(){return $scope.options},on:function(name,handler){return $scope.events.on(name,handler),this}}},this.registerTagItem=function(){return{getOptions:function(){return $scope.options},removeTag:function(index){$scope.disabled||$scope.tagList.remove(index)}}}}],link:function(scope,element,attrs,ngModelCtrl){var setElementValidity,hotkeys=[KEYS_enter,KEYS_comma,KEYS_space,KEYS_backspace,KEYS_delete,KEYS_left,KEYS_right],tagList=scope.tagList,events=scope.events,options=scope.options,input=element.find("input"),validationOptions=["minTags","maxTags","allowLeftoverText"];setElementValidity=function(){ngModelCtrl.$setValidity("maxTags",scope.tags.length<=options.maxTags),ngModelCtrl.$setValidity("minTags",scope.tags.length>=options.minTags),ngModelCtrl.$setValidity("leftoverText",!(!scope.hasFocus&&!options.allowLeftoverText)||!scope.newTag.text)},ngModelCtrl.$isEmpty=function(value){return!value||!value.length},scope.newTag={text:"",invalid:null,setText:function(value){this.text=value,events.trigger("input-change",value)}},scope.track=function(tag){return tag[options.keyProperty||options.displayProperty]},scope.$watch("tags",function(value){scope.tags=tiUtil.makeObjectArray(value,options.displayProperty),tagList.items=scope.tags}),scope.$watch("tags.length",function(){setElementValidity()}),attrs.$observe("disabled",function(value){scope.disabled=value}),scope.eventHandlers={input:{change:function(text){events.trigger("input-change",text)},keydown:function($event){events.trigger("input-keydown",$event)},focus:function(){scope.hasFocus||(scope.hasFocus=!0,events.trigger("input-focus"))},blur:function(){$timeout(function(){var activeElement=$document.prop("activeElement"),lostFocusToBrowserWindow=activeElement===input[0],lostFocusToChildElement=element[0].contains(activeElement);!lostFocusToBrowserWindow&&lostFocusToChildElement||(scope.hasFocus=!1,events.trigger("input-blur"))})},paste:function($event){$event.getTextData=function(){var clipboardData=$event.clipboardData||$event.originalEvent&&$event.originalEvent.clipboardData;return clipboardData?clipboardData.getData("text/plain"):$window.clipboardData.getData("Text")},events.trigger("input-paste",$event)}},host:{click:function(){scope.disabled}}},events.on("tag-added",scope.onTagAdded).on("invalid-tag",scope.onInvalidTag).on("tag-removed",scope.onTagRemoved).on("tag-added",function(){scope.newTag.setText("")}).on("tag-added tag-removed",function(){ngModelCtrl.$setViewValue(scope.tags)}).on("invalid-tag",function(){scope.newTag.invalid=!0}).on("option-change",function(e){-1!==validationOptions.indexOf(e.name)&&setElementValidity()}).on("input-change",function(){tagList.clearSelection(),scope.newTag.invalid=null}).on("input-focus",function(){element.triggerHandler("focus"),ngModelCtrl.$setValidity("leftoverText",!0)}).on("input-blur",function(){options.addOnBlur&&!options.addFromAutocompleteOnly&&tagList.addText(scope.newTag.text),element.triggerHandler("blur"),setElementValidity()}).on("input-keydown",function(event){var shouldAdd,shouldRemove,shouldSelect,shouldEditLastTag,key=event.keyCode,addKeys={};if(!(event.shiftKey||event.altKey||event.ctrlKey||event.metaKey)&&-1!==hotkeys.indexOf(key)){if(addKeys[KEYS_enter]=options.addOnEnter,addKeys[KEYS_comma]=options.addOnComma,addKeys[KEYS_space]=options.addOnSpace,shouldAdd=!options.addFromAutocompleteOnly&&addKeys[key],shouldRemove=(key===KEYS_backspace||key===KEYS_delete)&&tagList.selected,shouldEditLastTag=key===KEYS_backspace&&0===scope.newTag.text.length&&options.enableEditingLastTag,shouldSelect=(key===KEYS_backspace||key===KEYS_left||key===KEYS_right)&&0===scope.newTag.text.length&&!options.enableEditingLastTag,shouldAdd)tagList.addText(scope.newTag.text);else if(shouldEditLastTag){var tag;tagList.selectPrior(),(tag=tagList.removeSelected())&&scope.newTag.setText(tag[options.displayProperty])}else shouldRemove?tagList.removeSelected():shouldSelect&&(key===KEYS_left||key===KEYS_backspace?tagList.selectPrior():key===KEYS_right&&tagList.selectNext());(shouldAdd||shouldSelect||shouldRemove||shouldEditLastTag)&&event.preventDefault()}}).on("input-paste",function(event){if(options.addOnPaste){var tags=event.getTextData().split(options.pasteSplitPattern);tags.length>1&&(tags.forEach(function(tag){tagList.addText(tag)}),event.preventDefault())}})}}}]),tagsInput.directive("tiTagItem",["tiUtil",function(tiUtil){return{restrict:"E",require:"^tagsInput",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,tagsInputCtrl){var tagsInput=tagsInputCtrl.registerTagItem(),options=tagsInput.getOptions();scope.$$template=options.template,scope.$$removeTagSymbol=options.removeTagSymbol,scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty])},scope.$removeTag=function(){tagsInput.removeTag(scope.$index)},scope.$watch("$parent.$index",function(value){scope.$index=value})}}}]),tagsInput.directive("autoComplete",["$document","$timeout","$sce","$q","tagsInputConfig","tiUtil",function($document,$timeout,$sce,$q,tagsInputConfig,tiUtil){return{restrict:"E",require:"^tagsInput",scope:{source:"&"},templateUrl:"ngTagsInput/auto-complete.html",controller:["$scope","$element","$attrs",function($scope,$element,$attrs){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("autoComplete",$scope,$attrs,{template:[String,"ngTagsInput/auto-complete-match.html"],debounceDelay:[Number,100],minLength:[Number,3],highlightMatchedText:[Boolean,!0],maxResultsToShow:[Number,10],loadOnDownArrow:[Boolean,!1],loadOnEmpty:[Boolean,!1],loadOnFocus:[Boolean,!1],selectFirstMatch:[Boolean,!0],displayProperty:[String,""]}),$scope.suggestionList=new function(loadFn,options,events){var getDifference,lastPromise,getTagId,self={};return getTagId=function(){return options.tagsInput.keyProperty||options.tagsInput.displayProperty},getDifference=function(array1,array2){return array1.filter(function(item){return!tiUtil.findInObjectArray(array2,item,getTagId(),function(a,b){return options.tagsInput.replaceSpacesWithDashes&&(a=tiUtil.replaceSpacesWithDashes(a),b=tiUtil.replaceSpacesWithDashes(b)),tiUtil.defaultComparer(a,b)})})},self.reset=function(){lastPromise=null,self.items=[],self.visible=!1,self.index=-1,self.selected=null,self.query=null},self.show=function(){options.selectFirstMatch?self.select(0):self.selected=null,self.visible=!0},self.load=tiUtil.debounce(function(query,tags){self.query=query;var promise=$q.when(loadFn({$query:query}));lastPromise=promise,promise.then(function(items){promise===lastPromise&&(items=tiUtil.makeObjectArray(items.data||items,getTagId()),items=getDifference(items,tags),self.items=items.slice(0,options.maxResultsToShow),self.items.length>0?self.show():self.reset())})},options.debounceDelay),self.selectNext=function(){self.select(++self.index)},self.selectPrior=function(){self.select(--self.index)},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index],events.trigger("suggestion-selected",index)},self.reset(),self}($scope.source,$scope.options,$scope.events),this.registerAutocompleteMatch=function(){return{getOptions:function(){return $scope.options},getQuery:function(){return $scope.suggestionList.query}}}}],link:function(scope,element,attrs,tagsInputCtrl){var shouldLoadSuggestions,hotkeys=[KEYS_enter,KEYS_tab,KEYS_escape,KEYS_up,KEYS_down],suggestionList=scope.suggestionList,tagsInput=tagsInputCtrl.registerAutocomplete(),options=scope.options,events=scope.events;options.tagsInput=tagsInput.getOptions(),shouldLoadSuggestions=function(value){return value&&value.length>=options.minLength||!value&&options.loadOnEmpty},scope.addSuggestionByIndex=function(index){suggestionList.select(index),scope.addSuggestion()},scope.addSuggestion=function(){var added=!1;return suggestionList.selected&&(tagsInput.addTag(angular.copy(suggestionList.selected)),suggestionList.reset(),tagsInput.focusInput(),added=!0),added},scope.track=function(item){return item[options.tagsInput.keyProperty||options.tagsInput.displayProperty]},tagsInput.on("tag-added invalid-tag input-blur",function(){suggestionList.reset()}).on("input-change",function(value){shouldLoadSuggestions(value)?suggestionList.load(value,tagsInput.getTags()):suggestionList.reset()}).on("input-focus",function(){var value=tagsInput.getCurrentTagText();options.loadOnFocus&&shouldLoadSuggestions(value)&&suggestionList.load(value,tagsInput.getTags())}).on("input-keydown",function(event){var key=event.keyCode,handled=!1;if(-1!==hotkeys.indexOf(key))return suggestionList.visible?key===KEYS_down?(suggestionList.selectNext(),handled=!0):key===KEYS_up?(suggestionList.selectPrior(),handled=!0):key===KEYS_escape?(suggestionList.reset(),handled=!0):key!==KEYS_enter&&key!==KEYS_tab||(handled=scope.addSuggestion()):key===KEYS_down&&scope.options.loadOnDownArrow&&(suggestionList.load(tagsInput.getCurrentTagText(),tagsInput.getTags()),handled=!0),handled?(event.preventDefault(),event.stopImmediatePropagation(),!1):void 0}),events.on("suggestion-selected",function(index){!function(root,index){var element=root.find("li").eq(index),parent=element.parent(),elementTop=element.prop("offsetTop"),elementHeight=element.prop("offsetHeight"),parentHeight=parent.prop("clientHeight"),parentScrollTop=parent.prop("scrollTop");elementTop<parentScrollTop?parent.prop("scrollTop",elementTop):elementTop+elementHeight>parentHeight+parentScrollTop&&parent.prop("scrollTop",elementTop+elementHeight-parentHeight)}(element,index)})}}}]),tagsInput.directive("tiAutocompleteMatch",["$sce","tiUtil",function($sce,tiUtil){return{restrict:"E",require:"^autoComplete",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,autoCompleteCtrl){var autoComplete=autoCompleteCtrl.registerAutocompleteMatch(),options=autoComplete.getOptions();scope.$$template=options.template,scope.$index=scope.$parent.$index,scope.$highlight=function(text){return options.highlightMatchedText&&(text=tiUtil.safeHighlight(text,autoComplete.getQuery())),$sce.trustAsHtml(text)},scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty||options.tagsInput.displayProperty])}}}}]),tagsInput.directive("tiTranscludeAppend",function(){return function(scope,element,attrs,ctrl,transcludeFn){transcludeFn(function(clone){element.append(clone)})}}),tagsInput.directive("tiAutosize",["tagsInputConfig",function(tagsInputConfig){return{restrict:"A",require:"ngModel",link:function(scope,element,attrs,ctrl){var span,resize,threshold=tagsInputConfig.getTextAutosizeThreshold();(span=angular.element('<span class="input"></span>')).css("display","none").css("visibility","hidden").css("width","auto").css("white-space","pre"),element.parent().append(span),resize=function(originalValue){var width,value=originalValue;return angular.isString(value)&&0===value.length&&(value=attrs.placeholder),value&&(span.text(value),span.css("display",""),width=span.prop("offsetWidth"),span.css("display","none")),element.css("width",width?width+threshold+"px":""),originalValue},ctrl.$parsers.unshift(resize),ctrl.$formatters.unshift(resize),attrs.$observe("placeholder",function(value){ctrl.$modelValue||resize(value)})}}}]),tagsInput.directive("tiBindAttrs",function(){return function(scope,element,attrs){scope.$watch(attrs.tiBindAttrs,function(value){angular.forEach(value,function(value,key){"type"===key?element[0].type=value:attrs.$set(key,value)})},!0)}}),tagsInput.provider("tagsInputConfig",function(){var globalDefaults={},interpolationStatus={},autosizeThreshold=3;this.setDefaults=function(directive,defaults){return globalDefaults[directive]=defaults,this},this.setActiveInterpolation=function(directive,options){return interpolationStatus[directive]=options,this},this.setTextAutosizeThreshold=function(threshold){return autosizeThreshold=threshold,this},this.$get=["$interpolate",function($interpolate){var converters={};return converters[String]=function(value){return value},converters[Number]=function(value){return parseInt(value,10)},converters[Boolean]=function(value){return"true"===value.toLowerCase()},converters[RegExp]=function(value){return new RegExp(value)},{load:function(directive,scope,attrs,options){var defaultValidator=function(){return!0};scope.options={},angular.forEach(options,function(value,key){var type,localDefault,validator,converter,getDefault,updateValue;type=value[0],localDefault=value[1],validator=value[2]||defaultValidator,converter=converters[type],getDefault=function(){var globalValue=globalDefaults[directive]&&globalDefaults[directive][key];return angular.isDefined(globalValue)?globalValue:localDefault},updateValue=function(value){scope.options[key]=value&&validator(value)?converter(value):getDefault()},interpolationStatus[directive]&&interpolationStatus[directive][key]?attrs.$observe(key,function(value){updateValue(value),scope.events.trigger("option-change",{name:key,newValue:value})}):updateValue(attrs[key]&&$interpolate(attrs[key])(scope.$parent))})},getTextAutosizeThreshold:function(){return autosizeThreshold}}}]}),tagsInput.factory("tiUtil",["$timeout",function($timeout){var self={debounce:function(fn,delay){var timeoutId;return function(){var args=arguments;$timeout.cancel(timeoutId),timeoutId=$timeout(function(){fn.apply(null,args)},delay)}},makeObjectArray:function(array,key){return(array=array||[]).length>0&&!angular.isObject(array[0])&&array.forEach(function(item,index){array[index]={},array[index][key]=item}),array},findInObjectArray:function(array,obj,key,comparer){var item=null;return comparer=comparer||self.defaultComparer,array.some(function(element){if(comparer(element[key],obj[key]))return item=element,!0}),item},defaultComparer:function(a,b){return self.safeToString(a).toLowerCase()===self.safeToString(b).toLowerCase()},safeHighlight:function(str,value){if(!value)return str;str=self.encodeHTML(str),value=self.encodeHTML(value);var expression=new RegExp("&[^;]+;|"+function(str){return str.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}(value),"gi");return str.replace(expression,function(match){return match.toLowerCase()===value.toLowerCase()?"<em>"+match+"</em>":match})},safeToString:function(value){return angular.isUndefined(value)||null==value?"":value.toString().trim()},encodeHTML:function(value){return self.safeToString(value).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},handleUndefinedResult:function(fn,valueIfUndefined){return function(){var result=fn.apply(null,arguments);return angular.isUndefined(result)?valueIfUndefined:result}},replaceSpacesWithDashes:function(str){return self.safeToString(str).replace(/\s/g,"-")},simplePubSub:function(){var events={};return{on:function(names,handler){return names.split(" ").forEach(function(name){events[name]||(events[name]=[]),events[name].push(handler)}),this},trigger:function(name,args){return(events[name]||[]).every(function(handler){return self.handleUndefinedResult(handler,!0)(args)}),this}}}};return self}]),tagsInput.run(["$templateCache",function($templateCache){$templateCache.put("ngTagsInput/tags-input.html",'<div class="host" tabindex="-1" data-ng-click="eventHandlers.host.click()" ti-transclude-append=""><div class="tags" data-ng-class="{focused: hasFocus}"><ul class="tag-list"><li class="tag-item" data-ng-repeat="tag in tagList.items track by track(tag)" data-ng-class="{ selected: tag == tagList.selected }"><ti-tag-item data="tag"></ti-tag-item></li></ul><input class="input u-no-margin--top" autocomplete="off" data-ng-model="newTag.text" data-ng-change="eventHandlers.input.change(newTag.text)" data-ng-keydown="eventHandlers.input.keydown($event)" data-ng-focus="eventHandlers.input.focus($event)" data-ng-blur="eventHandlers.input.blur($event)" data-ng-paste="eventHandlers.input.paste($event)" data-ng-trim="false" data-ng-class="{\'invalid-tag\': newTag.invalid}" data-ng-disabled="disabled" ti-bind-attrs="{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}" ti-autosize=""></div></div>'),$templateCache.put("ngTagsInput/tag-item.html",'<span ng-bind="$getDisplayText()"></span> <a class="p-icon--close" data-ng-click="$removeTag()" data-ng-bind="$$removeTagSymbol">Remove tag</a>'),$templateCache.put("ngTagsInput/auto-complete.html",'<div class="autocomplete" data-ng-if="suggestionList.visible"><ul class="p-list suggestion-list"><li class="suggestion-item" data-ng-repeat="item in suggestionList.items track by track(item)" data-ng-class="{selected: item == suggestionList.selected}" data-ng-click="addSuggestionByIndex($index)" data-ng-mouseenter="suggestionList.select($index)"><ti-autocomplete-match data="item"></ti-autocomplete-match></li></ul></div>'),$templateCache.put("ngTagsInput/auto-complete-match.html",'<span data-ng-bind-html="$highlight($getDisplayText())"></span>')}])}()},"./src/maasserver/static/js/angular/3rdparty/vs-repeat.js":function(module,exports){!function(window,angular){"use strict";var dde=document.documentElement,matchingFunction=dde.matches?"matches":dde.matchesSelector?"matchesSelector":dde.webkitMatches?"webkitMatches":dde.webkitMatchesSelector?"webkitMatchesSelector":dde.msMatches?"msMatches":dde.msMatchesSelector?"msMatchesSelector":dde.mozMatches?"mozMatches":dde.mozMatchesSelector?"mozMatchesSelector":null,closestElement=angular.element.prototype.closest||function(selector){for(var el=this[0].parentNode;el!==document.documentElement&&null!=el&&!el[matchingFunction](selector);)el=el.parentNode;return el&&el[matchingFunction](selector)?angular.element(el):angular.element()};function getWindowScroll(){if("pageYOffset"in window)return{scrollTop:pageYOffset,scrollLeft:pageXOffset};var sx,d=document,r=d.documentElement,b=d.body;return sx=r.scrollLeft||b.scrollLeft||0,{scrollTop:r.scrollTop||b.scrollTop||0,scrollLeft:sx}}function getClientSize(element,sizeProp){return element===window?"clientWidth"===sizeProp?window.innerWidth:window.innerHeight:element[sizeProp]}var vsRepeatModule=angular.module("vs-repeat",[]).directive("vsRepeat",["$compile","$parse",function($compile,$parse){return{restrict:"A",scope:!0,compile:function($element,$attrs){var ngRepeatExpression,expressionMatches,lhs,rhs,rhsSuffix,originalNgRepeatAttr,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,ngRepeatChild=repeatContainer.children().eq(0),childCloneHtml=ngRepeatChild[0].outerHTML,collectionName="$vs_collection",isNgRepeatStart=!1,attributesDictionary={vsRepeat:"elementSize",vsOffsetBefore:"offsetBefore",vsOffsetAfter:"offsetAfter",vsScrolledToEndOffset:"scrolledToEndOffset",vsScrolledToBeginningOffset:"scrolledToBeginningOffset",vsExcess:"excess"};if(ngRepeatChild.attr("ng-repeat"))originalNgRepeatAttr="ng-repeat",ngRepeatExpression=ngRepeatChild.attr("ng-repeat");else if(ngRepeatChild.attr("data-ng-repeat"))originalNgRepeatAttr="data-ng-repeat",ngRepeatExpression=ngRepeatChild.attr("data-ng-repeat");else if(ngRepeatChild.attr("ng-repeat-start"))isNgRepeatStart=!0,originalNgRepeatAttr="ng-repeat-start",ngRepeatExpression=ngRepeatChild.attr("ng-repeat-start");else{if(!ngRepeatChild.attr("data-ng-repeat-start"))throw new Error("angular-vs-repeat: no ng-repeat directive on a child element");isNgRepeatStart=!0,originalNgRepeatAttr="data-ng-repeat-start",ngRepeatExpression=ngRepeatChild.attr("data-ng-repeat-start")}if(expressionMatches=/^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression),lhs=expressionMatches[1],rhs=expressionMatches[2],rhsSuffix=expressionMatches[3],isNgRepeatStart)for(var index=0,repeaterElement=repeatContainer.children().eq(0);null==repeaterElement.attr("ng-repeat-end")&&null==repeaterElement.attr("data-ng-repeat-end");)index++,repeaterElement=repeatContainer.children().eq(index),childCloneHtml+=repeaterElement[0].outerHTML;return repeatContainer.empty(),{pre:function($scope,$element,$attrs){var originalLength,_prevStartIndex,_prevEndIndex,_minStartIndex,_maxEndIndex,_prevClientSize,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,childClone=angular.element(childCloneHtml),childTagName=childClone[0].tagName.toLowerCase(),originalCollection=[],$$horizontal=void 0!==$attrs.vsHorizontal,$beforeContent=angular.element("<"+childTagName+' class="vs-repeat-before-content"></'+childTagName+">"),$afterContent=angular.element("<"+childTagName+' class="vs-repeat-after-content"></'+childTagName+">"),autoSize=!$attrs.vsRepeat,sizesPropertyExists=!!$attrs.vsSize||!!$attrs.vsSizeProperty,$scrollParent=$attrs.vsScrollParent?"window"===$attrs.vsScrollParent?angular.element(window):closestElement.call(repeatContainer,$attrs.vsScrollParent):repeatContainer,$$options="vsOptions"in $attrs?$scope.$eval($attrs.vsOptions):{},clientSize=$$horizontal?"clientWidth":"clientHeight",offsetSize=$$horizontal?"offsetWidth":"offsetHeight",scrollPos=$$horizontal?"scrollLeft":"scrollTop";if($scope.totalSize=0,!("vsSize"in $attrs)&&"vsSizeProperty"in $attrs&&console.warn("vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions."),0===$scrollParent.length)throw"Specified scroll parent selector did not match any element";function refresh(){if(!originalCollection||originalCollection.length<1)$scope[collectionName]=[],originalLength=0,$scope.sizesCumulative=[0];else if(originalLength=originalCollection.length,sizesPropertyExists){$scope.sizes=originalCollection.map(function(item){var s=$scope.$new(!1);angular.extend(s,item),s[lhs]=item;var size=$attrs.vsSize||$attrs.vsSizeProperty?s.$eval($attrs.vsSize||$attrs.vsSizeProperty):$scope.elementSize;return s.$destroy(),size});var sum=0;$scope.sizesCumulative=$scope.sizes.map(function(size){var res=sum;return sum+=size,res}),$scope.sizesCumulative.push(sum)}else setAutoSize();reinitialize()}function setAutoSize(){autoSize&&$scope.$$postDigest(function(){if(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth){for(var children=repeatContainer.children(),i=0,gotSomething=!1,insideStartEndSequence=!1;i<children.length;){if(null!=children[i].attributes[originalNgRepeatAttr]||insideStartEndSequence){if(gotSomething||($scope.elementSize=0),gotSomething=!0,children[i][offsetSize]&&($scope.elementSize+=children[i][offsetSize]),!isNgRepeatStart)break;if(null!=children[i].attributes["ng-repeat-end"]||null!=children[i].attributes["data-ng-repeat-end"])break;insideStartEndSequence=!0}i++}gotSomething&&(reinitialize(),autoSize=!1,$scope.$root&&!$scope.$root.$$phase&&$scope.$apply())}else var dereg=$scope.$watch(function(){(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth)&&(dereg(),setAutoSize())})})}function getLayoutProp(){var layoutPropPrefix="tr"===childTagName?"":"min-";return $$horizontal?layoutPropPrefix+"width":layoutPropPrefix+"height"}function scrollHandler(){updateInnerCollection()&&$scope.$digest()}function onWindowResize(){void 0!==$attrs.vsAutoresize&&(autoSize=!0,setAutoSize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$apply()),updateInnerCollection()&&$scope.$apply()}function reinitialize(){var size;_prevStartIndex=void 0,_prevEndIndex=void 0,_minStartIndex=originalLength,_maxEndIndex=0,size=sizesPropertyExists?$scope.sizesCumulative[originalLength]:$scope.elementSize*originalLength,$scope.totalSize=$scope.offsetBefore+size+$scope.offsetAfter,updateInnerCollection(),$scope.$emit("vsRepeatReinitialized",$scope.startIndex,$scope.endIndex)}function reinitOnClientHeightChange(){var ch=getClientSize($scrollParent[0],clientSize);ch!==_prevClientSize&&(reinitialize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$apply()),_prevClientSize=ch}function updateInnerCollection(){var element,scrollProp,vsElement,scrollElement,isHorizontal,$scrollPosition=(element=$scrollParent[0],scrollProp=scrollPos,element===window?getWindowScroll()[scrollProp]:element[scrollProp]),$clientSize=getClientSize($scrollParent[0],clientSize),scrollOffset=repeatContainer[0]===$scrollParent[0]?0:(vsElement=repeatContainer[0],scrollElement=$scrollParent[0],isHorizontal=$$horizontal,vsElement.getBoundingClientRect()[isHorizontal?"left":"top"]-(scrollElement===window?0:scrollElement.getBoundingClientRect()[isHorizontal?"left":"top"])+(scrollElement===window?getWindowScroll():scrollElement)[isHorizontal?"scrollLeft":"scrollTop"]),__startIndex=$scope.startIndex,__endIndex=$scope.endIndex;if(sizesPropertyExists){for(__startIndex=0;$scope.sizesCumulative[__startIndex]<$scrollPosition-$scope.offsetBefore-scrollOffset;)__startIndex++;for(__startIndex>0&&__startIndex--,__endIndex=__startIndex=Math.max(Math.floor(__startIndex-$scope.excess/2),0);$scope.sizesCumulative[__endIndex]<$scrollPosition-$scope.offsetBefore-scrollOffset+$clientSize;)__endIndex++;__endIndex=Math.min(Math.ceil(__endIndex+$scope.excess/2),originalLength)}else __startIndex=Math.max(Math.floor(($scrollPosition-$scope.offsetBefore-scrollOffset)/$scope.elementSize)-$scope.excess/2,0),__endIndex=Math.min(__startIndex+Math.ceil($clientSize/$scope.elementSize)+$scope.excess,originalLength);_minStartIndex=Math.min(__startIndex,_minStartIndex),_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.startIndex=$$options.latch?_minStartIndex:__startIndex,$scope.endIndex=$$options.latch?_maxEndIndex:__endIndex;var digestRequired=!1;if(null==_prevStartIndex?digestRequired=!0:null==_prevEndIndex&&(digestRequired=!0),digestRequired||($$options.hunked?Math.abs($scope.startIndex-_prevStartIndex)>=$scope.excess/2||0===$scope.startIndex&&0!==_prevStartIndex?digestRequired=!0:(Math.abs($scope.endIndex-_prevEndIndex)>=$scope.excess/2||$scope.endIndex===originalLength&&_prevEndIndex!==originalLength)&&(digestRequired=!0):digestRequired=$scope.startIndex!==_prevStartIndex||$scope.endIndex!==_prevEndIndex),digestRequired){var triggerIndex;$scope[collectionName]=originalCollection.slice($scope.startIndex,$scope.endIndex),$scope.$emit("vsRepeatInnerCollectionUpdated",$scope.startIndex,$scope.endIndex,_prevStartIndex,_prevEndIndex),$attrs.vsScrolledToEnd&&(triggerIndex=originalCollection.length-($scope.scrolledToEndOffset||0),($scope.endIndex>=triggerIndex&&_prevEndIndex<triggerIndex||originalCollection.length&&$scope.endIndex===originalCollection.length)&&$scope.$eval($attrs.vsScrolledToEnd)),$attrs.vsScrolledToBeginning&&(triggerIndex=$scope.scrolledToBeginningOffset||0,$scope.startIndex<=triggerIndex&&_prevStartIndex>$scope.startIndex&&$scope.$eval($attrs.vsScrolledToBeginning)),_prevStartIndex=$scope.startIndex,_prevEndIndex=$scope.endIndex;var parsed=$parse(sizesPropertyExists?"(sizesCumulative[$index + startIndex] + offsetBefore)":"(($index + startIndex) * elementSize + offsetBefore)"),o1=parsed($scope,{$index:0}),o2=parsed($scope,{$index:$scope[collectionName].length}),total=$scope.totalSize;$beforeContent.css(getLayoutProp(),o1+"px"),$afterContent.css(getLayoutProp(),total-o2+"px")}return digestRequired}$scope.$scrollParent=$scrollParent,sizesPropertyExists&&($scope.sizesCumulative=[]),$scope.elementSize=+$attrs.vsRepeat||getClientSize($scrollParent[0],clientSize)||50,$scope.offsetBefore=0,$scope.offsetAfter=0,$scope.excess=2,$$horizontal?($beforeContent.css("height","100%"),$afterContent.css("height","100%")):($beforeContent.css("width","100%"),$afterContent.css("width","100%")),Object.keys(attributesDictionary).forEach(function(key){$attrs[key]&&$attrs.$observe(key,function(value){$scope[attributesDictionary[key]]=+value,reinitialize()})}),$scope.$watchCollection(rhs,function(coll){originalCollection=coll||[],refresh()}),childClone.eq(0).attr(originalNgRepeatAttr,lhs+" in "+collectionName+(rhsSuffix?" "+rhsSuffix:"")),childClone.addClass("vs-repeat-repeated-element"),repeatContainer.append($beforeContent),repeatContainer.append(childClone),$compile(childClone)($scope),repeatContainer.append($afterContent),$scope.startIndex=0,$scope.endIndex=0,$scrollParent.on("scroll",scrollHandler),angular.element(window).on("resize",onWindowResize),$scope.$on("$destroy",function(){angular.element(window).off("resize",onWindowResize),$scrollParent.off("scroll",scrollHandler)}),$scope.$on("vsRepeatTrigger",refresh),$scope.$on("vsRepeatResize",function(){autoSize=!0,setAutoSize()}),$scope.$on("vsRenderAll",function(){$$options.latch&&setTimeout(function(){var __endIndex=originalLength;_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.endIndex=$$options.latch?_maxEndIndex:__endIndex,$scope[collectionName]=originalCollection.slice($scope.startIndex,$scope.endIndex),_prevEndIndex=$scope.endIndex,$scope.$$postDigest(function(){$beforeContent.css(getLayoutProp(),0),$afterContent.css(getLayoutProp(),0)}),$scope.$apply(function(){$scope.$emit("vsRenderAllDone")})})}),$scope.$watch(function(){"function"==typeof window.requestAnimationFrame?window.requestAnimationFrame(reinitOnClientHeightChange):reinitOnClientHeightChange()})}}}}}]);void 0!==module&&module.exports&&(module.exports=vsRepeatModule.name)}(window,window.angular)},0:function(module,exports,__webpack_require__){__webpack_require__("./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js"),module.exports=__webpack_require__("./src/maasserver/static/js/angular/3rdparty/vs-repeat.js")}});
2//# sourceMappingURL=vendor-min.js.map2//# sourceMappingURL=vendor-min.js.map
3\ No newline at end of file3\ No newline at end of file
diff --git a/src/maasserver/static/js/bundle/vendor-min.js.map b/src/maasserver/static/js/bundle/vendor-min.js.map
index 4d387bd..3cb19d2 100644
--- a/src/maasserver/static/js/bundle/vendor-min.js.map
+++ b/src/maasserver/static/js/bundle/vendor-min.js.map
@@ -1 +1 @@
1{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js","webpack:///./src/maasserver/static/js/angular/3rdparty/vs-repeat.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","KEYS","SUPPORTED_INPUT_TYPES","tagsInput","angular","directive","$timeout","$document","$window","tagsInputConfig","tiUtil","validateType","type","indexOf","restrict","require","scope","tags","onTagAdding","onTagAdded","onInvalidTag","onTagRemoving","onTagRemoved","replace","transclude","templateUrl","controller","$scope","$attrs","$element","events","simplePubSub","load","template","String","placeholder","tabindex","Number","removeTagSymbol","fromCharCode","replaceSpacesWithDashes","Boolean","minLength","maxLength","addOnEnter","addOnSpace","addOnComma","addOnBlur","addOnPaste","pasteSplitPattern","RegExp","allowedTagsPattern","enableEditingLastTag","minTags","maxTags","displayProperty","keyProperty","allowLeftoverText","addFromAutocompleteOnly","spellcheck","tagList","options","getTagText","setTagText","tagIsValid","self","tag","safeToString","text","tagText","length","test","findInObjectArray","items","$tag","addText","add","push","trigger","remove","index","splice","clearSelection","select","selected","selectPrior","selectNext","removeSelected","handleUndefinedResult","this","registerAutocomplete","find","addTag","focusInput","getTags","getCurrentTagText","newTag","getOptions","on","handler","registerTagItem","removeTag","disabled","link","element","attrs","ngModelCtrl","setElementValidity","hotkeys","input","validationOptions","$setValidity","hasFocus","$isEmpty","invalid","setText","track","$watch","makeObjectArray","$observe","eventHandlers","change","keydown","$event","focus","blur","activeElement","prop","lostFocusToBrowserWindow","lostFocusToChildElement","contains","paste","getTextData","clipboardData","originalEvent","getData","host","click","$setViewValue","e","triggerHandler","event","shouldAdd","shouldRemove","shouldSelect","shouldEditLastTag","key","keyCode","addKeys","shiftKey","altKey","ctrlKey","metaKey","preventDefault","split","forEach","data","tagsInputCtrl","$$template","$$removeTagSymbol","$getDisplayText","$removeTag","$index","$sce","$q","source","debounceDelay","highlightMatchedText","maxResultsToShow","loadOnDownArrow","loadOnEmpty","loadOnFocus","selectFirstMatch","suggestionList","loadFn","getDifference","lastPromise","getTagId","array1","array2","filter","item","a","b","defaultComparer","reset","visible","query","show","debounce","promise","when","$query","then","slice","registerAutocompleteMatch","getQuery","shouldLoadSuggestions","addSuggestionByIndex","addSuggestion","added","copy","handled","stopImmediatePropagation","root","eq","parent","elementTop","elementHeight","parentHeight","parentScrollTop","scrollToElement","autoCompleteCtrl","autoComplete","$parent","$highlight","safeHighlight","trustAsHtml","ctrl","transcludeFn","clone","append","span","resize","threshold","getTextAutosizeThreshold","css","originalValue","width","isString","$parsers","unshift","$formatters","$modelValue","tiBindAttrs","$set","provider","globalDefaults","interpolationStatus","autosizeThreshold","setDefaults","defaults","setActiveInterpolation","setTextAutosizeThreshold","$get","$interpolate","converters","parseInt","toLowerCase","defaultValidator","localDefault","validator","converter","getDefault","updateValue","globalValue","isDefined","newValue","factory","fn","delay","timeoutId","args","arguments","cancel","apply","array","isObject","obj","comparer","some","str","encodeHTML","expression","escapeRegexChars","match","isUndefined","toString","trim","valueIfUndefined","result","names","every","run","$templateCache","put","_extends","assign","target","_slicedToArray","arr","Array","isArray","Symbol","iterator","_arr","_n","_d","_e","undefined","_s","_i","next","done","err","_sliceIterator","TypeError","window","closestElement","closest","matchingFunction","reduce","res","_res","document","documentElement","selector","_el","el","parentNode","getWindowScroll","_ref","_document$documentEle","_ref2","_document$documentEle2","scrollTop","pageYOffset","scrollLeft","pageXOffset","body","getClientSize","sizeProp","innerWidth","innerHeight","attrDeprecated","attrname","message","console","warn","concat","printDeprecationWarning","defaultOptions","latch","container","scrollParent","size","offsetBefore","offsetAfter","scrolledToBeginning","noop","scrolledToEnd","scrolledToBeginningOffset","scrolledToEndOffset","scrollMargin","horizontal","autoresize","hunked","hunkSize","vsRepeatModule","$compile","$parse","compile","compileElement","compileAttrs","compileRepeatContainer","querySelector","vsRepeatContainer","repeatContainerChildren","children","ngRepeatChild","childCloneHtml","outerHTML","collectionName","_analyzeNgRepeatUsage2","opt","attr","Error","analyzeNgRepeatUsage","originalNgRepeatAttr","ngRepeatExpression","isNgRepeatStart","_expressionMatches","exec","lhs","rhs","rhsSuffix","repeaterElement","empty","pre","_$scope$$eval","_parseSize","getSize","parsed","writable","vsRepeat","$eval","originalLength","repeatContainer","childClone","childTagName","tagName","originalCollection","$beforeContent","$afterContent","autosizingRequired","$scrollParent","clientSize","offsetSize","scrollSize","scrollPos","totalSize","sizesCumulative","debug","$debugParent","$debug","$on","_prevStartIndex","_prevEndIndex","_minStartIndex","_maxEndIndex","_prevClientSize","measuredSize","refresh","_mapSize","getFromMeasured","reinitialize","hardSize","sizes","map","_hardSize","sum","arr2","from","_toConsumableArray","$$postDigest","offsetHeight","offsetWidth","gotSomething","insideStartEndSequence","attributes","$root","$$phase","$digest","dereg","getLayoutProps","layoutProp","acc","scrollHandler","pos","updateInnerCollection","_ensureScrollIntegrity","onWindowResize","$emit","startIndex","endIndex","reinitOnClientHeightChange","ch","binaryFind","Math","floor","scrollProp","$scrollPosition","$clientSize","vsElement","scrollElement","isHorizontal","scrollOffset","getBoundingClientRect","__startIndex","__endIndex","requestAnimationFrame","expectedSize","compStyle","getComputedStyle","paddings","containerSize","relativeScroll","max","min","digestRequired","abs","triggerIndex","o1","o2","total","vsRepeatOptions","$watchCollection","newOpts","mergedOptions","JSON","stringify","coll","addClass","off","setTimeout","head"],"mappings":"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","file":"vendor-min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/*!\n * ngTagsInput v2.3.0\n * http://mbenford.github.io/ngTagsInput\n *\n * Copyright (c) 2013-2015 Michael Benford\n * License: MIT\n *\n * Generated at 2015-03-24 00:49:44 -0300\n */\n(function() {\n'use strict';\n\nvar KEYS = {\n backspace: 8,\n tab: 9,\n enter: 13,\n escape: 27,\n space: 32,\n up: 38,\n down: 40,\n left: 37,\n right: 39,\n delete: 46,\n comma: 188\n};\n\nvar MAX_SAFE_INTEGER = 9007199254740991;\nvar SUPPORTED_INPUT_TYPES = ['text', 'email', 'url'];\n\nvar tagsInput = angular.module('ngTagsInput', []);\n\n/**\n * @ngdoc directive\n * @name tagsInput\n * @module ngTagsInput\n *\n * @description\n * Renders an input box with tag editing support.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} [displayProperty=text] Property to be rendered as the tag label.\n * @param {string=} [keyProperty=text] Property to be used as a unique identifier for the tag.\n * @param {string=} [type=text] Type of the input element. Only 'text', 'email' and 'url' are supported values.\n * @param {number=} tabindex Tab order of the control.\n * @param {string=} [placeholder=Add a tag] Placeholder text for the control.\n * @param {number=} [minLength=3] Minimum length for a new tag.\n * @param {number=} [maxLength=MAX_SAFE_INTEGER] Maximum length allowed for a new tag.\n * @param {number=} [minTags=0] Sets minTags validation error key if the number of tags added is less than minTags.\n * @param {number=} [maxTags=MAX_SAFE_INTEGER] Sets maxTags validation error key if the number of tags added is greater than maxTags.\n * @param {boolean=} [allowLeftoverText=false] Sets leftoverText validation error key if there is any leftover text in\n * the input element when the directive loses focus.\n * @param {string=} [removeTagSymbol=×] Symbol character for the remove tag button.\n * @param {boolean=} [addOnEnter=true] Flag indicating that a new tag will be added on pressing the ENTER key.\n * @param {boolean=} [addOnSpace=false] Flag indicating that a new tag will be added on pressing the SPACE key.\n * @param {boolean=} [addOnComma=true] Flag indicating that a new tag will be added on pressing the COMMA key.\n * @param {boolean=} [addOnBlur=true] Flag indicating that a new tag will be added when the input field loses focus.\n * @param {boolean=} [addOnPaste=false] Flag indicating that the text pasted into the input field will be split into tags.\n * @param {string=} [pasteSplitPattern=,] Regular expression used to split the pasted text into tags.\n * @param {boolean=} [replaceSpacesWithDashes=true] Flag indicating that spaces will be replaced with dashes.\n * @param {string=} [allowedTagsPattern=.+] Regular expression that determines whether a new tag is valid.\n * @param {boolean=} [enableEditingLastTag=false] Flag indicating that the last tag will be moved back into\n * the new tag input box instead of being removed when the backspace key\n * is pressed and the input box is empty.\n * @param {boolean=} [addFromAutocompleteOnly=false] Flag indicating that only tags coming from the autocomplete list will be allowed.\n * When this flag is true, addOnEnter, addOnComma, addOnSpace, addOnBlur and\n * allowLeftoverText values are ignored.\n * @param {boolean=} [spellcheck=true] Flag indicating whether the browser's spellcheck is enabled for the input field or not.\n * @param {expression} onTagAdding Expression to evaluate that will be invoked before adding a new tag. The new tag is available as $tag. This method must return either true or false. If false, the tag will not be added.\n * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.\n * @param {expression} onInvalidTag Expression to evaluate when a tag is invalid. The invalid tag is available as $tag.\n * @param {expression} onTagRemoving Expression to evaluate that will be invoked before removing a tag. The tag is available as $tag. This method must return either true or false. If false, the tag will not be removed.\n * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.\n */\ntagsInput.directive('tagsInput', [\"$timeout\",\"$document\",\"$window\",\"tagsInputConfig\",\"tiUtil\", function($timeout, $document, $window, tagsInputConfig, tiUtil) {\n function TagList(options, events, onTagAdding, onTagRemoving) {\n var self = {}, getTagText, setTagText, tagIsValid;\n\n getTagText = function(tag) {\n return tiUtil.safeToString(tag[options.displayProperty]);\n };\n\n setTagText = function(tag, text) {\n tag[options.displayProperty] = text;\n };\n\n tagIsValid = function(tag) {\n var tagText = getTagText(tag);\n\n return tagText &&\n tagText.length >= options.minLength &&\n tagText.length <= options.maxLength &&\n options.allowedTagsPattern.test(tagText) &&\n !tiUtil.findInObjectArray(self.items, tag, options.keyProperty || options.displayProperty) &&\n onTagAdding({ $tag: tag });\n };\n\n self.items = [];\n\n self.addText = function(text) {\n var tag = {};\n setTagText(tag, text);\n return self.add(tag);\n };\n\n self.add = function(tag) {\n var tagText = getTagText(tag);\n\n if (options.replaceSpacesWithDashes) {\n tagText = tiUtil.replaceSpacesWithDashes(tagText);\n }\n\n setTagText(tag, tagText);\n\n if (tagIsValid(tag)) {\n self.items.push(tag);\n events.trigger('tag-added', { $tag: tag });\n }\n else if (tagText) {\n events.trigger('invalid-tag', { $tag: tag });\n }\n\n return tag;\n };\n\n self.remove = function(index) {\n var tag = self.items[index];\n\n if (onTagRemoving({ $tag: tag })) {\n self.items.splice(index, 1);\n self.clearSelection();\n events.trigger('tag-removed', { $tag: tag });\n return tag;\n }\n };\n\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n\n self.index = index;\n self.selected = self.items[index];\n };\n\n self.selectPrior = function() {\n self.select(--self.index);\n };\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n\n self.removeSelected = function() {\n return self.remove(self.index);\n };\n\n self.clearSelection = function() {\n self.selected = null;\n self.index = -1;\n };\n\n self.clearSelection();\n\n return self;\n }\n\n function validateType(type) {\n return SUPPORTED_INPUT_TYPES.indexOf(type) !== -1;\n }\n\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n tags: '=ngModel',\n onTagAdding: '&',\n onTagAdded: '&',\n onInvalidTag: '&',\n onTagRemoving: '&',\n onTagRemoved: '&'\n },\n replace: false,\n transclude: true,\n templateUrl: 'ngTagsInput/tags-input.html',\n controller: [\"$scope\",\"$attrs\",\"$element\", function($scope, $attrs, $element) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('tagsInput', $scope, $attrs, {\n template: [String, 'ngTagsInput/tag-item.html'],\n type: [String, 'text', validateType],\n placeholder: [String, 'Add a tag'],\n tabindex: [Number, null],\n removeTagSymbol: [String, String.fromCharCode(215)],\n replaceSpacesWithDashes: [Boolean, true],\n minLength: [Number, 3],\n maxLength: [Number, MAX_SAFE_INTEGER],\n addOnEnter: [Boolean, true],\n addOnSpace: [Boolean, false],\n addOnComma: [Boolean, true],\n addOnBlur: [Boolean, true],\n addOnPaste: [Boolean, false],\n pasteSplitPattern: [RegExp, /,/],\n allowedTagsPattern: [RegExp, /.+/],\n enableEditingLastTag: [Boolean, false],\n minTags: [Number, 0],\n maxTags: [Number, MAX_SAFE_INTEGER],\n displayProperty: [String, 'text'],\n keyProperty: [String, ''],\n allowLeftoverText: [Boolean, false],\n addFromAutocompleteOnly: [Boolean, false],\n spellcheck: [Boolean, true]\n });\n\n $scope.tagList = new TagList($scope.options, $scope.events,\n tiUtil.handleUndefinedResult($scope.onTagAdding, true),\n tiUtil.handleUndefinedResult($scope.onTagRemoving, true));\n\n this.registerAutocomplete = function() {\n var input = $element.find('input');\n\n return {\n addTag: function(tag) {\n return $scope.tagList.add(tag);\n },\n focusInput: function() {\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n },\n getTags: function() {\n return $scope.tags;\n },\n getCurrentTagText: function() {\n return $scope.newTag.text;\n },\n getOptions: function() {\n return $scope.options;\n },\n on: function(name, handler) {\n $scope.events.on(name, handler);\n return this;\n }\n };\n };\n\n this.registerTagItem = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n removeTag: function(index) {\n if ($scope.disabled) {\n return;\n }\n $scope.tagList.remove(index);\n }\n };\n };\n }],\n link: function(scope, element, attrs, ngModelCtrl) {\n var hotkeys = [KEYS.enter, KEYS.comma, KEYS.space, KEYS.backspace, KEYS.delete, KEYS.left, KEYS.right],\n tagList = scope.tagList,\n events = scope.events,\n options = scope.options,\n input = element.find('input'),\n validationOptions = ['minTags', 'maxTags', 'allowLeftoverText'],\n setElementValidity;\n\n setElementValidity = function() {\n ngModelCtrl.$setValidity('maxTags', scope.tags.length <= options.maxTags);\n ngModelCtrl.$setValidity('minTags', scope.tags.length >= options.minTags);\n ngModelCtrl.$setValidity('leftoverText', scope.hasFocus || options.allowLeftoverText ? true : !scope.newTag.text);\n };\n\n ngModelCtrl.$isEmpty = function(value) {\n return !value || !value.length;\n };\n\n scope.newTag = {\n text: '',\n invalid: null,\n setText: function(value) {\n this.text = value;\n events.trigger('input-change', value);\n }\n };\n\n scope.track = function(tag) {\n return tag[options.keyProperty || options.displayProperty];\n };\n\n scope.$watch('tags', function(value) {\n scope.tags = tiUtil.makeObjectArray(value, options.displayProperty);\n tagList.items = scope.tags;\n });\n\n scope.$watch('tags.length', function() {\n setElementValidity();\n });\n\n attrs.$observe('disabled', function(value) {\n scope.disabled = value;\n });\n\n scope.eventHandlers = {\n input: {\n change: function(text) {\n events.trigger('input-change', text);\n },\n keydown: function($event) {\n events.trigger('input-keydown', $event);\n },\n focus: function() {\n if (scope.hasFocus) {\n return;\n }\n\n scope.hasFocus = true;\n events.trigger('input-focus');\n },\n blur: function() {\n $timeout(function() {\n var activeElement = $document.prop('activeElement'),\n lostFocusToBrowserWindow = activeElement === input[0],\n lostFocusToChildElement = element[0].contains(activeElement);\n\n if (lostFocusToBrowserWindow || !lostFocusToChildElement) {\n scope.hasFocus = false;\n events.trigger('input-blur');\n }\n });\n },\n paste: function($event) {\n $event.getTextData = function() {\n var clipboardData = $event.clipboardData || ($event.originalEvent && $event.originalEvent.clipboardData);\n return clipboardData ? clipboardData.getData('text/plain') : $window.clipboardData.getData('Text');\n };\n events.trigger('input-paste', $event);\n }\n },\n host: {\n click: function() {\n if (scope.disabled) {\n return;\n }\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n }\n }\n };\n\n events\n .on('tag-added', scope.onTagAdded)\n .on('invalid-tag', scope.onInvalidTag)\n .on('tag-removed', scope.onTagRemoved)\n .on('tag-added', function() {\n scope.newTag.setText('');\n })\n .on('tag-added tag-removed', function() {\n // Sets the element to its dirty state\n // In Angular 1.3 this will be replaced with $setDirty.\n ngModelCtrl.$setViewValue(scope.tags);\n })\n .on('invalid-tag', function() {\n scope.newTag.invalid = true;\n })\n .on('option-change', function(e) {\n if (validationOptions.indexOf(e.name) !== -1) {\n setElementValidity();\n }\n })\n .on('input-change', function() {\n tagList.clearSelection();\n scope.newTag.invalid = null;\n })\n .on('input-focus', function() {\n element.triggerHandler('focus');\n ngModelCtrl.$setValidity('leftoverText', true);\n })\n .on('input-blur', function() {\n if (options.addOnBlur && !options.addFromAutocompleteOnly) {\n tagList.addText(scope.newTag.text);\n }\n element.triggerHandler('blur');\n setElementValidity();\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n isModifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey,\n addKeys = {},\n shouldAdd, shouldRemove, shouldSelect, shouldEditLastTag;\n\n if (isModifier || hotkeys.indexOf(key) === -1) {\n return;\n }\n\n addKeys[KEYS.enter] = options.addOnEnter;\n addKeys[KEYS.comma] = options.addOnComma;\n addKeys[KEYS.space] = options.addOnSpace;\n\n shouldAdd = !options.addFromAutocompleteOnly && addKeys[key];\n shouldRemove = (key === KEYS.backspace || key === KEYS.delete) && tagList.selected;\n shouldEditLastTag = key === KEYS.backspace && scope.newTag.text.length === 0 && options.enableEditingLastTag;\n shouldSelect = (key === KEYS.backspace || key === KEYS.left || key === KEYS.right) && scope.newTag.text.length === 0 && !options.enableEditingLastTag;\n\n if (shouldAdd) {\n tagList.addText(scope.newTag.text);\n }\n else if (shouldEditLastTag) {\n var tag;\n\n tagList.selectPrior();\n tag = tagList.removeSelected();\n\n if (tag) {\n scope.newTag.setText(tag[options.displayProperty]);\n }\n }\n else if (shouldRemove) {\n tagList.removeSelected();\n }\n else if (shouldSelect) {\n if (key === KEYS.left || key === KEYS.backspace) {\n tagList.selectPrior();\n }\n else if (key === KEYS.right) {\n tagList.selectNext();\n }\n }\n\n if (shouldAdd || shouldSelect || shouldRemove || shouldEditLastTag) {\n event.preventDefault();\n }\n })\n .on('input-paste', function(event) {\n if (options.addOnPaste) {\n var data = event.getTextData();\n var tags = data.split(options.pasteSplitPattern);\n\n if (tags.length > 1) {\n tags.forEach(function(tag) {\n tagList.addText(tag);\n });\n event.preventDefault();\n }\n }\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTagItem\n * @module ngTagsInput\n *\n * @description\n * Represents a tag item. Used internally by the tagsInput directive.\n */\ntagsInput.directive('tiTagItem', [\"tiUtil\", function(tiUtil) {\n return {\n restrict: 'E',\n require: '^tagsInput',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, tagsInputCtrl) {\n var tagsInput = tagsInputCtrl.registerTagItem(),\n options = tagsInput.getOptions();\n\n scope.$$template = options.template;\n scope.$$removeTagSymbol = options.removeTagSymbol;\n\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty]);\n };\n scope.$removeTag = function() {\n tagsInput.removeTag(scope.$index);\n };\n\n scope.$watch('$parent.$index', function(value) {\n scope.$index = value;\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name autoComplete\n * @module ngTagsInput\n *\n * @description\n * Provides autocomplete support for the tagsInput directive.\n *\n * @param {expression} source Expression to evaluate upon changing the input content. The input value is available as\n * $query. The result of the expression must be a promise that eventually resolves to an\n * array of strings.\n * @param {string=} [displayProperty=text] Property to be rendered as the autocomplete label.\n * @param {number=} [debounceDelay=100] Amount of time, in milliseconds, to wait before evaluating the expression in\n * the source option after the last keystroke.\n * @param {number=} [minLength=3] Minimum number of characters that must be entered before evaluating the expression\n * in the source option.\n * @param {boolean=} [highlightMatchedText=true] Flag indicating that the matched text will be highlighted in the\n * suggestions list.\n * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time.\n * @param {boolean=} [loadOnDownArrow=false] Flag indicating that the source option will be evaluated when the down arrow\n * key is pressed and the suggestion list is closed. The current input value\n * is available as $query.\n * @param {boolean=} {loadOnEmpty=false} Flag indicating that the source option will be evaluated when the input content\n * becomes empty. The $query variable will be passed to the expression as an empty string.\n * @param {boolean=} {loadOnFocus=false} Flag indicating that the source option will be evaluated when the input element\n * gains focus. The current input value is available as $query.\n * @param {boolean=} [selectFirstMatch=true] Flag indicating that the first match will be automatically selected once\n * the suggestion list is shown.\n * @param {string=} [template=] URL or id of a custom template for rendering each element of the autocomplete list.\n */\ntagsInput.directive('autoComplete', [\"$document\",\"$timeout\",\"$sce\",\"$q\",\"tagsInputConfig\",\"tiUtil\", function($document, $timeout, $sce, $q, tagsInputConfig, tiUtil) {\n function SuggestionList(loadFn, options, events) {\n var self = {}, getDifference, lastPromise, getTagId;\n\n getTagId = function() {\n return options.tagsInput.keyProperty || options.tagsInput.displayProperty;\n };\n\n getDifference = function(array1, array2) {\n return array1.filter(function(item) {\n return !tiUtil.findInObjectArray(array2, item, getTagId(), function(a, b) {\n if (options.tagsInput.replaceSpacesWithDashes) {\n a = tiUtil.replaceSpacesWithDashes(a);\n b = tiUtil.replaceSpacesWithDashes(b);\n }\n return tiUtil.defaultComparer(a, b);\n });\n });\n };\n\n self.reset = function() {\n lastPromise = null;\n\n self.items = [];\n self.visible = false;\n self.index = -1;\n self.selected = null;\n self.query = null;\n };\n self.show = function() {\n if (options.selectFirstMatch) {\n self.select(0);\n }\n else {\n self.selected = null;\n }\n self.visible = true;\n };\n self.load = tiUtil.debounce(function(query, tags) {\n self.query = query;\n\n var promise = $q.when(loadFn({ $query: query }));\n lastPromise = promise;\n\n promise.then(function(items) {\n if (promise !== lastPromise) {\n return;\n }\n\n items = tiUtil.makeObjectArray(items.data || items, getTagId());\n items = getDifference(items, tags);\n self.items = items.slice(0, options.maxResultsToShow);\n\n if (self.items.length > 0) {\n self.show();\n }\n else {\n self.reset();\n }\n });\n }, options.debounceDelay);\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n self.selectPrior = function() {\n self.select(--self.index);\n };\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n self.index = index;\n self.selected = self.items[index];\n events.trigger('suggestion-selected', index);\n };\n\n self.reset();\n\n return self;\n }\n\n function scrollToElement(root, index) {\n var element = root.find('li').eq(index),\n parent = element.parent(),\n elementTop = element.prop('offsetTop'),\n elementHeight = element.prop('offsetHeight'),\n parentHeight = parent.prop('clientHeight'),\n parentScrollTop = parent.prop('scrollTop');\n\n if (elementTop < parentScrollTop) {\n parent.prop('scrollTop', elementTop);\n }\n else if (elementTop + elementHeight > parentHeight + parentScrollTop) {\n parent.prop('scrollTop', elementTop + elementHeight - parentHeight);\n }\n }\n\n return {\n restrict: 'E',\n require: '^tagsInput',\n scope: { source: '&' },\n templateUrl: 'ngTagsInput/auto-complete.html',\n controller: [\"$scope\",\"$element\",\"$attrs\", function($scope, $element, $attrs) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('autoComplete', $scope, $attrs, {\n template: [String, 'ngTagsInput/auto-complete-match.html'],\n debounceDelay: [Number, 100],\n minLength: [Number, 3],\n highlightMatchedText: [Boolean, true],\n maxResultsToShow: [Number, 10],\n loadOnDownArrow: [Boolean, false],\n loadOnEmpty: [Boolean, false],\n loadOnFocus: [Boolean, false],\n selectFirstMatch: [Boolean, true],\n displayProperty: [String, '']\n });\n\n $scope.suggestionList = new SuggestionList($scope.source, $scope.options, $scope.events);\n\n this.registerAutocompleteMatch = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n getQuery: function() {\n return $scope.suggestionList.query;\n }\n };\n };\n }],\n link: function(scope, element, attrs, tagsInputCtrl) {\n var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],\n suggestionList = scope.suggestionList,\n tagsInput = tagsInputCtrl.registerAutocomplete(),\n options = scope.options,\n events = scope.events,\n shouldLoadSuggestions;\n\n options.tagsInput = tagsInput.getOptions();\n\n shouldLoadSuggestions = function(value) {\n return value && value.length >= options.minLength || !value && options.loadOnEmpty;\n };\n\n scope.addSuggestionByIndex = function(index) {\n suggestionList.select(index);\n scope.addSuggestion();\n };\n\n scope.addSuggestion = function() {\n var added = false;\n\n if (suggestionList.selected) {\n tagsInput.addTag(angular.copy(suggestionList.selected));\n suggestionList.reset();\n tagsInput.focusInput();\n\n added = true;\n }\n return added;\n };\n\n scope.track = function(item) {\n return item[options.tagsInput.keyProperty || options.tagsInput.displayProperty];\n };\n\n tagsInput\n .on('tag-added invalid-tag input-blur', function() {\n suggestionList.reset();\n })\n .on('input-change', function(value) {\n if (shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n else {\n suggestionList.reset();\n }\n })\n .on('input-focus', function() {\n var value = tagsInput.getCurrentTagText();\n if (options.loadOnFocus && shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n handled = false;\n\n if (hotkeys.indexOf(key) === -1) {\n return;\n }\n\n if (suggestionList.visible) {\n\n if (key === KEYS.down) {\n suggestionList.selectNext();\n handled = true;\n }\n else if (key === KEYS.up) {\n suggestionList.selectPrior();\n handled = true;\n }\n else if (key === KEYS.escape) {\n suggestionList.reset();\n handled = true;\n }\n else if (key === KEYS.enter || key === KEYS.tab) {\n handled = scope.addSuggestion();\n }\n }\n else {\n if (key === KEYS.down && scope.options.loadOnDownArrow) {\n suggestionList.load(tagsInput.getCurrentTagText(), tagsInput.getTags());\n handled = true;\n }\n }\n\n if (handled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return false;\n }\n });\n\n events.on('suggestion-selected', function(index) {\n scrollToElement(element, index);\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiAutocompleteMatch\n * @module ngTagsInput\n *\n * @description\n * Represents an autocomplete match. Used internally by the autoComplete directive.\n */\ntagsInput.directive('tiAutocompleteMatch', [\"$sce\",\"tiUtil\", function($sce, tiUtil) {\n return {\n restrict: 'E',\n require: '^autoComplete',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, autoCompleteCtrl) {\n var autoComplete = autoCompleteCtrl.registerAutocompleteMatch(),\n options = autoComplete.getOptions();\n\n scope.$$template = options.template;\n scope.$index = scope.$parent.$index;\n\n scope.$highlight = function(text) {\n if (options.highlightMatchedText) {\n text = tiUtil.safeHighlight(text, autoComplete.getQuery());\n }\n return $sce.trustAsHtml(text);\n };\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty || options.tagsInput.displayProperty]);\n };\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTranscludeAppend\n * @module ngTagsInput\n *\n * @description\n * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiTranscludeAppend', function() {\n return function(scope, element, attrs, ctrl, transcludeFn) {\n transcludeFn(function(clone) {\n element.append(clone);\n });\n };\n});\n\n/**\n * @ngdoc directive\n * @name tiAutosize\n * @module ngTagsInput\n *\n * @description\n * Automatically sets the input's width so its content is always visible. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiAutosize', [\"tagsInputConfig\", function(tagsInputConfig) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function(scope, element, attrs, ctrl) {\n var threshold = tagsInputConfig.getTextAutosizeThreshold(),\n span, resize;\n\n span = angular.element('<span class=\"input\"></span>');\n span.css('display', 'none')\n .css('visibility', 'hidden')\n .css('width', 'auto')\n .css('white-space', 'pre');\n\n element.parent().append(span);\n\n resize = function(originalValue) {\n var value = originalValue, width;\n\n if (angular.isString(value) && value.length === 0) {\n value = attrs.placeholder;\n }\n\n if (value) {\n span.text(value);\n span.css('display', '');\n width = span.prop('offsetWidth');\n span.css('display', 'none');\n }\n\n element.css('width', width ? width + threshold + 'px' : '');\n\n return originalValue;\n };\n\n ctrl.$parsers.unshift(resize);\n ctrl.$formatters.unshift(resize);\n\n attrs.$observe('placeholder', function(value) {\n if (!ctrl.$modelValue) {\n resize(value);\n }\n });\n }\n };\n}]);\n\n/**\n * @ngdoc directive\n * @name tiBindAttrs\n * @module ngTagsInput\n *\n * @description\n * Binds attributes to expressions. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiBindAttrs', function() {\n return function(scope, element, attrs) {\n scope.$watch(attrs.tiBindAttrs, function(value) {\n angular.forEach(value, function(value, key) {\n /**\n * blake_r - Added to work around the version of jQuery that\n * MAAS currently ships with. Once packaging for jQuery is\n * version >1.9 this can be removed.\n */\n if(key === \"type\") {\n element[0].type = value;\n } else {\n attrs.$set(key, value);\n }\n });\n }, true);\n };\n});\n\n/**\n * @ngdoc service\n * @name tagsInputConfig\n * @module ngTagsInput\n *\n * @description\n * Sets global configuration settings for both tagsInput and autoComplete directives. It's also used internally to parse and\n * initialize options from HTML attributes.\n */\ntagsInput.provider('tagsInputConfig', function() {\n var globalDefaults = {},\n interpolationStatus = {},\n autosizeThreshold = 3;\n\n /**\n * @ngdoc method\n * @name setDefaults\n * @description Sets the default configuration option for a directive.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} defaults Object containing options and their values.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setDefaults = function(directive, defaults) {\n globalDefaults[directive] = defaults;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setActiveInterpolation\n * @description Sets active interpolation for a set of options.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} options Object containing which options should have interpolation turned on at all times.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setActiveInterpolation = function(directive, options) {\n interpolationStatus[directive] = options;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setTextAutosizeThreshold\n * @description Sets the threshold used by the tagsInput directive to re-size the inner input field element based on its contents.\n * @methodOf tagsInputConfig\n *\n * @param {number} threshold Threshold value, in pixels.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setTextAutosizeThreshold = function(threshold) {\n autosizeThreshold = threshold;\n return this;\n };\n\n this.$get = [\"$interpolate\", function($interpolate) {\n var converters = {};\n converters[String] = function(value) { return value; };\n converters[Number] = function(value) { return parseInt(value, 10); };\n converters[Boolean] = function(value) { return value.toLowerCase() === 'true'; };\n converters[RegExp] = function(value) { return new RegExp(value); };\n\n return {\n load: function(directive, scope, attrs, options) {\n var defaultValidator = function() { return true; };\n\n scope.options = {};\n\n angular.forEach(options, function(value, key) {\n var type, localDefault, validator, converter, getDefault, updateValue;\n\n type = value[0];\n localDefault = value[1];\n validator = value[2] || defaultValidator;\n converter = converters[type];\n\n getDefault = function() {\n var globalValue = globalDefaults[directive] && globalDefaults[directive][key];\n return angular.isDefined(globalValue) ? globalValue : localDefault;\n };\n\n updateValue = function(value) {\n scope.options[key] = value && validator(value) ? converter(value) : getDefault();\n };\n\n if (interpolationStatus[directive] && interpolationStatus[directive][key]) {\n attrs.$observe(key, function(value) {\n updateValue(value);\n scope.events.trigger('option-change', { name: key, newValue: value });\n });\n }\n else {\n updateValue(attrs[key] && $interpolate(attrs[key])(scope.$parent));\n }\n });\n },\n getTextAutosizeThreshold: function() {\n return autosizeThreshold;\n }\n };\n }];\n});\n\n\n/***\n * @ngdoc factory\n * @name tiUtil\n * @module ngTagsInput\n *\n * @description\n * Helper methods used internally by the directive. Should not be called directly from user code.\n */\ntagsInput.factory('tiUtil', [\"$timeout\", function($timeout) {\n var self = {};\n\n self.debounce = function(fn, delay) {\n var timeoutId;\n return function() {\n var args = arguments;\n $timeout.cancel(timeoutId);\n timeoutId = $timeout(function() { fn.apply(null, args); }, delay);\n };\n };\n\n self.makeObjectArray = function(array, key) {\n array = array || [];\n if (array.length > 0 && !angular.isObject(array[0])) {\n array.forEach(function(item, index) {\n array[index] = {};\n array[index][key] = item;\n });\n }\n return array;\n };\n\n self.findInObjectArray = function(array, obj, key, comparer) {\n var item = null;\n comparer = comparer || self.defaultComparer;\n\n array.some(function(element) {\n if (comparer(element[key], obj[key])) {\n item = element;\n return true;\n }\n });\n\n return item;\n };\n\n self.defaultComparer = function(a, b) {\n // I'm aware of the internationalization issues regarding toLowerCase()\n // but I couldn't come up with a better solution right now\n return self.safeToString(a).toLowerCase() === self.safeToString(b).toLowerCase();\n };\n\n self.safeHighlight = function(str, value) {\n if (!value) {\n return str;\n }\n\n function escapeRegexChars(str) {\n return str.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n }\n\n str = self.encodeHTML(str);\n value = self.encodeHTML(value);\n\n var expression = new RegExp('&[^;]+;|' + escapeRegexChars(value), 'gi');\n return str.replace(expression, function(match) {\n return match.toLowerCase() === value.toLowerCase() ? '<em>' + match + '</em>' : match;\n });\n };\n\n self.safeToString = function(value) {\n return angular.isUndefined(value) || value == null ? '' : value.toString().trim();\n };\n\n self.encodeHTML = function(value) {\n return self.safeToString(value)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n };\n\n self.handleUndefinedResult = function(fn, valueIfUndefined) {\n return function() {\n var result = fn.apply(null, arguments);\n return angular.isUndefined(result) ? valueIfUndefined : result;\n };\n };\n\n self.replaceSpacesWithDashes = function(str) {\n return self.safeToString(str).replace(/\\s/g, '-');\n };\n\n self.simplePubSub = function() {\n var events = {};\n return {\n on: function(names, handler) {\n names.split(' ').forEach(function(name) {\n if (!events[name]) {\n events[name] = [];\n }\n events[name].push(handler);\n });\n return this;\n },\n trigger: function(name, args) {\n var handlers = events[name] || [];\n handlers.every(function(handler) {\n return self.handleUndefinedResult(handler, true)(args);\n });\n return this;\n }\n };\n };\n\n return self;\n}]);\n\n/* HTML templates */\ntagsInput.run([\"$templateCache\", function($templateCache) {\n $templateCache.put('ngTagsInput/tags-input.html',\n \"<div class=\\\"host\\\" tabindex=\\\"-1\\\" data-ng-click=\\\"eventHandlers.host.click()\\\" ti-transclude-append=\\\"\\\"><div class=\\\"tags\\\" data-ng-class=\\\"{focused: hasFocus}\\\"><ul class=\\\"tag-list\\\"><li class=\\\"tag-item\\\" data-ng-repeat=\\\"tag in tagList.items track by track(tag)\\\" data-ng-class=\\\"{ selected: tag == tagList.selected }\\\"><ti-tag-item data=\\\"tag\\\"></ti-tag-item></li></ul><input class=\\\"input u-no-margin--top\\\" autocomplete=\\\"off\\\" data-ng-model=\\\"newTag.text\\\" data-ng-change=\\\"eventHandlers.input.change(newTag.text)\\\" data-ng-keydown=\\\"eventHandlers.input.keydown($event)\\\" data-ng-focus=\\\"eventHandlers.input.focus($event)\\\" data-ng-blur=\\\"eventHandlers.input.blur($event)\\\" data-ng-paste=\\\"eventHandlers.input.paste($event)\\\" data-ng-trim=\\\"false\\\" data-ng-class=\\\"{'invalid-tag': newTag.invalid}\\\" data-ng-disabled=\\\"disabled\\\" ti-bind-attrs=\\\"{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}\\\" ti-autosize=\\\"\\\"></div></div>\"\n );\n\n $templateCache.put('ngTagsInput/tag-item.html',\n \"<span ng-bind=\\\"$getDisplayText()\\\"></span> <a class=\\\"p-icon--close\\\" data-ng-click=\\\"$removeTag()\\\" data-ng-bind=\\\"$$removeTagSymbol\\\">Remove tag</a>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete.html',\n \"<div class=\\\"autocomplete\\\" data-ng-if=\\\"suggestionList.visible\\\"><ul class=\\\"p-list suggestion-list\\\"><li class=\\\"suggestion-item\\\" data-ng-repeat=\\\"item in suggestionList.items track by track(item)\\\" data-ng-class=\\\"{selected: item == suggestionList.selected}\\\" data-ng-click=\\\"addSuggestionByIndex($index)\\\" data-ng-mouseenter=\\\"suggestionList.select($index)\\\"><ti-autocomplete-match data=\\\"item\\\"></ti-autocomplete-match></li></ul></div>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete-match.html',\n \"<span data-ng-bind-html=\\\"$highlight($getDisplayText())\\\"></span>\"\n );\n}]);\n\n}());\n","/*!\n * Angular Virtual Scroll Repeat v2.0.9\n * https://github.com/kamilkp/angular-vs-repeat/\n *\n * Copyright Kamil Pękala\n * http://github.com/kamilkp\n *\n * Released under the MIT License\n * https://opensource.org/licenses/MIT\n *\n * Date: 2018/04/02\n */\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }\n\n/* global console, setTimeout, module */\n(function (window, angular) {\n /**\n * DESCRIPTION:\n * vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container\n * into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of\n * pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.\n * The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.\n * LIMITATIONS:\n * - current version only supports an Array as a right-hand-side object for ngRepeat\n * - all rendered elements must have the same height/width or the sizes of the elements must be known up front\n * USAGE:\n * In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat\n * example:\n * <div vs-repeat=\"options\">\n * <div ng-repeat=\"item in someArray\">\n * <!-- content -->\n * </div>\n * </div>\n * or:\n * <div vs-repeat=\"options\">\n * <div ng-repeat-start=\"item in someArray\">\n * <!-- content -->\n * </div>\n * <div>\n * <!-- something in the middle -->\n * </div>\n * <div ng-repeat-end>\n * <!-- content -->\n * </div>\n * </div>\n * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value\n * of the option's `size` property. This can be used if one wants to override the automatically computed element size.\n * example:\n * <div vs-repeat=\"{size: 50}\"> <!-- the specified element height is 50px -->\n * <div ng-repeat=\"item in someArray\">\n * <!-- content -->\n * </div>\n * </div>\n * IMPORTANT!\n * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat\n * - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive\n * will compute it automatically\n * OPTIONAL PARAMETERS (attributes):\n * vs-repeat-container=\"selector\" - selector for element containing ng-repeat. (defaults to the current element)\n * OPTIONS:\n * Options shall be passed as an object to the `vs-repeat` attribute e.g.: `<div vs-repeat=\"{scrollParent: 'window', size: 20}\"></div>`\n *\n * Available options:\n * `horizontal` - stack repeated elements horizontally instead of vertically\n * `offset-before` - top/left offset in pixels (defaults to 0)\n * `offset-after` - bottom/right offset in pixels (defaults to 0)\n * `scroll-margin` - how many pixels ahead should elements be rendered while scrolling\n * `latch` - if true, elements will be rendered gradually but won't be removed when scrolled away (defaults to false)\n * `size` - a property name of the items in collection that is a number denoting the element size (in pixels)\n * `autoresize` - use this attribute without vs-size and without specifying element's size. The automatically computed element style will\n * readjust upon window resize if the size is dependable on the viewport size\n * `scrolled-to-end` - callback will be called when the last item of the list is rendered\n * `scrolled-to-end-offset` - set this number to trigger the scrolledToEnd callback n items before the last gets rendered\n * `scrolled-to-beginning` - callback will be called when the first item of the list is rendered\n * `scrolled-to-beginning-offset` - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered\n * EVENTS:\n * - `vsRepeatTrigger` - an event the directive listens for to manually trigger reinitialization\n * - `vsRepeatReinitialized` - an event the directive emits upon reinitialization done\n */\n var closestElement = angular.element.prototype.closest;\n\n if (!closestElement) {\n var matchingFunction = ['matches', 'matchesSelector', 'webkitMatches', 'webkitMatchesSelector', 'msMatches', 'msMatchesSelector', 'mozMatches', 'mozMatchesSelector'].reduce(function (res, prop) {\n var _res;\n\n return (_res = res) !== null && _res !== void 0 ? _res : prop in document.documentElement ? prop : null;\n }, null);\n\n closestElement = function closestElement(selector) {\n var _el;\n\n var el = this[0].parentNode;\n\n while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {\n el = el.parentNode;\n }\n\n if ((_el = el) === null || _el === void 0 ? void 0 : _el[matchingFunction](selector)) {\n return angular.element(el);\n }\n\n return angular.element();\n };\n }\n\n function getWindowScroll() {\n var _ref, _document$documentEle, _ref2, _document$documentEle2;\n\n if ('pageYOffset' in window) {\n return {\n scrollTop: window.pageYOffset,\n scrollLeft: window.pageXOffset\n };\n }\n\n return {\n scrollTop: (_ref = (_document$documentEle = document.documentElement.scrollTop) !== null && _document$documentEle !== void 0 ? _document$documentEle : document.body.scrollTop) !== null && _ref !== void 0 ? _ref : 0,\n scrollLeft: (_ref2 = (_document$documentEle2 = document.documentElement.scrollLeft) !== null && _document$documentEle2 !== void 0 ? _document$documentEle2 : document.body.scrollLeft) !== null && _ref2 !== void 0 ? _ref2 : 0\n };\n }\n\n function getClientSize(element, sizeProp) {\n if (element === window) {\n return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;\n }\n\n return element[sizeProp];\n }\n\n function getScrollPos(element, scrollProp) {\n return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];\n }\n\n function getScrollOffset(vsElement, scrollElement, isHorizontal) {\n var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollValue = (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];\n return vsPos - scrollPos + scrollValue;\n }\n\n function analyzeNgRepeatUsage(element) {\n var options = ['ng-repeat', 'data-ng-repeat', 'ng-repeat-start', 'data-ng-repeat-start'];\n\n for (var _i = 0; _i < options.length; _i++) {\n var opt = options[_i];\n\n if (element.attr(opt)) {\n return [opt, element.attr(opt), opt.indexOf('-start') >= 0];\n }\n }\n\n throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');\n }\n\n function printDeprecationWarning($element, message) {\n console.warn(\"vs-repeat deprecation: \".concat(message), $element[0]);\n }\n\n function attrDeprecated(attrname, $element) {\n printDeprecationWarning($element, \"\".concat(attrname, \" attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options\"));\n }\n\n var defaultOptions = {\n latch: false,\n container: null,\n scrollParent: null,\n size: null,\n offsetBefore: 0,\n offsetAfter: 0,\n scrolledToBeginning: angular.noop,\n scrolledToEnd: angular.noop,\n scrolledToBeginningOffset: 0,\n scrolledToEndOffset: 0,\n scrollMargin: 0,\n horizontal: false,\n autoresize: false,\n hunked: false,\n hunkSize: 0\n };\n var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function ($compile, $parse) {\n return {\n restrict: 'A',\n scope: true,\n compile: function compile(compileElement, compileAttrs) {\n var compileRepeatContainer = 'vsRepeatContainer' in compileAttrs ? angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)) : compileElement;\n var repeatContainerChildren = compileRepeatContainer.children();\n var ngRepeatChild = repeatContainerChildren.eq(0);\n var childCloneHtml = ngRepeatChild[0].outerHTML;\n var collectionName = '$vs_collection'; // TODO: make configurable?\n\n ['vsSize', 'vsScrollParent', 'vsSizeProperty', 'vsHorizontal', 'vsOffsetBefore', 'vsOffsetAfter', 'vsScrolledToEndOffset', 'vsScrolledToBeginningOffset', 'vsExcess', 'vsScrollMargin'].forEach(function (attrname) {\n if (attrname in compileAttrs) {\n attrDeprecated(attrname, compileElement);\n }\n });\n\n var _analyzeNgRepeatUsage = analyzeNgRepeatUsage(ngRepeatChild),\n _analyzeNgRepeatUsage2 = _slicedToArray(_analyzeNgRepeatUsage, 3),\n originalNgRepeatAttr = _analyzeNgRepeatUsage2[0],\n ngRepeatExpression = _analyzeNgRepeatUsage2[1],\n isNgRepeatStart = _analyzeNgRepeatUsage2[2];\n\n var expressionMatches = /^\\s*(\\S+)\\s+in\\s+([\\S\\s]+?)(track\\s+by\\s+\\S+)?$/.exec(ngRepeatExpression);\n\n var _expressionMatches = _slicedToArray(expressionMatches, 4),\n lhs = _expressionMatches[1],\n rhs = _expressionMatches[2],\n rhsSuffix = _expressionMatches[3];\n\n if (isNgRepeatStart) {\n var index = 0;\n var repeaterElement = repeatContainerChildren.eq(index);\n\n while (repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {\n index++;\n repeaterElement = repeatContainerChildren.eq(index);\n childCloneHtml += repeaterElement[0].outerHTML;\n }\n }\n\n compileRepeatContainer.empty();\n return {\n pre: function pre($scope, $element, $attrs) {\n var _$scope$$eval;\n\n function _parseSize(options) {\n if (typeof options.size === 'number') {\n options.getSize = function () {\n return options.size;\n };\n } else {\n var parsed = $parse(String(options.size));\n\n options.getSize = function (item) {\n return parsed($scope, _defineProperty({}, lhs, item));\n };\n }\n }\n\n $scope.vsRepeat = {\n options: _extends({}, defaultOptions, (_$scope$$eval = $scope.$eval($attrs.vsRepeat)) !== null && _$scope$$eval !== void 0 ? _$scope$$eval : {})\n };\n var options = $scope.vsRepeat.options;\n\n _parseSize(options);\n\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element;\n var childClone = angular.element(childCloneHtml);\n var childTagName = childClone[0].tagName.toLowerCase();\n var originalCollection = [];\n var originalLength;\n var $beforeContent = angular.element('<' + childTagName + ' class=\"vs-repeat-before-content\"></' + childTagName + '>');\n var $afterContent = angular.element('<' + childTagName + ' class=\"vs-repeat-after-content\"></' + childTagName + '>');\n var autosizingRequired = options.size === null;\n var $scrollParent = options.scrollParent ? options.scrollParent === 'window' ? angular.element(window) : closestElement.call(repeatContainer, options.scrollParent) : repeatContainer;\n var clientSize = options.horizontal ? 'clientWidth' : 'clientHeight';\n var offsetSize = options.horizontal ? 'offsetWidth' : 'offsetHeight';\n var scrollSize = options.horizontal ? 'scrollWidth' : 'scrollHeight';\n var scrollPos = options.horizontal ? 'scrollLeft' : 'scrollTop';\n $scope.vsRepeat.totalSize = 0;\n\n if ($scrollParent.length === 0) {\n throw 'Specified scroll parent selector did not match any element';\n }\n\n $scope.vsRepeat.$scrollParent = $scrollParent;\n $scope.vsRepeat.sizesCumulative = [];\n\n if (options.debug) {\n var $debugParent = options.scrollParent === 'window' ? angular.element(document.body) : $scrollParent;\n var $debug = angular.element('<div class=\"vs-repeat-debug-element\"></div>');\n $debug.css('position', options.scrollParent === 'window' ? 'fixed' : 'absolute');\n $debugParent.append($debug);\n $scope.$on('$destroy', function () {\n $debug.remove();\n });\n }\n\n var measuredSize = getClientSize($scrollParent[0], clientSize) || 50;\n\n if (options.horizontal) {\n $beforeContent.css('height', '100%');\n $afterContent.css('height', '100%');\n } else {\n $beforeContent.css('width', '100%');\n $afterContent.css('width', '100%');\n }\n\n if ($attrs.vsRepeatOptions) {\n $scope.$watchCollection($attrs.vsRepeatOptions, function (newOpts) {\n var mergedOptions = _extends({}, options, newOpts);\n\n if (JSON.stringify(mergedOptions) !== JSON.stringify(options)) {\n Object.assign(options, newOpts);\n\n _parseSize(options);\n\n reinitialize();\n }\n });\n }\n\n $scope.$watchCollection(rhs, function () {\n var coll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n originalCollection = coll;\n refresh();\n });\n\n function refresh() {\n if (!originalCollection || originalCollection.length < 1) {\n $scope[collectionName] = [];\n originalLength = 0;\n $scope.vsRepeat.sizesCumulative = [0];\n } else {\n originalLength = originalCollection.length;\n\n if (options.size) {\n _mapSize();\n } else {\n getFromMeasured();\n }\n }\n\n reinitialize();\n }\n\n function _mapSize() {\n var hardSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n var sizes = originalCollection.map(function (item) {\n var _hardSize;\n\n return (_hardSize = hardSize) !== null && _hardSize !== void 0 ? _hardSize : options.getSize(item);\n });\n var sum = 0;\n $scope.vsRepeat.sizesCumulative = [0].concat(_toConsumableArray(sizes.map(function (size) {\n return sum += size;\n })));\n }\n\n function getFromMeasured() {\n if (autosizingRequired) {\n $scope.$$postDigest(function () {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n // element is visible\n var children = repeatContainer.children();\n var i = 0;\n var gotSomething = false;\n var insideStartEndSequence = false;\n\n while (i < children.length) {\n if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {\n if (!gotSomething) {\n measuredSize = 0;\n }\n\n gotSomething = true;\n\n if (children[i][offsetSize]) {\n measuredSize += children[i][offsetSize];\n }\n\n if (isNgRepeatStart) {\n if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {\n break;\n } else {\n insideStartEndSequence = true;\n }\n } else {\n break;\n }\n }\n\n i++;\n }\n\n if (gotSomething) {\n _mapSize(measuredSize);\n\n reinitialize();\n autosizingRequired = false;\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n } else {\n var dereg = $scope.$watch(function () {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n dereg();\n getFromMeasured();\n }\n });\n }\n });\n } else {\n _mapSize(measuredSize);\n }\n }\n\n function getLayoutProps(value) {\n var layoutProp = options.horizontal ? 'width' : 'height';\n return ['', 'min-', 'max-'].reduce(function (acc, prop) {\n return acc[\"\".concat(prop).concat(layoutProp)] = value, acc;\n }, {});\n }\n\n childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));\n childClone.addClass('vs-repeat-repeated-element');\n repeatContainer.append($beforeContent);\n repeatContainer.append(childClone);\n $compile(childClone)($scope);\n repeatContainer.append($afterContent);\n $scope.vsRepeat.startIndex = 0;\n $scope.vsRepeat.endIndex = 0;\n\n function scrollHandler() {\n var pos = $scrollParent[0][scrollPos];\n\n if (updateInnerCollection()) {\n $scope.$digest();\n\n if (options._ensureScrollIntegrity) {\n $scrollParent[0][scrollPos] = pos;\n }\n }\n }\n\n $scrollParent.on('scroll', scrollHandler);\n\n function onWindowResize() {\n if (options.autoresize) {\n autosizingRequired = true;\n getFromMeasured();\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n\n if (updateInnerCollection()) {\n $scope.$digest();\n }\n }\n\n angular.element(window).on('resize', onWindowResize);\n $scope.$on('$destroy', function () {\n angular.element(window).off('resize', onWindowResize);\n $scrollParent.off('scroll', scrollHandler);\n });\n $scope.$on('vsRepeatTrigger', refresh);\n $scope.$on('vsRepeatResize', function () {\n autosizingRequired = true;\n getFromMeasured();\n });\n\n var _prevStartIndex, _prevEndIndex, _minStartIndex, _maxEndIndex;\n\n $scope.$on('vsRenderAll', function () {\n if (!options.latch) {\n return;\n }\n\n if ($scope.vsRepeat.endIndex === originalLength) {\n $scope.$emit('vsRenderAllDone');\n return;\n }\n\n setTimeout(function () {\n // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength);\n var __endIndex = originalLength;\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex;\n $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);\n _prevEndIndex = $scope.vsRepeat.endIndex;\n $beforeContent.css(getLayoutProps(0));\n $afterContent.css(getLayoutProps(0));\n $scope.$emit('vsRenderAllDone');\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n });\n });\n\n function reinitialize() {\n _prevStartIndex = void 0;\n _prevEndIndex = void 0;\n _minStartIndex = originalLength;\n _maxEndIndex = 0;\n updateTotalSize($scope.vsRepeat.sizesCumulative[originalLength]);\n updateInnerCollection();\n $scope.$emit('vsRepeatReinitialized', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);\n }\n\n function updateTotalSize(size) {\n $scope.vsRepeat.totalSize = options.offsetBefore + size + options.offsetAfter;\n }\n\n var _prevClientSize;\n\n function reinitOnClientHeightChange() {\n var ch = getClientSize($scrollParent[0], clientSize);\n\n if (ch !== _prevClientSize) {\n reinitialize();\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n\n _prevClientSize = ch;\n }\n\n $scope.$watch(function () {\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(reinitOnClientHeightChange);\n } else {\n reinitOnClientHeightChange();\n }\n });\n\n function binaryFind(array, threshold) {\n var a = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;\n var b = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length - 1;\n var d = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;\n\n if (array[a] === threshold) {\n return [a, a, d];\n }\n\n if (array[b] === threshold) {\n return [b, b, d];\n }\n\n if (b - a > 1) {\n var m = Math.floor((a + b) / 2);\n\n if (array[m] > threshold) {\n return binaryFind(array, threshold, a, m, d + 1);\n }\n\n return binaryFind(array, threshold, m, b, d + 1);\n }\n\n return [threshold > array[b] ? b : a, threshold < array[a] ? a : b, d];\n }\n\n function updateInnerCollection() {\n var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);\n var $clientSize = getClientSize($scrollParent[0], clientSize);\n\n if (options.debug) {\n $clientSize /= 2;\n }\n\n var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(repeatContainer[0], $scrollParent[0], options.horizontal);\n var __startIndex = $scope.vsRepeat.startIndex;\n var __endIndex = $scope.vsRepeat.endIndex;\n\n if (autosizingRequired && !options.size) {\n __startIndex = 0;\n __endIndex = 1;\n } else {\n _warnMismatch();\n\n var relativeScroll = $scrollPosition - options.offsetBefore - scrollOffset;\n\n var _binaryFind = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll - options.scrollMargin);\n\n var _binaryFind2 = _slicedToArray(_binaryFind, 1);\n\n __startIndex = _binaryFind2[0];\n __startIndex = Math.max(__startIndex, 0);\n\n var _binaryFind3 = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll + options.scrollMargin + $clientSize, __startIndex);\n\n var _binaryFind4 = _slicedToArray(_binaryFind3, 2);\n\n __endIndex = _binaryFind4[1];\n __endIndex = Math.min(__endIndex, originalLength);\n }\n\n _minStartIndex = Math.min(__startIndex, _minStartIndex);\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.vsRepeat.startIndex = options.latch ? _minStartIndex : __startIndex;\n $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; // Move to the end of the collection if we are now past it\n\n if (_maxEndIndex < $scope.vsRepeat.startIndex) $scope.vsRepeat.startIndex = _maxEndIndex;\n var digestRequired = false;\n\n if (_prevStartIndex == null) {\n digestRequired = true;\n } else if (_prevEndIndex == null) {\n digestRequired = true;\n }\n\n if (!digestRequired) {\n if (options.hunked) {\n if (Math.abs($scope.vsRepeat.startIndex - _prevStartIndex) >= options.hunkSize || $scope.vsRepeat.startIndex === 0 && _prevStartIndex !== 0) {\n digestRequired = true;\n } else if (Math.abs($scope.vsRepeat.endIndex - _prevEndIndex) >= options.hunkSize || $scope.vsRepeat.endIndex === originalLength && _prevEndIndex !== originalLength) {\n digestRequired = true;\n }\n } else {\n digestRequired = $scope.vsRepeat.startIndex !== _prevStartIndex || $scope.vsRepeat.endIndex !== _prevEndIndex;\n }\n }\n\n if (digestRequired) {\n $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); // Emit the event\n\n $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex, _prevStartIndex, _prevEndIndex);\n var triggerIndex;\n\n if (options.scrolledToEnd) {\n triggerIndex = originalCollection.length - options.scrolledToEndOffset;\n\n if ($scope.vsRepeat.endIndex >= triggerIndex && _prevEndIndex < triggerIndex || originalCollection.length && $scope.vsRepeat.endIndex === originalCollection.length) {\n $scope.$eval(options.scrolledToEnd);\n }\n }\n\n if (options.scrolledToBeginning) {\n triggerIndex = options.scrolledToBeginningOffset;\n\n if ($scope.vsRepeat.startIndex <= triggerIndex && _prevStartIndex > $scope.vsRepeat.startIndex) {\n $scope.$eval(options.scrolledToBeginning);\n }\n }\n\n _prevStartIndex = $scope.vsRepeat.startIndex;\n _prevEndIndex = $scope.vsRepeat.endIndex;\n var o1 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex] + options.offsetBefore;\n var o2 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex + $scope[collectionName].length] + options.offsetBefore;\n var total = $scope.vsRepeat.totalSize;\n $beforeContent.css(getLayoutProps(o1 + 'px'));\n $afterContent.css(getLayoutProps(total - o2 + 'px'));\n }\n\n return digestRequired;\n }\n\n function _warnMismatch() {\n $scope.$$postDigest(function () {\n window.requestAnimationFrame(function () {\n var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength];\n var compStyle = window.getComputedStyle(repeatContainer[0]);\n var paddings = options.horizontal ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom'];\n var containerSize = repeatContainer[0][scrollSize] - paddings.reduce(function (acc, prop) {\n return acc + Number(compStyle[prop].slice(0, -2));\n }, 0);\n\n if (repeatContainer[0][scrollSize] && expectedSize !== containerSize) {\n console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + containerSize + 'px. Fix vsSize on element:', $element[0]);\n }\n });\n });\n }\n }\n };\n }\n };\n }]);\n angular.element(document.head).append(\"<style id=\\\"angular-vs-repeat-style\\\">\\n\\t \\t.vs-repeat-debug-element {\\n top: 50%;\\n left: 0;\\n right: 0;\\n height: 1px;\\n background: red;\\n z-index: 99999999;\\n box-shadow: 0 0 20px red;\\n }\\n\\n .vs-repeat-debug-element + .vs-repeat-debug-element {\\n display: none;\\n }\\n\\n .vs-repeat-before-content,\\n .vs-repeat-after-content {\\n border: none !important;\\n padding: 0 !important;\\n }\\n </style>\");\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = vsRepeatModule.name;\n }\n})(window, window.angular);"],"sourceRoot":""}
2\ No newline at end of file1\ No newline at end of file
2{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js","webpack:///./src/maasserver/static/js/angular/3rdparty/vs-repeat.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","KEYS","SUPPORTED_INPUT_TYPES","tagsInput","angular","directive","$timeout","$document","$window","tagsInputConfig","tiUtil","validateType","type","indexOf","restrict","require","scope","tags","onTagAdding","onTagAdded","onInvalidTag","onTagRemoving","onTagRemoved","replace","transclude","templateUrl","controller","$scope","$attrs","$element","events","simplePubSub","load","template","String","placeholder","tabindex","Number","removeTagSymbol","fromCharCode","replaceSpacesWithDashes","Boolean","minLength","maxLength","addOnEnter","addOnSpace","addOnComma","addOnBlur","addOnPaste","pasteSplitPattern","RegExp","allowedTagsPattern","enableEditingLastTag","minTags","maxTags","displayProperty","keyProperty","allowLeftoverText","addFromAutocompleteOnly","spellcheck","tagList","options","getTagText","setTagText","tagIsValid","self","tag","safeToString","text","tagText","length","test","findInObjectArray","items","$tag","addText","add","push","trigger","remove","index","splice","clearSelection","select","selected","selectPrior","selectNext","removeSelected","handleUndefinedResult","this","registerAutocomplete","find","addTag","focusInput","getTags","getCurrentTagText","newTag","getOptions","on","handler","registerTagItem","removeTag","disabled","link","element","attrs","ngModelCtrl","setElementValidity","hotkeys","input","validationOptions","$setValidity","hasFocus","$isEmpty","invalid","setText","track","$watch","makeObjectArray","$observe","eventHandlers","change","keydown","$event","focus","blur","activeElement","prop","lostFocusToBrowserWindow","lostFocusToChildElement","contains","paste","getTextData","clipboardData","originalEvent","getData","host","click","$setViewValue","e","triggerHandler","event","shouldAdd","shouldRemove","shouldSelect","shouldEditLastTag","key","keyCode","addKeys","shiftKey","altKey","ctrlKey","metaKey","preventDefault","split","forEach","data","tagsInputCtrl","$$template","$$removeTagSymbol","$getDisplayText","$removeTag","$index","$sce","$q","source","debounceDelay","highlightMatchedText","maxResultsToShow","loadOnDownArrow","loadOnEmpty","loadOnFocus","selectFirstMatch","suggestionList","loadFn","getDifference","lastPromise","getTagId","array1","array2","filter","item","a","b","defaultComparer","reset","visible","query","show","debounce","promise","when","$query","then","slice","registerAutocompleteMatch","getQuery","shouldLoadSuggestions","addSuggestionByIndex","addSuggestion","added","copy","handled","stopImmediatePropagation","root","eq","parent","elementTop","elementHeight","parentHeight","parentScrollTop","scrollToElement","autoCompleteCtrl","autoComplete","$parent","$highlight","safeHighlight","trustAsHtml","ctrl","transcludeFn","clone","append","span","resize","threshold","getTextAutosizeThreshold","css","originalValue","width","isString","$parsers","unshift","$formatters","$modelValue","tiBindAttrs","$set","provider","globalDefaults","interpolationStatus","autosizeThreshold","setDefaults","defaults","setActiveInterpolation","setTextAutosizeThreshold","$get","$interpolate","converters","parseInt","toLowerCase","defaultValidator","localDefault","validator","converter","getDefault","updateValue","globalValue","isDefined","newValue","factory","fn","delay","timeoutId","args","arguments","cancel","apply","array","isObject","obj","comparer","some","str","encodeHTML","expression","escapeRegexChars","match","isUndefined","toString","trim","valueIfUndefined","result","names","every","run","$templateCache","put","window","dde","document","documentElement","matchingFunction","matches","matchesSelector","webkitMatches","webkitMatchesSelector","msMatches","msMatchesSelector","mozMatches","mozMatchesSelector","closestElement","closest","selector","el","parentNode","getWindowScroll","scrollTop","pageYOffset","scrollLeft","pageXOffset","sx","body","getClientSize","sizeProp","innerWidth","innerHeight","vsRepeatModule","$compile","$parse","compile","ngRepeatExpression","expressionMatches","lhs","rhs","rhsSuffix","originalNgRepeatAttr","repeatContainer","vsRepeatContainer","querySelector","ngRepeatChild","children","childCloneHtml","outerHTML","collectionName","isNgRepeatStart","attributesDictionary","vsRepeat","vsOffsetBefore","vsOffsetAfter","vsScrolledToEndOffset","vsScrolledToBeginningOffset","vsExcess","attr","Error","exec","repeaterElement","empty","pre","originalLength","_prevStartIndex","_prevEndIndex","_minStartIndex","_maxEndIndex","_prevClientSize","childClone","childTagName","tagName","originalCollection","$$horizontal","vsHorizontal","$beforeContent","$afterContent","autoSize","sizesPropertyExists","vsSize","vsSizeProperty","$scrollParent","vsScrollParent","$$options","$eval","vsOptions","clientSize","offsetSize","scrollPos","totalSize","console","warn","refresh","sizesCumulative","sizes","map","$new","extend","size","elementSize","$destroy","sum","res","setAutoSize","reinitialize","$$postDigest","offsetHeight","offsetWidth","gotSomething","insideStartEndSequence","attributes","$root","$$phase","$apply","dereg","getLayoutProp","layoutPropPrefix","scrollHandler","updateInnerCollection","$digest","onWindowResize","vsAutoresize","offsetBefore","offsetAfter","$emit","startIndex","endIndex","reinitOnClientHeightChange","ch","scrollProp","vsElement","scrollElement","isHorizontal","$scrollPosition","$clientSize","scrollOffset","getBoundingClientRect","__startIndex","__endIndex","Math","max","floor","excess","min","ceil","latch","digestRequired","hunked","abs","triggerIndex","vsScrolledToEnd","scrolledToEndOffset","vsScrolledToBeginning","scrolledToBeginningOffset","parsed","o1","o2","total","keys","$watchCollection","coll","addClass","$on","off","setTimeout","requestAnimationFrame"],"mappings":"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","file":"vendor-min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/*!\n * ngTagsInput v2.3.0\n * http://mbenford.github.io/ngTagsInput\n *\n * Copyright (c) 2013-2015 Michael Benford\n * License: MIT\n *\n * Generated at 2015-03-24 00:49:44 -0300\n */\n(function() {\n'use strict';\n\nvar KEYS = {\n backspace: 8,\n tab: 9,\n enter: 13,\n escape: 27,\n space: 32,\n up: 38,\n down: 40,\n left: 37,\n right: 39,\n delete: 46,\n comma: 188\n};\n\nvar MAX_SAFE_INTEGER = 9007199254740991;\nvar SUPPORTED_INPUT_TYPES = ['text', 'email', 'url'];\n\nvar tagsInput = angular.module('ngTagsInput', []);\n\n/**\n * @ngdoc directive\n * @name tagsInput\n * @module ngTagsInput\n *\n * @description\n * Renders an input box with tag editing support.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} [displayProperty=text] Property to be rendered as the tag label.\n * @param {string=} [keyProperty=text] Property to be used as a unique identifier for the tag.\n * @param {string=} [type=text] Type of the input element. Only 'text', 'email' and 'url' are supported values.\n * @param {number=} tabindex Tab order of the control.\n * @param {string=} [placeholder=Add a tag] Placeholder text for the control.\n * @param {number=} [minLength=3] Minimum length for a new tag.\n * @param {number=} [maxLength=MAX_SAFE_INTEGER] Maximum length allowed for a new tag.\n * @param {number=} [minTags=0] Sets minTags validation error key if the number of tags added is less than minTags.\n * @param {number=} [maxTags=MAX_SAFE_INTEGER] Sets maxTags validation error key if the number of tags added is greater than maxTags.\n * @param {boolean=} [allowLeftoverText=false] Sets leftoverText validation error key if there is any leftover text in\n * the input element when the directive loses focus.\n * @param {string=} [removeTagSymbol=×] Symbol character for the remove tag button.\n * @param {boolean=} [addOnEnter=true] Flag indicating that a new tag will be added on pressing the ENTER key.\n * @param {boolean=} [addOnSpace=false] Flag indicating that a new tag will be added on pressing the SPACE key.\n * @param {boolean=} [addOnComma=true] Flag indicating that a new tag will be added on pressing the COMMA key.\n * @param {boolean=} [addOnBlur=true] Flag indicating that a new tag will be added when the input field loses focus.\n * @param {boolean=} [addOnPaste=false] Flag indicating that the text pasted into the input field will be split into tags.\n * @param {string=} [pasteSplitPattern=,] Regular expression used to split the pasted text into tags.\n * @param {boolean=} [replaceSpacesWithDashes=true] Flag indicating that spaces will be replaced with dashes.\n * @param {string=} [allowedTagsPattern=.+] Regular expression that determines whether a new tag is valid.\n * @param {boolean=} [enableEditingLastTag=false] Flag indicating that the last tag will be moved back into\n * the new tag input box instead of being removed when the backspace key\n * is pressed and the input box is empty.\n * @param {boolean=} [addFromAutocompleteOnly=false] Flag indicating that only tags coming from the autocomplete list will be allowed.\n * When this flag is true, addOnEnter, addOnComma, addOnSpace, addOnBlur and\n * allowLeftoverText values are ignored.\n * @param {boolean=} [spellcheck=true] Flag indicating whether the browser's spellcheck is enabled for the input field or not.\n * @param {expression} onTagAdding Expression to evaluate that will be invoked before adding a new tag. The new tag is available as $tag. This method must return either true or false. If false, the tag will not be added.\n * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.\n * @param {expression} onInvalidTag Expression to evaluate when a tag is invalid. The invalid tag is available as $tag.\n * @param {expression} onTagRemoving Expression to evaluate that will be invoked before removing a tag. The tag is available as $tag. This method must return either true or false. If false, the tag will not be removed.\n * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.\n */\ntagsInput.directive('tagsInput', [\"$timeout\",\"$document\",\"$window\",\"tagsInputConfig\",\"tiUtil\", function($timeout, $document, $window, tagsInputConfig, tiUtil) {\n function TagList(options, events, onTagAdding, onTagRemoving) {\n var self = {}, getTagText, setTagText, tagIsValid;\n\n getTagText = function(tag) {\n return tiUtil.safeToString(tag[options.displayProperty]);\n };\n\n setTagText = function(tag, text) {\n tag[options.displayProperty] = text;\n };\n\n tagIsValid = function(tag) {\n var tagText = getTagText(tag);\n\n return tagText &&\n tagText.length >= options.minLength &&\n tagText.length <= options.maxLength &&\n options.allowedTagsPattern.test(tagText) &&\n !tiUtil.findInObjectArray(self.items, tag, options.keyProperty || options.displayProperty) &&\n onTagAdding({ $tag: tag });\n };\n\n self.items = [];\n\n self.addText = function(text) {\n var tag = {};\n setTagText(tag, text);\n return self.add(tag);\n };\n\n self.add = function(tag) {\n var tagText = getTagText(tag);\n\n if (options.replaceSpacesWithDashes) {\n tagText = tiUtil.replaceSpacesWithDashes(tagText);\n }\n\n setTagText(tag, tagText);\n\n if (tagIsValid(tag)) {\n self.items.push(tag);\n events.trigger('tag-added', { $tag: tag });\n }\n else if (tagText) {\n events.trigger('invalid-tag', { $tag: tag });\n }\n\n return tag;\n };\n\n self.remove = function(index) {\n var tag = self.items[index];\n\n if (onTagRemoving({ $tag: tag })) {\n self.items.splice(index, 1);\n self.clearSelection();\n events.trigger('tag-removed', { $tag: tag });\n return tag;\n }\n };\n\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n\n self.index = index;\n self.selected = self.items[index];\n };\n\n self.selectPrior = function() {\n self.select(--self.index);\n };\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n\n self.removeSelected = function() {\n return self.remove(self.index);\n };\n\n self.clearSelection = function() {\n self.selected = null;\n self.index = -1;\n };\n\n self.clearSelection();\n\n return self;\n }\n\n function validateType(type) {\n return SUPPORTED_INPUT_TYPES.indexOf(type) !== -1;\n }\n\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n tags: '=ngModel',\n onTagAdding: '&',\n onTagAdded: '&',\n onInvalidTag: '&',\n onTagRemoving: '&',\n onTagRemoved: '&'\n },\n replace: false,\n transclude: true,\n templateUrl: 'ngTagsInput/tags-input.html',\n controller: [\"$scope\",\"$attrs\",\"$element\", function($scope, $attrs, $element) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('tagsInput', $scope, $attrs, {\n template: [String, 'ngTagsInput/tag-item.html'],\n type: [String, 'text', validateType],\n placeholder: [String, 'Add a tag'],\n tabindex: [Number, null],\n removeTagSymbol: [String, String.fromCharCode(215)],\n replaceSpacesWithDashes: [Boolean, true],\n minLength: [Number, 3],\n maxLength: [Number, MAX_SAFE_INTEGER],\n addOnEnter: [Boolean, true],\n addOnSpace: [Boolean, false],\n addOnComma: [Boolean, true],\n addOnBlur: [Boolean, true],\n addOnPaste: [Boolean, false],\n pasteSplitPattern: [RegExp, /,/],\n allowedTagsPattern: [RegExp, /.+/],\n enableEditingLastTag: [Boolean, false],\n minTags: [Number, 0],\n maxTags: [Number, MAX_SAFE_INTEGER],\n displayProperty: [String, 'text'],\n keyProperty: [String, ''],\n allowLeftoverText: [Boolean, false],\n addFromAutocompleteOnly: [Boolean, false],\n spellcheck: [Boolean, true]\n });\n\n $scope.tagList = new TagList($scope.options, $scope.events,\n tiUtil.handleUndefinedResult($scope.onTagAdding, true),\n tiUtil.handleUndefinedResult($scope.onTagRemoving, true));\n\n this.registerAutocomplete = function() {\n var input = $element.find('input');\n\n return {\n addTag: function(tag) {\n return $scope.tagList.add(tag);\n },\n focusInput: function() {\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n },\n getTags: function() {\n return $scope.tags;\n },\n getCurrentTagText: function() {\n return $scope.newTag.text;\n },\n getOptions: function() {\n return $scope.options;\n },\n on: function(name, handler) {\n $scope.events.on(name, handler);\n return this;\n }\n };\n };\n\n this.registerTagItem = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n removeTag: function(index) {\n if ($scope.disabled) {\n return;\n }\n $scope.tagList.remove(index);\n }\n };\n };\n }],\n link: function(scope, element, attrs, ngModelCtrl) {\n var hotkeys = [KEYS.enter, KEYS.comma, KEYS.space, KEYS.backspace, KEYS.delete, KEYS.left, KEYS.right],\n tagList = scope.tagList,\n events = scope.events,\n options = scope.options,\n input = element.find('input'),\n validationOptions = ['minTags', 'maxTags', 'allowLeftoverText'],\n setElementValidity;\n\n setElementValidity = function() {\n ngModelCtrl.$setValidity('maxTags', scope.tags.length <= options.maxTags);\n ngModelCtrl.$setValidity('minTags', scope.tags.length >= options.minTags);\n ngModelCtrl.$setValidity('leftoverText', scope.hasFocus || options.allowLeftoverText ? true : !scope.newTag.text);\n };\n\n ngModelCtrl.$isEmpty = function(value) {\n return !value || !value.length;\n };\n\n scope.newTag = {\n text: '',\n invalid: null,\n setText: function(value) {\n this.text = value;\n events.trigger('input-change', value);\n }\n };\n\n scope.track = function(tag) {\n return tag[options.keyProperty || options.displayProperty];\n };\n\n scope.$watch('tags', function(value) {\n scope.tags = tiUtil.makeObjectArray(value, options.displayProperty);\n tagList.items = scope.tags;\n });\n\n scope.$watch('tags.length', function() {\n setElementValidity();\n });\n\n attrs.$observe('disabled', function(value) {\n scope.disabled = value;\n });\n\n scope.eventHandlers = {\n input: {\n change: function(text) {\n events.trigger('input-change', text);\n },\n keydown: function($event) {\n events.trigger('input-keydown', $event);\n },\n focus: function() {\n if (scope.hasFocus) {\n return;\n }\n\n scope.hasFocus = true;\n events.trigger('input-focus');\n },\n blur: function() {\n $timeout(function() {\n var activeElement = $document.prop('activeElement'),\n lostFocusToBrowserWindow = activeElement === input[0],\n lostFocusToChildElement = element[0].contains(activeElement);\n\n if (lostFocusToBrowserWindow || !lostFocusToChildElement) {\n scope.hasFocus = false;\n events.trigger('input-blur');\n }\n });\n },\n paste: function($event) {\n $event.getTextData = function() {\n var clipboardData = $event.clipboardData || ($event.originalEvent && $event.originalEvent.clipboardData);\n return clipboardData ? clipboardData.getData('text/plain') : $window.clipboardData.getData('Text');\n };\n events.trigger('input-paste', $event);\n }\n },\n host: {\n click: function() {\n if (scope.disabled) {\n return;\n }\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n }\n }\n };\n\n events\n .on('tag-added', scope.onTagAdded)\n .on('invalid-tag', scope.onInvalidTag)\n .on('tag-removed', scope.onTagRemoved)\n .on('tag-added', function() {\n scope.newTag.setText('');\n })\n .on('tag-added tag-removed', function() {\n // Sets the element to its dirty state\n // In Angular 1.3 this will be replaced with $setDirty.\n ngModelCtrl.$setViewValue(scope.tags);\n })\n .on('invalid-tag', function() {\n scope.newTag.invalid = true;\n })\n .on('option-change', function(e) {\n if (validationOptions.indexOf(e.name) !== -1) {\n setElementValidity();\n }\n })\n .on('input-change', function() {\n tagList.clearSelection();\n scope.newTag.invalid = null;\n })\n .on('input-focus', function() {\n element.triggerHandler('focus');\n ngModelCtrl.$setValidity('leftoverText', true);\n })\n .on('input-blur', function() {\n if (options.addOnBlur && !options.addFromAutocompleteOnly) {\n tagList.addText(scope.newTag.text);\n }\n element.triggerHandler('blur');\n setElementValidity();\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n isModifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey,\n addKeys = {},\n shouldAdd, shouldRemove, shouldSelect, shouldEditLastTag;\n\n if (isModifier || hotkeys.indexOf(key) === -1) {\n return;\n }\n\n addKeys[KEYS.enter] = options.addOnEnter;\n addKeys[KEYS.comma] = options.addOnComma;\n addKeys[KEYS.space] = options.addOnSpace;\n\n shouldAdd = !options.addFromAutocompleteOnly && addKeys[key];\n shouldRemove = (key === KEYS.backspace || key === KEYS.delete) && tagList.selected;\n shouldEditLastTag = key === KEYS.backspace && scope.newTag.text.length === 0 && options.enableEditingLastTag;\n shouldSelect = (key === KEYS.backspace || key === KEYS.left || key === KEYS.right) && scope.newTag.text.length === 0 && !options.enableEditingLastTag;\n\n if (shouldAdd) {\n tagList.addText(scope.newTag.text);\n }\n else if (shouldEditLastTag) {\n var tag;\n\n tagList.selectPrior();\n tag = tagList.removeSelected();\n\n if (tag) {\n scope.newTag.setText(tag[options.displayProperty]);\n }\n }\n else if (shouldRemove) {\n tagList.removeSelected();\n }\n else if (shouldSelect) {\n if (key === KEYS.left || key === KEYS.backspace) {\n tagList.selectPrior();\n }\n else if (key === KEYS.right) {\n tagList.selectNext();\n }\n }\n\n if (shouldAdd || shouldSelect || shouldRemove || shouldEditLastTag) {\n event.preventDefault();\n }\n })\n .on('input-paste', function(event) {\n if (options.addOnPaste) {\n var data = event.getTextData();\n var tags = data.split(options.pasteSplitPattern);\n\n if (tags.length > 1) {\n tags.forEach(function(tag) {\n tagList.addText(tag);\n });\n event.preventDefault();\n }\n }\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTagItem\n * @module ngTagsInput\n *\n * @description\n * Represents a tag item. Used internally by the tagsInput directive.\n */\ntagsInput.directive('tiTagItem', [\"tiUtil\", function(tiUtil) {\n return {\n restrict: 'E',\n require: '^tagsInput',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, tagsInputCtrl) {\n var tagsInput = tagsInputCtrl.registerTagItem(),\n options = tagsInput.getOptions();\n\n scope.$$template = options.template;\n scope.$$removeTagSymbol = options.removeTagSymbol;\n\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty]);\n };\n scope.$removeTag = function() {\n tagsInput.removeTag(scope.$index);\n };\n\n scope.$watch('$parent.$index', function(value) {\n scope.$index = value;\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name autoComplete\n * @module ngTagsInput\n *\n * @description\n * Provides autocomplete support for the tagsInput directive.\n *\n * @param {expression} source Expression to evaluate upon changing the input content. The input value is available as\n * $query. The result of the expression must be a promise that eventually resolves to an\n * array of strings.\n * @param {string=} [displayProperty=text] Property to be rendered as the autocomplete label.\n * @param {number=} [debounceDelay=100] Amount of time, in milliseconds, to wait before evaluating the expression in\n * the source option after the last keystroke.\n * @param {number=} [minLength=3] Minimum number of characters that must be entered before evaluating the expression\n * in the source option.\n * @param {boolean=} [highlightMatchedText=true] Flag indicating that the matched text will be highlighted in the\n * suggestions list.\n * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time.\n * @param {boolean=} [loadOnDownArrow=false] Flag indicating that the source option will be evaluated when the down arrow\n * key is pressed and the suggestion list is closed. The current input value\n * is available as $query.\n * @param {boolean=} {loadOnEmpty=false} Flag indicating that the source option will be evaluated when the input content\n * becomes empty. The $query variable will be passed to the expression as an empty string.\n * @param {boolean=} {loadOnFocus=false} Flag indicating that the source option will be evaluated when the input element\n * gains focus. The current input value is available as $query.\n * @param {boolean=} [selectFirstMatch=true] Flag indicating that the first match will be automatically selected once\n * the suggestion list is shown.\n * @param {string=} [template=] URL or id of a custom template for rendering each element of the autocomplete list.\n */\ntagsInput.directive('autoComplete', [\"$document\",\"$timeout\",\"$sce\",\"$q\",\"tagsInputConfig\",\"tiUtil\", function($document, $timeout, $sce, $q, tagsInputConfig, tiUtil) {\n function SuggestionList(loadFn, options, events) {\n var self = {}, getDifference, lastPromise, getTagId;\n\n getTagId = function() {\n return options.tagsInput.keyProperty || options.tagsInput.displayProperty;\n };\n\n getDifference = function(array1, array2) {\n return array1.filter(function(item) {\n return !tiUtil.findInObjectArray(array2, item, getTagId(), function(a, b) {\n if (options.tagsInput.replaceSpacesWithDashes) {\n a = tiUtil.replaceSpacesWithDashes(a);\n b = tiUtil.replaceSpacesWithDashes(b);\n }\n return tiUtil.defaultComparer(a, b);\n });\n });\n };\n\n self.reset = function() {\n lastPromise = null;\n\n self.items = [];\n self.visible = false;\n self.index = -1;\n self.selected = null;\n self.query = null;\n };\n self.show = function() {\n if (options.selectFirstMatch) {\n self.select(0);\n }\n else {\n self.selected = null;\n }\n self.visible = true;\n };\n self.load = tiUtil.debounce(function(query, tags) {\n self.query = query;\n\n var promise = $q.when(loadFn({ $query: query }));\n lastPromise = promise;\n\n promise.then(function(items) {\n if (promise !== lastPromise) {\n return;\n }\n\n items = tiUtil.makeObjectArray(items.data || items, getTagId());\n items = getDifference(items, tags);\n self.items = items.slice(0, options.maxResultsToShow);\n\n if (self.items.length > 0) {\n self.show();\n }\n else {\n self.reset();\n }\n });\n }, options.debounceDelay);\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n self.selectPrior = function() {\n self.select(--self.index);\n };\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n self.index = index;\n self.selected = self.items[index];\n events.trigger('suggestion-selected', index);\n };\n\n self.reset();\n\n return self;\n }\n\n function scrollToElement(root, index) {\n var element = root.find('li').eq(index),\n parent = element.parent(),\n elementTop = element.prop('offsetTop'),\n elementHeight = element.prop('offsetHeight'),\n parentHeight = parent.prop('clientHeight'),\n parentScrollTop = parent.prop('scrollTop');\n\n if (elementTop < parentScrollTop) {\n parent.prop('scrollTop', elementTop);\n }\n else if (elementTop + elementHeight > parentHeight + parentScrollTop) {\n parent.prop('scrollTop', elementTop + elementHeight - parentHeight);\n }\n }\n\n return {\n restrict: 'E',\n require: '^tagsInput',\n scope: { source: '&' },\n templateUrl: 'ngTagsInput/auto-complete.html',\n controller: [\"$scope\",\"$element\",\"$attrs\", function($scope, $element, $attrs) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('autoComplete', $scope, $attrs, {\n template: [String, 'ngTagsInput/auto-complete-match.html'],\n debounceDelay: [Number, 100],\n minLength: [Number, 3],\n highlightMatchedText: [Boolean, true],\n maxResultsToShow: [Number, 10],\n loadOnDownArrow: [Boolean, false],\n loadOnEmpty: [Boolean, false],\n loadOnFocus: [Boolean, false],\n selectFirstMatch: [Boolean, true],\n displayProperty: [String, '']\n });\n\n $scope.suggestionList = new SuggestionList($scope.source, $scope.options, $scope.events);\n\n this.registerAutocompleteMatch = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n getQuery: function() {\n return $scope.suggestionList.query;\n }\n };\n };\n }],\n link: function(scope, element, attrs, tagsInputCtrl) {\n var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],\n suggestionList = scope.suggestionList,\n tagsInput = tagsInputCtrl.registerAutocomplete(),\n options = scope.options,\n events = scope.events,\n shouldLoadSuggestions;\n\n options.tagsInput = tagsInput.getOptions();\n\n shouldLoadSuggestions = function(value) {\n return value && value.length >= options.minLength || !value && options.loadOnEmpty;\n };\n\n scope.addSuggestionByIndex = function(index) {\n suggestionList.select(index);\n scope.addSuggestion();\n };\n\n scope.addSuggestion = function() {\n var added = false;\n\n if (suggestionList.selected) {\n tagsInput.addTag(angular.copy(suggestionList.selected));\n suggestionList.reset();\n tagsInput.focusInput();\n\n added = true;\n }\n return added;\n };\n\n scope.track = function(item) {\n return item[options.tagsInput.keyProperty || options.tagsInput.displayProperty];\n };\n\n tagsInput\n .on('tag-added invalid-tag input-blur', function() {\n suggestionList.reset();\n })\n .on('input-change', function(value) {\n if (shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n else {\n suggestionList.reset();\n }\n })\n .on('input-focus', function() {\n var value = tagsInput.getCurrentTagText();\n if (options.loadOnFocus && shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n handled = false;\n\n if (hotkeys.indexOf(key) === -1) {\n return;\n }\n\n if (suggestionList.visible) {\n\n if (key === KEYS.down) {\n suggestionList.selectNext();\n handled = true;\n }\n else if (key === KEYS.up) {\n suggestionList.selectPrior();\n handled = true;\n }\n else if (key === KEYS.escape) {\n suggestionList.reset();\n handled = true;\n }\n else if (key === KEYS.enter || key === KEYS.tab) {\n handled = scope.addSuggestion();\n }\n }\n else {\n if (key === KEYS.down && scope.options.loadOnDownArrow) {\n suggestionList.load(tagsInput.getCurrentTagText(), tagsInput.getTags());\n handled = true;\n }\n }\n\n if (handled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return false;\n }\n });\n\n events.on('suggestion-selected', function(index) {\n scrollToElement(element, index);\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiAutocompleteMatch\n * @module ngTagsInput\n *\n * @description\n * Represents an autocomplete match. Used internally by the autoComplete directive.\n */\ntagsInput.directive('tiAutocompleteMatch', [\"$sce\",\"tiUtil\", function($sce, tiUtil) {\n return {\n restrict: 'E',\n require: '^autoComplete',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, autoCompleteCtrl) {\n var autoComplete = autoCompleteCtrl.registerAutocompleteMatch(),\n options = autoComplete.getOptions();\n\n scope.$$template = options.template;\n scope.$index = scope.$parent.$index;\n\n scope.$highlight = function(text) {\n if (options.highlightMatchedText) {\n text = tiUtil.safeHighlight(text, autoComplete.getQuery());\n }\n return $sce.trustAsHtml(text);\n };\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty || options.tagsInput.displayProperty]);\n };\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTranscludeAppend\n * @module ngTagsInput\n *\n * @description\n * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiTranscludeAppend', function() {\n return function(scope, element, attrs, ctrl, transcludeFn) {\n transcludeFn(function(clone) {\n element.append(clone);\n });\n };\n});\n\n/**\n * @ngdoc directive\n * @name tiAutosize\n * @module ngTagsInput\n *\n * @description\n * Automatically sets the input's width so its content is always visible. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiAutosize', [\"tagsInputConfig\", function(tagsInputConfig) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function(scope, element, attrs, ctrl) {\n var threshold = tagsInputConfig.getTextAutosizeThreshold(),\n span, resize;\n\n span = angular.element('<span class=\"input\"></span>');\n span.css('display', 'none')\n .css('visibility', 'hidden')\n .css('width', 'auto')\n .css('white-space', 'pre');\n\n element.parent().append(span);\n\n resize = function(originalValue) {\n var value = originalValue, width;\n\n if (angular.isString(value) && value.length === 0) {\n value = attrs.placeholder;\n }\n\n if (value) {\n span.text(value);\n span.css('display', '');\n width = span.prop('offsetWidth');\n span.css('display', 'none');\n }\n\n element.css('width', width ? width + threshold + 'px' : '');\n\n return originalValue;\n };\n\n ctrl.$parsers.unshift(resize);\n ctrl.$formatters.unshift(resize);\n\n attrs.$observe('placeholder', function(value) {\n if (!ctrl.$modelValue) {\n resize(value);\n }\n });\n }\n };\n}]);\n\n/**\n * @ngdoc directive\n * @name tiBindAttrs\n * @module ngTagsInput\n *\n * @description\n * Binds attributes to expressions. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiBindAttrs', function() {\n return function(scope, element, attrs) {\n scope.$watch(attrs.tiBindAttrs, function(value) {\n angular.forEach(value, function(value, key) {\n /**\n * blake_r - Added to work around the version of jQuery that\n * MAAS currently ships with. Once packaging for jQuery is\n * version >1.9 this can be removed.\n */\n if(key === \"type\") {\n element[0].type = value;\n } else {\n attrs.$set(key, value);\n }\n });\n }, true);\n };\n});\n\n/**\n * @ngdoc service\n * @name tagsInputConfig\n * @module ngTagsInput\n *\n * @description\n * Sets global configuration settings for both tagsInput and autoComplete directives. It's also used internally to parse and\n * initialize options from HTML attributes.\n */\ntagsInput.provider('tagsInputConfig', function() {\n var globalDefaults = {},\n interpolationStatus = {},\n autosizeThreshold = 3;\n\n /**\n * @ngdoc method\n * @name setDefaults\n * @description Sets the default configuration option for a directive.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} defaults Object containing options and their values.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setDefaults = function(directive, defaults) {\n globalDefaults[directive] = defaults;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setActiveInterpolation\n * @description Sets active interpolation for a set of options.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} options Object containing which options should have interpolation turned on at all times.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setActiveInterpolation = function(directive, options) {\n interpolationStatus[directive] = options;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setTextAutosizeThreshold\n * @description Sets the threshold used by the tagsInput directive to re-size the inner input field element based on its contents.\n * @methodOf tagsInputConfig\n *\n * @param {number} threshold Threshold value, in pixels.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setTextAutosizeThreshold = function(threshold) {\n autosizeThreshold = threshold;\n return this;\n };\n\n this.$get = [\"$interpolate\", function($interpolate) {\n var converters = {};\n converters[String] = function(value) { return value; };\n converters[Number] = function(value) { return parseInt(value, 10); };\n converters[Boolean] = function(value) { return value.toLowerCase() === 'true'; };\n converters[RegExp] = function(value) { return new RegExp(value); };\n\n return {\n load: function(directive, scope, attrs, options) {\n var defaultValidator = function() { return true; };\n\n scope.options = {};\n\n angular.forEach(options, function(value, key) {\n var type, localDefault, validator, converter, getDefault, updateValue;\n\n type = value[0];\n localDefault = value[1];\n validator = value[2] || defaultValidator;\n converter = converters[type];\n\n getDefault = function() {\n var globalValue = globalDefaults[directive] && globalDefaults[directive][key];\n return angular.isDefined(globalValue) ? globalValue : localDefault;\n };\n\n updateValue = function(value) {\n scope.options[key] = value && validator(value) ? converter(value) : getDefault();\n };\n\n if (interpolationStatus[directive] && interpolationStatus[directive][key]) {\n attrs.$observe(key, function(value) {\n updateValue(value);\n scope.events.trigger('option-change', { name: key, newValue: value });\n });\n }\n else {\n updateValue(attrs[key] && $interpolate(attrs[key])(scope.$parent));\n }\n });\n },\n getTextAutosizeThreshold: function() {\n return autosizeThreshold;\n }\n };\n }];\n});\n\n\n/***\n * @ngdoc factory\n * @name tiUtil\n * @module ngTagsInput\n *\n * @description\n * Helper methods used internally by the directive. Should not be called directly from user code.\n */\ntagsInput.factory('tiUtil', [\"$timeout\", function($timeout) {\n var self = {};\n\n self.debounce = function(fn, delay) {\n var timeoutId;\n return function() {\n var args = arguments;\n $timeout.cancel(timeoutId);\n timeoutId = $timeout(function() { fn.apply(null, args); }, delay);\n };\n };\n\n self.makeObjectArray = function(array, key) {\n array = array || [];\n if (array.length > 0 && !angular.isObject(array[0])) {\n array.forEach(function(item, index) {\n array[index] = {};\n array[index][key] = item;\n });\n }\n return array;\n };\n\n self.findInObjectArray = function(array, obj, key, comparer) {\n var item = null;\n comparer = comparer || self.defaultComparer;\n\n array.some(function(element) {\n if (comparer(element[key], obj[key])) {\n item = element;\n return true;\n }\n });\n\n return item;\n };\n\n self.defaultComparer = function(a, b) {\n // I'm aware of the internationalization issues regarding toLowerCase()\n // but I couldn't come up with a better solution right now\n return self.safeToString(a).toLowerCase() === self.safeToString(b).toLowerCase();\n };\n\n self.safeHighlight = function(str, value) {\n if (!value) {\n return str;\n }\n\n function escapeRegexChars(str) {\n return str.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n }\n\n str = self.encodeHTML(str);\n value = self.encodeHTML(value);\n\n var expression = new RegExp('&[^;]+;|' + escapeRegexChars(value), 'gi');\n return str.replace(expression, function(match) {\n return match.toLowerCase() === value.toLowerCase() ? '<em>' + match + '</em>' : match;\n });\n };\n\n self.safeToString = function(value) {\n return angular.isUndefined(value) || value == null ? '' : value.toString().trim();\n };\n\n self.encodeHTML = function(value) {\n return self.safeToString(value)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n };\n\n self.handleUndefinedResult = function(fn, valueIfUndefined) {\n return function() {\n var result = fn.apply(null, arguments);\n return angular.isUndefined(result) ? valueIfUndefined : result;\n };\n };\n\n self.replaceSpacesWithDashes = function(str) {\n return self.safeToString(str).replace(/\\s/g, '-');\n };\n\n self.simplePubSub = function() {\n var events = {};\n return {\n on: function(names, handler) {\n names.split(' ').forEach(function(name) {\n if (!events[name]) {\n events[name] = [];\n }\n events[name].push(handler);\n });\n return this;\n },\n trigger: function(name, args) {\n var handlers = events[name] || [];\n handlers.every(function(handler) {\n return self.handleUndefinedResult(handler, true)(args);\n });\n return this;\n }\n };\n };\n\n return self;\n}]);\n\n/* HTML templates */\ntagsInput.run([\"$templateCache\", function($templateCache) {\n $templateCache.put('ngTagsInput/tags-input.html',\n \"<div class=\\\"host\\\" tabindex=\\\"-1\\\" data-ng-click=\\\"eventHandlers.host.click()\\\" ti-transclude-append=\\\"\\\"><div class=\\\"tags\\\" data-ng-class=\\\"{focused: hasFocus}\\\"><ul class=\\\"tag-list\\\"><li class=\\\"tag-item\\\" data-ng-repeat=\\\"tag in tagList.items track by track(tag)\\\" data-ng-class=\\\"{ selected: tag == tagList.selected }\\\"><ti-tag-item data=\\\"tag\\\"></ti-tag-item></li></ul><input class=\\\"input u-no-margin--top\\\" autocomplete=\\\"off\\\" data-ng-model=\\\"newTag.text\\\" data-ng-change=\\\"eventHandlers.input.change(newTag.text)\\\" data-ng-keydown=\\\"eventHandlers.input.keydown($event)\\\" data-ng-focus=\\\"eventHandlers.input.focus($event)\\\" data-ng-blur=\\\"eventHandlers.input.blur($event)\\\" data-ng-paste=\\\"eventHandlers.input.paste($event)\\\" data-ng-trim=\\\"false\\\" data-ng-class=\\\"{'invalid-tag': newTag.invalid}\\\" data-ng-disabled=\\\"disabled\\\" ti-bind-attrs=\\\"{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}\\\" ti-autosize=\\\"\\\"></div></div>\"\n );\n\n $templateCache.put('ngTagsInput/tag-item.html',\n \"<span ng-bind=\\\"$getDisplayText()\\\"></span> <a class=\\\"p-icon--close\\\" data-ng-click=\\\"$removeTag()\\\" data-ng-bind=\\\"$$removeTagSymbol\\\">Remove tag</a>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete.html',\n \"<div class=\\\"autocomplete\\\" data-ng-if=\\\"suggestionList.visible\\\"><ul class=\\\"p-list suggestion-list\\\"><li class=\\\"suggestion-item\\\" data-ng-repeat=\\\"item in suggestionList.items track by track(item)\\\" data-ng-class=\\\"{selected: item == suggestionList.selected}\\\" data-ng-click=\\\"addSuggestionByIndex($index)\\\" data-ng-mouseenter=\\\"suggestionList.select($index)\\\"><ti-autocomplete-match data=\\\"item\\\"></ti-autocomplete-match></li></ul></div>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete-match.html',\n \"<span data-ng-bind-html=\\\"$highlight($getDisplayText())\\\"></span>\"\n );\n}]);\n\n}());\n","//\n// Copyright Kamil Pękala http://github.com/kamilkp\n// Angular Virtual Scroll Repeat v1.1.7 2016/03/08\n//\n\n(function(window, angular) {\n 'use strict';\n /* jshint eqnull:true */\n /* jshint -W038 */\n\n // DESCRIPTION:\n // vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container\n // into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of\n // pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.\n // The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.\n\n // LIMITATIONS:\n // - current version only supports an Array as a right-hand-side object for ngRepeat\n // - all rendered elements must have the same height/width or the sizes of the elements must be known up front\n\n // USAGE:\n // In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat\n // example:\n // <div vs-repeat>\n // <div ng-repeat=\"item in someArray\">\n // <!-- content -->\n // </div>\n // </div>\n //\n // or:\n // <div vs-repeat>\n // <div ng-repeat-start=\"item in someArray\">\n // <!-- content -->\n // </div>\n // <div>\n // <!-- something in the middle -->\n // </div>\n // <div ng-repeat-end>\n // <!-- content -->\n // </div>\n // </div>\n //\n // You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value\n // of the attribute 'vs-repeat'. This can be used if one wants to override the automatically computed element size.\n // example:\n // <div vs-repeat=\"50\"> <!-- the specified element height is 50px -->\n // <div ng-repeat=\"item in someArray\">\n // <!-- content -->\n // </div>\n // </div>\n //\n // IMPORTANT!\n //\n // - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat\n // - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive\n // will compute it automatically\n\n // OPTIONAL PARAMETERS (attributes):\n // vs-repeat-container=\"selector\" - selector for element containing ng-repeat. (defaults to the current element)\n // vs-scroll-parent=\"selector\" - selector to the scrollable container. The directive will look for a closest parent matching\n // the given selector (defaults to the current element)\n // vs-horizontal - stack repeated elements horizontally instead of vertically\n // vs-offset-before=\"value\" - top/left offset in pixels (defaults to 0)\n // vs-offset-after=\"value\" - bottom/right offset in pixels (defaults to 0)\n // vs-excess=\"value\" - an integer number representing the number of elements to be rendered outside of the current container's viewport\n // (defaults to 2)\n // vs-size - a property name of the items in collection that is a number denoting the element size (in pixels)\n // vs-autoresize - use this attribute without vs-size and without specifying element's size. The automatically computed element style will\n // readjust upon window resize if the size is dependable on the viewport size\n // vs-scrolled-to-end=\"callback\" - callback will be called when the last item of the list is rendered\n // vs-scrolled-to-end-offset=\"integer\" - set this number to trigger the scrolledToEnd callback n items before the last gets rendered\n // vs-scrolled-to-beginning=\"callback\" - callback will be called when the first item of the list is rendered\n // vs-scrolled-to-beginning-offset=\"integer\" - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered\n\n // EVENTS:\n // - 'vsRepeatTrigger' - an event the directive listens for to manually trigger reinitialization\n // - 'vsRepeatReinitialized' - an event the directive emits upon reinitialization done\n\n var dde = document.documentElement,\n matchingFunction = dde.matches ? 'matches' :\n dde.matchesSelector ? 'matchesSelector' :\n dde.webkitMatches ? 'webkitMatches' :\n dde.webkitMatchesSelector ? 'webkitMatchesSelector' :\n dde.msMatches ? 'msMatches' :\n dde.msMatchesSelector ? 'msMatchesSelector' :\n dde.mozMatches ? 'mozMatches' :\n dde.mozMatchesSelector ? 'mozMatchesSelector' : null;\n\n var closestElement = angular.element.prototype.closest || function (selector) {\n var el = this[0].parentNode;\n while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {\n el = el.parentNode;\n }\n\n if (el && el[matchingFunction](selector)) {\n return angular.element(el);\n }\n else {\n return angular.element();\n }\n };\n\n function getWindowScroll() {\n if ('pageYOffset' in window) {\n return {\n scrollTop: pageYOffset,\n scrollLeft: pageXOffset\n };\n }\n else {\n var sx, sy, d = document, r = d.documentElement, b = d.body;\n sx = r.scrollLeft || b.scrollLeft || 0;\n sy = r.scrollTop || b.scrollTop || 0;\n return {\n scrollTop: sy,\n scrollLeft: sx\n };\n }\n }\n\n function getClientSize(element, sizeProp) {\n if (element === window) {\n return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;\n }\n else {\n return element[sizeProp];\n }\n }\n\n function getScrollPos(element, scrollProp) {\n return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];\n }\n\n function getScrollOffset(vsElement, scrollElement, isHorizontal) {\n var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var correction = vsPos - scrollPos +\n (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];\n\n return correction;\n }\n\n var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function($compile, $parse) {\n return {\n restrict: 'A',\n scope: true,\n compile: function($element, $attrs) {\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,\n ngRepeatChild = repeatContainer.children().eq(0),\n ngRepeatExpression,\n childCloneHtml = ngRepeatChild[0].outerHTML,\n expressionMatches,\n lhs,\n rhs,\n rhsSuffix,\n originalNgRepeatAttr,\n collectionName = '$vs_collection',\n isNgRepeatStart = false,\n attributesDictionary = {\n 'vsRepeat': 'elementSize',\n 'vsOffsetBefore': 'offsetBefore',\n 'vsOffsetAfter': 'offsetAfter',\n 'vsScrolledToEndOffset': 'scrolledToEndOffset',\n 'vsScrolledToBeginningOffset': 'scrolledToBeginningOffset',\n 'vsExcess': 'excess'\n };\n\n if (ngRepeatChild.attr('ng-repeat')) {\n originalNgRepeatAttr = 'ng-repeat';\n ngRepeatExpression = ngRepeatChild.attr('ng-repeat');\n }\n else if (ngRepeatChild.attr('data-ng-repeat')) {\n originalNgRepeatAttr = 'data-ng-repeat';\n ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat');\n }\n else if (ngRepeatChild.attr('ng-repeat-start')) {\n isNgRepeatStart = true;\n originalNgRepeatAttr = 'ng-repeat-start';\n ngRepeatExpression = ngRepeatChild.attr('ng-repeat-start');\n }\n else if (ngRepeatChild.attr('data-ng-repeat-start')) {\n isNgRepeatStart = true;\n originalNgRepeatAttr = 'data-ng-repeat-start';\n ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat-start');\n }\n else {\n throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');\n }\n\n expressionMatches = /^\\s*(\\S+)\\s+in\\s+([\\S\\s]+?)(track\\s+by\\s+\\S+)?$/.exec(ngRepeatExpression);\n lhs = expressionMatches[1];\n rhs = expressionMatches[2];\n rhsSuffix = expressionMatches[3];\n\n if (isNgRepeatStart) {\n var index = 0;\n var repeaterElement = repeatContainer.children().eq(0);\n while(repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {\n index++;\n repeaterElement = repeatContainer.children().eq(index);\n childCloneHtml += repeaterElement[0].outerHTML;\n }\n }\n\n repeatContainer.empty();\n return {\n pre: function($scope, $element, $attrs) {\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,\n childClone = angular.element(childCloneHtml),\n childTagName = childClone[0].tagName.toLowerCase(),\n originalCollection = [],\n originalLength,\n $$horizontal = typeof $attrs.vsHorizontal !== 'undefined',\n $beforeContent = angular.element('<' + childTagName + ' class=\"vs-repeat-before-content\"></' + childTagName + '>'),\n $afterContent = angular.element('<' + childTagName + ' class=\"vs-repeat-after-content\"></' + childTagName + '>'),\n autoSize = !$attrs.vsRepeat,\n sizesPropertyExists = !!$attrs.vsSize || !!$attrs.vsSizeProperty,\n $scrollParent = $attrs.vsScrollParent ?\n $attrs.vsScrollParent === 'window' ? angular.element(window) :\n closestElement.call(repeatContainer, $attrs.vsScrollParent) : repeatContainer,\n $$options = 'vsOptions' in $attrs ? $scope.$eval($attrs.vsOptions) : {},\n clientSize = $$horizontal ? 'clientWidth' : 'clientHeight',\n offsetSize = $$horizontal ? 'offsetWidth' : 'offsetHeight',\n scrollPos = $$horizontal ? 'scrollLeft' : 'scrollTop';\n\n $scope.totalSize = 0;\n if (!('vsSize' in $attrs) && 'vsSizeProperty' in $attrs) {\n console.warn('vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions.');\n }\n\n if ($scrollParent.length === 0) {\n throw 'Specified scroll parent selector did not match any element';\n }\n $scope.$scrollParent = $scrollParent;\n\n if (sizesPropertyExists) {\n $scope.sizesCumulative = [];\n }\n\n //initial defaults\n $scope.elementSize = (+$attrs.vsRepeat) || getClientSize($scrollParent[0], clientSize) || 50;\n $scope.offsetBefore = 0;\n $scope.offsetAfter = 0;\n $scope.excess = 2;\n\n if ($$horizontal) {\n $beforeContent.css('height', '100%');\n $afterContent.css('height', '100%');\n }\n else {\n $beforeContent.css('width', '100%');\n $afterContent.css('width', '100%');\n }\n\n Object.keys(attributesDictionary).forEach(function(key) {\n if ($attrs[key]) {\n $attrs.$observe(key, function(value) {\n // '+' serves for getting a number from the string as the attributes are always strings\n $scope[attributesDictionary[key]] = +value;\n reinitialize();\n });\n }\n });\n\n\n $scope.$watchCollection(rhs, function(coll) {\n originalCollection = coll || [];\n refresh();\n });\n\n function refresh() {\n if (!originalCollection || originalCollection.length < 1) {\n $scope[collectionName] = [];\n originalLength = 0;\n $scope.sizesCumulative = [0];\n }\n else {\n originalLength = originalCollection.length;\n if (sizesPropertyExists) {\n $scope.sizes = originalCollection.map(function(item) {\n var s = $scope.$new(false);\n angular.extend(s, item);\n s[lhs] = item;\n var size = ($attrs.vsSize || $attrs.vsSizeProperty) ?\n s.$eval($attrs.vsSize || $attrs.vsSizeProperty) :\n $scope.elementSize;\n s.$destroy();\n return size;\n });\n var sum = 0;\n $scope.sizesCumulative = $scope.sizes.map(function(size) {\n var res = sum;\n sum += size;\n return res;\n });\n $scope.sizesCumulative.push(sum);\n }\n else {\n setAutoSize();\n }\n }\n\n reinitialize();\n }\n\n function setAutoSize() {\n if (autoSize) {\n $scope.$$postDigest(function() {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { // element is visible\n var children = repeatContainer.children(),\n i = 0,\n gotSomething = false,\n insideStartEndSequence = false;\n\n while (i < children.length) {\n if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {\n if (!gotSomething) {\n $scope.elementSize = 0;\n }\n\n gotSomething = true;\n if (children[i][offsetSize]) {\n $scope.elementSize += children[i][offsetSize];\n }\n\n if (isNgRepeatStart) {\n if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {\n break;\n }\n else {\n insideStartEndSequence = true;\n }\n }\n else {\n break;\n }\n }\n i++;\n }\n\n if (gotSomething) {\n reinitialize();\n autoSize = false;\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n }\n else {\n var dereg = $scope.$watch(function() {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n dereg();\n setAutoSize();\n }\n });\n }\n });\n }\n }\n\n function getLayoutProp() {\n var layoutPropPrefix = childTagName === 'tr' ? '' : 'min-';\n var layoutProp = $$horizontal ? layoutPropPrefix + 'width' : layoutPropPrefix + 'height';\n return layoutProp;\n }\n\n childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));\n childClone.addClass('vs-repeat-repeated-element');\n\n repeatContainer.append($beforeContent);\n repeatContainer.append(childClone);\n $compile(childClone)($scope);\n repeatContainer.append($afterContent);\n\n $scope.startIndex = 0;\n $scope.endIndex = 0;\n\n function scrollHandler() {\n if (updateInnerCollection()) {\n $scope.$digest();\n }\n }\n\n $scrollParent.on('scroll', scrollHandler);\n\n function onWindowResize() {\n if (typeof $attrs.vsAutoresize !== 'undefined') {\n autoSize = true;\n setAutoSize();\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n if (updateInnerCollection()) {\n $scope.$apply();\n }\n }\n\n angular.element(window).on('resize', onWindowResize);\n $scope.$on('$destroy', function() {\n angular.element(window).off('resize', onWindowResize);\n $scrollParent.off('scroll', scrollHandler);\n });\n\n $scope.$on('vsRepeatTrigger', refresh);\n\n $scope.$on('vsRepeatResize', function() {\n autoSize = true;\n setAutoSize();\n });\n\n var _prevStartIndex,\n _prevEndIndex,\n _minStartIndex,\n _maxEndIndex;\n\n $scope.$on('vsRenderAll', function() {//e , quantum) {\n if($$options.latch) {\n setTimeout(function() {\n // var __endIndex = Math.min($scope.endIndex + (quantum || 1), originalLength);\n var __endIndex = originalLength;\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;\n $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);\n _prevEndIndex = $scope.endIndex;\n\n $scope.$$postDigest(function() {\n $beforeContent.css(getLayoutProp(), 0);\n $afterContent.css(getLayoutProp(), 0);\n });\n\n $scope.$apply(function() {\n $scope.$emit('vsRenderAllDone');\n });\n });\n }\n });\n\n function reinitialize() {\n _prevStartIndex = void 0;\n _prevEndIndex = void 0;\n _minStartIndex = originalLength;\n _maxEndIndex = 0;\n updateTotalSize(sizesPropertyExists ?\n $scope.sizesCumulative[originalLength] :\n $scope.elementSize * originalLength\n );\n updateInnerCollection();\n\n $scope.$emit('vsRepeatReinitialized', $scope.startIndex, $scope.endIndex);\n }\n\n function updateTotalSize(size) {\n $scope.totalSize = $scope.offsetBefore + size + $scope.offsetAfter;\n }\n\n var _prevClientSize;\n function reinitOnClientHeightChange() {\n var ch = getClientSize($scrollParent[0], clientSize);\n if (ch !== _prevClientSize) {\n reinitialize();\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n _prevClientSize = ch;\n }\n\n $scope.$watch(function() {\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(reinitOnClientHeightChange);\n }\n else {\n reinitOnClientHeightChange();\n }\n });\n\n function updateInnerCollection() {\n var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);\n var $clientSize = getClientSize($scrollParent[0], clientSize);\n\n var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(\n repeatContainer[0],\n $scrollParent[0],\n $$horizontal\n );\n\n var __startIndex = $scope.startIndex;\n var __endIndex = $scope.endIndex;\n\n if (sizesPropertyExists) {\n __startIndex = 0;\n while ($scope.sizesCumulative[__startIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset) {\n __startIndex++;\n }\n if (__startIndex > 0) { __startIndex--; }\n\n // Adjust the start index according to the excess\n __startIndex = Math.max(\n Math.floor(__startIndex - $scope.excess / 2),\n 0\n );\n\n __endIndex = __startIndex;\n while ($scope.sizesCumulative[__endIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset + $clientSize) {\n __endIndex++;\n }\n\n // Adjust the end index according to the excess\n __endIndex = Math.min(\n Math.ceil(__endIndex + $scope.excess / 2),\n originalLength\n );\n }\n else {\n __startIndex = Math.max(\n Math.floor(\n ($scrollPosition - $scope.offsetBefore - scrollOffset) / $scope.elementSize\n ) - $scope.excess / 2,\n 0\n );\n\n __endIndex = Math.min(\n __startIndex + Math.ceil(\n $clientSize / $scope.elementSize\n ) + $scope.excess,\n originalLength\n );\n }\n\n _minStartIndex = Math.min(__startIndex, _minStartIndex);\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n\n $scope.startIndex = $$options.latch ? _minStartIndex : __startIndex;\n $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;\n\n var digestRequired = false;\n if (_prevStartIndex == null) {\n digestRequired = true;\n }\n else if (_prevEndIndex == null) {\n digestRequired = true;\n }\n\n if (!digestRequired) {\n if ($$options.hunked) {\n if (Math.abs($scope.startIndex - _prevStartIndex) >= $scope.excess / 2 ||\n ($scope.startIndex === 0 && _prevStartIndex !== 0)) {\n digestRequired = true;\n }\n else if (Math.abs($scope.endIndex - _prevEndIndex) >= $scope.excess / 2 ||\n ($scope.endIndex === originalLength && _prevEndIndex !== originalLength)) {\n digestRequired = true;\n }\n }\n else {\n digestRequired = $scope.startIndex !== _prevStartIndex ||\n $scope.endIndex !== _prevEndIndex;\n }\n }\n\n if (digestRequired) {\n $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);\n\n // Emit the event\n $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.startIndex, $scope.endIndex, _prevStartIndex, _prevEndIndex);\n var triggerIndex;\n if ($attrs.vsScrolledToEnd) {\n triggerIndex = originalCollection.length - ($scope.scrolledToEndOffset || 0);\n if (($scope.endIndex >= triggerIndex && _prevEndIndex < triggerIndex) || (originalCollection.length && $scope.endIndex === originalCollection.length)) {\n $scope.$eval($attrs.vsScrolledToEnd);\n }\n }\n if ($attrs.vsScrolledToBeginning) {\n triggerIndex = $scope.scrolledToBeginningOffset || 0;\n if (($scope.startIndex <= triggerIndex && _prevStartIndex > $scope.startIndex)) {\n $scope.$eval($attrs.vsScrolledToBeginning);\n }\n }\n\n _prevStartIndex = $scope.startIndex;\n _prevEndIndex = $scope.endIndex;\n\n var offsetCalculationString = sizesPropertyExists ?\n '(sizesCumulative[$index + startIndex] + offsetBefore)' :\n '(($index + startIndex) * elementSize + offsetBefore)';\n\n var parsed = $parse(offsetCalculationString);\n var o1 = parsed($scope, {$index: 0});\n var o2 = parsed($scope, {$index: $scope[collectionName].length});\n var total = $scope.totalSize;\n\n $beforeContent.css(getLayoutProp(), o1 + 'px');\n $afterContent.css(getLayoutProp(), (total - o2) + 'px');\n }\n\n return digestRequired;\n }\n }\n };\n }\n };\n }]);\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = vsRepeatModule.name;\n }\n})(window, window.angular);\n"],"sourceRoot":""}
3\ No newline at end of file3\ No newline at end of file
diff --git a/src/maasserver/static/partials/dashboard.html b/src/maasserver/static/partials/dashboard.html
index 35e670d..b009216 100644
--- a/src/maasserver/static/partials/dashboard.html
+++ b/src/maasserver/static/partials/dashboard.html
@@ -57,7 +57,7 @@
57 </td>57 </td>
58 </tr>58 </tr>
59 </tbody>59 </tbody>
60 <tbody vs-repeat="{scrollParent: 'window'}">60 <tbody vs-repeat vs-scroll-parent="window">
61 <tr data-ng-repeat="discovery in discoveredDevices | orderBy:predicate:reverse track by discovery.first_seen"61 <tr data-ng-repeat="discovery in discoveredDevices | orderBy:predicate:reverse track by discovery.first_seen"
62 data-ng-class="{'is-active' : discovery.first_seen === selectedDevice}">62 data-ng-class="{'is-active' : discovery.first_seen === selectedDevice}">
63 <td class="p-table--network-discovery__name" aria-label="Name" data-ng-if="discovery.first_seen !== selectedDevice">63 <td class="p-table--network-discovery__name" aria-label="Name" data-ng-if="discovery.first_seen !== selectedDevice">
diff --git a/src/maasserver/static/partials/machines-table.html b/src/maasserver/static/partials/machines-table.html
index 727d392..1c49dbe 100644
--- a/src/maasserver/static/partials/machines-table.html
+++ b/src/maasserver/static/partials/machines-table.html
@@ -22,7 +22,7 @@
22 <th class="u-hide--small u-align--right" role="columnheader" data-ng-click="sortTable('storage')" data-ng-class="{'is-sorted': table.predicate === 'storage', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Storage (GB)">Storage (GB)</th>22 <th class="u-hide--small u-align--right" role="columnheader" data-ng-click="sortTable('storage')" data-ng-class="{'is-sorted': table.predicate === 'storage', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Storage (GB)">Storage (GB)</th>
23 </tr>23 </tr>
24 </thead>24 </thead>
25 <tbody vs-repeat="{scrollParent: 'window'}">25 <tbody vs-repeat vs-scroll-parent="window">
26 <tr class="p-table__row" data-ng-repeat="node in table.filteredMachines = (table.machines | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" data-ng-class="{ 'table--error': machineHasError({ $machine: node }), 'is-active': node.$selected }">26 <tr class="p-table__row" data-ng-repeat="node in table.filteredMachines = (table.machines | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" data-ng-class="{ 'table--error': machineHasError({ $machine: node }), 'is-active': node.$selected }">
27 <td class="u-align--left" aria-label="FQDN" data-ng-if="table.column === 'fqdn'">27 <td class="u-align--left" aria-label="FQDN" data-ng-if="table.column === 'fqdn'">
28 <div class="u-float--left" data-ng-if="!hideCheckboxes">28 <div class="u-float--left" data-ng-if="!hideCheckboxes">
diff --git a/src/maasserver/static/partials/networks-list.html b/src/maasserver/static/partials/networks-list.html
index 4517c73..9bdd75e 100644
--- a/src/maasserver/static/partials/networks-list.html
+++ b/src/maasserver/static/partials/networks-list.html
@@ -171,7 +171,7 @@
171 <th><div class="u-align--right">Available IPs</div></th>171 <th><div class="u-align--right">Available IPs</div></th>
172 </tr>172 </tr>
173 </thead>173 </thead>
174 <tbody vs-repeat="{scrollParent: 'window'}">174 <tbody vs-repeat vs-scroll-parent="window">
175 <tr data-ng-repeat="row in group.spaces.rows">175 <tr data-ng-repeat="row in group.spaces.rows">
176 <!-- <td class="ng-hide">176 <!-- <td class="ng-hide">
177 <div data-ng-if="row.space_name">177 <div data-ng-if="row.space_name">
@@ -241,7 +241,7 @@
241 <th>Space</th>241 <th>Space</th>
242 </tr>242 </tr>
243 </thead>243 </thead>
244 <tbody vs-repeat="{scrollParent: 'window'}">244 <tbody vs-repeat vs-scroll-parent="window">
245 <tr data-ng-repeat="row in group.fabrics.rows">245 <tr data-ng-repeat="row in group.fabrics.rows">
246 <!-- <td class="ng-hide">246 <!-- <td class="ng-hide">
247 <div data-ng-if="row.fabric_name">247 <div data-ng-if="row.fabric_name">
diff --git a/src/maasserver/static/partials/node-events.html b/src/maasserver/static/partials/node-events.html
index 75d6772..10c8d3a 100644
--- a/src/maasserver/static/partials/node-events.html
+++ b/src/maasserver/static/partials/node-events.html
@@ -46,7 +46,7 @@
46 <th class="col-9">Event</th>46 <th class="col-9">Event</th>
47 </tr>47 </tr>
48 </thead>48 </thead>
49 <tbody vs-repeat="{scrollParent: 'window'}">49 <tbody vs-repeat vs-scroll-parent="window">
50 <tr data-ng-repeat="event in events | filter:search | orderByDate:'created':'id' track by event.id">50 <tr data-ng-repeat="event in events | filter:search | orderByDate:'created':'id' track by event.id">
51 <td class="col-3" title="{$ event.created $}">51 <td class="col-3" title="{$ event.created $}">
52 <span class="p-icon--{$ event.type.level $}"></span>&nbsp;52 <span class="p-icon--{$ event.type.level $}"></span>&nbsp;
diff --git a/src/maasserver/static/partials/nodes-list.html b/src/maasserver/static/partials/nodes-list.html
index 6662a02..354c12f 100644
--- a/src/maasserver/static/partials/nodes-list.html
+++ b/src/maasserver/static/partials/nodes-list.html
@@ -438,7 +438,7 @@
438 <th class="p-table__cell">Actions</th>438 <th class="p-table__cell">Actions</th>
439 </tr>439 </tr>
440 </thead>440 </thead>
441 <tbody vs-repeat="{scrollParent: 'window'}">441 <tbody vs-repeat vs-scroll-parent="window">
442 <tr class="p-table__row" data-ng-repeat="interface in device.interfaces">442 <tr class="p-table__row" data-ng-repeat="interface in device.interfaces">
443 <td class="p-table__cell" aria-label="MAC address">443 <td class="p-table__cell" aria-label="MAC address">
444 <div class="p-form-validation u-no-margin--top" data-ng-class="{ 'is-error': macHasError(interface) }">444 <div class="p-form-validation u-no-margin--top" data-ng-class="{ 'is-error': macHasError(interface) }">
@@ -868,7 +868,7 @@ sudo maas-rack register --url {$ tabs.controllers.registerUrl $} --secret {$ tab
868 </th>868 </th>
869 </tr>869 </tr>
870 </thead>870 </thead>
871 <tbody vs-repeat="{scrollParent: 'window'}">871 <tbody vs-repeat vs-scroll-parent="window">
872 <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. -->872 <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. -->
873 <tr class="p-table__row"873 <tr class="p-table__row"
874 data-ng-repeat="device in tabs.devices.filtered_items = (devices | nodesFilter:tabs.devices.search | orderBy:tabs.devices.predicate:tabs.devices.reverse) track by device.system_id"874 data-ng-repeat="device in tabs.devices.filtered_items = (devices | nodesFilter:tabs.devices.search | orderBy:tabs.devices.predicate:tabs.devices.reverse) track by device.system_id"
@@ -1027,7 +1027,7 @@ sudo maas-rack register --url {$ tabs.controllers.registerUrl $} --secret {$ tab
1027 <th class="p-table__cell" role="columnheader" data-ng-click="sortTable('updated', 'controllers')" data-ng-class="{'is-sorted': tabs.controllers.predicate === 'updated', 'sort-asc': tabs.controllers.reverse === false, 'sort-desc': tabs.controllers.reverse === true}">Images Status</th>1027 <th class="p-table__cell" role="columnheader" data-ng-click="sortTable('updated', 'controllers')" data-ng-class="{'is-sorted': tabs.controllers.predicate === 'updated', 'sort-asc': tabs.controllers.reverse === false, 'sort-desc': tabs.controllers.reverse === true}">Images Status</th>
1028 </tr>1028 </tr>
1029 </thead>1029 </thead>
1030 <tbody vs-repeat="{scrollParent: 'window'}">1030 <tbody vs-repeat vs-scroll-parent="window">
1031 <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. -->1031 <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. -->
1032 <tr class="p-table__row"1032 <tr class="p-table__row"
1033 data-ng-repeat="controller in tabs.controllers.filtered_items = (controllers | nodesFilter:tabs.controllers.search | orderBy:tabs.controllers.predicate:tabs.controllers.reverse) track by controller.system_id"1033 data-ng-repeat="controller in tabs.controllers.filtered_items = (controllers | nodesFilter:tabs.controllers.search | orderBy:tabs.controllers.predicate:tabs.controllers.reverse) track by controller.system_id"
diff --git a/src/maasserver/static/partials/pods-list.html b/src/maasserver/static/partials/pods-list.html
index a7ff1f6..a692f91 100644
--- a/src/maasserver/static/partials/pods-list.html
+++ b/src/maasserver/static/partials/pods-list.html
@@ -133,7 +133,7 @@
133 <th class="p-table__cell u-align--right" role="columnheader" data-ng-click="sortTable('composed_machines')" data-ng-class="{'is-sorted': predicate === 'composed_machines', 'sort-asc': reverse === false, 'sort-desc': reverse === true}" title="Composed machines">Composed machines</th>133 <th class="p-table__cell u-align--right" role="columnheader" data-ng-click="sortTable('composed_machines')" data-ng-class="{'is-sorted': predicate === 'composed_machines', 'sort-asc': reverse === false, 'sort-desc': reverse === true}" title="Composed machines">Composed machines</th>
134 </tr>134 </tr>
135 </thead>135 </thead>
136 <tbody vs-repeat="{scrollParent: 'window'}">136 <tbody vs-repeat vs-scroll-parent="window">
137 <tr class="p-table__row" data-ng-repeat="pod in filteredItems = (pods | nodesFilter:search | orderBy:predicate:reverse) track by pod.id" data-ng-class="{ selected: pod.$selected, 'is-active': pod.$selected && pod.action_failed }">137 <tr class="p-table__row" data-ng-repeat="pod in filteredItems = (pods | nodesFilter:search | orderBy:predicate:reverse) track by pod.id" data-ng-class="{ selected: pod.$selected, 'is-active': pod.$selected && pod.action_failed }">
138 <td class="p-table__cell" aria-label="Name" title="{$ pod.name $}">138 <td class="p-table__cell" aria-label="Name" title="{$ pod.name $}">
139 <div class="u-float--left" data-ng-if="isSuperUser()">139 <div class="u-float--left" data-ng-if="isSuperUser()">
diff --git a/src/maasserver/static/partials/switches-table.html b/src/maasserver/static/partials/switches-table.html
index 371cbba..106a251 100644
--- a/src/maasserver/static/partials/switches-table.html
+++ b/src/maasserver/static/partials/switches-table.html
@@ -22,7 +22,7 @@
22 <th class="u-align--right" role="columnheader" data-ng-click="sortTable('serial')" data-ng-class="{'is-sorted': table.predicate === 'serial', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}">Serial</th>22 <th class="u-align--right" role="columnheader" data-ng-click="sortTable('serial')" data-ng-class="{'is-sorted': table.predicate === 'serial', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}">Serial</th>
23 </tr>23 </tr>
24 </thead>24 </thead>
25 <tbody vs-repeat="{scrollParent: 'window'}">25 <tbody vs-repeat vs-scroll-parent="window">
26 <tr26 <tr
27 data-ng-repeat="node in table.filteredSwitches = (table.switches | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id"27 data-ng-repeat="node in table.filteredSwitches = (table.switches | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id"
28 data-ng-class="{ 'table--error': machineHasError({ $switch_: node }), selected: node.$selected }">28 data-ng-class="{ 'table--error': machineHasError({ $switch_: node }), selected: node.$selected }">
diff --git a/src/maasserver/static/partials/zones-list.html b/src/maasserver/static/partials/zones-list.html
index 921db3d..c35cc5e 100755
--- a/src/maasserver/static/partials/zones-list.html
+++ b/src/maasserver/static/partials/zones-list.html
@@ -54,7 +54,7 @@
54 <th class="u-align--right">Controllers</th>54 <th class="u-align--right">Controllers</th>
55 </tr>55 </tr>
56 </thead>56 </thead>
57 <tbody vs-repeat="{scrollParent: 'window'}">57 <tbody vs-repeat vs-scroll-parent="window">
58 <tr data-ng-repeat="zone in zones">58 <tr data-ng-repeat="zone in zones">
59 <td aria-label="Name" title="{$ zone.name $}">59 <td aria-label="Name" title="{$ zone.name $}">
60 <a href="#/zone/{$ zone.id $}">{$ zone.name $}</a>60 <a href="#/zone/{$ zone.id $}">{$ zone.name $}</a>

Subscribers

People subscribed via source and target branches