UNPKG

2.46 MBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (factory((global.ionicBundle = global.ionicBundle || {})));
5}(this, (function (exports) { 'use strict';
6
7/*! *****************************************************************************
8Copyright (c) Microsoft Corporation. All rights reserved.
9Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10this file except in compliance with the License. You may obtain a copy of the
11License at http://www.apache.org/licenses/LICENSE-2.0
12
13THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16MERCHANTABLITY OR NON-INFRINGEMENT.
17
18See the Apache Version 2.0 License for specific language governing permissions
19and limitations under the License.
20***************************************************************************** */
21/* global Reflect, Promise */
22
23var extendStatics = Object.setPrototypeOf ||
24 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
25 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
26
27function __extends$1(d, b) {
28 extendStatics(d, b);
29 function __() { this.constructor = d; }
30 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
31}
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49function __values(o) {
50 var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
51 if (m) return m.call(o);
52 return {
53 next: function () {
54 if (o && i >= o.length) o = void 0;
55 return { value: o && o[i++], done: !o };
56 }
57 };
58}
59
60function __read(o, n) {
61 var m = typeof Symbol === "function" && o[Symbol.iterator];
62 if (!m) return o;
63 var i = m.call(o), r, ar = [], e;
64 try {
65 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
66 }
67 catch (error) { e = { error: error }; }
68 finally {
69 try {
70 if (r && !r.done && (m = i["return"])) m.call(i);
71 }
72 finally { if (e) throw e.error; }
73 }
74 return ar;
75}
76
77
78
79function __await(v) {
80 return this instanceof __await ? (this.v = v, this) : new __await(v);
81}
82
83var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
84
85
86
87
88
89function createCommonjsModule(fn, module) {
90 return module = { exports: {} }, fn(module, module.exports), module.exports;
91}
92
93// CommonJS / Node have global context exposed as "global" variable.
94// We don't want to include the whole node.d.ts this this compilation unit so we'll just fake
95// the global "global" var for now.
96var __window$1 = typeof window !== 'undefined' && window;
97var __self$1 = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
98 self instanceof WorkerGlobalScope && self;
99var __global$1 = typeof commonjsGlobal !== 'undefined' && commonjsGlobal;
100var _root = __window$1 || __global$1 || __self$1;
101var root_1 = _root;
102// Workaround Closure Compiler restriction: The body of a goog.module cannot use throw.
103// This is needed when used with angular/tsickle which inserts a goog.module statement.
104// Wrap in IIFE
105(function () {
106 if (!_root) {
107 throw new Error('RxJS could not find any global context (window, self, global)');
108 }
109})();
110
111var root = {
112 root: root_1
113};
114
115function isFunction(x) {
116 return typeof x === 'function';
117}
118var isFunction_2 = isFunction;
119
120var isFunction_1 = {
121 isFunction: isFunction_2
122};
123
124var isArray_1 = Array.isArray || (function (x) { return x && typeof x.length === 'number'; });
125
126var isArray = {
127 isArray: isArray_1
128};
129
130function isObject(x) {
131 return x != null && typeof x === 'object';
132}
133var isObject_2 = isObject;
134
135var isObject_1 = {
136 isObject: isObject_2
137};
138
139// typeof any so that it we don't have to cast when comparing a result to the error object
140var errorObject_1 = { e: {} };
141
142var errorObject = {
143 errorObject: errorObject_1
144};
145
146var tryCatchTarget;
147function tryCatcher() {
148 try {
149 return tryCatchTarget.apply(this, arguments);
150 }
151 catch (e) {
152 errorObject.errorObject.e = e;
153 return errorObject.errorObject;
154 }
155}
156function tryCatch(fn) {
157 tryCatchTarget = fn;
158 return tryCatcher;
159}
160var tryCatch_2 = tryCatch;
161
162
163var tryCatch_1 = {
164 tryCatch: tryCatch_2
165};
166
167var __extends$3 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
168 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
169 function __() { this.constructor = d; }
170 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
171};
172/**
173 * An error thrown when one or more errors have occurred during the
174 * `unsubscribe` of a {@link Subscription}.
175 */
176var UnsubscriptionError = (function (_super) {
177 __extends$3(UnsubscriptionError, _super);
178 function UnsubscriptionError(errors) {
179 _super.call(this);
180 this.errors = errors;
181 var err = Error.call(this, errors ?
182 errors.length + " errors occurred during unsubscription:\n " + errors.map(function (err, i) { return ((i + 1) + ") " + err.toString()); }).join('\n ') : '');
183 this.name = err.name = 'UnsubscriptionError';
184 this.stack = err.stack;
185 this.message = err.message;
186 }
187 return UnsubscriptionError;
188}(Error));
189var UnsubscriptionError_2 = UnsubscriptionError;
190
191var UnsubscriptionError_1 = {
192 UnsubscriptionError: UnsubscriptionError_2
193};
194
195/**
196 * Represents a disposable resource, such as the execution of an Observable. A
197 * Subscription has one important method, `unsubscribe`, that takes no argument
198 * and just disposes the resource held by the subscription.
199 *
200 * Additionally, subscriptions may be grouped together through the `add()`
201 * method, which will attach a child Subscription to the current Subscription.
202 * When a Subscription is unsubscribed, all its children (and its grandchildren)
203 * will be unsubscribed as well.
204 *
205 * @class Subscription
206 */
207var Subscription = (function () {
208 /**
209 * @param {function(): void} [unsubscribe] A function describing how to
210 * perform the disposal of resources when the `unsubscribe` method is called.
211 */
212 function Subscription(unsubscribe) {
213 /**
214 * A flag to indicate whether this Subscription has already been unsubscribed.
215 * @type {boolean}
216 */
217 this.closed = false;
218 this._parent = null;
219 this._parents = null;
220 this._subscriptions = null;
221 if (unsubscribe) {
222 this._unsubscribe = unsubscribe;
223 }
224 }
225 /**
226 * Disposes the resources held by the subscription. May, for instance, cancel
227 * an ongoing Observable execution or cancel any other type of work that
228 * started when the Subscription was created.
229 * @return {void}
230 */
231 Subscription.prototype.unsubscribe = function () {
232 var hasErrors = false;
233 var errors;
234 if (this.closed) {
235 return;
236 }
237 var _a = this, _parent = _a._parent, _parents = _a._parents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions;
238 this.closed = true;
239 this._parent = null;
240 this._parents = null;
241 // null out _subscriptions first so any child subscriptions that attempt
242 // to remove themselves from this subscription will noop
243 this._subscriptions = null;
244 var index = -1;
245 var len = _parents ? _parents.length : 0;
246 // if this._parent is null, then so is this._parents, and we
247 // don't have to remove ourselves from any parent subscriptions.
248 while (_parent) {
249 _parent.remove(this);
250 // if this._parents is null or index >= len,
251 // then _parent is set to null, and the loop exits
252 _parent = ++index < len && _parents[index] || null;
253 }
254 if (isFunction_1.isFunction(_unsubscribe)) {
255 var trial = tryCatch_1.tryCatch(_unsubscribe).call(this);
256 if (trial === errorObject.errorObject) {
257 hasErrors = true;
258 errors = errors || (errorObject.errorObject.e instanceof UnsubscriptionError_1.UnsubscriptionError ?
259 flattenUnsubscriptionErrors(errorObject.errorObject.e.errors) : [errorObject.errorObject.e]);
260 }
261 }
262 if (isArray.isArray(_subscriptions)) {
263 index = -1;
264 len = _subscriptions.length;
265 while (++index < len) {
266 var sub = _subscriptions[index];
267 if (isObject_1.isObject(sub)) {
268 var trial = tryCatch_1.tryCatch(sub.unsubscribe).call(sub);
269 if (trial === errorObject.errorObject) {
270 hasErrors = true;
271 errors = errors || [];
272 var err = errorObject.errorObject.e;
273 if (err instanceof UnsubscriptionError_1.UnsubscriptionError) {
274 errors = errors.concat(flattenUnsubscriptionErrors(err.errors));
275 }
276 else {
277 errors.push(err);
278 }
279 }
280 }
281 }
282 }
283 if (hasErrors) {
284 throw new UnsubscriptionError_1.UnsubscriptionError(errors);
285 }
286 };
287 /**
288 * Adds a tear down to be called during the unsubscribe() of this
289 * Subscription.
290 *
291 * If the tear down being added is a subscription that is already
292 * unsubscribed, is the same reference `add` is being called on, or is
293 * `Subscription.EMPTY`, it will not be added.
294 *
295 * If this subscription is already in an `closed` state, the passed
296 * tear down logic will be executed immediately.
297 *
298 * @param {TeardownLogic} teardown The additional logic to execute on
299 * teardown.
300 * @return {Subscription} Returns the Subscription used or created to be
301 * added to the inner subscriptions list. This Subscription can be used with
302 * `remove()` to remove the passed teardown logic from the inner subscriptions
303 * list.
304 */
305 Subscription.prototype.add = function (teardown) {
306 if (!teardown || (teardown === Subscription.EMPTY)) {
307 return Subscription.EMPTY;
308 }
309 if (teardown === this) {
310 return this;
311 }
312 var subscription = teardown;
313 switch (typeof teardown) {
314 case 'function':
315 subscription = new Subscription(teardown);
316 case 'object':
317 if (subscription.closed || typeof subscription.unsubscribe !== 'function') {
318 return subscription;
319 }
320 else if (this.closed) {
321 subscription.unsubscribe();
322 return subscription;
323 }
324 else if (typeof subscription._addParent !== 'function' /* quack quack */) {
325 var tmp = subscription;
326 subscription = new Subscription();
327 subscription._subscriptions = [tmp];
328 }
329 break;
330 default:
331 throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
332 }
333 var subscriptions = this._subscriptions || (this._subscriptions = []);
334 subscriptions.push(subscription);
335 subscription._addParent(this);
336 return subscription;
337 };
338 /**
339 * Removes a Subscription from the internal list of subscriptions that will
340 * unsubscribe during the unsubscribe process of this Subscription.
341 * @param {Subscription} subscription The subscription to remove.
342 * @return {void}
343 */
344 Subscription.prototype.remove = function (subscription) {
345 var subscriptions = this._subscriptions;
346 if (subscriptions) {
347 var subscriptionIndex = subscriptions.indexOf(subscription);
348 if (subscriptionIndex !== -1) {
349 subscriptions.splice(subscriptionIndex, 1);
350 }
351 }
352 };
353 Subscription.prototype._addParent = function (parent) {
354 var _a = this, _parent = _a._parent, _parents = _a._parents;
355 if (!_parent || _parent === parent) {
356 // If we don't have a parent, or the new parent is the same as the
357 // current parent, then set this._parent to the new parent.
358 this._parent = parent;
359 }
360 else if (!_parents) {
361 // If there's already one parent, but not multiple, allocate an Array to
362 // store the rest of the parent Subscriptions.
363 this._parents = [parent];
364 }
365 else if (_parents.indexOf(parent) === -1) {
366 // Only add the new parent to the _parents list if it's not already there.
367 _parents.push(parent);
368 }
369 };
370 Subscription.EMPTY = (function (empty) {
371 empty.closed = true;
372 return empty;
373 }(new Subscription()));
374 return Subscription;
375}());
376var Subscription_2 = Subscription;
377function flattenUnsubscriptionErrors(errors) {
378 return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError_1.UnsubscriptionError) ? err.errors : err); }, []);
379}
380
381var Subscription_1 = {
382 Subscription: Subscription_2
383};
384
385var empty = {
386 closed: true,
387 next: function (value) { },
388 error: function (err) { throw err; },
389 complete: function () { }
390};
391
392var Observer = {
393 empty: empty
394};
395
396var rxSubscriber = createCommonjsModule(function (module, exports) {
397"use strict";
398
399var Symbol = root.root.Symbol;
400exports.rxSubscriber = (typeof Symbol === 'function' && typeof Symbol.for === 'function') ?
401 Symbol.for('rxSubscriber') : '@@rxSubscriber';
402/**
403 * @deprecated use rxSubscriber instead
404 */
405exports.$$rxSubscriber = exports.rxSubscriber;
406});
407
408var __extends$2 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
409 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
410 function __() { this.constructor = d; }
411 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
412};
413
414
415
416
417/**
418 * Implements the {@link Observer} interface and extends the
419 * {@link Subscription} class. While the {@link Observer} is the public API for
420 * consuming the values of an {@link Observable}, all Observers get converted to
421 * a Subscriber, in order to provide Subscription-like capabilities such as
422 * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for
423 * implementing operators, but it is rarely used as a public API.
424 *
425 * @class Subscriber<T>
426 */
427var Subscriber = (function (_super) {
428 __extends$2(Subscriber, _super);
429 /**
430 * @param {Observer|function(value: T): void} [destinationOrNext] A partially
431 * defined Observer or a `next` callback function.
432 * @param {function(e: ?any): void} [error] The `error` callback of an
433 * Observer.
434 * @param {function(): void} [complete] The `complete` callback of an
435 * Observer.
436 */
437 function Subscriber(destinationOrNext, error, complete) {
438 _super.call(this);
439 this.syncErrorValue = null;
440 this.syncErrorThrown = false;
441 this.syncErrorThrowable = false;
442 this.isStopped = false;
443 switch (arguments.length) {
444 case 0:
445 this.destination = Observer.empty;
446 break;
447 case 1:
448 if (!destinationOrNext) {
449 this.destination = Observer.empty;
450 break;
451 }
452 if (typeof destinationOrNext === 'object') {
453 if (destinationOrNext instanceof Subscriber) {
454 this.destination = destinationOrNext;
455 this.destination.add(this);
456 }
457 else {
458 this.syncErrorThrowable = true;
459 this.destination = new SafeSubscriber(this, destinationOrNext);
460 }
461 break;
462 }
463 default:
464 this.syncErrorThrowable = true;
465 this.destination = new SafeSubscriber(this, destinationOrNext, error, complete);
466 break;
467 }
468 }
469 Subscriber.prototype[rxSubscriber.rxSubscriber] = function () { return this; };
470 /**
471 * A static factory for a Subscriber, given a (potentially partial) definition
472 * of an Observer.
473 * @param {function(x: ?T): void} [next] The `next` callback of an Observer.
474 * @param {function(e: ?any): void} [error] The `error` callback of an
475 * Observer.
476 * @param {function(): void} [complete] The `complete` callback of an
477 * Observer.
478 * @return {Subscriber<T>} A Subscriber wrapping the (partially defined)
479 * Observer represented by the given arguments.
480 */
481 Subscriber.create = function (next, error, complete) {
482 var subscriber = new Subscriber(next, error, complete);
483 subscriber.syncErrorThrowable = false;
484 return subscriber;
485 };
486 /**
487 * The {@link Observer} callback to receive notifications of type `next` from
488 * the Observable, with a value. The Observable may call this method 0 or more
489 * times.
490 * @param {T} [value] The `next` value.
491 * @return {void}
492 */
493 Subscriber.prototype.next = function (value) {
494 if (!this.isStopped) {
495 this._next(value);
496 }
497 };
498 /**
499 * The {@link Observer} callback to receive notifications of type `error` from
500 * the Observable, with an attached {@link Error}. Notifies the Observer that
501 * the Observable has experienced an error condition.
502 * @param {any} [err] The `error` exception.
503 * @return {void}
504 */
505 Subscriber.prototype.error = function (err) {
506 if (!this.isStopped) {
507 this.isStopped = true;
508 this._error(err);
509 }
510 };
511 /**
512 * The {@link Observer} callback to receive a valueless notification of type
513 * `complete` from the Observable. Notifies the Observer that the Observable
514 * has finished sending push-based notifications.
515 * @return {void}
516 */
517 Subscriber.prototype.complete = function () {
518 if (!this.isStopped) {
519 this.isStopped = true;
520 this._complete();
521 }
522 };
523 Subscriber.prototype.unsubscribe = function () {
524 if (this.closed) {
525 return;
526 }
527 this.isStopped = true;
528 _super.prototype.unsubscribe.call(this);
529 };
530 Subscriber.prototype._next = function (value) {
531 this.destination.next(value);
532 };
533 Subscriber.prototype._error = function (err) {
534 this.destination.error(err);
535 this.unsubscribe();
536 };
537 Subscriber.prototype._complete = function () {
538 this.destination.complete();
539 this.unsubscribe();
540 };
541 Subscriber.prototype._unsubscribeAndRecycle = function () {
542 var _a = this, _parent = _a._parent, _parents = _a._parents;
543 this._parent = null;
544 this._parents = null;
545 this.unsubscribe();
546 this.closed = false;
547 this.isStopped = false;
548 this._parent = _parent;
549 this._parents = _parents;
550 return this;
551 };
552 return Subscriber;
553}(Subscription_1.Subscription));
554var Subscriber_2 = Subscriber;
555/**
556 * We need this JSDoc comment for affecting ESDoc.
557 * @ignore
558 * @extends {Ignored}
559 */
560var SafeSubscriber = (function (_super) {
561 __extends$2(SafeSubscriber, _super);
562 function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) {
563 _super.call(this);
564 this._parentSubscriber = _parentSubscriber;
565 var next;
566 var context = this;
567 if (isFunction_1.isFunction(observerOrNext)) {
568 next = observerOrNext;
569 }
570 else if (observerOrNext) {
571 next = observerOrNext.next;
572 error = observerOrNext.error;
573 complete = observerOrNext.complete;
574 if (observerOrNext !== Observer.empty) {
575 context = Object.create(observerOrNext);
576 if (isFunction_1.isFunction(context.unsubscribe)) {
577 this.add(context.unsubscribe.bind(context));
578 }
579 context.unsubscribe = this.unsubscribe.bind(this);
580 }
581 }
582 this._context = context;
583 this._next = next;
584 this._error = error;
585 this._complete = complete;
586 }
587 SafeSubscriber.prototype.next = function (value) {
588 if (!this.isStopped && this._next) {
589 var _parentSubscriber = this._parentSubscriber;
590 if (!_parentSubscriber.syncErrorThrowable) {
591 this.__tryOrUnsub(this._next, value);
592 }
593 else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) {
594 this.unsubscribe();
595 }
596 }
597 };
598 SafeSubscriber.prototype.error = function (err) {
599 if (!this.isStopped) {
600 var _parentSubscriber = this._parentSubscriber;
601 if (this._error) {
602 if (!_parentSubscriber.syncErrorThrowable) {
603 this.__tryOrUnsub(this._error, err);
604 this.unsubscribe();
605 }
606 else {
607 this.__tryOrSetError(_parentSubscriber, this._error, err);
608 this.unsubscribe();
609 }
610 }
611 else if (!_parentSubscriber.syncErrorThrowable) {
612 this.unsubscribe();
613 throw err;
614 }
615 else {
616 _parentSubscriber.syncErrorValue = err;
617 _parentSubscriber.syncErrorThrown = true;
618 this.unsubscribe();
619 }
620 }
621 };
622 SafeSubscriber.prototype.complete = function () {
623 var _this = this;
624 if (!this.isStopped) {
625 var _parentSubscriber = this._parentSubscriber;
626 if (this._complete) {
627 var wrappedComplete = function () { return _this._complete.call(_this._context); };
628 if (!_parentSubscriber.syncErrorThrowable) {
629 this.__tryOrUnsub(wrappedComplete);
630 this.unsubscribe();
631 }
632 else {
633 this.__tryOrSetError(_parentSubscriber, wrappedComplete);
634 this.unsubscribe();
635 }
636 }
637 else {
638 this.unsubscribe();
639 }
640 }
641 };
642 SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
643 try {
644 fn.call(this._context, value);
645 }
646 catch (err) {
647 this.unsubscribe();
648 throw err;
649 }
650 };
651 SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) {
652 try {
653 fn.call(this._context, value);
654 }
655 catch (err) {
656 parent.syncErrorValue = err;
657 parent.syncErrorThrown = true;
658 return true;
659 }
660 return false;
661 };
662 SafeSubscriber.prototype._unsubscribe = function () {
663 var _parentSubscriber = this._parentSubscriber;
664 this._context = null;
665 this._parentSubscriber = null;
666 _parentSubscriber.unsubscribe();
667 };
668 return SafeSubscriber;
669}(Subscriber));
670
671var Subscriber_1 = {
672 Subscriber: Subscriber_2
673};
674
675function toSubscriber(nextOrObserver, error, complete) {
676 if (nextOrObserver) {
677 if (nextOrObserver instanceof Subscriber_1.Subscriber) {
678 return nextOrObserver;
679 }
680 if (nextOrObserver[rxSubscriber.rxSubscriber]) {
681 return nextOrObserver[rxSubscriber.rxSubscriber]();
682 }
683 }
684 if (!nextOrObserver && !error && !complete) {
685 return new Subscriber_1.Subscriber(Observer.empty);
686 }
687 return new Subscriber_1.Subscriber(nextOrObserver, error, complete);
688}
689var toSubscriber_2 = toSubscriber;
690
691var toSubscriber_1 = {
692 toSubscriber: toSubscriber_2
693};
694
695var observable = createCommonjsModule(function (module, exports) {
696"use strict";
697
698function getSymbolObservable(context) {
699 var $$observable;
700 var Symbol = context.Symbol;
701 if (typeof Symbol === 'function') {
702 if (Symbol.observable) {
703 $$observable = Symbol.observable;
704 }
705 else {
706 $$observable = Symbol('observable');
707 Symbol.observable = $$observable;
708 }
709 }
710 else {
711 $$observable = '@@observable';
712 }
713 return $$observable;
714}
715exports.getSymbolObservable = getSymbolObservable;
716exports.observable = getSymbolObservable(root.root);
717/**
718 * @deprecated use observable instead
719 */
720exports.$$observable = exports.observable;
721});
722
723/**
724 * A representation of any set of values over any amount of time. This is the most basic building block
725 * of RxJS.
726 *
727 * @class Observable<T>
728 */
729var Observable = (function () {
730 /**
731 * @constructor
732 * @param {Function} subscribe the function that is called when the Observable is
733 * initially subscribed to. This function is given a Subscriber, to which new values
734 * can be `next`ed, or an `error` method can be called to raise an error, or
735 * `complete` can be called to notify of a successful completion.
736 */
737 function Observable(subscribe) {
738 this._isScalar = false;
739 if (subscribe) {
740 this._subscribe = subscribe;
741 }
742 }
743 /**
744 * Creates a new Observable, with this Observable as the source, and the passed
745 * operator defined as the new observable's operator.
746 * @method lift
747 * @param {Operator} operator the operator defining the operation to take on the observable
748 * @return {Observable} a new observable with the Operator applied
749 */
750 Observable.prototype.lift = function (operator) {
751 var observable$$1 = new Observable();
752 observable$$1.source = this;
753 observable$$1.operator = operator;
754 return observable$$1;
755 };
756 /**
757 * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.
758 *
759 * <span class="informal">Use it when you have all these Observables, but still nothing is happening.</span>
760 *
761 * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It
762 * might be for example a function that you passed to a {@link create} static factory, but most of the time it is
763 * a library implementation, which defines what and when will be emitted by an Observable. This means that calling
764 * `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often
765 * thought.
766 *
767 * Apart from starting the execution of an Observable, this method allows you to listen for values
768 * that an Observable emits, as well as for when it completes or errors. You can achieve this in two
769 * following ways.
770 *
771 * The first way is creating an object that implements {@link Observer} interface. It should have methods
772 * defined by that interface, but note that it should be just a regular JavaScript object, which you can create
773 * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular do
774 * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also
775 * that your object does not have to implement all methods. If you find yourself creating a method that doesn't
776 * do anything, you can simply omit it. Note however, that if `error` method is not provided, all errors will
777 * be left uncaught.
778 *
779 * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.
780 * This means you can provide three functions as arguments to `subscribe`, where first function is equivalent
781 * of a `next` method, second of an `error` method and third of a `complete` method. Just as in case of Observer,
782 * if you do not need to listen for something, you can omit a function, preferably by passing `undefined` or `null`,
783 * since `subscribe` recognizes these functions by where they were placed in function call. When it comes
784 * to `error` function, just as before, if not provided, errors emitted by an Observable will be thrown.
785 *
786 * Whatever style of calling `subscribe` you use, in both cases it returns a Subscription object.
787 * This object allows you to call `unsubscribe` on it, which in turn will stop work that an Observable does and will clean
788 * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback
789 * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.
790 *
791 * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.
792 * It is an Observable itself that decides when these functions will be called. For example {@link of}
793 * by default emits all its values synchronously. Always check documentation for how given Observable
794 * will behave when subscribed and if its default behavior can be modified with a {@link Scheduler}.
795 *
796 * @example <caption>Subscribe with an Observer</caption>
797 * const sumObserver = {
798 * sum: 0,
799 * next(value) {
800 * console.log('Adding: ' + value);
801 * this.sum = this.sum + value;
802 * },
803 * error() { // We actually could just remove this method,
804 * }, // since we do not really care about errors right now.
805 * complete() {
806 * console.log('Sum equals: ' + this.sum);
807 * }
808 * };
809 *
810 * Rx.Observable.of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.
811 * .subscribe(sumObserver);
812 *
813 * // Logs:
814 * // "Adding: 1"
815 * // "Adding: 2"
816 * // "Adding: 3"
817 * // "Sum equals: 6"
818 *
819 *
820 * @example <caption>Subscribe with functions</caption>
821 * let sum = 0;
822 *
823 * Rx.Observable.of(1, 2, 3)
824 * .subscribe(
825 * function(value) {
826 * console.log('Adding: ' + value);
827 * sum = sum + value;
828 * },
829 * undefined,
830 * function() {
831 * console.log('Sum equals: ' + sum);
832 * }
833 * );
834 *
835 * // Logs:
836 * // "Adding: 1"
837 * // "Adding: 2"
838 * // "Adding: 3"
839 * // "Sum equals: 6"
840 *
841 *
842 * @example <caption>Cancel a subscription</caption>
843 * const subscription = Rx.Observable.interval(1000).subscribe(
844 * num => console.log(num),
845 * undefined,
846 * () => console.log('completed!') // Will not be called, even
847 * ); // when cancelling subscription
848 *
849 *
850 * setTimeout(() => {
851 * subscription.unsubscribe();
852 * console.log('unsubscribed!');
853 * }, 2500);
854 *
855 * // Logs:
856 * // 0 after 1s
857 * // 1 after 2s
858 * // "unsubscribed!" after 2.5s
859 *
860 *
861 * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,
862 * or the first of three possible handlers, which is the handler for each value emitted from the subscribed
863 * Observable.
864 * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,
865 * the error will be thrown as unhandled.
866 * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.
867 * @return {ISubscription} a subscription reference to the registered handlers
868 * @method subscribe
869 */
870 Observable.prototype.subscribe = function (observerOrNext, error, complete) {
871 var operator = this.operator;
872 var sink = toSubscriber_1.toSubscriber(observerOrNext, error, complete);
873 if (operator) {
874 operator.call(sink, this.source);
875 }
876 else {
877 sink.add(this.source ? this._subscribe(sink) : this._trySubscribe(sink));
878 }
879 if (sink.syncErrorThrowable) {
880 sink.syncErrorThrowable = false;
881 if (sink.syncErrorThrown) {
882 throw sink.syncErrorValue;
883 }
884 }
885 return sink;
886 };
887 Observable.prototype._trySubscribe = function (sink) {
888 try {
889 return this._subscribe(sink);
890 }
891 catch (err) {
892 sink.syncErrorThrown = true;
893 sink.syncErrorValue = err;
894 sink.error(err);
895 }
896 };
897 /**
898 * @method forEach
899 * @param {Function} next a handler for each value emitted by the observable
900 * @param {PromiseConstructor} [PromiseCtor] a constructor function used to instantiate the Promise
901 * @return {Promise} a promise that either resolves on observable completion or
902 * rejects with the handled error
903 */
904 Observable.prototype.forEach = function (next, PromiseCtor) {
905 var _this = this;
906 if (!PromiseCtor) {
907 if (root.root.Rx && root.root.Rx.config && root.root.Rx.config.Promise) {
908 PromiseCtor = root.root.Rx.config.Promise;
909 }
910 else if (root.root.Promise) {
911 PromiseCtor = root.root.Promise;
912 }
913 }
914 if (!PromiseCtor) {
915 throw new Error('no Promise impl found');
916 }
917 return new PromiseCtor(function (resolve, reject) {
918 // Must be declared in a separate statement to avoid a RefernceError when
919 // accessing subscription below in the closure due to Temporal Dead Zone.
920 var subscription;
921 subscription = _this.subscribe(function (value) {
922 if (subscription) {
923 // if there is a subscription, then we can surmise
924 // the next handling is asynchronous. Any errors thrown
925 // need to be rejected explicitly and unsubscribe must be
926 // called manually
927 try {
928 next(value);
929 }
930 catch (err) {
931 reject(err);
932 subscription.unsubscribe();
933 }
934 }
935 else {
936 // if there is NO subscription, then we're getting a nexted
937 // value synchronously during subscription. We can just call it.
938 // If it errors, Observable's `subscribe` will ensure the
939 // unsubscription logic is called, then synchronously rethrow the error.
940 // After that, Promise will trap the error and send it
941 // down the rejection path.
942 next(value);
943 }
944 }, reject, resolve);
945 });
946 };
947 Observable.prototype._subscribe = function (subscriber) {
948 return this.source.subscribe(subscriber);
949 };
950 /**
951 * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable
952 * @method Symbol.observable
953 * @return {Observable} this instance of the observable
954 */
955 Observable.prototype[observable.observable] = function () {
956 return this;
957 };
958 // HACK: Since TypeScript inherits static properties too, we have to
959 // fight against TypeScript here so Subject can have a different static create signature
960 /**
961 * Creates a new cold Observable by calling the Observable constructor
962 * @static true
963 * @owner Observable
964 * @method create
965 * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor
966 * @return {Observable} a new cold observable
967 */
968 Observable.create = function (subscribe) {
969 return new Observable(subscribe);
970 };
971 return Observable;
972}());
973var Observable_2 = Observable;
974
975var Observable_1 = {
976 Observable: Observable_2
977};
978
979var __extends$5 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
980 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
981 function __() { this.constructor = d; }
982 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
983};
984
985/**
986 * We need this JSDoc comment for affecting ESDoc.
987 * @extends {Ignored}
988 * @hide true
989 */
990var ScalarObservable = (function (_super) {
991 __extends$5(ScalarObservable, _super);
992 function ScalarObservable(value, scheduler) {
993 _super.call(this);
994 this.value = value;
995 this.scheduler = scheduler;
996 this._isScalar = true;
997 if (scheduler) {
998 this._isScalar = false;
999 }
1000 }
1001 ScalarObservable.create = function (value, scheduler) {
1002 return new ScalarObservable(value, scheduler);
1003 };
1004 ScalarObservable.dispatch = function (state) {
1005 var done = state.done, value = state.value, subscriber = state.subscriber;
1006 if (done) {
1007 subscriber.complete();
1008 return;
1009 }
1010 subscriber.next(value);
1011 if (subscriber.closed) {
1012 return;
1013 }
1014 state.done = true;
1015 this.schedule(state);
1016 };
1017 ScalarObservable.prototype._subscribe = function (subscriber) {
1018 var value = this.value;
1019 var scheduler = this.scheduler;
1020 if (scheduler) {
1021 return scheduler.schedule(ScalarObservable.dispatch, 0, {
1022 done: false, value: value, subscriber: subscriber
1023 });
1024 }
1025 else {
1026 subscriber.next(value);
1027 if (!subscriber.closed) {
1028 subscriber.complete();
1029 }
1030 }
1031 };
1032 return ScalarObservable;
1033}(Observable_1.Observable));
1034var ScalarObservable_2 = ScalarObservable;
1035
1036var ScalarObservable_1 = {
1037 ScalarObservable: ScalarObservable_2
1038};
1039
1040var __extends$6 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1041 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1042 function __() { this.constructor = d; }
1043 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1044};
1045
1046/**
1047 * We need this JSDoc comment for affecting ESDoc.
1048 * @extends {Ignored}
1049 * @hide true
1050 */
1051var EmptyObservable = (function (_super) {
1052 __extends$6(EmptyObservable, _super);
1053 function EmptyObservable(scheduler) {
1054 _super.call(this);
1055 this.scheduler = scheduler;
1056 }
1057 /**
1058 * Creates an Observable that emits no items to the Observer and immediately
1059 * emits a complete notification.
1060 *
1061 * <span class="informal">Just emits 'complete', and nothing else.
1062 * </span>
1063 *
1064 * <img src="./img/empty.png" width="100%">
1065 *
1066 * This static operator is useful for creating a simple Observable that only
1067 * emits the complete notification. It can be used for composing with other
1068 * Observables, such as in a {@link mergeMap}.
1069 *
1070 * @example <caption>Emit the number 7, then complete.</caption>
1071 * var result = Rx.Observable.empty().startWith(7);
1072 * result.subscribe(x => console.log(x));
1073 *
1074 * @example <caption>Map and flatten only odd numbers to the sequence 'a', 'b', 'c'</caption>
1075 * var interval = Rx.Observable.interval(1000);
1076 * var result = interval.mergeMap(x =>
1077 * x % 2 === 1 ? Rx.Observable.of('a', 'b', 'c') : Rx.Observable.empty()
1078 * );
1079 * result.subscribe(x => console.log(x));
1080 *
1081 * // Results in the following to the console:
1082 * // x is equal to the count on the interval eg(0,1,2,3,...)
1083 * // x will occur every 1000ms
1084 * // if x % 2 is equal to 1 print abc
1085 * // if x % 2 is not equal to 1 nothing will be output
1086 *
1087 * @see {@link create}
1088 * @see {@link never}
1089 * @see {@link of}
1090 * @see {@link throw}
1091 *
1092 * @param {Scheduler} [scheduler] A {@link IScheduler} to use for scheduling
1093 * the emission of the complete notification.
1094 * @return {Observable} An "empty" Observable: emits only the complete
1095 * notification.
1096 * @static true
1097 * @name empty
1098 * @owner Observable
1099 */
1100 EmptyObservable.create = function (scheduler) {
1101 return new EmptyObservable(scheduler);
1102 };
1103 EmptyObservable.dispatch = function (arg) {
1104 var subscriber = arg.subscriber;
1105 subscriber.complete();
1106 };
1107 EmptyObservable.prototype._subscribe = function (subscriber) {
1108 var scheduler = this.scheduler;
1109 if (scheduler) {
1110 return scheduler.schedule(EmptyObservable.dispatch, 0, { subscriber: subscriber });
1111 }
1112 else {
1113 subscriber.complete();
1114 }
1115 };
1116 return EmptyObservable;
1117}(Observable_1.Observable));
1118var EmptyObservable_2 = EmptyObservable;
1119
1120var EmptyObservable_1 = {
1121 EmptyObservable: EmptyObservable_2
1122};
1123
1124function isScheduler(value) {
1125 return value && typeof value.schedule === 'function';
1126}
1127var isScheduler_2 = isScheduler;
1128
1129var isScheduler_1 = {
1130 isScheduler: isScheduler_2
1131};
1132
1133var __extends$4 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1134 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1135 function __() { this.constructor = d; }
1136 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1137};
1138
1139
1140
1141
1142/**
1143 * We need this JSDoc comment for affecting ESDoc.
1144 * @extends {Ignored}
1145 * @hide true
1146 */
1147var ArrayObservable = (function (_super) {
1148 __extends$4(ArrayObservable, _super);
1149 function ArrayObservable(array, scheduler) {
1150 _super.call(this);
1151 this.array = array;
1152 this.scheduler = scheduler;
1153 if (!scheduler && array.length === 1) {
1154 this._isScalar = true;
1155 this.value = array[0];
1156 }
1157 }
1158 ArrayObservable.create = function (array, scheduler) {
1159 return new ArrayObservable(array, scheduler);
1160 };
1161 /**
1162 * Creates an Observable that emits some values you specify as arguments,
1163 * immediately one after the other, and then emits a complete notification.
1164 *
1165 * <span class="informal">Emits the arguments you provide, then completes.
1166 * </span>
1167 *
1168 * <img src="./img/of.png" width="100%">
1169 *
1170 * This static operator is useful for creating a simple Observable that only
1171 * emits the arguments given, and the complete notification thereafter. It can
1172 * be used for composing with other Observables, such as with {@link concat}.
1173 * By default, it uses a `null` IScheduler, which means the `next`
1174 * notifications are sent synchronously, although with a different IScheduler
1175 * it is possible to determine when those notifications will be delivered.
1176 *
1177 * @example <caption>Emit 10, 20, 30, then 'a', 'b', 'c', then start ticking every second.</caption>
1178 * var numbers = Rx.Observable.of(10, 20, 30);
1179 * var letters = Rx.Observable.of('a', 'b', 'c');
1180 * var interval = Rx.Observable.interval(1000);
1181 * var result = numbers.concat(letters).concat(interval);
1182 * result.subscribe(x => console.log(x));
1183 *
1184 * @see {@link create}
1185 * @see {@link empty}
1186 * @see {@link never}
1187 * @see {@link throw}
1188 *
1189 * @param {...T} values Arguments that represent `next` values to be emitted.
1190 * @param {Scheduler} [scheduler] A {@link IScheduler} to use for scheduling
1191 * the emissions of the `next` notifications.
1192 * @return {Observable<T>} An Observable that emits each given input value.
1193 * @static true
1194 * @name of
1195 * @owner Observable
1196 */
1197 ArrayObservable.of = function () {
1198 var array = [];
1199 for (var _i = 0; _i < arguments.length; _i++) {
1200 array[_i - 0] = arguments[_i];
1201 }
1202 var scheduler = array[array.length - 1];
1203 if (isScheduler_1.isScheduler(scheduler)) {
1204 array.pop();
1205 }
1206 else {
1207 scheduler = null;
1208 }
1209 var len = array.length;
1210 if (len > 1) {
1211 return new ArrayObservable(array, scheduler);
1212 }
1213 else if (len === 1) {
1214 return new ScalarObservable_1.ScalarObservable(array[0], scheduler);
1215 }
1216 else {
1217 return new EmptyObservable_1.EmptyObservable(scheduler);
1218 }
1219 };
1220 ArrayObservable.dispatch = function (state) {
1221 var array = state.array, index = state.index, count = state.count, subscriber = state.subscriber;
1222 if (index >= count) {
1223 subscriber.complete();
1224 return;
1225 }
1226 subscriber.next(array[index]);
1227 if (subscriber.closed) {
1228 return;
1229 }
1230 state.index = index + 1;
1231 this.schedule(state);
1232 };
1233 ArrayObservable.prototype._subscribe = function (subscriber) {
1234 var index = 0;
1235 var array = this.array;
1236 var count = array.length;
1237 var scheduler = this.scheduler;
1238 if (scheduler) {
1239 return scheduler.schedule(ArrayObservable.dispatch, 0, {
1240 array: array, index: index, count: count, subscriber: subscriber
1241 });
1242 }
1243 else {
1244 for (var i = 0; i < count && !subscriber.closed; i++) {
1245 subscriber.next(array[i]);
1246 }
1247 subscriber.complete();
1248 }
1249 };
1250 return ArrayObservable;
1251}(Observable_1.Observable));
1252var ArrayObservable_2 = ArrayObservable;
1253
1254var ArrayObservable_1 = {
1255 ArrayObservable: ArrayObservable_2
1256};
1257
1258var __extends$8 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1259 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1260 function __() { this.constructor = d; }
1261 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1262};
1263
1264/**
1265 * We need this JSDoc comment for affecting ESDoc.
1266 * @ignore
1267 * @extends {Ignored}
1268 */
1269var OuterSubscriber = (function (_super) {
1270 __extends$8(OuterSubscriber, _super);
1271 function OuterSubscriber() {
1272 _super.apply(this, arguments);
1273 }
1274 OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
1275 this.destination.next(innerValue);
1276 };
1277 OuterSubscriber.prototype.notifyError = function (error, innerSub) {
1278 this.destination.error(error);
1279 };
1280 OuterSubscriber.prototype.notifyComplete = function (innerSub) {
1281 this.destination.complete();
1282 };
1283 return OuterSubscriber;
1284}(Subscriber_1.Subscriber));
1285var OuterSubscriber_2 = OuterSubscriber;
1286
1287var OuterSubscriber_1 = {
1288 OuterSubscriber: OuterSubscriber_2
1289};
1290
1291var isArrayLike_1 = (function (x) { return x && typeof x.length === 'number'; });
1292
1293var isArrayLike = {
1294 isArrayLike: isArrayLike_1
1295};
1296
1297function isPromise$1(value) {
1298 return value && typeof value.subscribe !== 'function' && typeof value.then === 'function';
1299}
1300var isPromise_2 = isPromise$1;
1301
1302var isPromise_1 = {
1303 isPromise: isPromise_2
1304};
1305
1306var iterator = createCommonjsModule(function (module, exports) {
1307"use strict";
1308
1309function symbolIteratorPonyfill(root$$1) {
1310 var Symbol = root$$1.Symbol;
1311 if (typeof Symbol === 'function') {
1312 if (!Symbol.iterator) {
1313 Symbol.iterator = Symbol('iterator polyfill');
1314 }
1315 return Symbol.iterator;
1316 }
1317 else {
1318 // [for Mozilla Gecko 27-35:](https://mzl.la/2ewE1zC)
1319 var Set_1 = root$$1.Set;
1320 if (Set_1 && typeof new Set_1()['@@iterator'] === 'function') {
1321 return '@@iterator';
1322 }
1323 var Map_1 = root$$1.Map;
1324 // required for compatability with es6-shim
1325 if (Map_1) {
1326 var keys = Object.getOwnPropertyNames(Map_1.prototype);
1327 for (var i = 0; i < keys.length; ++i) {
1328 var key = keys[i];
1329 // according to spec, Map.prototype[@@iterator] and Map.orototype.entries must be equal.
1330 if (key !== 'entries' && key !== 'size' && Map_1.prototype[key] === Map_1.prototype['entries']) {
1331 return key;
1332 }
1333 }
1334 }
1335 return '@@iterator';
1336 }
1337}
1338exports.symbolIteratorPonyfill = symbolIteratorPonyfill;
1339exports.iterator = symbolIteratorPonyfill(root.root);
1340/**
1341 * @deprecated use iterator instead
1342 */
1343exports.$$iterator = exports.iterator;
1344});
1345
1346var __extends$9 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1347 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1348 function __() { this.constructor = d; }
1349 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1350};
1351
1352/**
1353 * We need this JSDoc comment for affecting ESDoc.
1354 * @ignore
1355 * @extends {Ignored}
1356 */
1357var InnerSubscriber = (function (_super) {
1358 __extends$9(InnerSubscriber, _super);
1359 function InnerSubscriber(parent, outerValue, outerIndex) {
1360 _super.call(this);
1361 this.parent = parent;
1362 this.outerValue = outerValue;
1363 this.outerIndex = outerIndex;
1364 this.index = 0;
1365 }
1366 InnerSubscriber.prototype._next = function (value) {
1367 this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);
1368 };
1369 InnerSubscriber.prototype._error = function (error) {
1370 this.parent.notifyError(error, this);
1371 this.unsubscribe();
1372 };
1373 InnerSubscriber.prototype._complete = function () {
1374 this.parent.notifyComplete(this);
1375 this.unsubscribe();
1376 };
1377 return InnerSubscriber;
1378}(Subscriber_1.Subscriber));
1379var InnerSubscriber_2 = InnerSubscriber;
1380
1381var InnerSubscriber_1 = {
1382 InnerSubscriber: InnerSubscriber_2
1383};
1384
1385function subscribeToResult(outerSubscriber, result, outerValue, outerIndex) {
1386 var destination = new InnerSubscriber_1.InnerSubscriber(outerSubscriber, outerValue, outerIndex);
1387 if (destination.closed) {
1388 return null;
1389 }
1390 if (result instanceof Observable_1.Observable) {
1391 if (result._isScalar) {
1392 destination.next(result.value);
1393 destination.complete();
1394 return null;
1395 }
1396 else {
1397 return result.subscribe(destination);
1398 }
1399 }
1400 else if (isArrayLike.isArrayLike(result)) {
1401 for (var i = 0, len = result.length; i < len && !destination.closed; i++) {
1402 destination.next(result[i]);
1403 }
1404 if (!destination.closed) {
1405 destination.complete();
1406 }
1407 }
1408 else if (isPromise_1.isPromise(result)) {
1409 result.then(function (value) {
1410 if (!destination.closed) {
1411 destination.next(value);
1412 destination.complete();
1413 }
1414 }, function (err) { return destination.error(err); })
1415 .then(null, function (err) {
1416 // Escaping the Promise trap: globally throw unhandled errors
1417 root.root.setTimeout(function () { throw err; });
1418 });
1419 return destination;
1420 }
1421 else if (result && typeof result[iterator.iterator] === 'function') {
1422 var iterator$$1 = result[iterator.iterator]();
1423 do {
1424 var item = iterator$$1.next();
1425 if (item.done) {
1426 destination.complete();
1427 break;
1428 }
1429 destination.next(item.value);
1430 if (destination.closed) {
1431 break;
1432 }
1433 } while (true);
1434 }
1435 else if (result && typeof result[observable.observable] === 'function') {
1436 var obs = result[observable.observable]();
1437 if (typeof obs.subscribe !== 'function') {
1438 destination.error(new TypeError('Provided object does not correctly implement Symbol.observable'));
1439 }
1440 else {
1441 return obs.subscribe(new InnerSubscriber_1.InnerSubscriber(outerSubscriber, outerValue, outerIndex));
1442 }
1443 }
1444 else {
1445 var value = isObject_1.isObject(result) ? 'an invalid object' : "'" + result + "'";
1446 var msg = ("You provided " + value + " where a stream was expected.")
1447 + ' You can provide an Observable, Promise, Array, or Iterable.';
1448 destination.error(new TypeError(msg));
1449 }
1450 return null;
1451}
1452var subscribeToResult_2 = subscribeToResult;
1453
1454var subscribeToResult_1 = {
1455 subscribeToResult: subscribeToResult_2
1456};
1457
1458var __extends$7 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1459 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1460 function __() { this.constructor = d; }
1461 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1462};
1463
1464
1465/**
1466 * Converts a higher-order Observable into a first-order Observable which
1467 * concurrently delivers all values that are emitted on the inner Observables.
1468 *
1469 * <span class="informal">Flattens an Observable-of-Observables.</span>
1470 *
1471 * <img src="./img/mergeAll.png" width="100%">
1472 *
1473 * `mergeAll` subscribes to an Observable that emits Observables, also known as
1474 * a higher-order Observable. Each time it observes one of these emitted inner
1475 * Observables, it subscribes to that and delivers all the values from the
1476 * inner Observable on the output Observable. The output Observable only
1477 * completes once all inner Observables have completed. Any error delivered by
1478 * a inner Observable will be immediately emitted on the output Observable.
1479 *
1480 * @example <caption>Spawn a new interval Observable for each click event, and blend their outputs as one Observable</caption>
1481 * var clicks = Rx.Observable.fromEvent(document, 'click');
1482 * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000));
1483 * var firstOrder = higherOrder.mergeAll();
1484 * firstOrder.subscribe(x => console.log(x));
1485 *
1486 * @example <caption>Count from 0 to 9 every second for each click, but only allow 2 concurrent timers</caption>
1487 * var clicks = Rx.Observable.fromEvent(document, 'click');
1488 * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000).take(10));
1489 * var firstOrder = higherOrder.mergeAll(2);
1490 * firstOrder.subscribe(x => console.log(x));
1491 *
1492 * @see {@link combineAll}
1493 * @see {@link concatAll}
1494 * @see {@link exhaust}
1495 * @see {@link merge}
1496 * @see {@link mergeMap}
1497 * @see {@link mergeMapTo}
1498 * @see {@link mergeScan}
1499 * @see {@link switch}
1500 * @see {@link zipAll}
1501 *
1502 * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of inner
1503 * Observables being subscribed to concurrently.
1504 * @return {Observable} An Observable that emits values coming from all the
1505 * inner Observables emitted by the source Observable.
1506 * @method mergeAll
1507 * @owner Observable
1508 */
1509function mergeAll(concurrent) {
1510 if (concurrent === void 0) { concurrent = Number.POSITIVE_INFINITY; }
1511 return this.lift(new MergeAllOperator(concurrent));
1512}
1513var mergeAll_2 = mergeAll;
1514var MergeAllOperator = (function () {
1515 function MergeAllOperator(concurrent) {
1516 this.concurrent = concurrent;
1517 }
1518 MergeAllOperator.prototype.call = function (observer, source) {
1519 return source.subscribe(new MergeAllSubscriber(observer, this.concurrent));
1520 };
1521 return MergeAllOperator;
1522}());
1523var MergeAllOperator_1 = MergeAllOperator;
1524/**
1525 * We need this JSDoc comment for affecting ESDoc.
1526 * @ignore
1527 * @extends {Ignored}
1528 */
1529var MergeAllSubscriber = (function (_super) {
1530 __extends$7(MergeAllSubscriber, _super);
1531 function MergeAllSubscriber(destination, concurrent) {
1532 _super.call(this, destination);
1533 this.concurrent = concurrent;
1534 this.hasCompleted = false;
1535 this.buffer = [];
1536 this.active = 0;
1537 }
1538 MergeAllSubscriber.prototype._next = function (observable) {
1539 if (this.active < this.concurrent) {
1540 this.active++;
1541 this.add(subscribeToResult_1.subscribeToResult(this, observable));
1542 }
1543 else {
1544 this.buffer.push(observable);
1545 }
1546 };
1547 MergeAllSubscriber.prototype._complete = function () {
1548 this.hasCompleted = true;
1549 if (this.active === 0 && this.buffer.length === 0) {
1550 this.destination.complete();
1551 }
1552 };
1553 MergeAllSubscriber.prototype.notifyComplete = function (innerSub) {
1554 var buffer = this.buffer;
1555 this.remove(innerSub);
1556 this.active--;
1557 if (buffer.length > 0) {
1558 this._next(buffer.shift());
1559 }
1560 else if (this.active === 0 && this.hasCompleted) {
1561 this.destination.complete();
1562 }
1563 };
1564 return MergeAllSubscriber;
1565}(OuterSubscriber_1.OuterSubscriber));
1566var MergeAllSubscriber_1 = MergeAllSubscriber;
1567
1568var mergeAll_1 = {
1569 mergeAll: mergeAll_2,
1570 MergeAllOperator: MergeAllOperator_1,
1571 MergeAllSubscriber: MergeAllSubscriber_1
1572};
1573
1574/* tslint:enable:max-line-length */
1575/**
1576 * Creates an output Observable which concurrently emits all values from every
1577 * given input Observable.
1578 *
1579 * <span class="informal">Flattens multiple Observables together by blending
1580 * their values into one Observable.</span>
1581 *
1582 * <img src="./img/merge.png" width="100%">
1583 *
1584 * `merge` subscribes to each given input Observable (either the source or an
1585 * Observable given as argument), and simply forwards (without doing any
1586 * transformation) all the values from all the input Observables to the output
1587 * Observable. The output Observable only completes once all input Observables
1588 * have completed. Any error delivered by an input Observable will be immediately
1589 * emitted on the output Observable.
1590 *
1591 * @example <caption>Merge together two Observables: 1s interval and clicks</caption>
1592 * var clicks = Rx.Observable.fromEvent(document, 'click');
1593 * var timer = Rx.Observable.interval(1000);
1594 * var clicksOrTimer = clicks.merge(timer);
1595 * clicksOrTimer.subscribe(x => console.log(x));
1596 *
1597 * @example <caption>Merge together 3 Observables, but only 2 run concurrently</caption>
1598 * var timer1 = Rx.Observable.interval(1000).take(10);
1599 * var timer2 = Rx.Observable.interval(2000).take(6);
1600 * var timer3 = Rx.Observable.interval(500).take(10);
1601 * var concurrent = 2; // the argument
1602 * var merged = timer1.merge(timer2, timer3, concurrent);
1603 * merged.subscribe(x => console.log(x));
1604 *
1605 * @see {@link mergeAll}
1606 * @see {@link mergeMap}
1607 * @see {@link mergeMapTo}
1608 * @see {@link mergeScan}
1609 *
1610 * @param {ObservableInput} other An input Observable to merge with the source
1611 * Observable. More than one input Observables may be given as argument.
1612 * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of input
1613 * Observables being subscribed to concurrently.
1614 * @param {Scheduler} [scheduler=null] The IScheduler to use for managing
1615 * concurrency of input Observables.
1616 * @return {Observable} An Observable that emits items that are the result of
1617 * every input Observable.
1618 * @method merge
1619 * @owner Observable
1620 */
1621function merge$2() {
1622 var observables = [];
1623 for (var _i = 0; _i < arguments.length; _i++) {
1624 observables[_i - 0] = arguments[_i];
1625 }
1626 return this.lift.call(mergeStatic.apply(void 0, [this].concat(observables)));
1627}
1628var merge_2$1 = merge$2;
1629/* tslint:enable:max-line-length */
1630/**
1631 * Creates an output Observable which concurrently emits all values from every
1632 * given input Observable.
1633 *
1634 * <span class="informal">Flattens multiple Observables together by blending
1635 * their values into one Observable.</span>
1636 *
1637 * <img src="./img/merge.png" width="100%">
1638 *
1639 * `merge` subscribes to each given input Observable (as arguments), and simply
1640 * forwards (without doing any transformation) all the values from all the input
1641 * Observables to the output Observable. The output Observable only completes
1642 * once all input Observables have completed. Any error delivered by an input
1643 * Observable will be immediately emitted on the output Observable.
1644 *
1645 * @example <caption>Merge together two Observables: 1s interval and clicks</caption>
1646 * var clicks = Rx.Observable.fromEvent(document, 'click');
1647 * var timer = Rx.Observable.interval(1000);
1648 * var clicksOrTimer = Rx.Observable.merge(clicks, timer);
1649 * clicksOrTimer.subscribe(x => console.log(x));
1650 *
1651 * // Results in the following:
1652 * // timer will emit ascending values, one every second(1000ms) to console
1653 * // clicks logs MouseEvents to console everytime the "document" is clicked
1654 * // Since the two streams are merged you see these happening
1655 * // as they occur.
1656 *
1657 * @example <caption>Merge together 3 Observables, but only 2 run concurrently</caption>
1658 * var timer1 = Rx.Observable.interval(1000).take(10);
1659 * var timer2 = Rx.Observable.interval(2000).take(6);
1660 * var timer3 = Rx.Observable.interval(500).take(10);
1661 * var concurrent = 2; // the argument
1662 * var merged = Rx.Observable.merge(timer1, timer2, timer3, concurrent);
1663 * merged.subscribe(x => console.log(x));
1664 *
1665 * // Results in the following:
1666 * // - First timer1 and timer2 will run concurrently
1667 * // - timer1 will emit a value every 1000ms for 10 iterations
1668 * // - timer2 will emit a value every 2000ms for 6 iterations
1669 * // - after timer1 hits it's max iteration, timer2 will
1670 * // continue, and timer3 will start to run concurrently with timer2
1671 * // - when timer2 hits it's max iteration it terminates, and
1672 * // timer3 will continue to emit a value every 500ms until it is complete
1673 *
1674 * @see {@link mergeAll}
1675 * @see {@link mergeMap}
1676 * @see {@link mergeMapTo}
1677 * @see {@link mergeScan}
1678 *
1679 * @param {...ObservableInput} observables Input Observables to merge together.
1680 * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of input
1681 * Observables being subscribed to concurrently.
1682 * @param {Scheduler} [scheduler=null] The IScheduler to use for managing
1683 * concurrency of input Observables.
1684 * @return {Observable} an Observable that emits items that are the result of
1685 * every input Observable.
1686 * @static true
1687 * @name merge
1688 * @owner Observable
1689 */
1690function mergeStatic() {
1691 var observables = [];
1692 for (var _i = 0; _i < arguments.length; _i++) {
1693 observables[_i - 0] = arguments[_i];
1694 }
1695 var concurrent = Number.POSITIVE_INFINITY;
1696 var scheduler = null;
1697 var last = observables[observables.length - 1];
1698 if (isScheduler_1.isScheduler(last)) {
1699 scheduler = observables.pop();
1700 if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') {
1701 concurrent = observables.pop();
1702 }
1703 }
1704 else if (typeof last === 'number') {
1705 concurrent = observables.pop();
1706 }
1707 if (scheduler === null && observables.length === 1 && observables[0] instanceof Observable_1.Observable) {
1708 return observables[0];
1709 }
1710 return new ArrayObservable_1.ArrayObservable(observables, scheduler).lift(new mergeAll_1.MergeAllOperator(concurrent));
1711}
1712var mergeStatic_1 = mergeStatic;
1713
1714var merge_1 = {
1715 merge: merge_2$1,
1716 mergeStatic: mergeStatic_1
1717};
1718
1719var merge_2 = merge_1.mergeStatic;
1720
1721var __extends$12 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1722 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1723 function __() { this.constructor = d; }
1724 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1725};
1726/**
1727 * An error thrown when an action is invalid because the object has been
1728 * unsubscribed.
1729 *
1730 * @see {@link Subject}
1731 * @see {@link BehaviorSubject}
1732 *
1733 * @class ObjectUnsubscribedError
1734 */
1735var ObjectUnsubscribedError = (function (_super) {
1736 __extends$12(ObjectUnsubscribedError, _super);
1737 function ObjectUnsubscribedError() {
1738 var err = _super.call(this, 'object unsubscribed');
1739 this.name = err.name = 'ObjectUnsubscribedError';
1740 this.stack = err.stack;
1741 this.message = err.message;
1742 }
1743 return ObjectUnsubscribedError;
1744}(Error));
1745var ObjectUnsubscribedError_2 = ObjectUnsubscribedError;
1746
1747var ObjectUnsubscribedError_1 = {
1748 ObjectUnsubscribedError: ObjectUnsubscribedError_2
1749};
1750
1751var __extends$13 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1752 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1753 function __() { this.constructor = d; }
1754 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1755};
1756
1757/**
1758 * We need this JSDoc comment for affecting ESDoc.
1759 * @ignore
1760 * @extends {Ignored}
1761 */
1762var SubjectSubscription = (function (_super) {
1763 __extends$13(SubjectSubscription, _super);
1764 function SubjectSubscription(subject, subscriber) {
1765 _super.call(this);
1766 this.subject = subject;
1767 this.subscriber = subscriber;
1768 this.closed = false;
1769 }
1770 SubjectSubscription.prototype.unsubscribe = function () {
1771 if (this.closed) {
1772 return;
1773 }
1774 this.closed = true;
1775 var subject = this.subject;
1776 var observers = subject.observers;
1777 this.subject = null;
1778 if (!observers || observers.length === 0 || subject.isStopped || subject.closed) {
1779 return;
1780 }
1781 var subscriberIndex = observers.indexOf(this.subscriber);
1782 if (subscriberIndex !== -1) {
1783 observers.splice(subscriberIndex, 1);
1784 }
1785 };
1786 return SubjectSubscription;
1787}(Subscription_1.Subscription));
1788var SubjectSubscription_2 = SubjectSubscription;
1789
1790var SubjectSubscription_1 = {
1791 SubjectSubscription: SubjectSubscription_2
1792};
1793
1794var __extends$11 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1795 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1796 function __() { this.constructor = d; }
1797 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1798};
1799
1800
1801
1802
1803
1804
1805/**
1806 * @class SubjectSubscriber<T>
1807 */
1808var SubjectSubscriber = (function (_super) {
1809 __extends$11(SubjectSubscriber, _super);
1810 function SubjectSubscriber(destination) {
1811 _super.call(this, destination);
1812 this.destination = destination;
1813 }
1814 return SubjectSubscriber;
1815}(Subscriber_1.Subscriber));
1816var SubjectSubscriber_1 = SubjectSubscriber;
1817/**
1818 * @class Subject<T>
1819 */
1820var Subject = (function (_super) {
1821 __extends$11(Subject, _super);
1822 function Subject() {
1823 _super.call(this);
1824 this.observers = [];
1825 this.closed = false;
1826 this.isStopped = false;
1827 this.hasError = false;
1828 this.thrownError = null;
1829 }
1830 Subject.prototype[rxSubscriber.rxSubscriber] = function () {
1831 return new SubjectSubscriber(this);
1832 };
1833 Subject.prototype.lift = function (operator) {
1834 var subject = new AnonymousSubject(this, this);
1835 subject.operator = operator;
1836 return subject;
1837 };
1838 Subject.prototype.next = function (value) {
1839 if (this.closed) {
1840 throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
1841 }
1842 if (!this.isStopped) {
1843 var observers = this.observers;
1844 var len = observers.length;
1845 var copy = observers.slice();
1846 for (var i = 0; i < len; i++) {
1847 copy[i].next(value);
1848 }
1849 }
1850 };
1851 Subject.prototype.error = function (err) {
1852 if (this.closed) {
1853 throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
1854 }
1855 this.hasError = true;
1856 this.thrownError = err;
1857 this.isStopped = true;
1858 var observers = this.observers;
1859 var len = observers.length;
1860 var copy = observers.slice();
1861 for (var i = 0; i < len; i++) {
1862 copy[i].error(err);
1863 }
1864 this.observers.length = 0;
1865 };
1866 Subject.prototype.complete = function () {
1867 if (this.closed) {
1868 throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
1869 }
1870 this.isStopped = true;
1871 var observers = this.observers;
1872 var len = observers.length;
1873 var copy = observers.slice();
1874 for (var i = 0; i < len; i++) {
1875 copy[i].complete();
1876 }
1877 this.observers.length = 0;
1878 };
1879 Subject.prototype.unsubscribe = function () {
1880 this.isStopped = true;
1881 this.closed = true;
1882 this.observers = null;
1883 };
1884 Subject.prototype._trySubscribe = function (subscriber) {
1885 if (this.closed) {
1886 throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
1887 }
1888 else {
1889 return _super.prototype._trySubscribe.call(this, subscriber);
1890 }
1891 };
1892 Subject.prototype._subscribe = function (subscriber) {
1893 if (this.closed) {
1894 throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
1895 }
1896 else if (this.hasError) {
1897 subscriber.error(this.thrownError);
1898 return Subscription_1.Subscription.EMPTY;
1899 }
1900 else if (this.isStopped) {
1901 subscriber.complete();
1902 return Subscription_1.Subscription.EMPTY;
1903 }
1904 else {
1905 this.observers.push(subscriber);
1906 return new SubjectSubscription_1.SubjectSubscription(this, subscriber);
1907 }
1908 };
1909 Subject.prototype.asObservable = function () {
1910 var observable = new Observable_1.Observable();
1911 observable.source = this;
1912 return observable;
1913 };
1914 Subject.create = function (destination, source) {
1915 return new AnonymousSubject(destination, source);
1916 };
1917 return Subject;
1918}(Observable_1.Observable));
1919var Subject_2 = Subject;
1920/**
1921 * @class AnonymousSubject<T>
1922 */
1923var AnonymousSubject = (function (_super) {
1924 __extends$11(AnonymousSubject, _super);
1925 function AnonymousSubject(destination, source) {
1926 _super.call(this);
1927 this.destination = destination;
1928 this.source = source;
1929 }
1930 AnonymousSubject.prototype.next = function (value) {
1931 var destination = this.destination;
1932 if (destination && destination.next) {
1933 destination.next(value);
1934 }
1935 };
1936 AnonymousSubject.prototype.error = function (err) {
1937 var destination = this.destination;
1938 if (destination && destination.error) {
1939 this.destination.error(err);
1940 }
1941 };
1942 AnonymousSubject.prototype.complete = function () {
1943 var destination = this.destination;
1944 if (destination && destination.complete) {
1945 this.destination.complete();
1946 }
1947 };
1948 AnonymousSubject.prototype._subscribe = function (subscriber) {
1949 var source = this.source;
1950 if (source) {
1951 return this.source.subscribe(subscriber);
1952 }
1953 else {
1954 return Subscription_1.Subscription.EMPTY;
1955 }
1956 };
1957 return AnonymousSubject;
1958}(Subject));
1959var AnonymousSubject_1 = AnonymousSubject;
1960
1961var Subject_1 = {
1962 SubjectSubscriber: SubjectSubscriber_1,
1963 Subject: Subject_2,
1964 AnonymousSubject: AnonymousSubject_1
1965};
1966
1967var __extends$10 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
1968 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1969 function __() { this.constructor = d; }
1970 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1971};
1972
1973
1974
1975
1976/**
1977 * @class ConnectableObservable<T>
1978 */
1979var ConnectableObservable = (function (_super) {
1980 __extends$10(ConnectableObservable, _super);
1981 function ConnectableObservable(source, subjectFactory) {
1982 _super.call(this);
1983 this.source = source;
1984 this.subjectFactory = subjectFactory;
1985 this._refCount = 0;
1986 this._isComplete = false;
1987 }
1988 ConnectableObservable.prototype._subscribe = function (subscriber) {
1989 return this.getSubject().subscribe(subscriber);
1990 };
1991 ConnectableObservable.prototype.getSubject = function () {
1992 var subject = this._subject;
1993 if (!subject || subject.isStopped) {
1994 this._subject = this.subjectFactory();
1995 }
1996 return this._subject;
1997 };
1998 ConnectableObservable.prototype.connect = function () {
1999 var connection = this._connection;
2000 if (!connection) {
2001 this._isComplete = false;
2002 connection = this._connection = new Subscription_1.Subscription();
2003 connection.add(this.source
2004 .subscribe(new ConnectableSubscriber(this.getSubject(), this)));
2005 if (connection.closed) {
2006 this._connection = null;
2007 connection = Subscription_1.Subscription.EMPTY;
2008 }
2009 else {
2010 this._connection = connection;
2011 }
2012 }
2013 return connection;
2014 };
2015 ConnectableObservable.prototype.refCount = function () {
2016 return this.lift(new RefCountOperator(this));
2017 };
2018 return ConnectableObservable;
2019}(Observable_1.Observable));
2020var ConnectableObservable_2 = ConnectableObservable;
2021var connectableProto = ConnectableObservable.prototype;
2022var connectableObservableDescriptor = {
2023 operator: { value: null },
2024 _refCount: { value: 0, writable: true },
2025 _subject: { value: null, writable: true },
2026 _connection: { value: null, writable: true },
2027 _subscribe: { value: connectableProto._subscribe },
2028 _isComplete: { value: connectableProto._isComplete, writable: true },
2029 getSubject: { value: connectableProto.getSubject },
2030 connect: { value: connectableProto.connect },
2031 refCount: { value: connectableProto.refCount }
2032};
2033var ConnectableSubscriber = (function (_super) {
2034 __extends$10(ConnectableSubscriber, _super);
2035 function ConnectableSubscriber(destination, connectable) {
2036 _super.call(this, destination);
2037 this.connectable = connectable;
2038 }
2039 ConnectableSubscriber.prototype._error = function (err) {
2040 this._unsubscribe();
2041 _super.prototype._error.call(this, err);
2042 };
2043 ConnectableSubscriber.prototype._complete = function () {
2044 this.connectable._isComplete = true;
2045 this._unsubscribe();
2046 _super.prototype._complete.call(this);
2047 };
2048 ConnectableSubscriber.prototype._unsubscribe = function () {
2049 var connectable = this.connectable;
2050 if (connectable) {
2051 this.connectable = null;
2052 var connection = connectable._connection;
2053 connectable._refCount = 0;
2054 connectable._subject = null;
2055 connectable._connection = null;
2056 if (connection) {
2057 connection.unsubscribe();
2058 }
2059 }
2060 };
2061 return ConnectableSubscriber;
2062}(Subject_1.SubjectSubscriber));
2063var RefCountOperator = (function () {
2064 function RefCountOperator(connectable) {
2065 this.connectable = connectable;
2066 }
2067 RefCountOperator.prototype.call = function (subscriber, source) {
2068 var connectable = this.connectable;
2069 connectable._refCount++;
2070 var refCounter = new RefCountSubscriber(subscriber, connectable);
2071 var subscription = source.subscribe(refCounter);
2072 if (!refCounter.closed) {
2073 refCounter.connection = connectable.connect();
2074 }
2075 return subscription;
2076 };
2077 return RefCountOperator;
2078}());
2079var RefCountSubscriber = (function (_super) {
2080 __extends$10(RefCountSubscriber, _super);
2081 function RefCountSubscriber(destination, connectable) {
2082 _super.call(this, destination);
2083 this.connectable = connectable;
2084 }
2085 RefCountSubscriber.prototype._unsubscribe = function () {
2086 var connectable = this.connectable;
2087 if (!connectable) {
2088 this.connection = null;
2089 return;
2090 }
2091 this.connectable = null;
2092 var refCount = connectable._refCount;
2093 if (refCount <= 0) {
2094 this.connection = null;
2095 return;
2096 }
2097 connectable._refCount = refCount - 1;
2098 if (refCount > 1) {
2099 this.connection = null;
2100 return;
2101 }
2102 ///
2103 // Compare the local RefCountSubscriber's connection Subscription to the
2104 // connection Subscription on the shared ConnectableObservable. In cases
2105 // where the ConnectableObservable source synchronously emits values, and
2106 // the RefCountSubscriber's downstream Observers synchronously unsubscribe,
2107 // execution continues to here before the RefCountOperator has a chance to
2108 // supply the RefCountSubscriber with the shared connection Subscription.
2109 // For example:
2110 // ```
2111 // Observable.range(0, 10)
2112 // .publish()
2113 // .refCount()
2114 // .take(5)
2115 // .subscribe();
2116 // ```
2117 // In order to account for this case, RefCountSubscriber should only dispose
2118 // the ConnectableObservable's shared connection Subscription if the
2119 // connection Subscription exists, *and* either:
2120 // a. RefCountSubscriber doesn't have a reference to the shared connection
2121 // Subscription yet, or,
2122 // b. RefCountSubscriber's connection Subscription reference is identical
2123 // to the shared connection Subscription
2124 ///
2125 var connection = this.connection;
2126 var sharedConnection = connectable._connection;
2127 this.connection = null;
2128 if (sharedConnection && (!connection || sharedConnection === connection)) {
2129 sharedConnection.unsubscribe();
2130 }
2131 };
2132 return RefCountSubscriber;
2133}(Subscriber_1.Subscriber));
2134
2135var ConnectableObservable_1 = {
2136 ConnectableObservable: ConnectableObservable_2,
2137 connectableObservableDescriptor: connectableObservableDescriptor
2138};
2139
2140/* tslint:enable:max-line-length */
2141/**
2142 * Returns an Observable that emits the results of invoking a specified selector on items
2143 * emitted by a ConnectableObservable that shares a single subscription to the underlying stream.
2144 *
2145 * <img src="./img/multicast.png" width="100%">
2146 *
2147 * @param {Function|Subject} subjectOrSubjectFactory - Factory function to create an intermediate subject through
2148 * which the source sequence's elements will be multicast to the selector function
2149 * or Subject to push source elements into.
2150 * @param {Function} [selector] - Optional selector function that can use the multicasted source stream
2151 * as many times as needed, without causing multiple subscriptions to the source stream.
2152 * Subscribers to the given source will receive all notifications of the source from the
2153 * time of the subscription forward.
2154 * @return {Observable} An Observable that emits the results of invoking the selector
2155 * on the items emitted by a `ConnectableObservable` that shares a single subscription to
2156 * the underlying stream.
2157 * @method multicast
2158 * @owner Observable
2159 */
2160function multicast(subjectOrSubjectFactory, selector) {
2161 var subjectFactory;
2162 if (typeof subjectOrSubjectFactory === 'function') {
2163 subjectFactory = subjectOrSubjectFactory;
2164 }
2165 else {
2166 subjectFactory = function subjectFactory() {
2167 return subjectOrSubjectFactory;
2168 };
2169 }
2170 if (typeof selector === 'function') {
2171 return this.lift(new MulticastOperator(subjectFactory, selector));
2172 }
2173 var connectable = Object.create(this, ConnectableObservable_1.connectableObservableDescriptor);
2174 connectable.source = this;
2175 connectable.subjectFactory = subjectFactory;
2176 return connectable;
2177}
2178var multicast_2 = multicast;
2179var MulticastOperator = (function () {
2180 function MulticastOperator(subjectFactory, selector) {
2181 this.subjectFactory = subjectFactory;
2182 this.selector = selector;
2183 }
2184 MulticastOperator.prototype.call = function (subscriber, source) {
2185 var selector = this.selector;
2186 var subject = this.subjectFactory();
2187 var subscription = selector(subject).subscribe(subscriber);
2188 subscription.add(source.subscribe(subject));
2189 return subscription;
2190 };
2191 return MulticastOperator;
2192}());
2193var MulticastOperator_1 = MulticastOperator;
2194
2195var multicast_1 = {
2196 multicast: multicast_2,
2197 MulticastOperator: MulticastOperator_1
2198};
2199
2200function shareSubjectFactory() {
2201 return new Subject_1.Subject();
2202}
2203/**
2204 * Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one
2205 * Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will
2206 * unsubscribe from the source Observable. Because the Observable is multicasting it makes the stream `hot`.
2207 * This is an alias for .publish().refCount().
2208 *
2209 * <img src="./img/share.png" width="100%">
2210 *
2211 * @return {Observable<T>} An Observable that upon connection causes the source Observable to emit items to its Observers.
2212 * @method share
2213 * @owner Observable
2214 */
2215function share() {
2216 return multicast_1.multicast.call(this, shareSubjectFactory).refCount();
2217}
2218var share_2 = share;
2219
2220/**
2221 * @license Angular v4.4.3
2222 * (c) 2010-2017 Google, Inc. https://angular.io/
2223 * License: MIT
2224 */
2225/**
2226 * Creates a token that can be used in a DI Provider.
2227 *
2228 * ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
2229 *
2230 * ```typescript
2231 * var t = new OpaqueToken("value");
2232 *
2233 * var injector = Injector.resolveAndCreate([
2234 * {provide: t, useValue: "bindingValue"}
2235 * ]);
2236 *
2237 * expect(injector.get(t)).toEqual("bindingValue");
2238 * ```
2239 *
2240 * Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
2241 * caused by multiple providers using the same string as two different tokens.
2242 *
2243 * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
2244 * error messages.
2245 * @deprecated since v4.0.0 because it does not support type information, use `InjectionToken<?>`
2246 * instead.
2247 */
2248var OpaqueToken = (function () {
2249 /**
2250 * @param {?} _desc
2251 */
2252 function OpaqueToken(_desc) {
2253 this._desc = _desc;
2254 }
2255 /**
2256 * @return {?}
2257 */
2258 OpaqueToken.prototype.toString = function () { return "Token " + this._desc; };
2259 return OpaqueToken;
2260}());
2261/**
2262 * Creates a token that can be used in a DI Provider.
2263 *
2264 * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
2265 * runtime representation) such as when injecting an interface, callable type, array or
2266 * parametrized type.
2267 *
2268 * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
2269 * the `Injector`. This provides additional level of type safety.
2270 *
2271 * ```
2272 * interface MyInterface {...}
2273 * var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
2274 * // myInterface is inferred to be MyInterface.
2275 * ```
2276 *
2277 * ### Example
2278 *
2279 * {\@example core/di/ts/injector_spec.ts region='InjectionToken'}
2280 *
2281 * \@stable
2282 */
2283var InjectionToken = (function (_super) {
2284 __extends$1(InjectionToken, _super);
2285 /**
2286 * @param {?} desc
2287 */
2288 function InjectionToken(desc) {
2289 return _super.call(this, desc) || this;
2290 }
2291 /**
2292 * @return {?}
2293 */
2294 InjectionToken.prototype.toString = function () { return "InjectionToken " + this._desc; };
2295 return InjectionToken;
2296}(OpaqueToken));
2297/**
2298 * @license
2299 * Copyright Google Inc. All Rights Reserved.
2300 *
2301 * Use of this source code is governed by an MIT-style license that can be
2302 * found in the LICENSE file at https://angular.io/license
2303 */
2304var __window = typeof window !== 'undefined' && window;
2305var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
2306 self instanceof WorkerGlobalScope && self;
2307var __global = typeof global !== 'undefined' && global;
2308var _global = __window || __global || __self;
2309var _symbolIterator = null;
2310/**
2311 * @return {?}
2312 */
2313function getSymbolIterator() {
2314 if (!_symbolIterator) {
2315 var /** @type {?} */ Symbol = _global['Symbol'];
2316 if (Symbol && Symbol.iterator) {
2317 _symbolIterator = Symbol.iterator;
2318 }
2319 else {
2320 // es6-shim specific logic
2321 var /** @type {?} */ keys = Object.getOwnPropertyNames(Map.prototype);
2322 for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
2323 var /** @type {?} */ key = keys[i];
2324 if (key !== 'entries' && key !== 'size' &&
2325 ((Map)).prototype[key] === Map.prototype['entries']) {
2326 _symbolIterator = key;
2327 }
2328 }
2329 }
2330 }
2331 return _symbolIterator;
2332}
2333/**
2334 * @param {?} fn
2335 * @return {?}
2336 */
2337function scheduleMicroTask(fn) {
2338 Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
2339}
2340/**
2341 * @param {?} a
2342 * @param {?} b
2343 * @return {?}
2344 */
2345function looseIdentical(a, b) {
2346 return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
2347}
2348/**
2349 * @param {?} token
2350 * @return {?}
2351 */
2352function stringify(token) {
2353 if (typeof token === 'string') {
2354 return token;
2355 }
2356 if (token == null) {
2357 return '' + token;
2358 }
2359 if (token.overriddenName) {
2360 return "" + token.overriddenName;
2361 }
2362 if (token.name) {
2363 return "" + token.name;
2364 }
2365 var /** @type {?} */ res = token.toString();
2366 if (res == null) {
2367 return '' + res;
2368 }
2369 var /** @type {?} */ newLineIndex = res.indexOf('\n');
2370 return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
2371}
2372/**
2373 * @license
2374 * Copyright Google Inc. All Rights Reserved.
2375 *
2376 * Use of this source code is governed by an MIT-style license that can be
2377 * found in the LICENSE file at https://angular.io/license
2378 */
2379var _nextClassId = 0;
2380var Reflect$1 = _global['Reflect'];
2381/**
2382 * @param {?} annotation
2383 * @return {?}
2384 */
2385function extractAnnotation(annotation) {
2386 if (typeof annotation === 'function' && annotation.hasOwnProperty('annotation')) {
2387 // it is a decorator, extract annotation
2388 annotation = annotation.annotation;
2389 }
2390 return annotation;
2391}
2392/**
2393 * @param {?} fnOrArray
2394 * @param {?} key
2395 * @return {?}
2396 */
2397function applyParams(fnOrArray, key) {
2398 if (fnOrArray === Object || fnOrArray === String || fnOrArray === Function ||
2399 fnOrArray === Number || fnOrArray === Array) {
2400 throw new Error("Can not use native " + stringify(fnOrArray) + " as constructor");
2401 }
2402 if (typeof fnOrArray === 'function') {
2403 return fnOrArray;
2404 }
2405 if (Array.isArray(fnOrArray)) {
2406 var /** @type {?} */ annotations = (fnOrArray);
2407 var /** @type {?} */ annoLength = annotations.length - 1;
2408 var /** @type {?} */ fn = fnOrArray[annoLength];
2409 if (typeof fn !== 'function') {
2410 throw new Error("Last position of Class method array must be Function in key " + key + " was '" + stringify(fn) + "'");
2411 }
2412 if (annoLength != fn.length) {
2413 throw new Error("Number of annotations (" + annoLength + ") does not match number of arguments (" + fn.length + ") in the function: " + stringify(fn));
2414 }
2415 var /** @type {?} */ paramsAnnotations = [];
2416 for (var /** @type {?} */ i = 0, /** @type {?} */ ii = annotations.length - 1; i < ii; i++) {
2417 var /** @type {?} */ paramAnnotations = [];
2418 paramsAnnotations.push(paramAnnotations);
2419 var /** @type {?} */ annotation = annotations[i];
2420 if (Array.isArray(annotation)) {
2421 for (var /** @type {?} */ j = 0; j < annotation.length; j++) {
2422 paramAnnotations.push(extractAnnotation(annotation[j]));
2423 }
2424 }
2425 else if (typeof annotation === 'function') {
2426 paramAnnotations.push(extractAnnotation(annotation));
2427 }
2428 else {
2429 paramAnnotations.push(annotation);
2430 }
2431 }
2432 Reflect$1.defineMetadata('parameters', paramsAnnotations, fn);
2433 return fn;
2434 }
2435 throw new Error("Only Function or Array is supported in Class definition for key '" + key + "' is '" + stringify(fnOrArray) + "'");
2436}
2437/**
2438 * Provides a way for expressing ES6 classes with parameter annotations in ES5.
2439 *
2440 * ## Basic Example
2441 *
2442 * ```
2443 * var Greeter = ng.Class({
2444 * constructor: function(name) {
2445 * this.name = name;
2446 * },
2447 *
2448 * greet: function() {
2449 * alert('Hello ' + this.name + '!');
2450 * }
2451 * });
2452 * ```
2453 *
2454 * is equivalent to ES6:
2455 *
2456 * ```
2457 * class Greeter {
2458 * constructor(name) {
2459 * this.name = name;
2460 * }
2461 *
2462 * greet() {
2463 * alert('Hello ' + this.name + '!');
2464 * }
2465 * }
2466 * ```
2467 *
2468 * or equivalent to ES5:
2469 *
2470 * ```
2471 * var Greeter = function (name) {
2472 * this.name = name;
2473 * }
2474 *
2475 * Greeter.prototype.greet = function () {
2476 * alert('Hello ' + this.name + '!');
2477 * }
2478 * ```
2479 *
2480 * ### Example with parameter annotations
2481 *
2482 * ```
2483 * var MyService = ng.Class({
2484 * constructor: [String, [new Optional(), Service], function(name, myService) {
2485 * ...
2486 * }]
2487 * });
2488 * ```
2489 *
2490 * is equivalent to ES6:
2491 *
2492 * ```
2493 * class MyService {
2494 * constructor(name: string, \@Optional() myService: Service) {
2495 * ...
2496 * }
2497 * }
2498 * ```
2499 *
2500 * ### Example with inheritance
2501 *
2502 * ```
2503 * var Shape = ng.Class({
2504 * constructor: (color) {
2505 * this.color = color;
2506 * }
2507 * });
2508 *
2509 * var Square = ng.Class({
2510 * extends: Shape,
2511 * constructor: function(color, size) {
2512 * Shape.call(this, color);
2513 * this.size = size;
2514 * }
2515 * });
2516 * ```
2517 * @suppress {globalThis}
2518 * \@stable
2519 * @param {?} clsDef
2520 * @return {?}
2521 */
2522function Class(clsDef) {
2523 var /** @type {?} */ constructor = applyParams(clsDef.hasOwnProperty('constructor') ? clsDef.constructor : undefined, 'constructor');
2524 var /** @type {?} */ proto = constructor.prototype;
2525 if (clsDef.hasOwnProperty('extends')) {
2526 if (typeof clsDef.extends === 'function') {
2527 ((constructor)).prototype = proto =
2528 Object.create(((clsDef.extends)).prototype);
2529 }
2530 else {
2531 throw new Error("Class definition 'extends' property must be a constructor function was: " + stringify(clsDef.extends));
2532 }
2533 }
2534 for (var /** @type {?} */ key in clsDef) {
2535 if (key !== 'extends' && key !== 'prototype' && clsDef.hasOwnProperty(key)) {
2536 proto[key] = applyParams(clsDef[key], key);
2537 }
2538 }
2539 if (this && this.annotations instanceof Array) {
2540 Reflect$1.defineMetadata('annotations', this.annotations, constructor);
2541 }
2542 var /** @type {?} */ constructorName = constructor['name'];
2543 if (!constructorName || constructorName === 'constructor') {
2544 ((constructor))['overriddenName'] = "class" + _nextClassId++;
2545 }
2546 return (constructor);
2547}
2548/**
2549 * @suppress {globalThis}
2550 * @param {?} name
2551 * @param {?=} props
2552 * @param {?=} parentClass
2553 * @param {?=} chainFn
2554 * @return {?}
2555 */
2556function makeDecorator(name, props, parentClass, chainFn) {
2557 var /** @type {?} */ metaCtor = makeMetadataCtor(props);
2558 /**
2559 * @param {?} objOrType
2560 * @return {?}
2561 */
2562 function DecoratorFactory(objOrType) {
2563 if (!(Reflect$1 && Reflect$1.getOwnMetadata)) {
2564 throw 'reflect-metadata shim is required when using class decorators';
2565 }
2566 if (this instanceof DecoratorFactory) {
2567 metaCtor.call(this, objOrType);
2568 return this;
2569 }
2570 var /** @type {?} */ annotationInstance = new ((DecoratorFactory))(objOrType);
2571 var /** @type {?} */ chainAnnotation = typeof this === 'function' && Array.isArray(this.annotations) ? this.annotations : [];
2572 chainAnnotation.push(annotationInstance);
2573 var /** @type {?} */ TypeDecorator = (function TypeDecorator(cls) {
2574 var /** @type {?} */ annotations = Reflect$1.getOwnMetadata('annotations', cls) || [];
2575 annotations.push(annotationInstance);
2576 Reflect$1.defineMetadata('annotations', annotations, cls);
2577 return cls;
2578 });
2579 TypeDecorator.annotations = chainAnnotation;
2580 TypeDecorator.Class = Class;
2581 if (chainFn)
2582 chainFn(TypeDecorator);
2583 return TypeDecorator;
2584 }
2585 if (parentClass) {
2586 DecoratorFactory.prototype = Object.create(parentClass.prototype);
2587 }
2588 DecoratorFactory.prototype.toString = function () { return "@" + name; };
2589 ((DecoratorFactory)).annotationCls = DecoratorFactory;
2590 return DecoratorFactory;
2591}
2592/**
2593 * @param {?=} props
2594 * @return {?}
2595 */
2596function makeMetadataCtor(props) {
2597 return function ctor() {
2598 var args = [];
2599 for (var _i = 0; _i < arguments.length; _i++) {
2600 args[_i] = arguments[_i];
2601 }
2602 if (props) {
2603 var /** @type {?} */ values = props.apply(void 0, args);
2604 for (var /** @type {?} */ propName in values) {
2605 this[propName] = values[propName];
2606 }
2607 }
2608 };
2609}
2610/**
2611 * @param {?} name
2612 * @param {?=} props
2613 * @param {?=} parentClass
2614 * @return {?}
2615 */
2616function makeParamDecorator(name, props, parentClass) {
2617 var /** @type {?} */ metaCtor = makeMetadataCtor(props);
2618 /**
2619 * @param {...?} args
2620 * @return {?}
2621 */
2622 function ParamDecoratorFactory() {
2623 var args = [];
2624 for (var _i = 0; _i < arguments.length; _i++) {
2625 args[_i] = arguments[_i];
2626 }
2627 if (this instanceof ParamDecoratorFactory) {
2628 metaCtor.apply(this, args);
2629 return this;
2630 }
2631 var /** @type {?} */ annotationInstance = new (((ParamDecoratorFactory)).bind.apply(((ParamDecoratorFactory)), [void 0].concat(args)))();
2632 ((ParamDecorator)).annotation = annotationInstance;
2633 return ParamDecorator;
2634 /**
2635 * @param {?} cls
2636 * @param {?} unusedKey
2637 * @param {?} index
2638 * @return {?}
2639 */
2640 function ParamDecorator(cls, unusedKey, index) {
2641 var /** @type {?} */ parameters = Reflect$1.getOwnMetadata('parameters', cls) || [];
2642 // there might be gaps if some in between parameters do not have annotations.
2643 // we pad with nulls.
2644 while (parameters.length <= index) {
2645 parameters.push(null);
2646 }
2647 parameters[index] = parameters[index] || []; /** @type {?} */
2648 ((parameters[index])).push(annotationInstance);
2649 Reflect$1.defineMetadata('parameters', parameters, cls);
2650 return cls;
2651 }
2652 }
2653 if (parentClass) {
2654 ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
2655 }
2656 ParamDecoratorFactory.prototype.toString = function () { return "@" + name; };
2657 ((ParamDecoratorFactory)).annotationCls = ParamDecoratorFactory;
2658 return ParamDecoratorFactory;
2659}
2660/**
2661 * @param {?} name
2662 * @param {?=} props
2663 * @param {?=} parentClass
2664 * @return {?}
2665 */
2666function makePropDecorator(name, props, parentClass) {
2667 var /** @type {?} */ metaCtor = makeMetadataCtor(props);
2668 /**
2669 * @param {...?} args
2670 * @return {?}
2671 */
2672 function PropDecoratorFactory() {
2673 var args = [];
2674 for (var _i = 0; _i < arguments.length; _i++) {
2675 args[_i] = arguments[_i];
2676 }
2677 if (this instanceof PropDecoratorFactory) {
2678 metaCtor.apply(this, args);
2679 return this;
2680 }
2681 var /** @type {?} */ decoratorInstance = new (((PropDecoratorFactory)).bind.apply(((PropDecoratorFactory)), [void 0].concat(args)))();
2682 return function PropDecorator(target, name) {
2683 var /** @type {?} */ meta = Reflect$1.getOwnMetadata('propMetadata', target.constructor) || {};
2684 meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
2685 meta[name].unshift(decoratorInstance);
2686 Reflect$1.defineMetadata('propMetadata', meta, target.constructor);
2687 };
2688 }
2689 if (parentClass) {
2690 PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
2691 }
2692 PropDecoratorFactory.prototype.toString = function () { return "@" + name; };
2693 ((PropDecoratorFactory)).annotationCls = PropDecoratorFactory;
2694 return PropDecoratorFactory;
2695}
2696/**
2697 * @license
2698 * Copyright Google Inc. All Rights Reserved.
2699 *
2700 * Use of this source code is governed by an MIT-style license that can be
2701 * found in the LICENSE file at https://angular.io/license
2702 */
2703/**
2704 * This token can be used to create a virtual provider that will populate the
2705 * `entryComponents` fields of components and ng modules based on its `useValue`.
2706 * All components that are referenced in the `useValue` value (either directly
2707 * or in a nested array or map) will be added to the `entryComponents` property.
2708 *
2709 * ### Example
2710 * The following example shows how the router can populate the `entryComponents`
2711 * field of an NgModule based on the router configuration which refers
2712 * to components.
2713 *
2714 * ```typescript
2715 * // helper function inside the router
2716 * function provideRoutes(routes) {
2717 * return [
2718 * {provide: ROUTES, useValue: routes},
2719 * {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
2720 * ];
2721 * }
2722 *
2723 * // user code
2724 * let routes = [
2725 * {path: '/root', component: RootComp},
2726 * {path: '/teams', component: TeamsComp}
2727 * ];
2728 *
2729 * \@NgModule({
2730 * providers: [provideRoutes(routes)]
2731 * })
2732 * class ModuleWithRoutes {}
2733 * ```
2734 *
2735 * \@experimental
2736 */
2737var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
2738/**
2739 * Attribute decorator and metadata.
2740 *
2741 * \@stable
2742 * \@Annotation
2743 */
2744var Attribute = makeParamDecorator('Attribute', function (attributeName) { return ({ attributeName: attributeName }); });
2745/**
2746 * Base class for query metadata.
2747 *
2748 * See {\@link ContentChildren}, {\@link ContentChild}, {\@link ViewChildren}, {\@link ViewChild} for
2749 * more information.
2750 *
2751 * \@stable
2752 * @abstract
2753 */
2754var Query = (function () {
2755 function Query() {
2756 }
2757 return Query;
2758}());
2759/**
2760 * ContentChildren decorator and metadata.
2761 *
2762 * \@stable
2763 * \@Annotation
2764 */
2765var ContentChildren = makePropDecorator('ContentChildren', function (selector, data) {
2766 if (data === void 0) { data = {}; }
2767 return (Object.assign({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
2768}, Query);
2769/**
2770 * ContentChild decorator and metadata.
2771 *
2772 * \@stable
2773 * \@Annotation
2774 */
2775var ContentChild = makePropDecorator('ContentChild', function (selector, data) {
2776 if (data === void 0) { data = {}; }
2777 return (Object.assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
2778}, Query);
2779/**
2780 * ViewChildren decorator and metadata.
2781 *
2782 * \@stable
2783 * \@Annotation
2784 */
2785var ViewChildren = makePropDecorator('ViewChildren', function (selector, data) {
2786 if (data === void 0) { data = {}; }
2787 return (Object.assign({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
2788}, Query);
2789/**
2790 * ViewChild decorator and metadata.
2791 *
2792 * \@stable
2793 * \@Annotation
2794 */
2795var ViewChild = makePropDecorator('ViewChild', function (selector, data) { return (Object.assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data)); }, Query);
2796var ChangeDetectionStrategy = {};
2797ChangeDetectionStrategy.OnPush = 0;
2798ChangeDetectionStrategy.Default = 1;
2799ChangeDetectionStrategy[ChangeDetectionStrategy.OnPush] = "OnPush";
2800ChangeDetectionStrategy[ChangeDetectionStrategy.Default] = "Default";
2801/**
2802 * @license
2803 * Copyright Google Inc. All Rights Reserved.
2804 *
2805 * Use of this source code is governed by an MIT-style license that can be
2806 * found in the LICENSE file at https://angular.io/license
2807 */
2808/**
2809 * Directive decorator and metadata.
2810 *
2811 * \@stable
2812 * \@Annotation
2813 */
2814var Directive = makeDecorator('Directive', function (dir) {
2815 if (dir === void 0) { dir = {}; }
2816 return dir;
2817});
2818/**
2819 * Component decorator and metadata.
2820 *
2821 * \@stable
2822 * \@Annotation
2823 */
2824var Component = makeDecorator('Component', function (c) {
2825 if (c === void 0) { c = {}; }
2826 return (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c));
2827}, Directive);
2828/**
2829 * Pipe decorator and metadata.
2830 *
2831 * \@stable
2832 * \@Annotation
2833 */
2834var Pipe = makeDecorator('Pipe', function (p) { return (Object.assign({ pure: true }, p)); });
2835/**
2836 * Input decorator and metadata.
2837 *
2838 * \@stable
2839 * \@Annotation
2840 */
2841var Input = makePropDecorator('Input', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
2842/**
2843 * Output decorator and metadata.
2844 *
2845 * \@stable
2846 * \@Annotation
2847 */
2848var Output = makePropDecorator('Output', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
2849/**
2850 * HostBinding decorator and metadata.
2851 *
2852 * \@stable
2853 * \@Annotation
2854 */
2855var HostBinding = makePropDecorator('HostBinding', function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); });
2856/**
2857 * HostListener decorator and metadata.
2858 *
2859 * \@stable
2860 * \@Annotation
2861 */
2862var HostListener = makePropDecorator('HostListener', function (eventName, args) { return ({ eventName: eventName, args: args }); });
2863/**
2864 * NgModule decorator and metadata.
2865 *
2866 * \@stable
2867 * \@Annotation
2868 */
2869var NgModule = makeDecorator('NgModule', function (ngModule) { return ngModule; });
2870var ViewEncapsulation = {};
2871ViewEncapsulation.Emulated = 0;
2872ViewEncapsulation.Native = 1;
2873ViewEncapsulation.None = 2;
2874ViewEncapsulation[ViewEncapsulation.Emulated] = "Emulated";
2875ViewEncapsulation[ViewEncapsulation.Native] = "Native";
2876ViewEncapsulation[ViewEncapsulation.None] = "None";
2877/**
2878 * @license
2879 * Copyright Google Inc. All Rights Reserved.
2880 *
2881 * Use of this source code is governed by an MIT-style license that can be
2882 * found in the LICENSE file at https://angular.io/license
2883 */
2884/**
2885 * \@whatItDoes Represents the version of Angular
2886 *
2887 * \@stable
2888 */
2889var Version = (function () {
2890 /**
2891 * @param {?} full
2892 */
2893 function Version(full) {
2894 this.full = full;
2895 }
2896 Object.defineProperty(Version.prototype, "major", {
2897 /**
2898 * @return {?}
2899 */
2900 get: function () { return this.full.split('.')[0]; },
2901 enumerable: true,
2902 configurable: true
2903 });
2904 Object.defineProperty(Version.prototype, "minor", {
2905 /**
2906 * @return {?}
2907 */
2908 get: function () { return this.full.split('.')[1]; },
2909 enumerable: true,
2910 configurable: true
2911 });
2912 Object.defineProperty(Version.prototype, "patch", {
2913 /**
2914 * @return {?}
2915 */
2916 get: function () { return this.full.split('.').slice(2).join('.'); },
2917 enumerable: true,
2918 configurable: true
2919 });
2920 return Version;
2921}());
2922/**
2923 * \@stable
2924 */
2925var VERSION = new Version('4.4.3');
2926/**
2927 * @license
2928 * Copyright Google Inc. All Rights Reserved.
2929 *
2930 * Use of this source code is governed by an MIT-style license that can be
2931 * found in the LICENSE file at https://angular.io/license
2932 */
2933/**
2934 * Inject decorator and metadata.
2935 *
2936 * \@stable
2937 * \@Annotation
2938 */
2939var Inject = makeParamDecorator('Inject', function (token) { return ({ token: token }); });
2940/**
2941 * Optional decorator and metadata.
2942 *
2943 * \@stable
2944 * \@Annotation
2945 */
2946var Optional = makeParamDecorator('Optional');
2947/**
2948 * Injectable decorator and metadata.
2949 *
2950 * \@stable
2951 * \@Annotation
2952 */
2953var Injectable = makeDecorator('Injectable');
2954/**
2955 * Self decorator and metadata.
2956 *
2957 * \@stable
2958 * \@Annotation
2959 */
2960var Self = makeParamDecorator('Self');
2961/**
2962 * SkipSelf decorator and metadata.
2963 *
2964 * \@stable
2965 * \@Annotation
2966 */
2967var SkipSelf = makeParamDecorator('SkipSelf');
2968/**
2969 * Host decorator and metadata.
2970 *
2971 * \@stable
2972 * \@Annotation
2973 */
2974var Host = makeParamDecorator('Host');
2975/**
2976 * @license
2977 * Copyright Google Inc. All Rights Reserved.
2978 *
2979 * Use of this source code is governed by an MIT-style license that can be
2980 * found in the LICENSE file at https://angular.io/license
2981 */
2982/**
2983 * Allows to refer to references which are not yet defined.
2984 *
2985 * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
2986 * DI is declared,
2987 * but not yet defined. It is also used when the `token` which we use when creating a query is not
2988 * yet defined.
2989 *
2990 * ### Example
2991 * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
2992 * \@experimental
2993 * @param {?} forwardRefFn
2994 * @return {?}
2995 */
2996function forwardRef(forwardRefFn) {
2997 ((forwardRefFn)).__forward_ref__ = forwardRef;
2998 ((forwardRefFn)).toString = function () { return stringify(this()); };
2999 return (((forwardRefFn)));
3000}
3001/**
3002 * Lazily retrieves the reference value from a forwardRef.
3003 *
3004 * Acts as the identity function when given a non-forward-ref value.
3005 *
3006 * ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
3007 *
3008 * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
3009 *
3010 * See: {\@link forwardRef}
3011 * \@experimental
3012 * @param {?} type
3013 * @return {?}
3014 */
3015function resolveForwardRef(type) {
3016 if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') &&
3017 type.__forward_ref__ === forwardRef) {
3018 return ((type))();
3019 }
3020 else {
3021 return type;
3022 }
3023}
3024/**
3025 * @license
3026 * Copyright Google Inc. All Rights Reserved.
3027 *
3028 * Use of this source code is governed by an MIT-style license that can be
3029 * found in the LICENSE file at https://angular.io/license
3030 */
3031var _THROW_IF_NOT_FOUND = new Object();
3032var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
3033var _NullInjector = (function () {
3034 function _NullInjector() {
3035 }
3036 /**
3037 * @param {?} token
3038 * @param {?=} notFoundValue
3039 * @return {?}
3040 */
3041 _NullInjector.prototype.get = function (token, notFoundValue) {
3042 if (notFoundValue === void 0) { notFoundValue = _THROW_IF_NOT_FOUND; }
3043 if (notFoundValue === _THROW_IF_NOT_FOUND) {
3044 throw new Error("No provider for " + stringify(token) + "!");
3045 }
3046 return notFoundValue;
3047 };
3048 return _NullInjector;
3049}());
3050/**
3051 * \@whatItDoes Injector interface
3052 * \@howToUse
3053 * ```
3054 * const injector: Injector = ...;
3055 * injector.get(...);
3056 * ```
3057 *
3058 * \@description
3059 * For more details, see the {\@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
3060 *
3061 * ### Example
3062 *
3063 * {\@example core/di/ts/injector_spec.ts region='Injector'}
3064 *
3065 * `Injector` returns itself when given `Injector` as a token:
3066 * {\@example core/di/ts/injector_spec.ts region='injectInjector'}
3067 *
3068 * \@stable
3069 * @abstract
3070 */
3071var Injector = (function () {
3072 function Injector() {
3073 }
3074 /**
3075 * Retrieves an instance from the injector based on the provided token.
3076 * If not found:
3077 * - Throws an error if no `notFoundValue` that is not equal to
3078 * Injector.THROW_IF_NOT_FOUND is given
3079 * - Returns the `notFoundValue` otherwise
3080 * @abstract
3081 * @template T
3082 * @param {?} token
3083 * @param {?=} notFoundValue
3084 * @return {?}
3085 */
3086 Injector.prototype.get = function (token, notFoundValue) { };
3087 /**
3088 * @deprecated from v4.0.0 use Type<T> or InjectionToken<T>
3089 * @suppress {duplicate}
3090 * @abstract
3091 * @param {?} token
3092 * @param {?=} notFoundValue
3093 * @return {?}
3094 */
3095 Injector.prototype.get = function (token, notFoundValue) { };
3096 return Injector;
3097}());
3098Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
3099Injector.NULL = new _NullInjector();
3100var ERROR_DEBUG_CONTEXT = 'ngDebugContext';
3101var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
3102var ERROR_LOGGER = 'ngErrorLogger';
3103/**
3104 * @param {?} error
3105 * @return {?}
3106 */
3107/**
3108 * @param {?} error
3109 * @return {?}
3110 */
3111function getDebugContext(error) {
3112 return ((error))[ERROR_DEBUG_CONTEXT];
3113}
3114/**
3115 * @param {?} error
3116 * @return {?}
3117 */
3118function getOriginalError(error) {
3119 return ((error))[ERROR_ORIGINAL_ERROR];
3120}
3121/**
3122 * @param {?} error
3123 * @return {?}
3124 */
3125function getErrorLogger(error) {
3126 return ((error))[ERROR_LOGGER] || defaultErrorLogger;
3127}
3128/**
3129 * @param {?} console
3130 * @param {...?} values
3131 * @return {?}
3132 */
3133function defaultErrorLogger(console) {
3134 var values = [];
3135 for (var _i = 1; _i < arguments.length; _i++) {
3136 values[_i - 1] = arguments[_i];
3137 }
3138 console.error.apply(console, values);
3139}
3140/**
3141 * @license
3142 * Copyright Google Inc. All Rights Reserved.
3143 *
3144 * Use of this source code is governed by an MIT-style license that can be
3145 * found in the LICENSE file at https://angular.io/license
3146 */
3147/**
3148 * \@whatItDoes Provides a hook for centralized exception handling.
3149 *
3150 * \@description
3151 *
3152 * The default implementation of `ErrorHandler` prints error messages to the `console`. To
3153 * intercept error handling, write a custom exception handler that replaces this default as
3154 * appropriate for your app.
3155 *
3156 * ### Example
3157 *
3158 * ```
3159 * class MyErrorHandler implements ErrorHandler {
3160 * handleError(error) {
3161 * // do something with the exception
3162 * }
3163 * }
3164 *
3165 * \@NgModule({
3166 * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
3167 * })
3168 * class MyModule {}
3169 * ```
3170 *
3171 * \@stable
3172 */
3173var ErrorHandler = (function () {
3174 /**
3175 * @param {?=} deprecatedParameter
3176 */
3177 function ErrorHandler(
3178 /**
3179 * @deprecated since v4.0 parameter no longer has an effect, as ErrorHandler will never
3180 * rethrow.
3181 */
3182 deprecatedParameter) {
3183 /**
3184 * \@internal
3185 */
3186 this._console = console;
3187 }
3188 /**
3189 * @param {?} error
3190 * @return {?}
3191 */
3192 ErrorHandler.prototype.handleError = function (error) {
3193 var /** @type {?} */ originalError = this._findOriginalError(error);
3194 var /** @type {?} */ context = this._findContext(error);
3195 // Note: Browser consoles show the place from where console.error was called.
3196 // We can use this to give users additional information about the error.
3197 var /** @type {?} */ errorLogger = getErrorLogger(error);
3198 errorLogger(this._console, "ERROR", error);
3199 if (originalError) {
3200 errorLogger(this._console, "ORIGINAL ERROR", originalError);
3201 }
3202 if (context) {
3203 errorLogger(this._console, 'ERROR CONTEXT', context);
3204 }
3205 };
3206 /**
3207 * \@internal
3208 * @param {?} error
3209 * @return {?}
3210 */
3211 ErrorHandler.prototype._findContext = function (error) {
3212 if (error) {
3213 return getDebugContext(error) ? getDebugContext(error) :
3214 this._findContext(getOriginalError(error));
3215 }
3216 return null;
3217 };
3218 /**
3219 * \@internal
3220 * @param {?} error
3221 * @return {?}
3222 */
3223 ErrorHandler.prototype._findOriginalError = function (error) {
3224 var /** @type {?} */ e = getOriginalError(error);
3225 while (e && getOriginalError(e)) {
3226 e = getOriginalError(e);
3227 }
3228 return e;
3229 };
3230 return ErrorHandler;
3231}());
3232/**
3233 * @param {?} message
3234 * @param {?} originalError
3235 * @return {?}
3236 */
3237function wrappedError(message, originalError) {
3238 var /** @type {?} */ msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
3239 var /** @type {?} */ error = Error(msg);
3240 ((error))[ERROR_ORIGINAL_ERROR] = originalError;
3241 return error;
3242}
3243/**
3244 * @license
3245 * Copyright Google Inc. All Rights Reserved.
3246 *
3247 * Use of this source code is governed by an MIT-style license that can be
3248 * found in the LICENSE file at https://angular.io/license
3249 */
3250/**
3251 * @param {?} keys
3252 * @return {?}
3253 */
3254function findFirstClosedCycle(keys) {
3255 var /** @type {?} */ res = [];
3256 for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
3257 if (res.indexOf(keys[i]) > -1) {
3258 res.push(keys[i]);
3259 return res;
3260 }
3261 res.push(keys[i]);
3262 }
3263 return res;
3264}
3265/**
3266 * @param {?} keys
3267 * @return {?}
3268 */
3269function constructResolvingPath(keys) {
3270 if (keys.length > 1) {
3271 var /** @type {?} */ reversed = findFirstClosedCycle(keys.slice().reverse());
3272 var /** @type {?} */ tokenStrs = reversed.map(function (k) { return stringify(k.token); });
3273 return ' (' + tokenStrs.join(' -> ') + ')';
3274 }
3275 return '';
3276}
3277/**
3278 * @param {?} injector
3279 * @param {?} key
3280 * @param {?} constructResolvingMessage
3281 * @param {?=} originalError
3282 * @return {?}
3283 */
3284function injectionError(injector, key, constructResolvingMessage, originalError) {
3285 var /** @type {?} */ keys = [key];
3286 var /** @type {?} */ errMsg = constructResolvingMessage(keys);
3287 var /** @type {?} */ error = ((originalError ? wrappedError(errMsg, originalError) : Error(errMsg)));
3288 error.addKey = addKey;
3289 error.keys = keys;
3290 error.injectors = [injector];
3291 error.constructResolvingMessage = constructResolvingMessage;
3292 ((error))[ERROR_ORIGINAL_ERROR] = originalError;
3293 return error;
3294}
3295/**
3296 * @this {?}
3297 * @param {?} injector
3298 * @param {?} key
3299 * @return {?}
3300 */
3301function addKey(injector, key) {
3302 this.injectors.push(injector);
3303 this.keys.push(key);
3304 // Note: This updated message won't be reflected in the `.stack` property
3305 this.message = this.constructResolvingMessage(this.keys);
3306}
3307/**
3308 * Thrown when trying to retrieve a dependency by key from {\@link Injector}, but the
3309 * {\@link Injector} does not have a {\@link Provider} for the given key.
3310 *
3311 * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
3312 *
3313 * ```typescript
3314 * class A {
3315 * constructor(b:B) {}
3316 * }
3317 *
3318 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
3319 * ```
3320 * @param {?} injector
3321 * @param {?} key
3322 * @return {?}
3323 */
3324function noProviderError(injector, key) {
3325 return injectionError(injector, key, function (keys) {
3326 var /** @type {?} */ first = stringify(keys[0].token);
3327 return "No provider for " + first + "!" + constructResolvingPath(keys);
3328 });
3329}
3330/**
3331 * Thrown when dependencies form a cycle.
3332 *
3333 * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
3334 *
3335 * ```typescript
3336 * var injector = Injector.resolveAndCreate([
3337 * {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
3338 * {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
3339 * ]);
3340 *
3341 * expect(() => injector.get("one")).toThrowError();
3342 * ```
3343 *
3344 * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
3345 * @param {?} injector
3346 * @param {?} key
3347 * @return {?}
3348 */
3349function cyclicDependencyError(injector, key) {
3350 return injectionError(injector, key, function (keys) {
3351 return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
3352 });
3353}
3354/**
3355 * Thrown when a constructing type returns with an Error.
3356 *
3357 * The `InstantiationError` class contains the original error plus the dependency graph which caused
3358 * this object to be instantiated.
3359 *
3360 * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
3361 *
3362 * ```typescript
3363 * class A {
3364 * constructor() {
3365 * throw new Error('message');
3366 * }
3367 * }
3368 *
3369 * var injector = Injector.resolveAndCreate([A]);
3370 * try {
3371 * injector.get(A);
3372 * } catch (e) {
3373 * expect(e instanceof InstantiationError).toBe(true);
3374 * expect(e.originalException.message).toEqual("message");
3375 * expect(e.originalStack).toBeDefined();
3376 * }
3377 * ```
3378 * @param {?} injector
3379 * @param {?} originalException
3380 * @param {?} originalStack
3381 * @param {?} key
3382 * @return {?}
3383 */
3384function instantiationError(injector, originalException, originalStack, key) {
3385 return injectionError(injector, key, function (keys) {
3386 var /** @type {?} */ first = stringify(keys[0].token);
3387 return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
3388 }, originalException);
3389}
3390/**
3391 * Thrown when an object other then {\@link Provider} (or `Type`) is passed to {\@link Injector}
3392 * creation.
3393 *
3394 * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
3395 *
3396 * ```typescript
3397 * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
3398 * ```
3399 * @param {?} provider
3400 * @return {?}
3401 */
3402function invalidProviderError(provider) {
3403 return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
3404}
3405/**
3406 * Thrown when the class has no annotation information.
3407 *
3408 * Lack of annotation information prevents the {\@link Injector} from determining which dependencies
3409 * need to be injected into the constructor.
3410 *
3411 * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
3412 *
3413 * ```typescript
3414 * class A {
3415 * constructor(b) {}
3416 * }
3417 *
3418 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
3419 * ```
3420 *
3421 * This error is also thrown when the class not marked with {\@link Injectable} has parameter types.
3422 *
3423 * ```typescript
3424 * class B {}
3425 *
3426 * class A {
3427 * constructor(b:B) {} // no information about the parameter types of A is available at runtime.
3428 * }
3429 *
3430 * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
3431 * ```
3432 * \@stable
3433 * @param {?} typeOrFunc
3434 * @param {?} params
3435 * @return {?}
3436 */
3437function noAnnotationError(typeOrFunc, params) {
3438 var /** @type {?} */ signature = [];
3439 for (var /** @type {?} */ i = 0, /** @type {?} */ ii = params.length; i < ii; i++) {
3440 var /** @type {?} */ parameter = params[i];
3441 if (!parameter || parameter.length == 0) {
3442 signature.push('?');
3443 }
3444 else {
3445 signature.push(parameter.map(stringify).join(' '));
3446 }
3447 }
3448 return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
3449 signature.join(', ') + '). ' +
3450 'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
3451 stringify(typeOrFunc) + '\' is decorated with Injectable.');
3452}
3453/**
3454 * Thrown when getting an object by index.
3455 *
3456 * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
3457 *
3458 * ```typescript
3459 * class A {}
3460 *
3461 * var injector = Injector.resolveAndCreate([A]);
3462 *
3463 * expect(() => injector.getAt(100)).toThrowError();
3464 * ```
3465 * \@stable
3466 * @param {?} index
3467 * @return {?}
3468 */
3469function outOfBoundsError(index) {
3470 return Error("Index " + index + " is out-of-bounds.");
3471}
3472/**
3473 * Thrown when a multi provider and a regular provider are bound to the same token.
3474 *
3475 * ### Example
3476 *
3477 * ```typescript
3478 * expect(() => Injector.resolveAndCreate([
3479 * { provide: "Strings", useValue: "string1", multi: true},
3480 * { provide: "Strings", useValue: "string2", multi: false}
3481 * ])).toThrowError();
3482 * ```
3483 * @param {?} provider1
3484 * @param {?} provider2
3485 * @return {?}
3486 */
3487function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
3488 return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
3489}
3490/**
3491 * @license
3492 * Copyright Google Inc. All Rights Reserved.
3493 *
3494 * Use of this source code is governed by an MIT-style license that can be
3495 * found in the LICENSE file at https://angular.io/license
3496 */
3497/**
3498 * A unique object used for retrieving items from the {\@link ReflectiveInjector}.
3499 *
3500 * Keys have:
3501 * - a system-wide unique `id`.
3502 * - a `token`.
3503 *
3504 * `Key` is used internally by {\@link ReflectiveInjector} because its system-wide unique `id` allows
3505 * the
3506 * injector to store created objects in a more efficient way.
3507 *
3508 * `Key` should not be created directly. {\@link ReflectiveInjector} creates keys automatically when
3509 * resolving
3510 * providers.
3511 * \@experimental
3512 */
3513var ReflectiveKey = (function () {
3514 /**
3515 * Private
3516 * @param {?} token
3517 * @param {?} id
3518 */
3519 function ReflectiveKey(token, id) {
3520 this.token = token;
3521 this.id = id;
3522 if (!token) {
3523 throw new Error('Token must be defined!');
3524 }
3525 }
3526 Object.defineProperty(ReflectiveKey.prototype, "displayName", {
3527 /**
3528 * Returns a stringified token.
3529 * @return {?}
3530 */
3531 get: function () { return stringify(this.token); },
3532 enumerable: true,
3533 configurable: true
3534 });
3535 /**
3536 * Retrieves a `Key` for a token.
3537 * @param {?} token
3538 * @return {?}
3539 */
3540 ReflectiveKey.get = function (token) {
3541 return _globalKeyRegistry.get(resolveForwardRef(token));
3542 };
3543 Object.defineProperty(ReflectiveKey, "numberOfKeys", {
3544 /**
3545 * @return {?} the number of keys registered in the system.
3546 */
3547 get: function () { return _globalKeyRegistry.numberOfKeys; },
3548 enumerable: true,
3549 configurable: true
3550 });
3551 return ReflectiveKey;
3552}());
3553/**
3554 * \@internal
3555 */
3556var KeyRegistry = (function () {
3557 function KeyRegistry() {
3558 this._allKeys = new Map();
3559 }
3560 /**
3561 * @param {?} token
3562 * @return {?}
3563 */
3564 KeyRegistry.prototype.get = function (token) {
3565 if (token instanceof ReflectiveKey)
3566 return token;
3567 if (this._allKeys.has(token)) {
3568 return ((this._allKeys.get(token)));
3569 }
3570 var /** @type {?} */ newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
3571 this._allKeys.set(token, newKey);
3572 return newKey;
3573 };
3574 Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
3575 /**
3576 * @return {?}
3577 */
3578 get: function () { return this._allKeys.size; },
3579 enumerable: true,
3580 configurable: true
3581 });
3582 return KeyRegistry;
3583}());
3584var _globalKeyRegistry = new KeyRegistry();
3585/**
3586 * \@whatItDoes Represents a type that a Component or other object is instances of.
3587 *
3588 * \@description
3589 *
3590 * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
3591 * the `MyCustomComponent` constructor function.
3592 *
3593 * \@stable
3594 */
3595var Type = Function;
3596/**
3597 * @param {?} v
3598 * @return {?}
3599 */
3600function isType(v) {
3601 return typeof v === 'function';
3602}
3603/**
3604 * @license
3605 * Copyright Google Inc. All Rights Reserved.
3606 *
3607 * Use of this source code is governed by an MIT-style license that can be
3608 * found in the LICENSE file at https://angular.io/license
3609 */
3610/**
3611 * Attention: This regex has to hold even if the code is minified!
3612 */
3613var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
3614var ReflectionCapabilities = (function () {
3615 /**
3616 * @param {?=} reflect
3617 */
3618 function ReflectionCapabilities(reflect) {
3619 this._reflect = reflect || _global['Reflect'];
3620 }
3621 /**
3622 * @return {?}
3623 */
3624 ReflectionCapabilities.prototype.isReflectionEnabled = function () { return true; };
3625 /**
3626 * @template T
3627 * @param {?} t
3628 * @return {?}
3629 */
3630 ReflectionCapabilities.prototype.factory = function (t) { return function () {
3631 var args = [];
3632 for (var _i = 0; _i < arguments.length; _i++) {
3633 args[_i] = arguments[_i];
3634 }
3635 return new (t.bind.apply(t, [void 0].concat(args)))();
3636 }; };
3637 /**
3638 * \@internal
3639 * @param {?} paramTypes
3640 * @param {?} paramAnnotations
3641 * @return {?}
3642 */
3643 ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
3644 var /** @type {?} */ result;
3645 if (typeof paramTypes === 'undefined') {
3646 result = new Array(paramAnnotations.length);
3647 }
3648 else {
3649 result = new Array(paramTypes.length);
3650 }
3651 for (var /** @type {?} */ i = 0; i < result.length; i++) {
3652 // TS outputs Object for parameters without types, while Traceur omits
3653 // the annotations. For now we preserve the Traceur behavior to aid
3654 // migration, but this can be revisited.
3655 if (typeof paramTypes === 'undefined') {
3656 result[i] = [];
3657 }
3658 else if (paramTypes[i] != Object) {
3659 result[i] = [paramTypes[i]];
3660 }
3661 else {
3662 result[i] = [];
3663 }
3664 if (paramAnnotations && paramAnnotations[i] != null) {
3665 result[i] = result[i].concat(paramAnnotations[i]);
3666 }
3667 }
3668 return result;
3669 };
3670 /**
3671 * @param {?} type
3672 * @param {?} parentCtor
3673 * @return {?}
3674 */
3675 ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
3676 // If we have no decorators, we only have function.length as metadata.
3677 // In that case, to detect whether a child class declared an own constructor or not,
3678 // we need to look inside of that constructor to check whether it is
3679 // just calling the parent.
3680 // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
3681 // that sets 'design:paramtypes' to []
3682 // if a class inherits from another class but has no ctor declared itself.
3683 if (DELEGATE_CTOR.exec(type.toString())) {
3684 return null;
3685 }
3686 // Prefer the direct API.
3687 if (((type)).parameters && ((type)).parameters !== parentCtor.parameters) {
3688 return ((type)).parameters;
3689 }
3690 // API of tsickle for lowering decorators to properties on the class.
3691 var /** @type {?} */ tsickleCtorParams = ((type)).ctorParameters;
3692 if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
3693 // Newer tsickle uses a function closure
3694 // Retain the non-function case for compatibility with older tsickle
3695 var /** @type {?} */ ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
3696 var /** @type {?} */ paramTypes = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
3697 var /** @type {?} */ paramAnnotations = ctorParameters.map(function (ctorParam) { return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators); });
3698 return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
3699 }
3700 // API for metadata created by invoking the decorators.
3701 if (this._reflect != null && this._reflect.getOwnMetadata != null) {
3702 var /** @type {?} */ paramAnnotations = this._reflect.getOwnMetadata('parameters', type);
3703 var /** @type {?} */ paramTypes = this._reflect.getOwnMetadata('design:paramtypes', type);
3704 if (paramTypes || paramAnnotations) {
3705 return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
3706 }
3707 }
3708 // If a class has no decorators, at least create metadata
3709 // based on function.length.
3710 // Note: We know that this is a real constructor as we checked
3711 // the content of the constructor above.
3712 return new Array(((type.length))).fill(undefined);
3713 };
3714 /**
3715 * @param {?} type
3716 * @return {?}
3717 */
3718 ReflectionCapabilities.prototype.parameters = function (type) {
3719 // Note: only report metadata if we have at least one class decorator
3720 // to stay in sync with the static reflector.
3721 if (!isType(type)) {
3722 return [];
3723 }
3724 var /** @type {?} */ parentCtor = getParentCtor(type);
3725 var /** @type {?} */ parameters = this._ownParameters(type, parentCtor);
3726 if (!parameters && parentCtor !== Object) {
3727 parameters = this.parameters(parentCtor);
3728 }
3729 return parameters || [];
3730 };
3731 /**
3732 * @param {?} typeOrFunc
3733 * @param {?} parentCtor
3734 * @return {?}
3735 */
3736 ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
3737 // Prefer the direct API.
3738 if (((typeOrFunc)).annotations && ((typeOrFunc)).annotations !== parentCtor.annotations) {
3739 var /** @type {?} */ annotations = ((typeOrFunc)).annotations;
3740 if (typeof annotations === 'function' && annotations.annotations) {
3741 annotations = annotations.annotations;
3742 }
3743 return annotations;
3744 }
3745 // API of tsickle for lowering decorators to properties on the class.
3746 if (((typeOrFunc)).decorators && ((typeOrFunc)).decorators !== parentCtor.decorators) {
3747 return convertTsickleDecoratorIntoMetadata(((typeOrFunc)).decorators);
3748 }
3749 // API for metadata created by invoking the decorators.
3750 if (this._reflect && this._reflect.getOwnMetadata) {
3751 return this._reflect.getOwnMetadata('annotations', typeOrFunc);
3752 }
3753 return null;
3754 };
3755 /**
3756 * @param {?} typeOrFunc
3757 * @return {?}
3758 */
3759 ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
3760 if (!isType(typeOrFunc)) {
3761 return [];
3762 }
3763 var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
3764 var /** @type {?} */ ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
3765 var /** @type {?} */ parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
3766 return parentAnnotations.concat(ownAnnotations);
3767 };
3768 /**
3769 * @param {?} typeOrFunc
3770 * @param {?} parentCtor
3771 * @return {?}
3772 */
3773 ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
3774 // Prefer the direct API.
3775 if (((typeOrFunc)).propMetadata &&
3776 ((typeOrFunc)).propMetadata !== parentCtor.propMetadata) {
3777 var /** @type {?} */ propMetadata = ((typeOrFunc)).propMetadata;
3778 if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
3779 propMetadata = propMetadata.propMetadata;
3780 }
3781 return propMetadata;
3782 }
3783 // API of tsickle for lowering decorators to properties on the class.
3784 if (((typeOrFunc)).propDecorators &&
3785 ((typeOrFunc)).propDecorators !== parentCtor.propDecorators) {
3786 var /** @type {?} */ propDecorators_1 = ((typeOrFunc)).propDecorators;
3787 var /** @type {?} */ propMetadata_1 = ({});
3788 Object.keys(propDecorators_1).forEach(function (prop) {
3789 propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
3790 });
3791 return propMetadata_1;
3792 }
3793 // API for metadata created by invoking the decorators.
3794 if (this._reflect && this._reflect.getOwnMetadata) {
3795 return this._reflect.getOwnMetadata('propMetadata', typeOrFunc);
3796 }
3797 return null;
3798 };
3799 /**
3800 * @param {?} typeOrFunc
3801 * @return {?}
3802 */
3803 ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
3804 if (!isType(typeOrFunc)) {
3805 return {};
3806 }
3807 var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
3808 var /** @type {?} */ propMetadata = {};
3809 if (parentCtor !== Object) {
3810 var /** @type {?} */ parentPropMetadata_1 = this.propMetadata(parentCtor);
3811 Object.keys(parentPropMetadata_1).forEach(function (propName) {
3812 propMetadata[propName] = parentPropMetadata_1[propName];
3813 });
3814 }
3815 var /** @type {?} */ ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
3816 if (ownPropMetadata) {
3817 Object.keys(ownPropMetadata).forEach(function (propName) {
3818 var /** @type {?} */ decorators = [];
3819 if (propMetadata.hasOwnProperty(propName)) {
3820 decorators.push.apply(decorators, propMetadata[propName]);
3821 }
3822 decorators.push.apply(decorators, ownPropMetadata[propName]);
3823 propMetadata[propName] = decorators;
3824 });
3825 }
3826 return propMetadata;
3827 };
3828 /**
3829 * @param {?} type
3830 * @param {?} lcProperty
3831 * @return {?}
3832 */
3833 ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
3834 return type instanceof Type && lcProperty in type.prototype;
3835 };
3836 /**
3837 * @param {?} name
3838 * @return {?}
3839 */
3840 ReflectionCapabilities.prototype.getter = function (name) { return (new Function('o', 'return o.' + name + ';')); };
3841 /**
3842 * @param {?} name
3843 * @return {?}
3844 */
3845 ReflectionCapabilities.prototype.setter = function (name) {
3846 return (new Function('o', 'v', 'return o.' + name + ' = v;'));
3847 };
3848 /**
3849 * @param {?} name
3850 * @return {?}
3851 */
3852 ReflectionCapabilities.prototype.method = function (name) {
3853 var /** @type {?} */ functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
3854 return (new Function('o', 'args', functionBody));
3855 };
3856 /**
3857 * @param {?} type
3858 * @return {?}
3859 */
3860 ReflectionCapabilities.prototype.importUri = function (type) {
3861 // StaticSymbol
3862 if (typeof type === 'object' && type['filePath']) {
3863 return type['filePath'];
3864 }
3865 // Runtime type
3866 return "./" + stringify(type);
3867 };
3868 /**
3869 * @param {?} type
3870 * @return {?}
3871 */
3872 ReflectionCapabilities.prototype.resourceUri = function (type) { return "./" + stringify(type); };
3873 /**
3874 * @param {?} name
3875 * @param {?} moduleUrl
3876 * @param {?} members
3877 * @param {?} runtime
3878 * @return {?}
3879 */
3880 ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
3881 return runtime;
3882 };
3883 /**
3884 * @param {?} enumIdentifier
3885 * @param {?} name
3886 * @return {?}
3887 */
3888 ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) { return enumIdentifier[name]; };
3889 return ReflectionCapabilities;
3890}());
3891/**
3892 * @param {?} decoratorInvocations
3893 * @return {?}
3894 */
3895function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
3896 if (!decoratorInvocations) {
3897 return [];
3898 }
3899 return decoratorInvocations.map(function (decoratorInvocation) {
3900 var /** @type {?} */ decoratorType = decoratorInvocation.type;
3901 var /** @type {?} */ annotationCls = decoratorType.annotationCls;
3902 var /** @type {?} */ annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
3903 return new (annotationCls.bind.apply(annotationCls, [void 0].concat(annotationArgs)))();
3904 });
3905}
3906/**
3907 * @param {?} ctor
3908 * @return {?}
3909 */
3910function getParentCtor(ctor) {
3911 var /** @type {?} */ parentProto = Object.getPrototypeOf(ctor.prototype);
3912 var /** @type {?} */ parentCtor = parentProto ? parentProto.constructor : null;
3913 // Note: We always use `Object` as the null value
3914 // to simplify checking later on.
3915 return parentCtor || Object;
3916}
3917/**
3918 * @license
3919 * Copyright Google Inc. All Rights Reserved.
3920 *
3921 * Use of this source code is governed by an MIT-style license that can be
3922 * found in the LICENSE file at https://angular.io/license
3923 */
3924/**
3925 * Provides access to reflection data about symbols. Used internally by Angular
3926 * to power dependency injection and compilation.
3927 */
3928var Reflector = (function () {
3929 /**
3930 * @param {?} reflectionCapabilities
3931 */
3932 function Reflector(reflectionCapabilities) {
3933 this.reflectionCapabilities = reflectionCapabilities;
3934 }
3935 /**
3936 * @param {?} caps
3937 * @return {?}
3938 */
3939 Reflector.prototype.updateCapabilities = function (caps) { this.reflectionCapabilities = caps; };
3940 /**
3941 * @param {?} type
3942 * @return {?}
3943 */
3944 Reflector.prototype.factory = function (type) { return this.reflectionCapabilities.factory(type); };
3945 /**
3946 * @param {?} typeOrFunc
3947 * @return {?}
3948 */
3949 Reflector.prototype.parameters = function (typeOrFunc) {
3950 return this.reflectionCapabilities.parameters(typeOrFunc);
3951 };
3952 /**
3953 * @param {?} typeOrFunc
3954 * @return {?}
3955 */
3956 Reflector.prototype.annotations = function (typeOrFunc) {
3957 return this.reflectionCapabilities.annotations(typeOrFunc);
3958 };
3959 /**
3960 * @param {?} typeOrFunc
3961 * @return {?}
3962 */
3963 Reflector.prototype.propMetadata = function (typeOrFunc) {
3964 return this.reflectionCapabilities.propMetadata(typeOrFunc);
3965 };
3966 /**
3967 * @param {?} type
3968 * @param {?} lcProperty
3969 * @return {?}
3970 */
3971 Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
3972 return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
3973 };
3974 /**
3975 * @param {?} name
3976 * @return {?}
3977 */
3978 Reflector.prototype.getter = function (name) { return this.reflectionCapabilities.getter(name); };
3979 /**
3980 * @param {?} name
3981 * @return {?}
3982 */
3983 Reflector.prototype.setter = function (name) { return this.reflectionCapabilities.setter(name); };
3984 /**
3985 * @param {?} name
3986 * @return {?}
3987 */
3988 Reflector.prototype.method = function (name) { return this.reflectionCapabilities.method(name); };
3989 /**
3990 * @param {?} type
3991 * @return {?}
3992 */
3993 Reflector.prototype.importUri = function (type) { return this.reflectionCapabilities.importUri(type); };
3994 /**
3995 * @param {?} type
3996 * @return {?}
3997 */
3998 Reflector.prototype.resourceUri = function (type) { return this.reflectionCapabilities.resourceUri(type); };
3999 /**
4000 * @param {?} name
4001 * @param {?} moduleUrl
4002 * @param {?} members
4003 * @param {?} runtime
4004 * @return {?}
4005 */
4006 Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
4007 return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
4008 };
4009 /**
4010 * @param {?} identifier
4011 * @param {?} name
4012 * @return {?}
4013 */
4014 Reflector.prototype.resolveEnum = function (identifier, name) {
4015 return this.reflectionCapabilities.resolveEnum(identifier, name);
4016 };
4017 return Reflector;
4018}());
4019/**
4020 * @license
4021 * Copyright Google Inc. All Rights Reserved.
4022 *
4023 * Use of this source code is governed by an MIT-style license that can be
4024 * found in the LICENSE file at https://angular.io/license
4025 */
4026/**
4027 * The {\@link Reflector} used internally in Angular to access metadata
4028 * about symbols.
4029 */
4030var reflector = new Reflector(new ReflectionCapabilities());
4031/**
4032 * @license
4033 * Copyright Google Inc. All Rights Reserved.
4034 *
4035 * Use of this source code is governed by an MIT-style license that can be
4036 * found in the LICENSE file at https://angular.io/license
4037 */
4038/**
4039 * `Dependency` is used by the framework to extend DI.
4040 * This is internal to Angular and should not be used directly.
4041 */
4042var ReflectiveDependency = (function () {
4043 /**
4044 * @param {?} key
4045 * @param {?} optional
4046 * @param {?} visibility
4047 */
4048 function ReflectiveDependency(key, optional, visibility) {
4049 this.key = key;
4050 this.optional = optional;
4051 this.visibility = visibility;
4052 }
4053 /**
4054 * @param {?} key
4055 * @return {?}
4056 */
4057 ReflectiveDependency.fromKey = function (key) {
4058 return new ReflectiveDependency(key, false, null);
4059 };
4060 return ReflectiveDependency;
4061}());
4062var _EMPTY_LIST = [];
4063var ResolvedReflectiveProvider_ = (function () {
4064 /**
4065 * @param {?} key
4066 * @param {?} resolvedFactories
4067 * @param {?} multiProvider
4068 */
4069 function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
4070 this.key = key;
4071 this.resolvedFactories = resolvedFactories;
4072 this.multiProvider = multiProvider;
4073 }
4074 Object.defineProperty(ResolvedReflectiveProvider_.prototype, "resolvedFactory", {
4075 /**
4076 * @return {?}
4077 */
4078 get: function () { return this.resolvedFactories[0]; },
4079 enumerable: true,
4080 configurable: true
4081 });
4082 return ResolvedReflectiveProvider_;
4083}());
4084/**
4085 * An internal resolved representation of a factory function created by resolving {\@link
4086 * Provider}.
4087 * \@experimental
4088 */
4089var ResolvedReflectiveFactory = (function () {
4090 /**
4091 * @param {?} factory
4092 * @param {?} dependencies
4093 */
4094 function ResolvedReflectiveFactory(factory, dependencies) {
4095 this.factory = factory;
4096 this.dependencies = dependencies;
4097 }
4098 return ResolvedReflectiveFactory;
4099}());
4100/**
4101 * Resolve a single provider.
4102 * @param {?} provider
4103 * @return {?}
4104 */
4105function resolveReflectiveFactory(provider) {
4106 var /** @type {?} */ factoryFn;
4107 var /** @type {?} */ resolvedDeps;
4108 if (provider.useClass) {
4109 var /** @type {?} */ useClass = resolveForwardRef(provider.useClass);
4110 factoryFn = reflector.factory(useClass);
4111 resolvedDeps = _dependenciesFor(useClass);
4112 }
4113 else if (provider.useExisting) {
4114 factoryFn = function (aliasInstance) { return aliasInstance; };
4115 resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
4116 }
4117 else if (provider.useFactory) {
4118 factoryFn = provider.useFactory;
4119 resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
4120 }
4121 else {
4122 factoryFn = function () { return provider.useValue; };
4123 resolvedDeps = _EMPTY_LIST;
4124 }
4125 return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
4126}
4127/**
4128 * Converts the {\@link Provider} into {\@link ResolvedProvider}.
4129 *
4130 * {\@link Injector} internally only uses {\@link ResolvedProvider}, {\@link Provider} contains
4131 * convenience provider syntax.
4132 * @param {?} provider
4133 * @return {?}
4134 */
4135function resolveReflectiveProvider(provider) {
4136 return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
4137}
4138/**
4139 * Resolve a list of Providers.
4140 * @param {?} providers
4141 * @return {?}
4142 */
4143function resolveReflectiveProviders(providers) {
4144 var /** @type {?} */ normalized = _normalizeProviders(providers, []);
4145 var /** @type {?} */ resolved = normalized.map(resolveReflectiveProvider);
4146 var /** @type {?} */ resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
4147 return Array.from(resolvedProviderMap.values());
4148}
4149/**
4150 * Merges a list of ResolvedProviders into a list where
4151 * each key is contained exactly once and multi providers
4152 * have been merged.
4153 * @param {?} providers
4154 * @param {?} normalizedProvidersMap
4155 * @return {?}
4156 */
4157function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
4158 for (var /** @type {?} */ i = 0; i < providers.length; i++) {
4159 var /** @type {?} */ provider = providers[i];
4160 var /** @type {?} */ existing = normalizedProvidersMap.get(provider.key.id);
4161 if (existing) {
4162 if (provider.multiProvider !== existing.multiProvider) {
4163 throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
4164 }
4165 if (provider.multiProvider) {
4166 for (var /** @type {?} */ j = 0; j < provider.resolvedFactories.length; j++) {
4167 existing.resolvedFactories.push(provider.resolvedFactories[j]);
4168 }
4169 }
4170 else {
4171 normalizedProvidersMap.set(provider.key.id, provider);
4172 }
4173 }
4174 else {
4175 var /** @type {?} */ resolvedProvider = void 0;
4176 if (provider.multiProvider) {
4177 resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
4178 }
4179 else {
4180 resolvedProvider = provider;
4181 }
4182 normalizedProvidersMap.set(provider.key.id, resolvedProvider);
4183 }
4184 }
4185 return normalizedProvidersMap;
4186}
4187/**
4188 * @param {?} providers
4189 * @param {?} res
4190 * @return {?}
4191 */
4192function _normalizeProviders(providers, res) {
4193 providers.forEach(function (b) {
4194 if (b instanceof Type) {
4195 res.push({ provide: b, useClass: b });
4196 }
4197 else if (b && typeof b == 'object' && ((b)).provide !== undefined) {
4198 res.push(/** @type {?} */ (b));
4199 }
4200 else if (b instanceof Array) {
4201 _normalizeProviders(b, res);
4202 }
4203 else {
4204 throw invalidProviderError(b);
4205 }
4206 });
4207 return res;
4208}
4209/**
4210 * @param {?} typeOrFunc
4211 * @param {?=} dependencies
4212 * @return {?}
4213 */
4214function constructDependencies(typeOrFunc, dependencies) {
4215 if (!dependencies) {
4216 return _dependenciesFor(typeOrFunc);
4217 }
4218 else {
4219 var /** @type {?} */ params_1 = dependencies.map(function (t) { return [t]; });
4220 return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
4221 }
4222}
4223/**
4224 * @param {?} typeOrFunc
4225 * @return {?}
4226 */
4227function _dependenciesFor(typeOrFunc) {
4228 var /** @type {?} */ params = reflector.parameters(typeOrFunc);
4229 if (!params)
4230 return [];
4231 if (params.some(function (p) { return p == null; })) {
4232 throw noAnnotationError(typeOrFunc, params);
4233 }
4234 return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
4235}
4236/**
4237 * @param {?} typeOrFunc
4238 * @param {?} metadata
4239 * @param {?} params
4240 * @return {?}
4241 */
4242function _extractToken(typeOrFunc, metadata, params) {
4243 var /** @type {?} */ token = null;
4244 var /** @type {?} */ optional = false;
4245 if (!Array.isArray(metadata)) {
4246 if (metadata instanceof Inject) {
4247 return _createDependency(metadata.token, optional, null);
4248 }
4249 else {
4250 return _createDependency(metadata, optional, null);
4251 }
4252 }
4253 var /** @type {?} */ visibility = null;
4254 for (var /** @type {?} */ i = 0; i < metadata.length; ++i) {
4255 var /** @type {?} */ paramMetadata = metadata[i];
4256 if (paramMetadata instanceof Type) {
4257 token = paramMetadata;
4258 }
4259 else if (paramMetadata instanceof Inject) {
4260 token = paramMetadata.token;
4261 }
4262 else if (paramMetadata instanceof Optional) {
4263 optional = true;
4264 }
4265 else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
4266 visibility = paramMetadata;
4267 }
4268 else if (paramMetadata instanceof InjectionToken) {
4269 token = paramMetadata;
4270 }
4271 }
4272 token = resolveForwardRef(token);
4273 if (token != null) {
4274 return _createDependency(token, optional, visibility);
4275 }
4276 else {
4277 throw noAnnotationError(typeOrFunc, params);
4278 }
4279}
4280/**
4281 * @param {?} token
4282 * @param {?} optional
4283 * @param {?} visibility
4284 * @return {?}
4285 */
4286function _createDependency(token, optional, visibility) {
4287 return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
4288}
4289/**
4290 * @license
4291 * Copyright Google Inc. All Rights Reserved.
4292 *
4293 * Use of this source code is governed by an MIT-style license that can be
4294 * found in the LICENSE file at https://angular.io/license
4295 */
4296// Threshold for the dynamic version
4297var UNDEFINED = new Object();
4298/**
4299 * A ReflectiveDependency injection container used for instantiating objects and resolving
4300 * dependencies.
4301 *
4302 * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
4303 * constructor dependencies.
4304 *
4305 * In typical use, application code asks for the dependencies in the constructor and they are
4306 * resolved by the `Injector`.
4307 *
4308 * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview))
4309 *
4310 * The following example creates an `Injector` configured to create `Engine` and `Car`.
4311 *
4312 * ```typescript
4313 * \@Injectable()
4314 * class Engine {
4315 * }
4316 *
4317 * \@Injectable()
4318 * class Car {
4319 * constructor(public engine:Engine) {}
4320 * }
4321 *
4322 * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
4323 * var car = injector.get(Car);
4324 * expect(car instanceof Car).toBe(true);
4325 * expect(car.engine instanceof Engine).toBe(true);
4326 * ```
4327 *
4328 * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
4329 * resolve all of the object's dependencies automatically.
4330 *
4331 * \@stable
4332 * @abstract
4333 */
4334var ReflectiveInjector = (function () {
4335 function ReflectiveInjector() {
4336 }
4337 /**
4338 * Turns an array of provider definitions into an array of resolved providers.
4339 *
4340 * A resolution is a process of flattening multiple nested arrays and converting individual
4341 * providers into an array of {\@link ResolvedReflectiveProvider}s.
4342 *
4343 * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
4344 *
4345 * ```typescript
4346 * \@Injectable()
4347 * class Engine {
4348 * }
4349 *
4350 * \@Injectable()
4351 * class Car {
4352 * constructor(public engine:Engine) {}
4353 * }
4354 *
4355 * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
4356 *
4357 * expect(providers.length).toEqual(2);
4358 *
4359 * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
4360 * expect(providers[0].key.displayName).toBe("Car");
4361 * expect(providers[0].dependencies.length).toEqual(1);
4362 * expect(providers[0].factory).toBeDefined();
4363 *
4364 * expect(providers[1].key.displayName).toBe("Engine");
4365 * });
4366 * ```
4367 *
4368 * See {\@link ReflectiveInjector#fromResolvedProviders} for more info.
4369 * @param {?} providers
4370 * @return {?}
4371 */
4372 ReflectiveInjector.resolve = function (providers) {
4373 return resolveReflectiveProviders(providers);
4374 };
4375 /**
4376 * Resolves an array of providers and creates an injector from those providers.
4377 *
4378 * The passed-in providers can be an array of `Type`, {\@link Provider},
4379 * or a recursive array of more providers.
4380 *
4381 * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
4382 *
4383 * ```typescript
4384 * \@Injectable()
4385 * class Engine {
4386 * }
4387 *
4388 * \@Injectable()
4389 * class Car {
4390 * constructor(public engine:Engine) {}
4391 * }
4392 *
4393 * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
4394 * expect(injector.get(Car) instanceof Car).toBe(true);
4395 * ```
4396 *
4397 * This function is slower than the corresponding `fromResolvedProviders`
4398 * because it needs to resolve the passed-in providers first.
4399 * See {\@link ReflectiveInjector#resolve} and {\@link ReflectiveInjector#fromResolvedProviders}.
4400 * @param {?} providers
4401 * @param {?=} parent
4402 * @return {?}
4403 */
4404 ReflectiveInjector.resolveAndCreate = function (providers, parent) {
4405 var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
4406 return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
4407 };
4408 /**
4409 * Creates an injector from previously resolved providers.
4410 *
4411 * This API is the recommended way to construct injectors in performance-sensitive parts.
4412 *
4413 * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
4414 *
4415 * ```typescript
4416 * \@Injectable()
4417 * class Engine {
4418 * }
4419 *
4420 * \@Injectable()
4421 * class Car {
4422 * constructor(public engine:Engine) {}
4423 * }
4424 *
4425 * var providers = ReflectiveInjector.resolve([Car, Engine]);
4426 * var injector = ReflectiveInjector.fromResolvedProviders(providers);
4427 * expect(injector.get(Car) instanceof Car).toBe(true);
4428 * ```
4429 * \@experimental
4430 * @param {?} providers
4431 * @param {?=} parent
4432 * @return {?}
4433 */
4434 ReflectiveInjector.fromResolvedProviders = function (providers, parent) {
4435 return new ReflectiveInjector_(providers, parent);
4436 };
4437 /**
4438 * Parent of this injector.
4439 *
4440 * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
4441 * -->
4442 *
4443 * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
4444 *
4445 * ```typescript
4446 * var parent = ReflectiveInjector.resolveAndCreate([]);
4447 * var child = parent.resolveAndCreateChild([]);
4448 * expect(child.parent).toBe(parent);
4449 * ```
4450 * @abstract
4451 * @return {?}
4452 */
4453 ReflectiveInjector.prototype.parent = function () { };
4454 /**
4455 * Resolves an array of providers and creates a child injector from those providers.
4456 *
4457 * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
4458 * -->
4459 *
4460 * The passed-in providers can be an array of `Type`, {\@link Provider},
4461 * or a recursive array of more providers.
4462 *
4463 * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
4464 *
4465 * ```typescript
4466 * class ParentProvider {}
4467 * class ChildProvider {}
4468 *
4469 * var parent = ReflectiveInjector.resolveAndCreate([ParentProvider]);
4470 * var child = parent.resolveAndCreateChild([ChildProvider]);
4471 *
4472 * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
4473 * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
4474 * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
4475 * ```
4476 *
4477 * This function is slower than the corresponding `createChildFromResolved`
4478 * because it needs to resolve the passed-in providers first.
4479 * See {\@link ReflectiveInjector#resolve} and {\@link ReflectiveInjector#createChildFromResolved}.
4480 * @abstract
4481 * @param {?} providers
4482 * @return {?}
4483 */
4484 ReflectiveInjector.prototype.resolveAndCreateChild = function (providers) { };
4485 /**
4486 * Creates a child injector from previously resolved providers.
4487 *
4488 * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
4489 * -->
4490 *
4491 * This API is the recommended way to construct injectors in performance-sensitive parts.
4492 *
4493 * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
4494 *
4495 * ```typescript
4496 * class ParentProvider {}
4497 * class ChildProvider {}
4498 *
4499 * var parentProviders = ReflectiveInjector.resolve([ParentProvider]);
4500 * var childProviders = ReflectiveInjector.resolve([ChildProvider]);
4501 *
4502 * var parent = ReflectiveInjector.fromResolvedProviders(parentProviders);
4503 * var child = parent.createChildFromResolved(childProviders);
4504 *
4505 * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
4506 * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
4507 * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
4508 * ```
4509 * @abstract
4510 * @param {?} providers
4511 * @return {?}
4512 */
4513 ReflectiveInjector.prototype.createChildFromResolved = function (providers) { };
4514 /**
4515 * Resolves a provider and instantiates an object in the context of the injector.
4516 *
4517 * The created object does not get cached by the injector.
4518 *
4519 * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
4520 *
4521 * ```typescript
4522 * \@Injectable()
4523 * class Engine {
4524 * }
4525 *
4526 * \@Injectable()
4527 * class Car {
4528 * constructor(public engine:Engine) {}
4529 * }
4530 *
4531 * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
4532 *
4533 * var car = injector.resolveAndInstantiate(Car);
4534 * expect(car.engine).toBe(injector.get(Engine));
4535 * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
4536 * ```
4537 * @abstract
4538 * @param {?} provider
4539 * @return {?}
4540 */
4541 ReflectiveInjector.prototype.resolveAndInstantiate = function (provider) { };
4542 /**
4543 * Instantiates an object using a resolved provider in the context of the injector.
4544 *
4545 * The created object does not get cached by the injector.
4546 *
4547 * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
4548 *
4549 * ```typescript
4550 * \@Injectable()
4551 * class Engine {
4552 * }
4553 *
4554 * \@Injectable()
4555 * class Car {
4556 * constructor(public engine:Engine) {}
4557 * }
4558 *
4559 * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
4560 * var carProvider = ReflectiveInjector.resolve([Car])[0];
4561 * var car = injector.instantiateResolved(carProvider);
4562 * expect(car.engine).toBe(injector.get(Engine));
4563 * expect(car).not.toBe(injector.instantiateResolved(carProvider));
4564 * ```
4565 * @abstract
4566 * @param {?} provider
4567 * @return {?}
4568 */
4569 ReflectiveInjector.prototype.instantiateResolved = function (provider) { };
4570 /**
4571 * @abstract
4572 * @param {?} token
4573 * @param {?=} notFoundValue
4574 * @return {?}
4575 */
4576 ReflectiveInjector.prototype.get = function (token, notFoundValue) { };
4577 return ReflectiveInjector;
4578}());
4579var ReflectiveInjector_ = (function () {
4580 /**
4581 * Private
4582 * @param {?} _providers
4583 * @param {?=} _parent
4584 */
4585 function ReflectiveInjector_(_providers, _parent) {
4586 /**
4587 * \@internal
4588 */
4589 this._constructionCounter = 0;
4590 this._providers = _providers;
4591 this._parent = _parent || null;
4592 var len = _providers.length;
4593 this.keyIds = new Array(len);
4594 this.objs = new Array(len);
4595 for (var i = 0; i < len; i++) {
4596 this.keyIds[i] = _providers[i].key.id;
4597 this.objs[i] = UNDEFINED;
4598 }
4599 }
4600 /**
4601 * @param {?} token
4602 * @param {?=} notFoundValue
4603 * @return {?}
4604 */
4605 ReflectiveInjector_.prototype.get = function (token, notFoundValue) {
4606 if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
4607 return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
4608 };
4609 Object.defineProperty(ReflectiveInjector_.prototype, "parent", {
4610 /**
4611 * @return {?}
4612 */
4613 get: function () { return this._parent; },
4614 enumerable: true,
4615 configurable: true
4616 });
4617 /**
4618 * @param {?} providers
4619 * @return {?}
4620 */
4621 ReflectiveInjector_.prototype.resolveAndCreateChild = function (providers) {
4622 var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
4623 return this.createChildFromResolved(ResolvedReflectiveProviders);
4624 };
4625 /**
4626 * @param {?} providers
4627 * @return {?}
4628 */
4629 ReflectiveInjector_.prototype.createChildFromResolved = function (providers) {
4630 var /** @type {?} */ inj = new ReflectiveInjector_(providers);
4631 inj._parent = this;
4632 return inj;
4633 };
4634 /**
4635 * @param {?} provider
4636 * @return {?}
4637 */
4638 ReflectiveInjector_.prototype.resolveAndInstantiate = function (provider) {
4639 return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
4640 };
4641 /**
4642 * @param {?} provider
4643 * @return {?}
4644 */
4645 ReflectiveInjector_.prototype.instantiateResolved = function (provider) {
4646 return this._instantiateProvider(provider);
4647 };
4648 /**
4649 * @param {?} index
4650 * @return {?}
4651 */
4652 ReflectiveInjector_.prototype.getProviderAtIndex = function (index) {
4653 if (index < 0 || index >= this._providers.length) {
4654 throw outOfBoundsError(index);
4655 }
4656 return this._providers[index];
4657 };
4658 /**
4659 * \@internal
4660 * @param {?} provider
4661 * @return {?}
4662 */
4663 ReflectiveInjector_.prototype._new = function (provider) {
4664 if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
4665 throw cyclicDependencyError(this, provider.key);
4666 }
4667 return this._instantiateProvider(provider);
4668 };
4669 /**
4670 * @return {?}
4671 */
4672 ReflectiveInjector_.prototype._getMaxNumberOfObjects = function () { return this.objs.length; };
4673 /**
4674 * @param {?} provider
4675 * @return {?}
4676 */
4677 ReflectiveInjector_.prototype._instantiateProvider = function (provider) {
4678 if (provider.multiProvider) {
4679 var /** @type {?} */ res = new Array(provider.resolvedFactories.length);
4680 for (var /** @type {?} */ i = 0; i < provider.resolvedFactories.length; ++i) {
4681 res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
4682 }
4683 return res;
4684 }
4685 else {
4686 return this._instantiate(provider, provider.resolvedFactories[0]);
4687 }
4688 };
4689 /**
4690 * @param {?} provider
4691 * @param {?} ResolvedReflectiveFactory
4692 * @return {?}
4693 */
4694 ReflectiveInjector_.prototype._instantiate = function (provider, ResolvedReflectiveFactory$$1) {
4695 var _this = this;
4696 var /** @type {?} */ factory = ResolvedReflectiveFactory$$1.factory;
4697 var /** @type {?} */ deps;
4698 try {
4699 deps =
4700 ResolvedReflectiveFactory$$1.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
4701 }
4702 catch (e) {
4703 if (e.addKey) {
4704 e.addKey(this, provider.key);
4705 }
4706 throw e;
4707 }
4708 var /** @type {?} */ obj;
4709 try {
4710 obj = factory.apply(void 0, deps);
4711 }
4712 catch (e) {
4713 throw instantiationError(this, e, e.stack, provider.key);
4714 }
4715 return obj;
4716 };
4717 /**
4718 * @param {?} dep
4719 * @return {?}
4720 */
4721 ReflectiveInjector_.prototype._getByReflectiveDependency = function (dep) {
4722 return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
4723 };
4724 /**
4725 * @param {?} key
4726 * @param {?} visibility
4727 * @param {?} notFoundValue
4728 * @return {?}
4729 */
4730 ReflectiveInjector_.prototype._getByKey = function (key, visibility, notFoundValue) {
4731 if (key === INJECTOR_KEY) {
4732 return this;
4733 }
4734 if (visibility instanceof Self) {
4735 return this._getByKeySelf(key, notFoundValue);
4736 }
4737 else {
4738 return this._getByKeyDefault(key, notFoundValue, visibility);
4739 }
4740 };
4741 /**
4742 * @param {?} keyId
4743 * @return {?}
4744 */
4745 ReflectiveInjector_.prototype._getObjByKeyId = function (keyId) {
4746 for (var /** @type {?} */ i = 0; i < this.keyIds.length; i++) {
4747 if (this.keyIds[i] === keyId) {
4748 if (this.objs[i] === UNDEFINED) {
4749 this.objs[i] = this._new(this._providers[i]);
4750 }
4751 return this.objs[i];
4752 }
4753 }
4754 return UNDEFINED;
4755 };
4756 /**
4757 * \@internal
4758 * @param {?} key
4759 * @param {?} notFoundValue
4760 * @return {?}
4761 */
4762 ReflectiveInjector_.prototype._throwOrNull = function (key, notFoundValue) {
4763 if (notFoundValue !== THROW_IF_NOT_FOUND) {
4764 return notFoundValue;
4765 }
4766 else {
4767 throw noProviderError(this, key);
4768 }
4769 };
4770 /**
4771 * \@internal
4772 * @param {?} key
4773 * @param {?} notFoundValue
4774 * @return {?}
4775 */
4776 ReflectiveInjector_.prototype._getByKeySelf = function (key, notFoundValue) {
4777 var /** @type {?} */ obj = this._getObjByKeyId(key.id);
4778 return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
4779 };
4780 /**
4781 * \@internal
4782 * @param {?} key
4783 * @param {?} notFoundValue
4784 * @param {?} visibility
4785 * @return {?}
4786 */
4787 ReflectiveInjector_.prototype._getByKeyDefault = function (key, notFoundValue, visibility) {
4788 var /** @type {?} */ inj;
4789 if (visibility instanceof SkipSelf) {
4790 inj = this._parent;
4791 }
4792 else {
4793 inj = this;
4794 }
4795 while (inj instanceof ReflectiveInjector_) {
4796 var /** @type {?} */ inj_ = (inj);
4797 var /** @type {?} */ obj = inj_._getObjByKeyId(key.id);
4798 if (obj !== UNDEFINED)
4799 return obj;
4800 inj = inj_._parent;
4801 }
4802 if (inj !== null) {
4803 return inj.get(key.token, notFoundValue);
4804 }
4805 else {
4806 return this._throwOrNull(key, notFoundValue);
4807 }
4808 };
4809 Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
4810 /**
4811 * @return {?}
4812 */
4813 get: function () {
4814 var /** @type {?} */ providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
4815 .join(', ');
4816 return "ReflectiveInjector(providers: [" + providers + "])";
4817 },
4818 enumerable: true,
4819 configurable: true
4820 });
4821 /**
4822 * @return {?}
4823 */
4824 ReflectiveInjector_.prototype.toString = function () { return this.displayName; };
4825 return ReflectiveInjector_;
4826}());
4827var INJECTOR_KEY = ReflectiveKey.get(Injector);
4828/**
4829 * @param {?} injector
4830 * @param {?} fn
4831 * @return {?}
4832 */
4833function _mapProviders(injector, fn) {
4834 var /** @type {?} */ res = new Array(injector._providers.length);
4835 for (var /** @type {?} */ i = 0; i < injector._providers.length; ++i) {
4836 res[i] = fn(injector.getProviderAtIndex(i));
4837 }
4838 return res;
4839}
4840/**
4841 * @license
4842 * Copyright Google Inc. All Rights Reserved.
4843 *
4844 * Use of this source code is governed by an MIT-style license that can be
4845 * found in the LICENSE file at https://angular.io/license
4846 */
4847/**
4848 * @module
4849 * @description
4850 * The `di` module provides dependency injection container services.
4851 */
4852/**
4853 * @license
4854 * Copyright Google Inc. All Rights Reserved.
4855 *
4856 * Use of this source code is governed by an MIT-style license that can be
4857 * found in the LICENSE file at https://angular.io/license
4858 */
4859/**
4860 * Determine if the argument is shaped like a Promise
4861 * @param {?} obj
4862 * @return {?}
4863 */
4864function isPromise(obj) {
4865 // allow any Promise/A+ compliant thenable.
4866 // It's up to the caller to ensure that obj.then conforms to the spec
4867 return !!obj && typeof obj.then === 'function';
4868}
4869/**
4870 * Determine if the argument is an Observable
4871 * @param {?} obj
4872 * @return {?}
4873 */
4874function isObservable(obj) {
4875 // TODO use Symbol.observable when https://github.com/ReactiveX/rxjs/issues/2415 will be resolved
4876 return !!obj && typeof obj.subscribe === 'function';
4877}
4878/**
4879 * @license
4880 * Copyright Google Inc. All Rights Reserved.
4881 *
4882 * Use of this source code is governed by an MIT-style license that can be
4883 * found in the LICENSE file at https://angular.io/license
4884 */
4885/**
4886 * A function that will be executed when an application is initialized.
4887 * \@experimental
4888 */
4889var APP_INITIALIZER = new InjectionToken('Application Initializer');
4890/**
4891 * A class that reflects the state of running {\@link APP_INITIALIZER}s.
4892 *
4893 * \@experimental
4894 */
4895var ApplicationInitStatus = (function () {
4896 /**
4897 * @param {?} appInits
4898 */
4899 function ApplicationInitStatus(appInits) {
4900 var _this = this;
4901 this.appInits = appInits;
4902 this.initialized = false;
4903 this._done = false;
4904 this._donePromise = new Promise(function (res, rej) {
4905 _this.resolve = res;
4906 _this.reject = rej;
4907 });
4908 }
4909 /**
4910 * \@internal
4911 * @return {?}
4912 */
4913 ApplicationInitStatus.prototype.runInitializers = function () {
4914 var _this = this;
4915 if (this.initialized) {
4916 return;
4917 }
4918 var /** @type {?} */ asyncInitPromises = [];
4919 var /** @type {?} */ complete = function () {
4920 _this._done = true;
4921 _this.resolve();
4922 };
4923 if (this.appInits) {
4924 for (var /** @type {?} */ i = 0; i < this.appInits.length; i++) {
4925 var /** @type {?} */ initResult = this.appInits[i]();
4926 if (isPromise(initResult)) {
4927 asyncInitPromises.push(initResult);
4928 }
4929 }
4930 }
4931 Promise.all(asyncInitPromises).then(function () { complete(); }).catch(function (e) { _this.reject(e); });
4932 if (asyncInitPromises.length === 0) {
4933 complete();
4934 }
4935 this.initialized = true;
4936 };
4937 Object.defineProperty(ApplicationInitStatus.prototype, "done", {
4938 /**
4939 * @return {?}
4940 */
4941 get: function () { return this._done; },
4942 enumerable: true,
4943 configurable: true
4944 });
4945 Object.defineProperty(ApplicationInitStatus.prototype, "donePromise", {
4946 /**
4947 * @return {?}
4948 */
4949 get: function () { return this._donePromise; },
4950 enumerable: true,
4951 configurable: true
4952 });
4953 return ApplicationInitStatus;
4954}());
4955ApplicationInitStatus.decorators = [
4956 { type: Injectable },
4957];
4958/**
4959 * @nocollapse
4960 */
4961ApplicationInitStatus.ctorParameters = function () { return [
4962 { type: Array, decorators: [{ type: Inject, args: [APP_INITIALIZER,] }, { type: Optional },] },
4963]; };
4964/**
4965 * @license
4966 * Copyright Google Inc. All Rights Reserved.
4967 *
4968 * Use of this source code is governed by an MIT-style license that can be
4969 * found in the LICENSE file at https://angular.io/license
4970 */
4971/**
4972 * A DI Token representing a unique string id assigned to the application by Angular and used
4973 * primarily for prefixing application attributes and CSS styles when
4974 * {\@link ViewEncapsulation#Emulated} is being used.
4975 *
4976 * If you need to avoid randomly generated value to be used as an application id, you can provide
4977 * a custom value via a DI provider <!-- TODO: provider --> configuring the root {\@link Injector}
4978 * using this token.
4979 * \@experimental
4980 */
4981var APP_ID = new InjectionToken('AppId');
4982/**
4983 * @return {?}
4984 */
4985function _appIdRandomProviderFactory() {
4986 return "" + _randomChar() + _randomChar() + _randomChar();
4987}
4988/**
4989 * Providers that will generate a random APP_ID_TOKEN.
4990 * \@experimental
4991 */
4992var APP_ID_RANDOM_PROVIDER = {
4993 provide: APP_ID,
4994 useFactory: _appIdRandomProviderFactory,
4995 deps: [],
4996};
4997/**
4998 * @return {?}
4999 */
5000function _randomChar() {
5001 return String.fromCharCode(97 + Math.floor(Math.random() * 25));
5002}
5003/**
5004 * A function that will be executed when a platform is initialized.
5005 * \@experimental
5006 */
5007var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
5008/**
5009 * A token that indicates an opaque platform id.
5010 * \@experimental
5011 */
5012var PLATFORM_ID = new InjectionToken('Platform ID');
5013/**
5014 * All callbacks provided via this token will be called for every component that is bootstrapped.
5015 * Signature of the callback:
5016 *
5017 * `(componentRef: ComponentRef) => void`.
5018 *
5019 * \@experimental
5020 */
5021var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
5022/**
5023 * A token which indicates the root directory of the application
5024 * \@experimental
5025 */
5026var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
5027/**
5028 * @license
5029 * Copyright Google Inc. All Rights Reserved.
5030 *
5031 * Use of this source code is governed by an MIT-style license that can be
5032 * found in the LICENSE file at https://angular.io/license
5033 */
5034var Console = (function () {
5035 function Console() {
5036 }
5037 /**
5038 * @param {?} message
5039 * @return {?}
5040 */
5041 Console.prototype.log = function (message) {
5042 // tslint:disable-next-line:no-console
5043 console.log(message);
5044 };
5045 /**
5046 * @param {?} message
5047 * @return {?}
5048 */
5049 Console.prototype.warn = function (message) {
5050 // tslint:disable-next-line:no-console
5051 console.warn(message);
5052 };
5053 return Console;
5054}());
5055Console.decorators = [
5056 { type: Injectable },
5057];
5058/**
5059 * @nocollapse
5060 */
5061Console.ctorParameters = function () { return []; };
5062/**
5063 * @return {?}
5064 */
5065function _throwError() {
5066 throw new Error("Runtime compiler is not loaded");
5067}
5068/**
5069 * Low-level service for running the angular compiler during runtime
5070 * to create {\@link ComponentFactory}s, which
5071 * can later be used to create and render a Component instance.
5072 *
5073 * Each `\@NgModule` provides an own `Compiler` to its injector,
5074 * that will use the directives/pipes of the ng module for compilation
5075 * of components.
5076 * \@stable
5077 */
5078var Compiler = (function () {
5079 function Compiler() {
5080 }
5081 /**
5082 * Compiles the given NgModule and all of its components. All templates of the components listed
5083 * in `entryComponents` have to be inlined.
5084 * @template T
5085 * @param {?} moduleType
5086 * @return {?}
5087 */
5088 Compiler.prototype.compileModuleSync = function (moduleType) { throw _throwError(); };
5089 /**
5090 * Compiles the given NgModule and all of its components
5091 * @template T
5092 * @param {?} moduleType
5093 * @return {?}
5094 */
5095 Compiler.prototype.compileModuleAsync = function (moduleType) { throw _throwError(); };
5096 /**
5097 * Same as {\@link #compileModuleSync} but also creates ComponentFactories for all components.
5098 * @template T
5099 * @param {?} moduleType
5100 * @return {?}
5101 */
5102 Compiler.prototype.compileModuleAndAllComponentsSync = function (moduleType) {
5103 throw _throwError();
5104 };
5105 /**
5106 * Same as {\@link #compileModuleAsync} but also creates ComponentFactories for all components.
5107 * @template T
5108 * @param {?} moduleType
5109 * @return {?}
5110 */
5111 Compiler.prototype.compileModuleAndAllComponentsAsync = function (moduleType) {
5112 throw _throwError();
5113 };
5114 /**
5115 * Exposes the CSS-style selectors that have been used in `ngContent` directives within
5116 * the template of the given component.
5117 * This is used by the `upgrade` library to compile the appropriate transclude content
5118 * in the AngularJS wrapper component.
5119 *
5120 * @deprecated since v4. Use ComponentFactory.ngContentSelectors instead.
5121 * @param {?} component
5122 * @return {?}
5123 */
5124 Compiler.prototype.getNgContentSelectors = function (component) { throw _throwError(); };
5125 /**
5126 * Clears all caches.
5127 * @return {?}
5128 */
5129 Compiler.prototype.clearCache = function () { };
5130 /**
5131 * Clears the cache for the given component/ngModule.
5132 * @param {?} type
5133 * @return {?}
5134 */
5135 Compiler.prototype.clearCacheFor = function (type) { };
5136 return Compiler;
5137}());
5138Compiler.decorators = [
5139 { type: Injectable },
5140];
5141/**
5142 * @nocollapse
5143 */
5144Compiler.ctorParameters = function () { return []; };
5145/**
5146 * Token to provide CompilerOptions in the platform injector.
5147 *
5148 * \@experimental
5149 */
5150var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
5151/**
5152 * A factory for creating a Compiler
5153 *
5154 * \@experimental
5155 * @abstract
5156 */
5157var CompilerFactory = (function () {
5158 function CompilerFactory() {
5159 }
5160 /**
5161 * @abstract
5162 * @param {?=} options
5163 * @return {?}
5164 */
5165 CompilerFactory.prototype.createCompiler = function (options) { };
5166 return CompilerFactory;
5167}());
5168/**
5169 * @license
5170 * Copyright Google Inc. All Rights Reserved.
5171 *
5172 * Use of this source code is governed by an MIT-style license that can be
5173 * found in the LICENSE file at https://angular.io/license
5174 */
5175/**
5176 * Represents an instance of a Component created via a {\@link ComponentFactory}.
5177 *
5178 * `ComponentRef` provides access to the Component Instance as well other objects related to this
5179 * Component Instance and allows you to destroy the Component Instance via the {\@link #destroy}
5180 * method.
5181 * \@stable
5182 * @abstract
5183 */
5184var ComponentRef = (function () {
5185 function ComponentRef() {
5186 }
5187 /**
5188 * Location of the Host Element of this Component Instance.
5189 * @abstract
5190 * @return {?}
5191 */
5192 ComponentRef.prototype.location = function () { };
5193 /**
5194 * The injector on which the component instance exists.
5195 * @abstract
5196 * @return {?}
5197 */
5198 ComponentRef.prototype.injector = function () { };
5199 /**
5200 * The instance of the Component.
5201 * @abstract
5202 * @return {?}
5203 */
5204 ComponentRef.prototype.instance = function () { };
5205 /**
5206 * The {\@link ViewRef} of the Host View of this Component instance.
5207 * @abstract
5208 * @return {?}
5209 */
5210 ComponentRef.prototype.hostView = function () { };
5211 /**
5212 * The {\@link ChangeDetectorRef} of the Component instance.
5213 * @abstract
5214 * @return {?}
5215 */
5216 ComponentRef.prototype.changeDetectorRef = function () { };
5217 /**
5218 * The component type.
5219 * @abstract
5220 * @return {?}
5221 */
5222 ComponentRef.prototype.componentType = function () { };
5223 /**
5224 * Destroys the component instance and all of the data structures associated with it.
5225 * @abstract
5226 * @return {?}
5227 */
5228 ComponentRef.prototype.destroy = function () { };
5229 /**
5230 * Allows to register a callback that will be called when the component is destroyed.
5231 * @abstract
5232 * @param {?} callback
5233 * @return {?}
5234 */
5235 ComponentRef.prototype.onDestroy = function (callback) { };
5236 return ComponentRef;
5237}());
5238/**
5239 * \@stable
5240 * @abstract
5241 */
5242var ComponentFactory = (function () {
5243 function ComponentFactory() {
5244 }
5245 /**
5246 * @abstract
5247 * @return {?}
5248 */
5249 ComponentFactory.prototype.selector = function () { };
5250 /**
5251 * @abstract
5252 * @return {?}
5253 */
5254 ComponentFactory.prototype.componentType = function () { };
5255 /**
5256 * selector for all <ng-content> elements in the component.
5257 * @abstract
5258 * @return {?}
5259 */
5260 ComponentFactory.prototype.ngContentSelectors = function () { };
5261 /**
5262 * the inputs of the component.
5263 * @abstract
5264 * @return {?}
5265 */
5266 ComponentFactory.prototype.inputs = function () { };
5267 /**
5268 * the outputs of the component.
5269 * @abstract
5270 * @return {?}
5271 */
5272 ComponentFactory.prototype.outputs = function () { };
5273 /**
5274 * Creates a new component.
5275 * @abstract
5276 * @param {?} injector
5277 * @param {?=} projectableNodes
5278 * @param {?=} rootSelectorOrNode
5279 * @param {?=} ngModule
5280 * @return {?}
5281 */
5282 ComponentFactory.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) { };
5283 return ComponentFactory;
5284}());
5285/**
5286 * @license
5287 * Copyright Google Inc. All Rights Reserved.
5288 *
5289 * Use of this source code is governed by an MIT-style license that can be
5290 * found in the LICENSE file at https://angular.io/license
5291 */
5292/**
5293 * @param {?} component
5294 * @return {?}
5295 */
5296function noComponentFactoryError(component) {
5297 var /** @type {?} */ error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
5298 ((error))[ERROR_COMPONENT] = component;
5299 return error;
5300}
5301var ERROR_COMPONENT = 'ngComponent';
5302/**
5303 * @param {?} error
5304 * @return {?}
5305 */
5306var _NullComponentFactoryResolver = (function () {
5307 function _NullComponentFactoryResolver() {
5308 }
5309 /**
5310 * @template T
5311 * @param {?} component
5312 * @return {?}
5313 */
5314 _NullComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
5315 throw noComponentFactoryError(component);
5316 };
5317 return _NullComponentFactoryResolver;
5318}());
5319/**
5320 * \@stable
5321 * @abstract
5322 */
5323var ComponentFactoryResolver = (function () {
5324 function ComponentFactoryResolver() {
5325 }
5326 /**
5327 * @abstract
5328 * @template T
5329 * @param {?} component
5330 * @return {?}
5331 */
5332 ComponentFactoryResolver.prototype.resolveComponentFactory = function (component) { };
5333 return ComponentFactoryResolver;
5334}());
5335ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
5336var ComponentFactoryBoundToModule = (function (_super) {
5337 __extends$1(ComponentFactoryBoundToModule, _super);
5338 /**
5339 * @param {?} factory
5340 * @param {?} ngModule
5341 */
5342 function ComponentFactoryBoundToModule(factory, ngModule) {
5343 var _this = _super.call(this) || this;
5344 _this.factory = factory;
5345 _this.ngModule = ngModule;
5346 return _this;
5347 }
5348 Object.defineProperty(ComponentFactoryBoundToModule.prototype, "selector", {
5349 /**
5350 * @return {?}
5351 */
5352 get: function () { return this.factory.selector; },
5353 enumerable: true,
5354 configurable: true
5355 });
5356 Object.defineProperty(ComponentFactoryBoundToModule.prototype, "componentType", {
5357 /**
5358 * @return {?}
5359 */
5360 get: function () { return this.factory.componentType; },
5361 enumerable: true,
5362 configurable: true
5363 });
5364 Object.defineProperty(ComponentFactoryBoundToModule.prototype, "ngContentSelectors", {
5365 /**
5366 * @return {?}
5367 */
5368 get: function () { return this.factory.ngContentSelectors; },
5369 enumerable: true,
5370 configurable: true
5371 });
5372 Object.defineProperty(ComponentFactoryBoundToModule.prototype, "inputs", {
5373 /**
5374 * @return {?}
5375 */
5376 get: function () { return this.factory.inputs; },
5377 enumerable: true,
5378 configurable: true
5379 });
5380 Object.defineProperty(ComponentFactoryBoundToModule.prototype, "outputs", {
5381 /**
5382 * @return {?}
5383 */
5384 get: function () { return this.factory.outputs; },
5385 enumerable: true,
5386 configurable: true
5387 });
5388 /**
5389 * @param {?} injector
5390 * @param {?=} projectableNodes
5391 * @param {?=} rootSelectorOrNode
5392 * @param {?=} ngModule
5393 * @return {?}
5394 */
5395 ComponentFactoryBoundToModule.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
5396 return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
5397 };
5398 return ComponentFactoryBoundToModule;
5399}(ComponentFactory));
5400/**
5401 * @license
5402 * Copyright Google Inc. All Rights Reserved.
5403 *
5404 * Use of this source code is governed by an MIT-style license that can be
5405 * found in the LICENSE file at https://angular.io/license
5406 */
5407/**
5408 * Represents an instance of an NgModule created via a {\@link NgModuleFactory}.
5409 *
5410 * `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
5411 * NgModule Instance.
5412 *
5413 * \@stable
5414 * @abstract
5415 */
5416var NgModuleRef = (function () {
5417 function NgModuleRef() {
5418 }
5419 /**
5420 * The injector that contains all of the providers of the NgModule.
5421 * @abstract
5422 * @return {?}
5423 */
5424 NgModuleRef.prototype.injector = function () { };
5425 /**
5426 * The ComponentFactoryResolver to get hold of the ComponentFactories
5427 * declared in the `entryComponents` property of the module.
5428 * @abstract
5429 * @return {?}
5430 */
5431 NgModuleRef.prototype.componentFactoryResolver = function () { };
5432 /**
5433 * The NgModule instance.
5434 * @abstract
5435 * @return {?}
5436 */
5437 NgModuleRef.prototype.instance = function () { };
5438 /**
5439 * Destroys the module instance and all of the data structures associated with it.
5440 * @abstract
5441 * @return {?}
5442 */
5443 NgModuleRef.prototype.destroy = function () { };
5444 /**
5445 * Allows to register a callback that will be called when the module is destroyed.
5446 * @abstract
5447 * @param {?} callback
5448 * @return {?}
5449 */
5450 NgModuleRef.prototype.onDestroy = function (callback) { };
5451 return NgModuleRef;
5452}());
5453/**
5454 * \@experimental
5455 * @abstract
5456 */
5457var NgModuleFactory = (function () {
5458 function NgModuleFactory() {
5459 }
5460 /**
5461 * @abstract
5462 * @return {?}
5463 */
5464 NgModuleFactory.prototype.moduleType = function () { };
5465 /**
5466 * @abstract
5467 * @param {?} parentInjector
5468 * @return {?}
5469 */
5470 NgModuleFactory.prototype.create = function (parentInjector) { };
5471 return NgModuleFactory;
5472}());
5473/**
5474 * @license
5475 * Copyright Google Inc. All Rights Reserved.
5476 *
5477 * Use of this source code is governed by an MIT-style license that can be
5478 * found in the LICENSE file at https://angular.io/license
5479 */
5480var trace;
5481var events;
5482/**
5483 * @return {?}
5484 */
5485function detectWTF() {
5486 var /** @type {?} */ wtf = ((_global) /** TODO #9100 */)['wtf'];
5487 if (wtf) {
5488 trace = wtf['trace'];
5489 if (trace) {
5490 events = trace['events'];
5491 return true;
5492 }
5493 }
5494 return false;
5495}
5496/**
5497 * @param {?} signature
5498 * @param {?=} flags
5499 * @return {?}
5500 */
5501function createScope$1(signature, flags) {
5502 if (flags === void 0) { flags = null; }
5503 return events.createScope(signature, flags);
5504}
5505/**
5506 * @template T
5507 * @param {?} scope
5508 * @param {?=} returnValue
5509 * @return {?}
5510 */
5511function leave(scope, returnValue) {
5512 trace.leaveScope(scope, returnValue);
5513 return returnValue;
5514}
5515/**
5516 * @license
5517 * Copyright Google Inc. All Rights Reserved.
5518 *
5519 * Use of this source code is governed by an MIT-style license that can be
5520 * found in the LICENSE file at https://angular.io/license
5521 */
5522/**
5523 * True if WTF is enabled.
5524 */
5525var wtfEnabled = detectWTF();
5526/**
5527 * @param {?=} arg0
5528 * @param {?=} arg1
5529 * @return {?}
5530 */
5531function noopScope(arg0, arg1) {
5532 return null;
5533}
5534/**
5535 * Create trace scope.
5536 *
5537 * Scopes must be strictly nested and are analogous to stack frames, but
5538 * do not have to follow the stack frames. Instead it is recommended that they follow logical
5539 * nesting. You may want to use
5540 * [Event
5541 * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
5542 * as they are defined in WTF.
5543 *
5544 * Used to mark scope entry. The return value is used to leave the scope.
5545 *
5546 * var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
5547 *
5548 * someMethod() {
5549 * var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
5550 * // DO SOME WORK HERE
5551 * return wtfLeave(s, 123); // Return value 123
5552 * }
5553 *
5554 * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
5555 * negatively impact the performance of your application. For this reason we recommend that
5556 * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
5557 * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
5558 * exception, will produce incorrect trace, but presence of exception signifies logic error which
5559 * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
5560 * an exception is expected during normal execution while profiling.
5561 *
5562 * \@experimental
5563 */
5564var wtfCreateScope = wtfEnabled ? createScope$1 : function (signature, flags) { return noopScope; };
5565/**
5566 * Used to mark end of Scope.
5567 *
5568 * - `scope` to end.
5569 * - `returnValue` (optional) to be passed to the WTF.
5570 *
5571 * Returns the `returnValue for easy chaining.
5572 * \@experimental
5573 */
5574var wtfLeave = wtfEnabled ? leave : function (s, r) { return r; };
5575/**
5576 * @license
5577 * Copyright Google Inc. All Rights Reserved.
5578 *
5579 * Use of this source code is governed by an MIT-style license that can be
5580 * found in the LICENSE file at https://angular.io/license
5581 */
5582/**
5583 * Use by directives and components to emit custom Events.
5584 *
5585 * ### Examples
5586 *
5587 * In the following example, `Zippy` alternatively emits `open` and `close` events when its
5588 * title gets clicked:
5589 *
5590 * ```
5591 * \@Component({
5592 * selector: 'zippy',
5593 * template: `
5594 * <div class="zippy">
5595 * <div (click)="toggle()">Toggle</div>
5596 * <div [hidden]="!visible">
5597 * <ng-content></ng-content>
5598 * </div>
5599 * </div>`})
5600 * export class Zippy {
5601 * visible: boolean = true;
5602 * \@Output() open: EventEmitter<any> = new EventEmitter();
5603 * \@Output() close: EventEmitter<any> = new EventEmitter();
5604 *
5605 * toggle() {
5606 * this.visible = !this.visible;
5607 * if (this.visible) {
5608 * this.open.emit(null);
5609 * } else {
5610 * this.close.emit(null);
5611 * }
5612 * }
5613 * }
5614 * ```
5615 *
5616 * The events payload can be accessed by the parameter `$event` on the components output event
5617 * handler:
5618 *
5619 * ```
5620 * <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
5621 * ```
5622 *
5623 * Uses Rx.Observable but provides an adapter to make it work as specified here:
5624 * https://github.com/jhusain/observable-spec
5625 *
5626 * Once a reference implementation of the spec is available, switch to it.
5627 * \@stable
5628 */
5629var EventEmitter = (function (_super) {
5630 __extends$1(EventEmitter, _super);
5631 /**
5632 * Creates an instance of {\@link EventEmitter}, which depending on `isAsync`,
5633 * delivers events synchronously or asynchronously.
5634 *
5635 * @param {?=} isAsync By default, events are delivered synchronously (default value: `false`).
5636 * Set to `true` for asynchronous event delivery.
5637 */
5638 function EventEmitter(isAsync) {
5639 if (isAsync === void 0) { isAsync = false; }
5640 var _this = _super.call(this) || this;
5641 _this.__isAsync = isAsync;
5642 return _this;
5643 }
5644 /**
5645 * @param {?=} value
5646 * @return {?}
5647 */
5648 EventEmitter.prototype.emit = function (value) { _super.prototype.next.call(this, value); };
5649 /**
5650 * @param {?=} generatorOrNext
5651 * @param {?=} error
5652 * @param {?=} complete
5653 * @return {?}
5654 */
5655 EventEmitter.prototype.subscribe = function (generatorOrNext, error, complete) {
5656 var /** @type {?} */ schedulerFn;
5657 var /** @type {?} */ errorFn = function (err) { return null; };
5658 var /** @type {?} */ completeFn = function () { return null; };
5659 if (generatorOrNext && typeof generatorOrNext === 'object') {
5660 schedulerFn = this.__isAsync ? function (value) {
5661 setTimeout(function () { return generatorOrNext.next(value); });
5662 } : function (value) { generatorOrNext.next(value); };
5663 if (generatorOrNext.error) {
5664 errorFn = this.__isAsync ? function (err) { setTimeout(function () { return generatorOrNext.error(err); }); } :
5665 function (err) { generatorOrNext.error(err); };
5666 }
5667 if (generatorOrNext.complete) {
5668 completeFn = this.__isAsync ? function () { setTimeout(function () { return generatorOrNext.complete(); }); } :
5669 function () { generatorOrNext.complete(); };
5670 }
5671 }
5672 else {
5673 schedulerFn = this.__isAsync ? function (value) { setTimeout(function () { return generatorOrNext(value); }); } :
5674 function (value) { generatorOrNext(value); };
5675 if (error) {
5676 errorFn =
5677 this.__isAsync ? function (err) { setTimeout(function () { return error(err); }); } : function (err) { error(err); };
5678 }
5679 if (complete) {
5680 completeFn =
5681 this.__isAsync ? function () { setTimeout(function () { return complete(); }); } : function () { complete(); };
5682 }
5683 }
5684 return _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
5685 };
5686 return EventEmitter;
5687}(Subject_2));
5688/**
5689 * @license
5690 * Copyright Google Inc. All Rights Reserved.
5691 *
5692 * Use of this source code is governed by an MIT-style license that can be
5693 * found in the LICENSE file at https://angular.io/license
5694 */
5695/**
5696 * An injectable service for executing work inside or outside of the Angular zone.
5697 *
5698 * The most common use of this service is to optimize performance when starting a work consisting of
5699 * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
5700 * Angular. Such tasks can be kicked off via {\@link #runOutsideAngular} and if needed, these tasks
5701 * can reenter the Angular zone via {\@link #run}.
5702 *
5703 * <!-- TODO: add/fix links to:
5704 * - docs explaining zones and the use of zones in Angular and change-detection
5705 * - link to runOutsideAngular/run (throughout this file!)
5706 * -->
5707 *
5708 * ### Example
5709 *
5710 * ```
5711 * import {Component, NgZone} from '\@angular/core';
5712 * import {NgIf} from '\@angular/common';
5713 *
5714 * \@Component({
5715 * selector: 'ng-zone-demo'.
5716 * template: `
5717 * <h2>Demo: NgZone</h2>
5718 *
5719 * <p>Progress: {{progress}}%</p>
5720 * <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
5721 *
5722 * <button (click)="processWithinAngularZone()">Process within Angular zone</button>
5723 * <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
5724 * `,
5725 * })
5726 * export class NgZoneDemo {
5727 * progress: number = 0;
5728 * label: string;
5729 *
5730 * constructor(private _ngZone: NgZone) {}
5731 *
5732 * // Loop inside the Angular zone
5733 * // so the UI DOES refresh after each setTimeout cycle
5734 * processWithinAngularZone() {
5735 * this.label = 'inside';
5736 * this.progress = 0;
5737 * this._increaseProgress(() => console.log('Inside Done!'));
5738 * }
5739 *
5740 * // Loop outside of the Angular zone
5741 * // so the UI DOES NOT refresh after each setTimeout cycle
5742 * processOutsideOfAngularZone() {
5743 * this.label = 'outside';
5744 * this.progress = 0;
5745 * this._ngZone.runOutsideAngular(() => {
5746 * this._increaseProgress(() => {
5747 * // reenter the Angular zone and display done
5748 * this._ngZone.run(() => {console.log('Outside Done!') });
5749 * }}));
5750 * }
5751 *
5752 * _increaseProgress(doneCallback: () => void) {
5753 * this.progress += 1;
5754 * console.log(`Current progress: ${this.progress}%`);
5755 *
5756 * if (this.progress < 100) {
5757 * window.setTimeout(() => this._increaseProgress(doneCallback)), 10)
5758 * } else {
5759 * doneCallback();
5760 * }
5761 * }
5762 * }
5763 * ```
5764 *
5765 * \@experimental
5766 */
5767var NgZone = (function () {
5768 /**
5769 * @param {?} __0
5770 */
5771 function NgZone(_a) {
5772 var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b;
5773 this.hasPendingMicrotasks = false;
5774 this.hasPendingMacrotasks = false;
5775 /**
5776 * Whether there are no outstanding microtasks or macrotasks.
5777 */
5778 this.isStable = true;
5779 /**
5780 * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
5781 */
5782 this.onUnstable = new EventEmitter(false);
5783 /**
5784 * Notifies when there is no more microtasks enqueue in the current VM Turn.
5785 * This is a hint for Angular to do change detection, which may enqueue more microtasks.
5786 * For this reason this event can fire multiple times per VM Turn.
5787 */
5788 this.onMicrotaskEmpty = new EventEmitter(false);
5789 /**
5790 * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
5791 * implies we are about to relinquish VM turn.
5792 * This event gets called just once.
5793 */
5794 this.onStable = new EventEmitter(false);
5795 /**
5796 * Notifies that an error has been delivered.
5797 */
5798 this.onError = new EventEmitter(false);
5799 if (typeof Zone == 'undefined') {
5800 throw new Error('Angular requires Zone.js prolyfill.');
5801 }
5802 Zone.assertZonePatched();
5803 var self = this;
5804 self._nesting = 0;
5805 self._outer = self._inner = Zone.current;
5806 if (Zone['wtfZoneSpec']) {
5807 self._inner = self._inner.fork(Zone['wtfZoneSpec']);
5808 }
5809 if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
5810 self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
5811 }
5812 forkInnerZoneWithAngularBehavior(self);
5813 }
5814 /**
5815 * @return {?}
5816 */
5817 NgZone.isInAngularZone = function () { return Zone.current.get('isAngularZone') === true; };
5818 /**
5819 * @return {?}
5820 */
5821 NgZone.assertInAngularZone = function () {
5822 if (!NgZone.isInAngularZone()) {
5823 throw new Error('Expected to be in Angular Zone, but it is not!');
5824 }
5825 };
5826 /**
5827 * @return {?}
5828 */
5829 NgZone.assertNotInAngularZone = function () {
5830 if (NgZone.isInAngularZone()) {
5831 throw new Error('Expected to not be in Angular Zone, but it is!');
5832 }
5833 };
5834 /**
5835 * Executes the `fn` function synchronously within the Angular zone and returns value returned by
5836 * the function.
5837 *
5838 * Running functions via `run` allows you to reenter Angular zone from a task that was executed
5839 * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
5840 *
5841 * Any future tasks or microtasks scheduled from within this function will continue executing from
5842 * within the Angular zone.
5843 *
5844 * If a synchronous error happens it will be rethrown and not reported via `onError`.
5845 * @param {?} fn
5846 * @return {?}
5847 */
5848 NgZone.prototype.run = function (fn) { return (((this)))._inner.run(fn); };
5849 /**
5850 * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
5851 * rethrown.
5852 * @param {?} fn
5853 * @return {?}
5854 */
5855 NgZone.prototype.runGuarded = function (fn) { return (((this)))._inner.runGuarded(fn); };
5856 /**
5857 * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
5858 * the function.
5859 *
5860 * Running functions via {\@link #runOutsideAngular} allows you to escape Angular's zone and do
5861 * work that
5862 * doesn't trigger Angular change-detection or is subject to Angular's error handling.
5863 *
5864 * Any future tasks or microtasks scheduled from within this function will continue executing from
5865 * outside of the Angular zone.
5866 *
5867 * Use {\@link #run} to reenter the Angular zone and do work that updates the application model.
5868 * @param {?} fn
5869 * @return {?}
5870 */
5871 NgZone.prototype.runOutsideAngular = function (fn) { return (((this)))._outer.run(fn); };
5872 return NgZone;
5873}());
5874/**
5875 * @param {?} zone
5876 * @return {?}
5877 */
5878function checkStable(zone) {
5879 if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
5880 try {
5881 zone._nesting++;
5882 zone.onMicrotaskEmpty.emit(null);
5883 }
5884 finally {
5885 zone._nesting--;
5886 if (!zone.hasPendingMicrotasks) {
5887 try {
5888 zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
5889 }
5890 finally {
5891 zone.isStable = true;
5892 }
5893 }
5894 }
5895 }
5896}
5897/**
5898 * @param {?} zone
5899 * @return {?}
5900 */
5901function forkInnerZoneWithAngularBehavior(zone) {
5902 zone._inner = zone._inner.fork({
5903 name: 'angular',
5904 properties: /** @type {?} */ ({ 'isAngularZone': true }),
5905 onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
5906 try {
5907 onEnter(zone);
5908 return delegate.invokeTask(target, task, applyThis, applyArgs);
5909 }
5910 finally {
5911 onLeave(zone);
5912 }
5913 },
5914 onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
5915 try {
5916 onEnter(zone);
5917 return delegate.invoke(target, callback, applyThis, applyArgs, source);
5918 }
5919 finally {
5920 onLeave(zone);
5921 }
5922 },
5923 onHasTask: function (delegate, current, target, hasTaskState) {
5924 delegate.hasTask(target, hasTaskState);
5925 if (current === target) {
5926 // We are only interested in hasTask events which originate from our zone
5927 // (A child hasTask event is not interesting to us)
5928 if (hasTaskState.change == 'microTask') {
5929 zone.hasPendingMicrotasks = hasTaskState.microTask;
5930 checkStable(zone);
5931 }
5932 else if (hasTaskState.change == 'macroTask') {
5933 zone.hasPendingMacrotasks = hasTaskState.macroTask;
5934 }
5935 }
5936 },
5937 onHandleError: function (delegate, current, target, error) {
5938 delegate.handleError(target, error);
5939 zone.runOutsideAngular(function () { return zone.onError.emit(error); });
5940 return false;
5941 }
5942 });
5943}
5944/**
5945 * @param {?} zone
5946 * @return {?}
5947 */
5948function onEnter(zone) {
5949 zone._nesting++;
5950 if (zone.isStable) {
5951 zone.isStable = false;
5952 zone.onUnstable.emit(null);
5953 }
5954}
5955/**
5956 * @param {?} zone
5957 * @return {?}
5958 */
5959function onLeave(zone) {
5960 zone._nesting--;
5961 checkStable(zone);
5962}
5963/**
5964 * @license
5965 * Copyright Google Inc. All Rights Reserved.
5966 *
5967 * Use of this source code is governed by an MIT-style license that can be
5968 * found in the LICENSE file at https://angular.io/license
5969 */
5970/**
5971 * The Testability service provides testing hooks that can be accessed from
5972 * the browser and by services such as Protractor. Each bootstrapped Angular
5973 * application on the page will have an instance of Testability.
5974 * \@experimental
5975 */
5976var Testability = (function () {
5977 /**
5978 * @param {?} _ngZone
5979 */
5980 function Testability(_ngZone) {
5981 this._ngZone = _ngZone;
5982 /**
5983 * \@internal
5984 */
5985 this._pendingCount = 0;
5986 /**
5987 * \@internal
5988 */
5989 this._isZoneStable = true;
5990 /**
5991 * Whether any work was done since the last 'whenStable' callback. This is
5992 * useful to detect if this could have potentially destabilized another
5993 * component while it is stabilizing.
5994 * \@internal
5995 */
5996 this._didWork = false;
5997 /**
5998 * \@internal
5999 */
6000 this._callbacks = [];
6001 this._watchAngularEvents();
6002 }
6003 /**
6004 * \@internal
6005 * @return {?}
6006 */
6007 Testability.prototype._watchAngularEvents = function () {
6008 var _this = this;
6009 this._ngZone.onUnstable.subscribe({
6010 next: function () {
6011 _this._didWork = true;
6012 _this._isZoneStable = false;
6013 }
6014 });
6015 this._ngZone.runOutsideAngular(function () {
6016 _this._ngZone.onStable.subscribe({
6017 next: function () {
6018 NgZone.assertNotInAngularZone();
6019 scheduleMicroTask(function () {
6020 _this._isZoneStable = true;
6021 _this._runCallbacksIfReady();
6022 });
6023 }
6024 });
6025 });
6026 };
6027 /**
6028 * @return {?}
6029 */
6030 Testability.prototype.increasePendingRequestCount = function () {
6031 this._pendingCount += 1;
6032 this._didWork = true;
6033 return this._pendingCount;
6034 };
6035 /**
6036 * @return {?}
6037 */
6038 Testability.prototype.decreasePendingRequestCount = function () {
6039 this._pendingCount -= 1;
6040 if (this._pendingCount < 0) {
6041 throw new Error('pending async requests below zero');
6042 }
6043 this._runCallbacksIfReady();
6044 return this._pendingCount;
6045 };
6046 /**
6047 * @return {?}
6048 */
6049 Testability.prototype.isStable = function () {
6050 return this._isZoneStable && this._pendingCount == 0 && !this._ngZone.hasPendingMacrotasks;
6051 };
6052 /**
6053 * \@internal
6054 * @return {?}
6055 */
6056 Testability.prototype._runCallbacksIfReady = function () {
6057 var _this = this;
6058 if (this.isStable()) {
6059 // Schedules the call backs in a new frame so that it is always async.
6060 scheduleMicroTask(function () {
6061 while (_this._callbacks.length !== 0) {
6062 (((_this._callbacks.pop())))(_this._didWork);
6063 }
6064 _this._didWork = false;
6065 });
6066 }
6067 else {
6068 // Not Ready
6069 this._didWork = true;
6070 }
6071 };
6072 /**
6073 * @param {?} callback
6074 * @return {?}
6075 */
6076 Testability.prototype.whenStable = function (callback) {
6077 this._callbacks.push(callback);
6078 this._runCallbacksIfReady();
6079 };
6080 /**
6081 * @return {?}
6082 */
6083 Testability.prototype.getPendingRequestCount = function () { return this._pendingCount; };
6084 /**
6085 * @deprecated use findProviders
6086 * @param {?} using
6087 * @param {?} provider
6088 * @param {?} exactMatch
6089 * @return {?}
6090 */
6091 Testability.prototype.findBindings = function (using, provider, exactMatch) {
6092 // TODO(juliemr): implement.
6093 return [];
6094 };
6095 /**
6096 * @param {?} using
6097 * @param {?} provider
6098 * @param {?} exactMatch
6099 * @return {?}
6100 */
6101 Testability.prototype.findProviders = function (using, provider, exactMatch) {
6102 // TODO(juliemr): implement.
6103 return [];
6104 };
6105 return Testability;
6106}());
6107Testability.decorators = [
6108 { type: Injectable },
6109];
6110/**
6111 * @nocollapse
6112 */
6113Testability.ctorParameters = function () { return [
6114 { type: NgZone, },
6115]; };
6116/**
6117 * A global registry of {\@link Testability} instances for specific elements.
6118 * \@experimental
6119 */
6120var TestabilityRegistry = (function () {
6121 function TestabilityRegistry() {
6122 /**
6123 * \@internal
6124 */
6125 this._applications = new Map();
6126 _testabilityGetter.addToWindow(this);
6127 }
6128 /**
6129 * @param {?} token
6130 * @param {?} testability
6131 * @return {?}
6132 */
6133 TestabilityRegistry.prototype.registerApplication = function (token, testability) {
6134 this._applications.set(token, testability);
6135 };
6136 /**
6137 * @param {?} elem
6138 * @return {?}
6139 */
6140 TestabilityRegistry.prototype.getTestability = function (elem) { return this._applications.get(elem) || null; };
6141 /**
6142 * @return {?}
6143 */
6144 TestabilityRegistry.prototype.getAllTestabilities = function () { return Array.from(this._applications.values()); };
6145 /**
6146 * @return {?}
6147 */
6148 TestabilityRegistry.prototype.getAllRootElements = function () { return Array.from(this._applications.keys()); };
6149 /**
6150 * @param {?} elem
6151 * @param {?=} findInAncestors
6152 * @return {?}
6153 */
6154 TestabilityRegistry.prototype.findTestabilityInTree = function (elem, findInAncestors) {
6155 if (findInAncestors === void 0) { findInAncestors = true; }
6156 return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
6157 };
6158 return TestabilityRegistry;
6159}());
6160TestabilityRegistry.decorators = [
6161 { type: Injectable },
6162];
6163/**
6164 * @nocollapse
6165 */
6166TestabilityRegistry.ctorParameters = function () { return []; };
6167var _NoopGetTestability = (function () {
6168 function _NoopGetTestability() {
6169 }
6170 /**
6171 * @param {?} registry
6172 * @return {?}
6173 */
6174 _NoopGetTestability.prototype.addToWindow = function (registry) { };
6175 /**
6176 * @param {?} registry
6177 * @param {?} elem
6178 * @param {?} findInAncestors
6179 * @return {?}
6180 */
6181 _NoopGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
6182 return null;
6183 };
6184 return _NoopGetTestability;
6185}());
6186/**
6187 * Set the {\@link GetTestability} implementation used by the Angular testing framework.
6188 * \@experimental
6189 * @param {?} getter
6190 * @return {?}
6191 */
6192function setTestabilityGetter(getter) {
6193 _testabilityGetter = getter;
6194}
6195var _testabilityGetter = new _NoopGetTestability();
6196/**
6197 * @license
6198 * Copyright Google Inc. All Rights Reserved.
6199 *
6200 * Use of this source code is governed by an MIT-style license that can be
6201 * found in the LICENSE file at https://angular.io/license
6202 */
6203var _devMode = true;
6204var _runModeLocked = false;
6205var _platform;
6206var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
6207/**
6208 * Returns whether Angular is in development mode. After called once,
6209 * the value is locked and won't change any more.
6210 *
6211 * By default, this is true, unless a user calls `enableProdMode` before calling this.
6212 *
6213 * \@experimental APIs related to application bootstrap are currently under review.
6214 * @return {?}
6215 */
6216function isDevMode() {
6217 _runModeLocked = true;
6218 return _devMode;
6219}
6220/**
6221 * A token for third-party components that can register themselves with NgProbe.
6222 *
6223 * \@experimental
6224 */
6225var NgProbeToken = (function () {
6226 /**
6227 * @param {?} name
6228 * @param {?} token
6229 */
6230 function NgProbeToken(name, token) {
6231 this.name = name;
6232 this.token = token;
6233 }
6234 return NgProbeToken;
6235}());
6236/**
6237 * Creates a platform.
6238 * Platforms have to be eagerly created via this function.
6239 *
6240 * \@experimental APIs related to application bootstrap are currently under review.
6241 * @param {?} injector
6242 * @return {?}
6243 */
6244function createPlatform(injector) {
6245 if (_platform && !_platform.destroyed &&
6246 !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
6247 throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
6248 }
6249 _platform = injector.get(PlatformRef);
6250 var /** @type {?} */ inits = injector.get(PLATFORM_INITIALIZER, null);
6251 if (inits)
6252 inits.forEach(function (init) { return init(); });
6253 return _platform;
6254}
6255/**
6256 * Creates a factory for a platform
6257 *
6258 * \@experimental APIs related to application bootstrap are currently under review.
6259 * @param {?} parentPlatformFactory
6260 * @param {?} name
6261 * @param {?=} providers
6262 * @return {?}
6263 */
6264function createPlatformFactory(parentPlatformFactory, name, providers) {
6265 if (providers === void 0) { providers = []; }
6266 var /** @type {?} */ marker = new InjectionToken("Platform: " + name);
6267 return function (extraProviders) {
6268 if (extraProviders === void 0) { extraProviders = []; }
6269 var /** @type {?} */ platform = getPlatform();
6270 if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
6271 if (parentPlatformFactory) {
6272 parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
6273 }
6274 else {
6275 createPlatform(ReflectiveInjector.resolveAndCreate(providers.concat(extraProviders).concat({ provide: marker, useValue: true })));
6276 }
6277 }
6278 return assertPlatform(marker);
6279 };
6280}
6281/**
6282 * Checks that there currently is a platform which contains the given token as a provider.
6283 *
6284 * \@experimental APIs related to application bootstrap are currently under review.
6285 * @param {?} requiredToken
6286 * @return {?}
6287 */
6288function assertPlatform(requiredToken) {
6289 var /** @type {?} */ platform = getPlatform();
6290 if (!platform) {
6291 throw new Error('No platform exists!');
6292 }
6293 if (!platform.injector.get(requiredToken, null)) {
6294 throw new Error('A platform with a different configuration has been created. Please destroy it first.');
6295 }
6296 return platform;
6297}
6298/**
6299 * Returns the current platform.
6300 *
6301 * \@experimental APIs related to application bootstrap are currently under review.
6302 * @return {?}
6303 */
6304function getPlatform() {
6305 return _platform && !_platform.destroyed ? _platform : null;
6306}
6307/**
6308 * The Angular platform is the entry point for Angular on a web page. Each page
6309 * has exactly one platform, and services (such as reflection) which are common
6310 * to every Angular application running on the page are bound in its scope.
6311 *
6312 * A page's platform is initialized implicitly when a platform is created via a platform factory
6313 * (e.g. {\@link platformBrowser}), or explicitly by calling the {\@link createPlatform} function.
6314 *
6315 * \@stable
6316 * @abstract
6317 */
6318var PlatformRef = (function () {
6319 function PlatformRef() {
6320 }
6321 /**
6322 * Creates an instance of an `\@NgModule` for the given platform
6323 * for offline compilation.
6324 *
6325 * ## Simple Example
6326 *
6327 * ```typescript
6328 * my_module.ts:
6329 *
6330 * \@NgModule({
6331 * imports: [BrowserModule]
6332 * })
6333 * class MyModule {}
6334 *
6335 * main.ts:
6336 * import {MyModuleNgFactory} from './my_module.ngfactory';
6337 * import {platformBrowser} from '\@angular/platform-browser';
6338 *
6339 * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
6340 * ```
6341 *
6342 * \@experimental APIs related to application bootstrap are currently under review.
6343 * @abstract
6344 * @template M
6345 * @param {?} moduleFactory
6346 * @return {?}
6347 */
6348 PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory) { };
6349 /**
6350 * Creates an instance of an `\@NgModule` for a given platform using the given runtime compiler.
6351 *
6352 * ## Simple Example
6353 *
6354 * ```typescript
6355 * \@NgModule({
6356 * imports: [BrowserModule]
6357 * })
6358 * class MyModule {}
6359 *
6360 * let moduleRef = platformBrowser().bootstrapModule(MyModule);
6361 * ```
6362 * \@stable
6363 * @abstract
6364 * @template M
6365 * @param {?} moduleType
6366 * @param {?=} compilerOptions
6367 * @return {?}
6368 */
6369 PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) { };
6370 /**
6371 * Register a listener to be called when the platform is disposed.
6372 * @abstract
6373 * @param {?} callback
6374 * @return {?}
6375 */
6376 PlatformRef.prototype.onDestroy = function (callback) { };
6377 /**
6378 * Retrieve the platform {\@link Injector}, which is the parent injector for
6379 * every Angular application on the page and provides singleton providers.
6380 * @abstract
6381 * @return {?}
6382 */
6383 PlatformRef.prototype.injector = function () { };
6384 /**
6385 * Destroy the Angular platform and all Angular applications on the page.
6386 * @abstract
6387 * @return {?}
6388 */
6389 PlatformRef.prototype.destroy = function () { };
6390 /**
6391 * @abstract
6392 * @return {?}
6393 */
6394 PlatformRef.prototype.destroyed = function () { };
6395 return PlatformRef;
6396}());
6397/**
6398 * @param {?} errorHandler
6399 * @param {?} ngZone
6400 * @param {?} callback
6401 * @return {?}
6402 */
6403function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
6404 try {
6405 var /** @type {?} */ result = callback();
6406 if (isPromise(result)) {
6407 return result.catch(function (e) {
6408 ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
6409 // rethrow as the exception handler might not do it
6410 throw e;
6411 });
6412 }
6413 return result;
6414 }
6415 catch (e) {
6416 ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
6417 // rethrow as the exception handler might not do it
6418 throw e;
6419 }
6420}
6421/**
6422 * workaround https://github.com/angular/tsickle/issues/350
6423 * @suppress {checkTypes}
6424 */
6425var PlatformRef_ = (function (_super) {
6426 __extends$1(PlatformRef_, _super);
6427 /**
6428 * @param {?} _injector
6429 */
6430 function PlatformRef_(_injector) {
6431 var _this = _super.call(this) || this;
6432 _this._injector = _injector;
6433 _this._modules = [];
6434 _this._destroyListeners = [];
6435 _this._destroyed = false;
6436 return _this;
6437 }
6438 /**
6439 * @param {?} callback
6440 * @return {?}
6441 */
6442 PlatformRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
6443 Object.defineProperty(PlatformRef_.prototype, "injector", {
6444 /**
6445 * @return {?}
6446 */
6447 get: function () { return this._injector; },
6448 enumerable: true,
6449 configurable: true
6450 });
6451 Object.defineProperty(PlatformRef_.prototype, "destroyed", {
6452 /**
6453 * @return {?}
6454 */
6455 get: function () { return this._destroyed; },
6456 enumerable: true,
6457 configurable: true
6458 });
6459 /**
6460 * @return {?}
6461 */
6462 PlatformRef_.prototype.destroy = function () {
6463 if (this._destroyed) {
6464 throw new Error('The platform has already been destroyed!');
6465 }
6466 this._modules.slice().forEach(function (module) { return module.destroy(); });
6467 this._destroyListeners.forEach(function (listener) { return listener(); });
6468 this._destroyed = true;
6469 };
6470 /**
6471 * @template M
6472 * @param {?} moduleFactory
6473 * @return {?}
6474 */
6475 PlatformRef_.prototype.bootstrapModuleFactory = function (moduleFactory) {
6476 return this._bootstrapModuleFactoryWithZone(moduleFactory);
6477 };
6478 /**
6479 * @template M
6480 * @param {?} moduleFactory
6481 * @param {?=} ngZone
6482 * @return {?}
6483 */
6484 PlatformRef_.prototype._bootstrapModuleFactoryWithZone = function (moduleFactory, ngZone) {
6485 var _this = this;
6486 // Note: We need to create the NgZone _before_ we instantiate the module,
6487 // as instantiating the module creates some providers eagerly.
6488 // So we create a mini parent injector that just contains the new NgZone and
6489 // pass that as parent to the NgModuleFactory.
6490 if (!ngZone)
6491 ngZone = new NgZone({ enableLongStackTrace: isDevMode() });
6492 // Attention: Don't use ApplicationRef.run here,
6493 // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
6494 return ngZone.run(function () {
6495 var /** @type {?} */ ngZoneInjector = ReflectiveInjector.resolveAndCreate([{ provide: NgZone, useValue: ngZone }], _this.injector);
6496 var /** @type {?} */ moduleRef = (moduleFactory.create(ngZoneInjector));
6497 var /** @type {?} */ exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
6498 if (!exceptionHandler) {
6499 throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
6500 }
6501 moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); }); /** @type {?} */
6502 ((ngZone)).runOutsideAngular(function () { return ((ngZone)).onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } }); });
6503 return _callAndReportToErrorHandler(exceptionHandler, /** @type {?} */ ((ngZone)), function () {
6504 var /** @type {?} */ initStatus = moduleRef.injector.get(ApplicationInitStatus);
6505 initStatus.runInitializers();
6506 return initStatus.donePromise.then(function () {
6507 _this._moduleDoBootstrap(moduleRef);
6508 return moduleRef;
6509 });
6510 });
6511 });
6512 };
6513 /**
6514 * @template M
6515 * @param {?} moduleType
6516 * @param {?=} compilerOptions
6517 * @return {?}
6518 */
6519 PlatformRef_.prototype.bootstrapModule = function (moduleType, compilerOptions) {
6520 if (compilerOptions === void 0) { compilerOptions = []; }
6521 return this._bootstrapModuleWithZone(moduleType, compilerOptions);
6522 };
6523 /**
6524 * @template M
6525 * @param {?} moduleType
6526 * @param {?=} compilerOptions
6527 * @param {?=} ngZone
6528 * @return {?}
6529 */
6530 PlatformRef_.prototype._bootstrapModuleWithZone = function (moduleType, compilerOptions, ngZone) {
6531 var _this = this;
6532 if (compilerOptions === void 0) { compilerOptions = []; }
6533 var /** @type {?} */ compilerFactory = this.injector.get(CompilerFactory);
6534 var /** @type {?} */ compiler = compilerFactory.createCompiler(Array.isArray(compilerOptions) ? compilerOptions : [compilerOptions]);
6535 return compiler.compileModuleAsync(moduleType)
6536 .then(function (moduleFactory) { return _this._bootstrapModuleFactoryWithZone(moduleFactory, ngZone); });
6537 };
6538 /**
6539 * @param {?} moduleRef
6540 * @return {?}
6541 */
6542 PlatformRef_.prototype._moduleDoBootstrap = function (moduleRef) {
6543 var /** @type {?} */ appRef = (moduleRef.injector.get(ApplicationRef));
6544 if (moduleRef._bootstrapComponents.length > 0) {
6545 moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
6546 }
6547 else if (moduleRef.instance.ngDoBootstrap) {
6548 moduleRef.instance.ngDoBootstrap(appRef);
6549 }
6550 else {
6551 throw new Error("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
6552 "Please define one of these.");
6553 }
6554 this._modules.push(moduleRef);
6555 };
6556 return PlatformRef_;
6557}(PlatformRef));
6558PlatformRef_.decorators = [
6559 { type: Injectable },
6560];
6561/**
6562 * @nocollapse
6563 */
6564PlatformRef_.ctorParameters = function () { return [
6565 { type: Injector, },
6566]; };
6567/**
6568 * A reference to an Angular application running on a page.
6569 *
6570 * \@stable
6571 * @abstract
6572 */
6573var ApplicationRef = (function () {
6574 function ApplicationRef() {
6575 }
6576 /**
6577 * Bootstrap a new component at the root level of the application.
6578 *
6579 * ### Bootstrap process
6580 *
6581 * When bootstrapping a new root component into an application, Angular mounts the
6582 * specified application component onto DOM elements identified by the [componentType]'s
6583 * selector and kicks off automatic change detection to finish initializing the component.
6584 *
6585 * Optionally, a component can be mounted onto a DOM element that does not match the
6586 * [componentType]'s selector.
6587 *
6588 * ### Example
6589 * {\@example core/ts/platform/platform.ts region='longform'}
6590 * @abstract
6591 * @template C
6592 * @param {?} componentFactory
6593 * @param {?=} rootSelectorOrNode
6594 * @return {?}
6595 */
6596 ApplicationRef.prototype.bootstrap = function (componentFactory, rootSelectorOrNode) { };
6597 /**
6598 * Invoke this method to explicitly process change detection and its side-effects.
6599 *
6600 * In development mode, `tick()` also performs a second change detection cycle to ensure that no
6601 * further changes are detected. If additional changes are picked up during this second cycle,
6602 * bindings in the app have side-effects that cannot be resolved in a single change detection
6603 * pass.
6604 * In this case, Angular throws an error, since an Angular application can only have one change
6605 * detection pass during which all change detection must complete.
6606 * @abstract
6607 * @return {?}
6608 */
6609 ApplicationRef.prototype.tick = function () { };
6610 /**
6611 * Get a list of component types registered to this application.
6612 * This list is populated even before the component is created.
6613 * @abstract
6614 * @return {?}
6615 */
6616 ApplicationRef.prototype.componentTypes = function () { };
6617 /**
6618 * Get a list of components registered to this application.
6619 * @abstract
6620 * @return {?}
6621 */
6622 ApplicationRef.prototype.components = function () { };
6623 /**
6624 * Attaches a view so that it will be dirty checked.
6625 * The view will be automatically detached when it is destroyed.
6626 * This will throw if the view is already attached to a ViewContainer.
6627 * @abstract
6628 * @param {?} view
6629 * @return {?}
6630 */
6631 ApplicationRef.prototype.attachView = function (view) { };
6632 /**
6633 * Detaches a view from dirty checking again.
6634 * @abstract
6635 * @param {?} view
6636 * @return {?}
6637 */
6638 ApplicationRef.prototype.detachView = function (view) { };
6639 /**
6640 * Returns the number of attached views.
6641 * @abstract
6642 * @return {?}
6643 */
6644 ApplicationRef.prototype.viewCount = function () { };
6645 /**
6646 * Returns an Observable that indicates when the application is stable or unstable.
6647 * @abstract
6648 * @return {?}
6649 */
6650 ApplicationRef.prototype.isStable = function () { };
6651 return ApplicationRef;
6652}());
6653/**
6654 * workaround https://github.com/angular/tsickle/issues/350
6655 * @suppress {checkTypes}
6656 */
6657var ApplicationRef_ = (function (_super) {
6658 __extends$1(ApplicationRef_, _super);
6659 /**
6660 * @param {?} _zone
6661 * @param {?} _console
6662 * @param {?} _injector
6663 * @param {?} _exceptionHandler
6664 * @param {?} _componentFactoryResolver
6665 * @param {?} _initStatus
6666 */
6667 function ApplicationRef_(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
6668 var _this = _super.call(this) || this;
6669 _this._zone = _zone;
6670 _this._console = _console;
6671 _this._injector = _injector;
6672 _this._exceptionHandler = _exceptionHandler;
6673 _this._componentFactoryResolver = _componentFactoryResolver;
6674 _this._initStatus = _initStatus;
6675 _this._bootstrapListeners = [];
6676 _this._rootComponents = [];
6677 _this._rootComponentTypes = [];
6678 _this._views = [];
6679 _this._runningTick = false;
6680 _this._enforceNoNewChanges = false;
6681 _this._stable = true;
6682 _this._enforceNoNewChanges = isDevMode();
6683 _this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
6684 var isCurrentlyStable = new Observable_2(function (observer) {
6685 _this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
6686 !_this._zone.hasPendingMicrotasks;
6687 _this._zone.runOutsideAngular(function () {
6688 observer.next(_this._stable);
6689 observer.complete();
6690 });
6691 });
6692 var isStable = new Observable_2(function (observer) {
6693 // Create the subscription to onStable outside the Angular Zone so that
6694 // the callback is run outside the Angular Zone.
6695 var stableSub;
6696 _this._zone.runOutsideAngular(function () {
6697 stableSub = _this._zone.onStable.subscribe(function () {
6698 NgZone.assertNotInAngularZone();
6699 // Check whether there are no pending macro/micro tasks in the next tick
6700 // to allow for NgZone to update the state.
6701 scheduleMicroTask(function () {
6702 if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
6703 !_this._zone.hasPendingMicrotasks) {
6704 _this._stable = true;
6705 observer.next(true);
6706 }
6707 });
6708 });
6709 });
6710 var unstableSub = _this._zone.onUnstable.subscribe(function () {
6711 NgZone.assertInAngularZone();
6712 if (_this._stable) {
6713 _this._stable = false;
6714 _this._zone.runOutsideAngular(function () { observer.next(false); });
6715 }
6716 });
6717 return function () {
6718 stableSub.unsubscribe();
6719 unstableSub.unsubscribe();
6720 };
6721 });
6722 _this._isStable = merge_2(isCurrentlyStable, share_2.call(isStable));
6723 return _this;
6724 }
6725 /**
6726 * @param {?} viewRef
6727 * @return {?}
6728 */
6729 ApplicationRef_.prototype.attachView = function (viewRef) {
6730 var /** @type {?} */ view = ((viewRef));
6731 this._views.push(view);
6732 view.attachToAppRef(this);
6733 };
6734 /**
6735 * @param {?} viewRef
6736 * @return {?}
6737 */
6738 ApplicationRef_.prototype.detachView = function (viewRef) {
6739 var /** @type {?} */ view = ((viewRef));
6740 remove(this._views, view);
6741 view.detachFromAppRef();
6742 };
6743 /**
6744 * @template C
6745 * @param {?} componentOrFactory
6746 * @param {?=} rootSelectorOrNode
6747 * @return {?}
6748 */
6749 ApplicationRef_.prototype.bootstrap = function (componentOrFactory, rootSelectorOrNode) {
6750 var _this = this;
6751 if (!this._initStatus.done) {
6752 throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
6753 }
6754 var /** @type {?} */ componentFactory;
6755 if (componentOrFactory instanceof ComponentFactory) {
6756 componentFactory = componentOrFactory;
6757 }
6758 else {
6759 componentFactory = ((this._componentFactoryResolver.resolveComponentFactory(componentOrFactory)));
6760 }
6761 this._rootComponentTypes.push(componentFactory.componentType);
6762 // Create a factory associated with the current module if it's not bound to some other
6763 var /** @type {?} */ ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
6764 null :
6765 this._injector.get(NgModuleRef);
6766 var /** @type {?} */ selectorOrNode = rootSelectorOrNode || componentFactory.selector;
6767 var /** @type {?} */ compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
6768 compRef.onDestroy(function () { _this._unloadComponent(compRef); });
6769 var /** @type {?} */ testability = compRef.injector.get(Testability, null);
6770 if (testability) {
6771 compRef.injector.get(TestabilityRegistry)
6772 .registerApplication(compRef.location.nativeElement, testability);
6773 }
6774 this._loadComponent(compRef);
6775 if (isDevMode()) {
6776 this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode.");
6777 }
6778 return compRef;
6779 };
6780 /**
6781 * @param {?} componentRef
6782 * @return {?}
6783 */
6784 ApplicationRef_.prototype._loadComponent = function (componentRef) {
6785 this.attachView(componentRef.hostView);
6786 this.tick();
6787 this._rootComponents.push(componentRef);
6788 // Get the listeners lazily to prevent DI cycles.
6789 var /** @type {?} */ listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
6790 listeners.forEach(function (listener) { return listener(componentRef); });
6791 };
6792 /**
6793 * @param {?} componentRef
6794 * @return {?}
6795 */
6796 ApplicationRef_.prototype._unloadComponent = function (componentRef) {
6797 this.detachView(componentRef.hostView);
6798 remove(this._rootComponents, componentRef);
6799 };
6800 /**
6801 * @return {?}
6802 */
6803 ApplicationRef_.prototype.tick = function () {
6804 var _this = this;
6805 if (this._runningTick) {
6806 throw new Error('ApplicationRef.tick is called recursively');
6807 }
6808 var /** @type {?} */ scope = ApplicationRef_._tickScope();
6809 try {
6810 this._runningTick = true;
6811 this._views.forEach(function (view) { return view.detectChanges(); });
6812 if (this._enforceNoNewChanges) {
6813 this._views.forEach(function (view) { return view.checkNoChanges(); });
6814 }
6815 }
6816 catch (e) {
6817 // Attention: Don't rethrow as it could cancel subscriptions to Observables!
6818 this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
6819 }
6820 finally {
6821 this._runningTick = false;
6822 wtfLeave(scope);
6823 }
6824 };
6825 /**
6826 * @return {?}
6827 */
6828 ApplicationRef_.prototype.ngOnDestroy = function () {
6829 // TODO(alxhub): Dispose of the NgZone.
6830 this._views.slice().forEach(function (view) { return view.destroy(); });
6831 };
6832 Object.defineProperty(ApplicationRef_.prototype, "viewCount", {
6833 /**
6834 * @return {?}
6835 */
6836 get: function () { return this._views.length; },
6837 enumerable: true,
6838 configurable: true
6839 });
6840 Object.defineProperty(ApplicationRef_.prototype, "componentTypes", {
6841 /**
6842 * @return {?}
6843 */
6844 get: function () { return this._rootComponentTypes; },
6845 enumerable: true,
6846 configurable: true
6847 });
6848 Object.defineProperty(ApplicationRef_.prototype, "components", {
6849 /**
6850 * @return {?}
6851 */
6852 get: function () { return this._rootComponents; },
6853 enumerable: true,
6854 configurable: true
6855 });
6856 Object.defineProperty(ApplicationRef_.prototype, "isStable", {
6857 /**
6858 * @return {?}
6859 */
6860 get: function () { return this._isStable; },
6861 enumerable: true,
6862 configurable: true
6863 });
6864 return ApplicationRef_;
6865}(ApplicationRef));
6866/**
6867 * \@internal
6868 */
6869ApplicationRef_._tickScope = wtfCreateScope('ApplicationRef#tick()');
6870ApplicationRef_.decorators = [
6871 { type: Injectable },
6872];
6873/**
6874 * @nocollapse
6875 */
6876ApplicationRef_.ctorParameters = function () { return [
6877 { type: NgZone, },
6878 { type: Console, },
6879 { type: Injector, },
6880 { type: ErrorHandler, },
6881 { type: ComponentFactoryResolver, },
6882 { type: ApplicationInitStatus, },
6883]; };
6884/**
6885 * @template T
6886 * @param {?} list
6887 * @param {?} el
6888 * @return {?}
6889 */
6890function remove(list, el) {
6891 var /** @type {?} */ index = list.indexOf(el);
6892 if (index > -1) {
6893 list.splice(index, 1);
6894 }
6895}
6896/**
6897 * @deprecated Use the `Renderer2` instead.
6898 * @abstract
6899 */
6900var Renderer = (function () {
6901 function Renderer() {
6902 }
6903 /**
6904 * @abstract
6905 * @param {?} selectorOrNode
6906 * @param {?=} debugInfo
6907 * @return {?}
6908 */
6909 Renderer.prototype.selectRootElement = function (selectorOrNode, debugInfo) { };
6910 /**
6911 * @abstract
6912 * @param {?} parentElement
6913 * @param {?} name
6914 * @param {?=} debugInfo
6915 * @return {?}
6916 */
6917 Renderer.prototype.createElement = function (parentElement, name, debugInfo) { };
6918 /**
6919 * @abstract
6920 * @param {?} hostElement
6921 * @return {?}
6922 */
6923 Renderer.prototype.createViewRoot = function (hostElement) { };
6924 /**
6925 * @abstract
6926 * @param {?} parentElement
6927 * @param {?=} debugInfo
6928 * @return {?}
6929 */
6930 Renderer.prototype.createTemplateAnchor = function (parentElement, debugInfo) { };
6931 /**
6932 * @abstract
6933 * @param {?} parentElement
6934 * @param {?} value
6935 * @param {?=} debugInfo
6936 * @return {?}
6937 */
6938 Renderer.prototype.createText = function (parentElement, value, debugInfo) { };
6939 /**
6940 * @abstract
6941 * @param {?} parentElement
6942 * @param {?} nodes
6943 * @return {?}
6944 */
6945 Renderer.prototype.projectNodes = function (parentElement, nodes) { };
6946 /**
6947 * @abstract
6948 * @param {?} node
6949 * @param {?} viewRootNodes
6950 * @return {?}
6951 */
6952 Renderer.prototype.attachViewAfter = function (node, viewRootNodes) { };
6953 /**
6954 * @abstract
6955 * @param {?} viewRootNodes
6956 * @return {?}
6957 */
6958 Renderer.prototype.detachView = function (viewRootNodes) { };
6959 /**
6960 * @abstract
6961 * @param {?} hostElement
6962 * @param {?} viewAllNodes
6963 * @return {?}
6964 */
6965 Renderer.prototype.destroyView = function (hostElement, viewAllNodes) { };
6966 /**
6967 * @abstract
6968 * @param {?} renderElement
6969 * @param {?} name
6970 * @param {?} callback
6971 * @return {?}
6972 */
6973 Renderer.prototype.listen = function (renderElement, name, callback) { };
6974 /**
6975 * @abstract
6976 * @param {?} target
6977 * @param {?} name
6978 * @param {?} callback
6979 * @return {?}
6980 */
6981 Renderer.prototype.listenGlobal = function (target, name, callback) { };
6982 /**
6983 * @abstract
6984 * @param {?} renderElement
6985 * @param {?} propertyName
6986 * @param {?} propertyValue
6987 * @return {?}
6988 */
6989 Renderer.prototype.setElementProperty = function (renderElement, propertyName, propertyValue) { };
6990 /**
6991 * @abstract
6992 * @param {?} renderElement
6993 * @param {?} attributeName
6994 * @param {?} attributeValue
6995 * @return {?}
6996 */
6997 Renderer.prototype.setElementAttribute = function (renderElement, attributeName, attributeValue) { };
6998 /**
6999 * Used only in debug mode to serialize property changes to dom nodes as attributes.
7000 * @abstract
7001 * @param {?} renderElement
7002 * @param {?} propertyName
7003 * @param {?} propertyValue
7004 * @return {?}
7005 */
7006 Renderer.prototype.setBindingDebugInfo = function (renderElement, propertyName, propertyValue) { };
7007 /**
7008 * @abstract
7009 * @param {?} renderElement
7010 * @param {?} className
7011 * @param {?} isAdd
7012 * @return {?}
7013 */
7014 Renderer.prototype.setElementClass = function (renderElement, className, isAdd) { };
7015 /**
7016 * @abstract
7017 * @param {?} renderElement
7018 * @param {?} styleName
7019 * @param {?} styleValue
7020 * @return {?}
7021 */
7022 Renderer.prototype.setElementStyle = function (renderElement, styleName, styleValue) { };
7023 /**
7024 * @abstract
7025 * @param {?} renderElement
7026 * @param {?} methodName
7027 * @param {?=} args
7028 * @return {?}
7029 */
7030 Renderer.prototype.invokeElementMethod = function (renderElement, methodName, args) { };
7031 /**
7032 * @abstract
7033 * @param {?} renderNode
7034 * @param {?} text
7035 * @return {?}
7036 */
7037 Renderer.prototype.setText = function (renderNode, text) { };
7038 /**
7039 * @abstract
7040 * @param {?} element
7041 * @param {?} startingStyles
7042 * @param {?} keyframes
7043 * @param {?} duration
7044 * @param {?} delay
7045 * @param {?} easing
7046 * @param {?=} previousPlayers
7047 * @return {?}
7048 */
7049 Renderer.prototype.animate = function (element, startingStyles, keyframes, duration, delay, easing, previousPlayers) { };
7050 return Renderer;
7051}());
7052var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
7053/**
7054 * \@experimental
7055 * @abstract
7056 */
7057var RendererFactory2 = (function () {
7058 function RendererFactory2() {
7059 }
7060 /**
7061 * @abstract
7062 * @param {?} hostElement
7063 * @param {?} type
7064 * @return {?}
7065 */
7066 RendererFactory2.prototype.createRenderer = function (hostElement, type) { };
7067 /**
7068 * @abstract
7069 * @return {?}
7070 */
7071 RendererFactory2.prototype.begin = function () { };
7072 /**
7073 * @abstract
7074 * @return {?}
7075 */
7076 RendererFactory2.prototype.end = function () { };
7077 /**
7078 * @abstract
7079 * @return {?}
7080 */
7081 RendererFactory2.prototype.whenRenderingDone = function () { };
7082 return RendererFactory2;
7083}());
7084var RendererStyleFlags2 = {};
7085RendererStyleFlags2.Important = 1;
7086RendererStyleFlags2.DashCase = 2;
7087RendererStyleFlags2[RendererStyleFlags2.Important] = "Important";
7088RendererStyleFlags2[RendererStyleFlags2.DashCase] = "DashCase";
7089/**
7090 * \@experimental
7091 * @abstract
7092 */
7093var Renderer2 = (function () {
7094 function Renderer2() {
7095 }
7096 /**
7097 * This field can be used to store arbitrary data on this renderer instance.
7098 * This is useful for renderers that delegate to other renderers.
7099 * @abstract
7100 * @return {?}
7101 */
7102 Renderer2.prototype.data = function () { };
7103 /**
7104 * @abstract
7105 * @return {?}
7106 */
7107 Renderer2.prototype.destroy = function () { };
7108 /**
7109 * @abstract
7110 * @param {?} name
7111 * @param {?=} namespace
7112 * @return {?}
7113 */
7114 Renderer2.prototype.createElement = function (name, namespace) { };
7115 /**
7116 * @abstract
7117 * @param {?} value
7118 * @return {?}
7119 */
7120 Renderer2.prototype.createComment = function (value) { };
7121 /**
7122 * @abstract
7123 * @param {?} value
7124 * @return {?}
7125 */
7126 Renderer2.prototype.createText = function (value) { };
7127 /**
7128 * @abstract
7129 * @param {?} parent
7130 * @param {?} newChild
7131 * @return {?}
7132 */
7133 Renderer2.prototype.appendChild = function (parent, newChild) { };
7134 /**
7135 * @abstract
7136 * @param {?} parent
7137 * @param {?} newChild
7138 * @param {?} refChild
7139 * @return {?}
7140 */
7141 Renderer2.prototype.insertBefore = function (parent, newChild, refChild) { };
7142 /**
7143 * @abstract
7144 * @param {?} parent
7145 * @param {?} oldChild
7146 * @return {?}
7147 */
7148 Renderer2.prototype.removeChild = function (parent, oldChild) { };
7149 /**
7150 * @abstract
7151 * @param {?} selectorOrNode
7152 * @return {?}
7153 */
7154 Renderer2.prototype.selectRootElement = function (selectorOrNode) { };
7155 /**
7156 * Attention: On WebWorkers, this will always return a value,
7157 * as we are asking for a result synchronously. I.e.
7158 * the caller can't rely on checking whether this is null or not.
7159 * @abstract
7160 * @param {?} node
7161 * @return {?}
7162 */
7163 Renderer2.prototype.parentNode = function (node) { };
7164 /**
7165 * Attention: On WebWorkers, this will always return a value,
7166 * as we are asking for a result synchronously. I.e.
7167 * the caller can't rely on checking whether this is null or not.
7168 * @abstract
7169 * @param {?} node
7170 * @return {?}
7171 */
7172 Renderer2.prototype.nextSibling = function (node) { };
7173 /**
7174 * @abstract
7175 * @param {?} el
7176 * @param {?} name
7177 * @param {?} value
7178 * @param {?=} namespace
7179 * @return {?}
7180 */
7181 Renderer2.prototype.setAttribute = function (el, name, value, namespace) { };
7182 /**
7183 * @abstract
7184 * @param {?} el
7185 * @param {?} name
7186 * @param {?=} namespace
7187 * @return {?}
7188 */
7189 Renderer2.prototype.removeAttribute = function (el, name, namespace) { };
7190 /**
7191 * @abstract
7192 * @param {?} el
7193 * @param {?} name
7194 * @return {?}
7195 */
7196 Renderer2.prototype.addClass = function (el, name) { };
7197 /**
7198 * @abstract
7199 * @param {?} el
7200 * @param {?} name
7201 * @return {?}
7202 */
7203 Renderer2.prototype.removeClass = function (el, name) { };
7204 /**
7205 * @abstract
7206 * @param {?} el
7207 * @param {?} style
7208 * @param {?} value
7209 * @param {?=} flags
7210 * @return {?}
7211 */
7212 Renderer2.prototype.setStyle = function (el, style, value, flags) { };
7213 /**
7214 * @abstract
7215 * @param {?} el
7216 * @param {?} style
7217 * @param {?=} flags
7218 * @return {?}
7219 */
7220 Renderer2.prototype.removeStyle = function (el, style, flags) { };
7221 /**
7222 * @abstract
7223 * @param {?} el
7224 * @param {?} name
7225 * @param {?} value
7226 * @return {?}
7227 */
7228 Renderer2.prototype.setProperty = function (el, name, value) { };
7229 /**
7230 * @abstract
7231 * @param {?} node
7232 * @param {?} value
7233 * @return {?}
7234 */
7235 Renderer2.prototype.setValue = function (node, value) { };
7236 /**
7237 * @abstract
7238 * @param {?} target
7239 * @param {?} eventName
7240 * @param {?} callback
7241 * @return {?}
7242 */
7243 Renderer2.prototype.listen = function (target, eventName, callback) { };
7244 return Renderer2;
7245}());
7246/**
7247 * @license
7248 * Copyright Google Inc. All Rights Reserved.
7249 *
7250 * Use of this source code is governed by an MIT-style license that can be
7251 * found in the LICENSE file at https://angular.io/license
7252 */
7253// Public API for render
7254var ElementRef = (function () {
7255 /**
7256 * @param {?} nativeElement
7257 */
7258 function ElementRef(nativeElement) {
7259 this.nativeElement = nativeElement;
7260 }
7261 return ElementRef;
7262}());
7263var moduleFactories = new Map();
7264/**
7265 * @license
7266 * Copyright Google Inc. All Rights Reserved.
7267 *
7268 * Use of this source code is governed by an MIT-style license that can be
7269 * found in the LICENSE file at https://angular.io/license
7270 */
7271/**
7272 * An unmodifiable list of items that Angular keeps up to date when the state
7273 * of the application changes.
7274 *
7275 * The type of object that {\@link ViewChildren}, {\@link ContentChildren}, and {\@link QueryList}
7276 * provide.
7277 *
7278 * Implements an iterable interface, therefore it can be used in both ES6
7279 * javascript `for (var i of items)` loops as well as in Angular templates with
7280 * `*ngFor="let i of myList"`.
7281 *
7282 * Changes can be observed by subscribing to the changes `Observable`.
7283 *
7284 * NOTE: In the future this class will implement an `Observable` interface.
7285 *
7286 * ### Example ([live demo](http://plnkr.co/edit/RX8sJnQYl9FWuSCWme5z?p=preview))
7287 * ```typescript
7288 * \@Component({...})
7289 * class Container {
7290 * \@ViewChildren(Item) items:QueryList<Item>;
7291 * }
7292 * ```
7293 * \@stable
7294 */
7295var QueryList = (function () {
7296 function QueryList() {
7297 this._dirty = true;
7298 this._results = [];
7299 this._emitter = new EventEmitter();
7300 }
7301 Object.defineProperty(QueryList.prototype, "changes", {
7302 /**
7303 * @return {?}
7304 */
7305 get: function () { return this._emitter; },
7306 enumerable: true,
7307 configurable: true
7308 });
7309 Object.defineProperty(QueryList.prototype, "length", {
7310 /**
7311 * @return {?}
7312 */
7313 get: function () { return this._results.length; },
7314 enumerable: true,
7315 configurable: true
7316 });
7317 Object.defineProperty(QueryList.prototype, "first", {
7318 /**
7319 * @return {?}
7320 */
7321 get: function () { return this._results[0]; },
7322 enumerable: true,
7323 configurable: true
7324 });
7325 Object.defineProperty(QueryList.prototype, "last", {
7326 /**
7327 * @return {?}
7328 */
7329 get: function () { return this._results[this.length - 1]; },
7330 enumerable: true,
7331 configurable: true
7332 });
7333 /**
7334 * See
7335 * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
7336 * @template U
7337 * @param {?} fn
7338 * @return {?}
7339 */
7340 QueryList.prototype.map = function (fn) { return this._results.map(fn); };
7341 /**
7342 * See
7343 * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
7344 * @param {?} fn
7345 * @return {?}
7346 */
7347 QueryList.prototype.filter = function (fn) {
7348 return this._results.filter(fn);
7349 };
7350 /**
7351 * See
7352 * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
7353 * @param {?} fn
7354 * @return {?}
7355 */
7356 QueryList.prototype.find = function (fn) {
7357 return this._results.find(fn);
7358 };
7359 /**
7360 * See
7361 * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
7362 * @template U
7363 * @param {?} fn
7364 * @param {?} init
7365 * @return {?}
7366 */
7367 QueryList.prototype.reduce = function (fn, init) {
7368 return this._results.reduce(fn, init);
7369 };
7370 /**
7371 * See
7372 * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
7373 * @param {?} fn
7374 * @return {?}
7375 */
7376 QueryList.prototype.forEach = function (fn) { this._results.forEach(fn); };
7377 /**
7378 * See
7379 * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
7380 * @param {?} fn
7381 * @return {?}
7382 */
7383 QueryList.prototype.some = function (fn) {
7384 return this._results.some(fn);
7385 };
7386 /**
7387 * @return {?}
7388 */
7389 QueryList.prototype.toArray = function () { return this._results.slice(); };
7390 /**
7391 * @return {?}
7392 */
7393 QueryList.prototype[getSymbolIterator()] = function () { return ((this._results))[getSymbolIterator()](); };
7394 /**
7395 * @return {?}
7396 */
7397 QueryList.prototype.toString = function () { return this._results.toString(); };
7398 /**
7399 * @param {?} res
7400 * @return {?}
7401 */
7402 QueryList.prototype.reset = function (res) {
7403 this._results = flatten(res);
7404 this._dirty = false;
7405 };
7406 /**
7407 * @return {?}
7408 */
7409 QueryList.prototype.notifyOnChanges = function () { this._emitter.emit(this); };
7410 /**
7411 * internal
7412 * @return {?}
7413 */
7414 QueryList.prototype.setDirty = function () { this._dirty = true; };
7415 Object.defineProperty(QueryList.prototype, "dirty", {
7416 /**
7417 * internal
7418 * @return {?}
7419 */
7420 get: function () { return this._dirty; },
7421 enumerable: true,
7422 configurable: true
7423 });
7424 /**
7425 * internal
7426 * @return {?}
7427 */
7428 QueryList.prototype.destroy = function () {
7429 this._emitter.complete();
7430 this._emitter.unsubscribe();
7431 };
7432 return QueryList;
7433}());
7434/**
7435 * @template T
7436 * @param {?} list
7437 * @return {?}
7438 */
7439function flatten(list) {
7440 return list.reduce(function (flat, item) {
7441 var /** @type {?} */ flatItem = Array.isArray(item) ? flatten(item) : item;
7442 return ((flat)).concat(flatItem);
7443 }, []);
7444}
7445/**
7446 * @license
7447 * Copyright Google Inc. All Rights Reserved.
7448 *
7449 * Use of this source code is governed by an MIT-style license that can be
7450 * found in the LICENSE file at https://angular.io/license
7451 */
7452var _SEPARATOR = '#';
7453var FACTORY_CLASS_SUFFIX = 'NgFactory';
7454/**
7455 * Configuration for SystemJsNgModuleLoader.
7456 * token.
7457 *
7458 * \@experimental
7459 * @abstract
7460 */
7461var SystemJsNgModuleLoaderConfig = (function () {
7462 function SystemJsNgModuleLoaderConfig() {
7463 }
7464 return SystemJsNgModuleLoaderConfig;
7465}());
7466var DEFAULT_CONFIG = {
7467 factoryPathPrefix: '',
7468 factoryPathSuffix: '.ngfactory',
7469};
7470/**
7471 * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
7472 * \@experimental
7473 */
7474var SystemJsNgModuleLoader = (function () {
7475 /**
7476 * @param {?} _compiler
7477 * @param {?=} config
7478 */
7479 function SystemJsNgModuleLoader(_compiler, config) {
7480 this._compiler = _compiler;
7481 this._config = config || DEFAULT_CONFIG;
7482 }
7483 /**
7484 * @param {?} path
7485 * @return {?}
7486 */
7487 SystemJsNgModuleLoader.prototype.load = function (path) {
7488 var /** @type {?} */ offlineMode = this._compiler instanceof Compiler;
7489 return offlineMode ? this.loadFactory(path) : this.loadAndCompile(path);
7490 };
7491 /**
7492 * @param {?} path
7493 * @return {?}
7494 */
7495 SystemJsNgModuleLoader.prototype.loadAndCompile = function (path) {
7496 var _this = this;
7497 var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
7498 if (exportName === undefined) {
7499 exportName = 'default';
7500 }
7501 return System.import(module)
7502 .then(function (module) { return module[exportName]; })
7503 .then(function (type) { return checkNotEmpty(type, module, exportName); })
7504 .then(function (type) { return _this._compiler.compileModuleAsync(type); });
7505 };
7506 /**
7507 * @param {?} path
7508 * @return {?}
7509 */
7510 SystemJsNgModuleLoader.prototype.loadFactory = function (path) {
7511 var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
7512 var /** @type {?} */ factoryClassSuffix = FACTORY_CLASS_SUFFIX;
7513 if (exportName === undefined) {
7514 exportName = 'default';
7515 factoryClassSuffix = '';
7516 }
7517 return System.import(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
7518 .then(function (module) { return module[exportName + factoryClassSuffix]; })
7519 .then(function (factory) { return checkNotEmpty(factory, module, exportName); });
7520 };
7521 return SystemJsNgModuleLoader;
7522}());
7523SystemJsNgModuleLoader.decorators = [
7524 { type: Injectable },
7525];
7526/**
7527 * @nocollapse
7528 */
7529SystemJsNgModuleLoader.ctorParameters = function () { return [
7530 { type: Compiler, },
7531 { type: SystemJsNgModuleLoaderConfig, decorators: [{ type: Optional },] },
7532]; };
7533/**
7534 * @param {?} value
7535 * @param {?} modulePath
7536 * @param {?} exportName
7537 * @return {?}
7538 */
7539function checkNotEmpty(value, modulePath, exportName) {
7540 if (!value) {
7541 throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
7542 }
7543 return value;
7544}
7545/**
7546 * @license
7547 * Copyright Google Inc. All Rights Reserved.
7548 *
7549 * Use of this source code is governed by an MIT-style license that can be
7550 * found in the LICENSE file at https://angular.io/license
7551 */
7552/**
7553 * Represents an Embedded Template that can be used to instantiate Embedded Views.
7554 *
7555 * You can access a `TemplateRef`, in two ways. Via a directive placed on a `<ng-template>` element
7556 * (or directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into
7557 * the constructor of the directive using the `TemplateRef` Token. Alternatively you can query for
7558 * the `TemplateRef` from a Component or a Directive via {\@link Query}.
7559 *
7560 * To instantiate Embedded Views based on a Template, use
7561 * {\@link ViewContainerRef#createEmbeddedView}, which will create the View and attach it to the
7562 * View Container.
7563 * \@stable
7564 * @abstract
7565 */
7566var TemplateRef = (function () {
7567 function TemplateRef() {
7568 }
7569 /**
7570 * @abstract
7571 * @return {?}
7572 */
7573 TemplateRef.prototype.elementRef = function () { };
7574 /**
7575 * @abstract
7576 * @param {?} context
7577 * @return {?}
7578 */
7579 TemplateRef.prototype.createEmbeddedView = function (context) { };
7580 return TemplateRef;
7581}());
7582/**
7583 * @license
7584 * Copyright Google Inc. All Rights Reserved.
7585 *
7586 * Use of this source code is governed by an MIT-style license that can be
7587 * found in the LICENSE file at https://angular.io/license
7588 */
7589/**
7590 * Represents a container where one or more Views can be attached.
7591 *
7592 * The container can contain two kinds of Views. Host Views, created by instantiating a
7593 * {\@link Component} via {\@link #createComponent}, and Embedded Views, created by instantiating an
7594 * {\@link TemplateRef Embedded Template} via {\@link #createEmbeddedView}.
7595 *
7596 * The location of the View Container within the containing View is specified by the Anchor
7597 * `element`. Each View Container can have only one Anchor Element and each Anchor Element can only
7598 * have a single View Container.
7599 *
7600 * Root elements of Views attached to this container become siblings of the Anchor Element in
7601 * the Rendered View.
7602 *
7603 * To access a `ViewContainerRef` of an Element, you can either place a {\@link Directive} injected
7604 * with `ViewContainerRef` on the Element, or you obtain it via a {\@link ViewChild} query.
7605 * \@stable
7606 * @abstract
7607 */
7608var ViewContainerRef = (function () {
7609 function ViewContainerRef() {
7610 }
7611 /**
7612 * Anchor element that specifies the location of this container in the containing View.
7613 * <!-- TODO: rename to anchorElement -->
7614 * @abstract
7615 * @return {?}
7616 */
7617 ViewContainerRef.prototype.element = function () { };
7618 /**
7619 * @abstract
7620 * @return {?}
7621 */
7622 ViewContainerRef.prototype.injector = function () { };
7623 /**
7624 * @abstract
7625 * @return {?}
7626 */
7627 ViewContainerRef.prototype.parentInjector = function () { };
7628 /**
7629 * Destroys all Views in this container.
7630 * @abstract
7631 * @return {?}
7632 */
7633 ViewContainerRef.prototype.clear = function () { };
7634 /**
7635 * Returns the {\@link ViewRef} for the View located in this container at the specified index.
7636 * @abstract
7637 * @param {?} index
7638 * @return {?}
7639 */
7640 ViewContainerRef.prototype.get = function (index) { };
7641 /**
7642 * Returns the number of Views currently attached to this container.
7643 * @abstract
7644 * @return {?}
7645 */
7646 ViewContainerRef.prototype.length = function () { };
7647 /**
7648 * Instantiates an Embedded View based on the {\@link TemplateRef `templateRef`} and inserts it
7649 * into this container at the specified `index`.
7650 *
7651 * If `index` is not specified, the new View will be inserted as the last View in the container.
7652 *
7653 * Returns the {\@link ViewRef} for the newly created View.
7654 * @abstract
7655 * @template C
7656 * @param {?} templateRef
7657 * @param {?=} context
7658 * @param {?=} index
7659 * @return {?}
7660 */
7661 ViewContainerRef.prototype.createEmbeddedView = function (templateRef, context, index) { };
7662 /**
7663 * Instantiates a single {\@link Component} and inserts its Host View into this container at the
7664 * specified `index`.
7665 *
7666 * The component is instantiated using its {\@link ComponentFactory} which can be
7667 * obtained via {\@link ComponentFactoryResolver#resolveComponentFactory}.
7668 *
7669 * If `index` is not specified, the new View will be inserted as the last View in the container.
7670 *
7671 * You can optionally specify the {\@link Injector} that will be used as parent for the Component.
7672 *
7673 * Returns the {\@link ComponentRef} of the Host View created for the newly instantiated Component.
7674 * @abstract
7675 * @template C
7676 * @param {?} componentFactory
7677 * @param {?=} index
7678 * @param {?=} injector
7679 * @param {?=} projectableNodes
7680 * @param {?=} ngModule
7681 * @return {?}
7682 */
7683 ViewContainerRef.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModule) { };
7684 /**
7685 * Inserts a View identified by a {\@link ViewRef} into the container at the specified `index`.
7686 *
7687 * If `index` is not specified, the new View will be inserted as the last View in the container.
7688 *
7689 * Returns the inserted {\@link ViewRef}.
7690 * @abstract
7691 * @param {?} viewRef
7692 * @param {?=} index
7693 * @return {?}
7694 */
7695 ViewContainerRef.prototype.insert = function (viewRef, index) { };
7696 /**
7697 * Moves a View identified by a {\@link ViewRef} into the container at the specified `index`.
7698 *
7699 * Returns the inserted {\@link ViewRef}.
7700 * @abstract
7701 * @param {?} viewRef
7702 * @param {?} currentIndex
7703 * @return {?}
7704 */
7705 ViewContainerRef.prototype.move = function (viewRef, currentIndex) { };
7706 /**
7707 * Returns the index of the View, specified via {\@link ViewRef}, within the current container or
7708 * `-1` if this container doesn't contain the View.
7709 * @abstract
7710 * @param {?} viewRef
7711 * @return {?}
7712 */
7713 ViewContainerRef.prototype.indexOf = function (viewRef) { };
7714 /**
7715 * Destroys a View attached to this container at the specified `index`.
7716 *
7717 * If `index` is not specified, the last View in the container will be removed.
7718 * @abstract
7719 * @param {?=} index
7720 * @return {?}
7721 */
7722 ViewContainerRef.prototype.remove = function (index) { };
7723 /**
7724 * Use along with {\@link #insert} to move a View within the current container.
7725 *
7726 * If the `index` param is omitted, the last {\@link ViewRef} is detached.
7727 * @abstract
7728 * @param {?=} index
7729 * @return {?}
7730 */
7731 ViewContainerRef.prototype.detach = function (index) { };
7732 return ViewContainerRef;
7733}());
7734/**
7735 * \@stable
7736 * @abstract
7737 */
7738var ChangeDetectorRef = (function () {
7739 function ChangeDetectorRef() {
7740 }
7741 /**
7742 * Marks all {\@link ChangeDetectionStrategy#OnPush} ancestors as to be checked.
7743 *
7744 * <!-- TODO: Add a link to a chapter on OnPush components -->
7745 *
7746 * ### Example ([live demo](http://plnkr.co/edit/GC512b?p=preview))
7747 *
7748 * ```typescript
7749 * \@Component({
7750 * selector: 'cmp',
7751 * changeDetection: ChangeDetectionStrategy.OnPush,
7752 * template: `Number of ticks: {{numberOfTicks}}`
7753 * })
7754 * class Cmp {
7755 * numberOfTicks = 0;
7756 *
7757 * constructor(private ref: ChangeDetectorRef) {
7758 * setInterval(() => {
7759 * this.numberOfTicks++;
7760 * // the following is required, otherwise the view will not be updated
7761 * this.ref.markForCheck();
7762 * }, 1000);
7763 * }
7764 * }
7765 *
7766 * \@Component({
7767 * selector: 'app',
7768 * changeDetection: ChangeDetectionStrategy.OnPush,
7769 * template: `
7770 * <cmp><cmp>
7771 * `,
7772 * })
7773 * class App {
7774 * }
7775 * ```
7776 * @abstract
7777 * @return {?}
7778 */
7779 ChangeDetectorRef.prototype.markForCheck = function () { };
7780 /**
7781 * Detaches the change detector from the change detector tree.
7782 *
7783 * The detached change detector will not be checked until it is reattached.
7784 *
7785 * This can also be used in combination with {\@link ChangeDetectorRef#detectChanges} to implement
7786 * local change
7787 * detection checks.
7788 *
7789 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
7790 * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
7791 *
7792 * ### Example
7793 *
7794 * The following example defines a component with a large list of readonly data.
7795 * Imagine the data changes constantly, many times per second. For performance reasons,
7796 * we want to check and update the list every five seconds. We can do that by detaching
7797 * the component's change detector and doing a local check every five seconds.
7798 *
7799 * ```typescript
7800 * class DataProvider {
7801 * // in a real application the returned data will be different every time
7802 * get data() {
7803 * return [1,2,3,4,5];
7804 * }
7805 * }
7806 *
7807 * \@Component({
7808 * selector: 'giant-list',
7809 * template: `
7810 * <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
7811 * `,
7812 * })
7813 * class GiantList {
7814 * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
7815 * ref.detach();
7816 * setInterval(() => {
7817 * this.ref.detectChanges();
7818 * }, 5000);
7819 * }
7820 * }
7821 *
7822 * \@Component({
7823 * selector: 'app',
7824 * providers: [DataProvider],
7825 * template: `
7826 * <giant-list><giant-list>
7827 * `,
7828 * })
7829 * class App {
7830 * }
7831 * ```
7832 * @abstract
7833 * @return {?}
7834 */
7835 ChangeDetectorRef.prototype.detach = function () { };
7836 /**
7837 * Checks the change detector and its children.
7838 *
7839 * This can also be used in combination with {\@link ChangeDetectorRef#detach} to implement local
7840 * change detection
7841 * checks.
7842 *
7843 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
7844 * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
7845 *
7846 * ### Example
7847 *
7848 * The following example defines a component with a large list of readonly data.
7849 * Imagine, the data changes constantly, many times per second. For performance reasons,
7850 * we want to check and update the list every five seconds.
7851 *
7852 * We can do that by detaching the component's change detector and doing a local change detection
7853 * check
7854 * every five seconds.
7855 *
7856 * See {\@link ChangeDetectorRef#detach} for more information.
7857 * @abstract
7858 * @return {?}
7859 */
7860 ChangeDetectorRef.prototype.detectChanges = function () { };
7861 /**
7862 * Checks the change detector and its children, and throws if any changes are detected.
7863 *
7864 * This is used in development mode to verify that running change detection doesn't introduce
7865 * other changes.
7866 * @abstract
7867 * @return {?}
7868 */
7869 ChangeDetectorRef.prototype.checkNoChanges = function () { };
7870 /**
7871 * Reattach the change detector to the change detector tree.
7872 *
7873 * This also marks OnPush ancestors as to be checked. This reattached change detector will be
7874 * checked during the next change detection run.
7875 *
7876 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
7877 *
7878 * ### Example ([live demo](http://plnkr.co/edit/aUhZha?p=preview))
7879 *
7880 * The following example creates a component displaying `live` data. The component will detach
7881 * its change detector from the main change detector tree when the component's live property
7882 * is set to false.
7883 *
7884 * ```typescript
7885 * class DataProvider {
7886 * data = 1;
7887 *
7888 * constructor() {
7889 * setInterval(() => {
7890 * this.data = this.data * 2;
7891 * }, 500);
7892 * }
7893 * }
7894 *
7895 * \@Component({
7896 * selector: 'live-data',
7897 * inputs: ['live'],
7898 * template: 'Data: {{dataProvider.data}}'
7899 * })
7900 * class LiveData {
7901 * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
7902 *
7903 * set live(value) {
7904 * if (value) {
7905 * this.ref.reattach();
7906 * } else {
7907 * this.ref.detach();
7908 * }
7909 * }
7910 * }
7911 *
7912 * \@Component({
7913 * selector: 'app',
7914 * providers: [DataProvider],
7915 * template: `
7916 * Live Update: <input type="checkbox" [(ngModel)]="live">
7917 * <live-data [live]="live"><live-data>
7918 * `,
7919 * })
7920 * class App {
7921 * live = true;
7922 * }
7923 * ```
7924 * @abstract
7925 * @return {?}
7926 */
7927 ChangeDetectorRef.prototype.reattach = function () { };
7928 return ChangeDetectorRef;
7929}());
7930/**
7931 * @license
7932 * Copyright Google Inc. All Rights Reserved.
7933 *
7934 * Use of this source code is governed by an MIT-style license that can be
7935 * found in the LICENSE file at https://angular.io/license
7936 */
7937/**
7938 * \@stable
7939 * @abstract
7940 */
7941var ViewRef = (function (_super) {
7942 __extends$1(ViewRef, _super);
7943 function ViewRef() {
7944 return _super !== null && _super.apply(this, arguments) || this;
7945 }
7946 /**
7947 * Destroys the view and all of the data structures associated with it.
7948 * @abstract
7949 * @return {?}
7950 */
7951 ViewRef.prototype.destroy = function () { };
7952 /**
7953 * @abstract
7954 * @return {?}
7955 */
7956 ViewRef.prototype.destroyed = function () { };
7957 /**
7958 * @abstract
7959 * @param {?} callback
7960 * @return {?}
7961 */
7962 ViewRef.prototype.onDestroy = function (callback) { };
7963 return ViewRef;
7964}(ChangeDetectorRef));
7965/**
7966 * Represents an Angular View.
7967 *
7968 * <!-- TODO: move the next two paragraphs to the dev guide -->
7969 * A View is a fundamental building block of the application UI. It is the smallest grouping of
7970 * Elements which are created and destroyed together.
7971 *
7972 * Properties of elements in a View can change, but the structure (number and order) of elements in
7973 * a View cannot. Changing the structure of Elements can only be done by inserting, moving or
7974 * removing nested Views via a {\@link ViewContainerRef}. Each View can contain many View Containers.
7975 * <!-- /TODO -->
7976 *
7977 * ### Example
7978 *
7979 * Given this template...
7980 *
7981 * ```
7982 * Count: {{items.length}}
7983 * <ul>
7984 * <li *ngFor="let item of items">{{item}}</li>
7985 * </ul>
7986 * ```
7987 *
7988 * We have two {\@link TemplateRef}s:
7989 *
7990 * Outer {\@link TemplateRef}:
7991 * ```
7992 * Count: {{items.length}}
7993 * <ul>
7994 * <ng-template ngFor let-item [ngForOf]="items"></ng-template>
7995 * </ul>
7996 * ```
7997 *
7998 * Inner {\@link TemplateRef}:
7999 * ```
8000 * <li>{{item}}</li>
8001 * ```
8002 *
8003 * Notice that the original template is broken down into two separate {\@link TemplateRef}s.
8004 *
8005 * The outer/inner {\@link TemplateRef}s are then assembled into views like so:
8006 *
8007 * ```
8008 * <!-- ViewRef: outer-0 -->
8009 * Count: 2
8010 * <ul>
8011 * <ng-template view-container-ref></ng-template>
8012 * <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
8013 * <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
8014 * </ul>
8015 * <!-- /ViewRef: outer-0 -->
8016 * ```
8017 * \@experimental
8018 * @abstract
8019 */
8020var EmbeddedViewRef = (function (_super) {
8021 __extends$1(EmbeddedViewRef, _super);
8022 function EmbeddedViewRef() {
8023 return _super !== null && _super.apply(this, arguments) || this;
8024 }
8025 /**
8026 * @abstract
8027 * @return {?}
8028 */
8029 EmbeddedViewRef.prototype.context = function () { };
8030 /**
8031 * @abstract
8032 * @return {?}
8033 */
8034 EmbeddedViewRef.prototype.rootNodes = function () { };
8035 return EmbeddedViewRef;
8036}(ViewRef));
8037/**
8038 * @license
8039 * Copyright Google Inc. All Rights Reserved.
8040 *
8041 * Use of this source code is governed by an MIT-style license that can be
8042 * found in the LICENSE file at https://angular.io/license
8043 */
8044// Public API for compiler
8045/**
8046 * @license
8047 * Copyright Google Inc. All Rights Reserved.
8048 *
8049 * Use of this source code is governed by an MIT-style license that can be
8050 * found in the LICENSE file at https://angular.io/license
8051 */
8052var EventListener = (function () {
8053 /**
8054 * @param {?} name
8055 * @param {?} callback
8056 */
8057 function EventListener(name, callback) {
8058 this.name = name;
8059 this.callback = callback;
8060 }
8061
8062 return EventListener;
8063}());
8064/**
8065 * \@experimental All debugging apis are currently experimental.
8066 */
8067var DebugNode = (function () {
8068 /**
8069 * @param {?} nativeNode
8070 * @param {?} parent
8071 * @param {?} _debugContext
8072 */
8073 function DebugNode(nativeNode, parent, _debugContext) {
8074 this._debugContext = _debugContext;
8075 this.nativeNode = nativeNode;
8076 if (parent && parent instanceof DebugElement) {
8077 parent.addChild(this);
8078 }
8079 else {
8080 this.parent = null;
8081 }
8082 this.listeners = [];
8083 }
8084 Object.defineProperty(DebugNode.prototype, "injector", {
8085 /**
8086 * @return {?}
8087 */
8088 get: function () { return this._debugContext.injector; },
8089 enumerable: true,
8090 configurable: true
8091 });
8092 Object.defineProperty(DebugNode.prototype, "componentInstance", {
8093 /**
8094 * @return {?}
8095 */
8096 get: function () { return this._debugContext.component; },
8097 enumerable: true,
8098 configurable: true
8099 });
8100 Object.defineProperty(DebugNode.prototype, "context", {
8101 /**
8102 * @return {?}
8103 */
8104 get: function () { return this._debugContext.context; },
8105 enumerable: true,
8106 configurable: true
8107 });
8108 Object.defineProperty(DebugNode.prototype, "references", {
8109 /**
8110 * @return {?}
8111 */
8112 get: function () { return this._debugContext.references; },
8113 enumerable: true,
8114 configurable: true
8115 });
8116 Object.defineProperty(DebugNode.prototype, "providerTokens", {
8117 /**
8118 * @return {?}
8119 */
8120 get: function () { return this._debugContext.providerTokens; },
8121 enumerable: true,
8122 configurable: true
8123 });
8124 Object.defineProperty(DebugNode.prototype, "source", {
8125 /**
8126 * @deprecated since v4
8127 * @return {?}
8128 */
8129 get: function () { return 'Deprecated since v4'; },
8130 enumerable: true,
8131 configurable: true
8132 });
8133 return DebugNode;
8134}());
8135/**
8136 * \@experimental All debugging apis are currently experimental.
8137 */
8138var DebugElement = (function (_super) {
8139 __extends$1(DebugElement, _super);
8140 /**
8141 * @param {?} nativeNode
8142 * @param {?} parent
8143 * @param {?} _debugContext
8144 */
8145 function DebugElement(nativeNode, parent, _debugContext) {
8146 var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
8147 _this.properties = {};
8148 _this.attributes = {};
8149 _this.classes = {};
8150 _this.styles = {};
8151 _this.childNodes = [];
8152 _this.nativeElement = nativeNode;
8153 return _this;
8154 }
8155 /**
8156 * @param {?} child
8157 * @return {?}
8158 */
8159 DebugElement.prototype.addChild = function (child) {
8160 if (child) {
8161 this.childNodes.push(child);
8162 child.parent = this;
8163 }
8164 };
8165 /**
8166 * @param {?} child
8167 * @return {?}
8168 */
8169 DebugElement.prototype.removeChild = function (child) {
8170 var /** @type {?} */ childIndex = this.childNodes.indexOf(child);
8171 if (childIndex !== -1) {
8172 child.parent = null;
8173 this.childNodes.splice(childIndex, 1);
8174 }
8175 };
8176 /**
8177 * @param {?} child
8178 * @param {?} newChildren
8179 * @return {?}
8180 */
8181 DebugElement.prototype.insertChildrenAfter = function (child, newChildren) {
8182 var _this = this;
8183 var /** @type {?} */ siblingIndex = this.childNodes.indexOf(child);
8184 if (siblingIndex !== -1) {
8185 (_a = this.childNodes).splice.apply(_a, [siblingIndex + 1, 0].concat(newChildren));
8186 newChildren.forEach(function (c) {
8187 if (c.parent) {
8188 c.parent.removeChild(c);
8189 }
8190 c.parent = _this;
8191 });
8192 }
8193 var _a;
8194 };
8195 /**
8196 * @param {?} refChild
8197 * @param {?} newChild
8198 * @return {?}
8199 */
8200 DebugElement.prototype.insertBefore = function (refChild, newChild) {
8201 var /** @type {?} */ refIndex = this.childNodes.indexOf(refChild);
8202 if (refIndex === -1) {
8203 this.addChild(newChild);
8204 }
8205 else {
8206 if (newChild.parent) {
8207 newChild.parent.removeChild(newChild);
8208 }
8209 newChild.parent = this;
8210 this.childNodes.splice(refIndex, 0, newChild);
8211 }
8212 };
8213 /**
8214 * @param {?} predicate
8215 * @return {?}
8216 */
8217 DebugElement.prototype.query = function (predicate) {
8218 var /** @type {?} */ results = this.queryAll(predicate);
8219 return results[0] || null;
8220 };
8221 /**
8222 * @param {?} predicate
8223 * @return {?}
8224 */
8225 DebugElement.prototype.queryAll = function (predicate) {
8226 var /** @type {?} */ matches = [];
8227 _queryElementChildren(this, predicate, matches);
8228 return matches;
8229 };
8230 /**
8231 * @param {?} predicate
8232 * @return {?}
8233 */
8234 DebugElement.prototype.queryAllNodes = function (predicate) {
8235 var /** @type {?} */ matches = [];
8236 _queryNodeChildren(this, predicate, matches);
8237 return matches;
8238 };
8239 Object.defineProperty(DebugElement.prototype, "children", {
8240 /**
8241 * @return {?}
8242 */
8243 get: function () {
8244 return (this.childNodes.filter(function (node) { return node instanceof DebugElement; }));
8245 },
8246 enumerable: true,
8247 configurable: true
8248 });
8249 /**
8250 * @param {?} eventName
8251 * @param {?} eventObj
8252 * @return {?}
8253 */
8254 DebugElement.prototype.triggerEventHandler = function (eventName, eventObj) {
8255 this.listeners.forEach(function (listener) {
8256 if (listener.name == eventName) {
8257 listener.callback(eventObj);
8258 }
8259 });
8260 };
8261 return DebugElement;
8262}(DebugNode));
8263/**
8264 * @param {?} element
8265 * @param {?} predicate
8266 * @param {?} matches
8267 * @return {?}
8268 */
8269function _queryElementChildren(element, predicate, matches) {
8270 element.childNodes.forEach(function (node) {
8271 if (node instanceof DebugElement) {
8272 if (predicate(node)) {
8273 matches.push(node);
8274 }
8275 _queryElementChildren(node, predicate, matches);
8276 }
8277 });
8278}
8279/**
8280 * @param {?} parentNode
8281 * @param {?} predicate
8282 * @param {?} matches
8283 * @return {?}
8284 */
8285function _queryNodeChildren(parentNode, predicate, matches) {
8286 if (parentNode instanceof DebugElement) {
8287 parentNode.childNodes.forEach(function (node) {
8288 if (predicate(node)) {
8289 matches.push(node);
8290 }
8291 if (node instanceof DebugElement) {
8292 _queryNodeChildren(node, predicate, matches);
8293 }
8294 });
8295 }
8296}
8297// Need to keep the nodes in a global Map so that multiple angular apps are supported.
8298var _nativeNodeToDebugNode = new Map();
8299/**
8300 * \@experimental
8301 * @param {?} nativeNode
8302 * @return {?}
8303 */
8304function getDebugNode(nativeNode) {
8305 return _nativeNodeToDebugNode.get(nativeNode) || null;
8306}
8307/**
8308 * @return {?}
8309 */
8310/**
8311 * @param {?} node
8312 * @return {?}
8313 */
8314function indexDebugNode(node) {
8315 _nativeNodeToDebugNode.set(node.nativeNode, node);
8316}
8317/**
8318 * @param {?} node
8319 * @return {?}
8320 */
8321function removeDebugNodeFromIndex(node) {
8322 _nativeNodeToDebugNode.delete(node.nativeNode);
8323}
8324/**
8325 * @license
8326 * Copyright Google Inc. All Rights Reserved.
8327 *
8328 * Use of this source code is governed by an MIT-style license that can be
8329 * found in the LICENSE file at https://angular.io/license
8330 */
8331/**
8332 * @param {?} a
8333 * @param {?} b
8334 * @return {?}
8335 */
8336function devModeEqual(a, b) {
8337 var /** @type {?} */ isListLikeIterableA = isListLikeIterable(a);
8338 var /** @type {?} */ isListLikeIterableB = isListLikeIterable(b);
8339 if (isListLikeIterableA && isListLikeIterableB) {
8340 return areIterablesEqual(a, b, devModeEqual);
8341 }
8342 else {
8343 var /** @type {?} */ isAObject = a && (typeof a === 'object' || typeof a === 'function');
8344 var /** @type {?} */ isBObject = b && (typeof b === 'object' || typeof b === 'function');
8345 if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
8346 return true;
8347 }
8348 else {
8349 return looseIdentical(a, b);
8350 }
8351 }
8352}
8353/**
8354 * Indicates that the result of a {\@link Pipe} transformation has changed even though the
8355 * reference
8356 * has not changed.
8357 *
8358 * The wrapped value will be unwrapped by change detection, and the unwrapped value will be stored.
8359 *
8360 * Example:
8361 *
8362 * ```
8363 * if (this._latestValue === this._latestReturnedValue) {
8364 * return this._latestReturnedValue;
8365 * } else {
8366 * this._latestReturnedValue = this._latestValue;
8367 * return WrappedValue.wrap(this._latestValue); // this will force update
8368 * }
8369 * ```
8370 * \@stable
8371 */
8372var WrappedValue = (function () {
8373 /**
8374 * @param {?} wrapped
8375 */
8376 function WrappedValue(wrapped) {
8377 this.wrapped = wrapped;
8378 }
8379 /**
8380 * @param {?} value
8381 * @return {?}
8382 */
8383 WrappedValue.wrap = function (value) { return new WrappedValue(value); };
8384 return WrappedValue;
8385}());
8386/**
8387 * Represents a basic change from a previous to a new value.
8388 * \@stable
8389 */
8390var SimpleChange = (function () {
8391 /**
8392 * @param {?} previousValue
8393 * @param {?} currentValue
8394 * @param {?} firstChange
8395 */
8396 function SimpleChange(previousValue, currentValue, firstChange) {
8397 this.previousValue = previousValue;
8398 this.currentValue = currentValue;
8399 this.firstChange = firstChange;
8400 }
8401 /**
8402 * Check whether the new value is the first value assigned.
8403 * @return {?}
8404 */
8405 SimpleChange.prototype.isFirstChange = function () { return this.firstChange; };
8406 return SimpleChange;
8407}());
8408/**
8409 * @param {?} obj
8410 * @return {?}
8411 */
8412function isListLikeIterable(obj) {
8413 if (!isJsObject(obj))
8414 return false;
8415 return Array.isArray(obj) ||
8416 (!(obj instanceof Map) &&
8417 getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
8418}
8419/**
8420 * @param {?} a
8421 * @param {?} b
8422 * @param {?} comparator
8423 * @return {?}
8424 */
8425function areIterablesEqual(a, b, comparator) {
8426 var /** @type {?} */ iterator1 = a[getSymbolIterator()]();
8427 var /** @type {?} */ iterator2 = b[getSymbolIterator()]();
8428 while (true) {
8429 var /** @type {?} */ item1 = iterator1.next();
8430 var /** @type {?} */ item2 = iterator2.next();
8431 if (item1.done && item2.done)
8432 return true;
8433 if (item1.done || item2.done)
8434 return false;
8435 if (!comparator(item1.value, item2.value))
8436 return false;
8437 }
8438}
8439/**
8440 * @param {?} obj
8441 * @param {?} fn
8442 * @return {?}
8443 */
8444function iterateListLike(obj, fn) {
8445 if (Array.isArray(obj)) {
8446 for (var /** @type {?} */ i = 0; i < obj.length; i++) {
8447 fn(obj[i]);
8448 }
8449 }
8450 else {
8451 var /** @type {?} */ iterator = obj[getSymbolIterator()]();
8452 var /** @type {?} */ item = void 0;
8453 while (!((item = iterator.next()).done)) {
8454 fn(item.value);
8455 }
8456 }
8457}
8458/**
8459 * @param {?} o
8460 * @return {?}
8461 */
8462function isJsObject(o) {
8463 return o !== null && (typeof o === 'function' || typeof o === 'object');
8464}
8465/**
8466 * @license
8467 * Copyright Google Inc. All Rights Reserved.
8468 *
8469 * Use of this source code is governed by an MIT-style license that can be
8470 * found in the LICENSE file at https://angular.io/license
8471 */
8472var DefaultIterableDifferFactory = (function () {
8473 function DefaultIterableDifferFactory() {
8474 }
8475 /**
8476 * @param {?} obj
8477 * @return {?}
8478 */
8479 DefaultIterableDifferFactory.prototype.supports = function (obj) { return isListLikeIterable(obj); };
8480 /**
8481 * @deprecated v4.0.0 - ChangeDetectorRef is not used and is no longer a parameter
8482 * @template V
8483 * @param {?=} cdRefOrTrackBy
8484 * @param {?=} trackByFn
8485 * @return {?}
8486 */
8487 DefaultIterableDifferFactory.prototype.create = function (cdRefOrTrackBy, trackByFn) {
8488 return new DefaultIterableDiffer(trackByFn || (cdRefOrTrackBy));
8489 };
8490 return DefaultIterableDifferFactory;
8491}());
8492var trackByIdentity = function (index, item) { return item; };
8493/**
8494 * @deprecated v4.0.0 - Should not be part of public API.
8495 */
8496var DefaultIterableDiffer = (function () {
8497 /**
8498 * @param {?=} trackByFn
8499 */
8500 function DefaultIterableDiffer(trackByFn) {
8501 this._length = 0;
8502 this._collection = null;
8503 this._linkedRecords = null;
8504 this._unlinkedRecords = null;
8505 this._previousItHead = null;
8506 this._itHead = null;
8507 this._itTail = null;
8508 this._additionsHead = null;
8509 this._additionsTail = null;
8510 this._movesHead = null;
8511 this._movesTail = null;
8512 this._removalsHead = null;
8513 this._removalsTail = null;
8514 this._identityChangesHead = null;
8515 this._identityChangesTail = null;
8516 this._trackByFn = trackByFn || trackByIdentity;
8517 }
8518 Object.defineProperty(DefaultIterableDiffer.prototype, "collection", {
8519 /**
8520 * @return {?}
8521 */
8522 get: function () { return this._collection; },
8523 enumerable: true,
8524 configurable: true
8525 });
8526 Object.defineProperty(DefaultIterableDiffer.prototype, "length", {
8527 /**
8528 * @return {?}
8529 */
8530 get: function () { return this._length; },
8531 enumerable: true,
8532 configurable: true
8533 });
8534 /**
8535 * @param {?} fn
8536 * @return {?}
8537 */
8538 DefaultIterableDiffer.prototype.forEachItem = function (fn) {
8539 var /** @type {?} */ record;
8540 for (record = this._itHead; record !== null; record = record._next) {
8541 fn(record);
8542 }
8543 };
8544 /**
8545 * @param {?} fn
8546 * @return {?}
8547 */
8548 DefaultIterableDiffer.prototype.forEachOperation = function (fn) {
8549 var /** @type {?} */ nextIt = this._itHead;
8550 var /** @type {?} */ nextRemove = this._removalsHead;
8551 var /** @type {?} */ addRemoveOffset = 0;
8552 var /** @type {?} */ moveOffsets = null;
8553 while (nextIt || nextRemove) {
8554 // Figure out which is the next record to process
8555 // Order: remove, add, move
8556 var /** @type {?} */ record = !nextRemove ||
8557 nextIt && ((nextIt.currentIndex)) <
8558 getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? ((nextIt)) :
8559 nextRemove;
8560 var /** @type {?} */ adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
8561 var /** @type {?} */ currentIndex = record.currentIndex;
8562 // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
8563 if (record === nextRemove) {
8564 addRemoveOffset--;
8565 nextRemove = nextRemove._nextRemoved;
8566 }
8567 else {
8568 nextIt = ((nextIt))._next;
8569 if (record.previousIndex == null) {
8570 addRemoveOffset++;
8571 }
8572 else {
8573 // INVARIANT: currentIndex < previousIndex
8574 if (!moveOffsets)
8575 moveOffsets = [];
8576 var /** @type {?} */ localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
8577 var /** @type {?} */ localCurrentIndex = ((currentIndex)) - addRemoveOffset;
8578 if (localMovePreviousIndex != localCurrentIndex) {
8579 for (var /** @type {?} */ i = 0; i < localMovePreviousIndex; i++) {
8580 var /** @type {?} */ offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
8581 var /** @type {?} */ index = offset + i;
8582 if (localCurrentIndex <= index && index < localMovePreviousIndex) {
8583 moveOffsets[i] = offset + 1;
8584 }
8585 }
8586 var /** @type {?} */ previousIndex = record.previousIndex;
8587 moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
8588 }
8589 }
8590 }
8591 if (adjPreviousIndex !== currentIndex) {
8592 fn(record, adjPreviousIndex, currentIndex);
8593 }
8594 }
8595 };
8596 /**
8597 * @param {?} fn
8598 * @return {?}
8599 */
8600 DefaultIterableDiffer.prototype.forEachPreviousItem = function (fn) {
8601 var /** @type {?} */ record;
8602 for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
8603 fn(record);
8604 }
8605 };
8606 /**
8607 * @param {?} fn
8608 * @return {?}
8609 */
8610 DefaultIterableDiffer.prototype.forEachAddedItem = function (fn) {
8611 var /** @type {?} */ record;
8612 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
8613 fn(record);
8614 }
8615 };
8616 /**
8617 * @param {?} fn
8618 * @return {?}
8619 */
8620 DefaultIterableDiffer.prototype.forEachMovedItem = function (fn) {
8621 var /** @type {?} */ record;
8622 for (record = this._movesHead; record !== null; record = record._nextMoved) {
8623 fn(record);
8624 }
8625 };
8626 /**
8627 * @param {?} fn
8628 * @return {?}
8629 */
8630 DefaultIterableDiffer.prototype.forEachRemovedItem = function (fn) {
8631 var /** @type {?} */ record;
8632 for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
8633 fn(record);
8634 }
8635 };
8636 /**
8637 * @param {?} fn
8638 * @return {?}
8639 */
8640 DefaultIterableDiffer.prototype.forEachIdentityChange = function (fn) {
8641 var /** @type {?} */ record;
8642 for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
8643 fn(record);
8644 }
8645 };
8646 /**
8647 * @param {?} collection
8648 * @return {?}
8649 */
8650 DefaultIterableDiffer.prototype.diff = function (collection) {
8651 if (collection == null)
8652 collection = [];
8653 if (!isListLikeIterable(collection)) {
8654 throw new Error("Error trying to diff '" + stringify(collection) + "'. Only arrays and iterables are allowed");
8655 }
8656 if (this.check(collection)) {
8657 return this;
8658 }
8659 else {
8660 return null;
8661 }
8662 };
8663 /**
8664 * @return {?}
8665 */
8666 DefaultIterableDiffer.prototype.onDestroy = function () { };
8667 /**
8668 * @param {?} collection
8669 * @return {?}
8670 */
8671 DefaultIterableDiffer.prototype.check = function (collection) {
8672 var _this = this;
8673 this._reset();
8674 var /** @type {?} */ record = this._itHead;
8675 var /** @type {?} */ mayBeDirty = false;
8676 var /** @type {?} */ index;
8677 var /** @type {?} */ item;
8678 var /** @type {?} */ itemTrackBy;
8679 if (Array.isArray(collection)) {
8680 this._length = collection.length;
8681 for (var /** @type {?} */ index_1 = 0; index_1 < this._length; index_1++) {
8682 item = collection[index_1];
8683 itemTrackBy = this._trackByFn(index_1, item);
8684 if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
8685 record = this._mismatch(record, item, itemTrackBy, index_1);
8686 mayBeDirty = true;
8687 }
8688 else {
8689 if (mayBeDirty) {
8690 // TODO(misko): can we limit this to duplicates only?
8691 record = this._verifyReinsertion(record, item, itemTrackBy, index_1);
8692 }
8693 if (!looseIdentical(record.item, item))
8694 this._addIdentityChange(record, item);
8695 }
8696 record = record._next;
8697 }
8698 }
8699 else {
8700 index = 0;
8701 iterateListLike(collection, function (item) {
8702 itemTrackBy = _this._trackByFn(index, item);
8703 if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
8704 record = _this._mismatch(record, item, itemTrackBy, index);
8705 mayBeDirty = true;
8706 }
8707 else {
8708 if (mayBeDirty) {
8709 // TODO(misko): can we limit this to duplicates only?
8710 record = _this._verifyReinsertion(record, item, itemTrackBy, index);
8711 }
8712 if (!looseIdentical(record.item, item))
8713 _this._addIdentityChange(record, item);
8714 }
8715 record = record._next;
8716 index++;
8717 });
8718 this._length = index;
8719 }
8720 this._truncate(record);
8721 this._collection = collection;
8722 return this.isDirty;
8723 };
8724 Object.defineProperty(DefaultIterableDiffer.prototype, "isDirty", {
8725 /**
8726 * @return {?}
8727 */
8728 get: function () {
8729 return this._additionsHead !== null || this._movesHead !== null ||
8730 this._removalsHead !== null || this._identityChangesHead !== null;
8731 },
8732 enumerable: true,
8733 configurable: true
8734 });
8735 /**
8736 * Reset the state of the change objects to show no changes. This means set previousKey to
8737 * currentKey, and clear all of the queues (additions, moves, removals).
8738 * Set the previousIndexes of moved and added items to their currentIndexes
8739 * Reset the list of additions, moves and removals
8740 *
8741 * \@internal
8742 * @return {?}
8743 */
8744 DefaultIterableDiffer.prototype._reset = function () {
8745 if (this.isDirty) {
8746 var /** @type {?} */ record = void 0;
8747 var /** @type {?} */ nextRecord = void 0;
8748 for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
8749 record._nextPrevious = record._next;
8750 }
8751 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
8752 record.previousIndex = record.currentIndex;
8753 }
8754 this._additionsHead = this._additionsTail = null;
8755 for (record = this._movesHead; record !== null; record = nextRecord) {
8756 record.previousIndex = record.currentIndex;
8757 nextRecord = record._nextMoved;
8758 }
8759 this._movesHead = this._movesTail = null;
8760 this._removalsHead = this._removalsTail = null;
8761 this._identityChangesHead = this._identityChangesTail = null;
8762 // todo(vicb) when assert gets supported
8763 // assert(!this.isDirty);
8764 }
8765 };
8766 /**
8767 * This is the core function which handles differences between collections.
8768 *
8769 * - `record` is the record which we saw at this position last time. If null then it is a new
8770 * item.
8771 * - `item` is the current item in the collection
8772 * - `index` is the position of the item in the collection
8773 *
8774 * \@internal
8775 * @param {?} record
8776 * @param {?} item
8777 * @param {?} itemTrackBy
8778 * @param {?} index
8779 * @return {?}
8780 */
8781 DefaultIterableDiffer.prototype._mismatch = function (record, item, itemTrackBy, index) {
8782 // The previous record after which we will append the current one.
8783 var /** @type {?} */ previousRecord;
8784 if (record === null) {
8785 previousRecord = this._itTail;
8786 }
8787 else {
8788 previousRecord = record._prev;
8789 // Remove the record from the collection since we know it does not match the item.
8790 this._remove(record);
8791 }
8792 // Attempt to see if we have seen the item before.
8793 record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
8794 if (record !== null) {
8795 // We have seen this before, we need to move it forward in the collection.
8796 // But first we need to check if identity changed, so we can update in view if necessary
8797 if (!looseIdentical(record.item, item))
8798 this._addIdentityChange(record, item);
8799 this._moveAfter(record, previousRecord, index);
8800 }
8801 else {
8802 // Never seen it, check evicted list.
8803 record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
8804 if (record !== null) {
8805 // It is an item which we have evicted earlier: reinsert it back into the list.
8806 // But first we need to check if identity changed, so we can update in view if necessary
8807 if (!looseIdentical(record.item, item))
8808 this._addIdentityChange(record, item);
8809 this._reinsertAfter(record, previousRecord, index);
8810 }
8811 else {
8812 // It is a new item: add it.
8813 record =
8814 this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
8815 }
8816 }
8817 return record;
8818 };
8819 /**
8820 * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
8821 *
8822 * Use case: `[a, a]` => `[b, a, a]`
8823 *
8824 * If we did not have this check then the insertion of `b` would:
8825 * 1) evict first `a`
8826 * 2) insert `b` at `0` index.
8827 * 3) leave `a` at index `1` as is. <-- this is wrong!
8828 * 3) reinsert `a` at index 2. <-- this is wrong!
8829 *
8830 * The correct behavior is:
8831 * 1) evict first `a`
8832 * 2) insert `b` at `0` index.
8833 * 3) reinsert `a` at index 1.
8834 * 3) move `a` at from `1` to `2`.
8835 *
8836 *
8837 * Double check that we have not evicted a duplicate item. We need to check if the item type may
8838 * have already been removed:
8839 * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
8840 * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
8841 * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
8842 * at the end.
8843 *
8844 * \@internal
8845 * @param {?} record
8846 * @param {?} item
8847 * @param {?} itemTrackBy
8848 * @param {?} index
8849 * @return {?}
8850 */
8851 DefaultIterableDiffer.prototype._verifyReinsertion = function (record, item, itemTrackBy, index) {
8852 var /** @type {?} */ reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
8853 if (reinsertRecord !== null) {
8854 record = this._reinsertAfter(reinsertRecord, /** @type {?} */ ((record._prev)), index);
8855 }
8856 else if (record.currentIndex != index) {
8857 record.currentIndex = index;
8858 this._addToMoves(record, index);
8859 }
8860 return record;
8861 };
8862 /**
8863 * Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection
8864 *
8865 * - `record` The first excess {\@link IterableChangeRecord_}.
8866 *
8867 * \@internal
8868 * @param {?} record
8869 * @return {?}
8870 */
8871 DefaultIterableDiffer.prototype._truncate = function (record) {
8872 // Anything after that needs to be removed;
8873 while (record !== null) {
8874 var /** @type {?} */ nextRecord = record._next;
8875 this._addToRemovals(this._unlink(record));
8876 record = nextRecord;
8877 }
8878 if (this._unlinkedRecords !== null) {
8879 this._unlinkedRecords.clear();
8880 }
8881 if (this._additionsTail !== null) {
8882 this._additionsTail._nextAdded = null;
8883 }
8884 if (this._movesTail !== null) {
8885 this._movesTail._nextMoved = null;
8886 }
8887 if (this._itTail !== null) {
8888 this._itTail._next = null;
8889 }
8890 if (this._removalsTail !== null) {
8891 this._removalsTail._nextRemoved = null;
8892 }
8893 if (this._identityChangesTail !== null) {
8894 this._identityChangesTail._nextIdentityChange = null;
8895 }
8896 };
8897 /**
8898 * \@internal
8899 * @param {?} record
8900 * @param {?} prevRecord
8901 * @param {?} index
8902 * @return {?}
8903 */
8904 DefaultIterableDiffer.prototype._reinsertAfter = function (record, prevRecord, index) {
8905 if (this._unlinkedRecords !== null) {
8906 this._unlinkedRecords.remove(record);
8907 }
8908 var /** @type {?} */ prev = record._prevRemoved;
8909 var /** @type {?} */ next = record._nextRemoved;
8910 if (prev === null) {
8911 this._removalsHead = next;
8912 }
8913 else {
8914 prev._nextRemoved = next;
8915 }
8916 if (next === null) {
8917 this._removalsTail = prev;
8918 }
8919 else {
8920 next._prevRemoved = prev;
8921 }
8922 this._insertAfter(record, prevRecord, index);
8923 this._addToMoves(record, index);
8924 return record;
8925 };
8926 /**
8927 * \@internal
8928 * @param {?} record
8929 * @param {?} prevRecord
8930 * @param {?} index
8931 * @return {?}
8932 */
8933 DefaultIterableDiffer.prototype._moveAfter = function (record, prevRecord, index) {
8934 this._unlink(record);
8935 this._insertAfter(record, prevRecord, index);
8936 this._addToMoves(record, index);
8937 return record;
8938 };
8939 /**
8940 * \@internal
8941 * @param {?} record
8942 * @param {?} prevRecord
8943 * @param {?} index
8944 * @return {?}
8945 */
8946 DefaultIterableDiffer.prototype._addAfter = function (record, prevRecord, index) {
8947 this._insertAfter(record, prevRecord, index);
8948 if (this._additionsTail === null) {
8949 // todo(vicb)
8950 // assert(this._additionsHead === null);
8951 this._additionsTail = this._additionsHead = record;
8952 }
8953 else {
8954 // todo(vicb)
8955 // assert(_additionsTail._nextAdded === null);
8956 // assert(record._nextAdded === null);
8957 this._additionsTail = this._additionsTail._nextAdded = record;
8958 }
8959 return record;
8960 };
8961 /**
8962 * \@internal
8963 * @param {?} record
8964 * @param {?} prevRecord
8965 * @param {?} index
8966 * @return {?}
8967 */
8968 DefaultIterableDiffer.prototype._insertAfter = function (record, prevRecord, index) {
8969 // todo(vicb)
8970 // assert(record != prevRecord);
8971 // assert(record._next === null);
8972 // assert(record._prev === null);
8973 var /** @type {?} */ next = prevRecord === null ? this._itHead : prevRecord._next;
8974 // todo(vicb)
8975 // assert(next != record);
8976 // assert(prevRecord != record);
8977 record._next = next;
8978 record._prev = prevRecord;
8979 if (next === null) {
8980 this._itTail = record;
8981 }
8982 else {
8983 next._prev = record;
8984 }
8985 if (prevRecord === null) {
8986 this._itHead = record;
8987 }
8988 else {
8989 prevRecord._next = record;
8990 }
8991 if (this._linkedRecords === null) {
8992 this._linkedRecords = new _DuplicateMap();
8993 }
8994 this._linkedRecords.put(record);
8995 record.currentIndex = index;
8996 return record;
8997 };
8998 /**
8999 * \@internal
9000 * @param {?} record
9001 * @return {?}
9002 */
9003 DefaultIterableDiffer.prototype._remove = function (record) {
9004 return this._addToRemovals(this._unlink(record));
9005 };
9006 /**
9007 * \@internal
9008 * @param {?} record
9009 * @return {?}
9010 */
9011 DefaultIterableDiffer.prototype._unlink = function (record) {
9012 if (this._linkedRecords !== null) {
9013 this._linkedRecords.remove(record);
9014 }
9015 var /** @type {?} */ prev = record._prev;
9016 var /** @type {?} */ next = record._next;
9017 // todo(vicb)
9018 // assert((record._prev = null) === null);
9019 // assert((record._next = null) === null);
9020 if (prev === null) {
9021 this._itHead = next;
9022 }
9023 else {
9024 prev._next = next;
9025 }
9026 if (next === null) {
9027 this._itTail = prev;
9028 }
9029 else {
9030 next._prev = prev;
9031 }
9032 return record;
9033 };
9034 /**
9035 * \@internal
9036 * @param {?} record
9037 * @param {?} toIndex
9038 * @return {?}
9039 */
9040 DefaultIterableDiffer.prototype._addToMoves = function (record, toIndex) {
9041 // todo(vicb)
9042 // assert(record._nextMoved === null);
9043 if (record.previousIndex === toIndex) {
9044 return record;
9045 }
9046 if (this._movesTail === null) {
9047 // todo(vicb)
9048 // assert(_movesHead === null);
9049 this._movesTail = this._movesHead = record;
9050 }
9051 else {
9052 // todo(vicb)
9053 // assert(_movesTail._nextMoved === null);
9054 this._movesTail = this._movesTail._nextMoved = record;
9055 }
9056 return record;
9057 };
9058 /**
9059 * @param {?} record
9060 * @return {?}
9061 */
9062 DefaultIterableDiffer.prototype._addToRemovals = function (record) {
9063 if (this._unlinkedRecords === null) {
9064 this._unlinkedRecords = new _DuplicateMap();
9065 }
9066 this._unlinkedRecords.put(record);
9067 record.currentIndex = null;
9068 record._nextRemoved = null;
9069 if (this._removalsTail === null) {
9070 // todo(vicb)
9071 // assert(_removalsHead === null);
9072 this._removalsTail = this._removalsHead = record;
9073 record._prevRemoved = null;
9074 }
9075 else {
9076 // todo(vicb)
9077 // assert(_removalsTail._nextRemoved === null);
9078 // assert(record._nextRemoved === null);
9079 record._prevRemoved = this._removalsTail;
9080 this._removalsTail = this._removalsTail._nextRemoved = record;
9081 }
9082 return record;
9083 };
9084 /**
9085 * \@internal
9086 * @param {?} record
9087 * @param {?} item
9088 * @return {?}
9089 */
9090 DefaultIterableDiffer.prototype._addIdentityChange = function (record, item) {
9091 record.item = item;
9092 if (this._identityChangesTail === null) {
9093 this._identityChangesTail = this._identityChangesHead = record;
9094 }
9095 else {
9096 this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
9097 }
9098 return record;
9099 };
9100 /**
9101 * @return {?}
9102 */
9103 DefaultIterableDiffer.prototype.toString = function () {
9104 var /** @type {?} */ list = [];
9105 this.forEachItem(function (record) { return list.push(record); });
9106 var /** @type {?} */ previous = [];
9107 this.forEachPreviousItem(function (record) { return previous.push(record); });
9108 var /** @type {?} */ additions = [];
9109 this.forEachAddedItem(function (record) { return additions.push(record); });
9110 var /** @type {?} */ moves = [];
9111 this.forEachMovedItem(function (record) { return moves.push(record); });
9112 var /** @type {?} */ removals = [];
9113 this.forEachRemovedItem(function (record) { return removals.push(record); });
9114 var /** @type {?} */ identityChanges = [];
9115 this.forEachIdentityChange(function (record) { return identityChanges.push(record); });
9116 return 'collection: ' + list.join(', ') + '\n' +
9117 'previous: ' + previous.join(', ') + '\n' +
9118 'additions: ' + additions.join(', ') + '\n' +
9119 'moves: ' + moves.join(', ') + '\n' +
9120 'removals: ' + removals.join(', ') + '\n' +
9121 'identityChanges: ' + identityChanges.join(', ') + '\n';
9122 };
9123 return DefaultIterableDiffer;
9124}());
9125/**
9126 * \@stable
9127 */
9128var IterableChangeRecord_ = (function () {
9129 /**
9130 * @param {?} item
9131 * @param {?} trackById
9132 */
9133 function IterableChangeRecord_(item, trackById) {
9134 this.item = item;
9135 this.trackById = trackById;
9136 this.currentIndex = null;
9137 this.previousIndex = null;
9138 /**
9139 * \@internal
9140 */
9141 this._nextPrevious = null;
9142 /**
9143 * \@internal
9144 */
9145 this._prev = null;
9146 /**
9147 * \@internal
9148 */
9149 this._next = null;
9150 /**
9151 * \@internal
9152 */
9153 this._prevDup = null;
9154 /**
9155 * \@internal
9156 */
9157 this._nextDup = null;
9158 /**
9159 * \@internal
9160 */
9161 this._prevRemoved = null;
9162 /**
9163 * \@internal
9164 */
9165 this._nextRemoved = null;
9166 /**
9167 * \@internal
9168 */
9169 this._nextAdded = null;
9170 /**
9171 * \@internal
9172 */
9173 this._nextMoved = null;
9174 /**
9175 * \@internal
9176 */
9177 this._nextIdentityChange = null;
9178 }
9179 /**
9180 * @return {?}
9181 */
9182 IterableChangeRecord_.prototype.toString = function () {
9183 return this.previousIndex === this.currentIndex ? stringify(this.item) :
9184 stringify(this.item) + '[' +
9185 stringify(this.previousIndex) + '->' + stringify(this.currentIndex) + ']';
9186 };
9187 return IterableChangeRecord_;
9188}());
9189var _DuplicateItemRecordList = (function () {
9190 function _DuplicateItemRecordList() {
9191 /**
9192 * \@internal
9193 */
9194 this._head = null;
9195 /**
9196 * \@internal
9197 */
9198 this._tail = null;
9199 }
9200 /**
9201 * Append the record to the list of duplicates.
9202 *
9203 * Note: by design all records in the list of duplicates hold the same value in record.item.
9204 * @param {?} record
9205 * @return {?}
9206 */
9207 _DuplicateItemRecordList.prototype.add = function (record) {
9208 if (this._head === null) {
9209 this._head = this._tail = record;
9210 record._nextDup = null;
9211 record._prevDup = null;
9212 }
9213 else {
9214 ((
9215 // todo(vicb)
9216 // assert(record.item == _head.item ||
9217 // record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
9218 this._tail))._nextDup = record;
9219 record._prevDup = this._tail;
9220 record._nextDup = null;
9221 this._tail = record;
9222 }
9223 };
9224 /**
9225 * @param {?} trackById
9226 * @param {?} atOrAfterIndex
9227 * @return {?}
9228 */
9229 _DuplicateItemRecordList.prototype.get = function (trackById, atOrAfterIndex) {
9230 var /** @type {?} */ record;
9231 for (record = this._head; record !== null; record = record._nextDup) {
9232 if ((atOrAfterIndex === null || atOrAfterIndex <= ((record.currentIndex))) &&
9233 looseIdentical(record.trackById, trackById)) {
9234 return record;
9235 }
9236 }
9237 return null;
9238 };
9239 /**
9240 * Remove one {\@link IterableChangeRecord_} from the list of duplicates.
9241 *
9242 * Returns whether the list of duplicates is empty.
9243 * @param {?} record
9244 * @return {?}
9245 */
9246 _DuplicateItemRecordList.prototype.remove = function (record) {
9247 // todo(vicb)
9248 // assert(() {
9249 // // verify that the record being removed is in the list.
9250 // for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
9251 // if (identical(cursor, record)) return true;
9252 // }
9253 // return false;
9254 //});
9255 var /** @type {?} */ prev = record._prevDup;
9256 var /** @type {?} */ next = record._nextDup;
9257 if (prev === null) {
9258 this._head = next;
9259 }
9260 else {
9261 prev._nextDup = next;
9262 }
9263 if (next === null) {
9264 this._tail = prev;
9265 }
9266 else {
9267 next._prevDup = prev;
9268 }
9269 return this._head === null;
9270 };
9271 return _DuplicateItemRecordList;
9272}());
9273var _DuplicateMap = (function () {
9274 function _DuplicateMap() {
9275 this.map = new Map();
9276 }
9277 /**
9278 * @param {?} record
9279 * @return {?}
9280 */
9281 _DuplicateMap.prototype.put = function (record) {
9282 var /** @type {?} */ key = record.trackById;
9283 var /** @type {?} */ duplicates = this.map.get(key);
9284 if (!duplicates) {
9285 duplicates = new _DuplicateItemRecordList();
9286 this.map.set(key, duplicates);
9287 }
9288 duplicates.add(record);
9289 };
9290 /**
9291 * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
9292 * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
9293 *
9294 * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
9295 * have any more `a`s needs to return the second `a`.
9296 * @param {?} trackById
9297 * @param {?} atOrAfterIndex
9298 * @return {?}
9299 */
9300 _DuplicateMap.prototype.get = function (trackById, atOrAfterIndex) {
9301 var /** @type {?} */ key = trackById;
9302 var /** @type {?} */ recordList = this.map.get(key);
9303 return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
9304 };
9305 /**
9306 * Removes a {\@link IterableChangeRecord_} from the list of duplicates.
9307 *
9308 * The list of duplicates also is removed from the map if it gets empty.
9309 * @param {?} record
9310 * @return {?}
9311 */
9312 _DuplicateMap.prototype.remove = function (record) {
9313 var /** @type {?} */ key = record.trackById;
9314 var /** @type {?} */ recordList = ((this.map.get(key)));
9315 // Remove the list of duplicates when it gets empty
9316 if (recordList.remove(record)) {
9317 this.map.delete(key);
9318 }
9319 return record;
9320 };
9321 Object.defineProperty(_DuplicateMap.prototype, "isEmpty", {
9322 /**
9323 * @return {?}
9324 */
9325 get: function () { return this.map.size === 0; },
9326 enumerable: true,
9327 configurable: true
9328 });
9329 /**
9330 * @return {?}
9331 */
9332 _DuplicateMap.prototype.clear = function () { this.map.clear(); };
9333 /**
9334 * @return {?}
9335 */
9336 _DuplicateMap.prototype.toString = function () { return '_DuplicateMap(' + stringify(this.map) + ')'; };
9337 return _DuplicateMap;
9338}());
9339/**
9340 * @param {?} item
9341 * @param {?} addRemoveOffset
9342 * @param {?} moveOffsets
9343 * @return {?}
9344 */
9345function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
9346 var /** @type {?} */ previousIndex = item.previousIndex;
9347 if (previousIndex === null)
9348 return previousIndex;
9349 var /** @type {?} */ moveOffset = 0;
9350 if (moveOffsets && previousIndex < moveOffsets.length) {
9351 moveOffset = moveOffsets[previousIndex];
9352 }
9353 return previousIndex + addRemoveOffset + moveOffset;
9354}
9355/**
9356 * @license
9357 * Copyright Google Inc. All Rights Reserved.
9358 *
9359 * Use of this source code is governed by an MIT-style license that can be
9360 * found in the LICENSE file at https://angular.io/license
9361 */
9362var DefaultKeyValueDifferFactory = (function () {
9363 function DefaultKeyValueDifferFactory() {
9364 }
9365 /**
9366 * @param {?} obj
9367 * @return {?}
9368 */
9369 DefaultKeyValueDifferFactory.prototype.supports = function (obj) { return obj instanceof Map || isJsObject(obj); };
9370 /**
9371 * @deprecated v4.0.0 - ChangeDetectorRef is not used and is no longer a parameter
9372 * @template K, V
9373 * @param {?=} cd
9374 * @return {?}
9375 */
9376 DefaultKeyValueDifferFactory.prototype.create = function (cd) {
9377 return new DefaultKeyValueDiffer();
9378 };
9379 return DefaultKeyValueDifferFactory;
9380}());
9381var DefaultKeyValueDiffer = (function () {
9382 function DefaultKeyValueDiffer() {
9383 this._records = new Map();
9384 this._mapHead = null;
9385 this._appendAfter = null;
9386 this._previousMapHead = null;
9387 this._changesHead = null;
9388 this._changesTail = null;
9389 this._additionsHead = null;
9390 this._additionsTail = null;
9391 this._removalsHead = null;
9392 this._removalsTail = null;
9393 }
9394 Object.defineProperty(DefaultKeyValueDiffer.prototype, "isDirty", {
9395 /**
9396 * @return {?}
9397 */
9398 get: function () {
9399 return this._additionsHead !== null || this._changesHead !== null ||
9400 this._removalsHead !== null;
9401 },
9402 enumerable: true,
9403 configurable: true
9404 });
9405 /**
9406 * @param {?} fn
9407 * @return {?}
9408 */
9409 DefaultKeyValueDiffer.prototype.forEachItem = function (fn) {
9410 var /** @type {?} */ record;
9411 for (record = this._mapHead; record !== null; record = record._next) {
9412 fn(record);
9413 }
9414 };
9415 /**
9416 * @param {?} fn
9417 * @return {?}
9418 */
9419 DefaultKeyValueDiffer.prototype.forEachPreviousItem = function (fn) {
9420 var /** @type {?} */ record;
9421 for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
9422 fn(record);
9423 }
9424 };
9425 /**
9426 * @param {?} fn
9427 * @return {?}
9428 */
9429 DefaultKeyValueDiffer.prototype.forEachChangedItem = function (fn) {
9430 var /** @type {?} */ record;
9431 for (record = this._changesHead; record !== null; record = record._nextChanged) {
9432 fn(record);
9433 }
9434 };
9435 /**
9436 * @param {?} fn
9437 * @return {?}
9438 */
9439 DefaultKeyValueDiffer.prototype.forEachAddedItem = function (fn) {
9440 var /** @type {?} */ record;
9441 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
9442 fn(record);
9443 }
9444 };
9445 /**
9446 * @param {?} fn
9447 * @return {?}
9448 */
9449 DefaultKeyValueDiffer.prototype.forEachRemovedItem = function (fn) {
9450 var /** @type {?} */ record;
9451 for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
9452 fn(record);
9453 }
9454 };
9455 /**
9456 * @param {?=} map
9457 * @return {?}
9458 */
9459 DefaultKeyValueDiffer.prototype.diff = function (map) {
9460 if (!map) {
9461 map = new Map();
9462 }
9463 else if (!(map instanceof Map || isJsObject(map))) {
9464 throw new Error("Error trying to diff '" + stringify(map) + "'. Only maps and objects are allowed");
9465 }
9466 return this.check(map) ? this : null;
9467 };
9468 /**
9469 * @return {?}
9470 */
9471 DefaultKeyValueDiffer.prototype.onDestroy = function () { };
9472 /**
9473 * Check the current state of the map vs the previous.
9474 * The algorithm is optimised for when the keys do no change.
9475 * @param {?} map
9476 * @return {?}
9477 */
9478 DefaultKeyValueDiffer.prototype.check = function (map) {
9479 var _this = this;
9480 this._reset();
9481 var /** @type {?} */ insertBefore = this._mapHead;
9482 this._appendAfter = null;
9483 this._forEach(map, function (value, key) {
9484 if (insertBefore && insertBefore.key === key) {
9485 _this._maybeAddToChanges(insertBefore, value);
9486 _this._appendAfter = insertBefore;
9487 insertBefore = insertBefore._next;
9488 }
9489 else {
9490 var /** @type {?} */ record = _this._getOrCreateRecordForKey(key, value);
9491 insertBefore = _this._insertBeforeOrAppend(insertBefore, record);
9492 }
9493 });
9494 // Items remaining at the end of the list have been deleted
9495 if (insertBefore) {
9496 if (insertBefore._prev) {
9497 insertBefore._prev._next = null;
9498 }
9499 this._removalsHead = insertBefore;
9500 for (var /** @type {?} */ record = insertBefore; record !== null; record = record._nextRemoved) {
9501 if (record === this._mapHead) {
9502 this._mapHead = null;
9503 }
9504 this._records.delete(record.key);
9505 record._nextRemoved = record._next;
9506 record.previousValue = record.currentValue;
9507 record.currentValue = null;
9508 record._prev = null;
9509 record._next = null;
9510 }
9511 }
9512 // Make sure tails have no next records from previous runs
9513 if (this._changesTail)
9514 this._changesTail._nextChanged = null;
9515 if (this._additionsTail)
9516 this._additionsTail._nextAdded = null;
9517 return this.isDirty;
9518 };
9519 /**
9520 * Inserts a record before `before` or append at the end of the list when `before` is null.
9521 *
9522 * Notes:
9523 * - This method appends at `this._appendAfter`,
9524 * - This method updates `this._appendAfter`,
9525 * - The return value is the new value for the insertion pointer.
9526 * @param {?} before
9527 * @param {?} record
9528 * @return {?}
9529 */
9530 DefaultKeyValueDiffer.prototype._insertBeforeOrAppend = function (before, record) {
9531 if (before) {
9532 var /** @type {?} */ prev = before._prev;
9533 record._next = before;
9534 record._prev = prev;
9535 before._prev = record;
9536 if (prev) {
9537 prev._next = record;
9538 }
9539 if (before === this._mapHead) {
9540 this._mapHead = record;
9541 }
9542 this._appendAfter = before;
9543 return before;
9544 }
9545 if (this._appendAfter) {
9546 this._appendAfter._next = record;
9547 record._prev = this._appendAfter;
9548 }
9549 else {
9550 this._mapHead = record;
9551 }
9552 this._appendAfter = record;
9553 return null;
9554 };
9555 /**
9556 * @param {?} key
9557 * @param {?} value
9558 * @return {?}
9559 */
9560 DefaultKeyValueDiffer.prototype._getOrCreateRecordForKey = function (key, value) {
9561 if (this._records.has(key)) {
9562 var /** @type {?} */ record_1 = ((this._records.get(key)));
9563 this._maybeAddToChanges(record_1, value);
9564 var /** @type {?} */ prev = record_1._prev;
9565 var /** @type {?} */ next = record_1._next;
9566 if (prev) {
9567 prev._next = next;
9568 }
9569 if (next) {
9570 next._prev = prev;
9571 }
9572 record_1._next = null;
9573 record_1._prev = null;
9574 return record_1;
9575 }
9576 var /** @type {?} */ record = new KeyValueChangeRecord_(key);
9577 this._records.set(key, record);
9578 record.currentValue = value;
9579 this._addToAdditions(record);
9580 return record;
9581 };
9582 /**
9583 * \@internal
9584 * @return {?}
9585 */
9586 DefaultKeyValueDiffer.prototype._reset = function () {
9587 if (this.isDirty) {
9588 var /** @type {?} */ record = void 0;
9589 // let `_previousMapHead` contain the state of the map before the changes
9590 this._previousMapHead = this._mapHead;
9591 for (record = this._previousMapHead; record !== null; record = record._next) {
9592 record._nextPrevious = record._next;
9593 }
9594 // Update `record.previousValue` with the value of the item before the changes
9595 // We need to update all changed items (that's those which have been added and changed)
9596 for (record = this._changesHead; record !== null; record = record._nextChanged) {
9597 record.previousValue = record.currentValue;
9598 }
9599 for (record = this._additionsHead; record != null; record = record._nextAdded) {
9600 record.previousValue = record.currentValue;
9601 }
9602 this._changesHead = this._changesTail = null;
9603 this._additionsHead = this._additionsTail = null;
9604 this._removalsHead = null;
9605 }
9606 };
9607 /**
9608 * @param {?} record
9609 * @param {?} newValue
9610 * @return {?}
9611 */
9612 DefaultKeyValueDiffer.prototype._maybeAddToChanges = function (record, newValue) {
9613 if (!looseIdentical(newValue, record.currentValue)) {
9614 record.previousValue = record.currentValue;
9615 record.currentValue = newValue;
9616 this._addToChanges(record);
9617 }
9618 };
9619 /**
9620 * @param {?} record
9621 * @return {?}
9622 */
9623 DefaultKeyValueDiffer.prototype._addToAdditions = function (record) {
9624 if (this._additionsHead === null) {
9625 this._additionsHead = this._additionsTail = record;
9626 }
9627 else {
9628 ((this._additionsTail))._nextAdded = record;
9629 this._additionsTail = record;
9630 }
9631 };
9632 /**
9633 * @param {?} record
9634 * @return {?}
9635 */
9636 DefaultKeyValueDiffer.prototype._addToChanges = function (record) {
9637 if (this._changesHead === null) {
9638 this._changesHead = this._changesTail = record;
9639 }
9640 else {
9641 ((this._changesTail))._nextChanged = record;
9642 this._changesTail = record;
9643 }
9644 };
9645 /**
9646 * \@internal
9647 * @template K, V
9648 * @param {?} obj
9649 * @param {?} fn
9650 * @return {?}
9651 */
9652 DefaultKeyValueDiffer.prototype._forEach = function (obj, fn) {
9653 if (obj instanceof Map) {
9654 obj.forEach(fn);
9655 }
9656 else {
9657 Object.keys(obj).forEach(function (k) { return fn(obj[k], k); });
9658 }
9659 };
9660 return DefaultKeyValueDiffer;
9661}());
9662/**
9663 * \@stable
9664 */
9665var KeyValueChangeRecord_ = (function () {
9666 /**
9667 * @param {?} key
9668 */
9669 function KeyValueChangeRecord_(key) {
9670 this.key = key;
9671 this.previousValue = null;
9672 this.currentValue = null;
9673 /**
9674 * \@internal
9675 */
9676 this._nextPrevious = null;
9677 /**
9678 * \@internal
9679 */
9680 this._next = null;
9681 /**
9682 * \@internal
9683 */
9684 this._prev = null;
9685 /**
9686 * \@internal
9687 */
9688 this._nextAdded = null;
9689 /**
9690 * \@internal
9691 */
9692 this._nextRemoved = null;
9693 /**
9694 * \@internal
9695 */
9696 this._nextChanged = null;
9697 }
9698 return KeyValueChangeRecord_;
9699}());
9700/**
9701 * @license
9702 * Copyright Google Inc. All Rights Reserved.
9703 *
9704 * Use of this source code is governed by an MIT-style license that can be
9705 * found in the LICENSE file at https://angular.io/license
9706 */
9707/**
9708 * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
9709 * \@stable
9710 */
9711var IterableDiffers = (function () {
9712 /**
9713 * @param {?} factories
9714 */
9715 function IterableDiffers(factories) {
9716 this.factories = factories;
9717 }
9718 /**
9719 * @param {?} factories
9720 * @param {?=} parent
9721 * @return {?}
9722 */
9723 IterableDiffers.create = function (factories, parent) {
9724 if (parent != null) {
9725 var /** @type {?} */ copied = parent.factories.slice();
9726 factories = factories.concat(copied);
9727 return new IterableDiffers(factories);
9728 }
9729 else {
9730 return new IterableDiffers(factories);
9731 }
9732 };
9733 /**
9734 * Takes an array of {\@link IterableDifferFactory} and returns a provider used to extend the
9735 * inherited {\@link IterableDiffers} instance with the provided factories and return a new
9736 * {\@link IterableDiffers} instance.
9737 *
9738 * The following example shows how to extend an existing list of factories,
9739 * which will only be applied to the injector for this component and its children.
9740 * This step is all that's required to make a new {\@link IterableDiffer} available.
9741 *
9742 * ### Example
9743 *
9744 * ```
9745 * \@Component({
9746 * viewProviders: [
9747 * IterableDiffers.extend([new ImmutableListDiffer()])
9748 * ]
9749 * })
9750 * ```
9751 * @param {?} factories
9752 * @return {?}
9753 */
9754 IterableDiffers.extend = function (factories) {
9755 return {
9756 provide: IterableDiffers,
9757 useFactory: function (parent) {
9758 if (!parent) {
9759 // Typically would occur when calling IterableDiffers.extend inside of dependencies passed
9760 // to
9761 // bootstrap(), which would override default pipes instead of extending them.
9762 throw new Error('Cannot extend IterableDiffers without a parent injector');
9763 }
9764 return IterableDiffers.create(factories, parent);
9765 },
9766 // Dependency technically isn't optional, but we can provide a better error message this way.
9767 deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
9768 };
9769 };
9770 /**
9771 * @param {?} iterable
9772 * @return {?}
9773 */
9774 IterableDiffers.prototype.find = function (iterable) {
9775 var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(iterable); });
9776 if (factory != null) {
9777 return factory;
9778 }
9779 else {
9780 throw new Error("Cannot find a differ supporting object '" + iterable + "' of type '" + getTypeNameForDebugging(iterable) + "'");
9781 }
9782 };
9783 return IterableDiffers;
9784}());
9785/**
9786 * @param {?} type
9787 * @return {?}
9788 */
9789function getTypeNameForDebugging(type) {
9790 return type['name'] || typeof type;
9791}
9792/**
9793 * @license
9794 * Copyright Google Inc. All Rights Reserved.
9795 *
9796 * Use of this source code is governed by an MIT-style license that can be
9797 * found in the LICENSE file at https://angular.io/license
9798 */
9799/**
9800 * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
9801 * \@stable
9802 */
9803var KeyValueDiffers = (function () {
9804 /**
9805 * @param {?} factories
9806 */
9807 function KeyValueDiffers(factories) {
9808 this.factories = factories;
9809 }
9810 /**
9811 * @template S
9812 * @param {?} factories
9813 * @param {?=} parent
9814 * @return {?}
9815 */
9816 KeyValueDiffers.create = function (factories, parent) {
9817 if (parent) {
9818 var /** @type {?} */ copied = parent.factories.slice();
9819 factories = factories.concat(copied);
9820 }
9821 return new KeyValueDiffers(factories);
9822 };
9823 /**
9824 * Takes an array of {\@link KeyValueDifferFactory} and returns a provider used to extend the
9825 * inherited {\@link KeyValueDiffers} instance with the provided factories and return a new
9826 * {\@link KeyValueDiffers} instance.
9827 *
9828 * The following example shows how to extend an existing list of factories,
9829 * which will only be applied to the injector for this component and its children.
9830 * This step is all that's required to make a new {\@link KeyValueDiffer} available.
9831 *
9832 * ### Example
9833 *
9834 * ```
9835 * \@Component({
9836 * viewProviders: [
9837 * KeyValueDiffers.extend([new ImmutableMapDiffer()])
9838 * ]
9839 * })
9840 * ```
9841 * @template S
9842 * @param {?} factories
9843 * @return {?}
9844 */
9845 KeyValueDiffers.extend = function (factories) {
9846 return {
9847 provide: KeyValueDiffers,
9848 useFactory: function (parent) {
9849 if (!parent) {
9850 // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed
9851 // to bootstrap(), which would override default pipes instead of extending them.
9852 throw new Error('Cannot extend KeyValueDiffers without a parent injector');
9853 }
9854 return KeyValueDiffers.create(factories, parent);
9855 },
9856 // Dependency technically isn't optional, but we can provide a better error message this way.
9857 deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
9858 };
9859 };
9860 /**
9861 * @param {?} kv
9862 * @return {?}
9863 */
9864 KeyValueDiffers.prototype.find = function (kv) {
9865 var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(kv); });
9866 if (factory) {
9867 return factory;
9868 }
9869 throw new Error("Cannot find a differ supporting object '" + kv + "'");
9870 };
9871 return KeyValueDiffers;
9872}());
9873/**
9874 * @license
9875 * Copyright Google Inc. All Rights Reserved.
9876 *
9877 * Use of this source code is governed by an MIT-style license that can be
9878 * found in the LICENSE file at https://angular.io/license
9879 */
9880/**
9881 * Structural diffing for `Object`s and `Map`s.
9882 */
9883var keyValDiff = [new DefaultKeyValueDifferFactory()];
9884/**
9885 * Structural diffing for `Iterable` types such as `Array`s.
9886 */
9887var iterableDiff = [new DefaultIterableDifferFactory()];
9888var defaultIterableDiffers = new IterableDiffers(iterableDiff);
9889var defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);
9890/**
9891 * @license
9892 * Copyright Google Inc. All Rights Reserved.
9893 *
9894 * Use of this source code is governed by an MIT-style license that can be
9895 * found in the LICENSE file at https://angular.io/license
9896 */
9897/**
9898 * @module
9899 * @description
9900 * Change detection enables data binding in Angular.
9901 */
9902/**
9903 * @license
9904 * Copyright Google Inc. All Rights Reserved.
9905 *
9906 * Use of this source code is governed by an MIT-style license that can be
9907 * found in the LICENSE file at https://angular.io/license
9908 */
9909/**
9910 * @return {?}
9911 */
9912function _reflector() {
9913 return reflector;
9914}
9915var _CORE_PLATFORM_PROVIDERS = [
9916 // Set a default platform name for platforms that don't set it explicitly.
9917 { provide: PLATFORM_ID, useValue: 'unknown' },
9918 PlatformRef_,
9919 { provide: PlatformRef, useExisting: PlatformRef_ },
9920 { provide: Reflector, useFactory: _reflector, deps: [] },
9921 TestabilityRegistry,
9922 Console,
9923];
9924/**
9925 * This platform has to be included in any other platform
9926 *
9927 * \@experimental
9928 */
9929var platformCore = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
9930/**
9931 * @license
9932 * Copyright Google Inc. All Rights Reserved.
9933 *
9934 * Use of this source code is governed by an MIT-style license that can be
9935 * found in the LICENSE file at https://angular.io/license
9936 */
9937/**
9938 * \@experimental i18n support is experimental.
9939 */
9940var LOCALE_ID = new InjectionToken('LocaleId');
9941/**
9942 * \@experimental i18n support is experimental.
9943 */
9944var TRANSLATIONS = new InjectionToken('Translations');
9945/**
9946 * \@experimental i18n support is experimental.
9947 */
9948var TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
9949/**
9950 * @license
9951 * Copyright Google Inc. All Rights Reserved.
9952 *
9953 * Use of this source code is governed by an MIT-style license that can be
9954 * found in the LICENSE file at https://angular.io/license
9955 */
9956/**
9957 * @return {?}
9958 */
9959function _iterableDiffersFactory() {
9960 return defaultIterableDiffers;
9961}
9962/**
9963 * @return {?}
9964 */
9965function _keyValueDiffersFactory() {
9966 return defaultKeyValueDiffers;
9967}
9968/**
9969 * @param {?=} locale
9970 * @return {?}
9971 */
9972function _localeFactory(locale) {
9973 return locale || 'en-US';
9974}
9975/**
9976 * This module includes the providers of \@angular/core that are needed
9977 * to bootstrap components via `ApplicationRef`.
9978 *
9979 * \@experimental
9980 */
9981var ApplicationModule = (function () {
9982 /**
9983 * @param {?} appRef
9984 */
9985 function ApplicationModule(appRef) {
9986 }
9987 return ApplicationModule;
9988}());
9989ApplicationModule.decorators = [
9990 { type: NgModule, args: [{
9991 providers: [
9992 ApplicationRef_,
9993 { provide: ApplicationRef, useExisting: ApplicationRef_ },
9994 ApplicationInitStatus,
9995 Compiler,
9996 APP_ID_RANDOM_PROVIDER,
9997 { provide: IterableDiffers, useFactory: _iterableDiffersFactory },
9998 { provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory },
9999 {
10000 provide: LOCALE_ID,
10001 useFactory: _localeFactory,
10002 deps: [[new Inject(LOCALE_ID), new Optional(), new SkipSelf()]]
10003 },
10004 ]
10005 },] },
10006];
10007/**
10008 * @nocollapse
10009 */
10010ApplicationModule.ctorParameters = function () { return [
10011 { type: ApplicationRef, },
10012]; };
10013var SecurityContext = {};
10014SecurityContext.NONE = 0;
10015SecurityContext.HTML = 1;
10016SecurityContext.STYLE = 2;
10017SecurityContext.SCRIPT = 3;
10018SecurityContext.URL = 4;
10019SecurityContext.RESOURCE_URL = 5;
10020SecurityContext[SecurityContext.NONE] = "NONE";
10021SecurityContext[SecurityContext.HTML] = "HTML";
10022SecurityContext[SecurityContext.STYLE] = "STYLE";
10023SecurityContext[SecurityContext.SCRIPT] = "SCRIPT";
10024SecurityContext[SecurityContext.URL] = "URL";
10025SecurityContext[SecurityContext.RESOURCE_URL] = "RESOURCE_URL";
10026/**
10027 * Sanitizer is used by the views to sanitize potentially dangerous values.
10028 *
10029 * \@stable
10030 * @abstract
10031 */
10032var Sanitizer = (function () {
10033 function Sanitizer() {
10034 }
10035 /**
10036 * @abstract
10037 * @param {?} context
10038 * @param {?} value
10039 * @return {?}
10040 */
10041 Sanitizer.prototype.sanitize = function (context, value) { };
10042 return Sanitizer;
10043}());
10044/**
10045 * @license
10046 * Copyright Google Inc. All Rights Reserved.
10047 *
10048 * Use of this source code is governed by an MIT-style license that can be
10049 * found in the LICENSE file at https://angular.io/license
10050 */
10051/**
10052 * Node instance data.
10053 *
10054 * We have a separate type per NodeType to save memory
10055 * (TextData | ElementData | ProviderData | PureExpressionData | QueryList<any>)
10056 *
10057 * To keep our code monomorphic,
10058 * we prohibit using `NodeData` directly but enforce the use of accessors (`asElementData`, ...).
10059 * This way, no usage site can get a `NodeData` from view.nodes and then use it for different
10060 * purposes.
10061 */
10062/**
10063 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
10064 * @param {?} view
10065 * @param {?} index
10066 * @return {?}
10067 */
10068function asTextData(view, index) {
10069 return (view.nodes[index]);
10070}
10071/**
10072 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
10073 * @param {?} view
10074 * @param {?} index
10075 * @return {?}
10076 */
10077function asElementData(view, index) {
10078 return (view.nodes[index]);
10079}
10080/**
10081 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
10082 * @param {?} view
10083 * @param {?} index
10084 * @return {?}
10085 */
10086function asProviderData(view, index) {
10087 return (view.nodes[index]);
10088}
10089/**
10090 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
10091 * @param {?} view
10092 * @param {?} index
10093 * @return {?}
10094 */
10095function asPureExpressionData(view, index) {
10096 return (view.nodes[index]);
10097}
10098/**
10099 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
10100 * @param {?} view
10101 * @param {?} index
10102 * @return {?}
10103 */
10104function asQueryList(view, index) {
10105 return (view.nodes[index]);
10106}
10107/**
10108 * This object is used to prevent cycles in the source files and to have a place where
10109 * debug mode can hook it. It is lazily filled when `isDevMode` is known.
10110 */
10111var Services = {
10112 setCurrentNode: undefined,
10113 createRootView: undefined,
10114 createEmbeddedView: undefined,
10115 createComponentView: undefined,
10116 createNgModuleRef: undefined,
10117 overrideProvider: undefined,
10118 clearProviderOverrides: undefined,
10119 checkAndUpdateView: undefined,
10120 checkNoChangesView: undefined,
10121 destroyView: undefined,
10122 resolveDep: undefined,
10123 createDebugContext: undefined,
10124 handleEvent: undefined,
10125 updateDirectives: undefined,
10126 updateRenderer: undefined,
10127 dirtyParentQueries: undefined,
10128};
10129/**
10130 * @license
10131 * Copyright Google Inc. All Rights Reserved.
10132 *
10133 * Use of this source code is governed by an MIT-style license that can be
10134 * found in the LICENSE file at https://angular.io/license
10135 */
10136/**
10137 * @param {?} context
10138 * @param {?} oldValue
10139 * @param {?} currValue
10140 * @param {?} isFirstCheck
10141 * @return {?}
10142 */
10143function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
10144 var /** @type {?} */ msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
10145 if (isFirstCheck) {
10146 msg +=
10147 " It seems like the view has been created after its parent and its children have been dirty checked." +
10148 " Has it been created in a change detection hook ?";
10149 }
10150 return viewDebugError(msg, context);
10151}
10152/**
10153 * @param {?} err
10154 * @param {?} context
10155 * @return {?}
10156 */
10157function viewWrappedDebugError(err, context) {
10158 if (!(err instanceof Error)) {
10159 // errors that are not Error instances don't have a stack,
10160 // so it is ok to wrap them into a new Error object...
10161 err = new Error(err.toString());
10162 }
10163 _addDebugContext(err, context);
10164 return err;
10165}
10166/**
10167 * @param {?} msg
10168 * @param {?} context
10169 * @return {?}
10170 */
10171function viewDebugError(msg, context) {
10172 var /** @type {?} */ err = new Error(msg);
10173 _addDebugContext(err, context);
10174 return err;
10175}
10176/**
10177 * @param {?} err
10178 * @param {?} context
10179 * @return {?}
10180 */
10181function _addDebugContext(err, context) {
10182 ((err))[ERROR_DEBUG_CONTEXT] = context;
10183 ((err))[ERROR_LOGGER] = context.logError.bind(context);
10184}
10185/**
10186 * @param {?} err
10187 * @return {?}
10188 */
10189function isViewDebugError(err) {
10190 return !!getDebugContext(err);
10191}
10192/**
10193 * @param {?} action
10194 * @return {?}
10195 */
10196function viewDestroyedError(action) {
10197 return new Error("ViewDestroyedError: Attempt to use a destroyed view: " + action);
10198}
10199/**
10200 * @license
10201 * Copyright Google Inc. All Rights Reserved.
10202 *
10203 * Use of this source code is governed by an MIT-style license that can be
10204 * found in the LICENSE file at https://angular.io/license
10205 */
10206var NOOP = function () { };
10207var _tokenKeyCache = new Map();
10208/**
10209 * @param {?} token
10210 * @return {?}
10211 */
10212function tokenKey(token) {
10213 var /** @type {?} */ key = _tokenKeyCache.get(token);
10214 if (!key) {
10215 key = stringify(token) + '_' + _tokenKeyCache.size;
10216 _tokenKeyCache.set(token, key);
10217 }
10218 return key;
10219}
10220var UNDEFINED_RENDERER_TYPE_ID = '$$undefined';
10221var EMPTY_RENDERER_TYPE_ID = '$$empty';
10222var _renderCompCount = 0;
10223/**
10224 * @param {?=} type
10225 * @return {?}
10226 */
10227function resolveRendererType2(type) {
10228 if (type && type.id === UNDEFINED_RENDERER_TYPE_ID) {
10229 // first time we see this RendererType2. Initialize it...
10230 var /** @type {?} */ isFilled = ((type.encapsulation != null && type.encapsulation !== ViewEncapsulation.None) ||
10231 type.styles.length || Object.keys(type.data).length);
10232 if (isFilled) {
10233 type.id = "c" + _renderCompCount++;
10234 }
10235 else {
10236 type.id = EMPTY_RENDERER_TYPE_ID;
10237 }
10238 }
10239 if (type && type.id === EMPTY_RENDERER_TYPE_ID) {
10240 type = null;
10241 }
10242 return type || null;
10243}
10244/**
10245 * @param {?} view
10246 * @param {?} def
10247 * @param {?} bindingIdx
10248 * @param {?} value
10249 * @return {?}
10250 */
10251function checkBinding(view, def, bindingIdx, value) {
10252 var /** @type {?} */ oldValues = view.oldValues;
10253 if ((view.state & 2 /* FirstCheck */) ||
10254 !looseIdentical(oldValues[def.bindingIndex + bindingIdx], value)) {
10255 return true;
10256 }
10257 return false;
10258}
10259/**
10260 * @param {?} view
10261 * @param {?} def
10262 * @param {?} bindingIdx
10263 * @param {?} value
10264 * @return {?}
10265 */
10266function checkAndUpdateBinding(view, def, bindingIdx, value) {
10267 if (checkBinding(view, def, bindingIdx, value)) {
10268 view.oldValues[def.bindingIndex + bindingIdx] = value;
10269 return true;
10270 }
10271 return false;
10272}
10273/**
10274 * @param {?} view
10275 * @param {?} def
10276 * @param {?} bindingIdx
10277 * @param {?} value
10278 * @return {?}
10279 */
10280function checkBindingNoChanges(view, def, bindingIdx, value) {
10281 var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
10282 if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual(oldValue, value)) {
10283 throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.index), oldValue, value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
10284 }
10285}
10286/**
10287 * @param {?} view
10288 * @return {?}
10289 */
10290function markParentViewsForCheck(view) {
10291 var /** @type {?} */ currView = view;
10292 while (currView) {
10293 if (currView.def.flags & 2 /* OnPush */) {
10294 currView.state |= 8 /* ChecksEnabled */;
10295 }
10296 currView = currView.viewContainerParent || currView.parent;
10297 }
10298}
10299/**
10300 * @param {?} view
10301 * @param {?} endView
10302 * @return {?}
10303 */
10304function markParentViewsForCheckProjectedViews(view, endView) {
10305 var /** @type {?} */ currView = view;
10306 while (currView && currView !== endView) {
10307 currView.state |= 64 /* CheckProjectedViews */;
10308 currView = currView.viewContainerParent || currView.parent;
10309 }
10310}
10311/**
10312 * @param {?} view
10313 * @param {?} nodeIndex
10314 * @param {?} eventName
10315 * @param {?} event
10316 * @return {?}
10317 */
10318function dispatchEvent(view, nodeIndex, eventName, event) {
10319 var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
10320 var /** @type {?} */ startView = nodeDef.flags & 33554432 /* ComponentView */ ? asElementData(view, nodeIndex).componentView : view;
10321 markParentViewsForCheck(startView);
10322 return Services.handleEvent(view, nodeIndex, eventName, event);
10323}
10324/**
10325 * @param {?} view
10326 * @return {?}
10327 */
10328function declaredViewContainer(view) {
10329 if (view.parent) {
10330 var /** @type {?} */ parentView = view.parent;
10331 return asElementData(parentView, /** @type {?} */ ((view.parentNodeDef)).index);
10332 }
10333 return null;
10334}
10335/**
10336 * for component views, this is the host element.
10337 * for embedded views, this is the index of the parent node
10338 * that contains the view container.
10339 * @param {?} view
10340 * @return {?}
10341 */
10342function viewParentEl(view) {
10343 var /** @type {?} */ parentView = view.parent;
10344 if (parentView) {
10345 return ((view.parentNodeDef)).parent;
10346 }
10347 else {
10348 return null;
10349 }
10350}
10351/**
10352 * @param {?} view
10353 * @param {?} def
10354 * @return {?}
10355 */
10356function renderNode(view, def) {
10357 switch (def.flags & 201347067 /* Types */) {
10358 case 1 /* TypeElement */:
10359 return asElementData(view, def.index).renderElement;
10360 case 2 /* TypeText */:
10361 return asTextData(view, def.index).renderText;
10362 }
10363}
10364/**
10365 * @param {?} target
10366 * @param {?} name
10367 * @return {?}
10368 */
10369function elementEventFullName(target, name) {
10370 return target ? target + ":" + name : name;
10371}
10372/**
10373 * @param {?} view
10374 * @return {?}
10375 */
10376function isComponentView(view) {
10377 return !!view.parent && !!(((view.parentNodeDef)).flags & 32768 /* Component */);
10378}
10379/**
10380 * @param {?} view
10381 * @return {?}
10382 */
10383function isEmbeddedView(view) {
10384 return !!view.parent && !(((view.parentNodeDef)).flags & 32768 /* Component */);
10385}
10386/**
10387 * @param {?} queryId
10388 * @return {?}
10389 */
10390function filterQueryId(queryId) {
10391 return 1 << (queryId % 32);
10392}
10393/**
10394 * @param {?} matchedQueriesDsl
10395 * @return {?}
10396 */
10397function splitMatchedQueriesDsl(matchedQueriesDsl) {
10398 var /** @type {?} */ matchedQueries = {};
10399 var /** @type {?} */ matchedQueryIds = 0;
10400 var /** @type {?} */ references = {};
10401 if (matchedQueriesDsl) {
10402 matchedQueriesDsl.forEach(function (_a) {
10403 var queryId = _a[0], valueType = _a[1];
10404 if (typeof queryId === 'number') {
10405 matchedQueries[queryId] = valueType;
10406 matchedQueryIds |= filterQueryId(queryId);
10407 }
10408 else {
10409 references[queryId] = valueType;
10410 }
10411 });
10412 }
10413 return { matchedQueries: matchedQueries, references: references, matchedQueryIds: matchedQueryIds };
10414}
10415/**
10416 * @param {?} deps
10417 * @return {?}
10418 */
10419function splitDepsDsl(deps) {
10420 return deps.map(function (value) {
10421 var /** @type {?} */ token;
10422 var /** @type {?} */ flags;
10423 if (Array.isArray(value)) {
10424 flags = value[0], token = value[1];
10425 }
10426 else {
10427 flags = 0 /* None */;
10428 token = value;
10429 }
10430 return { flags: flags, token: token, tokenKey: tokenKey(token) };
10431 });
10432}
10433/**
10434 * @param {?} view
10435 * @param {?} renderHost
10436 * @param {?} def
10437 * @return {?}
10438 */
10439function getParentRenderElement(view, renderHost, def) {
10440 var /** @type {?} */ renderParent = def.renderParent;
10441 if (renderParent) {
10442 if ((renderParent.flags & 1 /* TypeElement */) === 0 ||
10443 (renderParent.flags & 33554432 /* ComponentView */) === 0 ||
10444 (((renderParent.element)).componentRendererType && ((((renderParent.element)).componentRendererType)).encapsulation ===
10445 ViewEncapsulation.Native)) {
10446 // only children of non components, or children of components with native encapsulation should
10447 // be attached.
10448 return asElementData(view, /** @type {?} */ ((def.renderParent)).index).renderElement;
10449 }
10450 }
10451 else {
10452 return renderHost;
10453 }
10454}
10455var DEFINITION_CACHE = new WeakMap();
10456/**
10457 * @template D
10458 * @param {?} factory
10459 * @return {?}
10460 */
10461function resolveDefinition(factory) {
10462 var /** @type {?} */ value = (((DEFINITION_CACHE.get(factory))));
10463 if (!value) {
10464 value = factory(function () { return NOOP; });
10465 value.factory = factory;
10466 DEFINITION_CACHE.set(factory, value);
10467 }
10468 return value;
10469}
10470/**
10471 * @param {?} view
10472 * @return {?}
10473 */
10474function rootRenderNodes(view) {
10475 var /** @type {?} */ renderNodes = [];
10476 visitRootRenderNodes(view, 0 /* Collect */, undefined, undefined, renderNodes);
10477 return renderNodes;
10478}
10479/**
10480 * @param {?} view
10481 * @param {?} action
10482 * @param {?} parentNode
10483 * @param {?} nextSibling
10484 * @param {?=} target
10485 * @return {?}
10486 */
10487function visitRootRenderNodes(view, action, parentNode, nextSibling, target) {
10488 // We need to re-compute the parent node in case the nodes have been moved around manually
10489 if (action === 3 /* RemoveChild */) {
10490 parentNode = view.renderer.parentNode(renderNode(view, /** @type {?} */ ((view.def.lastRenderRootNode))));
10491 }
10492 visitSiblingRenderNodes(view, action, 0, view.def.nodes.length - 1, parentNode, nextSibling, target);
10493}
10494/**
10495 * @param {?} view
10496 * @param {?} action
10497 * @param {?} startIndex
10498 * @param {?} endIndex
10499 * @param {?} parentNode
10500 * @param {?} nextSibling
10501 * @param {?=} target
10502 * @return {?}
10503 */
10504function visitSiblingRenderNodes(view, action, startIndex, endIndex, parentNode, nextSibling, target) {
10505 for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
10506 var /** @type {?} */ nodeDef = view.def.nodes[i];
10507 if (nodeDef.flags & (1 /* TypeElement */ | 2 /* TypeText */ | 8 /* TypeNgContent */)) {
10508 visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target);
10509 }
10510 // jump to next sibling
10511 i += nodeDef.childCount;
10512 }
10513}
10514/**
10515 * @param {?} view
10516 * @param {?} ngContentIndex
10517 * @param {?} action
10518 * @param {?} parentNode
10519 * @param {?} nextSibling
10520 * @param {?=} target
10521 * @return {?}
10522 */
10523function visitProjectedRenderNodes(view, ngContentIndex, action, parentNode, nextSibling, target) {
10524 var /** @type {?} */ compView = view;
10525 while (compView && !isComponentView(compView)) {
10526 compView = compView.parent;
10527 }
10528 var /** @type {?} */ hostView = ((compView)).parent;
10529 var /** @type {?} */ hostElDef = viewParentEl(/** @type {?} */ ((compView)));
10530 var /** @type {?} */ startIndex = ((hostElDef)).index + 1;
10531 var /** @type {?} */ endIndex = ((hostElDef)).index + ((hostElDef)).childCount;
10532 for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
10533 var /** @type {?} */ nodeDef = ((hostView)).def.nodes[i];
10534 if (nodeDef.ngContentIndex === ngContentIndex) {
10535 visitRenderNode(/** @type {?} */ ((hostView)), nodeDef, action, parentNode, nextSibling, target);
10536 }
10537 // jump to next sibling
10538 i += nodeDef.childCount;
10539 }
10540 if (!((hostView)).parent) {
10541 // a root view
10542 var /** @type {?} */ projectedNodes = view.root.projectableNodes[ngContentIndex];
10543 if (projectedNodes) {
10544 for (var /** @type {?} */ i = 0; i < projectedNodes.length; i++) {
10545 execRenderNodeAction(view, projectedNodes[i], action, parentNode, nextSibling, target);
10546 }
10547 }
10548 }
10549}
10550/**
10551 * @param {?} view
10552 * @param {?} nodeDef
10553 * @param {?} action
10554 * @param {?} parentNode
10555 * @param {?} nextSibling
10556 * @param {?=} target
10557 * @return {?}
10558 */
10559function visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target) {
10560 if (nodeDef.flags & 8 /* TypeNgContent */) {
10561 visitProjectedRenderNodes(view, /** @type {?} */ ((nodeDef.ngContent)).index, action, parentNode, nextSibling, target);
10562 }
10563 else {
10564 var /** @type {?} */ rn = renderNode(view, nodeDef);
10565 if (action === 3 /* RemoveChild */ && (nodeDef.flags & 33554432 /* ComponentView */) &&
10566 (nodeDef.bindingFlags & 48 /* CatSyntheticProperty */)) {
10567 // Note: we might need to do both actions.
10568 if (nodeDef.bindingFlags & (16 /* SyntheticProperty */)) {
10569 execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
10570 }
10571 if (nodeDef.bindingFlags & (32 /* SyntheticHostProperty */)) {
10572 var /** @type {?} */ compView = asElementData(view, nodeDef.index).componentView;
10573 execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
10574 }
10575 }
10576 else {
10577 execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
10578 }
10579 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
10580 var /** @type {?} */ embeddedViews = ((asElementData(view, nodeDef.index).viewContainer))._embeddedViews;
10581 for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
10582 visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
10583 }
10584 }
10585 if (nodeDef.flags & 1 /* TypeElement */ && !((nodeDef.element)).name) {
10586 visitSiblingRenderNodes(view, action, nodeDef.index + 1, nodeDef.index + nodeDef.childCount, parentNode, nextSibling, target);
10587 }
10588 }
10589}
10590/**
10591 * @param {?} view
10592 * @param {?} renderNode
10593 * @param {?} action
10594 * @param {?} parentNode
10595 * @param {?} nextSibling
10596 * @param {?=} target
10597 * @return {?}
10598 */
10599function execRenderNodeAction(view, renderNode, action, parentNode, nextSibling, target) {
10600 var /** @type {?} */ renderer = view.renderer;
10601 switch (action) {
10602 case 1 /* AppendChild */:
10603 renderer.appendChild(parentNode, renderNode);
10604 break;
10605 case 2 /* InsertBefore */:
10606 renderer.insertBefore(parentNode, renderNode, nextSibling);
10607 break;
10608 case 3 /* RemoveChild */:
10609 renderer.removeChild(parentNode, renderNode);
10610 break;
10611 case 0 /* Collect */:
10612 ((target)).push(renderNode);
10613 break;
10614 }
10615}
10616var NS_PREFIX_RE = /^:([^:]+):(.+)$/;
10617/**
10618 * @param {?} name
10619 * @return {?}
10620 */
10621function splitNamespace(name) {
10622 if (name[0] === ':') {
10623 var /** @type {?} */ match = ((name.match(NS_PREFIX_RE)));
10624 return [match[1], match[2]];
10625 }
10626 return ['', name];
10627}
10628/**
10629 * @param {?} bindings
10630 * @return {?}
10631 */
10632function calcBindingFlags(bindings) {
10633 var /** @type {?} */ flags = 0;
10634 for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
10635 flags |= bindings[i].flags;
10636 }
10637 return flags;
10638}
10639/**
10640 * @param {?} v
10641 * @return {?}
10642 */
10643function _toStringWithNull(v) {
10644 return v != null ? v.toString() : '';
10645}
10646/**
10647 * @param {?} view
10648 * @param {?} renderHost
10649 * @param {?} def
10650 * @return {?}
10651 */
10652function createElement(view, renderHost, def) {
10653 var /** @type {?} */ elDef = ((def.element));
10654 var /** @type {?} */ rootSelectorOrNode = view.root.selectorOrNode;
10655 var /** @type {?} */ renderer = view.renderer;
10656 var /** @type {?} */ el;
10657 if (view.parent || !rootSelectorOrNode) {
10658 if (elDef.name) {
10659 el = renderer.createElement(elDef.name, elDef.ns);
10660 }
10661 else {
10662 el = renderer.createComment('');
10663 }
10664 var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
10665 if (parentEl) {
10666 renderer.appendChild(parentEl, el);
10667 }
10668 }
10669 else {
10670 el = renderer.selectRootElement(rootSelectorOrNode);
10671 }
10672 if (elDef.attrs) {
10673 for (var /** @type {?} */ i = 0; i < elDef.attrs.length; i++) {
10674 var _a = elDef.attrs[i], ns = _a[0], name = _a[1], value = _a[2];
10675 renderer.setAttribute(el, name, value, ns);
10676 }
10677 }
10678 return el;
10679}
10680/**
10681 * @param {?} view
10682 * @param {?} compView
10683 * @param {?} def
10684 * @param {?} el
10685 * @return {?}
10686 */
10687function listenToElementOutputs(view, compView, def, el) {
10688 for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
10689 var /** @type {?} */ output = def.outputs[i];
10690 var /** @type {?} */ handleEventClosure = renderEventHandlerClosure(view, def.index, elementEventFullName(output.target, output.eventName));
10691 var /** @type {?} */ listenTarget = output.target;
10692 var /** @type {?} */ listenerView = view;
10693 if (output.target === 'component') {
10694 listenTarget = null;
10695 listenerView = compView;
10696 }
10697 var /** @type {?} */ disposable = (listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure)); /** @type {?} */
10698 ((view.disposables))[def.outputIndex + i] = disposable;
10699 }
10700}
10701/**
10702 * @param {?} view
10703 * @param {?} index
10704 * @param {?} eventName
10705 * @return {?}
10706 */
10707function renderEventHandlerClosure(view, index, eventName) {
10708 return function (event) {
10709 try {
10710 return dispatchEvent(view, index, eventName, event);
10711 }
10712 catch (e) {
10713 // Attention: Don't rethrow, to keep in sync with directive events.
10714 view.root.errorHandler.handleError(e);
10715 }
10716 };
10717}
10718/**
10719 * @param {?} view
10720 * @param {?} def
10721 * @param {?} v0
10722 * @param {?} v1
10723 * @param {?} v2
10724 * @param {?} v3
10725 * @param {?} v4
10726 * @param {?} v5
10727 * @param {?} v6
10728 * @param {?} v7
10729 * @param {?} v8
10730 * @param {?} v9
10731 * @return {?}
10732 */
10733function checkAndUpdateElementInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
10734 var /** @type {?} */ bindLen = def.bindings.length;
10735 var /** @type {?} */ changed = false;
10736 if (bindLen > 0 && checkAndUpdateElementValue(view, def, 0, v0))
10737 changed = true;
10738 if (bindLen > 1 && checkAndUpdateElementValue(view, def, 1, v1))
10739 changed = true;
10740 if (bindLen > 2 && checkAndUpdateElementValue(view, def, 2, v2))
10741 changed = true;
10742 if (bindLen > 3 && checkAndUpdateElementValue(view, def, 3, v3))
10743 changed = true;
10744 if (bindLen > 4 && checkAndUpdateElementValue(view, def, 4, v4))
10745 changed = true;
10746 if (bindLen > 5 && checkAndUpdateElementValue(view, def, 5, v5))
10747 changed = true;
10748 if (bindLen > 6 && checkAndUpdateElementValue(view, def, 6, v6))
10749 changed = true;
10750 if (bindLen > 7 && checkAndUpdateElementValue(view, def, 7, v7))
10751 changed = true;
10752 if (bindLen > 8 && checkAndUpdateElementValue(view, def, 8, v8))
10753 changed = true;
10754 if (bindLen > 9 && checkAndUpdateElementValue(view, def, 9, v9))
10755 changed = true;
10756 return changed;
10757}
10758/**
10759 * @param {?} view
10760 * @param {?} def
10761 * @param {?} values
10762 * @return {?}
10763 */
10764function checkAndUpdateElementDynamic(view, def, values) {
10765 var /** @type {?} */ changed = false;
10766 for (var /** @type {?} */ i = 0; i < values.length; i++) {
10767 if (checkAndUpdateElementValue(view, def, i, values[i]))
10768 changed = true;
10769 }
10770 return changed;
10771}
10772/**
10773 * @param {?} view
10774 * @param {?} def
10775 * @param {?} bindingIdx
10776 * @param {?} value
10777 * @return {?}
10778 */
10779function checkAndUpdateElementValue(view, def, bindingIdx, value) {
10780 if (!checkAndUpdateBinding(view, def, bindingIdx, value)) {
10781 return false;
10782 }
10783 var /** @type {?} */ binding = def.bindings[bindingIdx];
10784 var /** @type {?} */ elData = asElementData(view, def.index);
10785 var /** @type {?} */ renderNode$$1 = elData.renderElement;
10786 var /** @type {?} */ name = ((binding.name));
10787 switch (binding.flags & 15 /* Types */) {
10788 case 1 /* TypeElementAttribute */:
10789 setElementAttribute(view, binding, renderNode$$1, binding.ns, name, value);
10790 break;
10791 case 2 /* TypeElementClass */:
10792 setElementClass(view, renderNode$$1, name, value);
10793 break;
10794 case 4 /* TypeElementStyle */:
10795 setElementStyle(view, binding, renderNode$$1, name, value);
10796 break;
10797 case 8 /* TypeProperty */:
10798 var /** @type {?} */ bindView = (def.flags & 33554432 /* ComponentView */ &&
10799 binding.flags & 32 /* SyntheticHostProperty */) ?
10800 elData.componentView :
10801 view;
10802 setElementProperty(bindView, binding, renderNode$$1, name, value);
10803 break;
10804 }
10805 return true;
10806}
10807/**
10808 * @param {?} view
10809 * @param {?} binding
10810 * @param {?} renderNode
10811 * @param {?} ns
10812 * @param {?} name
10813 * @param {?} value
10814 * @return {?}
10815 */
10816function setElementAttribute(view, binding, renderNode$$1, ns, name, value) {
10817 var /** @type {?} */ securityContext = binding.securityContext;
10818 var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
10819 renderValue = renderValue != null ? renderValue.toString() : null;
10820 var /** @type {?} */ renderer = view.renderer;
10821 if (value != null) {
10822 renderer.setAttribute(renderNode$$1, name, renderValue, ns);
10823 }
10824 else {
10825 renderer.removeAttribute(renderNode$$1, name, ns);
10826 }
10827}
10828/**
10829 * @param {?} view
10830 * @param {?} renderNode
10831 * @param {?} name
10832 * @param {?} value
10833 * @return {?}
10834 */
10835function setElementClass(view, renderNode$$1, name, value) {
10836 var /** @type {?} */ renderer = view.renderer;
10837 if (value) {
10838 renderer.addClass(renderNode$$1, name);
10839 }
10840 else {
10841 renderer.removeClass(renderNode$$1, name);
10842 }
10843}
10844/**
10845 * @param {?} view
10846 * @param {?} binding
10847 * @param {?} renderNode
10848 * @param {?} name
10849 * @param {?} value
10850 * @return {?}
10851 */
10852function setElementStyle(view, binding, renderNode$$1, name, value) {
10853 var /** @type {?} */ renderValue = view.root.sanitizer.sanitize(SecurityContext.STYLE, /** @type {?} */ (value));
10854 if (renderValue != null) {
10855 renderValue = renderValue.toString();
10856 var /** @type {?} */ unit = binding.suffix;
10857 if (unit != null) {
10858 renderValue = renderValue + unit;
10859 }
10860 }
10861 else {
10862 renderValue = null;
10863 }
10864 var /** @type {?} */ renderer = view.renderer;
10865 if (renderValue != null) {
10866 renderer.setStyle(renderNode$$1, name, renderValue);
10867 }
10868 else {
10869 renderer.removeStyle(renderNode$$1, name);
10870 }
10871}
10872/**
10873 * @param {?} view
10874 * @param {?} binding
10875 * @param {?} renderNode
10876 * @param {?} name
10877 * @param {?} value
10878 * @return {?}
10879 */
10880function setElementProperty(view, binding, renderNode$$1, name, value) {
10881 var /** @type {?} */ securityContext = binding.securityContext;
10882 var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
10883 view.renderer.setProperty(renderNode$$1, name, renderValue);
10884}
10885/**
10886 * @license
10887 * Copyright Google Inc. All Rights Reserved.
10888 *
10889 * Use of this source code is governed by an MIT-style license that can be
10890 * found in the LICENSE file at https://angular.io/license
10891 */
10892var NOT_CREATED$1 = new Object();
10893var InjectorRefTokenKey$1 = tokenKey(Injector);
10894var NgModuleRefTokenKey = tokenKey(NgModuleRef);
10895/**
10896 * @param {?} data
10897 * @return {?}
10898 */
10899function initNgModule(data) {
10900 var /** @type {?} */ def = data._def;
10901 var /** @type {?} */ providers = data._providers = new Array(def.providers.length);
10902 for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
10903 var /** @type {?} */ provDef = def.providers[i];
10904 providers[i] = provDef.flags & 4096 /* LazyProvider */ ? NOT_CREATED$1 :
10905 _createProviderInstance$1(data, provDef);
10906 }
10907}
10908/**
10909 * @param {?} data
10910 * @param {?} depDef
10911 * @param {?=} notFoundValue
10912 * @return {?}
10913 */
10914function resolveNgModuleDep(data, depDef, notFoundValue) {
10915 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
10916 if (depDef.flags & 8 /* Value */) {
10917 return depDef.token;
10918 }
10919 if (depDef.flags & 2 /* Optional */) {
10920 notFoundValue = null;
10921 }
10922 if (depDef.flags & 1 /* SkipSelf */) {
10923 return data._parent.get(depDef.token, notFoundValue);
10924 }
10925 var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
10926 switch (tokenKey$$1) {
10927 case InjectorRefTokenKey$1:
10928 case NgModuleRefTokenKey:
10929 return data;
10930 }
10931 var /** @type {?} */ providerDef = data._def.providersByKey[tokenKey$$1];
10932 if (providerDef) {
10933 var /** @type {?} */ providerInstance = data._providers[providerDef.index];
10934 if (providerInstance === NOT_CREATED$1) {
10935 providerInstance = data._providers[providerDef.index] =
10936 _createProviderInstance$1(data, providerDef);
10937 }
10938 return providerInstance;
10939 }
10940 return data._parent.get(depDef.token, notFoundValue);
10941}
10942/**
10943 * @param {?} ngModule
10944 * @param {?} providerDef
10945 * @return {?}
10946 */
10947function _createProviderInstance$1(ngModule, providerDef) {
10948 var /** @type {?} */ injectable;
10949 switch (providerDef.flags & 201347067 /* Types */) {
10950 case 512 /* TypeClassProvider */:
10951 injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
10952 break;
10953 case 1024 /* TypeFactoryProvider */:
10954 injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
10955 break;
10956 case 2048 /* TypeUseExistingProvider */:
10957 injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
10958 break;
10959 case 256 /* TypeValueProvider */:
10960 injectable = providerDef.value;
10961 break;
10962 }
10963 return injectable;
10964}
10965/**
10966 * @param {?} ngModule
10967 * @param {?} ctor
10968 * @param {?} deps
10969 * @return {?}
10970 */
10971function _createClass(ngModule, ctor, deps) {
10972 var /** @type {?} */ len = deps.length;
10973 var /** @type {?} */ injectable;
10974 switch (len) {
10975 case 0:
10976 injectable = new ctor();
10977 break;
10978 case 1:
10979 injectable = new ctor(resolveNgModuleDep(ngModule, deps[0]));
10980 break;
10981 case 2:
10982 injectable =
10983 new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
10984 break;
10985 case 3:
10986 injectable = new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
10987 break;
10988 default:
10989 var /** @type {?} */ depValues = new Array(len);
10990 for (var /** @type {?} */ i = 0; i < len; i++) {
10991 depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
10992 }
10993 injectable = new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
10994 }
10995 return injectable;
10996}
10997/**
10998 * @param {?} ngModule
10999 * @param {?} factory
11000 * @param {?} deps
11001 * @return {?}
11002 */
11003function _callFactory(ngModule, factory, deps) {
11004 var /** @type {?} */ len = deps.length;
11005 var /** @type {?} */ injectable;
11006 switch (len) {
11007 case 0:
11008 injectable = factory();
11009 break;
11010 case 1:
11011 injectable = factory(resolveNgModuleDep(ngModule, deps[0]));
11012 break;
11013 case 2:
11014 injectable =
11015 factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
11016 break;
11017 case 3:
11018 injectable = factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
11019 break;
11020 default:
11021 var /** @type {?} */ depValues = Array(len);
11022 for (var /** @type {?} */ i = 0; i < len; i++) {
11023 depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
11024 }
11025 injectable = factory.apply(void 0, depValues);
11026 }
11027 return injectable;
11028}
11029/**
11030 * @param {?} ngModule
11031 * @param {?} lifecycles
11032 * @return {?}
11033 */
11034function callNgModuleLifecycle(ngModule, lifecycles) {
11035 var /** @type {?} */ def = ngModule._def;
11036 for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
11037 var /** @type {?} */ provDef = def.providers[i];
11038 if (provDef.flags & 131072 /* OnDestroy */) {
11039 var /** @type {?} */ instance = ngModule._providers[i];
11040 if (instance && instance !== NOT_CREATED$1) {
11041 instance.ngOnDestroy();
11042 }
11043 }
11044 }
11045}
11046/**
11047 * @license
11048 * Copyright Google Inc. All Rights Reserved.
11049 *
11050 * Use of this source code is governed by an MIT-style license that can be
11051 * found in the LICENSE file at https://angular.io/license
11052 */
11053/**
11054 * @param {?} parentView
11055 * @param {?} elementData
11056 * @param {?} viewIndex
11057 * @param {?} view
11058 * @return {?}
11059 */
11060function attachEmbeddedView(parentView, elementData, viewIndex, view) {
11061 var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
11062 if (viewIndex === null || viewIndex === undefined) {
11063 viewIndex = embeddedViews.length;
11064 }
11065 view.viewContainerParent = parentView;
11066 addToArray(embeddedViews, /** @type {?} */ ((viewIndex)), view);
11067 attachProjectedView(elementData, view);
11068 Services.dirtyParentQueries(view);
11069 var /** @type {?} */ prevView = ((viewIndex)) > 0 ? embeddedViews[((viewIndex)) - 1] : null;
11070 renderAttachEmbeddedView(elementData, prevView, view);
11071}
11072/**
11073 * @param {?} vcElementData
11074 * @param {?} view
11075 * @return {?}
11076 */
11077function attachProjectedView(vcElementData, view) {
11078 var /** @type {?} */ dvcElementData = declaredViewContainer(view);
11079 if (!dvcElementData || dvcElementData === vcElementData ||
11080 view.state & 16 /* IsProjectedView */) {
11081 return;
11082 }
11083 // Note: For performance reasons, we
11084 // - add a view to template._projectedViews only 1x throughout its lifetime,
11085 // and remove it not until the view is destroyed.
11086 // (hard, as when a parent view is attached/detached we would need to attach/detach all
11087 // nested projected views as well, even accross component boundaries).
11088 // - don't track the insertion order of views in the projected views array
11089 // (hard, as when the views of the same template are inserted different view containers)
11090 view.state |= 16 /* IsProjectedView */;
11091 var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
11092 if (!projectedViews) {
11093 projectedViews = dvcElementData.template._projectedViews = [];
11094 }
11095 projectedViews.push(view);
11096 // Note: we are changing the NodeDef here as we cannot calculate
11097 // the fact whether a template is used for projection during compilation.
11098 markNodeAsProjectedTemplate(/** @type {?} */ ((view.parent)).def, /** @type {?} */ ((view.parentNodeDef)));
11099}
11100/**
11101 * @param {?} viewDef
11102 * @param {?} nodeDef
11103 * @return {?}
11104 */
11105function markNodeAsProjectedTemplate(viewDef, nodeDef) {
11106 if (nodeDef.flags & 4 /* ProjectedTemplate */) {
11107 return;
11108 }
11109 viewDef.nodeFlags |= 4 /* ProjectedTemplate */;
11110 nodeDef.flags |= 4 /* ProjectedTemplate */;
11111 var /** @type {?} */ parentNodeDef = nodeDef.parent;
11112 while (parentNodeDef) {
11113 parentNodeDef.childFlags |= 4 /* ProjectedTemplate */;
11114 parentNodeDef = parentNodeDef.parent;
11115 }
11116}
11117/**
11118 * @param {?} elementData
11119 * @param {?=} viewIndex
11120 * @return {?}
11121 */
11122function detachEmbeddedView(elementData, viewIndex) {
11123 var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
11124 if (viewIndex == null || viewIndex >= embeddedViews.length) {
11125 viewIndex = embeddedViews.length - 1;
11126 }
11127 if (viewIndex < 0) {
11128 return null;
11129 }
11130 var /** @type {?} */ view = embeddedViews[viewIndex];
11131 view.viewContainerParent = null;
11132 removeFromArray(embeddedViews, viewIndex);
11133 // See attachProjectedView for why we don't update projectedViews here.
11134 Services.dirtyParentQueries(view);
11135 renderDetachView(view);
11136 return view;
11137}
11138/**
11139 * @param {?} view
11140 * @return {?}
11141 */
11142function detachProjectedView(view) {
11143 if (!(view.state & 16 /* IsProjectedView */)) {
11144 return;
11145 }
11146 var /** @type {?} */ dvcElementData = declaredViewContainer(view);
11147 if (dvcElementData) {
11148 var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
11149 if (projectedViews) {
11150 removeFromArray(projectedViews, projectedViews.indexOf(view));
11151 Services.dirtyParentQueries(view);
11152 }
11153 }
11154}
11155/**
11156 * @param {?} elementData
11157 * @param {?} oldViewIndex
11158 * @param {?} newViewIndex
11159 * @return {?}
11160 */
11161function moveEmbeddedView(elementData, oldViewIndex, newViewIndex) {
11162 var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
11163 var /** @type {?} */ view = embeddedViews[oldViewIndex];
11164 removeFromArray(embeddedViews, oldViewIndex);
11165 if (newViewIndex == null) {
11166 newViewIndex = embeddedViews.length;
11167 }
11168 addToArray(embeddedViews, newViewIndex, view);
11169 // Note: Don't need to change projectedViews as the order in there
11170 // as always invalid...
11171 Services.dirtyParentQueries(view);
11172 renderDetachView(view);
11173 var /** @type {?} */ prevView = newViewIndex > 0 ? embeddedViews[newViewIndex - 1] : null;
11174 renderAttachEmbeddedView(elementData, prevView, view);
11175 return view;
11176}
11177/**
11178 * @param {?} elementData
11179 * @param {?} prevView
11180 * @param {?} view
11181 * @return {?}
11182 */
11183function renderAttachEmbeddedView(elementData, prevView, view) {
11184 var /** @type {?} */ prevRenderNode = prevView ? renderNode(prevView, /** @type {?} */ ((prevView.def.lastRenderRootNode))) :
11185 elementData.renderElement;
11186 var /** @type {?} */ parentNode = view.renderer.parentNode(prevRenderNode);
11187 var /** @type {?} */ nextSibling = view.renderer.nextSibling(prevRenderNode);
11188 // Note: We can't check if `nextSibling` is present, as on WebWorkers it will always be!
11189 // However, browsers automatically do `appendChild` when there is no `nextSibling`.
11190 visitRootRenderNodes(view, 2 /* InsertBefore */, parentNode, nextSibling, undefined);
11191}
11192/**
11193 * @param {?} view
11194 * @return {?}
11195 */
11196function renderDetachView(view) {
11197 visitRootRenderNodes(view, 3 /* RemoveChild */, null, null, undefined);
11198}
11199/**
11200 * @param {?} arr
11201 * @param {?} index
11202 * @param {?} value
11203 * @return {?}
11204 */
11205function addToArray(arr, index, value) {
11206 // perf: array.push is faster than array.splice!
11207 if (index >= arr.length) {
11208 arr.push(value);
11209 }
11210 else {
11211 arr.splice(index, 0, value);
11212 }
11213}
11214/**
11215 * @param {?} arr
11216 * @param {?} index
11217 * @return {?}
11218 */
11219function removeFromArray(arr, index) {
11220 // perf: array.pop is faster than array.splice!
11221 if (index >= arr.length - 1) {
11222 arr.pop();
11223 }
11224 else {
11225 arr.splice(index, 1);
11226 }
11227}
11228/**
11229 * @license
11230 * Copyright Google Inc. All Rights Reserved.
11231 *
11232 * Use of this source code is governed by an MIT-style license that can be
11233 * found in the LICENSE file at https://angular.io/license
11234 */
11235var EMPTY_CONTEXT = new Object();
11236var ComponentFactory_ = (function (_super) {
11237 __extends$1(ComponentFactory_, _super);
11238 /**
11239 * @param {?} selector
11240 * @param {?} componentType
11241 * @param {?} viewDefFactory
11242 * @param {?} _inputs
11243 * @param {?} _outputs
11244 * @param {?} ngContentSelectors
11245 */
11246 function ComponentFactory_(selector, componentType, viewDefFactory, _inputs, _outputs, ngContentSelectors) {
11247 var _this =
11248 // Attention: this ctor is called as top level function.
11249 // Putting any logic in here will destroy closure tree shaking!
11250 _super.call(this) || this;
11251 _this.selector = selector;
11252 _this.componentType = componentType;
11253 _this._inputs = _inputs;
11254 _this._outputs = _outputs;
11255 _this.ngContentSelectors = ngContentSelectors;
11256 _this.viewDefFactory = viewDefFactory;
11257 return _this;
11258 }
11259 Object.defineProperty(ComponentFactory_.prototype, "inputs", {
11260 /**
11261 * @return {?}
11262 */
11263 get: function () {
11264 var /** @type {?} */ inputsArr = [];
11265 var /** @type {?} */ inputs = ((this._inputs));
11266 for (var /** @type {?} */ propName in inputs) {
11267 var /** @type {?} */ templateName = inputs[propName];
11268 inputsArr.push({ propName: propName, templateName: templateName });
11269 }
11270 return inputsArr;
11271 },
11272 enumerable: true,
11273 configurable: true
11274 });
11275 Object.defineProperty(ComponentFactory_.prototype, "outputs", {
11276 /**
11277 * @return {?}
11278 */
11279 get: function () {
11280 var /** @type {?} */ outputsArr = [];
11281 for (var /** @type {?} */ propName in this._outputs) {
11282 var /** @type {?} */ templateName = this._outputs[propName];
11283 outputsArr.push({ propName: propName, templateName: templateName });
11284 }
11285 return outputsArr;
11286 },
11287 enumerable: true,
11288 configurable: true
11289 });
11290 /**
11291 * Creates a new component.
11292 * @param {?} injector
11293 * @param {?=} projectableNodes
11294 * @param {?=} rootSelectorOrNode
11295 * @param {?=} ngModule
11296 * @return {?}
11297 */
11298 ComponentFactory_.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
11299 if (!ngModule) {
11300 throw new Error('ngModule should be provided');
11301 }
11302 var /** @type {?} */ viewDef = resolveDefinition(this.viewDefFactory);
11303 var /** @type {?} */ componentNodeIndex = ((((viewDef.nodes[0].element)).componentProvider)).index;
11304 var /** @type {?} */ view = Services.createRootView(injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
11305 var /** @type {?} */ component = asProviderData(view, componentNodeIndex).instance;
11306 if (rootSelectorOrNode) {
11307 view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
11308 }
11309 return new ComponentRef_(view, new ViewRef_(view), component);
11310 };
11311 return ComponentFactory_;
11312}(ComponentFactory));
11313var ComponentRef_ = (function (_super) {
11314 __extends$1(ComponentRef_, _super);
11315 /**
11316 * @param {?} _view
11317 * @param {?} _viewRef
11318 * @param {?} _component
11319 */
11320 function ComponentRef_(_view, _viewRef, _component) {
11321 var _this = _super.call(this) || this;
11322 _this._view = _view;
11323 _this._viewRef = _viewRef;
11324 _this._component = _component;
11325 _this._elDef = _this._view.def.nodes[0];
11326 return _this;
11327 }
11328 Object.defineProperty(ComponentRef_.prototype, "location", {
11329 /**
11330 * @return {?}
11331 */
11332 get: function () {
11333 return new ElementRef(asElementData(this._view, this._elDef.index).renderElement);
11334 },
11335 enumerable: true,
11336 configurable: true
11337 });
11338 Object.defineProperty(ComponentRef_.prototype, "injector", {
11339 /**
11340 * @return {?}
11341 */
11342 get: function () { return new Injector_(this._view, this._elDef); },
11343 enumerable: true,
11344 configurable: true
11345 });
11346 Object.defineProperty(ComponentRef_.prototype, "instance", {
11347 /**
11348 * @return {?}
11349 */
11350 get: function () { return this._component; },
11351 enumerable: true,
11352 configurable: true
11353 });
11354
11355 Object.defineProperty(ComponentRef_.prototype, "hostView", {
11356 /**
11357 * @return {?}
11358 */
11359 get: function () { return this._viewRef; },
11360 enumerable: true,
11361 configurable: true
11362 });
11363
11364 Object.defineProperty(ComponentRef_.prototype, "changeDetectorRef", {
11365 /**
11366 * @return {?}
11367 */
11368 get: function () { return this._viewRef; },
11369 enumerable: true,
11370 configurable: true
11371 });
11372
11373 Object.defineProperty(ComponentRef_.prototype, "componentType", {
11374 /**
11375 * @return {?}
11376 */
11377 get: function () { return (this._component.constructor); },
11378 enumerable: true,
11379 configurable: true
11380 });
11381 /**
11382 * @return {?}
11383 */
11384 ComponentRef_.prototype.destroy = function () { this._viewRef.destroy(); };
11385 /**
11386 * @param {?} callback
11387 * @return {?}
11388 */
11389 ComponentRef_.prototype.onDestroy = function (callback) { this._viewRef.onDestroy(callback); };
11390 return ComponentRef_;
11391}(ComponentRef));
11392/**
11393 * @param {?} view
11394 * @param {?} elDef
11395 * @param {?} elData
11396 * @return {?}
11397 */
11398function createViewContainerData(view, elDef, elData) {
11399 return new ViewContainerRef_(view, elDef, elData);
11400}
11401var ViewContainerRef_ = (function () {
11402 /**
11403 * @param {?} _view
11404 * @param {?} _elDef
11405 * @param {?} _data
11406 */
11407 function ViewContainerRef_(_view, _elDef, _data) {
11408 this._view = _view;
11409 this._elDef = _elDef;
11410 this._data = _data;
11411 /**
11412 * \@internal
11413 */
11414 this._embeddedViews = [];
11415 }
11416 Object.defineProperty(ViewContainerRef_.prototype, "element", {
11417 /**
11418 * @return {?}
11419 */
11420 get: function () { return new ElementRef(this._data.renderElement); },
11421 enumerable: true,
11422 configurable: true
11423 });
11424 Object.defineProperty(ViewContainerRef_.prototype, "injector", {
11425 /**
11426 * @return {?}
11427 */
11428 get: function () { return new Injector_(this._view, this._elDef); },
11429 enumerable: true,
11430 configurable: true
11431 });
11432 Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
11433 /**
11434 * @return {?}
11435 */
11436 get: function () {
11437 var /** @type {?} */ view = this._view;
11438 var /** @type {?} */ elDef = this._elDef.parent;
11439 while (!elDef && view) {
11440 elDef = viewParentEl(view);
11441 view = ((view.parent));
11442 }
11443 return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
11444 },
11445 enumerable: true,
11446 configurable: true
11447 });
11448 /**
11449 * @return {?}
11450 */
11451 ViewContainerRef_.prototype.clear = function () {
11452 var /** @type {?} */ len = this._embeddedViews.length;
11453 for (var /** @type {?} */ i = len - 1; i >= 0; i--) {
11454 var /** @type {?} */ view = ((detachEmbeddedView(this._data, i)));
11455 Services.destroyView(view);
11456 }
11457 };
11458 /**
11459 * @param {?} index
11460 * @return {?}
11461 */
11462 ViewContainerRef_.prototype.get = function (index) {
11463 var /** @type {?} */ view = this._embeddedViews[index];
11464 if (view) {
11465 var /** @type {?} */ ref = new ViewRef_(view);
11466 ref.attachToViewContainerRef(this);
11467 return ref;
11468 }
11469 return null;
11470 };
11471 Object.defineProperty(ViewContainerRef_.prototype, "length", {
11472 /**
11473 * @return {?}
11474 */
11475 get: function () { return this._embeddedViews.length; },
11476 enumerable: true,
11477 configurable: true
11478 });
11479
11480 /**
11481 * @template C
11482 * @param {?} templateRef
11483 * @param {?=} context
11484 * @param {?=} index
11485 * @return {?}
11486 */
11487 ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
11488 var /** @type {?} */ viewRef = templateRef.createEmbeddedView(context || ({}));
11489 this.insert(viewRef, index);
11490 return viewRef;
11491 };
11492 /**
11493 * @template C
11494 * @param {?} componentFactory
11495 * @param {?=} index
11496 * @param {?=} injector
11497 * @param {?=} projectableNodes
11498 * @param {?=} ngModuleRef
11499 * @return {?}
11500 */
11501 ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
11502 var /** @type {?} */ contextInjector = injector || this.parentInjector;
11503 if (!ngModuleRef && !(componentFactory instanceof ComponentFactoryBoundToModule)) {
11504 ngModuleRef = contextInjector.get(NgModuleRef);
11505 }
11506 var /** @type {?} */ componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
11507 this.insert(componentRef.hostView, index);
11508 return componentRef;
11509 };
11510 /**
11511 * @param {?} viewRef
11512 * @param {?=} index
11513 * @return {?}
11514 */
11515 ViewContainerRef_.prototype.insert = function (viewRef, index) {
11516 if (viewRef.destroyed) {
11517 throw new Error('Cannot insert a destroyed View in a ViewContainer!');
11518 }
11519 var /** @type {?} */ viewRef_ = (viewRef);
11520 var /** @type {?} */ viewData = viewRef_._view;
11521 attachEmbeddedView(this._view, this._data, index, viewData);
11522 viewRef_.attachToViewContainerRef(this);
11523 return viewRef;
11524 };
11525 /**
11526 * @param {?} viewRef
11527 * @param {?} currentIndex
11528 * @return {?}
11529 */
11530 ViewContainerRef_.prototype.move = function (viewRef, currentIndex) {
11531 if (viewRef.destroyed) {
11532 throw new Error('Cannot move a destroyed View in a ViewContainer!');
11533 }
11534 var /** @type {?} */ previousIndex = this._embeddedViews.indexOf(viewRef._view);
11535 moveEmbeddedView(this._data, previousIndex, currentIndex);
11536 return viewRef;
11537 };
11538 /**
11539 * @param {?} viewRef
11540 * @return {?}
11541 */
11542 ViewContainerRef_.prototype.indexOf = function (viewRef) {
11543 return this._embeddedViews.indexOf(((viewRef))._view);
11544 };
11545 /**
11546 * @param {?=} index
11547 * @return {?}
11548 */
11549 ViewContainerRef_.prototype.remove = function (index) {
11550 var /** @type {?} */ viewData = detachEmbeddedView(this._data, index);
11551 if (viewData) {
11552 Services.destroyView(viewData);
11553 }
11554 };
11555 /**
11556 * @param {?=} index
11557 * @return {?}
11558 */
11559 ViewContainerRef_.prototype.detach = function (index) {
11560 var /** @type {?} */ view = detachEmbeddedView(this._data, index);
11561 return view ? new ViewRef_(view) : null;
11562 };
11563 return ViewContainerRef_;
11564}());
11565/**
11566 * @param {?} view
11567 * @return {?}
11568 */
11569function createChangeDetectorRef(view) {
11570 return new ViewRef_(view);
11571}
11572var ViewRef_ = (function () {
11573 /**
11574 * @param {?} _view
11575 */
11576 function ViewRef_(_view) {
11577 this._view = _view;
11578 this._viewContainerRef = null;
11579 this._appRef = null;
11580 }
11581 Object.defineProperty(ViewRef_.prototype, "rootNodes", {
11582 /**
11583 * @return {?}
11584 */
11585 get: function () { return rootRenderNodes(this._view); },
11586 enumerable: true,
11587 configurable: true
11588 });
11589 Object.defineProperty(ViewRef_.prototype, "context", {
11590 /**
11591 * @return {?}
11592 */
11593 get: function () { return this._view.context; },
11594 enumerable: true,
11595 configurable: true
11596 });
11597 Object.defineProperty(ViewRef_.prototype, "destroyed", {
11598 /**
11599 * @return {?}
11600 */
11601 get: function () { return (this._view.state & 128 /* Destroyed */) !== 0; },
11602 enumerable: true,
11603 configurable: true
11604 });
11605 /**
11606 * @return {?}
11607 */
11608 ViewRef_.prototype.markForCheck = function () { markParentViewsForCheck(this._view); };
11609 /**
11610 * @return {?}
11611 */
11612 ViewRef_.prototype.detach = function () { this._view.state &= ~4 /* Attached */; };
11613 /**
11614 * @return {?}
11615 */
11616 ViewRef_.prototype.detectChanges = function () {
11617 var /** @type {?} */ fs = this._view.root.rendererFactory;
11618 if (fs.begin) {
11619 fs.begin();
11620 }
11621 Services.checkAndUpdateView(this._view);
11622 if (fs.end) {
11623 fs.end();
11624 }
11625 };
11626 /**
11627 * @return {?}
11628 */
11629 ViewRef_.prototype.checkNoChanges = function () { Services.checkNoChangesView(this._view); };
11630 /**
11631 * @return {?}
11632 */
11633 ViewRef_.prototype.reattach = function () { this._view.state |= 4 /* Attached */; };
11634 /**
11635 * @param {?} callback
11636 * @return {?}
11637 */
11638 ViewRef_.prototype.onDestroy = function (callback) {
11639 if (!this._view.disposables) {
11640 this._view.disposables = [];
11641 }
11642 this._view.disposables.push(/** @type {?} */ (callback));
11643 };
11644 /**
11645 * @return {?}
11646 */
11647 ViewRef_.prototype.destroy = function () {
11648 if (this._appRef) {
11649 this._appRef.detachView(this);
11650 }
11651 else if (this._viewContainerRef) {
11652 this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
11653 }
11654 Services.destroyView(this._view);
11655 };
11656 /**
11657 * @return {?}
11658 */
11659 ViewRef_.prototype.detachFromAppRef = function () {
11660 this._appRef = null;
11661 renderDetachView(this._view);
11662 Services.dirtyParentQueries(this._view);
11663 };
11664 /**
11665 * @param {?} appRef
11666 * @return {?}
11667 */
11668 ViewRef_.prototype.attachToAppRef = function (appRef) {
11669 if (this._viewContainerRef) {
11670 throw new Error('This view is already attached to a ViewContainer!');
11671 }
11672 this._appRef = appRef;
11673 };
11674 /**
11675 * @param {?} vcRef
11676 * @return {?}
11677 */
11678 ViewRef_.prototype.attachToViewContainerRef = function (vcRef) {
11679 if (this._appRef) {
11680 throw new Error('This view is already attached directly to the ApplicationRef!');
11681 }
11682 this._viewContainerRef = vcRef;
11683 };
11684 return ViewRef_;
11685}());
11686/**
11687 * @param {?} view
11688 * @param {?} def
11689 * @return {?}
11690 */
11691function createTemplateData(view, def) {
11692 return new TemplateRef_(view, def);
11693}
11694var TemplateRef_ = (function (_super) {
11695 __extends$1(TemplateRef_, _super);
11696 /**
11697 * @param {?} _parentView
11698 * @param {?} _def
11699 */
11700 function TemplateRef_(_parentView, _def) {
11701 var _this = _super.call(this) || this;
11702 _this._parentView = _parentView;
11703 _this._def = _def;
11704 return _this;
11705 }
11706 /**
11707 * @param {?} context
11708 * @return {?}
11709 */
11710 TemplateRef_.prototype.createEmbeddedView = function (context) {
11711 return new ViewRef_(Services.createEmbeddedView(this._parentView, this._def, /** @type {?} */ ((((this._def.element)).template)), context));
11712 };
11713 Object.defineProperty(TemplateRef_.prototype, "elementRef", {
11714 /**
11715 * @return {?}
11716 */
11717 get: function () {
11718 return new ElementRef(asElementData(this._parentView, this._def.index).renderElement);
11719 },
11720 enumerable: true,
11721 configurable: true
11722 });
11723 return TemplateRef_;
11724}(TemplateRef));
11725/**
11726 * @param {?} view
11727 * @param {?} elDef
11728 * @return {?}
11729 */
11730function createInjector(view, elDef) {
11731 return new Injector_(view, elDef);
11732}
11733var Injector_ = (function () {
11734 /**
11735 * @param {?} view
11736 * @param {?} elDef
11737 */
11738 function Injector_(view, elDef) {
11739 this.view = view;
11740 this.elDef = elDef;
11741 }
11742 /**
11743 * @param {?} token
11744 * @param {?=} notFoundValue
11745 * @return {?}
11746 */
11747 Injector_.prototype.get = function (token, notFoundValue) {
11748 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
11749 var /** @type {?} */ allowPrivateServices = this.elDef ? (this.elDef.flags & 33554432 /* ComponentView */) !== 0 : false;
11750 return Services.resolveDep(this.view, this.elDef, allowPrivateServices, { flags: 0 /* None */, token: token, tokenKey: tokenKey(token) }, notFoundValue);
11751 };
11752 return Injector_;
11753}());
11754/**
11755 * @param {?} view
11756 * @return {?}
11757 */
11758function createRendererV1(view) {
11759 return new RendererAdapter(view.renderer);
11760}
11761var RendererAdapter = (function () {
11762 /**
11763 * @param {?} delegate
11764 */
11765 function RendererAdapter(delegate) {
11766 this.delegate = delegate;
11767 }
11768 /**
11769 * @param {?} selectorOrNode
11770 * @return {?}
11771 */
11772 RendererAdapter.prototype.selectRootElement = function (selectorOrNode) {
11773 return this.delegate.selectRootElement(selectorOrNode);
11774 };
11775 /**
11776 * @param {?} parent
11777 * @param {?} namespaceAndName
11778 * @return {?}
11779 */
11780 RendererAdapter.prototype.createElement = function (parent, namespaceAndName) {
11781 var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
11782 var /** @type {?} */ el = this.delegate.createElement(name, ns);
11783 if (parent) {
11784 this.delegate.appendChild(parent, el);
11785 }
11786 return el;
11787 };
11788 /**
11789 * @param {?} hostElement
11790 * @return {?}
11791 */
11792 RendererAdapter.prototype.createViewRoot = function (hostElement) { return hostElement; };
11793 /**
11794 * @param {?} parentElement
11795 * @return {?}
11796 */
11797 RendererAdapter.prototype.createTemplateAnchor = function (parentElement) {
11798 var /** @type {?} */ comment = this.delegate.createComment('');
11799 if (parentElement) {
11800 this.delegate.appendChild(parentElement, comment);
11801 }
11802 return comment;
11803 };
11804 /**
11805 * @param {?} parentElement
11806 * @param {?} value
11807 * @return {?}
11808 */
11809 RendererAdapter.prototype.createText = function (parentElement, value) {
11810 var /** @type {?} */ node = this.delegate.createText(value);
11811 if (parentElement) {
11812 this.delegate.appendChild(parentElement, node);
11813 }
11814 return node;
11815 };
11816 /**
11817 * @param {?} parentElement
11818 * @param {?} nodes
11819 * @return {?}
11820 */
11821 RendererAdapter.prototype.projectNodes = function (parentElement, nodes) {
11822 for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
11823 this.delegate.appendChild(parentElement, nodes[i]);
11824 }
11825 };
11826 /**
11827 * @param {?} node
11828 * @param {?} viewRootNodes
11829 * @return {?}
11830 */
11831 RendererAdapter.prototype.attachViewAfter = function (node, viewRootNodes) {
11832 var /** @type {?} */ parentElement = this.delegate.parentNode(node);
11833 var /** @type {?} */ nextSibling = this.delegate.nextSibling(node);
11834 for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
11835 this.delegate.insertBefore(parentElement, viewRootNodes[i], nextSibling);
11836 }
11837 };
11838 /**
11839 * @param {?} viewRootNodes
11840 * @return {?}
11841 */
11842 RendererAdapter.prototype.detachView = function (viewRootNodes) {
11843 for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
11844 var /** @type {?} */ node = viewRootNodes[i];
11845 var /** @type {?} */ parentElement = this.delegate.parentNode(node);
11846 this.delegate.removeChild(parentElement, node);
11847 }
11848 };
11849 /**
11850 * @param {?} hostElement
11851 * @param {?} viewAllNodes
11852 * @return {?}
11853 */
11854 RendererAdapter.prototype.destroyView = function (hostElement, viewAllNodes) {
11855 for (var /** @type {?} */ i = 0; i < viewAllNodes.length; i++) {
11856 ((this.delegate.destroyNode))(viewAllNodes[i]);
11857 }
11858 };
11859 /**
11860 * @param {?} renderElement
11861 * @param {?} name
11862 * @param {?} callback
11863 * @return {?}
11864 */
11865 RendererAdapter.prototype.listen = function (renderElement, name, callback) {
11866 return this.delegate.listen(renderElement, name, /** @type {?} */ (callback));
11867 };
11868 /**
11869 * @param {?} target
11870 * @param {?} name
11871 * @param {?} callback
11872 * @return {?}
11873 */
11874 RendererAdapter.prototype.listenGlobal = function (target, name, callback) {
11875 return this.delegate.listen(target, name, /** @type {?} */ (callback));
11876 };
11877 /**
11878 * @param {?} renderElement
11879 * @param {?} propertyName
11880 * @param {?} propertyValue
11881 * @return {?}
11882 */
11883 RendererAdapter.prototype.setElementProperty = function (renderElement, propertyName, propertyValue) {
11884 this.delegate.setProperty(renderElement, propertyName, propertyValue);
11885 };
11886 /**
11887 * @param {?} renderElement
11888 * @param {?} namespaceAndName
11889 * @param {?} attributeValue
11890 * @return {?}
11891 */
11892 RendererAdapter.prototype.setElementAttribute = function (renderElement, namespaceAndName, attributeValue) {
11893 var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
11894 if (attributeValue != null) {
11895 this.delegate.setAttribute(renderElement, name, attributeValue, ns);
11896 }
11897 else {
11898 this.delegate.removeAttribute(renderElement, name, ns);
11899 }
11900 };
11901 /**
11902 * @param {?} renderElement
11903 * @param {?} propertyName
11904 * @param {?} propertyValue
11905 * @return {?}
11906 */
11907 RendererAdapter.prototype.setBindingDebugInfo = function (renderElement, propertyName, propertyValue) { };
11908 /**
11909 * @param {?} renderElement
11910 * @param {?} className
11911 * @param {?} isAdd
11912 * @return {?}
11913 */
11914 RendererAdapter.prototype.setElementClass = function (renderElement, className, isAdd) {
11915 if (isAdd) {
11916 this.delegate.addClass(renderElement, className);
11917 }
11918 else {
11919 this.delegate.removeClass(renderElement, className);
11920 }
11921 };
11922 /**
11923 * @param {?} renderElement
11924 * @param {?} styleName
11925 * @param {?} styleValue
11926 * @return {?}
11927 */
11928 RendererAdapter.prototype.setElementStyle = function (renderElement, styleName, styleValue) {
11929 if (styleValue != null) {
11930 this.delegate.setStyle(renderElement, styleName, styleValue);
11931 }
11932 else {
11933 this.delegate.removeStyle(renderElement, styleName);
11934 }
11935 };
11936 /**
11937 * @param {?} renderElement
11938 * @param {?} methodName
11939 * @param {?} args
11940 * @return {?}
11941 */
11942 RendererAdapter.prototype.invokeElementMethod = function (renderElement, methodName, args) {
11943 ((renderElement))[methodName].apply(renderElement, args);
11944 };
11945 /**
11946 * @param {?} renderNode
11947 * @param {?} text
11948 * @return {?}
11949 */
11950 RendererAdapter.prototype.setText = function (renderNode$$1, text) { this.delegate.setValue(renderNode$$1, text); };
11951 /**
11952 * @return {?}
11953 */
11954 RendererAdapter.prototype.animate = function () { throw new Error('Renderer.animate is no longer supported!'); };
11955 return RendererAdapter;
11956}());
11957/**
11958 * @param {?} moduleType
11959 * @param {?} parent
11960 * @param {?} bootstrapComponents
11961 * @param {?} def
11962 * @return {?}
11963 */
11964function createNgModuleRef(moduleType, parent, bootstrapComponents, def) {
11965 return new NgModuleRef_(moduleType, parent, bootstrapComponents, def);
11966}
11967var NgModuleRef_ = (function () {
11968 /**
11969 * @param {?} _moduleType
11970 * @param {?} _parent
11971 * @param {?} _bootstrapComponents
11972 * @param {?} _def
11973 */
11974 function NgModuleRef_(_moduleType, _parent, _bootstrapComponents, _def) {
11975 this._moduleType = _moduleType;
11976 this._parent = _parent;
11977 this._bootstrapComponents = _bootstrapComponents;
11978 this._def = _def;
11979 this._destroyListeners = [];
11980 this._destroyed = false;
11981 initNgModule(this);
11982 }
11983 /**
11984 * @param {?} token
11985 * @param {?=} notFoundValue
11986 * @return {?}
11987 */
11988 NgModuleRef_.prototype.get = function (token, notFoundValue) {
11989 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
11990 return resolveNgModuleDep(this, { token: token, tokenKey: tokenKey(token), flags: 0 /* None */ }, notFoundValue);
11991 };
11992 Object.defineProperty(NgModuleRef_.prototype, "instance", {
11993 /**
11994 * @return {?}
11995 */
11996 get: function () { return this.get(this._moduleType); },
11997 enumerable: true,
11998 configurable: true
11999 });
12000 Object.defineProperty(NgModuleRef_.prototype, "componentFactoryResolver", {
12001 /**
12002 * @return {?}
12003 */
12004 get: function () { return this.get(ComponentFactoryResolver); },
12005 enumerable: true,
12006 configurable: true
12007 });
12008 Object.defineProperty(NgModuleRef_.prototype, "injector", {
12009 /**
12010 * @return {?}
12011 */
12012 get: function () { return this; },
12013 enumerable: true,
12014 configurable: true
12015 });
12016 /**
12017 * @return {?}
12018 */
12019 NgModuleRef_.prototype.destroy = function () {
12020 if (this._destroyed) {
12021 throw new Error("The ng module " + stringify(this.instance.constructor) + " has already been destroyed.");
12022 }
12023 this._destroyed = true;
12024 callNgModuleLifecycle(this, 131072 /* OnDestroy */);
12025 this._destroyListeners.forEach(function (listener) { return listener(); });
12026 };
12027 /**
12028 * @param {?} callback
12029 * @return {?}
12030 */
12031 NgModuleRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
12032 return NgModuleRef_;
12033}());
12034/**
12035 * @license
12036 * Copyright Google Inc. All Rights Reserved.
12037 *
12038 * Use of this source code is governed by an MIT-style license that can be
12039 * found in the LICENSE file at https://angular.io/license
12040 */
12041var RendererV1TokenKey = tokenKey(Renderer);
12042var Renderer2TokenKey = tokenKey(Renderer2);
12043var ElementRefTokenKey = tokenKey(ElementRef);
12044var ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
12045var TemplateRefTokenKey = tokenKey(TemplateRef);
12046var ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
12047var InjectorRefTokenKey = tokenKey(Injector);
12048var NOT_CREATED = new Object();
12049/**
12050 * @param {?} flags
12051 * @param {?} matchedQueriesDsl
12052 * @param {?} childCount
12053 * @param {?} token
12054 * @param {?} value
12055 * @param {?} deps
12056 * @param {?=} bindings
12057 * @param {?=} outputs
12058 * @return {?}
12059 */
12060function _def(flags, matchedQueriesDsl, childCount, token, value, deps, bindings, outputs) {
12061 var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
12062 if (!outputs) {
12063 outputs = [];
12064 }
12065 if (!bindings) {
12066 bindings = [];
12067 }
12068 var /** @type {?} */ depDefs = splitDepsDsl(deps);
12069 return {
12070 // will bet set by the view definition
12071 index: -1,
12072 parent: null,
12073 renderParent: null,
12074 bindingIndex: -1,
12075 outputIndex: -1,
12076 // regular values
12077 flags: flags,
12078 childFlags: 0,
12079 directChildFlags: 0,
12080 childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references,
12081 ngContentIndex: -1, childCount: childCount, bindings: bindings,
12082 bindingFlags: calcBindingFlags(bindings), outputs: outputs,
12083 element: null,
12084 provider: { token: token, value: value, deps: depDefs },
12085 text: null,
12086 query: null,
12087 ngContent: null
12088 };
12089}
12090/**
12091 * @param {?} view
12092 * @param {?} def
12093 * @return {?}
12094 */
12095function createProviderInstance(view, def) {
12096 return def.flags & 4096 /* LazyProvider */ ? NOT_CREATED : _createProviderInstance(view, def);
12097}
12098/**
12099 * @param {?} view
12100 * @param {?} def
12101 * @return {?}
12102 */
12103function createPipeInstance(view, def) {
12104 // deps are looked up from component.
12105 var /** @type {?} */ compView = view;
12106 while (compView.parent && !isComponentView(compView)) {
12107 compView = compView.parent;
12108 }
12109 // pipes can see the private services of the component
12110 var /** @type {?} */ allowPrivateServices = true;
12111 // pipes are always eager and classes!
12112 return createClass(/** @type {?} */ ((compView.parent)), /** @type {?} */ ((viewParentEl(compView))), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
12113}
12114/**
12115 * @param {?} view
12116 * @param {?} def
12117 * @return {?}
12118 */
12119function createDirectiveInstance(view, def) {
12120 // components can see other private services, other directives can't.
12121 var /** @type {?} */ allowPrivateServices = (def.flags & 32768 /* Component */) > 0;
12122 // directives are always eager and classes!
12123 var /** @type {?} */ instance = createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
12124 if (def.outputs.length) {
12125 for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
12126 var /** @type {?} */ output = def.outputs[i];
12127 var /** @type {?} */ subscription = instance[((output.propName))].subscribe(eventHandlerClosure(view, /** @type {?} */ ((def.parent)).index, output.eventName)); /** @type {?} */
12128 ((view.disposables))[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
12129 }
12130 }
12131 return instance;
12132}
12133/**
12134 * @param {?} view
12135 * @param {?} index
12136 * @param {?} eventName
12137 * @return {?}
12138 */
12139function eventHandlerClosure(view, index, eventName) {
12140 return function (event) {
12141 try {
12142 return dispatchEvent(view, index, eventName, event);
12143 }
12144 catch (e) {
12145 // Attention: Don't rethrow, as it would cancel Observable subscriptions!
12146 view.root.errorHandler.handleError(e);
12147 }
12148 };
12149}
12150/**
12151 * @param {?} view
12152 * @param {?} def
12153 * @param {?} v0
12154 * @param {?} v1
12155 * @param {?} v2
12156 * @param {?} v3
12157 * @param {?} v4
12158 * @param {?} v5
12159 * @param {?} v6
12160 * @param {?} v7
12161 * @param {?} v8
12162 * @param {?} v9
12163 * @return {?}
12164 */
12165function checkAndUpdateDirectiveInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
12166 var /** @type {?} */ providerData = asProviderData(view, def.index);
12167 var /** @type {?} */ directive = providerData.instance;
12168 var /** @type {?} */ changed = false;
12169 var /** @type {?} */ changes = ((undefined));
12170 var /** @type {?} */ bindLen = def.bindings.length;
12171 if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
12172 changed = true;
12173 changes = updateProp(view, providerData, def, 0, v0, changes);
12174 }
12175 if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
12176 changed = true;
12177 changes = updateProp(view, providerData, def, 1, v1, changes);
12178 }
12179 if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
12180 changed = true;
12181 changes = updateProp(view, providerData, def, 2, v2, changes);
12182 }
12183 if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
12184 changed = true;
12185 changes = updateProp(view, providerData, def, 3, v3, changes);
12186 }
12187 if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
12188 changed = true;
12189 changes = updateProp(view, providerData, def, 4, v4, changes);
12190 }
12191 if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
12192 changed = true;
12193 changes = updateProp(view, providerData, def, 5, v5, changes);
12194 }
12195 if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
12196 changed = true;
12197 changes = updateProp(view, providerData, def, 6, v6, changes);
12198 }
12199 if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
12200 changed = true;
12201 changes = updateProp(view, providerData, def, 7, v7, changes);
12202 }
12203 if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
12204 changed = true;
12205 changes = updateProp(view, providerData, def, 8, v8, changes);
12206 }
12207 if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
12208 changed = true;
12209 changes = updateProp(view, providerData, def, 9, v9, changes);
12210 }
12211 if (changes) {
12212 directive.ngOnChanges(changes);
12213 }
12214 if ((view.state & 2 /* FirstCheck */) && (def.flags & 65536 /* OnInit */)) {
12215 directive.ngOnInit();
12216 }
12217 if (def.flags & 262144 /* DoCheck */) {
12218 directive.ngDoCheck();
12219 }
12220 return changed;
12221}
12222/**
12223 * @param {?} view
12224 * @param {?} def
12225 * @param {?} values
12226 * @return {?}
12227 */
12228function checkAndUpdateDirectiveDynamic(view, def, values) {
12229 var /** @type {?} */ providerData = asProviderData(view, def.index);
12230 var /** @type {?} */ directive = providerData.instance;
12231 var /** @type {?} */ changed = false;
12232 var /** @type {?} */ changes = ((undefined));
12233 for (var /** @type {?} */ i = 0; i < values.length; i++) {
12234 if (checkBinding(view, def, i, values[i])) {
12235 changed = true;
12236 changes = updateProp(view, providerData, def, i, values[i], changes);
12237 }
12238 }
12239 if (changes) {
12240 directive.ngOnChanges(changes);
12241 }
12242 if ((view.state & 2 /* FirstCheck */) && (def.flags & 65536 /* OnInit */)) {
12243 directive.ngOnInit();
12244 }
12245 if (def.flags & 262144 /* DoCheck */) {
12246 directive.ngDoCheck();
12247 }
12248 return changed;
12249}
12250/**
12251 * @param {?} view
12252 * @param {?} def
12253 * @return {?}
12254 */
12255function _createProviderInstance(view, def) {
12256 // private services can see other private services
12257 var /** @type {?} */ allowPrivateServices = (def.flags & 8192 /* PrivateProvider */) > 0;
12258 var /** @type {?} */ providerDef = def.provider;
12259 var /** @type {?} */ injectable;
12260 switch (def.flags & 201347067 /* Types */) {
12261 case 512 /* TypeClassProvider */:
12262 injectable = createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
12263 break;
12264 case 1024 /* TypeFactoryProvider */:
12265 injectable = callFactory(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
12266 break;
12267 case 2048 /* TypeUseExistingProvider */:
12268 injectable = resolveDep(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).deps[0]);
12269 break;
12270 case 256 /* TypeValueProvider */:
12271 injectable = ((providerDef)).value;
12272 break;
12273 }
12274 return injectable;
12275}
12276/**
12277 * @param {?} view
12278 * @param {?} elDef
12279 * @param {?} allowPrivateServices
12280 * @param {?} ctor
12281 * @param {?} deps
12282 * @return {?}
12283 */
12284function createClass(view, elDef, allowPrivateServices, ctor, deps) {
12285 var /** @type {?} */ len = deps.length;
12286 var /** @type {?} */ injectable;
12287 switch (len) {
12288 case 0:
12289 injectable = new ctor();
12290 break;
12291 case 1:
12292 injectable = new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
12293 break;
12294 case 2:
12295 injectable = new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
12296 break;
12297 case 3:
12298 injectable = new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
12299 break;
12300 default:
12301 var /** @type {?} */ depValues = new Array(len);
12302 for (var /** @type {?} */ i = 0; i < len; i++) {
12303 depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
12304 }
12305 injectable = new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
12306 }
12307 return injectable;
12308}
12309/**
12310 * @param {?} view
12311 * @param {?} elDef
12312 * @param {?} allowPrivateServices
12313 * @param {?} factory
12314 * @param {?} deps
12315 * @return {?}
12316 */
12317function callFactory(view, elDef, allowPrivateServices, factory, deps) {
12318 var /** @type {?} */ len = deps.length;
12319 var /** @type {?} */ injectable;
12320 switch (len) {
12321 case 0:
12322 injectable = factory();
12323 break;
12324 case 1:
12325 injectable = factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
12326 break;
12327 case 2:
12328 injectable = factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
12329 break;
12330 case 3:
12331 injectable = factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
12332 break;
12333 default:
12334 var /** @type {?} */ depValues = Array(len);
12335 for (var /** @type {?} */ i = 0; i < len; i++) {
12336 depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
12337 }
12338 injectable = factory.apply(void 0, depValues);
12339 }
12340 return injectable;
12341}
12342// This default value is when checking the hierarchy for a token.
12343//
12344// It means both:
12345// - the token is not provided by the current injector,
12346// - only the element injectors should be checked (ie do not check module injectors
12347//
12348// mod1
12349// /
12350// el1 mod2
12351// \ /
12352// el2
12353//
12354// When requesting el2.injector.get(token), we should check in the following order and return the
12355// first found value:
12356// - el2.injector.get(token, default)
12357// - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
12358// - mod2.injector.get(token, default)
12359var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
12360/**
12361 * @param {?} view
12362 * @param {?} elDef
12363 * @param {?} allowPrivateServices
12364 * @param {?} depDef
12365 * @param {?=} notFoundValue
12366 * @return {?}
12367 */
12368function resolveDep(view, elDef, allowPrivateServices, depDef, notFoundValue) {
12369 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
12370 if (depDef.flags & 8 /* Value */) {
12371 return depDef.token;
12372 }
12373 var /** @type {?} */ startView = view;
12374 if (depDef.flags & 2 /* Optional */) {
12375 notFoundValue = null;
12376 }
12377 var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
12378 if (tokenKey$$1 === ChangeDetectorRefTokenKey) {
12379 // directives on the same element as a component should be able to control the change detector
12380 // of that component as well.
12381 allowPrivateServices = !!(elDef && ((elDef.element)).componentView);
12382 }
12383 if (elDef && (depDef.flags & 1 /* SkipSelf */)) {
12384 allowPrivateServices = false;
12385 elDef = ((elDef.parent));
12386 }
12387 while (view) {
12388 if (elDef) {
12389 switch (tokenKey$$1) {
12390 case RendererV1TokenKey: {
12391 var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
12392 return createRendererV1(compView);
12393 }
12394 case Renderer2TokenKey: {
12395 var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
12396 return compView.renderer;
12397 }
12398 case ElementRefTokenKey:
12399 return new ElementRef(asElementData(view, elDef.index).renderElement);
12400 case ViewContainerRefTokenKey:
12401 return asElementData(view, elDef.index).viewContainer;
12402 case TemplateRefTokenKey: {
12403 if (((elDef.element)).template) {
12404 return asElementData(view, elDef.index).template;
12405 }
12406 break;
12407 }
12408 case ChangeDetectorRefTokenKey: {
12409 var /** @type {?} */ cdView = findCompView(view, elDef, allowPrivateServices);
12410 return createChangeDetectorRef(cdView);
12411 }
12412 case InjectorRefTokenKey:
12413 return createInjector(view, elDef);
12414 default:
12415 var /** @type {?} */ providerDef_1 = (((allowPrivateServices ? ((elDef.element)).allProviders : ((elDef.element)).publicProviders)))[tokenKey$$1];
12416 if (providerDef_1) {
12417 var /** @type {?} */ providerData = asProviderData(view, providerDef_1.index);
12418 if (providerData.instance === NOT_CREATED) {
12419 providerData.instance = _createProviderInstance(view, providerDef_1);
12420 }
12421 return providerData.instance;
12422 }
12423 }
12424 }
12425 allowPrivateServices = isComponentView(view);
12426 elDef = ((viewParentEl(view)));
12427 view = ((view.parent));
12428 }
12429 var /** @type {?} */ value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
12430 if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
12431 notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
12432 // Return the value from the root element injector when
12433 // - it provides it
12434 // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
12435 // - the module injector should not be checked
12436 // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
12437 return value;
12438 }
12439 return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
12440}
12441/**
12442 * @param {?} view
12443 * @param {?} elDef
12444 * @param {?} allowPrivateServices
12445 * @return {?}
12446 */
12447function findCompView(view, elDef, allowPrivateServices) {
12448 var /** @type {?} */ compView;
12449 if (allowPrivateServices) {
12450 compView = asElementData(view, elDef.index).componentView;
12451 }
12452 else {
12453 compView = view;
12454 while (compView.parent && !isComponentView(compView)) {
12455 compView = compView.parent;
12456 }
12457 }
12458 return compView;
12459}
12460/**
12461 * @param {?} view
12462 * @param {?} providerData
12463 * @param {?} def
12464 * @param {?} bindingIdx
12465 * @param {?} value
12466 * @param {?} changes
12467 * @return {?}
12468 */
12469function updateProp(view, providerData, def, bindingIdx, value, changes) {
12470 if (def.flags & 32768 /* Component */) {
12471 var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((def.parent)).index).componentView;
12472 if (compView.def.flags & 2 /* OnPush */) {
12473 compView.state |= 8 /* ChecksEnabled */;
12474 }
12475 }
12476 var /** @type {?} */ binding = def.bindings[bindingIdx];
12477 var /** @type {?} */ propName = ((binding.name));
12478 // Note: This is still safe with Closure Compiler as
12479 // the user passed in the property name as an object has to `providerDef`,
12480 // so Closure Compiler will have renamed the property correctly already.
12481 providerData.instance[propName] = value;
12482 if (def.flags & 524288 /* OnChanges */) {
12483 changes = changes || {};
12484 var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
12485 if (oldValue instanceof WrappedValue) {
12486 oldValue = oldValue.wrapped;
12487 }
12488 var /** @type {?} */ binding_1 = def.bindings[bindingIdx];
12489 changes[((binding_1.nonMinifiedName))] =
12490 new SimpleChange(oldValue, value, (view.state & 2 /* FirstCheck */) !== 0);
12491 }
12492 view.oldValues[def.bindingIndex + bindingIdx] = value;
12493 return changes;
12494}
12495/**
12496 * @param {?} view
12497 * @param {?} lifecycles
12498 * @return {?}
12499 */
12500function callLifecycleHooksChildrenFirst(view, lifecycles) {
12501 if (!(view.def.nodeFlags & lifecycles)) {
12502 return;
12503 }
12504 var /** @type {?} */ nodes = view.def.nodes;
12505 for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
12506 var /** @type {?} */ nodeDef = nodes[i];
12507 var /** @type {?} */ parent = nodeDef.parent;
12508 if (!parent && nodeDef.flags & lifecycles) {
12509 // matching root node (e.g. a pipe)
12510 callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
12511 }
12512 if ((nodeDef.childFlags & lifecycles) === 0) {
12513 // no child matches one of the lifecycles
12514 i += nodeDef.childCount;
12515 }
12516 while (parent && (parent.flags & 1 /* TypeElement */) &&
12517 i === parent.index + parent.childCount) {
12518 // last child of an element
12519 if (parent.directChildFlags & lifecycles) {
12520 callElementProvidersLifecycles(view, parent, lifecycles);
12521 }
12522 parent = parent.parent;
12523 }
12524 }
12525}
12526/**
12527 * @param {?} view
12528 * @param {?} elDef
12529 * @param {?} lifecycles
12530 * @return {?}
12531 */
12532function callElementProvidersLifecycles(view, elDef, lifecycles) {
12533 for (var /** @type {?} */ i = elDef.index + 1; i <= elDef.index + elDef.childCount; i++) {
12534 var /** @type {?} */ nodeDef = view.def.nodes[i];
12535 if (nodeDef.flags & lifecycles) {
12536 callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
12537 }
12538 // only visit direct children
12539 i += nodeDef.childCount;
12540 }
12541}
12542/**
12543 * @param {?} view
12544 * @param {?} index
12545 * @param {?} lifecycles
12546 * @return {?}
12547 */
12548function callProviderLifecycles(view, index, lifecycles) {
12549 var /** @type {?} */ provider = asProviderData(view, index).instance;
12550 if (provider === NOT_CREATED) {
12551 return;
12552 }
12553 Services.setCurrentNode(view, index);
12554 if (lifecycles & 1048576 /* AfterContentInit */) {
12555 provider.ngAfterContentInit();
12556 }
12557 if (lifecycles & 2097152 /* AfterContentChecked */) {
12558 provider.ngAfterContentChecked();
12559 }
12560 if (lifecycles & 4194304 /* AfterViewInit */) {
12561 provider.ngAfterViewInit();
12562 }
12563 if (lifecycles & 8388608 /* AfterViewChecked */) {
12564 provider.ngAfterViewChecked();
12565 }
12566 if (lifecycles & 131072 /* OnDestroy */) {
12567 provider.ngOnDestroy();
12568 }
12569}
12570/**
12571 * @return {?}
12572 */
12573function createQuery() {
12574 return new QueryList();
12575}
12576/**
12577 * @param {?} view
12578 * @return {?}
12579 */
12580function dirtyParentQueries(view) {
12581 var /** @type {?} */ queryIds = view.def.nodeMatchedQueries;
12582 while (view.parent && isEmbeddedView(view)) {
12583 var /** @type {?} */ tplDef = ((view.parentNodeDef));
12584 view = view.parent;
12585 // content queries
12586 var /** @type {?} */ end = tplDef.index + tplDef.childCount;
12587 for (var /** @type {?} */ i = 0; i <= end; i++) {
12588 var /** @type {?} */ nodeDef = view.def.nodes[i];
12589 if ((nodeDef.flags & 67108864 /* TypeContentQuery */) &&
12590 (nodeDef.flags & 536870912 /* DynamicQuery */) &&
12591 (((nodeDef.query)).filterId & queryIds) === ((nodeDef.query)).filterId) {
12592 asQueryList(view, i).setDirty();
12593 }
12594 if ((nodeDef.flags & 1 /* TypeElement */ && i + nodeDef.childCount < tplDef.index) ||
12595 !(nodeDef.childFlags & 67108864 /* TypeContentQuery */) ||
12596 !(nodeDef.childFlags & 536870912 /* DynamicQuery */)) {
12597 // skip elements that don't contain the template element or no query.
12598 i += nodeDef.childCount;
12599 }
12600 }
12601 }
12602 // view queries
12603 if (view.def.nodeFlags & 134217728 /* TypeViewQuery */) {
12604 for (var /** @type {?} */ i = 0; i < view.def.nodes.length; i++) {
12605 var /** @type {?} */ nodeDef = view.def.nodes[i];
12606 if ((nodeDef.flags & 134217728 /* TypeViewQuery */) && (nodeDef.flags & 536870912 /* DynamicQuery */)) {
12607 asQueryList(view, i).setDirty();
12608 }
12609 // only visit the root nodes
12610 i += nodeDef.childCount;
12611 }
12612 }
12613}
12614/**
12615 * @param {?} view
12616 * @param {?} nodeDef
12617 * @return {?}
12618 */
12619function checkAndUpdateQuery(view, nodeDef) {
12620 var /** @type {?} */ queryList = asQueryList(view, nodeDef.index);
12621 if (!queryList.dirty) {
12622 return;
12623 }
12624 var /** @type {?} */ directiveInstance;
12625 var /** @type {?} */ newValues = ((undefined));
12626 if (nodeDef.flags & 67108864 /* TypeContentQuery */) {
12627 var /** @type {?} */ elementDef_1 = ((((nodeDef.parent)).parent));
12628 newValues = calcQueryValues(view, elementDef_1.index, elementDef_1.index + elementDef_1.childCount, /** @type {?} */ ((nodeDef.query)), []);
12629 directiveInstance = asProviderData(view, /** @type {?} */ ((nodeDef.parent)).index).instance;
12630 }
12631 else if (nodeDef.flags & 134217728 /* TypeViewQuery */) {
12632 newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, /** @type {?} */ ((nodeDef.query)), []);
12633 directiveInstance = view.component;
12634 }
12635 queryList.reset(newValues);
12636 var /** @type {?} */ bindings = ((nodeDef.query)).bindings;
12637 var /** @type {?} */ notify = false;
12638 for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
12639 var /** @type {?} */ binding = bindings[i];
12640 var /** @type {?} */ boundValue = void 0;
12641 switch (binding.bindingType) {
12642 case 0 /* First */:
12643 boundValue = queryList.first;
12644 break;
12645 case 1 /* All */:
12646 boundValue = queryList;
12647 notify = true;
12648 break;
12649 }
12650 directiveInstance[binding.propName] = boundValue;
12651 }
12652 if (notify) {
12653 queryList.notifyOnChanges();
12654 }
12655}
12656/**
12657 * @param {?} view
12658 * @param {?} startIndex
12659 * @param {?} endIndex
12660 * @param {?} queryDef
12661 * @param {?} values
12662 * @return {?}
12663 */
12664function calcQueryValues(view, startIndex, endIndex, queryDef, values) {
12665 for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
12666 var /** @type {?} */ nodeDef = view.def.nodes[i];
12667 var /** @type {?} */ valueType = nodeDef.matchedQueries[queryDef.id];
12668 if (valueType != null) {
12669 values.push(getQueryValue(view, nodeDef, valueType));
12670 }
12671 if (nodeDef.flags & 1 /* TypeElement */ && ((nodeDef.element)).template &&
12672 (((((nodeDef.element)).template)).nodeMatchedQueries & queryDef.filterId) ===
12673 queryDef.filterId) {
12674 var /** @type {?} */ elementData = asElementData(view, i);
12675 // check embedded views that were attached at the place of their template,
12676 // but process child nodes first if some match the query (see issue #16568)
12677 if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
12678 calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
12679 i += nodeDef.childCount;
12680 }
12681 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
12682 var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
12683 for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
12684 var /** @type {?} */ embeddedView = embeddedViews[k];
12685 var /** @type {?} */ dvc = declaredViewContainer(embeddedView);
12686 if (dvc && dvc === elementData) {
12687 calcQueryValues(embeddedView, 0, embeddedView.def.nodes.length - 1, queryDef, values);
12688 }
12689 }
12690 }
12691 var /** @type {?} */ projectedViews = elementData.template._projectedViews;
12692 if (projectedViews) {
12693 for (var /** @type {?} */ k = 0; k < projectedViews.length; k++) {
12694 var /** @type {?} */ projectedView = projectedViews[k];
12695 calcQueryValues(projectedView, 0, projectedView.def.nodes.length - 1, queryDef, values);
12696 }
12697 }
12698 }
12699 if ((nodeDef.childMatchedQueries & queryDef.filterId) !== queryDef.filterId) {
12700 // if no child matches the query, skip the children.
12701 i += nodeDef.childCount;
12702 }
12703 }
12704 return values;
12705}
12706/**
12707 * @param {?} view
12708 * @param {?} nodeDef
12709 * @param {?} queryValueType
12710 * @return {?}
12711 */
12712function getQueryValue(view, nodeDef, queryValueType) {
12713 if (queryValueType != null) {
12714 // a match
12715 var /** @type {?} */ value = void 0;
12716 switch (queryValueType) {
12717 case 1 /* RenderElement */:
12718 value = asElementData(view, nodeDef.index).renderElement;
12719 break;
12720 case 0 /* ElementRef */:
12721 value = new ElementRef(asElementData(view, nodeDef.index).renderElement);
12722 break;
12723 case 2 /* TemplateRef */:
12724 value = asElementData(view, nodeDef.index).template;
12725 break;
12726 case 3 /* ViewContainerRef */:
12727 value = asElementData(view, nodeDef.index).viewContainer;
12728 break;
12729 case 4 /* Provider */:
12730 value = asProviderData(view, nodeDef.index).instance;
12731 break;
12732 }
12733 return value;
12734 }
12735}
12736/**
12737 * @param {?} view
12738 * @param {?} renderHost
12739 * @param {?} def
12740 * @return {?}
12741 */
12742function appendNgContent(view, renderHost, def) {
12743 var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
12744 if (!parentEl) {
12745 // Nothing to do if there is no parent element.
12746 return;
12747 }
12748 var /** @type {?} */ ngContentIndex = ((def.ngContent)).index;
12749 visitProjectedRenderNodes(view, ngContentIndex, 1 /* AppendChild */, parentEl, null, undefined);
12750}
12751/**
12752 * @param {?} flags
12753 * @param {?} propertyNames
12754 * @return {?}
12755 */
12756function _pureExpressionDef(flags, propertyNames) {
12757 var /** @type {?} */ bindings = new Array(propertyNames.length);
12758 for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
12759 var /** @type {?} */ prop = propertyNames[i];
12760 bindings[i] = {
12761 flags: 8 /* TypeProperty */,
12762 name: prop,
12763 ns: null,
12764 nonMinifiedName: prop,
12765 securityContext: null,
12766 suffix: null
12767 };
12768 }
12769 return {
12770 // will bet set by the view definition
12771 index: -1,
12772 parent: null,
12773 renderParent: null,
12774 bindingIndex: -1,
12775 outputIndex: -1,
12776 // regular values
12777 flags: flags,
12778 childFlags: 0,
12779 directChildFlags: 0,
12780 childMatchedQueries: 0,
12781 matchedQueries: {},
12782 matchedQueryIds: 0,
12783 references: {},
12784 ngContentIndex: -1,
12785 childCount: 0, bindings: bindings,
12786 bindingFlags: calcBindingFlags(bindings),
12787 outputs: [],
12788 element: null,
12789 provider: null,
12790 text: null,
12791 query: null,
12792 ngContent: null
12793 };
12794}
12795/**
12796 * @param {?} view
12797 * @param {?} def
12798 * @return {?}
12799 */
12800function createPureExpression(view, def) {
12801 return { value: undefined };
12802}
12803/**
12804 * @param {?} view
12805 * @param {?} def
12806 * @param {?} v0
12807 * @param {?} v1
12808 * @param {?} v2
12809 * @param {?} v3
12810 * @param {?} v4
12811 * @param {?} v5
12812 * @param {?} v6
12813 * @param {?} v7
12814 * @param {?} v8
12815 * @param {?} v9
12816 * @return {?}
12817 */
12818function checkAndUpdatePureExpressionInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
12819 var /** @type {?} */ bindings = def.bindings;
12820 var /** @type {?} */ changed = false;
12821 var /** @type {?} */ bindLen = bindings.length;
12822 if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
12823 changed = true;
12824 if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
12825 changed = true;
12826 if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
12827 changed = true;
12828 if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
12829 changed = true;
12830 if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
12831 changed = true;
12832 if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
12833 changed = true;
12834 if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
12835 changed = true;
12836 if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
12837 changed = true;
12838 if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
12839 changed = true;
12840 if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
12841 changed = true;
12842 if (changed) {
12843 var /** @type {?} */ data = asPureExpressionData(view, def.index);
12844 var /** @type {?} */ value = void 0;
12845 switch (def.flags & 201347067 /* Types */) {
12846 case 32 /* TypePureArray */:
12847 value = new Array(bindings.length);
12848 if (bindLen > 0)
12849 value[0] = v0;
12850 if (bindLen > 1)
12851 value[1] = v1;
12852 if (bindLen > 2)
12853 value[2] = v2;
12854 if (bindLen > 3)
12855 value[3] = v3;
12856 if (bindLen > 4)
12857 value[4] = v4;
12858 if (bindLen > 5)
12859 value[5] = v5;
12860 if (bindLen > 6)
12861 value[6] = v6;
12862 if (bindLen > 7)
12863 value[7] = v7;
12864 if (bindLen > 8)
12865 value[8] = v8;
12866 if (bindLen > 9)
12867 value[9] = v9;
12868 break;
12869 case 64 /* TypePureObject */:
12870 value = {};
12871 if (bindLen > 0)
12872 value[((bindings[0].name))] = v0;
12873 if (bindLen > 1)
12874 value[((bindings[1].name))] = v1;
12875 if (bindLen > 2)
12876 value[((bindings[2].name))] = v2;
12877 if (bindLen > 3)
12878 value[((bindings[3].name))] = v3;
12879 if (bindLen > 4)
12880 value[((bindings[4].name))] = v4;
12881 if (bindLen > 5)
12882 value[((bindings[5].name))] = v5;
12883 if (bindLen > 6)
12884 value[((bindings[6].name))] = v6;
12885 if (bindLen > 7)
12886 value[((bindings[7].name))] = v7;
12887 if (bindLen > 8)
12888 value[((bindings[8].name))] = v8;
12889 if (bindLen > 9)
12890 value[((bindings[9].name))] = v9;
12891 break;
12892 case 128 /* TypePurePipe */:
12893 var /** @type {?} */ pipe = v0;
12894 switch (bindLen) {
12895 case 1:
12896 value = pipe.transform(v0);
12897 break;
12898 case 2:
12899 value = pipe.transform(v1);
12900 break;
12901 case 3:
12902 value = pipe.transform(v1, v2);
12903 break;
12904 case 4:
12905 value = pipe.transform(v1, v2, v3);
12906 break;
12907 case 5:
12908 value = pipe.transform(v1, v2, v3, v4);
12909 break;
12910 case 6:
12911 value = pipe.transform(v1, v2, v3, v4, v5);
12912 break;
12913 case 7:
12914 value = pipe.transform(v1, v2, v3, v4, v5, v6);
12915 break;
12916 case 8:
12917 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7);
12918 break;
12919 case 9:
12920 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8);
12921 break;
12922 case 10:
12923 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8, v9);
12924 break;
12925 }
12926 break;
12927 }
12928 data.value = value;
12929 }
12930 return changed;
12931}
12932/**
12933 * @param {?} view
12934 * @param {?} def
12935 * @param {?} values
12936 * @return {?}
12937 */
12938function checkAndUpdatePureExpressionDynamic(view, def, values) {
12939 var /** @type {?} */ bindings = def.bindings;
12940 var /** @type {?} */ changed = false;
12941 for (var /** @type {?} */ i = 0; i < values.length; i++) {
12942 // Note: We need to loop over all values, so that
12943 // the old values are updates as well!
12944 if (checkAndUpdateBinding(view, def, i, values[i])) {
12945 changed = true;
12946 }
12947 }
12948 if (changed) {
12949 var /** @type {?} */ data = asPureExpressionData(view, def.index);
12950 var /** @type {?} */ value = void 0;
12951 switch (def.flags & 201347067 /* Types */) {
12952 case 32 /* TypePureArray */:
12953 value = values;
12954 break;
12955 case 64 /* TypePureObject */:
12956 value = {};
12957 for (var /** @type {?} */ i = 0; i < values.length; i++) {
12958 value[((bindings[i].name))] = values[i];
12959 }
12960 break;
12961 case 128 /* TypePurePipe */:
12962 var /** @type {?} */ pipe = values[0];
12963 var /** @type {?} */ params = values.slice(1);
12964 value = pipe.transform.apply(pipe, params);
12965 break;
12966 }
12967 data.value = value;
12968 }
12969 return changed;
12970}
12971/**
12972 * @param {?} view
12973 * @param {?} renderHost
12974 * @param {?} def
12975 * @return {?}
12976 */
12977function createText(view, renderHost, def) {
12978 var /** @type {?} */ renderNode$$1;
12979 var /** @type {?} */ renderer = view.renderer;
12980 renderNode$$1 = renderer.createText(/** @type {?} */ ((def.text)).prefix);
12981 var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
12982 if (parentEl) {
12983 renderer.appendChild(parentEl, renderNode$$1);
12984 }
12985 return { renderText: renderNode$$1 };
12986}
12987/**
12988 * @param {?} view
12989 * @param {?} def
12990 * @param {?} v0
12991 * @param {?} v1
12992 * @param {?} v2
12993 * @param {?} v3
12994 * @param {?} v4
12995 * @param {?} v5
12996 * @param {?} v6
12997 * @param {?} v7
12998 * @param {?} v8
12999 * @param {?} v9
13000 * @return {?}
13001 */
13002function checkAndUpdateTextInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
13003 var /** @type {?} */ changed = false;
13004 var /** @type {?} */ bindings = def.bindings;
13005 var /** @type {?} */ bindLen = bindings.length;
13006 if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
13007 changed = true;
13008 if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
13009 changed = true;
13010 if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
13011 changed = true;
13012 if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
13013 changed = true;
13014 if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
13015 changed = true;
13016 if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
13017 changed = true;
13018 if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
13019 changed = true;
13020 if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
13021 changed = true;
13022 if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
13023 changed = true;
13024 if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
13025 changed = true;
13026 if (changed) {
13027 var /** @type {?} */ value = ((def.text)).prefix;
13028 if (bindLen > 0)
13029 value += _addInterpolationPart(v0, bindings[0]);
13030 if (bindLen > 1)
13031 value += _addInterpolationPart(v1, bindings[1]);
13032 if (bindLen > 2)
13033 value += _addInterpolationPart(v2, bindings[2]);
13034 if (bindLen > 3)
13035 value += _addInterpolationPart(v3, bindings[3]);
13036 if (bindLen > 4)
13037 value += _addInterpolationPart(v4, bindings[4]);
13038 if (bindLen > 5)
13039 value += _addInterpolationPart(v5, bindings[5]);
13040 if (bindLen > 6)
13041 value += _addInterpolationPart(v6, bindings[6]);
13042 if (bindLen > 7)
13043 value += _addInterpolationPart(v7, bindings[7]);
13044 if (bindLen > 8)
13045 value += _addInterpolationPart(v8, bindings[8]);
13046 if (bindLen > 9)
13047 value += _addInterpolationPart(v9, bindings[9]);
13048 var /** @type {?} */ renderNode$$1 = asTextData(view, def.index).renderText;
13049 view.renderer.setValue(renderNode$$1, value);
13050 }
13051 return changed;
13052}
13053/**
13054 * @param {?} view
13055 * @param {?} def
13056 * @param {?} values
13057 * @return {?}
13058 */
13059function checkAndUpdateTextDynamic(view, def, values) {
13060 var /** @type {?} */ bindings = def.bindings;
13061 var /** @type {?} */ changed = false;
13062 for (var /** @type {?} */ i = 0; i < values.length; i++) {
13063 // Note: We need to loop over all values, so that
13064 // the old values are updates as well!
13065 if (checkAndUpdateBinding(view, def, i, values[i])) {
13066 changed = true;
13067 }
13068 }
13069 if (changed) {
13070 var /** @type {?} */ value = '';
13071 for (var /** @type {?} */ i = 0; i < values.length; i++) {
13072 value = value + _addInterpolationPart(values[i], bindings[i]);
13073 }
13074 value = ((def.text)).prefix + value;
13075 var /** @type {?} */ renderNode$$1 = asTextData(view, def.index).renderText;
13076 view.renderer.setValue(renderNode$$1, value);
13077 }
13078 return changed;
13079}
13080/**
13081 * @param {?} value
13082 * @param {?} binding
13083 * @return {?}
13084 */
13085function _addInterpolationPart(value, binding) {
13086 var /** @type {?} */ valueStr = value != null ? value.toString() : '';
13087 return valueStr + binding.suffix;
13088}
13089/**
13090 * @param {?} parent
13091 * @param {?} node
13092 * @param {?} nodeCount
13093 * @return {?}
13094 */
13095function validateNode(parent, node, nodeCount) {
13096 var /** @type {?} */ template = node.element && node.element.template;
13097 if (template) {
13098 if (!template.lastRenderRootNode) {
13099 throw new Error("Illegal State: Embedded templates without nodes are not allowed!");
13100 }
13101 if (template.lastRenderRootNode &&
13102 template.lastRenderRootNode.flags & 16777216 /* EmbeddedViews */) {
13103 throw new Error("Illegal State: Last root node of a template can't have embedded views, at index " + node.index + "!");
13104 }
13105 }
13106 if (node.flags & 20224 /* CatProvider */) {
13107 var /** @type {?} */ parentFlags = parent ? parent.flags : 0;
13108 if ((parentFlags & 1 /* TypeElement */) === 0) {
13109 throw new Error("Illegal State: Provider/Directive nodes need to be children of elements or anchors, at index " + node.index + "!");
13110 }
13111 }
13112 if (node.query) {
13113 if (node.flags & 67108864 /* TypeContentQuery */ &&
13114 (!parent || (parent.flags & 16384 /* TypeDirective */) === 0)) {
13115 throw new Error("Illegal State: Content Query nodes need to be children of directives, at index " + node.index + "!");
13116 }
13117 if (node.flags & 134217728 /* TypeViewQuery */ && parent) {
13118 throw new Error("Illegal State: View Query nodes have to be top level nodes, at index " + node.index + "!");
13119 }
13120 }
13121 if (node.childCount) {
13122 var /** @type {?} */ parentEnd = parent ? parent.index + parent.childCount : nodeCount - 1;
13123 if (node.index <= parentEnd && node.index + node.childCount > parentEnd) {
13124 throw new Error("Illegal State: childCount of node leads outside of parent, at index " + node.index + "!");
13125 }
13126 }
13127}
13128/**
13129 * @param {?} parent
13130 * @param {?} anchorDef
13131 * @param {?} viewDef
13132 * @param {?=} context
13133 * @return {?}
13134 */
13135function createEmbeddedView(parent, anchorDef$$1, viewDef, context) {
13136 // embedded views are seen as siblings to the anchor, so we need
13137 // to get the parent of the anchor and use it as parentIndex.
13138 var /** @type {?} */ view = createView(parent.root, parent.renderer, parent, anchorDef$$1, viewDef);
13139 initView(view, parent.component, context);
13140 createViewNodes(view);
13141 return view;
13142}
13143/**
13144 * @param {?} root
13145 * @param {?} def
13146 * @param {?=} context
13147 * @return {?}
13148 */
13149function createRootView(root, def, context) {
13150 var /** @type {?} */ view = createView(root, root.renderer, null, null, def);
13151 initView(view, context, context);
13152 createViewNodes(view);
13153 return view;
13154}
13155/**
13156 * @param {?} parentView
13157 * @param {?} nodeDef
13158 * @param {?} viewDef
13159 * @param {?} hostElement
13160 * @return {?}
13161 */
13162function createComponentView(parentView, nodeDef, viewDef, hostElement) {
13163 var /** @type {?} */ rendererType = ((nodeDef.element)).componentRendererType;
13164 var /** @type {?} */ compRenderer;
13165 if (!rendererType) {
13166 compRenderer = parentView.root.renderer;
13167 }
13168 else {
13169 compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
13170 }
13171 return createView(parentView.root, compRenderer, parentView, /** @type {?} */ ((nodeDef.element)).componentProvider, viewDef);
13172}
13173/**
13174 * @param {?} root
13175 * @param {?} renderer
13176 * @param {?} parent
13177 * @param {?} parentNodeDef
13178 * @param {?} def
13179 * @return {?}
13180 */
13181function createView(root, renderer, parent, parentNodeDef, def) {
13182 var /** @type {?} */ nodes = new Array(def.nodes.length);
13183 var /** @type {?} */ disposables = def.outputCount ? new Array(def.outputCount) : null;
13184 var /** @type {?} */ view = {
13185 def: def,
13186 parent: parent,
13187 viewContainerParent: null, parentNodeDef: parentNodeDef,
13188 context: null,
13189 component: null, nodes: nodes,
13190 state: 13 /* CatInit */, root: root, renderer: renderer,
13191 oldValues: new Array(def.bindingCount), disposables: disposables
13192 };
13193 return view;
13194}
13195/**
13196 * @param {?} view
13197 * @param {?} component
13198 * @param {?} context
13199 * @return {?}
13200 */
13201function initView(view, component, context) {
13202 view.component = component;
13203 view.context = context;
13204}
13205/**
13206 * @param {?} view
13207 * @return {?}
13208 */
13209function createViewNodes(view) {
13210 var /** @type {?} */ renderHost;
13211 if (isComponentView(view)) {
13212 var /** @type {?} */ hostDef = view.parentNodeDef;
13213 renderHost = asElementData(/** @type {?} */ ((view.parent)), /** @type {?} */ ((((hostDef)).parent)).index).renderElement;
13214 }
13215 var /** @type {?} */ def = view.def;
13216 var /** @type {?} */ nodes = view.nodes;
13217 for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
13218 var /** @type {?} */ nodeDef = def.nodes[i];
13219 Services.setCurrentNode(view, i);
13220 var /** @type {?} */ nodeData = void 0;
13221 switch (nodeDef.flags & 201347067 /* Types */) {
13222 case 1 /* TypeElement */:
13223 var /** @type {?} */ el = (createElement(view, renderHost, nodeDef));
13224 var /** @type {?} */ componentView = ((undefined));
13225 if (nodeDef.flags & 33554432 /* ComponentView */) {
13226 var /** @type {?} */ compViewDef = resolveDefinition(/** @type {?} */ ((((nodeDef.element)).componentView)));
13227 componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
13228 }
13229 listenToElementOutputs(view, componentView, nodeDef, el);
13230 nodeData = ({
13231 renderElement: el,
13232 componentView: componentView,
13233 viewContainer: null,
13234 template: /** @type {?} */ ((nodeDef.element)).template ? createTemplateData(view, nodeDef) : undefined
13235 });
13236 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
13237 nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
13238 }
13239 break;
13240 case 2 /* TypeText */:
13241 nodeData = (createText(view, renderHost, nodeDef));
13242 break;
13243 case 512 /* TypeClassProvider */:
13244 case 1024 /* TypeFactoryProvider */:
13245 case 2048 /* TypeUseExistingProvider */:
13246 case 256 /* TypeValueProvider */: {
13247 var /** @type {?} */ instance = createProviderInstance(view, nodeDef);
13248 nodeData = ({ instance: instance });
13249 break;
13250 }
13251 case 16 /* TypePipe */: {
13252 var /** @type {?} */ instance = createPipeInstance(view, nodeDef);
13253 nodeData = ({ instance: instance });
13254 break;
13255 }
13256 case 16384 /* TypeDirective */: {
13257 var /** @type {?} */ instance = createDirectiveInstance(view, nodeDef);
13258 nodeData = ({ instance: instance });
13259 if (nodeDef.flags & 32768 /* Component */) {
13260 var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((nodeDef.parent)).index).componentView;
13261 initView(compView, instance, instance);
13262 }
13263 break;
13264 }
13265 case 32 /* TypePureArray */:
13266 case 64 /* TypePureObject */:
13267 case 128 /* TypePurePipe */:
13268 nodeData = (createPureExpression(view, nodeDef));
13269 break;
13270 case 67108864 /* TypeContentQuery */:
13271 case 134217728 /* TypeViewQuery */:
13272 nodeData = (createQuery());
13273 break;
13274 case 8 /* TypeNgContent */:
13275 appendNgContent(view, renderHost, nodeDef);
13276 // no runtime data needed for NgContent...
13277 nodeData = undefined;
13278 break;
13279 }
13280 nodes[i] = nodeData;
13281 }
13282 // Create the ViewData.nodes of component views after we created everything else,
13283 // so that e.g. ng-content works
13284 execComponentViewsAction(view, ViewAction.CreateViewNodes);
13285 // fill static content and view queries
13286 execQueriesAction(view, 67108864 /* TypeContentQuery */ | 134217728 /* TypeViewQuery */, 268435456 /* StaticQuery */, 0 /* CheckAndUpdate */);
13287}
13288/**
13289 * @param {?} view
13290 * @return {?}
13291 */
13292function checkNoChangesView(view) {
13293 markProjectedViewsForCheck(view);
13294 Services.updateDirectives(view, 1 /* CheckNoChanges */);
13295 execEmbeddedViewsAction(view, ViewAction.CheckNoChanges);
13296 Services.updateRenderer(view, 1 /* CheckNoChanges */);
13297 execComponentViewsAction(view, ViewAction.CheckNoChanges);
13298 // Note: We don't check queries for changes as we didn't do this in v2.x.
13299 // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message.
13300 view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
13301}
13302/**
13303 * @param {?} view
13304 * @return {?}
13305 */
13306function checkAndUpdateView(view) {
13307 if (view.state & 1 /* BeforeFirstCheck */) {
13308 view.state &= ~1 /* BeforeFirstCheck */;
13309 view.state |= 2 /* FirstCheck */;
13310 }
13311 else {
13312 view.state &= ~2 /* FirstCheck */;
13313 }
13314 markProjectedViewsForCheck(view);
13315 Services.updateDirectives(view, 0 /* CheckAndUpdate */);
13316 execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
13317 execQueriesAction(view, 67108864 /* TypeContentQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
13318 callLifecycleHooksChildrenFirst(view, 2097152 /* AfterContentChecked */ |
13319 (view.state & 2 /* FirstCheck */ ? 1048576 /* AfterContentInit */ : 0));
13320 Services.updateRenderer(view, 0 /* CheckAndUpdate */);
13321 execComponentViewsAction(view, ViewAction.CheckAndUpdate);
13322 execQueriesAction(view, 134217728 /* TypeViewQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
13323 callLifecycleHooksChildrenFirst(view, 8388608 /* AfterViewChecked */ |
13324 (view.state & 2 /* FirstCheck */ ? 4194304 /* AfterViewInit */ : 0));
13325 if (view.def.flags & 2 /* OnPush */) {
13326 view.state &= ~8 /* ChecksEnabled */;
13327 }
13328 view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
13329}
13330/**
13331 * @param {?} view
13332 * @param {?} nodeDef
13333 * @param {?} argStyle
13334 * @param {?=} v0
13335 * @param {?=} v1
13336 * @param {?=} v2
13337 * @param {?=} v3
13338 * @param {?=} v4
13339 * @param {?=} v5
13340 * @param {?=} v6
13341 * @param {?=} v7
13342 * @param {?=} v8
13343 * @param {?=} v9
13344 * @return {?}
13345 */
13346function checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
13347 if (argStyle === 0 /* Inline */) {
13348 return checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13349 }
13350 else {
13351 return checkAndUpdateNodeDynamic(view, nodeDef, v0);
13352 }
13353}
13354/**
13355 * @param {?} view
13356 * @return {?}
13357 */
13358function markProjectedViewsForCheck(view) {
13359 var /** @type {?} */ def = view.def;
13360 if (!(def.nodeFlags & 4 /* ProjectedTemplate */)) {
13361 return;
13362 }
13363 for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
13364 var /** @type {?} */ nodeDef = def.nodes[i];
13365 if (nodeDef.flags & 4 /* ProjectedTemplate */) {
13366 var /** @type {?} */ projectedViews = asElementData(view, i).template._projectedViews;
13367 if (projectedViews) {
13368 for (var /** @type {?} */ i_1 = 0; i_1 < projectedViews.length; i_1++) {
13369 var /** @type {?} */ projectedView = projectedViews[i_1];
13370 projectedView.state |= 32 /* CheckProjectedView */;
13371 markParentViewsForCheckProjectedViews(projectedView, view);
13372 }
13373 }
13374 }
13375 else if ((nodeDef.childFlags & 4 /* ProjectedTemplate */) === 0) {
13376 // a parent with leafs
13377 // no child is a component,
13378 // then skip the children
13379 i += nodeDef.childCount;
13380 }
13381 }
13382}
13383/**
13384 * @param {?} view
13385 * @param {?} nodeDef
13386 * @param {?=} v0
13387 * @param {?=} v1
13388 * @param {?=} v2
13389 * @param {?=} v3
13390 * @param {?=} v4
13391 * @param {?=} v5
13392 * @param {?=} v6
13393 * @param {?=} v7
13394 * @param {?=} v8
13395 * @param {?=} v9
13396 * @return {?}
13397 */
13398function checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
13399 var /** @type {?} */ changed = false;
13400 switch (nodeDef.flags & 201347067 /* Types */) {
13401 case 1 /* TypeElement */:
13402 changed = checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13403 break;
13404 case 2 /* TypeText */:
13405 changed = checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13406 break;
13407 case 16384 /* TypeDirective */:
13408 changed =
13409 checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13410 break;
13411 case 32 /* TypePureArray */:
13412 case 64 /* TypePureObject */:
13413 case 128 /* TypePurePipe */:
13414 changed =
13415 checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13416 break;
13417 }
13418 return changed;
13419}
13420/**
13421 * @param {?} view
13422 * @param {?} nodeDef
13423 * @param {?} values
13424 * @return {?}
13425 */
13426function checkAndUpdateNodeDynamic(view, nodeDef, values) {
13427 var /** @type {?} */ changed = false;
13428 switch (nodeDef.flags & 201347067 /* Types */) {
13429 case 1 /* TypeElement */:
13430 changed = checkAndUpdateElementDynamic(view, nodeDef, values);
13431 break;
13432 case 2 /* TypeText */:
13433 changed = checkAndUpdateTextDynamic(view, nodeDef, values);
13434 break;
13435 case 16384 /* TypeDirective */:
13436 changed = checkAndUpdateDirectiveDynamic(view, nodeDef, values);
13437 break;
13438 case 32 /* TypePureArray */:
13439 case 64 /* TypePureObject */:
13440 case 128 /* TypePurePipe */:
13441 changed = checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
13442 break;
13443 }
13444 if (changed) {
13445 // Update oldValues after all bindings have been updated,
13446 // as a setter for a property might update other properties.
13447 var /** @type {?} */ bindLen = nodeDef.bindings.length;
13448 var /** @type {?} */ bindingStart = nodeDef.bindingIndex;
13449 var /** @type {?} */ oldValues = view.oldValues;
13450 for (var /** @type {?} */ i = 0; i < bindLen; i++) {
13451 oldValues[bindingStart + i] = values[i];
13452 }
13453 }
13454 return changed;
13455}
13456/**
13457 * @param {?} view
13458 * @param {?} nodeDef
13459 * @param {?} argStyle
13460 * @param {?=} v0
13461 * @param {?=} v1
13462 * @param {?=} v2
13463 * @param {?=} v3
13464 * @param {?=} v4
13465 * @param {?=} v5
13466 * @param {?=} v6
13467 * @param {?=} v7
13468 * @param {?=} v8
13469 * @param {?=} v9
13470 * @return {?}
13471 */
13472function checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
13473 if (argStyle === 0 /* Inline */) {
13474 checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
13475 }
13476 else {
13477 checkNoChangesNodeDynamic(view, nodeDef, v0);
13478 }
13479 // Returning false is ok here as we would have thrown in case of a change.
13480 return false;
13481}
13482/**
13483 * @param {?} view
13484 * @param {?} nodeDef
13485 * @param {?} v0
13486 * @param {?} v1
13487 * @param {?} v2
13488 * @param {?} v3
13489 * @param {?} v4
13490 * @param {?} v5
13491 * @param {?} v6
13492 * @param {?} v7
13493 * @param {?} v8
13494 * @param {?} v9
13495 * @return {?}
13496 */
13497function checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
13498 var /** @type {?} */ bindLen = nodeDef.bindings.length;
13499 if (bindLen > 0)
13500 checkBindingNoChanges(view, nodeDef, 0, v0);
13501 if (bindLen > 1)
13502 checkBindingNoChanges(view, nodeDef, 1, v1);
13503 if (bindLen > 2)
13504 checkBindingNoChanges(view, nodeDef, 2, v2);
13505 if (bindLen > 3)
13506 checkBindingNoChanges(view, nodeDef, 3, v3);
13507 if (bindLen > 4)
13508 checkBindingNoChanges(view, nodeDef, 4, v4);
13509 if (bindLen > 5)
13510 checkBindingNoChanges(view, nodeDef, 5, v5);
13511 if (bindLen > 6)
13512 checkBindingNoChanges(view, nodeDef, 6, v6);
13513 if (bindLen > 7)
13514 checkBindingNoChanges(view, nodeDef, 7, v7);
13515 if (bindLen > 8)
13516 checkBindingNoChanges(view, nodeDef, 8, v8);
13517 if (bindLen > 9)
13518 checkBindingNoChanges(view, nodeDef, 9, v9);
13519}
13520/**
13521 * @param {?} view
13522 * @param {?} nodeDef
13523 * @param {?} values
13524 * @return {?}
13525 */
13526function checkNoChangesNodeDynamic(view, nodeDef, values) {
13527 for (var /** @type {?} */ i = 0; i < values.length; i++) {
13528 checkBindingNoChanges(view, nodeDef, i, values[i]);
13529 }
13530}
13531/**
13532 * Workaround https://github.com/angular/tsickle/issues/497
13533 * @suppress {misplacedTypeAnnotation}
13534 * @param {?} view
13535 * @param {?} nodeDef
13536 * @return {?}
13537 */
13538function checkNoChangesQuery(view, nodeDef) {
13539 var /** @type {?} */ queryList = asQueryList(view, nodeDef.index);
13540 if (queryList.dirty) {
13541 throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, nodeDef.index), "Query " + ((nodeDef.query)).id + " not dirty", "Query " + ((nodeDef.query)).id + " dirty", (view.state & 1 /* BeforeFirstCheck */) !== 0);
13542 }
13543}
13544/**
13545 * @param {?} view
13546 * @return {?}
13547 */
13548function destroyView(view) {
13549 if (view.state & 128 /* Destroyed */) {
13550 return;
13551 }
13552 execEmbeddedViewsAction(view, ViewAction.Destroy);
13553 execComponentViewsAction(view, ViewAction.Destroy);
13554 callLifecycleHooksChildrenFirst(view, 131072 /* OnDestroy */);
13555 if (view.disposables) {
13556 for (var /** @type {?} */ i = 0; i < view.disposables.length; i++) {
13557 view.disposables[i]();
13558 }
13559 }
13560 detachProjectedView(view);
13561 if (view.renderer.destroyNode) {
13562 destroyViewNodes(view);
13563 }
13564 if (isComponentView(view)) {
13565 view.renderer.destroy();
13566 }
13567 view.state |= 128 /* Destroyed */;
13568}
13569/**
13570 * @param {?} view
13571 * @return {?}
13572 */
13573function destroyViewNodes(view) {
13574 var /** @type {?} */ len = view.def.nodes.length;
13575 for (var /** @type {?} */ i = 0; i < len; i++) {
13576 var /** @type {?} */ def = view.def.nodes[i];
13577 if (def.flags & 1 /* TypeElement */) {
13578 ((view.renderer.destroyNode))(asElementData(view, i).renderElement);
13579 }
13580 else if (def.flags & 2 /* TypeText */) {
13581 ((view.renderer.destroyNode))(asTextData(view, i).renderText);
13582 }
13583 else if (def.flags & 67108864 /* TypeContentQuery */ || def.flags & 134217728 /* TypeViewQuery */) {
13584 asQueryList(view, i).destroy();
13585 }
13586 }
13587}
13588var ViewAction = {};
13589ViewAction.CreateViewNodes = 0;
13590ViewAction.CheckNoChanges = 1;
13591ViewAction.CheckNoChangesProjectedViews = 2;
13592ViewAction.CheckAndUpdate = 3;
13593ViewAction.CheckAndUpdateProjectedViews = 4;
13594ViewAction.Destroy = 5;
13595ViewAction[ViewAction.CreateViewNodes] = "CreateViewNodes";
13596ViewAction[ViewAction.CheckNoChanges] = "CheckNoChanges";
13597ViewAction[ViewAction.CheckNoChangesProjectedViews] = "CheckNoChangesProjectedViews";
13598ViewAction[ViewAction.CheckAndUpdate] = "CheckAndUpdate";
13599ViewAction[ViewAction.CheckAndUpdateProjectedViews] = "CheckAndUpdateProjectedViews";
13600ViewAction[ViewAction.Destroy] = "Destroy";
13601/**
13602 * @param {?} view
13603 * @param {?} action
13604 * @return {?}
13605 */
13606function execComponentViewsAction(view, action) {
13607 var /** @type {?} */ def = view.def;
13608 if (!(def.nodeFlags & 33554432 /* ComponentView */)) {
13609 return;
13610 }
13611 for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
13612 var /** @type {?} */ nodeDef = def.nodes[i];
13613 if (nodeDef.flags & 33554432 /* ComponentView */) {
13614 // a leaf
13615 callViewAction(asElementData(view, i).componentView, action);
13616 }
13617 else if ((nodeDef.childFlags & 33554432 /* ComponentView */) === 0) {
13618 // a parent with leafs
13619 // no child is a component,
13620 // then skip the children
13621 i += nodeDef.childCount;
13622 }
13623 }
13624}
13625/**
13626 * @param {?} view
13627 * @param {?} action
13628 * @return {?}
13629 */
13630function execEmbeddedViewsAction(view, action) {
13631 var /** @type {?} */ def = view.def;
13632 if (!(def.nodeFlags & 16777216 /* EmbeddedViews */)) {
13633 return;
13634 }
13635 for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
13636 var /** @type {?} */ nodeDef = def.nodes[i];
13637 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
13638 // a leaf
13639 var /** @type {?} */ embeddedViews = ((asElementData(view, i).viewContainer))._embeddedViews;
13640 for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
13641 callViewAction(embeddedViews[k], action);
13642 }
13643 }
13644 else if ((nodeDef.childFlags & 16777216 /* EmbeddedViews */) === 0) {
13645 // a parent with leafs
13646 // no child is a component,
13647 // then skip the children
13648 i += nodeDef.childCount;
13649 }
13650 }
13651}
13652/**
13653 * @param {?} view
13654 * @param {?} action
13655 * @return {?}
13656 */
13657function callViewAction(view, action) {
13658 var /** @type {?} */ viewState = view.state;
13659 switch (action) {
13660 case ViewAction.CheckNoChanges:
13661 if ((viewState & 128 /* Destroyed */) === 0) {
13662 if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
13663 checkNoChangesView(view);
13664 }
13665 else if (viewState & 64 /* CheckProjectedViews */) {
13666 execProjectedViewsAction(view, ViewAction.CheckNoChangesProjectedViews);
13667 }
13668 }
13669 break;
13670 case ViewAction.CheckNoChangesProjectedViews:
13671 if ((viewState & 128 /* Destroyed */) === 0) {
13672 if (viewState & 32 /* CheckProjectedView */) {
13673 checkNoChangesView(view);
13674 }
13675 else if (viewState & 64 /* CheckProjectedViews */) {
13676 execProjectedViewsAction(view, action);
13677 }
13678 }
13679 break;
13680 case ViewAction.CheckAndUpdate:
13681 if ((viewState & 128 /* Destroyed */) === 0) {
13682 if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
13683 checkAndUpdateView(view);
13684 }
13685 else if (viewState & 64 /* CheckProjectedViews */) {
13686 execProjectedViewsAction(view, ViewAction.CheckAndUpdateProjectedViews);
13687 }
13688 }
13689 break;
13690 case ViewAction.CheckAndUpdateProjectedViews:
13691 if ((viewState & 128 /* Destroyed */) === 0) {
13692 if (viewState & 32 /* CheckProjectedView */) {
13693 checkAndUpdateView(view);
13694 }
13695 else if (viewState & 64 /* CheckProjectedViews */) {
13696 execProjectedViewsAction(view, action);
13697 }
13698 }
13699 break;
13700 case ViewAction.Destroy:
13701 // Note: destroyView recurses over all views,
13702 // so we don't need to special case projected views here.
13703 destroyView(view);
13704 break;
13705 case ViewAction.CreateViewNodes:
13706 createViewNodes(view);
13707 break;
13708 }
13709}
13710/**
13711 * @param {?} view
13712 * @param {?} action
13713 * @return {?}
13714 */
13715function execProjectedViewsAction(view, action) {
13716 execEmbeddedViewsAction(view, action);
13717 execComponentViewsAction(view, action);
13718}
13719/**
13720 * @param {?} view
13721 * @param {?} queryFlags
13722 * @param {?} staticDynamicQueryFlag
13723 * @param {?} checkType
13724 * @return {?}
13725 */
13726function execQueriesAction(view, queryFlags, staticDynamicQueryFlag, checkType) {
13727 if (!(view.def.nodeFlags & queryFlags) || !(view.def.nodeFlags & staticDynamicQueryFlag)) {
13728 return;
13729 }
13730 var /** @type {?} */ nodeCount = view.def.nodes.length;
13731 for (var /** @type {?} */ i = 0; i < nodeCount; i++) {
13732 var /** @type {?} */ nodeDef = view.def.nodes[i];
13733 if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
13734 Services.setCurrentNode(view, nodeDef.index);
13735 switch (checkType) {
13736 case 0 /* CheckAndUpdate */:
13737 checkAndUpdateQuery(view, nodeDef);
13738 break;
13739 case 1 /* CheckNoChanges */:
13740 checkNoChangesQuery(view, nodeDef);
13741 break;
13742 }
13743 }
13744 if (!(nodeDef.childFlags & queryFlags) || !(nodeDef.childFlags & staticDynamicQueryFlag)) {
13745 // no child has a matching query
13746 // then skip the children
13747 i += nodeDef.childCount;
13748 }
13749 }
13750}
13751/**
13752 * @license
13753 * Copyright Google Inc. All Rights Reserved.
13754 *
13755 * Use of this source code is governed by an MIT-style license that can be
13756 * found in the LICENSE file at https://angular.io/license
13757 */
13758var initialized = false;
13759/**
13760 * @return {?}
13761 */
13762function initServicesIfNeeded() {
13763 if (initialized) {
13764 return;
13765 }
13766 initialized = true;
13767 var /** @type {?} */ services = isDevMode() ? createDebugServices() : createProdServices();
13768 Services.setCurrentNode = services.setCurrentNode;
13769 Services.createRootView = services.createRootView;
13770 Services.createEmbeddedView = services.createEmbeddedView;
13771 Services.createComponentView = services.createComponentView;
13772 Services.createNgModuleRef = services.createNgModuleRef;
13773 Services.overrideProvider = services.overrideProvider;
13774 Services.clearProviderOverrides = services.clearProviderOverrides;
13775 Services.checkAndUpdateView = services.checkAndUpdateView;
13776 Services.checkNoChangesView = services.checkNoChangesView;
13777 Services.destroyView = services.destroyView;
13778 Services.resolveDep = resolveDep;
13779 Services.createDebugContext = services.createDebugContext;
13780 Services.handleEvent = services.handleEvent;
13781 Services.updateDirectives = services.updateDirectives;
13782 Services.updateRenderer = services.updateRenderer;
13783 Services.dirtyParentQueries = dirtyParentQueries;
13784}
13785/**
13786 * @return {?}
13787 */
13788function createProdServices() {
13789 return {
13790 setCurrentNode: function () { },
13791 createRootView: createProdRootView,
13792 createEmbeddedView: createEmbeddedView,
13793 createComponentView: createComponentView,
13794 createNgModuleRef: createNgModuleRef,
13795 overrideProvider: NOOP,
13796 clearProviderOverrides: NOOP,
13797 checkAndUpdateView: checkAndUpdateView,
13798 checkNoChangesView: checkNoChangesView,
13799 destroyView: destroyView,
13800 createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
13801 handleEvent: function (view, nodeIndex, eventName, event) { return view.def.handleEvent(view, nodeIndex, eventName, event); },
13802 updateDirectives: function (view, checkType) { return view.def.updateDirectives(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
13803 prodCheckNoChangesNode, view); },
13804 updateRenderer: function (view, checkType) { return view.def.updateRenderer(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
13805 prodCheckNoChangesNode, view); },
13806 };
13807}
13808/**
13809 * @return {?}
13810 */
13811function createDebugServices() {
13812 return {
13813 setCurrentNode: debugSetCurrentNode,
13814 createRootView: debugCreateRootView,
13815 createEmbeddedView: debugCreateEmbeddedView,
13816 createComponentView: debugCreateComponentView,
13817 createNgModuleRef: debugCreateNgModuleRef,
13818 overrideProvider: debugOverrideProvider,
13819 clearProviderOverrides: debugClearProviderOverrides,
13820 checkAndUpdateView: debugCheckAndUpdateView,
13821 checkNoChangesView: debugCheckNoChangesView,
13822 destroyView: debugDestroyView,
13823 createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
13824 handleEvent: debugHandleEvent,
13825 updateDirectives: debugUpdateDirectives,
13826 updateRenderer: debugUpdateRenderer,
13827 };
13828}
13829/**
13830 * @param {?} elInjector
13831 * @param {?} projectableNodes
13832 * @param {?} rootSelectorOrNode
13833 * @param {?} def
13834 * @param {?} ngModule
13835 * @param {?=} context
13836 * @return {?}
13837 */
13838function createProdRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
13839 var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
13840 return createRootView(createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode), def, context);
13841}
13842/**
13843 * @param {?} elInjector
13844 * @param {?} projectableNodes
13845 * @param {?} rootSelectorOrNode
13846 * @param {?} def
13847 * @param {?} ngModule
13848 * @param {?=} context
13849 * @return {?}
13850 */
13851function debugCreateRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
13852 var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
13853 var /** @type {?} */ root = createRootData(elInjector, ngModule, new DebugRendererFactory2(rendererFactory), projectableNodes, rootSelectorOrNode);
13854 var /** @type {?} */ defWithOverride = applyProviderOverridesToView(def);
13855 return callWithDebugContext(DebugAction.create, createRootView, null, [root, defWithOverride, context]);
13856}
13857/**
13858 * @param {?} elInjector
13859 * @param {?} ngModule
13860 * @param {?} rendererFactory
13861 * @param {?} projectableNodes
13862 * @param {?} rootSelectorOrNode
13863 * @return {?}
13864 */
13865function createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode) {
13866 var /** @type {?} */ sanitizer = ngModule.injector.get(Sanitizer);
13867 var /** @type {?} */ errorHandler = ngModule.injector.get(ErrorHandler);
13868 var /** @type {?} */ renderer = rendererFactory.createRenderer(null, null);
13869 return {
13870 ngModule: ngModule,
13871 injector: elInjector, projectableNodes: projectableNodes,
13872 selectorOrNode: rootSelectorOrNode, sanitizer: sanitizer, rendererFactory: rendererFactory, renderer: renderer, errorHandler: errorHandler
13873 };
13874}
13875/**
13876 * @param {?} parentView
13877 * @param {?} anchorDef
13878 * @param {?} viewDef
13879 * @param {?=} context
13880 * @return {?}
13881 */
13882function debugCreateEmbeddedView(parentView, anchorDef, viewDef$$1, context) {
13883 var /** @type {?} */ defWithOverride = applyProviderOverridesToView(viewDef$$1);
13884 return callWithDebugContext(DebugAction.create, createEmbeddedView, null, [parentView, anchorDef, defWithOverride, context]);
13885}
13886/**
13887 * @param {?} parentView
13888 * @param {?} nodeDef
13889 * @param {?} viewDef
13890 * @param {?} hostElement
13891 * @return {?}
13892 */
13893function debugCreateComponentView(parentView, nodeDef, viewDef$$1, hostElement) {
13894 var /** @type {?} */ defWithOverride = applyProviderOverridesToView(viewDef$$1);
13895 return callWithDebugContext(DebugAction.create, createComponentView, null, [parentView, nodeDef, defWithOverride, hostElement]);
13896}
13897/**
13898 * @param {?} moduleType
13899 * @param {?} parentInjector
13900 * @param {?} bootstrapComponents
13901 * @param {?} def
13902 * @return {?}
13903 */
13904function debugCreateNgModuleRef(moduleType, parentInjector, bootstrapComponents, def) {
13905 var /** @type {?} */ defWithOverride = applyProviderOverridesToNgModule(def);
13906 return createNgModuleRef(moduleType, parentInjector, bootstrapComponents, defWithOverride);
13907}
13908var providerOverrides = new Map();
13909/**
13910 * @param {?} override
13911 * @return {?}
13912 */
13913function debugOverrideProvider(override) {
13914 providerOverrides.set(override.token, override);
13915}
13916/**
13917 * @return {?}
13918 */
13919function debugClearProviderOverrides() {
13920 providerOverrides.clear();
13921}
13922/**
13923 * @param {?} def
13924 * @return {?}
13925 */
13926function applyProviderOverridesToView(def) {
13927 if (providerOverrides.size === 0) {
13928 return def;
13929 }
13930 var /** @type {?} */ elementIndicesWithOverwrittenProviders = findElementIndicesWithOverwrittenProviders(def);
13931 if (elementIndicesWithOverwrittenProviders.length === 0) {
13932 return def;
13933 }
13934 // clone the whole view definition,
13935 // as it maintains references between the nodes that are hard to update.
13936 def = ((def.factory))(function () { return NOOP; });
13937 for (var /** @type {?} */ i = 0; i < elementIndicesWithOverwrittenProviders.length; i++) {
13938 applyProviderOverridesToElement(def, elementIndicesWithOverwrittenProviders[i]);
13939 }
13940 return def;
13941 /**
13942 * @param {?} def
13943 * @return {?}
13944 */
13945 function findElementIndicesWithOverwrittenProviders(def) {
13946 var /** @type {?} */ elIndicesWithOverwrittenProviders = [];
13947 var /** @type {?} */ lastElementDef = null;
13948 for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
13949 var /** @type {?} */ nodeDef = def.nodes[i];
13950 if (nodeDef.flags & 1 /* TypeElement */) {
13951 lastElementDef = nodeDef;
13952 }
13953 if (lastElementDef && nodeDef.flags & 3840 /* CatProviderNoDirective */ &&
13954 providerOverrides.has(/** @type {?} */ ((nodeDef.provider)).token)) {
13955 elIndicesWithOverwrittenProviders.push(/** @type {?} */ ((lastElementDef)).index);
13956 lastElementDef = null;
13957 }
13958 }
13959 return elIndicesWithOverwrittenProviders;
13960 }
13961 /**
13962 * @param {?} viewDef
13963 * @param {?} elIndex
13964 * @return {?}
13965 */
13966 function applyProviderOverridesToElement(viewDef$$1, elIndex) {
13967 for (var /** @type {?} */ i = elIndex + 1; i < viewDef$$1.nodes.length; i++) {
13968 var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
13969 if (nodeDef.flags & 1 /* TypeElement */) {
13970 // stop at the next element
13971 return;
13972 }
13973 if (nodeDef.flags & 3840 /* CatProviderNoDirective */) {
13974 // Make all providers lazy, so that we don't get into trouble
13975 // with ordering problems of providers on the same element
13976 nodeDef.flags |= 4096 /* LazyProvider */;
13977 var /** @type {?} */ provider = ((nodeDef.provider));
13978 var /** @type {?} */ override = providerOverrides.get(provider.token);
13979 if (override) {
13980 nodeDef.flags = (nodeDef.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
13981 provider.deps = splitDepsDsl(override.deps);
13982 provider.value = override.value;
13983 }
13984 }
13985 }
13986 }
13987}
13988/**
13989 * @param {?} def
13990 * @return {?}
13991 */
13992function applyProviderOverridesToNgModule(def) {
13993 if (providerOverrides.size === 0 || !hasOverrrides(def)) {
13994 return def;
13995 }
13996 // clone the whole view definition,
13997 // as it maintains references between the nodes that are hard to update.
13998 def = ((def.factory))(function () { return NOOP; });
13999 applyProviderOverrides(def);
14000 return def;
14001 /**
14002 * @param {?} def
14003 * @return {?}
14004 */
14005 function hasOverrrides(def) {
14006 return def.providers.some(function (node) { return !!(node.flags & 3840 /* CatProviderNoDirective */) && providerOverrides.has(node.token); });
14007 }
14008 /**
14009 * @param {?} def
14010 * @return {?}
14011 */
14012 function applyProviderOverrides(def) {
14013 for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
14014 var /** @type {?} */ provider = def.providers[i];
14015 // Make all providers lazy, so that we don't get into trouble
14016 // with ordering problems of providers on the same element
14017 provider.flags |= 4096 /* LazyProvider */;
14018 var /** @type {?} */ override = providerOverrides.get(provider.token);
14019 if (override) {
14020 provider.flags = (provider.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
14021 provider.deps = splitDepsDsl(override.deps);
14022 provider.value = override.value;
14023 }
14024 }
14025 }
14026}
14027/**
14028 * @param {?} view
14029 * @param {?} nodeIndex
14030 * @param {?} argStyle
14031 * @param {?=} v0
14032 * @param {?=} v1
14033 * @param {?=} v2
14034 * @param {?=} v3
14035 * @param {?=} v4
14036 * @param {?=} v5
14037 * @param {?=} v6
14038 * @param {?=} v7
14039 * @param {?=} v8
14040 * @param {?=} v9
14041 * @return {?}
14042 */
14043function prodCheckAndUpdateNode(view, nodeIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
14044 var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
14045 checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
14046 return (nodeDef.flags & 224 /* CatPureExpression */) ?
14047 asPureExpressionData(view, nodeIndex).value :
14048 undefined;
14049}
14050/**
14051 * @param {?} view
14052 * @param {?} nodeIndex
14053 * @param {?} argStyle
14054 * @param {?=} v0
14055 * @param {?=} v1
14056 * @param {?=} v2
14057 * @param {?=} v3
14058 * @param {?=} v4
14059 * @param {?=} v5
14060 * @param {?=} v6
14061 * @param {?=} v7
14062 * @param {?=} v8
14063 * @param {?=} v9
14064 * @return {?}
14065 */
14066function prodCheckNoChangesNode(view, nodeIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
14067 var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
14068 checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
14069 return (nodeDef.flags & 224 /* CatPureExpression */) ?
14070 asPureExpressionData(view, nodeIndex).value :
14071 undefined;
14072}
14073/**
14074 * @param {?} view
14075 * @return {?}
14076 */
14077function debugCheckAndUpdateView(view) {
14078 return callWithDebugContext(DebugAction.detectChanges, checkAndUpdateView, null, [view]);
14079}
14080/**
14081 * @param {?} view
14082 * @return {?}
14083 */
14084function debugCheckNoChangesView(view) {
14085 return callWithDebugContext(DebugAction.checkNoChanges, checkNoChangesView, null, [view]);
14086}
14087/**
14088 * @param {?} view
14089 * @return {?}
14090 */
14091function debugDestroyView(view) {
14092 return callWithDebugContext(DebugAction.destroy, destroyView, null, [view]);
14093}
14094var DebugAction = {};
14095DebugAction.create = 0;
14096DebugAction.detectChanges = 1;
14097DebugAction.checkNoChanges = 2;
14098DebugAction.destroy = 3;
14099DebugAction.handleEvent = 4;
14100DebugAction[DebugAction.create] = "create";
14101DebugAction[DebugAction.detectChanges] = "detectChanges";
14102DebugAction[DebugAction.checkNoChanges] = "checkNoChanges";
14103DebugAction[DebugAction.destroy] = "destroy";
14104DebugAction[DebugAction.handleEvent] = "handleEvent";
14105var _currentAction;
14106var _currentView;
14107var _currentNodeIndex;
14108/**
14109 * @param {?} view
14110 * @param {?} nodeIndex
14111 * @return {?}
14112 */
14113function debugSetCurrentNode(view, nodeIndex) {
14114 _currentView = view;
14115 _currentNodeIndex = nodeIndex;
14116}
14117/**
14118 * @param {?} view
14119 * @param {?} nodeIndex
14120 * @param {?} eventName
14121 * @param {?} event
14122 * @return {?}
14123 */
14124function debugHandleEvent(view, nodeIndex, eventName, event) {
14125 debugSetCurrentNode(view, nodeIndex);
14126 return callWithDebugContext(DebugAction.handleEvent, view.def.handleEvent, null, [view, nodeIndex, eventName, event]);
14127}
14128/**
14129 * @param {?} view
14130 * @param {?} checkType
14131 * @return {?}
14132 */
14133function debugUpdateDirectives(view, checkType) {
14134 if (view.state & 128 /* Destroyed */) {
14135 throw viewDestroyedError(DebugAction[_currentAction]);
14136 }
14137 debugSetCurrentNode(view, nextDirectiveWithBinding(view, 0));
14138 return view.def.updateDirectives(debugCheckDirectivesFn, view);
14139 /**
14140 * @param {?} view
14141 * @param {?} nodeIndex
14142 * @param {?} argStyle
14143 * @param {...?} values
14144 * @return {?}
14145 */
14146 function debugCheckDirectivesFn(view, nodeIndex, argStyle) {
14147 var values = [];
14148 for (var _i = 3; _i < arguments.length; _i++) {
14149 values[_i - 3] = arguments[_i];
14150 }
14151 var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
14152 if (checkType === 0 /* CheckAndUpdate */) {
14153 debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
14154 }
14155 else {
14156 debugCheckNoChangesNode(view, nodeDef, argStyle, values);
14157 }
14158 if (nodeDef.flags & 16384 /* TypeDirective */) {
14159 debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
14160 }
14161 return (nodeDef.flags & 224 /* CatPureExpression */) ?
14162 asPureExpressionData(view, nodeDef.index).value :
14163 undefined;
14164 }
14165}
14166/**
14167 * @param {?} view
14168 * @param {?} checkType
14169 * @return {?}
14170 */
14171function debugUpdateRenderer(view, checkType) {
14172 if (view.state & 128 /* Destroyed */) {
14173 throw viewDestroyedError(DebugAction[_currentAction]);
14174 }
14175 debugSetCurrentNode(view, nextRenderNodeWithBinding(view, 0));
14176 return view.def.updateRenderer(debugCheckRenderNodeFn, view);
14177 /**
14178 * @param {?} view
14179 * @param {?} nodeIndex
14180 * @param {?} argStyle
14181 * @param {...?} values
14182 * @return {?}
14183 */
14184 function debugCheckRenderNodeFn(view, nodeIndex, argStyle) {
14185 var values = [];
14186 for (var _i = 3; _i < arguments.length; _i++) {
14187 values[_i - 3] = arguments[_i];
14188 }
14189 var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
14190 if (checkType === 0 /* CheckAndUpdate */) {
14191 debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
14192 }
14193 else {
14194 debugCheckNoChangesNode(view, nodeDef, argStyle, values);
14195 }
14196 if (nodeDef.flags & 3 /* CatRenderNode */) {
14197 debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
14198 }
14199 return (nodeDef.flags & 224 /* CatPureExpression */) ?
14200 asPureExpressionData(view, nodeDef.index).value :
14201 undefined;
14202 }
14203}
14204/**
14205 * @param {?} view
14206 * @param {?} nodeDef
14207 * @param {?} argStyle
14208 * @param {?} givenValues
14209 * @return {?}
14210 */
14211function debugCheckAndUpdateNode(view, nodeDef, argStyle, givenValues) {
14212 var /** @type {?} */ changed = ((checkAndUpdateNode)).apply(void 0, [view, nodeDef, argStyle].concat(givenValues));
14213 if (changed) {
14214 var /** @type {?} */ values = argStyle === 1 /* Dynamic */ ? givenValues[0] : givenValues;
14215 if (nodeDef.flags & 16384 /* TypeDirective */) {
14216 var /** @type {?} */ bindingValues = {};
14217 for (var /** @type {?} */ i = 0; i < nodeDef.bindings.length; i++) {
14218 var /** @type {?} */ binding = nodeDef.bindings[i];
14219 var /** @type {?} */ value = values[i];
14220 if (binding.flags & 8 /* TypeProperty */) {
14221 bindingValues[normalizeDebugBindingName(/** @type {?} */ ((binding.nonMinifiedName)))] =
14222 normalizeDebugBindingValue(value);
14223 }
14224 }
14225 var /** @type {?} */ elDef = ((nodeDef.parent));
14226 var /** @type {?} */ el = asElementData(view, elDef.index).renderElement;
14227 if (!((elDef.element)).name) {
14228 // a comment.
14229 view.renderer.setValue(el, "bindings=" + JSON.stringify(bindingValues, null, 2));
14230 }
14231 else {
14232 // a regular element.
14233 for (var /** @type {?} */ attr in bindingValues) {
14234 var /** @type {?} */ value = bindingValues[attr];
14235 if (value != null) {
14236 view.renderer.setAttribute(el, attr, value);
14237 }
14238 else {
14239 view.renderer.removeAttribute(el, attr);
14240 }
14241 }
14242 }
14243 }
14244 }
14245}
14246/**
14247 * @param {?} view
14248 * @param {?} nodeDef
14249 * @param {?} argStyle
14250 * @param {?} values
14251 * @return {?}
14252 */
14253function debugCheckNoChangesNode(view, nodeDef, argStyle, values) {
14254 ((checkNoChangesNode)).apply(void 0, [view, nodeDef, argStyle].concat(values));
14255}
14256/**
14257 * @param {?} name
14258 * @return {?}
14259 */
14260function normalizeDebugBindingName(name) {
14261 // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
14262 name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
14263 return "ng-reflect-" + name;
14264}
14265var CAMEL_CASE_REGEXP = /([A-Z])/g;
14266/**
14267 * @param {?} input
14268 * @return {?}
14269 */
14270function camelCaseToDashCase(input) {
14271 return input.replace(CAMEL_CASE_REGEXP, function () {
14272 var m = [];
14273 for (var _i = 0; _i < arguments.length; _i++) {
14274 m[_i] = arguments[_i];
14275 }
14276 return '-' + m[1].toLowerCase();
14277 });
14278}
14279/**
14280 * @param {?} value
14281 * @return {?}
14282 */
14283function normalizeDebugBindingValue(value) {
14284 try {
14285 // Limit the size of the value as otherwise the DOM just gets polluted.
14286 return value != null ? value.toString().slice(0, 30) : value;
14287 }
14288 catch (e) {
14289 return '[ERROR] Exception while trying to serialize the value';
14290 }
14291}
14292/**
14293 * @param {?} view
14294 * @param {?} nodeIndex
14295 * @return {?}
14296 */
14297function nextDirectiveWithBinding(view, nodeIndex) {
14298 for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
14299 var /** @type {?} */ nodeDef = view.def.nodes[i];
14300 if (nodeDef.flags & 16384 /* TypeDirective */ && nodeDef.bindings && nodeDef.bindings.length) {
14301 return i;
14302 }
14303 }
14304 return null;
14305}
14306/**
14307 * @param {?} view
14308 * @param {?} nodeIndex
14309 * @return {?}
14310 */
14311function nextRenderNodeWithBinding(view, nodeIndex) {
14312 for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
14313 var /** @type {?} */ nodeDef = view.def.nodes[i];
14314 if ((nodeDef.flags & 3 /* CatRenderNode */) && nodeDef.bindings && nodeDef.bindings.length) {
14315 return i;
14316 }
14317 }
14318 return null;
14319}
14320var DebugContext_ = (function () {
14321 /**
14322 * @param {?} view
14323 * @param {?} nodeIndex
14324 */
14325 function DebugContext_(view, nodeIndex) {
14326 this.view = view;
14327 this.nodeIndex = nodeIndex;
14328 if (nodeIndex == null) {
14329 this.nodeIndex = nodeIndex = 0;
14330 }
14331 this.nodeDef = view.def.nodes[nodeIndex];
14332 var elDef = this.nodeDef;
14333 var elView = view;
14334 while (elDef && (elDef.flags & 1 /* TypeElement */) === 0) {
14335 elDef = elDef.parent;
14336 }
14337 if (!elDef) {
14338 while (!elDef && elView) {
14339 elDef = viewParentEl(elView);
14340 elView = elView.parent;
14341 }
14342 }
14343 this.elDef = elDef;
14344 this.elView = elView;
14345 }
14346 Object.defineProperty(DebugContext_.prototype, "elOrCompView", {
14347 /**
14348 * @return {?}
14349 */
14350 get: function () {
14351 // Has to be done lazily as we use the DebugContext also during creation of elements...
14352 return asElementData(this.elView, this.elDef.index).componentView || this.view;
14353 },
14354 enumerable: true,
14355 configurable: true
14356 });
14357 Object.defineProperty(DebugContext_.prototype, "injector", {
14358 /**
14359 * @return {?}
14360 */
14361 get: function () { return createInjector(this.elView, this.elDef); },
14362 enumerable: true,
14363 configurable: true
14364 });
14365 Object.defineProperty(DebugContext_.prototype, "component", {
14366 /**
14367 * @return {?}
14368 */
14369 get: function () { return this.elOrCompView.component; },
14370 enumerable: true,
14371 configurable: true
14372 });
14373 Object.defineProperty(DebugContext_.prototype, "context", {
14374 /**
14375 * @return {?}
14376 */
14377 get: function () { return this.elOrCompView.context; },
14378 enumerable: true,
14379 configurable: true
14380 });
14381 Object.defineProperty(DebugContext_.prototype, "providerTokens", {
14382 /**
14383 * @return {?}
14384 */
14385 get: function () {
14386 var /** @type {?} */ tokens = [];
14387 if (this.elDef) {
14388 for (var /** @type {?} */ i = this.elDef.index + 1; i <= this.elDef.index + this.elDef.childCount; i++) {
14389 var /** @type {?} */ childDef = this.elView.def.nodes[i];
14390 if (childDef.flags & 20224 /* CatProvider */) {
14391 tokens.push(/** @type {?} */ ((childDef.provider)).token);
14392 }
14393 i += childDef.childCount;
14394 }
14395 }
14396 return tokens;
14397 },
14398 enumerable: true,
14399 configurable: true
14400 });
14401 Object.defineProperty(DebugContext_.prototype, "references", {
14402 /**
14403 * @return {?}
14404 */
14405 get: function () {
14406 var /** @type {?} */ references = {};
14407 if (this.elDef) {
14408 collectReferences(this.elView, this.elDef, references);
14409 for (var /** @type {?} */ i = this.elDef.index + 1; i <= this.elDef.index + this.elDef.childCount; i++) {
14410 var /** @type {?} */ childDef = this.elView.def.nodes[i];
14411 if (childDef.flags & 20224 /* CatProvider */) {
14412 collectReferences(this.elView, childDef, references);
14413 }
14414 i += childDef.childCount;
14415 }
14416 }
14417 return references;
14418 },
14419 enumerable: true,
14420 configurable: true
14421 });
14422 Object.defineProperty(DebugContext_.prototype, "componentRenderElement", {
14423 /**
14424 * @return {?}
14425 */
14426 get: function () {
14427 var /** @type {?} */ elData = findHostElement(this.elOrCompView);
14428 return elData ? elData.renderElement : undefined;
14429 },
14430 enumerable: true,
14431 configurable: true
14432 });
14433 Object.defineProperty(DebugContext_.prototype, "renderNode", {
14434 /**
14435 * @return {?}
14436 */
14437 get: function () {
14438 return this.nodeDef.flags & 2 /* TypeText */ ? renderNode(this.view, this.nodeDef) :
14439 renderNode(this.elView, this.elDef);
14440 },
14441 enumerable: true,
14442 configurable: true
14443 });
14444 /**
14445 * @param {?} console
14446 * @param {...?} values
14447 * @return {?}
14448 */
14449 DebugContext_.prototype.logError = function (console) {
14450 var values = [];
14451 for (var _i = 1; _i < arguments.length; _i++) {
14452 values[_i - 1] = arguments[_i];
14453 }
14454 var /** @type {?} */ logViewDef;
14455 var /** @type {?} */ logNodeIndex;
14456 if (this.nodeDef.flags & 2 /* TypeText */) {
14457 logViewDef = this.view.def;
14458 logNodeIndex = this.nodeDef.index;
14459 }
14460 else {
14461 logViewDef = this.elView.def;
14462 logNodeIndex = this.elDef.index;
14463 }
14464 // Note: we only generate a log function for text and element nodes
14465 // to make the generated code as small as possible.
14466 var /** @type {?} */ renderNodeIndex = getRenderNodeIndex(logViewDef, logNodeIndex);
14467 var /** @type {?} */ currRenderNodeIndex = -1;
14468 var /** @type {?} */ nodeLogger = function () {
14469 currRenderNodeIndex++;
14470 if (currRenderNodeIndex === renderNodeIndex) {
14471 return (_a = console.error).bind.apply(_a, [console].concat(values));
14472 }
14473 else {
14474 return NOOP;
14475 }
14476 var _a;
14477 }; /** @type {?} */
14478 ((logViewDef.factory))(nodeLogger);
14479 if (currRenderNodeIndex < renderNodeIndex) {
14480 console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
14481 console.error.apply(console, values);
14482 }
14483 };
14484 return DebugContext_;
14485}());
14486/**
14487 * @param {?} viewDef
14488 * @param {?} nodeIndex
14489 * @return {?}
14490 */
14491function getRenderNodeIndex(viewDef$$1, nodeIndex) {
14492 var /** @type {?} */ renderNodeIndex = -1;
14493 for (var /** @type {?} */ i = 0; i <= nodeIndex; i++) {
14494 var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
14495 if (nodeDef.flags & 3 /* CatRenderNode */) {
14496 renderNodeIndex++;
14497 }
14498 }
14499 return renderNodeIndex;
14500}
14501/**
14502 * @param {?} view
14503 * @return {?}
14504 */
14505function findHostElement(view) {
14506 while (view && !isComponentView(view)) {
14507 view = ((view.parent));
14508 }
14509 if (view.parent) {
14510 return asElementData(view.parent, /** @type {?} */ ((viewParentEl(view))).index);
14511 }
14512 return null;
14513}
14514/**
14515 * @param {?} view
14516 * @param {?} nodeDef
14517 * @param {?} references
14518 * @return {?}
14519 */
14520function collectReferences(view, nodeDef, references) {
14521 for (var /** @type {?} */ refName in nodeDef.references) {
14522 references[refName] = getQueryValue(view, nodeDef, nodeDef.references[refName]);
14523 }
14524}
14525/**
14526 * @param {?} action
14527 * @param {?} fn
14528 * @param {?} self
14529 * @param {?} args
14530 * @return {?}
14531 */
14532function callWithDebugContext(action, fn, self, args) {
14533 var /** @type {?} */ oldAction = _currentAction;
14534 var /** @type {?} */ oldView = _currentView;
14535 var /** @type {?} */ oldNodeIndex = _currentNodeIndex;
14536 try {
14537 _currentAction = action;
14538 var /** @type {?} */ result = fn.apply(self, args);
14539 _currentView = oldView;
14540 _currentNodeIndex = oldNodeIndex;
14541 _currentAction = oldAction;
14542 return result;
14543 }
14544 catch (e) {
14545 if (isViewDebugError(e) || !_currentView) {
14546 throw e;
14547 }
14548 throw viewWrappedDebugError(e, /** @type {?} */ ((getCurrentDebugContext())));
14549 }
14550}
14551/**
14552 * @return {?}
14553 */
14554function getCurrentDebugContext() {
14555 return _currentView ? new DebugContext_(_currentView, _currentNodeIndex) : null;
14556}
14557var DebugRendererFactory2 = (function () {
14558 /**
14559 * @param {?} delegate
14560 */
14561 function DebugRendererFactory2(delegate) {
14562 this.delegate = delegate;
14563 }
14564 /**
14565 * @param {?} element
14566 * @param {?} renderData
14567 * @return {?}
14568 */
14569 DebugRendererFactory2.prototype.createRenderer = function (element, renderData) {
14570 return new DebugRenderer2(this.delegate.createRenderer(element, renderData));
14571 };
14572 /**
14573 * @return {?}
14574 */
14575 DebugRendererFactory2.prototype.begin = function () {
14576 if (this.delegate.begin) {
14577 this.delegate.begin();
14578 }
14579 };
14580 /**
14581 * @return {?}
14582 */
14583 DebugRendererFactory2.prototype.end = function () {
14584 if (this.delegate.end) {
14585 this.delegate.end();
14586 }
14587 };
14588 /**
14589 * @return {?}
14590 */
14591 DebugRendererFactory2.prototype.whenRenderingDone = function () {
14592 if (this.delegate.whenRenderingDone) {
14593 return this.delegate.whenRenderingDone();
14594 }
14595 return Promise.resolve(null);
14596 };
14597 return DebugRendererFactory2;
14598}());
14599var DebugRenderer2 = (function () {
14600 /**
14601 * @param {?} delegate
14602 */
14603 function DebugRenderer2(delegate) {
14604 this.delegate = delegate;
14605 }
14606 Object.defineProperty(DebugRenderer2.prototype, "data", {
14607 /**
14608 * @return {?}
14609 */
14610 get: function () { return this.delegate.data; },
14611 enumerable: true,
14612 configurable: true
14613 });
14614 /**
14615 * @param {?} node
14616 * @return {?}
14617 */
14618 DebugRenderer2.prototype.destroyNode = function (node) {
14619 removeDebugNodeFromIndex(/** @type {?} */ ((getDebugNode(node))));
14620 if (this.delegate.destroyNode) {
14621 this.delegate.destroyNode(node);
14622 }
14623 };
14624 /**
14625 * @return {?}
14626 */
14627 DebugRenderer2.prototype.destroy = function () { this.delegate.destroy(); };
14628 /**
14629 * @param {?} name
14630 * @param {?=} namespace
14631 * @return {?}
14632 */
14633 DebugRenderer2.prototype.createElement = function (name, namespace) {
14634 var /** @type {?} */ el = this.delegate.createElement(name, namespace);
14635 var /** @type {?} */ debugCtx = getCurrentDebugContext();
14636 if (debugCtx) {
14637 var /** @type {?} */ debugEl = new DebugElement(el, null, debugCtx);
14638 debugEl.name = name;
14639 indexDebugNode(debugEl);
14640 }
14641 return el;
14642 };
14643 /**
14644 * @param {?} value
14645 * @return {?}
14646 */
14647 DebugRenderer2.prototype.createComment = function (value) {
14648 var /** @type {?} */ comment = this.delegate.createComment(value);
14649 var /** @type {?} */ debugCtx = getCurrentDebugContext();
14650 if (debugCtx) {
14651 indexDebugNode(new DebugNode(comment, null, debugCtx));
14652 }
14653 return comment;
14654 };
14655 /**
14656 * @param {?} value
14657 * @return {?}
14658 */
14659 DebugRenderer2.prototype.createText = function (value) {
14660 var /** @type {?} */ text = this.delegate.createText(value);
14661 var /** @type {?} */ debugCtx = getCurrentDebugContext();
14662 if (debugCtx) {
14663 indexDebugNode(new DebugNode(text, null, debugCtx));
14664 }
14665 return text;
14666 };
14667 /**
14668 * @param {?} parent
14669 * @param {?} newChild
14670 * @return {?}
14671 */
14672 DebugRenderer2.prototype.appendChild = function (parent, newChild) {
14673 var /** @type {?} */ debugEl = getDebugNode(parent);
14674 var /** @type {?} */ debugChildEl = getDebugNode(newChild);
14675 if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
14676 debugEl.addChild(debugChildEl);
14677 }
14678 this.delegate.appendChild(parent, newChild);
14679 };
14680 /**
14681 * @param {?} parent
14682 * @param {?} newChild
14683 * @param {?} refChild
14684 * @return {?}
14685 */
14686 DebugRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
14687 var /** @type {?} */ debugEl = getDebugNode(parent);
14688 var /** @type {?} */ debugChildEl = getDebugNode(newChild);
14689 var /** @type {?} */ debugRefEl = ((getDebugNode(refChild)));
14690 if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
14691 debugEl.insertBefore(debugRefEl, debugChildEl);
14692 }
14693 this.delegate.insertBefore(parent, newChild, refChild);
14694 };
14695 /**
14696 * @param {?} parent
14697 * @param {?} oldChild
14698 * @return {?}
14699 */
14700 DebugRenderer2.prototype.removeChild = function (parent, oldChild) {
14701 var /** @type {?} */ debugEl = getDebugNode(parent);
14702 var /** @type {?} */ debugChildEl = getDebugNode(oldChild);
14703 if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
14704 debugEl.removeChild(debugChildEl);
14705 }
14706 this.delegate.removeChild(parent, oldChild);
14707 };
14708 /**
14709 * @param {?} selectorOrNode
14710 * @return {?}
14711 */
14712 DebugRenderer2.prototype.selectRootElement = function (selectorOrNode) {
14713 var /** @type {?} */ el = this.delegate.selectRootElement(selectorOrNode);
14714 var /** @type {?} */ debugCtx = getCurrentDebugContext();
14715 if (debugCtx) {
14716 indexDebugNode(new DebugElement(el, null, debugCtx));
14717 }
14718 return el;
14719 };
14720 /**
14721 * @param {?} el
14722 * @param {?} name
14723 * @param {?} value
14724 * @param {?=} namespace
14725 * @return {?}
14726 */
14727 DebugRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
14728 var /** @type {?} */ debugEl = getDebugNode(el);
14729 if (debugEl && debugEl instanceof DebugElement) {
14730 var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
14731 debugEl.attributes[fullName] = value;
14732 }
14733 this.delegate.setAttribute(el, name, value, namespace);
14734 };
14735 /**
14736 * @param {?} el
14737 * @param {?} name
14738 * @param {?=} namespace
14739 * @return {?}
14740 */
14741 DebugRenderer2.prototype.removeAttribute = function (el, name, namespace) {
14742 var /** @type {?} */ debugEl = getDebugNode(el);
14743 if (debugEl && debugEl instanceof DebugElement) {
14744 var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
14745 debugEl.attributes[fullName] = null;
14746 }
14747 this.delegate.removeAttribute(el, name, namespace);
14748 };
14749 /**
14750 * @param {?} el
14751 * @param {?} name
14752 * @return {?}
14753 */
14754 DebugRenderer2.prototype.addClass = function (el, name) {
14755 var /** @type {?} */ debugEl = getDebugNode(el);
14756 if (debugEl && debugEl instanceof DebugElement) {
14757 debugEl.classes[name] = true;
14758 }
14759 this.delegate.addClass(el, name);
14760 };
14761 /**
14762 * @param {?} el
14763 * @param {?} name
14764 * @return {?}
14765 */
14766 DebugRenderer2.prototype.removeClass = function (el, name) {
14767 var /** @type {?} */ debugEl = getDebugNode(el);
14768 if (debugEl && debugEl instanceof DebugElement) {
14769 debugEl.classes[name] = false;
14770 }
14771 this.delegate.removeClass(el, name);
14772 };
14773 /**
14774 * @param {?} el
14775 * @param {?} style
14776 * @param {?} value
14777 * @param {?} flags
14778 * @return {?}
14779 */
14780 DebugRenderer2.prototype.setStyle = function (el, style, value, flags) {
14781 var /** @type {?} */ debugEl = getDebugNode(el);
14782 if (debugEl && debugEl instanceof DebugElement) {
14783 debugEl.styles[style] = value;
14784 }
14785 this.delegate.setStyle(el, style, value, flags);
14786 };
14787 /**
14788 * @param {?} el
14789 * @param {?} style
14790 * @param {?} flags
14791 * @return {?}
14792 */
14793 DebugRenderer2.prototype.removeStyle = function (el, style, flags) {
14794 var /** @type {?} */ debugEl = getDebugNode(el);
14795 if (debugEl && debugEl instanceof DebugElement) {
14796 debugEl.styles[style] = null;
14797 }
14798 this.delegate.removeStyle(el, style, flags);
14799 };
14800 /**
14801 * @param {?} el
14802 * @param {?} name
14803 * @param {?} value
14804 * @return {?}
14805 */
14806 DebugRenderer2.prototype.setProperty = function (el, name, value) {
14807 var /** @type {?} */ debugEl = getDebugNode(el);
14808 if (debugEl && debugEl instanceof DebugElement) {
14809 debugEl.properties[name] = value;
14810 }
14811 this.delegate.setProperty(el, name, value);
14812 };
14813 /**
14814 * @param {?} target
14815 * @param {?} eventName
14816 * @param {?} callback
14817 * @return {?}
14818 */
14819 DebugRenderer2.prototype.listen = function (target, eventName, callback) {
14820 if (typeof target !== 'string') {
14821 var /** @type {?} */ debugEl = getDebugNode(target);
14822 if (debugEl) {
14823 debugEl.listeners.push(new EventListener(eventName, callback));
14824 }
14825 }
14826 return this.delegate.listen(target, eventName, callback);
14827 };
14828 /**
14829 * @param {?} node
14830 * @return {?}
14831 */
14832 DebugRenderer2.prototype.parentNode = function (node) { return this.delegate.parentNode(node); };
14833 /**
14834 * @param {?} node
14835 * @return {?}
14836 */
14837 DebugRenderer2.prototype.nextSibling = function (node) { return this.delegate.nextSibling(node); };
14838 /**
14839 * @param {?} node
14840 * @param {?} value
14841 * @return {?}
14842 */
14843 DebugRenderer2.prototype.setValue = function (node, value) { return this.delegate.setValue(node, value); };
14844 return DebugRenderer2;
14845}());
14846var NgModuleFactory_ = (function (_super) {
14847 __extends$1(NgModuleFactory_, _super);
14848 /**
14849 * @param {?} moduleType
14850 * @param {?} _bootstrapComponents
14851 * @param {?} _ngModuleDefFactory
14852 */
14853 function NgModuleFactory_(moduleType, _bootstrapComponents, _ngModuleDefFactory) {
14854 var _this =
14855 // Attention: this ctor is called as top level function.
14856 // Putting any logic in here will destroy closure tree shaking!
14857 _super.call(this) || this;
14858 _this.moduleType = moduleType;
14859 _this._bootstrapComponents = _bootstrapComponents;
14860 _this._ngModuleDefFactory = _ngModuleDefFactory;
14861 return _this;
14862 }
14863 /**
14864 * @param {?} parentInjector
14865 * @return {?}
14866 */
14867 NgModuleFactory_.prototype.create = function (parentInjector) {
14868 initServicesIfNeeded();
14869 var /** @type {?} */ def = resolveDefinition(this._ngModuleDefFactory);
14870 return Services.createNgModuleRef(this.moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
14871 };
14872 return NgModuleFactory_;
14873}(NgModuleFactory));
14874/**
14875 * `animate` is an animation-specific function that is designed to be used inside of Angular's
14876 * animation DSL language. If this information is new, please navigate to the {\@link
14877 * Component#animations component animations metadata page} to gain a better understanding of
14878 * how animations in Angular are used.
14879 *
14880 * `animate` specifies an animation step that will apply the provided `styles` data for a given
14881 * amount of time based on the provided `timing` expression value. Calls to `animate` are expected
14882 * to be used within {\@link sequence an animation sequence}, {\@link group group}, or {\@link
14883 * transition transition}.
14884 *
14885 * ### Usage
14886 *
14887 * The `animate` function accepts two input parameters: `timing` and `styles`:
14888 *
14889 * - `timing` is a string based value that can be a combination of a duration with optional delay
14890 * and easing values. The format for the expression breaks down to `duration delay easing`
14891 * (therefore a value such as `1s 100ms ease-out` will be parse itself into `duration=1000,
14892 * delay=100, easing=ease-out`. If a numeric value is provided then that will be used as the
14893 * `duration` value in millisecond form.
14894 * - `styles` is the style input data which can either be a call to {\@link style style} or {\@link
14895 * keyframes keyframes}. If left empty then the styles from the destination state will be collected
14896 * and used (this is useful when describing an animation step that will complete an animation by
14897 * {\@link transition#the-final-animate-call animating to the final state}).
14898 *
14899 * ```typescript
14900 * // various functions for specifying timing data
14901 * animate(500, style(...))
14902 * animate("1s", style(...))
14903 * animate("100ms 0.5s", style(...))
14904 * animate("5s ease", style(...))
14905 * animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
14906 *
14907 * // either style() of keyframes() can be used
14908 * animate(500, style({ background: "red" }))
14909 * animate(500, keyframes([
14910 * style({ background: "blue" })),
14911 * style({ background: "red" }))
14912 * ])
14913 * ```
14914 *
14915 * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
14916 *
14917 * \@experimental Animation support is experimental.
14918 * @param {?} timings
14919 * @param {?=} styles
14920 * @return {?}
14921 */
14922function animate$1(timings, styles) {
14923 if (styles === void 0) { styles = null; }
14924 return { type: 4 /* Animate */, styles: styles, timings: timings };
14925}
14926/**
14927 * `group` is an animation-specific function that is designed to be used inside of Angular's
14928 * animation DSL language. If this information is new, please navigate to the {\@link
14929 * Component#animations component animations metadata page} to gain a better understanding of
14930 * how animations in Angular are used.
14931 *
14932 * `group` specifies a list of animation steps that are all run in parallel. Grouped animations are
14933 * useful when a series of styles must be animated/closed off at different starting/ending times.
14934 *
14935 * The `group` function can either be used within a {\@link sequence sequence} or a {\@link transition
14936 * transition} and it will only continue to the next instruction once all of the inner animation
14937 * steps have completed.
14938 *
14939 * ### Usage
14940 *
14941 * The `steps` data that is passed into the `group` animation function can either consist of {\@link
14942 * style style} or {\@link animate animate} function calls. Each call to `style()` or `animate()`
14943 * within a group will be executed instantly (use {\@link keyframes keyframes} or a {\@link
14944 * animate#usage animate() with a delay value} to offset styles to be applied at a later time).
14945 *
14946 * ```typescript
14947 * group([
14948 * animate("1s", { background: "black" }))
14949 * animate("2s", { color: "white" }))
14950 * ])
14951 * ```
14952 *
14953 * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
14954 *
14955 * \@experimental Animation support is experimental.
14956 * @param {?} steps
14957 * @param {?=} options
14958 * @return {?}
14959 */
14960function group$1(steps, options) {
14961 if (options === void 0) { options = null; }
14962 return { type: 3 /* Group */, steps: steps, options: options };
14963}
14964/**
14965 * `sequence` is an animation-specific function that is designed to be used inside of Angular's
14966 * animation DSL language. If this information is new, please navigate to the {\@link
14967 * Component#animations component animations metadata page} to gain a better understanding of
14968 * how animations in Angular are used.
14969 *
14970 * `sequence` Specifies a list of animation steps that are run one by one. (`sequence` is used by
14971 * default when an array is passed as animation data into {\@link transition transition}.)
14972 *
14973 * The `sequence` function can either be used within a {\@link group group} or a {\@link transition
14974 * transition} and it will only continue to the next instruction once each of the inner animation
14975 * steps have completed.
14976 *
14977 * To perform animation styling in parallel with other animation steps then have a look at the
14978 * {\@link group group} animation function.
14979 *
14980 * ### Usage
14981 *
14982 * The `steps` data that is passed into the `sequence` animation function can either consist of
14983 * {\@link style style} or {\@link animate animate} function calls. A call to `style()` will apply the
14984 * provided styling data immediately while a call to `animate()` will apply its styling data over a
14985 * given time depending on its timing data.
14986 *
14987 * ```typescript
14988 * sequence([
14989 * style({ opacity: 0 })),
14990 * animate("1s", { opacity: 1 }))
14991 * ])
14992 * ```
14993 *
14994 * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
14995 *
14996 * \@experimental Animation support is experimental.
14997 * @param {?} steps
14998 * @param {?=} options
14999 * @return {?}
15000 */
15001function sequence$1(steps, options) {
15002 if (options === void 0) { options = null; }
15003 return { type: 2 /* Sequence */, steps: steps, options: options };
15004}
15005/**
15006 * `transition` is an animation-specific function that is designed to be used inside of Angular's
15007 * animation DSL language. If this information is new, please navigate to the {\@link
15008 * Component#animations component animations metadata page} to gain a better understanding of
15009 * how animations in Angular are used.
15010 *
15011 * `transition` declares the {\@link sequence sequence of animation steps} that will be run when the
15012 * provided `stateChangeExpr` value is satisfied. The `stateChangeExpr` consists of a `state1 =>
15013 * state2` which consists of two known states (use an asterix (`*`) to refer to a dynamic starting
15014 * and/or ending state).
15015 *
15016 * A function can also be provided as the `stateChangeExpr` argument for a transition and this
15017 * function will be executed each time a state change occurs. If the value returned within the
15018 * function is true then the associated animation will be run.
15019 *
15020 * Animation transitions are placed within an {\@link trigger animation trigger}. For an transition
15021 * to animate to a state value and persist its styles then one or more {\@link state animation
15022 * states} is expected to be defined.
15023 *
15024 * ### Usage
15025 *
15026 * An animation transition is kicked off the `stateChangeExpr` predicate evaluates to true based on
15027 * what the previous state is and what the current state has become. In other words, if a transition
15028 * is defined that matches the old/current state criteria then the associated animation will be
15029 * triggered.
15030 *
15031 * ```typescript
15032 * // all transition/state changes are defined within an animation trigger
15033 * trigger("myAnimationTrigger", [
15034 * // if a state is defined then its styles will be persisted when the
15035 * // animation has fully completed itself
15036 * state("on", style({ background: "green" })),
15037 * state("off", style({ background: "grey" })),
15038 *
15039 * // a transition animation that will be kicked off when the state value
15040 * // bound to "myAnimationTrigger" changes from "on" to "off"
15041 * transition("on => off", animate(500)),
15042 *
15043 * // it is also possible to do run the same animation for both directions
15044 * transition("on <=> off", animate(500)),
15045 *
15046 * // or to define multiple states pairs separated by commas
15047 * transition("on => off, off => void", animate(500)),
15048 *
15049 * // this is a catch-all state change for when an element is inserted into
15050 * // the page and the destination state is unknown
15051 * transition("void => *", [
15052 * style({ opacity: 0 }),
15053 * animate(500)
15054 * ]),
15055 *
15056 * // this will capture a state change between any states
15057 * transition("* => *", animate("1s 0s")),
15058 *
15059 * // you can also go full out and include a function
15060 * transition((fromState, toState) => {
15061 * // when `true` then it will allow the animation below to be invoked
15062 * return fromState == "off" && toState == "on";
15063 * }, animate("1s 0s"))
15064 * ])
15065 * ```
15066 *
15067 * The template associated with this component will make use of the `myAnimationTrigger` animation
15068 * trigger by binding to an element within its template code.
15069 *
15070 * ```html
15071 * <!-- somewhere inside of my-component-tpl.html -->
15072 * <div [\@myAnimationTrigger]="myStatusExp">...</div>
15073 * ```
15074 *
15075 * #### The final `animate` call
15076 *
15077 * If the final step within the transition steps is a call to `animate()` that **only** uses a
15078 * timing value with **no style data** then it will be automatically used as the final animation arc
15079 * for the element to animate itself to the final state. This involves an automatic mix of
15080 * adding/removing CSS styles so that the element will be in the exact state it should be for the
15081 * applied state to be presented correctly.
15082 *
15083 * ```
15084 * // start off by hiding the element, but make sure that it animates properly to whatever state
15085 * // is currently active for "myAnimationTrigger"
15086 * transition("void => *", [
15087 * style({ opacity: 0 }),
15088 * animate(500)
15089 * ])
15090 * ```
15091 *
15092 * ### Transition Aliases (`:enter` and `:leave`)
15093 *
15094 * Given that enter (insertion) and leave (removal) animations are so common, the `transition`
15095 * function accepts both `:enter` and `:leave` values which are aliases for the `void => *` and `*
15096 * => void` state changes.
15097 *
15098 * ```
15099 * transition(":enter", [
15100 * style({ opacity: 0 }),
15101 * animate(500, style({ opacity: 1 }))
15102 * ])
15103 * transition(":leave", [
15104 * animate(500, style({ opacity: 0 }))
15105 * ])
15106 * ```
15107 *
15108 * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
15109 *
15110 * \@experimental Animation support is experimental.
15111 * @param {?} stateChangeExpr
15112 * @param {?} steps
15113 * @param {?=} options
15114 * @return {?}
15115 */
15116function transition$1(stateChangeExpr, steps, options) {
15117 if (options === void 0) { options = null; }
15118 return { type: 1 /* Transition */, expr: stateChangeExpr, animation: steps, options: options };
15119}
15120
15121/**
15122 * @license Angular v4.4.3
15123 * (c) 2010-2017 Google, Inc. https://angular.io/
15124 * License: MIT
15125 */
15126/**
15127 * @license
15128 * Copyright Google Inc. All Rights Reserved.
15129 *
15130 * Use of this source code is governed by an MIT-style license that can be
15131 * found in the LICENSE file at https://angular.io/license
15132 */
15133/**
15134 * This class should not be used directly by an application developer. Instead, use
15135 * {\@link Location}.
15136 *
15137 * `PlatformLocation` encapsulates all calls to DOM apis, which allows the Router to be platform
15138 * agnostic.
15139 * This means that we can have different implementation of `PlatformLocation` for the different
15140 * platforms that angular supports. For example, `\@angular/platform-browser` provides an
15141 * implementation specific to the browser environment, while `\@angular/platform-webworker` provides
15142 * one suitable for use with web workers.
15143 *
15144 * The `PlatformLocation` class is used directly by all implementations of {\@link LocationStrategy}
15145 * when they need to interact with the DOM apis like pushState, popState, etc...
15146 *
15147 * {\@link LocationStrategy} in turn is used by the {\@link Location} service which is used directly
15148 * by the {\@link Router} in order to navigate between routes. Since all interactions between {\@link
15149 * Router} /
15150 * {\@link Location} / {\@link LocationStrategy} and DOM apis flow through the `PlatformLocation`
15151 * class they are all platform independent.
15152 *
15153 * \@stable
15154 * @abstract
15155 */
15156var PlatformLocation = (function () {
15157 function PlatformLocation() {
15158 }
15159 /**
15160 * @abstract
15161 * @return {?}
15162 */
15163 PlatformLocation.prototype.getBaseHrefFromDOM = function () { };
15164 /**
15165 * @abstract
15166 * @param {?} fn
15167 * @return {?}
15168 */
15169 PlatformLocation.prototype.onPopState = function (fn) { };
15170 /**
15171 * @abstract
15172 * @param {?} fn
15173 * @return {?}
15174 */
15175 PlatformLocation.prototype.onHashChange = function (fn) { };
15176 /**
15177 * @abstract
15178 * @return {?}
15179 */
15180 PlatformLocation.prototype.pathname = function () { };
15181 /**
15182 * @abstract
15183 * @return {?}
15184 */
15185 PlatformLocation.prototype.search = function () { };
15186 /**
15187 * @abstract
15188 * @return {?}
15189 */
15190 PlatformLocation.prototype.hash = function () { };
15191 /**
15192 * @abstract
15193 * @param {?} state
15194 * @param {?} title
15195 * @param {?} url
15196 * @return {?}
15197 */
15198 PlatformLocation.prototype.replaceState = function (state$$1, title, url) { };
15199 /**
15200 * @abstract
15201 * @param {?} state
15202 * @param {?} title
15203 * @param {?} url
15204 * @return {?}
15205 */
15206 PlatformLocation.prototype.pushState = function (state$$1, title, url) { };
15207 /**
15208 * @abstract
15209 * @return {?}
15210 */
15211 PlatformLocation.prototype.forward = function () { };
15212 /**
15213 * @abstract
15214 * @return {?}
15215 */
15216 PlatformLocation.prototype.back = function () { };
15217 return PlatformLocation;
15218}());
15219/**
15220 * \@whatItDoes indicates when a location is initialized
15221 * \@experimental
15222 */
15223var LOCATION_INITIALIZED = new InjectionToken('Location Initialized');
15224/**
15225 * @license
15226 * Copyright Google Inc. All Rights Reserved.
15227 *
15228 * Use of this source code is governed by an MIT-style license that can be
15229 * found in the LICENSE file at https://angular.io/license
15230 */
15231/**
15232 * `LocationStrategy` is responsible for representing and reading route state
15233 * from the browser's URL. Angular provides two strategies:
15234 * {\@link HashLocationStrategy} and {\@link PathLocationStrategy}.
15235 *
15236 * This is used under the hood of the {\@link Location} service.
15237 *
15238 * Applications should use the {\@link Router} or {\@link Location} services to
15239 * interact with application route state.
15240 *
15241 * For instance, {\@link HashLocationStrategy} produces URLs like
15242 * `http://example.com#/foo`, and {\@link PathLocationStrategy} produces
15243 * `http://example.com/foo` as an equivalent URL.
15244 *
15245 * See these two classes for more.
15246 *
15247 * \@stable
15248 * @abstract
15249 */
15250var LocationStrategy = (function () {
15251 function LocationStrategy() {
15252 }
15253 /**
15254 * @abstract
15255 * @param {?=} includeHash
15256 * @return {?}
15257 */
15258 LocationStrategy.prototype.path = function (includeHash) { };
15259 /**
15260 * @abstract
15261 * @param {?} internal
15262 * @return {?}
15263 */
15264 LocationStrategy.prototype.prepareExternalUrl = function (internal) { };
15265 /**
15266 * @abstract
15267 * @param {?} state
15268 * @param {?} title
15269 * @param {?} url
15270 * @param {?} queryParams
15271 * @return {?}
15272 */
15273 LocationStrategy.prototype.pushState = function (state$$1, title, url, queryParams) { };
15274 /**
15275 * @abstract
15276 * @param {?} state
15277 * @param {?} title
15278 * @param {?} url
15279 * @param {?} queryParams
15280 * @return {?}
15281 */
15282 LocationStrategy.prototype.replaceState = function (state$$1, title, url, queryParams) { };
15283 /**
15284 * @abstract
15285 * @return {?}
15286 */
15287 LocationStrategy.prototype.forward = function () { };
15288 /**
15289 * @abstract
15290 * @return {?}
15291 */
15292 LocationStrategy.prototype.back = function () { };
15293 /**
15294 * @abstract
15295 * @param {?} fn
15296 * @return {?}
15297 */
15298 LocationStrategy.prototype.onPopState = function (fn) { };
15299 /**
15300 * @abstract
15301 * @return {?}
15302 */
15303 LocationStrategy.prototype.getBaseHref = function () { };
15304 return LocationStrategy;
15305}());
15306/**
15307 * The `APP_BASE_HREF` token represents the base href to be used with the
15308 * {\@link PathLocationStrategy}.
15309 *
15310 * If you're using {\@link PathLocationStrategy}, you must provide a provider to a string
15311 * representing the URL prefix that should be preserved when generating and recognizing
15312 * URLs.
15313 *
15314 * ### Example
15315 *
15316 * ```typescript
15317 * import {Component, NgModule} from '\@angular/core';
15318 * import {APP_BASE_HREF} from '\@angular/common';
15319 *
15320 * \@NgModule({
15321 * providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
15322 * })
15323 * class AppModule {}
15324 * ```
15325 *
15326 * \@stable
15327 */
15328var APP_BASE_HREF = new InjectionToken('appBaseHref');
15329/**
15330 * @license
15331 * Copyright Google Inc. All Rights Reserved.
15332 *
15333 * Use of this source code is governed by an MIT-style license that can be
15334 * found in the LICENSE file at https://angular.io/license
15335 */
15336/**
15337 * \@whatItDoes `Location` is a service that applications can use to interact with a browser's URL.
15338 * \@description
15339 * Depending on which {\@link LocationStrategy} is used, `Location` will either persist
15340 * to the URL's path or the URL's hash segment.
15341 *
15342 * Note: it's better to use {\@link Router#navigate} service to trigger route changes. Use
15343 * `Location` only if you need to interact with or create normalized URLs outside of
15344 * routing.
15345 *
15346 * `Location` is responsible for normalizing the URL against the application's base href.
15347 * A normalized URL is absolute from the URL host, includes the application's base href, and has no
15348 * trailing slash:
15349 * - `/my/app/user/123` is normalized
15350 * - `my/app/user/123` **is not** normalized
15351 * - `/my/app/user/123/` **is not** normalized
15352 *
15353 * ### Example
15354 * {\@example common/location/ts/path_location_component.ts region='LocationComponent'}
15355 * \@stable
15356 */
15357var Location = (function () {
15358 /**
15359 * @param {?} platformStrategy
15360 */
15361 function Location(platformStrategy) {
15362 var _this = this;
15363 /**
15364 * \@internal
15365 */
15366 this._subject = new EventEmitter();
15367 this._platformStrategy = platformStrategy;
15368 var browserBaseHref = this._platformStrategy.getBaseHref();
15369 this._baseHref = Location.stripTrailingSlash(_stripIndexHtml(browserBaseHref));
15370 this._platformStrategy.onPopState(function (ev) {
15371 _this._subject.emit({
15372 'url': _this.path(true),
15373 'pop': true,
15374 'type': ev.type,
15375 });
15376 });
15377 }
15378 /**
15379 * @param {?=} includeHash
15380 * @return {?}
15381 */
15382 Location.prototype.path = function (includeHash) {
15383 if (includeHash === void 0) { includeHash = false; }
15384 return this.normalize(this._platformStrategy.path(includeHash));
15385 };
15386 /**
15387 * Normalizes the given path and compares to the current normalized path.
15388 * @param {?} path
15389 * @param {?=} query
15390 * @return {?}
15391 */
15392 Location.prototype.isCurrentPathEqualTo = function (path, query) {
15393 if (query === void 0) { query = ''; }
15394 return this.path() == this.normalize(path + Location.normalizeQueryParams(query));
15395 };
15396 /**
15397 * Given a string representing a URL, returns the normalized URL path without leading or
15398 * trailing slashes.
15399 * @param {?} url
15400 * @return {?}
15401 */
15402 Location.prototype.normalize = function (url) {
15403 return Location.stripTrailingSlash(_stripBaseHref(this._baseHref, _stripIndexHtml(url)));
15404 };
15405 /**
15406 * Given a string representing a URL, returns the platform-specific external URL path.
15407 * If the given URL doesn't begin with a leading slash (`'/'`), this method adds one
15408 * before normalizing. This method will also add a hash if `HashLocationStrategy` is
15409 * used, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
15410 * @param {?} url
15411 * @return {?}
15412 */
15413 Location.prototype.prepareExternalUrl = function (url) {
15414 if (url && url[0] !== '/') {
15415 url = '/' + url;
15416 }
15417 return this._platformStrategy.prepareExternalUrl(url);
15418 };
15419 /**
15420 * Changes the browsers URL to the normalized version of the given URL, and pushes a
15421 * new item onto the platform's history.
15422 * @param {?} path
15423 * @param {?=} query
15424 * @return {?}
15425 */
15426 Location.prototype.go = function (path, query) {
15427 if (query === void 0) { query = ''; }
15428 this._platformStrategy.pushState(null, '', path, query);
15429 };
15430 /**
15431 * Changes the browsers URL to the normalized version of the given URL, and replaces
15432 * the top item on the platform's history stack.
15433 * @param {?} path
15434 * @param {?=} query
15435 * @return {?}
15436 */
15437 Location.prototype.replaceState = function (path, query) {
15438 if (query === void 0) { query = ''; }
15439 this._platformStrategy.replaceState(null, '', path, query);
15440 };
15441 /**
15442 * Navigates forward in the platform's history.
15443 * @return {?}
15444 */
15445 Location.prototype.forward = function () { this._platformStrategy.forward(); };
15446 /**
15447 * Navigates back in the platform's history.
15448 * @return {?}
15449 */
15450 Location.prototype.back = function () { this._platformStrategy.back(); };
15451 /**
15452 * Subscribe to the platform's `popState` events.
15453 * @param {?} onNext
15454 * @param {?=} onThrow
15455 * @param {?=} onReturn
15456 * @return {?}
15457 */
15458 Location.prototype.subscribe = function (onNext, onThrow, onReturn) {
15459 return this._subject.subscribe({ next: onNext, error: onThrow, complete: onReturn });
15460 };
15461 /**
15462 * Given a string of url parameters, prepend with '?' if needed, otherwise return parameters as
15463 * is.
15464 * @param {?} params
15465 * @return {?}
15466 */
15467 Location.normalizeQueryParams = function (params) {
15468 return params && params[0] !== '?' ? '?' + params : params;
15469 };
15470 /**
15471 * Given 2 parts of a url, join them with a slash if needed.
15472 * @param {?} start
15473 * @param {?} end
15474 * @return {?}
15475 */
15476 Location.joinWithSlash = function (start, end) {
15477 if (start.length == 0) {
15478 return end;
15479 }
15480 if (end.length == 0) {
15481 return start;
15482 }
15483 var /** @type {?} */ slashes = 0;
15484 if (start.endsWith('/')) {
15485 slashes++;
15486 }
15487 if (end.startsWith('/')) {
15488 slashes++;
15489 }
15490 if (slashes == 2) {
15491 return start + end.substring(1);
15492 }
15493 if (slashes == 1) {
15494 return start + end;
15495 }
15496 return start + '/' + end;
15497 };
15498 /**
15499 * If url has a trailing slash, remove it, otherwise return url as is. This
15500 * method looks for the first occurence of either #, ?, or the end of the
15501 * line as `/` characters after any of these should not be replaced.
15502 * @param {?} url
15503 * @return {?}
15504 */
15505 Location.stripTrailingSlash = function (url) {
15506 var /** @type {?} */ match = url.match(/#|\?|$/);
15507 var /** @type {?} */ pathEndIdx = match && match.index || url.length;
15508 var /** @type {?} */ droppedSlashIdx = pathEndIdx - (url[pathEndIdx - 1] === '/' ? 1 : 0);
15509 return url.slice(0, droppedSlashIdx) + url.slice(pathEndIdx);
15510 };
15511 return Location;
15512}());
15513Location.decorators = [
15514 { type: Injectable },
15515];
15516/**
15517 * @nocollapse
15518 */
15519Location.ctorParameters = function () { return [
15520 { type: LocationStrategy, },
15521]; };
15522/**
15523 * @param {?} baseHref
15524 * @param {?} url
15525 * @return {?}
15526 */
15527function _stripBaseHref(baseHref, url) {
15528 return baseHref && url.startsWith(baseHref) ? url.substring(baseHref.length) : url;
15529}
15530/**
15531 * @param {?} url
15532 * @return {?}
15533 */
15534function _stripIndexHtml(url) {
15535 return url.replace(/\/index.html$/, '');
15536}
15537/**
15538 * @license
15539 * Copyright Google Inc. All Rights Reserved.
15540 *
15541 * Use of this source code is governed by an MIT-style license that can be
15542 * found in the LICENSE file at https://angular.io/license
15543 */
15544/**
15545 * \@whatItDoes Use URL hash for storing application location data.
15546 * \@description
15547 * `HashLocationStrategy` is a {\@link LocationStrategy} used to configure the
15548 * {\@link Location} service to represent its state in the
15549 * [hash fragment](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
15550 * of the browser's URL.
15551 *
15552 * For instance, if you call `location.go('/foo')`, the browser's URL will become
15553 * `example.com#/foo`.
15554 *
15555 * ### Example
15556 *
15557 * {\@example common/location/ts/hash_location_component.ts region='LocationComponent'}
15558 *
15559 * \@stable
15560 */
15561var HashLocationStrategy = (function (_super) {
15562 __extends$1(HashLocationStrategy, _super);
15563 /**
15564 * @param {?} _platformLocation
15565 * @param {?=} _baseHref
15566 */
15567 function HashLocationStrategy(_platformLocation, _baseHref) {
15568 var _this = _super.call(this) || this;
15569 _this._platformLocation = _platformLocation;
15570 _this._baseHref = '';
15571 if (_baseHref != null) {
15572 _this._baseHref = _baseHref;
15573 }
15574 return _this;
15575 }
15576 /**
15577 * @param {?} fn
15578 * @return {?}
15579 */
15580 HashLocationStrategy.prototype.onPopState = function (fn) {
15581 this._platformLocation.onPopState(fn);
15582 this._platformLocation.onHashChange(fn);
15583 };
15584 /**
15585 * @return {?}
15586 */
15587 HashLocationStrategy.prototype.getBaseHref = function () { return this._baseHref; };
15588 /**
15589 * @param {?=} includeHash
15590 * @return {?}
15591 */
15592 HashLocationStrategy.prototype.path = function (includeHash) {
15593 if (includeHash === void 0) { includeHash = false; }
15594 // the hash value is always prefixed with a `#`
15595 // and if it is empty then it will stay empty
15596 var /** @type {?} */ path = this._platformLocation.hash;
15597 if (path == null)
15598 path = '#';
15599 return path.length > 0 ? path.substring(1) : path;
15600 };
15601 /**
15602 * @param {?} internal
15603 * @return {?}
15604 */
15605 HashLocationStrategy.prototype.prepareExternalUrl = function (internal) {
15606 var /** @type {?} */ url = Location.joinWithSlash(this._baseHref, internal);
15607 return url.length > 0 ? ('#' + url) : url;
15608 };
15609 /**
15610 * @param {?} state
15611 * @param {?} title
15612 * @param {?} path
15613 * @param {?} queryParams
15614 * @return {?}
15615 */
15616 HashLocationStrategy.prototype.pushState = function (state$$1, title, path, queryParams) {
15617 var /** @type {?} */ url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
15618 if (url.length == 0) {
15619 url = this._platformLocation.pathname;
15620 }
15621 this._platformLocation.pushState(state$$1, title, url);
15622 };
15623 /**
15624 * @param {?} state
15625 * @param {?} title
15626 * @param {?} path
15627 * @param {?} queryParams
15628 * @return {?}
15629 */
15630 HashLocationStrategy.prototype.replaceState = function (state$$1, title, path, queryParams) {
15631 var /** @type {?} */ url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
15632 if (url.length == 0) {
15633 url = this._platformLocation.pathname;
15634 }
15635 this._platformLocation.replaceState(state$$1, title, url);
15636 };
15637 /**
15638 * @return {?}
15639 */
15640 HashLocationStrategy.prototype.forward = function () { this._platformLocation.forward(); };
15641 /**
15642 * @return {?}
15643 */
15644 HashLocationStrategy.prototype.back = function () { this._platformLocation.back(); };
15645 return HashLocationStrategy;
15646}(LocationStrategy));
15647HashLocationStrategy.decorators = [
15648 { type: Injectable },
15649];
15650/**
15651 * @nocollapse
15652 */
15653HashLocationStrategy.ctorParameters = function () { return [
15654 { type: PlatformLocation, },
15655 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF,] },] },
15656]; };
15657/**
15658 * @license
15659 * Copyright Google Inc. All Rights Reserved.
15660 *
15661 * Use of this source code is governed by an MIT-style license that can be
15662 * found in the LICENSE file at https://angular.io/license
15663 */
15664/**
15665 * \@whatItDoes Use URL for storing application location data.
15666 * \@description
15667 * `PathLocationStrategy` is a {\@link LocationStrategy} used to configure the
15668 * {\@link Location} service to represent its state in the
15669 * [path](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax) of the
15670 * browser's URL.
15671 *
15672 * If you're using `PathLocationStrategy`, you must provide a {\@link APP_BASE_HREF}
15673 * or add a base element to the document. This URL prefix that will be preserved
15674 * when generating and recognizing URLs.
15675 *
15676 * For instance, if you provide an `APP_BASE_HREF` of `'/my/app'` and call
15677 * `location.go('/foo')`, the browser's URL will become
15678 * `example.com/my/app/foo`.
15679 *
15680 * Similarly, if you add `<base href='/my/app'/>` to the document and call
15681 * `location.go('/foo')`, the browser's URL will become
15682 * `example.com/my/app/foo`.
15683 *
15684 * ### Example
15685 *
15686 * {\@example common/location/ts/path_location_component.ts region='LocationComponent'}
15687 *
15688 * \@stable
15689 */
15690var PathLocationStrategy = (function (_super) {
15691 __extends$1(PathLocationStrategy, _super);
15692 /**
15693 * @param {?} _platformLocation
15694 * @param {?=} href
15695 */
15696 function PathLocationStrategy(_platformLocation, href) {
15697 var _this = _super.call(this) || this;
15698 _this._platformLocation = _platformLocation;
15699 if (href == null) {
15700 href = _this._platformLocation.getBaseHrefFromDOM();
15701 }
15702 if (href == null) {
15703 throw new Error("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");
15704 }
15705 _this._baseHref = href;
15706 return _this;
15707 }
15708 /**
15709 * @param {?} fn
15710 * @return {?}
15711 */
15712 PathLocationStrategy.prototype.onPopState = function (fn) {
15713 this._platformLocation.onPopState(fn);
15714 this._platformLocation.onHashChange(fn);
15715 };
15716 /**
15717 * @return {?}
15718 */
15719 PathLocationStrategy.prototype.getBaseHref = function () { return this._baseHref; };
15720 /**
15721 * @param {?} internal
15722 * @return {?}
15723 */
15724 PathLocationStrategy.prototype.prepareExternalUrl = function (internal) {
15725 return Location.joinWithSlash(this._baseHref, internal);
15726 };
15727 /**
15728 * @param {?=} includeHash
15729 * @return {?}
15730 */
15731 PathLocationStrategy.prototype.path = function (includeHash) {
15732 if (includeHash === void 0) { includeHash = false; }
15733 var /** @type {?} */ pathname = this._platformLocation.pathname +
15734 Location.normalizeQueryParams(this._platformLocation.search);
15735 var /** @type {?} */ hash = this._platformLocation.hash;
15736 return hash && includeHash ? "" + pathname + hash : pathname;
15737 };
15738 /**
15739 * @param {?} state
15740 * @param {?} title
15741 * @param {?} url
15742 * @param {?} queryParams
15743 * @return {?}
15744 */
15745 PathLocationStrategy.prototype.pushState = function (state$$1, title, url, queryParams) {
15746 var /** @type {?} */ externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
15747 this._platformLocation.pushState(state$$1, title, externalUrl);
15748 };
15749 /**
15750 * @param {?} state
15751 * @param {?} title
15752 * @param {?} url
15753 * @param {?} queryParams
15754 * @return {?}
15755 */
15756 PathLocationStrategy.prototype.replaceState = function (state$$1, title, url, queryParams) {
15757 var /** @type {?} */ externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
15758 this._platformLocation.replaceState(state$$1, title, externalUrl);
15759 };
15760 /**
15761 * @return {?}
15762 */
15763 PathLocationStrategy.prototype.forward = function () { this._platformLocation.forward(); };
15764 /**
15765 * @return {?}
15766 */
15767 PathLocationStrategy.prototype.back = function () { this._platformLocation.back(); };
15768 return PathLocationStrategy;
15769}(LocationStrategy));
15770PathLocationStrategy.decorators = [
15771 { type: Injectable },
15772];
15773/**
15774 * @nocollapse
15775 */
15776PathLocationStrategy.ctorParameters = function () { return [
15777 { type: PlatformLocation, },
15778 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF,] },] },
15779]; };
15780/**
15781 * @license
15782 * Copyright Google Inc. All Rights Reserved.
15783 *
15784 * Use of this source code is governed by an MIT-style license that can be
15785 * found in the LICENSE file at https://angular.io/license
15786 */
15787/**
15788 * @license
15789 * Copyright Google Inc. All Rights Reserved.
15790 *
15791 * Use of this source code is governed by an MIT-style license that can be
15792 * found in the LICENSE file at https://angular.io/license
15793 */
15794/**
15795 * \@experimental
15796 * @abstract
15797 */
15798var NgLocalization = (function () {
15799 function NgLocalization() {
15800 }
15801 /**
15802 * @abstract
15803 * @param {?} value
15804 * @return {?}
15805 */
15806 NgLocalization.prototype.getPluralCategory = function (value) { };
15807 return NgLocalization;
15808}());
15809/**
15810 * Returns the plural category for a given value.
15811 * - "=value" when the case exists,
15812 * - the plural category otherwise
15813 *
15814 * \@internal
15815 * @param {?} value
15816 * @param {?} cases
15817 * @param {?} ngLocalization
15818 * @return {?}
15819 */
15820function getPluralCategory(value, cases, ngLocalization) {
15821 var /** @type {?} */ key = "=" + value;
15822 if (cases.indexOf(key) > -1) {
15823 return key;
15824 }
15825 key = ngLocalization.getPluralCategory(value);
15826 if (cases.indexOf(key) > -1) {
15827 return key;
15828 }
15829 if (cases.indexOf('other') > -1) {
15830 return 'other';
15831 }
15832 throw new Error("No plural message found for value \"" + value + "\"");
15833}
15834/**
15835 * Returns the plural case based on the locale
15836 *
15837 * \@experimental
15838 */
15839var NgLocaleLocalization = (function (_super) {
15840 __extends$1(NgLocaleLocalization, _super);
15841 /**
15842 * @param {?} locale
15843 */
15844 function NgLocaleLocalization(locale) {
15845 var _this = _super.call(this) || this;
15846 _this.locale = locale;
15847 return _this;
15848 }
15849 /**
15850 * @param {?} value
15851 * @return {?}
15852 */
15853 NgLocaleLocalization.prototype.getPluralCategory = function (value) {
15854 var /** @type {?} */ plural = getPluralCase(this.locale, value);
15855 switch (plural) {
15856 case Plural.Zero:
15857 return 'zero';
15858 case Plural.One:
15859 return 'one';
15860 case Plural.Two:
15861 return 'two';
15862 case Plural.Few:
15863 return 'few';
15864 case Plural.Many:
15865 return 'many';
15866 default:
15867 return 'other';
15868 }
15869 };
15870 return NgLocaleLocalization;
15871}(NgLocalization));
15872NgLocaleLocalization.decorators = [
15873 { type: Injectable },
15874];
15875/**
15876 * @nocollapse
15877 */
15878NgLocaleLocalization.ctorParameters = function () { return [
15879 { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
15880]; };
15881var Plural = {};
15882Plural.Zero = 0;
15883Plural.One = 1;
15884Plural.Two = 2;
15885Plural.Few = 3;
15886Plural.Many = 4;
15887Plural.Other = 5;
15888Plural[Plural.Zero] = "Zero";
15889Plural[Plural.One] = "One";
15890Plural[Plural.Two] = "Two";
15891Plural[Plural.Few] = "Few";
15892Plural[Plural.Many] = "Many";
15893Plural[Plural.Other] = "Other";
15894/**
15895 * Returns the plural case based on the locale
15896 *
15897 * \@experimental
15898 * @param {?} locale
15899 * @param {?} nLike
15900 * @return {?}
15901 */
15902function getPluralCase(locale, nLike) {
15903 // TODO(vicb): lazy compute
15904 if (typeof nLike === 'string') {
15905 nLike = parseInt(/** @type {?} */ (nLike), 10);
15906 }
15907 var /** @type {?} */ n = (nLike);
15908 var /** @type {?} */ nDecimal = n.toString().replace(/^[^.]*\.?/, '');
15909 var /** @type {?} */ i = Math.floor(Math.abs(n));
15910 var /** @type {?} */ v = nDecimal.length;
15911 var /** @type {?} */ f = parseInt(nDecimal, 10);
15912 var /** @type {?} */ t = parseInt(n.toString().replace(/^[^.]*\.?|0+$/g, ''), 10) || 0;
15913 var /** @type {?} */ lang = locale.split('-')[0].toLowerCase();
15914 switch (lang) {
15915 case 'af':
15916 case 'asa':
15917 case 'az':
15918 case 'bem':
15919 case 'bez':
15920 case 'bg':
15921 case 'brx':
15922 case 'ce':
15923 case 'cgg':
15924 case 'chr':
15925 case 'ckb':
15926 case 'ee':
15927 case 'el':
15928 case 'eo':
15929 case 'es':
15930 case 'eu':
15931 case 'fo':
15932 case 'fur':
15933 case 'gsw':
15934 case 'ha':
15935 case 'haw':
15936 case 'hu':
15937 case 'jgo':
15938 case 'jmc':
15939 case 'ka':
15940 case 'kk':
15941 case 'kkj':
15942 case 'kl':
15943 case 'ks':
15944 case 'ksb':
15945 case 'ky':
15946 case 'lb':
15947 case 'lg':
15948 case 'mas':
15949 case 'mgo':
15950 case 'ml':
15951 case 'mn':
15952 case 'nb':
15953 case 'nd':
15954 case 'ne':
15955 case 'nn':
15956 case 'nnh':
15957 case 'nyn':
15958 case 'om':
15959 case 'or':
15960 case 'os':
15961 case 'ps':
15962 case 'rm':
15963 case 'rof':
15964 case 'rwk':
15965 case 'saq':
15966 case 'seh':
15967 case 'sn':
15968 case 'so':
15969 case 'sq':
15970 case 'ta':
15971 case 'te':
15972 case 'teo':
15973 case 'tk':
15974 case 'tr':
15975 case 'ug':
15976 case 'uz':
15977 case 'vo':
15978 case 'vun':
15979 case 'wae':
15980 case 'xog':
15981 if (n === 1)
15982 return Plural.One;
15983 return Plural.Other;
15984 case 'ak':
15985 case 'ln':
15986 case 'mg':
15987 case 'pa':
15988 case 'ti':
15989 if (n === Math.floor(n) && n >= 0 && n <= 1)
15990 return Plural.One;
15991 return Plural.Other;
15992 case 'am':
15993 case 'as':
15994 case 'bn':
15995 case 'fa':
15996 case 'gu':
15997 case 'hi':
15998 case 'kn':
15999 case 'mr':
16000 case 'zu':
16001 if (i === 0 || n === 1)
16002 return Plural.One;
16003 return Plural.Other;
16004 case 'ar':
16005 if (n === 0)
16006 return Plural.Zero;
16007 if (n === 1)
16008 return Plural.One;
16009 if (n === 2)
16010 return Plural.Two;
16011 if (n % 100 === Math.floor(n % 100) && n % 100 >= 3 && n % 100 <= 10)
16012 return Plural.Few;
16013 if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 99)
16014 return Plural.Many;
16015 return Plural.Other;
16016 case 'ast':
16017 case 'ca':
16018 case 'de':
16019 case 'en':
16020 case 'et':
16021 case 'fi':
16022 case 'fy':
16023 case 'gl':
16024 case 'it':
16025 case 'nl':
16026 case 'sv':
16027 case 'sw':
16028 case 'ur':
16029 case 'yi':
16030 if (i === 1 && v === 0)
16031 return Plural.One;
16032 return Plural.Other;
16033 case 'be':
16034 if (n % 10 === 1 && !(n % 100 === 11))
16035 return Plural.One;
16036 if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 4 &&
16037 !(n % 100 >= 12 && n % 100 <= 14))
16038 return Plural.Few;
16039 if (n % 10 === 0 || n % 10 === Math.floor(n % 10) && n % 10 >= 5 && n % 10 <= 9 ||
16040 n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 14)
16041 return Plural.Many;
16042 return Plural.Other;
16043 case 'br':
16044 if (n % 10 === 1 && !(n % 100 === 11 || n % 100 === 71 || n % 100 === 91))
16045 return Plural.One;
16046 if (n % 10 === 2 && !(n % 100 === 12 || n % 100 === 72 || n % 100 === 92))
16047 return Plural.Two;
16048 if (n % 10 === Math.floor(n % 10) && (n % 10 >= 3 && n % 10 <= 4 || n % 10 === 9) &&
16049 !(n % 100 >= 10 && n % 100 <= 19 || n % 100 >= 70 && n % 100 <= 79 ||
16050 n % 100 >= 90 && n % 100 <= 99))
16051 return Plural.Few;
16052 if (!(n === 0) && n % 1e6 === 0)
16053 return Plural.Many;
16054 return Plural.Other;
16055 case 'bs':
16056 case 'hr':
16057 case 'sr':
16058 if (v === 0 && i % 10 === 1 && !(i % 100 === 11) || f % 10 === 1 && !(f % 100 === 11))
16059 return Plural.One;
16060 if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
16061 !(i % 100 >= 12 && i % 100 <= 14) ||
16062 f % 10 === Math.floor(f % 10) && f % 10 >= 2 && f % 10 <= 4 &&
16063 !(f % 100 >= 12 && f % 100 <= 14))
16064 return Plural.Few;
16065 return Plural.Other;
16066 case 'cs':
16067 case 'sk':
16068 if (i === 1 && v === 0)
16069 return Plural.One;
16070 if (i === Math.floor(i) && i >= 2 && i <= 4 && v === 0)
16071 return Plural.Few;
16072 if (!(v === 0))
16073 return Plural.Many;
16074 return Plural.Other;
16075 case 'cy':
16076 if (n === 0)
16077 return Plural.Zero;
16078 if (n === 1)
16079 return Plural.One;
16080 if (n === 2)
16081 return Plural.Two;
16082 if (n === 3)
16083 return Plural.Few;
16084 if (n === 6)
16085 return Plural.Many;
16086 return Plural.Other;
16087 case 'da':
16088 if (n === 1 || !(t === 0) && (i === 0 || i === 1))
16089 return Plural.One;
16090 return Plural.Other;
16091 case 'dsb':
16092 case 'hsb':
16093 if (v === 0 && i % 100 === 1 || f % 100 === 1)
16094 return Plural.One;
16095 if (v === 0 && i % 100 === 2 || f % 100 === 2)
16096 return Plural.Two;
16097 if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 ||
16098 f % 100 === Math.floor(f % 100) && f % 100 >= 3 && f % 100 <= 4)
16099 return Plural.Few;
16100 return Plural.Other;
16101 case 'ff':
16102 case 'fr':
16103 case 'hy':
16104 case 'kab':
16105 if (i === 0 || i === 1)
16106 return Plural.One;
16107 return Plural.Other;
16108 case 'fil':
16109 if (v === 0 && (i === 1 || i === 2 || i === 3) ||
16110 v === 0 && !(i % 10 === 4 || i % 10 === 6 || i % 10 === 9) ||
16111 !(v === 0) && !(f % 10 === 4 || f % 10 === 6 || f % 10 === 9))
16112 return Plural.One;
16113 return Plural.Other;
16114 case 'ga':
16115 if (n === 1)
16116 return Plural.One;
16117 if (n === 2)
16118 return Plural.Two;
16119 if (n === Math.floor(n) && n >= 3 && n <= 6)
16120 return Plural.Few;
16121 if (n === Math.floor(n) && n >= 7 && n <= 10)
16122 return Plural.Many;
16123 return Plural.Other;
16124 case 'gd':
16125 if (n === 1 || n === 11)
16126 return Plural.One;
16127 if (n === 2 || n === 12)
16128 return Plural.Two;
16129 if (n === Math.floor(n) && (n >= 3 && n <= 10 || n >= 13 && n <= 19))
16130 return Plural.Few;
16131 return Plural.Other;
16132 case 'gv':
16133 if (v === 0 && i % 10 === 1)
16134 return Plural.One;
16135 if (v === 0 && i % 10 === 2)
16136 return Plural.Two;
16137 if (v === 0 &&
16138 (i % 100 === 0 || i % 100 === 20 || i % 100 === 40 || i % 100 === 60 || i % 100 === 80))
16139 return Plural.Few;
16140 if (!(v === 0))
16141 return Plural.Many;
16142 return Plural.Other;
16143 case 'he':
16144 if (i === 1 && v === 0)
16145 return Plural.One;
16146 if (i === 2 && v === 0)
16147 return Plural.Two;
16148 if (v === 0 && !(n >= 0 && n <= 10) && n % 10 === 0)
16149 return Plural.Many;
16150 return Plural.Other;
16151 case 'is':
16152 if (t === 0 && i % 10 === 1 && !(i % 100 === 11) || !(t === 0))
16153 return Plural.One;
16154 return Plural.Other;
16155 case 'ksh':
16156 if (n === 0)
16157 return Plural.Zero;
16158 if (n === 1)
16159 return Plural.One;
16160 return Plural.Other;
16161 case 'kw':
16162 case 'naq':
16163 case 'se':
16164 case 'smn':
16165 if (n === 1)
16166 return Plural.One;
16167 if (n === 2)
16168 return Plural.Two;
16169 return Plural.Other;
16170 case 'lag':
16171 if (n === 0)
16172 return Plural.Zero;
16173 if ((i === 0 || i === 1) && !(n === 0))
16174 return Plural.One;
16175 return Plural.Other;
16176 case 'lt':
16177 if (n % 10 === 1 && !(n % 100 >= 11 && n % 100 <= 19))
16178 return Plural.One;
16179 if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 9 &&
16180 !(n % 100 >= 11 && n % 100 <= 19))
16181 return Plural.Few;
16182 if (!(f === 0))
16183 return Plural.Many;
16184 return Plural.Other;
16185 case 'lv':
16186 case 'prg':
16187 if (n % 10 === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19 ||
16188 v === 2 && f % 100 === Math.floor(f % 100) && f % 100 >= 11 && f % 100 <= 19)
16189 return Plural.Zero;
16190 if (n % 10 === 1 && !(n % 100 === 11) || v === 2 && f % 10 === 1 && !(f % 100 === 11) ||
16191 !(v === 2) && f % 10 === 1)
16192 return Plural.One;
16193 return Plural.Other;
16194 case 'mk':
16195 if (v === 0 && i % 10 === 1 || f % 10 === 1)
16196 return Plural.One;
16197 return Plural.Other;
16198 case 'mt':
16199 if (n === 1)
16200 return Plural.One;
16201 if (n === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 2 && n % 100 <= 10)
16202 return Plural.Few;
16203 if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19)
16204 return Plural.Many;
16205 return Plural.Other;
16206 case 'pl':
16207 if (i === 1 && v === 0)
16208 return Plural.One;
16209 if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
16210 !(i % 100 >= 12 && i % 100 <= 14))
16211 return Plural.Few;
16212 if (v === 0 && !(i === 1) && i % 10 === Math.floor(i % 10) && i % 10 >= 0 && i % 10 <= 1 ||
16213 v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
16214 v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 12 && i % 100 <= 14)
16215 return Plural.Many;
16216 return Plural.Other;
16217 case 'pt':
16218 if (n === Math.floor(n) && n >= 0 && n <= 2 && !(n === 2))
16219 return Plural.One;
16220 return Plural.Other;
16221 case 'ro':
16222 if (i === 1 && v === 0)
16223 return Plural.One;
16224 if (!(v === 0) || n === 0 ||
16225 !(n === 1) && n % 100 === Math.floor(n % 100) && n % 100 >= 1 && n % 100 <= 19)
16226 return Plural.Few;
16227 return Plural.Other;
16228 case 'ru':
16229 case 'uk':
16230 if (v === 0 && i % 10 === 1 && !(i % 100 === 11))
16231 return Plural.One;
16232 if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
16233 !(i % 100 >= 12 && i % 100 <= 14))
16234 return Plural.Few;
16235 if (v === 0 && i % 10 === 0 ||
16236 v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
16237 v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 11 && i % 100 <= 14)
16238 return Plural.Many;
16239 return Plural.Other;
16240 case 'shi':
16241 if (i === 0 || n === 1)
16242 return Plural.One;
16243 if (n === Math.floor(n) && n >= 2 && n <= 10)
16244 return Plural.Few;
16245 return Plural.Other;
16246 case 'si':
16247 if (n === 0 || n === 1 || i === 0 && f === 1)
16248 return Plural.One;
16249 return Plural.Other;
16250 case 'sl':
16251 if (v === 0 && i % 100 === 1)
16252 return Plural.One;
16253 if (v === 0 && i % 100 === 2)
16254 return Plural.Two;
16255 if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 || !(v === 0))
16256 return Plural.Few;
16257 return Plural.Other;
16258 case 'tzm':
16259 if (n === Math.floor(n) && n >= 0 && n <= 1 || n === Math.floor(n) && n >= 11 && n <= 99)
16260 return Plural.One;
16261 return Plural.Other;
16262 // When there is no specification, the default is always "other"
16263 // Spec: http://cldr.unicode.org/index/cldr-spec/plural-rules
16264 // > other (required—general plural form — also used if the language only has a single form)
16265 default:
16266 return Plural.Other;
16267 }
16268}
16269/**
16270 * @license
16271 * Copyright Google Inc. All Rights Reserved.
16272 *
16273 * Use of this source code is governed by an MIT-style license that can be
16274 * found in the LICENSE file at https://angular.io/license
16275 * @param {?} cookieStr
16276 * @param {?} name
16277 * @return {?}
16278 */
16279function parseCookieValue(cookieStr, name) {
16280 name = encodeURIComponent(name);
16281 for (var _i = 0, _a = cookieStr.split(';'); _i < _a.length; _i++) {
16282 var cookie = _a[_i];
16283 var /** @type {?} */ eqIndex = cookie.indexOf('=');
16284 var _b = eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)], cookieName = _b[0], cookieValue = _b[1];
16285 if (cookieName.trim() === name) {
16286 return decodeURIComponent(cookieValue);
16287 }
16288 }
16289 return null;
16290}
16291/**
16292 * @license
16293 * Copyright Google Inc. All Rights Reserved.
16294 *
16295 * Use of this source code is governed by an MIT-style license that can be
16296 * found in the LICENSE file at https://angular.io/license
16297 */
16298/**
16299 * \@ngModule CommonModule
16300 *
16301 * \@whatItDoes Adds and removes CSS classes on an HTML element.
16302 *
16303 * \@howToUse
16304 * ```
16305 * <some-element [ngClass]="'first second'">...</some-element>
16306 *
16307 * <some-element [ngClass]="['first', 'second']">...</some-element>
16308 *
16309 * <some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
16310 *
16311 * <some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
16312 *
16313 * <some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
16314 * ```
16315 *
16316 * \@description
16317 *
16318 * The CSS classes are updated as follows, depending on the type of the expression evaluation:
16319 * - `string` - the CSS classes listed in the string (space delimited) are added,
16320 * - `Array` - the CSS classes declared as Array elements are added,
16321 * - `Object` - keys are CSS classes that get added when the expression given in the value
16322 * evaluates to a truthy value, otherwise they are removed.
16323 *
16324 * \@stable
16325 */
16326var NgClass = (function () {
16327 /**
16328 * @param {?} _iterableDiffers
16329 * @param {?} _keyValueDiffers
16330 * @param {?} _ngEl
16331 * @param {?} _renderer
16332 */
16333 function NgClass(_iterableDiffers, _keyValueDiffers, _ngEl, _renderer) {
16334 this._iterableDiffers = _iterableDiffers;
16335 this._keyValueDiffers = _keyValueDiffers;
16336 this._ngEl = _ngEl;
16337 this._renderer = _renderer;
16338 this._initialClasses = [];
16339 }
16340 Object.defineProperty(NgClass.prototype, "klass", {
16341 /**
16342 * @param {?} v
16343 * @return {?}
16344 */
16345 set: function (v) {
16346 this._applyInitialClasses(true);
16347 this._initialClasses = typeof v === 'string' ? v.split(/\s+/) : [];
16348 this._applyInitialClasses(false);
16349 this._applyClasses(this._rawClass, false);
16350 },
16351 enumerable: true,
16352 configurable: true
16353 });
16354 Object.defineProperty(NgClass.prototype, "ngClass", {
16355 /**
16356 * @param {?} v
16357 * @return {?}
16358 */
16359 set: function (v) {
16360 this._cleanupClasses(this._rawClass);
16361 this._iterableDiffer = null;
16362 this._keyValueDiffer = null;
16363 this._rawClass = typeof v === 'string' ? v.split(/\s+/) : v;
16364 if (this._rawClass) {
16365 if (isListLikeIterable(this._rawClass)) {
16366 this._iterableDiffer = this._iterableDiffers.find(this._rawClass).create();
16367 }
16368 else {
16369 this._keyValueDiffer = this._keyValueDiffers.find(this._rawClass).create();
16370 }
16371 }
16372 },
16373 enumerable: true,
16374 configurable: true
16375 });
16376 /**
16377 * @return {?}
16378 */
16379 NgClass.prototype.ngDoCheck = function () {
16380 if (this._iterableDiffer) {
16381 var /** @type {?} */ iterableChanges = this._iterableDiffer.diff(/** @type {?} */ (this._rawClass));
16382 if (iterableChanges) {
16383 this._applyIterableChanges(iterableChanges);
16384 }
16385 }
16386 else if (this._keyValueDiffer) {
16387 var /** @type {?} */ keyValueChanges = this._keyValueDiffer.diff(/** @type {?} */ (this._rawClass));
16388 if (keyValueChanges) {
16389 this._applyKeyValueChanges(keyValueChanges);
16390 }
16391 }
16392 };
16393 /**
16394 * @param {?} rawClassVal
16395 * @return {?}
16396 */
16397 NgClass.prototype._cleanupClasses = function (rawClassVal) {
16398 this._applyClasses(rawClassVal, true);
16399 this._applyInitialClasses(false);
16400 };
16401 /**
16402 * @param {?} changes
16403 * @return {?}
16404 */
16405 NgClass.prototype._applyKeyValueChanges = function (changes) {
16406 var _this = this;
16407 changes.forEachAddedItem(function (record) { return _this._toggleClass(record.key, record.currentValue); });
16408 changes.forEachChangedItem(function (record) { return _this._toggleClass(record.key, record.currentValue); });
16409 changes.forEachRemovedItem(function (record) {
16410 if (record.previousValue) {
16411 _this._toggleClass(record.key, false);
16412 }
16413 });
16414 };
16415 /**
16416 * @param {?} changes
16417 * @return {?}
16418 */
16419 NgClass.prototype._applyIterableChanges = function (changes) {
16420 var _this = this;
16421 changes.forEachAddedItem(function (record) {
16422 if (typeof record.item === 'string') {
16423 _this._toggleClass(record.item, true);
16424 }
16425 else {
16426 throw new Error("NgClass can only toggle CSS classes expressed as strings, got " + stringify(record.item));
16427 }
16428 });
16429 changes.forEachRemovedItem(function (record) { return _this._toggleClass(record.item, false); });
16430 };
16431 /**
16432 * @param {?} isCleanup
16433 * @return {?}
16434 */
16435 NgClass.prototype._applyInitialClasses = function (isCleanup) {
16436 var _this = this;
16437 this._initialClasses.forEach(function (klass) { return _this._toggleClass(klass, !isCleanup); });
16438 };
16439 /**
16440 * @param {?} rawClassVal
16441 * @param {?} isCleanup
16442 * @return {?}
16443 */
16444 NgClass.prototype._applyClasses = function (rawClassVal, isCleanup) {
16445 var _this = this;
16446 if (rawClassVal) {
16447 if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) {
16448 ((rawClassVal)).forEach(function (klass) { return _this._toggleClass(klass, !isCleanup); });
16449 }
16450 else {
16451 Object.keys(rawClassVal).forEach(function (klass) {
16452 if (rawClassVal[klass] != null)
16453 _this._toggleClass(klass, !isCleanup);
16454 });
16455 }
16456 }
16457 };
16458 /**
16459 * @param {?} klass
16460 * @param {?} enabled
16461 * @return {?}
16462 */
16463 NgClass.prototype._toggleClass = function (klass, enabled) {
16464 var _this = this;
16465 klass = klass.trim();
16466 if (klass) {
16467 klass.split(/\s+/g).forEach(function (klass) { _this._renderer.setElementClass(_this._ngEl.nativeElement, klass, !!enabled); });
16468 }
16469 };
16470 return NgClass;
16471}());
16472NgClass.decorators = [
16473 { type: Directive, args: [{ selector: '[ngClass]' },] },
16474];
16475/**
16476 * @nocollapse
16477 */
16478NgClass.ctorParameters = function () { return [
16479 { type: IterableDiffers, },
16480 { type: KeyValueDiffers, },
16481 { type: ElementRef, },
16482 { type: Renderer, },
16483]; };
16484NgClass.propDecorators = {
16485 'klass': [{ type: Input, args: ['class',] },],
16486 'ngClass': [{ type: Input },],
16487};
16488/**
16489 * @license
16490 * Copyright Google Inc. All Rights Reserved.
16491 *
16492 * Use of this source code is governed by an MIT-style license that can be
16493 * found in the LICENSE file at https://angular.io/license
16494 */
16495/**
16496 * Instantiates a single {\@link Component} type and inserts its Host View into current View.
16497 * `NgComponentOutlet` provides a declarative approach for dynamic component creation.
16498 *
16499 * `NgComponentOutlet` requires a component type, if a falsy value is set the view will clear and
16500 * any existing component will get destroyed.
16501 *
16502 * ### Fine tune control
16503 *
16504 * You can control the component creation process by using the following optional attributes:
16505 *
16506 * * `ngComponentOutletInjector`: Optional custom {\@link Injector} that will be used as parent for
16507 * the Component. Defaults to the injector of the current view container.
16508 *
16509 * * `ngComponentOutletContent`: Optional list of projectable nodes to insert into the content
16510 * section of the component, if exists.
16511 *
16512 * * `ngComponentOutletNgModuleFactory`: Optional module factory to allow dynamically loading other
16513 * module, then load a component from that module.
16514 *
16515 * ### Syntax
16516 *
16517 * Simple
16518 * ```
16519 * <ng-container *ngComponentOutlet="componentTypeExpression"></ng-container>
16520 * ```
16521 *
16522 * Customized injector/content
16523 * ```
16524 * <ng-container *ngComponentOutlet="componentTypeExpression;
16525 * injector: injectorExpression;
16526 * content: contentNodesExpression;">
16527 * </ng-container>
16528 * ```
16529 *
16530 * Customized ngModuleFactory
16531 * ```
16532 * <ng-container *ngComponentOutlet="componentTypeExpression;
16533 * ngModuleFactory: moduleFactory;">
16534 * </ng-container>
16535 * ```
16536 * ## Example
16537 *
16538 * {\@example common/ngComponentOutlet/ts/module.ts region='SimpleExample'}
16539 *
16540 * A more complete example with additional options:
16541 *
16542 * {\@example common/ngComponentOutlet/ts/module.ts region='CompleteExample'}
16543 * A more complete example with ngModuleFactory:
16544 *
16545 * {\@example common/ngComponentOutlet/ts/module.ts region='NgModuleFactoryExample'}
16546 *
16547 * \@experimental
16548 */
16549var NgComponentOutlet = (function () {
16550 /**
16551 * @param {?} _viewContainerRef
16552 */
16553 function NgComponentOutlet(_viewContainerRef) {
16554 this._viewContainerRef = _viewContainerRef;
16555 this._componentRef = null;
16556 this._moduleRef = null;
16557 }
16558 /**
16559 * @param {?} changes
16560 * @return {?}
16561 */
16562 NgComponentOutlet.prototype.ngOnChanges = function (changes) {
16563 this._viewContainerRef.clear();
16564 this._componentRef = null;
16565 if (this.ngComponentOutlet) {
16566 var /** @type {?} */ elInjector = this.ngComponentOutletInjector || this._viewContainerRef.parentInjector;
16567 if (changes['ngComponentOutletNgModuleFactory']) {
16568 if (this._moduleRef)
16569 this._moduleRef.destroy();
16570 if (this.ngComponentOutletNgModuleFactory) {
16571 var /** @type {?} */ parentModule = elInjector.get(NgModuleRef);
16572 this._moduleRef = this.ngComponentOutletNgModuleFactory.create(parentModule.injector);
16573 }
16574 else {
16575 this._moduleRef = null;
16576 }
16577 }
16578 var /** @type {?} */ componentFactoryResolver = this._moduleRef ? this._moduleRef.componentFactoryResolver :
16579 elInjector.get(ComponentFactoryResolver);
16580 var /** @type {?} */ componentFactory = componentFactoryResolver.resolveComponentFactory(this.ngComponentOutlet);
16581 this._componentRef = this._viewContainerRef.createComponent(componentFactory, this._viewContainerRef.length, elInjector, this.ngComponentOutletContent);
16582 }
16583 };
16584 /**
16585 * @return {?}
16586 */
16587 NgComponentOutlet.prototype.ngOnDestroy = function () {
16588 if (this._moduleRef)
16589 this._moduleRef.destroy();
16590 };
16591 return NgComponentOutlet;
16592}());
16593NgComponentOutlet.decorators = [
16594 { type: Directive, args: [{ selector: '[ngComponentOutlet]' },] },
16595];
16596/**
16597 * @nocollapse
16598 */
16599NgComponentOutlet.ctorParameters = function () { return [
16600 { type: ViewContainerRef, },
16601]; };
16602NgComponentOutlet.propDecorators = {
16603 'ngComponentOutlet': [{ type: Input },],
16604 'ngComponentOutletInjector': [{ type: Input },],
16605 'ngComponentOutletContent': [{ type: Input },],
16606 'ngComponentOutletNgModuleFactory': [{ type: Input },],
16607};
16608/**
16609 * @license
16610 * Copyright Google Inc. All Rights Reserved.
16611 *
16612 * Use of this source code is governed by an MIT-style license that can be
16613 * found in the LICENSE file at https://angular.io/license
16614 */
16615/**
16616 * \@stable
16617 */
16618var NgForOfContext = (function () {
16619 /**
16620 * @param {?} $implicit
16621 * @param {?} ngForOf
16622 * @param {?} index
16623 * @param {?} count
16624 */
16625 function NgForOfContext($implicit, ngForOf, index, count) {
16626 this.$implicit = $implicit;
16627 this.ngForOf = ngForOf;
16628 this.index = index;
16629 this.count = count;
16630 }
16631 Object.defineProperty(NgForOfContext.prototype, "first", {
16632 /**
16633 * @return {?}
16634 */
16635 get: function () { return this.index === 0; },
16636 enumerable: true,
16637 configurable: true
16638 });
16639 Object.defineProperty(NgForOfContext.prototype, "last", {
16640 /**
16641 * @return {?}
16642 */
16643 get: function () { return this.index === this.count - 1; },
16644 enumerable: true,
16645 configurable: true
16646 });
16647 Object.defineProperty(NgForOfContext.prototype, "even", {
16648 /**
16649 * @return {?}
16650 */
16651 get: function () { return this.index % 2 === 0; },
16652 enumerable: true,
16653 configurable: true
16654 });
16655 Object.defineProperty(NgForOfContext.prototype, "odd", {
16656 /**
16657 * @return {?}
16658 */
16659 get: function () { return !this.even; },
16660 enumerable: true,
16661 configurable: true
16662 });
16663 return NgForOfContext;
16664}());
16665/**
16666 * The `NgForOf` directive instantiates a template once per item from an iterable. The context
16667 * for each instantiated template inherits from the outer context with the given loop variable
16668 * set to the current item from the iterable.
16669 *
16670 * ### Local Variables
16671 *
16672 * `NgForOf` provides several exported values that can be aliased to local variables:
16673 *
16674 * - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
16675 * - `ngForOf: NgIterable<T>`: The value of the iterable expression. Useful when the expression is
16676 * more complex then a property access, for example when using the async pipe (`userStreams |
16677 * async`).
16678 * - `index: number`: The index of the current item in the iterable.
16679 * - `first: boolean`: True when the item is the first item in the iterable.
16680 * - `last: boolean`: True when the item is the last item in the iterable.
16681 * - `even: boolean`: True when the item has an even index in the iterable.
16682 * - `odd: boolean`: True when the item has an odd index in the iterable.
16683 *
16684 * ```
16685 * <li *ngFor="let user of userObservable | async as users; index as i; first as isFirst">
16686 * {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
16687 * </li>
16688 * ```
16689 *
16690 * ### Change Propagation
16691 *
16692 * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
16693 *
16694 * * When an item is added, a new instance of the template is added to the DOM.
16695 * * When an item is removed, its template instance is removed from the DOM.
16696 * * When items are reordered, their respective templates are reordered in the DOM.
16697 * * Otherwise, the DOM element for that item will remain the same.
16698 *
16699 * Angular uses object identity to track insertions and deletions within the iterator and reproduce
16700 * those changes in the DOM. This has important implications for animations and any stateful
16701 * controls (such as `<input>` elements which accept user input) that are present. Inserted rows can
16702 * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
16703 * such as user input.
16704 *
16705 * It is possible for the identities of elements in the iterator to change while the data does not.
16706 * This can happen, for example, if the iterator produced from an RPC to the server, and that
16707 * RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
16708 * different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
16709 * elements were deleted and all new elements inserted). This is an expensive operation and should
16710 * be avoided if possible.
16711 *
16712 * To customize the default tracking algorithm, `NgForOf` supports `trackBy` option.
16713 * `trackBy` takes a function which has two arguments: `index` and `item`.
16714 * If `trackBy` is given, Angular tracks changes by the return value of the function.
16715 *
16716 * ### Syntax
16717 *
16718 * - `<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>`
16719 * - `<li template="ngFor let item of items; index as i; trackBy: trackByFn">...</li>`
16720 *
16721 * With `<ng-template>` element:
16722 *
16723 * ```
16724 * <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
16725 * <li>...</li>
16726 * </ng-template>
16727 * ```
16728 *
16729 * ### Example
16730 *
16731 * See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed
16732 * example.
16733 *
16734 * \@stable
16735 */
16736var NgForOf = (function () {
16737 /**
16738 * @param {?} _viewContainer
16739 * @param {?} _template
16740 * @param {?} _differs
16741 */
16742 function NgForOf(_viewContainer, _template, _differs) {
16743 this._viewContainer = _viewContainer;
16744 this._template = _template;
16745 this._differs = _differs;
16746 this._differ = null;
16747 }
16748 Object.defineProperty(NgForOf.prototype, "ngForTrackBy", {
16749 /**
16750 * @return {?}
16751 */
16752 get: function () { return this._trackByFn; },
16753 /**
16754 * @param {?} fn
16755 * @return {?}
16756 */
16757 set: function (fn) {
16758 if (isDevMode() && fn != null && typeof fn !== 'function') {
16759 // TODO(vicb): use a log service once there is a public one available
16760 if ((console) && (console.warn)) {
16761 console.warn("trackBy must be a function, but received " + JSON.stringify(fn) + ". " +
16762 "See https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html#!#change-propagation for more information.");
16763 }
16764 }
16765 this._trackByFn = fn;
16766 },
16767 enumerable: true,
16768 configurable: true
16769 });
16770 Object.defineProperty(NgForOf.prototype, "ngForTemplate", {
16771 /**
16772 * @param {?} value
16773 * @return {?}
16774 */
16775 set: function (value) {
16776 // TODO(TS2.1): make TemplateRef<Partial<NgForRowOf<T>>> once we move to TS v2.1
16777 // The current type is too restrictive; a template that just uses index, for example,
16778 // should be acceptable.
16779 if (value) {
16780 this._template = value;
16781 }
16782 },
16783 enumerable: true,
16784 configurable: true
16785 });
16786 /**
16787 * @param {?} changes
16788 * @return {?}
16789 */
16790 NgForOf.prototype.ngOnChanges = function (changes) {
16791 if ('ngForOf' in changes) {
16792 // React on ngForOf changes only once all inputs have been initialized
16793 var /** @type {?} */ value = changes['ngForOf'].currentValue;
16794 if (!this._differ && value) {
16795 try {
16796 this._differ = this._differs.find(value).create(this.ngForTrackBy);
16797 }
16798 catch (e) {
16799 throw new Error("Cannot find a differ supporting object '" + value + "' of type '" + getTypeNameForDebugging$1(value) + "'. NgFor only supports binding to Iterables such as Arrays.");
16800 }
16801 }
16802 }
16803 };
16804 /**
16805 * @return {?}
16806 */
16807 NgForOf.prototype.ngDoCheck = function () {
16808 if (this._differ) {
16809 var /** @type {?} */ changes = this._differ.diff(this.ngForOf);
16810 if (changes)
16811 this._applyChanges(changes);
16812 }
16813 };
16814 /**
16815 * @param {?} changes
16816 * @return {?}
16817 */
16818 NgForOf.prototype._applyChanges = function (changes) {
16819 var _this = this;
16820 var /** @type {?} */ insertTuples = [];
16821 changes.forEachOperation(function (item, adjustedPreviousIndex, currentIndex) {
16822 if (item.previousIndex == null) {
16823 var /** @type {?} */ view = _this._viewContainer.createEmbeddedView(_this._template, new NgForOfContext(/** @type {?} */ ((null)), _this.ngForOf, -1, -1), currentIndex);
16824 var /** @type {?} */ tuple = new RecordViewTuple(item, view);
16825 insertTuples.push(tuple);
16826 }
16827 else if (currentIndex == null) {
16828 _this._viewContainer.remove(adjustedPreviousIndex);
16829 }
16830 else {
16831 var /** @type {?} */ view = ((_this._viewContainer.get(adjustedPreviousIndex)));
16832 _this._viewContainer.move(view, currentIndex);
16833 var /** @type {?} */ tuple = new RecordViewTuple(item, /** @type {?} */ (view));
16834 insertTuples.push(tuple);
16835 }
16836 });
16837 for (var /** @type {?} */ i = 0; i < insertTuples.length; i++) {
16838 this._perViewChange(insertTuples[i].view, insertTuples[i].record);
16839 }
16840 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = this._viewContainer.length; i < ilen; i++) {
16841 var /** @type {?} */ viewRef = (this._viewContainer.get(i));
16842 viewRef.context.index = i;
16843 viewRef.context.count = ilen;
16844 }
16845 changes.forEachIdentityChange(function (record) {
16846 var /** @type {?} */ viewRef = (_this._viewContainer.get(record.currentIndex));
16847 viewRef.context.$implicit = record.item;
16848 });
16849 };
16850 /**
16851 * @param {?} view
16852 * @param {?} record
16853 * @return {?}
16854 */
16855 NgForOf.prototype._perViewChange = function (view, record) {
16856 view.context.$implicit = record.item;
16857 };
16858 return NgForOf;
16859}());
16860NgForOf.decorators = [
16861 { type: Directive, args: [{ selector: '[ngFor][ngForOf]' },] },
16862];
16863/**
16864 * @nocollapse
16865 */
16866NgForOf.ctorParameters = function () { return [
16867 { type: ViewContainerRef, },
16868 { type: TemplateRef, },
16869 { type: IterableDiffers, },
16870]; };
16871NgForOf.propDecorators = {
16872 'ngForOf': [{ type: Input },],
16873 'ngForTrackBy': [{ type: Input },],
16874 'ngForTemplate': [{ type: Input },],
16875};
16876var RecordViewTuple = (function () {
16877 /**
16878 * @param {?} record
16879 * @param {?} view
16880 */
16881 function RecordViewTuple(record, view) {
16882 this.record = record;
16883 this.view = view;
16884 }
16885 return RecordViewTuple;
16886}());
16887/**
16888 * @param {?} type
16889 * @return {?}
16890 */
16891function getTypeNameForDebugging$1(type) {
16892 return type['name'] || typeof type;
16893}
16894/**
16895 * @license
16896 * Copyright Google Inc. All Rights Reserved.
16897 *
16898 * Use of this source code is governed by an MIT-style license that can be
16899 * found in the LICENSE file at https://angular.io/license
16900 */
16901/**
16902 * Conditionally includes a template based on the value of an `expression`.
16903 *
16904 * `ngIf` evaluates the `expression` and then renders the `then` or `else` template in its place
16905 * when expression is truthy or falsy respectively. Typically the:
16906 * - `then` template is the inline template of `ngIf` unless bound to a different value.
16907 * - `else` template is blank unless it is bound.
16908 *
16909 * ## Most common usage
16910 *
16911 * The most common usage of the `ngIf` directive is to conditionally show the inline template as
16912 * seen in this example:
16913 * {\@example common/ngIf/ts/module.ts region='NgIfSimple'}
16914 *
16915 * ## Showing an alternative template using `else`
16916 *
16917 * If it is necessary to display a template when the `expression` is falsy use the `else` template
16918 * binding as shown. Note that the `else` binding points to a `<ng-template>` labeled `#elseBlock`.
16919 * The template can be defined anywhere in the component view but is typically placed right after
16920 * `ngIf` for readability.
16921 *
16922 * {\@example common/ngIf/ts/module.ts region='NgIfElse'}
16923 *
16924 * ## Using non-inlined `then` template
16925 *
16926 * Usually the `then` template is the inlined template of the `ngIf`, but it can be changed using
16927 * a binding (just like `else`). Because `then` and `else` are bindings, the template references can
16928 * change at runtime as shown in this example.
16929 *
16930 * {\@example common/ngIf/ts/module.ts region='NgIfThenElse'}
16931 *
16932 * ## Storing conditional result in a variable
16933 *
16934 * A common pattern is that we need to show a set of properties from the same object. If the
16935 * object is undefined, then we have to use the safe-traversal-operator `?.` to guard against
16936 * dereferencing a `null` value. This is especially the case when waiting on async data such as
16937 * when using the `async` pipe as shown in following example:
16938 *
16939 * ```
16940 * Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
16941 * ```
16942 *
16943 * There are several inefficiencies in the above example:
16944 * - We create multiple subscriptions on `userStream`. One for each `async` pipe, or two in the
16945 * example above.
16946 * - We cannot display an alternative screen while waiting for the data to arrive asynchronously.
16947 * - We have to use the safe-traversal-operator `?.` to access properties, which is cumbersome.
16948 * - We have to place the `async` pipe in parenthesis.
16949 *
16950 * A better way to do this is to use `ngIf` and store the result of the condition in a local
16951 * variable as shown in the the example below:
16952 *
16953 * {\@example common/ngIf/ts/module.ts region='NgIfAs'}
16954 *
16955 * Notice that:
16956 * - We use only one `async` pipe and hence only one subscription gets created.
16957 * - `ngIf` stores the result of the `userStream|async` in the local variable `user`.
16958 * - The local `user` can then be bound repeatedly in a more efficient way.
16959 * - No need to use the safe-traversal-operator `?.` to access properties as `ngIf` will only
16960 * display the data if `userStream` returns a value.
16961 * - We can display an alternative template while waiting for the data.
16962 *
16963 * ### Syntax
16964 *
16965 * Simple form:
16966 * - `<div *ngIf="condition">...</div>`
16967 * - `<div template="ngIf condition">...</div>`
16968 * - `<ng-template [ngIf]="condition"><div>...</div></ng-template>`
16969 *
16970 * Form with an else block:
16971 * ```
16972 * <div *ngIf="condition; else elseBlock">...</div>
16973 * <ng-template #elseBlock>...</ng-template>
16974 * ```
16975 *
16976 * Form with a `then` and `else` block:
16977 * ```
16978 * <div *ngIf="condition; then thenBlock else elseBlock"></div>
16979 * <ng-template #thenBlock>...</ng-template>
16980 * <ng-template #elseBlock>...</ng-template>
16981 * ```
16982 *
16983 * Form with storing the value locally:
16984 * ```
16985 * <div *ngIf="condition as value; else elseBlock">{{value}}</div>
16986 * <ng-template #elseBlock>...</ng-template>
16987 * ```
16988 *
16989 * \@stable
16990 */
16991var NgIf = (function () {
16992 /**
16993 * @param {?} _viewContainer
16994 * @param {?} templateRef
16995 */
16996 function NgIf(_viewContainer, templateRef) {
16997 this._viewContainer = _viewContainer;
16998 this._context = new NgIfContext();
16999 this._thenTemplateRef = null;
17000 this._elseTemplateRef = null;
17001 this._thenViewRef = null;
17002 this._elseViewRef = null;
17003 this._thenTemplateRef = templateRef;
17004 }
17005 Object.defineProperty(NgIf.prototype, "ngIf", {
17006 /**
17007 * @param {?} condition
17008 * @return {?}
17009 */
17010 set: function (condition) {
17011 this._context.$implicit = this._context.ngIf = condition;
17012 this._updateView();
17013 },
17014 enumerable: true,
17015 configurable: true
17016 });
17017 Object.defineProperty(NgIf.prototype, "ngIfThen", {
17018 /**
17019 * @param {?} templateRef
17020 * @return {?}
17021 */
17022 set: function (templateRef) {
17023 this._thenTemplateRef = templateRef;
17024 this._thenViewRef = null; // clear previous view if any.
17025 this._updateView();
17026 },
17027 enumerable: true,
17028 configurable: true
17029 });
17030 Object.defineProperty(NgIf.prototype, "ngIfElse", {
17031 /**
17032 * @param {?} templateRef
17033 * @return {?}
17034 */
17035 set: function (templateRef) {
17036 this._elseTemplateRef = templateRef;
17037 this._elseViewRef = null; // clear previous view if any.
17038 this._updateView();
17039 },
17040 enumerable: true,
17041 configurable: true
17042 });
17043 /**
17044 * @return {?}
17045 */
17046 NgIf.prototype._updateView = function () {
17047 if (this._context.$implicit) {
17048 if (!this._thenViewRef) {
17049 this._viewContainer.clear();
17050 this._elseViewRef = null;
17051 if (this._thenTemplateRef) {
17052 this._thenViewRef =
17053 this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
17054 }
17055 }
17056 }
17057 else {
17058 if (!this._elseViewRef) {
17059 this._viewContainer.clear();
17060 this._thenViewRef = null;
17061 if (this._elseTemplateRef) {
17062 this._elseViewRef =
17063 this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
17064 }
17065 }
17066 }
17067 };
17068 return NgIf;
17069}());
17070NgIf.decorators = [
17071 { type: Directive, args: [{ selector: '[ngIf]' },] },
17072];
17073/**
17074 * @nocollapse
17075 */
17076NgIf.ctorParameters = function () { return [
17077 { type: ViewContainerRef, },
17078 { type: TemplateRef, },
17079]; };
17080NgIf.propDecorators = {
17081 'ngIf': [{ type: Input },],
17082 'ngIfThen': [{ type: Input },],
17083 'ngIfElse': [{ type: Input },],
17084};
17085/**
17086 * \@stable
17087 */
17088var NgIfContext = (function () {
17089 function NgIfContext() {
17090 this.$implicit = null;
17091 this.ngIf = null;
17092 }
17093 return NgIfContext;
17094}());
17095/**
17096 * @license
17097 * Copyright Google Inc. All Rights Reserved.
17098 *
17099 * Use of this source code is governed by an MIT-style license that can be
17100 * found in the LICENSE file at https://angular.io/license
17101 */
17102var SwitchView = (function () {
17103 /**
17104 * @param {?} _viewContainerRef
17105 * @param {?} _templateRef
17106 */
17107 function SwitchView(_viewContainerRef, _templateRef) {
17108 this._viewContainerRef = _viewContainerRef;
17109 this._templateRef = _templateRef;
17110 this._created = false;
17111 }
17112 /**
17113 * @return {?}
17114 */
17115 SwitchView.prototype.create = function () {
17116 this._created = true;
17117 this._viewContainerRef.createEmbeddedView(this._templateRef);
17118 };
17119 /**
17120 * @return {?}
17121 */
17122 SwitchView.prototype.destroy = function () {
17123 this._created = false;
17124 this._viewContainerRef.clear();
17125 };
17126 /**
17127 * @param {?} created
17128 * @return {?}
17129 */
17130 SwitchView.prototype.enforceState = function (created) {
17131 if (created && !this._created) {
17132 this.create();
17133 }
17134 else if (!created && this._created) {
17135 this.destroy();
17136 }
17137 };
17138 return SwitchView;
17139}());
17140/**
17141 * \@ngModule CommonModule
17142 *
17143 * \@whatItDoes Adds / removes DOM sub-trees when the nest match expressions matches the switch
17144 * expression.
17145 *
17146 * \@howToUse
17147 * ```
17148 * <container-element [ngSwitch]="switch_expression">
17149 * <some-element *ngSwitchCase="match_expression_1">...</some-element>
17150 * <some-element *ngSwitchCase="match_expression_2">...</some-element>
17151 * <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
17152 * <ng-container *ngSwitchCase="match_expression_3">
17153 * <!-- use a ng-container to group multiple root nodes -->
17154 * <inner-element></inner-element>
17155 * <inner-other-element></inner-other-element>
17156 * </ng-container>
17157 * <some-element *ngSwitchDefault>...</some-element>
17158 * </container-element>
17159 * ```
17160 * \@description
17161 *
17162 * `NgSwitch` stamps out nested views when their match expression value matches the value of the
17163 * switch expression.
17164 *
17165 * In other words:
17166 * - you define a container element (where you place the directive with a switch expression on the
17167 * `[ngSwitch]="..."` attribute)
17168 * - you define inner views inside the `NgSwitch` and place a `*ngSwitchCase` attribute on the view
17169 * root elements.
17170 *
17171 * Elements within `NgSwitch` but outside of a `NgSwitchCase` or `NgSwitchDefault` directives will
17172 * be preserved at the location.
17173 *
17174 * The `ngSwitchCase` directive informs the parent `NgSwitch` of which view to display when the
17175 * expression is evaluated.
17176 * When no matching expression is found on a `ngSwitchCase` view, the `ngSwitchDefault` view is
17177 * stamped out.
17178 *
17179 * \@stable
17180 */
17181var NgSwitch = (function () {
17182 function NgSwitch() {
17183 this._defaultUsed = false;
17184 this._caseCount = 0;
17185 this._lastCaseCheckIndex = 0;
17186 this._lastCasesMatched = false;
17187 }
17188 Object.defineProperty(NgSwitch.prototype, "ngSwitch", {
17189 /**
17190 * @param {?} newValue
17191 * @return {?}
17192 */
17193 set: function (newValue) {
17194 this._ngSwitch = newValue;
17195 if (this._caseCount === 0) {
17196 this._updateDefaultCases(true);
17197 }
17198 },
17199 enumerable: true,
17200 configurable: true
17201 });
17202 /**
17203 * \@internal
17204 * @return {?}
17205 */
17206 NgSwitch.prototype._addCase = function () { return this._caseCount++; };
17207 /**
17208 * \@internal
17209 * @param {?} view
17210 * @return {?}
17211 */
17212 NgSwitch.prototype._addDefault = function (view) {
17213 if (!this._defaultViews) {
17214 this._defaultViews = [];
17215 }
17216 this._defaultViews.push(view);
17217 };
17218 /**
17219 * \@internal
17220 * @param {?} value
17221 * @return {?}
17222 */
17223 NgSwitch.prototype._matchCase = function (value) {
17224 var /** @type {?} */ matched = value == this._ngSwitch;
17225 this._lastCasesMatched = this._lastCasesMatched || matched;
17226 this._lastCaseCheckIndex++;
17227 if (this._lastCaseCheckIndex === this._caseCount) {
17228 this._updateDefaultCases(!this._lastCasesMatched);
17229 this._lastCaseCheckIndex = 0;
17230 this._lastCasesMatched = false;
17231 }
17232 return matched;
17233 };
17234 /**
17235 * @param {?} useDefault
17236 * @return {?}
17237 */
17238 NgSwitch.prototype._updateDefaultCases = function (useDefault) {
17239 if (this._defaultViews && useDefault !== this._defaultUsed) {
17240 this._defaultUsed = useDefault;
17241 for (var /** @type {?} */ i = 0; i < this._defaultViews.length; i++) {
17242 var /** @type {?} */ defaultView = this._defaultViews[i];
17243 defaultView.enforceState(useDefault);
17244 }
17245 }
17246 };
17247 return NgSwitch;
17248}());
17249NgSwitch.decorators = [
17250 { type: Directive, args: [{ selector: '[ngSwitch]' },] },
17251];
17252/**
17253 * @nocollapse
17254 */
17255NgSwitch.ctorParameters = function () { return []; };
17256NgSwitch.propDecorators = {
17257 'ngSwitch': [{ type: Input },],
17258};
17259/**
17260 * \@ngModule CommonModule
17261 *
17262 * \@whatItDoes Creates a view that will be added/removed from the parent {\@link NgSwitch} when the
17263 * given expression evaluate to respectively the same/different value as the switch
17264 * expression.
17265 *
17266 * \@howToUse
17267 * ```
17268 * <container-element [ngSwitch]="switch_expression">
17269 * <some-element *ngSwitchCase="match_expression_1">...</some-element>
17270 * </container-element>
17271 * ```
17272 * \@description
17273 *
17274 * Insert the sub-tree when the expression evaluates to the same value as the enclosing switch
17275 * expression.
17276 *
17277 * If multiple match expressions match the switch expression value, all of them are displayed.
17278 *
17279 * See {\@link NgSwitch} for more details and example.
17280 *
17281 * \@stable
17282 */
17283var NgSwitchCase = (function () {
17284 /**
17285 * @param {?} viewContainer
17286 * @param {?} templateRef
17287 * @param {?} ngSwitch
17288 */
17289 function NgSwitchCase(viewContainer, templateRef, ngSwitch) {
17290 this.ngSwitch = ngSwitch;
17291 ngSwitch._addCase();
17292 this._view = new SwitchView(viewContainer, templateRef);
17293 }
17294 /**
17295 * @return {?}
17296 */
17297 NgSwitchCase.prototype.ngDoCheck = function () { this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase)); };
17298 return NgSwitchCase;
17299}());
17300NgSwitchCase.decorators = [
17301 { type: Directive, args: [{ selector: '[ngSwitchCase]' },] },
17302];
17303/**
17304 * @nocollapse
17305 */
17306NgSwitchCase.ctorParameters = function () { return [
17307 { type: ViewContainerRef, },
17308 { type: TemplateRef, },
17309 { type: NgSwitch, decorators: [{ type: Host },] },
17310]; };
17311NgSwitchCase.propDecorators = {
17312 'ngSwitchCase': [{ type: Input },],
17313};
17314/**
17315 * \@ngModule CommonModule
17316 * \@whatItDoes Creates a view that is added to the parent {\@link NgSwitch} when no case expressions
17317 * match the
17318 * switch expression.
17319 *
17320 * \@howToUse
17321 * ```
17322 * <container-element [ngSwitch]="switch_expression">
17323 * <some-element *ngSwitchCase="match_expression_1">...</some-element>
17324 * <some-other-element *ngSwitchDefault>...</some-other-element>
17325 * </container-element>
17326 * ```
17327 *
17328 * \@description
17329 *
17330 * Insert the sub-tree when no case expressions evaluate to the same value as the enclosing switch
17331 * expression.
17332 *
17333 * See {\@link NgSwitch} for more details and example.
17334 *
17335 * \@stable
17336 */
17337var NgSwitchDefault = (function () {
17338 /**
17339 * @param {?} viewContainer
17340 * @param {?} templateRef
17341 * @param {?} ngSwitch
17342 */
17343 function NgSwitchDefault(viewContainer, templateRef, ngSwitch) {
17344 ngSwitch._addDefault(new SwitchView(viewContainer, templateRef));
17345 }
17346 return NgSwitchDefault;
17347}());
17348NgSwitchDefault.decorators = [
17349 { type: Directive, args: [{ selector: '[ngSwitchDefault]' },] },
17350];
17351/**
17352 * @nocollapse
17353 */
17354NgSwitchDefault.ctorParameters = function () { return [
17355 { type: ViewContainerRef, },
17356 { type: TemplateRef, },
17357 { type: NgSwitch, decorators: [{ type: Host },] },
17358]; };
17359/**
17360 * @license
17361 * Copyright Google Inc. All Rights Reserved.
17362 *
17363 * Use of this source code is governed by an MIT-style license that can be
17364 * found in the LICENSE file at https://angular.io/license
17365 */
17366/**
17367 * \@ngModule CommonModule
17368 *
17369 * \@whatItDoes Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
17370 *
17371 * \@howToUse
17372 * ```
17373 * <some-element [ngPlural]="value">
17374 * <ng-template ngPluralCase="=0">there is nothing</ng-template>
17375 * <ng-template ngPluralCase="=1">there is one</ng-template>
17376 * <ng-template ngPluralCase="few">there are a few</ng-template>
17377 * </some-element>
17378 * ```
17379 *
17380 * \@description
17381 *
17382 * Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
17383 * that match the switch expression's pluralization category.
17384 *
17385 * To use this directive you must provide a container element that sets the `[ngPlural]` attribute
17386 * to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
17387 * expression:
17388 * - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
17389 * matches the switch expression exactly,
17390 * - otherwise, the view will be treated as a "category match", and will only display if exact
17391 * value matches aren't found and the value maps to its category for the defined locale.
17392 *
17393 * See http://cldr.unicode.org/index/cldr-spec/plural-rules
17394 *
17395 * \@experimental
17396 */
17397var NgPlural = (function () {
17398 /**
17399 * @param {?} _localization
17400 */
17401 function NgPlural(_localization) {
17402 this._localization = _localization;
17403 this._caseViews = {};
17404 }
17405 Object.defineProperty(NgPlural.prototype, "ngPlural", {
17406 /**
17407 * @param {?} value
17408 * @return {?}
17409 */
17410 set: function (value) {
17411 this._switchValue = value;
17412 this._updateView();
17413 },
17414 enumerable: true,
17415 configurable: true
17416 });
17417 /**
17418 * @param {?} value
17419 * @param {?} switchView
17420 * @return {?}
17421 */
17422 NgPlural.prototype.addCase = function (value, switchView) { this._caseViews[value] = switchView; };
17423 /**
17424 * @return {?}
17425 */
17426 NgPlural.prototype._updateView = function () {
17427 this._clearViews();
17428 var /** @type {?} */ cases = Object.keys(this._caseViews);
17429 var /** @type {?} */ key = getPluralCategory(this._switchValue, cases, this._localization);
17430 this._activateView(this._caseViews[key]);
17431 };
17432 /**
17433 * @return {?}
17434 */
17435 NgPlural.prototype._clearViews = function () {
17436 if (this._activeView)
17437 this._activeView.destroy();
17438 };
17439 /**
17440 * @param {?} view
17441 * @return {?}
17442 */
17443 NgPlural.prototype._activateView = function (view) {
17444 if (view) {
17445 this._activeView = view;
17446 this._activeView.create();
17447 }
17448 };
17449 return NgPlural;
17450}());
17451NgPlural.decorators = [
17452 { type: Directive, args: [{ selector: '[ngPlural]' },] },
17453];
17454/**
17455 * @nocollapse
17456 */
17457NgPlural.ctorParameters = function () { return [
17458 { type: NgLocalization, },
17459]; };
17460NgPlural.propDecorators = {
17461 'ngPlural': [{ type: Input },],
17462};
17463/**
17464 * \@ngModule CommonModule
17465 *
17466 * \@whatItDoes Creates a view that will be added/removed from the parent {\@link NgPlural} when the
17467 * given expression matches the plural expression according to CLDR rules.
17468 *
17469 * \@howToUse
17470 * ```
17471 * <some-element [ngPlural]="value">
17472 * <ng-template ngPluralCase="=0">...</ng-template>
17473 * <ng-template ngPluralCase="other">...</ng-template>
17474 * </some-element>
17475 * ```
17476 *
17477 * See {\@link NgPlural} for more details and example.
17478 *
17479 * \@experimental
17480 */
17481var NgPluralCase = (function () {
17482 /**
17483 * @param {?} value
17484 * @param {?} template
17485 * @param {?} viewContainer
17486 * @param {?} ngPlural
17487 */
17488 function NgPluralCase(value, template, viewContainer, ngPlural) {
17489 this.value = value;
17490 var isANumber = !isNaN(Number(value));
17491 ngPlural.addCase(isANumber ? "=" + value : value, new SwitchView(viewContainer, template));
17492 }
17493 return NgPluralCase;
17494}());
17495NgPluralCase.decorators = [
17496 { type: Directive, args: [{ selector: '[ngPluralCase]' },] },
17497];
17498/**
17499 * @nocollapse
17500 */
17501NgPluralCase.ctorParameters = function () { return [
17502 { type: undefined, decorators: [{ type: Attribute, args: ['ngPluralCase',] },] },
17503 { type: TemplateRef, },
17504 { type: ViewContainerRef, },
17505 { type: NgPlural, decorators: [{ type: Host },] },
17506]; };
17507/**
17508 * @license
17509 * Copyright Google Inc. All Rights Reserved.
17510 *
17511 * Use of this source code is governed by an MIT-style license that can be
17512 * found in the LICENSE file at https://angular.io/license
17513 */
17514/**
17515 * \@ngModule CommonModule
17516 *
17517 * \@whatItDoes Update an HTML element styles.
17518 *
17519 * \@howToUse
17520 * ```
17521 * <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
17522 *
17523 * <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
17524 *
17525 * <some-element [ngStyle]="objExp">...</some-element>
17526 * ```
17527 *
17528 * \@description
17529 *
17530 * The styles are updated according to the value of the expression evaluation:
17531 * - keys are style names with an optional `.<unit>` suffix (ie 'top.px', 'font-style.em'),
17532 * - values are the values assigned to those properties (expressed in the given unit).
17533 *
17534 * \@stable
17535 */
17536var NgStyle = (function () {
17537 /**
17538 * @param {?} _differs
17539 * @param {?} _ngEl
17540 * @param {?} _renderer
17541 */
17542 function NgStyle(_differs, _ngEl, _renderer) {
17543 this._differs = _differs;
17544 this._ngEl = _ngEl;
17545 this._renderer = _renderer;
17546 }
17547 Object.defineProperty(NgStyle.prototype, "ngStyle", {
17548 /**
17549 * @param {?} v
17550 * @return {?}
17551 */
17552 set: function (v) {
17553 this._ngStyle = v;
17554 if (!this._differ && v) {
17555 this._differ = this._differs.find(v).create();
17556 }
17557 },
17558 enumerable: true,
17559 configurable: true
17560 });
17561 /**
17562 * @return {?}
17563 */
17564 NgStyle.prototype.ngDoCheck = function () {
17565 if (this._differ) {
17566 var /** @type {?} */ changes = this._differ.diff(this._ngStyle);
17567 if (changes) {
17568 this._applyChanges(changes);
17569 }
17570 }
17571 };
17572 /**
17573 * @param {?} changes
17574 * @return {?}
17575 */
17576 NgStyle.prototype._applyChanges = function (changes) {
17577 var _this = this;
17578 changes.forEachRemovedItem(function (record) { return _this._setStyle(record.key, null); });
17579 changes.forEachAddedItem(function (record) { return _this._setStyle(record.key, record.currentValue); });
17580 changes.forEachChangedItem(function (record) { return _this._setStyle(record.key, record.currentValue); });
17581 };
17582 /**
17583 * @param {?} nameAndUnit
17584 * @param {?} value
17585 * @return {?}
17586 */
17587 NgStyle.prototype._setStyle = function (nameAndUnit, value) {
17588 var _a = nameAndUnit.split('.'), name = _a[0], unit = _a[1];
17589 value = value != null && unit ? "" + value + unit : value;
17590 this._renderer.setElementStyle(this._ngEl.nativeElement, name, /** @type {?} */ (value));
17591 };
17592 return NgStyle;
17593}());
17594NgStyle.decorators = [
17595 { type: Directive, args: [{ selector: '[ngStyle]' },] },
17596];
17597/**
17598 * @nocollapse
17599 */
17600NgStyle.ctorParameters = function () { return [
17601 { type: KeyValueDiffers, },
17602 { type: ElementRef, },
17603 { type: Renderer, },
17604]; };
17605NgStyle.propDecorators = {
17606 'ngStyle': [{ type: Input },],
17607};
17608/**
17609 * @license
17610 * Copyright Google Inc. All Rights Reserved.
17611 *
17612 * Use of this source code is governed by an MIT-style license that can be
17613 * found in the LICENSE file at https://angular.io/license
17614 */
17615/**
17616 * \@ngModule CommonModule
17617 *
17618 * \@whatItDoes Inserts an embedded view from a prepared `TemplateRef`
17619 *
17620 * \@howToUse
17621 * ```
17622 * <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
17623 * ```
17624 *
17625 * \@description
17626 *
17627 * You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
17628 * `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
17629 * by the local template `let` declarations.
17630 *
17631 * Note: using the key `$implicit` in the context object will set it's value as default.
17632 *
17633 * ## Example
17634 *
17635 * {\@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
17636 *
17637 * \@experimental
17638 */
17639var NgTemplateOutlet = (function () {
17640 /**
17641 * @param {?} _viewContainerRef
17642 */
17643 function NgTemplateOutlet(_viewContainerRef) {
17644 this._viewContainerRef = _viewContainerRef;
17645 }
17646 Object.defineProperty(NgTemplateOutlet.prototype, "ngOutletContext", {
17647 /**
17648 * @deprecated v4.0.0 - Renamed to ngTemplateOutletContext.
17649 * @param {?} context
17650 * @return {?}
17651 */
17652 set: function (context) { this.ngTemplateOutletContext = context; },
17653 enumerable: true,
17654 configurable: true
17655 });
17656 /**
17657 * @param {?} changes
17658 * @return {?}
17659 */
17660 NgTemplateOutlet.prototype.ngOnChanges = function (changes) {
17661 if (this._viewRef) {
17662 this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
17663 }
17664 if (this.ngTemplateOutlet) {
17665 this._viewRef = this._viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, this.ngTemplateOutletContext);
17666 }
17667 };
17668 return NgTemplateOutlet;
17669}());
17670NgTemplateOutlet.decorators = [
17671 { type: Directive, args: [{ selector: '[ngTemplateOutlet]' },] },
17672];
17673/**
17674 * @nocollapse
17675 */
17676NgTemplateOutlet.ctorParameters = function () { return [
17677 { type: ViewContainerRef, },
17678]; };
17679NgTemplateOutlet.propDecorators = {
17680 'ngTemplateOutletContext': [{ type: Input },],
17681 'ngTemplateOutlet': [{ type: Input },],
17682 'ngOutletContext': [{ type: Input },],
17683};
17684/**
17685 * @license
17686 * Copyright Google Inc. All Rights Reserved.
17687 *
17688 * Use of this source code is governed by an MIT-style license that can be
17689 * found in the LICENSE file at https://angular.io/license
17690 */
17691/**
17692 * A collection of Angular directives that are likely to be used in each and every Angular
17693 * application.
17694 */
17695var COMMON_DIRECTIVES = [
17696 NgClass,
17697 NgComponentOutlet,
17698 NgForOf,
17699 NgIf,
17700 NgTemplateOutlet,
17701 NgStyle,
17702 NgSwitch,
17703 NgSwitchCase,
17704 NgSwitchDefault,
17705 NgPlural,
17706 NgPluralCase,
17707];
17708/**
17709 * A collection of deprecated directives that are no longer part of the core module.
17710 */
17711/**
17712 * @license
17713 * Copyright Google Inc. All Rights Reserved.
17714 *
17715 * Use of this source code is governed by an MIT-style license that can be
17716 * found in the LICENSE file at https://angular.io/license
17717 */
17718/**
17719 * @param {?} type
17720 * @param {?} value
17721 * @return {?}
17722 */
17723function invalidPipeArgumentError(type, value) {
17724 return Error("InvalidPipeArgument: '" + value + "' for pipe '" + stringify(type) + "'");
17725}
17726/**
17727 * @license
17728 * Copyright Google Inc. All Rights Reserved.
17729 *
17730 * Use of this source code is governed by an MIT-style license that can be
17731 * found in the LICENSE file at https://angular.io/license
17732 */
17733var ObservableStrategy = (function () {
17734 function ObservableStrategy() {
17735 }
17736 /**
17737 * @param {?} async
17738 * @param {?} updateLatestValue
17739 * @return {?}
17740 */
17741 ObservableStrategy.prototype.createSubscription = function (async, updateLatestValue) {
17742 return async.subscribe({ next: updateLatestValue, error: function (e) { throw e; } });
17743 };
17744 /**
17745 * @param {?} subscription
17746 * @return {?}
17747 */
17748 ObservableStrategy.prototype.dispose = function (subscription) { subscription.unsubscribe(); };
17749 /**
17750 * @param {?} subscription
17751 * @return {?}
17752 */
17753 ObservableStrategy.prototype.onDestroy = function (subscription) { subscription.unsubscribe(); };
17754 return ObservableStrategy;
17755}());
17756var PromiseStrategy = (function () {
17757 function PromiseStrategy() {
17758 }
17759 /**
17760 * @param {?} async
17761 * @param {?} updateLatestValue
17762 * @return {?}
17763 */
17764 PromiseStrategy.prototype.createSubscription = function (async, updateLatestValue) {
17765 return async.then(updateLatestValue, function (e) { throw e; });
17766 };
17767 /**
17768 * @param {?} subscription
17769 * @return {?}
17770 */
17771 PromiseStrategy.prototype.dispose = function (subscription) { };
17772 /**
17773 * @param {?} subscription
17774 * @return {?}
17775 */
17776 PromiseStrategy.prototype.onDestroy = function (subscription) { };
17777 return PromiseStrategy;
17778}());
17779var _promiseStrategy = new PromiseStrategy();
17780var _observableStrategy = new ObservableStrategy();
17781/**
17782 * \@ngModule CommonModule
17783 * \@whatItDoes Unwraps a value from an asynchronous primitive.
17784 * \@howToUse `observable_or_promise_expression | async`
17785 * \@description
17786 * The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has
17787 * emitted. When a new value is emitted, the `async` pipe marks the component to be checked for
17788 * changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid
17789 * potential memory leaks.
17790 *
17791 *
17792 * ## Examples
17793 *
17794 * This example binds a `Promise` to the view. Clicking the `Resolve` button resolves the
17795 * promise.
17796 *
17797 * {\@example common/pipes/ts/async_pipe.ts region='AsyncPipePromise'}
17798 *
17799 * It's also possible to use `async` with Observables. The example below binds the `time` Observable
17800 * to the view. The Observable continuously updates the view with the current time.
17801 *
17802 * {\@example common/pipes/ts/async_pipe.ts region='AsyncPipeObservable'}
17803 *
17804 * \@stable
17805 */
17806var AsyncPipe = (function () {
17807 /**
17808 * @param {?} _ref
17809 */
17810 function AsyncPipe(_ref) {
17811 this._ref = _ref;
17812 this._latestValue = null;
17813 this._latestReturnedValue = null;
17814 this._subscription = null;
17815 this._obj = null;
17816 this._strategy = ((null));
17817 }
17818 /**
17819 * @return {?}
17820 */
17821 AsyncPipe.prototype.ngOnDestroy = function () {
17822 if (this._subscription) {
17823 this._dispose();
17824 }
17825 };
17826 /**
17827 * @param {?} obj
17828 * @return {?}
17829 */
17830 AsyncPipe.prototype.transform = function (obj) {
17831 if (!this._obj) {
17832 if (obj) {
17833 this._subscribe(obj);
17834 }
17835 this._latestReturnedValue = this._latestValue;
17836 return this._latestValue;
17837 }
17838 if (obj !== this._obj) {
17839 this._dispose();
17840 return this.transform(/** @type {?} */ (obj));
17841 }
17842 if (this._latestValue === this._latestReturnedValue) {
17843 return this._latestReturnedValue;
17844 }
17845 this._latestReturnedValue = this._latestValue;
17846 return WrappedValue.wrap(this._latestValue);
17847 };
17848 /**
17849 * @param {?} obj
17850 * @return {?}
17851 */
17852 AsyncPipe.prototype._subscribe = function (obj) {
17853 var _this = this;
17854 this._obj = obj;
17855 this._strategy = this._selectStrategy(obj);
17856 this._subscription = this._strategy.createSubscription(obj, function (value) { return _this._updateLatestValue(obj, value); });
17857 };
17858 /**
17859 * @param {?} obj
17860 * @return {?}
17861 */
17862 AsyncPipe.prototype._selectStrategy = function (obj) {
17863 if (isPromise(obj)) {
17864 return _promiseStrategy;
17865 }
17866 if (isObservable(obj)) {
17867 return _observableStrategy;
17868 }
17869 throw invalidPipeArgumentError(AsyncPipe, obj);
17870 };
17871 /**
17872 * @return {?}
17873 */
17874 AsyncPipe.prototype._dispose = function () {
17875 this._strategy.dispose(/** @type {?} */ ((this._subscription)));
17876 this._latestValue = null;
17877 this._latestReturnedValue = null;
17878 this._subscription = null;
17879 this._obj = null;
17880 };
17881 /**
17882 * @param {?} async
17883 * @param {?} value
17884 * @return {?}
17885 */
17886 AsyncPipe.prototype._updateLatestValue = function (async, value) {
17887 if (async === this._obj) {
17888 this._latestValue = value;
17889 this._ref.markForCheck();
17890 }
17891 };
17892 return AsyncPipe;
17893}());
17894AsyncPipe.decorators = [
17895 { type: Pipe, args: [{ name: 'async', pure: false },] },
17896];
17897/**
17898 * @nocollapse
17899 */
17900AsyncPipe.ctorParameters = function () { return [
17901 { type: ChangeDetectorRef, },
17902]; };
17903/**
17904 * @license
17905 * Copyright Google Inc. All Rights Reserved.
17906 *
17907 * Use of this source code is governed by an MIT-style license that can be
17908 * found in the LICENSE file at https://angular.io/license
17909 */
17910/**
17911 * Transforms text to lowercase.
17912 *
17913 * {\@example common/pipes/ts/lowerupper_pipe.ts region='LowerUpperPipe' }
17914 *
17915 * \@stable
17916 */
17917var LowerCasePipe = (function () {
17918 function LowerCasePipe() {
17919 }
17920 /**
17921 * @param {?} value
17922 * @return {?}
17923 */
17924 LowerCasePipe.prototype.transform = function (value) {
17925 if (!value)
17926 return value;
17927 if (typeof value !== 'string') {
17928 throw invalidPipeArgumentError(LowerCasePipe, value);
17929 }
17930 return value.toLowerCase();
17931 };
17932 return LowerCasePipe;
17933}());
17934LowerCasePipe.decorators = [
17935 { type: Pipe, args: [{ name: 'lowercase' },] },
17936];
17937/**
17938 * @nocollapse
17939 */
17940LowerCasePipe.ctorParameters = function () { return []; };
17941/**
17942 * Helper method to transform a single word to titlecase.
17943 *
17944 * \@stable
17945 * @param {?} word
17946 * @return {?}
17947 */
17948function titleCaseWord(word) {
17949 if (!word)
17950 return word;
17951 return word[0].toUpperCase() + word.substr(1).toLowerCase();
17952}
17953/**
17954 * Transforms text to titlecase.
17955 *
17956 * \@stable
17957 */
17958var TitleCasePipe = (function () {
17959 function TitleCasePipe() {
17960 }
17961 /**
17962 * @param {?} value
17963 * @return {?}
17964 */
17965 TitleCasePipe.prototype.transform = function (value) {
17966 if (!value)
17967 return value;
17968 if (typeof value !== 'string') {
17969 throw invalidPipeArgumentError(TitleCasePipe, value);
17970 }
17971 return value.split(/\b/g).map(function (word) { return titleCaseWord(word); }).join('');
17972 };
17973 return TitleCasePipe;
17974}());
17975TitleCasePipe.decorators = [
17976 { type: Pipe, args: [{ name: 'titlecase' },] },
17977];
17978/**
17979 * @nocollapse
17980 */
17981TitleCasePipe.ctorParameters = function () { return []; };
17982/**
17983 * Transforms text to uppercase.
17984 *
17985 * \@stable
17986 */
17987var UpperCasePipe = (function () {
17988 function UpperCasePipe() {
17989 }
17990 /**
17991 * @param {?} value
17992 * @return {?}
17993 */
17994 UpperCasePipe.prototype.transform = function (value) {
17995 if (!value)
17996 return value;
17997 if (typeof value !== 'string') {
17998 throw invalidPipeArgumentError(UpperCasePipe, value);
17999 }
18000 return value.toUpperCase();
18001 };
18002 return UpperCasePipe;
18003}());
18004UpperCasePipe.decorators = [
18005 { type: Pipe, args: [{ name: 'uppercase' },] },
18006];
18007/**
18008 * @nocollapse
18009 */
18010UpperCasePipe.ctorParameters = function () { return []; };
18011var NumberFormatStyle = {};
18012NumberFormatStyle.Decimal = 0;
18013NumberFormatStyle.Percent = 1;
18014NumberFormatStyle.Currency = 2;
18015NumberFormatStyle[NumberFormatStyle.Decimal] = "Decimal";
18016NumberFormatStyle[NumberFormatStyle.Percent] = "Percent";
18017NumberFormatStyle[NumberFormatStyle.Currency] = "Currency";
18018var NumberFormatter = (function () {
18019 function NumberFormatter() {
18020 }
18021 /**
18022 * @param {?} num
18023 * @param {?} locale
18024 * @param {?} style
18025 * @param {?=} opts
18026 * @return {?}
18027 */
18028 NumberFormatter.format = function (num, locale, style$$1, opts) {
18029 if (opts === void 0) { opts = {}; }
18030 var minimumIntegerDigits = opts.minimumIntegerDigits, minimumFractionDigits = opts.minimumFractionDigits, maximumFractionDigits = opts.maximumFractionDigits, currency = opts.currency, _a = opts.currencyAsSymbol, currencyAsSymbol = _a === void 0 ? false : _a;
18031 var /** @type {?} */ options = {
18032 minimumIntegerDigits: minimumIntegerDigits,
18033 minimumFractionDigits: minimumFractionDigits,
18034 maximumFractionDigits: maximumFractionDigits,
18035 style: NumberFormatStyle[style$$1].toLowerCase()
18036 };
18037 if (style$$1 == NumberFormatStyle.Currency) {
18038 options.currency = typeof currency == 'string' ? currency : undefined;
18039 options.currencyDisplay = currencyAsSymbol ? 'symbol' : 'code';
18040 }
18041 return new Intl.NumberFormat(locale, options).format(num);
18042 };
18043 return NumberFormatter;
18044}());
18045var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsazZEwGjJ']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|J+|j+|m+|s+|a|z|Z|G+|w+))(.*)/;
18046var PATTERN_ALIASES = {
18047 // Keys are quoted so they do not get renamed during closure compilation.
18048 'yMMMdjms': datePartGetterFactory(combine([
18049 digitCondition('year', 1),
18050 nameCondition('month', 3),
18051 digitCondition('day', 1),
18052 digitCondition('hour', 1),
18053 digitCondition('minute', 1),
18054 digitCondition('second', 1),
18055 ])),
18056 'yMdjm': datePartGetterFactory(combine([
18057 digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1),
18058 digitCondition('hour', 1), digitCondition('minute', 1)
18059 ])),
18060 'yMMMMEEEEd': datePartGetterFactory(combine([
18061 digitCondition('year', 1), nameCondition('month', 4), nameCondition('weekday', 4),
18062 digitCondition('day', 1)
18063 ])),
18064 'yMMMMd': datePartGetterFactory(combine([digitCondition('year', 1), nameCondition('month', 4), digitCondition('day', 1)])),
18065 'yMMMd': datePartGetterFactory(combine([digitCondition('year', 1), nameCondition('month', 3), digitCondition('day', 1)])),
18066 'yMd': datePartGetterFactory(combine([digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1)])),
18067 'jms': datePartGetterFactory(combine([digitCondition('hour', 1), digitCondition('second', 1), digitCondition('minute', 1)])),
18068 'jm': datePartGetterFactory(combine([digitCondition('hour', 1), digitCondition('minute', 1)]))
18069};
18070var DATE_FORMATS = {
18071 // Keys are quoted so they do not get renamed.
18072 'yyyy': datePartGetterFactory(digitCondition('year', 4)),
18073 'yy': datePartGetterFactory(digitCondition('year', 2)),
18074 'y': datePartGetterFactory(digitCondition('year', 1)),
18075 'MMMM': datePartGetterFactory(nameCondition('month', 4)),
18076 'MMM': datePartGetterFactory(nameCondition('month', 3)),
18077 'MM': datePartGetterFactory(digitCondition('month', 2)),
18078 'M': datePartGetterFactory(digitCondition('month', 1)),
18079 'LLLL': datePartGetterFactory(nameCondition('month', 4)),
18080 'L': datePartGetterFactory(nameCondition('month', 1)),
18081 'dd': datePartGetterFactory(digitCondition('day', 2)),
18082 'd': datePartGetterFactory(digitCondition('day', 1)),
18083 'HH': digitModifier(hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), false)))),
18084 'H': hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), false))),
18085 'hh': digitModifier(hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), true)))),
18086 'h': hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
18087 'jj': datePartGetterFactory(digitCondition('hour', 2)),
18088 'j': datePartGetterFactory(digitCondition('hour', 1)),
18089 'mm': digitModifier(datePartGetterFactory(digitCondition('minute', 2))),
18090 'm': datePartGetterFactory(digitCondition('minute', 1)),
18091 'ss': digitModifier(datePartGetterFactory(digitCondition('second', 2))),
18092 's': datePartGetterFactory(digitCondition('second', 1)),
18093 // while ISO 8601 requires fractions to be prefixed with `.` or `,`
18094 // we can be just safely rely on using `sss` since we currently don't support single or two digit
18095 // fractions
18096 'sss': datePartGetterFactory(digitCondition('second', 3)),
18097 'EEEE': datePartGetterFactory(nameCondition('weekday', 4)),
18098 'EEE': datePartGetterFactory(nameCondition('weekday', 3)),
18099 'EE': datePartGetterFactory(nameCondition('weekday', 2)),
18100 'E': datePartGetterFactory(nameCondition('weekday', 1)),
18101 'a': hourClockExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
18102 'Z': timeZoneGetter('short'),
18103 'z': timeZoneGetter('long'),
18104 'ww': datePartGetterFactory({}),
18105 // first Thursday of the year. not support ?
18106 'w': datePartGetterFactory({}),
18107 // of the year not support ?
18108 'G': datePartGetterFactory(nameCondition('era', 1)),
18109 'GG': datePartGetterFactory(nameCondition('era', 2)),
18110 'GGG': datePartGetterFactory(nameCondition('era', 3)),
18111 'GGGG': datePartGetterFactory(nameCondition('era', 4))
18112};
18113/**
18114 * @param {?} inner
18115 * @return {?}
18116 */
18117function digitModifier(inner) {
18118 return function (date, locale) {
18119 var /** @type {?} */ result = inner(date, locale);
18120 return result.length == 1 ? '0' + result : result;
18121 };
18122}
18123/**
18124 * @param {?} inner
18125 * @return {?}
18126 */
18127function hourClockExtractor(inner) {
18128 return function (date, locale) { return inner(date, locale).split(' ')[1]; };
18129}
18130/**
18131 * @param {?} inner
18132 * @return {?}
18133 */
18134function hourExtractor(inner) {
18135 return function (date, locale) { return inner(date, locale).split(' ')[0]; };
18136}
18137/**
18138 * @param {?} date
18139 * @param {?} locale
18140 * @param {?} options
18141 * @return {?}
18142 */
18143function intlDateFormat(date, locale, options) {
18144 return new Intl.DateTimeFormat(locale, options).format(date).replace(/[\u200e\u200f]/g, '');
18145}
18146/**
18147 * @param {?} timezone
18148 * @return {?}
18149 */
18150function timeZoneGetter(timezone) {
18151 // To workaround `Intl` API restriction for single timezone let format with 24 hours
18152 var /** @type {?} */ options = { hour: '2-digit', hour12: false, timeZoneName: timezone };
18153 return function (date, locale) {
18154 var /** @type {?} */ result = intlDateFormat(date, locale, options);
18155 // Then extract first 3 letters that related to hours
18156 return result ? result.substring(3) : '';
18157 };
18158}
18159/**
18160 * @param {?} options
18161 * @param {?} value
18162 * @return {?}
18163 */
18164function hour12Modify(options, value) {
18165 options.hour12 = value;
18166 return options;
18167}
18168/**
18169 * @param {?} prop
18170 * @param {?} len
18171 * @return {?}
18172 */
18173function digitCondition(prop, len) {
18174 var /** @type {?} */ result = {};
18175 result[prop] = len === 2 ? '2-digit' : 'numeric';
18176 return result;
18177}
18178/**
18179 * @param {?} prop
18180 * @param {?} len
18181 * @return {?}
18182 */
18183function nameCondition(prop, len) {
18184 var /** @type {?} */ result = {};
18185 if (len < 4) {
18186 result[prop] = len > 1 ? 'short' : 'narrow';
18187 }
18188 else {
18189 result[prop] = 'long';
18190 }
18191 return result;
18192}
18193/**
18194 * @param {?} options
18195 * @return {?}
18196 */
18197function combine(options) {
18198 return options.reduce(function (merged, opt) { return (Object.assign({}, merged, opt)); }, {});
18199}
18200/**
18201 * @param {?} ret
18202 * @return {?}
18203 */
18204function datePartGetterFactory(ret) {
18205 return function (date, locale) { return intlDateFormat(date, locale, ret); };
18206}
18207var DATE_FORMATTER_CACHE = new Map();
18208/**
18209 * @param {?} format
18210 * @param {?} date
18211 * @param {?} locale
18212 * @return {?}
18213 */
18214function dateFormatter(format, date, locale) {
18215 var /** @type {?} */ fn = PATTERN_ALIASES[format];
18216 if (fn)
18217 return fn(date, locale);
18218 var /** @type {?} */ cacheKey = format;
18219 var /** @type {?} */ parts = DATE_FORMATTER_CACHE.get(cacheKey);
18220 if (!parts) {
18221 parts = [];
18222 var /** @type {?} */ match = void 0;
18223 DATE_FORMATS_SPLIT.exec(format);
18224 var /** @type {?} */ _format = format;
18225 while (_format) {
18226 match = DATE_FORMATS_SPLIT.exec(_format);
18227 if (match) {
18228 parts = parts.concat(match.slice(1));
18229 _format = ((parts.pop()));
18230 }
18231 else {
18232 parts.push(_format);
18233 _format = null;
18234 }
18235 }
18236 DATE_FORMATTER_CACHE.set(cacheKey, parts);
18237 }
18238 return parts.reduce(function (text, part) {
18239 var /** @type {?} */ fn = DATE_FORMATS[part];
18240 return text + (fn ? fn(date, locale) : partToTime(part));
18241 }, '');
18242}
18243/**
18244 * @param {?} part
18245 * @return {?}
18246 */
18247function partToTime(part) {
18248 return part === '\'\'' ? '\'' : part.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
18249}
18250var DateFormatter = (function () {
18251 function DateFormatter() {
18252 }
18253 /**
18254 * @param {?} date
18255 * @param {?} locale
18256 * @param {?} pattern
18257 * @return {?}
18258 */
18259 DateFormatter.format = function (date, locale, pattern) {
18260 return dateFormatter(pattern, date, locale);
18261 };
18262 return DateFormatter;
18263}());
18264/**
18265 * @license
18266 * Copyright Google Inc. All Rights Reserved.
18267 *
18268 * Use of this source code is governed by an MIT-style license that can be
18269 * found in the LICENSE file at https://angular.io/license
18270 */
18271var _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
18272/**
18273 * @param {?} pipe
18274 * @param {?} locale
18275 * @param {?} value
18276 * @param {?} style
18277 * @param {?=} digits
18278 * @param {?=} currency
18279 * @param {?=} currencyAsSymbol
18280 * @return {?}
18281 */
18282function formatNumber(pipe, locale, value, style$$1, digits, currency, currencyAsSymbol) {
18283 if (currency === void 0) { currency = null; }
18284 if (currencyAsSymbol === void 0) { currencyAsSymbol = false; }
18285 if (value == null)
18286 return null;
18287 // Convert strings to numbers
18288 value = typeof value === 'string' && isNumeric(value) ? +value : value;
18289 if (typeof value !== 'number') {
18290 throw invalidPipeArgumentError(pipe, value);
18291 }
18292 var /** @type {?} */ minInt = undefined;
18293 var /** @type {?} */ minFraction = undefined;
18294 var /** @type {?} */ maxFraction = undefined;
18295 if (style$$1 !== NumberFormatStyle.Currency) {
18296 // rely on Intl default for currency
18297 minInt = 1;
18298 minFraction = 0;
18299 maxFraction = 3;
18300 }
18301 if (digits) {
18302 var /** @type {?} */ parts = digits.match(_NUMBER_FORMAT_REGEXP);
18303 if (parts === null) {
18304 throw new Error(digits + " is not a valid digit info for number pipes");
18305 }
18306 if (parts[1] != null) {
18307 minInt = parseIntAutoRadix(parts[1]);
18308 }
18309 if (parts[3] != null) {
18310 minFraction = parseIntAutoRadix(parts[3]);
18311 }
18312 if (parts[5] != null) {
18313 maxFraction = parseIntAutoRadix(parts[5]);
18314 }
18315 }
18316 return NumberFormatter.format(/** @type {?} */ (value), locale, style$$1, {
18317 minimumIntegerDigits: minInt,
18318 minimumFractionDigits: minFraction,
18319 maximumFractionDigits: maxFraction,
18320 currency: currency,
18321 currencyAsSymbol: currencyAsSymbol,
18322 });
18323}
18324/**
18325 * \@ngModule CommonModule
18326 * \@whatItDoes Formats a number according to locale rules.
18327 * \@howToUse `number_expression | number[:digitInfo]`
18328 *
18329 * Formats a number as text. Group sizing and separator and other locale-specific
18330 * configurations are based on the active locale.
18331 *
18332 * where `expression` is a number:
18333 * - `digitInfo` is a `string` which has a following format: <br>
18334 * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>
18335 * - `minIntegerDigits` is the minimum number of integer digits to use. Defaults to `1`.
18336 * - `minFractionDigits` is the minimum number of digits after fraction. Defaults to `0`.
18337 * - `maxFractionDigits` is the maximum number of digits after fraction. Defaults to `3`.
18338 *
18339 * For more information on the acceptable range for each of these numbers and other
18340 * details see your native internationalization library.
18341 *
18342 * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
18343 * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
18344 *
18345 * ### Example
18346 *
18347 * {\@example common/pipes/ts/number_pipe.ts region='NumberPipe'}
18348 *
18349 * \@stable
18350 */
18351var DecimalPipe = (function () {
18352 /**
18353 * @param {?} _locale
18354 */
18355 function DecimalPipe(_locale) {
18356 this._locale = _locale;
18357 }
18358 /**
18359 * @param {?} value
18360 * @param {?=} digits
18361 * @return {?}
18362 */
18363 DecimalPipe.prototype.transform = function (value, digits) {
18364 return formatNumber(DecimalPipe, this._locale, value, NumberFormatStyle.Decimal, digits);
18365 };
18366 return DecimalPipe;
18367}());
18368DecimalPipe.decorators = [
18369 { type: Pipe, args: [{ name: 'number' },] },
18370];
18371/**
18372 * @nocollapse
18373 */
18374DecimalPipe.ctorParameters = function () { return [
18375 { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
18376]; };
18377/**
18378 * \@ngModule CommonModule
18379 * \@whatItDoes Formats a number as a percentage according to locale rules.
18380 * \@howToUse `number_expression | percent[:digitInfo]`
18381 *
18382 * \@description
18383 *
18384 * Formats a number as percentage.
18385 *
18386 * - `digitInfo` See {\@link DecimalPipe} for detailed description.
18387 *
18388 * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
18389 * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
18390 *
18391 * ### Example
18392 *
18393 * {\@example common/pipes/ts/number_pipe.ts region='PercentPipe'}
18394 *
18395 * \@stable
18396 */
18397var PercentPipe = (function () {
18398 /**
18399 * @param {?} _locale
18400 */
18401 function PercentPipe(_locale) {
18402 this._locale = _locale;
18403 }
18404 /**
18405 * @param {?} value
18406 * @param {?=} digits
18407 * @return {?}
18408 */
18409 PercentPipe.prototype.transform = function (value, digits) {
18410 return formatNumber(PercentPipe, this._locale, value, NumberFormatStyle.Percent, digits);
18411 };
18412 return PercentPipe;
18413}());
18414PercentPipe.decorators = [
18415 { type: Pipe, args: [{ name: 'percent' },] },
18416];
18417/**
18418 * @nocollapse
18419 */
18420PercentPipe.ctorParameters = function () { return [
18421 { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
18422]; };
18423/**
18424 * \@ngModule CommonModule
18425 * \@whatItDoes Formats a number as currency using locale rules.
18426 * \@howToUse `number_expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]`
18427 * \@description
18428 *
18429 * Use `currency` to format a number as currency.
18430 *
18431 * - `currencyCode` is the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code, such
18432 * as `USD` for the US dollar and `EUR` for the euro.
18433 * - `symbolDisplay` is a boolean indicating whether to use the currency symbol or code.
18434 * - `true`: use symbol (e.g. `$`).
18435 * - `false`(default): use code (e.g. `USD`).
18436 * - `digitInfo` See {\@link DecimalPipe} for detailed description.
18437 *
18438 * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
18439 * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
18440 *
18441 * ### Example
18442 *
18443 * {\@example common/pipes/ts/number_pipe.ts region='CurrencyPipe'}
18444 *
18445 * \@stable
18446 */
18447var CurrencyPipe = (function () {
18448 /**
18449 * @param {?} _locale
18450 */
18451 function CurrencyPipe(_locale) {
18452 this._locale = _locale;
18453 }
18454 /**
18455 * @param {?} value
18456 * @param {?=} currencyCode
18457 * @param {?=} symbolDisplay
18458 * @param {?=} digits
18459 * @return {?}
18460 */
18461 CurrencyPipe.prototype.transform = function (value, currencyCode, symbolDisplay, digits) {
18462 if (currencyCode === void 0) { currencyCode = 'USD'; }
18463 if (symbolDisplay === void 0) { symbolDisplay = false; }
18464 return formatNumber(CurrencyPipe, this._locale, value, NumberFormatStyle.Currency, digits, currencyCode, symbolDisplay);
18465 };
18466 return CurrencyPipe;
18467}());
18468CurrencyPipe.decorators = [
18469 { type: Pipe, args: [{ name: 'currency' },] },
18470];
18471/**
18472 * @nocollapse
18473 */
18474CurrencyPipe.ctorParameters = function () { return [
18475 { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
18476]; };
18477/**
18478 * @param {?} text
18479 * @return {?}
18480 */
18481function parseIntAutoRadix(text) {
18482 var /** @type {?} */ result = parseInt(text);
18483 if (isNaN(result)) {
18484 throw new Error('Invalid integer literal when parsing ' + text);
18485 }
18486 return result;
18487}
18488/**
18489 * @param {?} value
18490 * @return {?}
18491 */
18492function isNumeric(value) {
18493 return !isNaN(value - parseFloat(value));
18494}
18495/**
18496 * @license
18497 * Copyright Google Inc. All Rights Reserved.
18498 *
18499 * Use of this source code is governed by an MIT-style license that can be
18500 * found in the LICENSE file at https://angular.io/license
18501 */
18502var ISO8601_DATE_REGEX = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
18503/**
18504 * \@ngModule CommonModule
18505 * \@whatItDoes Formats a date according to locale rules.
18506 * \@howToUse `date_expression | date[:format]`
18507 * \@description
18508 *
18509 * Where:
18510 * - `expression` is a date object or a number (milliseconds since UTC epoch) or an ISO string
18511 * (https://www.w3.org/TR/NOTE-datetime).
18512 * - `format` indicates which date/time components to include. The format can be predefined as
18513 * shown below or custom as shown in the table.
18514 * - `'medium'`: equivalent to `'yMMMdjms'` (e.g. `Sep 3, 2010, 12:05:08 PM` for `en-US`)
18515 * - `'short'`: equivalent to `'yMdjm'` (e.g. `9/3/2010, 12:05 PM` for `en-US`)
18516 * - `'fullDate'`: equivalent to `'yMMMMEEEEd'` (e.g. `Friday, September 3, 2010` for `en-US`)
18517 * - `'longDate'`: equivalent to `'yMMMMd'` (e.g. `September 3, 2010` for `en-US`)
18518 * - `'mediumDate'`: equivalent to `'yMMMd'` (e.g. `Sep 3, 2010` for `en-US`)
18519 * - `'shortDate'`: equivalent to `'yMd'` (e.g. `9/3/2010` for `en-US`)
18520 * - `'mediumTime'`: equivalent to `'jms'` (e.g. `12:05:08 PM` for `en-US`)
18521 * - `'shortTime'`: equivalent to `'jm'` (e.g. `12:05 PM` for `en-US`)
18522 *
18523 *
18524 * | Component | Symbol | Narrow | Short Form | Long Form | Numeric | 2-digit |
18525 * |-----------|:------:|--------|--------------|-------------------|-----------|-----------|
18526 * | era | G | G (A) | GGG (AD) | GGGG (Anno Domini)| - | - |
18527 * | year | y | - | - | - | y (2015) | yy (15) |
18528 * | month | M | L (S) | MMM (Sep) | MMMM (September) | M (9) | MM (09) |
18529 * | day | d | - | - | - | d (3) | dd (03) |
18530 * | weekday | E | E (S) | EEE (Sun) | EEEE (Sunday) | - | - |
18531 * | hour | j | - | - | - | j (1 PM) | jj (1 PM) |
18532 * | hour12 | h | - | - | - | h (1) | hh (01) |
18533 * | hour24 | H | - | - | - | H (13) | HH (13) |
18534 * | minute | m | - | - | - | m (5) | mm (05) |
18535 * | second | s | - | - | - | s (9) | ss (09) |
18536 * | timezone | z | - | - | z (Pacific Standard Time)| - | - |
18537 * | timezone | Z | - | Z (GMT-8:00) | - | - | - |
18538 * | timezone | a | - | a (PM) | - | - | - |
18539 *
18540 * In javascript, only the components specified will be respected (not the ordering,
18541 * punctuations, ...) and details of the formatting will be dependent on the locale.
18542 *
18543 * Timezone of the formatted text will be the local system timezone of the end-user's machine.
18544 *
18545 * When the expression is a ISO string without time (e.g. 2016-09-19) the time zone offset is not
18546 * applied and the formatted text will have the same day, month and year of the expression.
18547 *
18548 * WARNINGS:
18549 * - this pipe is marked as pure hence it will not be re-evaluated when the input is mutated.
18550 * Instead users should treat the date as an immutable object and change the reference when the
18551 * pipe needs to re-run (this is to avoid reformatting the date on every change detection run
18552 * which would be an expensive operation).
18553 * - this pipe uses the Internationalization API. Therefore it is only reliable in Chrome and Opera
18554 * browsers.
18555 *
18556 * ### Examples
18557 *
18558 * Assuming `dateObj` is (year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11)
18559 * in the _local_ time and locale is 'en-US':
18560 *
18561 * ```
18562 * {{ dateObj | date }} // output is 'Jun 15, 2015'
18563 * {{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 PM'
18564 * {{ dateObj | date:'shortTime' }} // output is '9:43 PM'
18565 * {{ dateObj | date:'mmss' }} // output is '43:11'
18566 * ```
18567 *
18568 * {\@example common/pipes/ts/date_pipe.ts region='DatePipe'}
18569 *
18570 * \@stable
18571 */
18572var DatePipe = (function () {
18573 /**
18574 * @param {?} _locale
18575 */
18576 function DatePipe(_locale) {
18577 this._locale = _locale;
18578 }
18579 /**
18580 * @param {?} value
18581 * @param {?=} pattern
18582 * @return {?}
18583 */
18584 DatePipe.prototype.transform = function (value, pattern) {
18585 if (pattern === void 0) { pattern = 'mediumDate'; }
18586 var /** @type {?} */ date;
18587 if (isBlank(value) || value !== value)
18588 return null;
18589 if (typeof value === 'string') {
18590 value = value.trim();
18591 }
18592 if (isDate(value)) {
18593 date = value;
18594 }
18595 else if (isNumeric(value)) {
18596 date = new Date(parseFloat(value));
18597 }
18598 else if (typeof value === 'string' && /^(\d{4}-\d{1,2}-\d{1,2})$/.test(value)) {
18599 /**
18600 * For ISO Strings without time the day, month and year must be extracted from the ISO String
18601 * before Date creation to avoid time offset and errors in the new Date.
18602 * If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new
18603 * date, some browsers (e.g. IE 9) will throw an invalid Date error
18604 * If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset
18605 * is applied
18606 * Note: ISO months are 0 for January, 1 for February, ...
18607 */
18608 var _a = value.split('-').map(function (val) { return parseInt(val, 10); }), y = _a[0], m = _a[1], d = _a[2];
18609 date = new Date(y, m - 1, d);
18610 }
18611 else {
18612 date = new Date(value);
18613 }
18614 if (!isDate(date)) {
18615 var /** @type {?} */ match = void 0;
18616 if ((typeof value === 'string') && (match = value.match(ISO8601_DATE_REGEX))) {
18617 date = isoStringToDate(match);
18618 }
18619 else {
18620 throw invalidPipeArgumentError(DatePipe, value);
18621 }
18622 }
18623 return DateFormatter.format(date, this._locale, DatePipe._ALIASES[pattern] || pattern);
18624 };
18625 return DatePipe;
18626}());
18627/**
18628 * \@internal
18629 */
18630DatePipe._ALIASES = {
18631 'medium': 'yMMMdjms',
18632 'short': 'yMdjm',
18633 'fullDate': 'yMMMMEEEEd',
18634 'longDate': 'yMMMMd',
18635 'mediumDate': 'yMMMd',
18636 'shortDate': 'yMd',
18637 'mediumTime': 'jms',
18638 'shortTime': 'jm'
18639};
18640DatePipe.decorators = [
18641 { type: Pipe, args: [{ name: 'date', pure: true },] },
18642];
18643/**
18644 * @nocollapse
18645 */
18646DatePipe.ctorParameters = function () { return [
18647 { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
18648]; };
18649/**
18650 * @param {?} obj
18651 * @return {?}
18652 */
18653function isBlank(obj) {
18654 return obj == null || obj === '';
18655}
18656/**
18657 * @param {?} obj
18658 * @return {?}
18659 */
18660function isDate(obj) {
18661 return obj instanceof Date && !isNaN(obj.valueOf());
18662}
18663/**
18664 * @param {?} match
18665 * @return {?}
18666 */
18667function isoStringToDate(match) {
18668 var /** @type {?} */ date = new Date(0);
18669 var /** @type {?} */ tzHour = 0;
18670 var /** @type {?} */ tzMin = 0;
18671 var /** @type {?} */ dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear;
18672 var /** @type {?} */ timeSetter = match[8] ? date.setUTCHours : date.setHours;
18673 if (match[9]) {
18674 tzHour = toInt(match[9] + match[10]);
18675 tzMin = toInt(match[9] + match[11]);
18676 }
18677 dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
18678 var /** @type {?} */ h = toInt(match[4] || '0') - tzHour;
18679 var /** @type {?} */ m = toInt(match[5] || '0') - tzMin;
18680 var /** @type {?} */ s = toInt(match[6] || '0');
18681 var /** @type {?} */ ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
18682 timeSetter.call(date, h, m, s, ms);
18683 return date;
18684}
18685/**
18686 * @param {?} str
18687 * @return {?}
18688 */
18689function toInt(str) {
18690 return parseInt(str, 10);
18691}
18692/**
18693 * @license
18694 * Copyright Google Inc. All Rights Reserved.
18695 *
18696 * Use of this source code is governed by an MIT-style license that can be
18697 * found in the LICENSE file at https://angular.io/license
18698 */
18699var _INTERPOLATION_REGEXP = /#/g;
18700/**
18701 * \@ngModule CommonModule
18702 * \@whatItDoes Maps a value to a string that pluralizes the value according to locale rules.
18703 * \@howToUse `expression | i18nPlural:mapping`
18704 * \@description
18705 *
18706 * Where:
18707 * - `expression` is a number.
18708 * - `mapping` is an object that mimics the ICU format, see
18709 * http://userguide.icu-project.org/formatparse/messages
18710 *
18711 * ## Example
18712 *
18713 * {\@example common/pipes/ts/i18n_pipe.ts region='I18nPluralPipeComponent'}
18714 *
18715 * \@experimental
18716 */
18717var I18nPluralPipe = (function () {
18718 /**
18719 * @param {?} _localization
18720 */
18721 function I18nPluralPipe(_localization) {
18722 this._localization = _localization;
18723 }
18724 /**
18725 * @param {?} value
18726 * @param {?} pluralMap
18727 * @return {?}
18728 */
18729 I18nPluralPipe.prototype.transform = function (value, pluralMap) {
18730 if (value == null)
18731 return '';
18732 if (typeof pluralMap !== 'object' || pluralMap === null) {
18733 throw invalidPipeArgumentError(I18nPluralPipe, pluralMap);
18734 }
18735 var /** @type {?} */ key = getPluralCategory(value, Object.keys(pluralMap), this._localization);
18736 return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString());
18737 };
18738 return I18nPluralPipe;
18739}());
18740I18nPluralPipe.decorators = [
18741 { type: Pipe, args: [{ name: 'i18nPlural', pure: true },] },
18742];
18743/**
18744 * @nocollapse
18745 */
18746I18nPluralPipe.ctorParameters = function () { return [
18747 { type: NgLocalization, },
18748]; };
18749/**
18750 * @license
18751 * Copyright Google Inc. All Rights Reserved.
18752 *
18753 * Use of this source code is governed by an MIT-style license that can be
18754 * found in the LICENSE file at https://angular.io/license
18755 */
18756/**
18757 * \@ngModule CommonModule
18758 * \@whatItDoes Generic selector that displays the string that matches the current value.
18759 * \@howToUse `expression | i18nSelect:mapping`
18760 * \@description
18761 *
18762 * Where `mapping` is an object that indicates the text that should be displayed
18763 * for different values of the provided `expression`.
18764 * If none of the keys of the mapping match the value of the `expression`, then the content
18765 * of the `other` key is returned when present, otherwise an empty string is returned.
18766 *
18767 * ## Example
18768 *
18769 * {\@example common/pipes/ts/i18n_pipe.ts region='I18nSelectPipeComponent'}
18770 *
18771 * \@experimental
18772 */
18773var I18nSelectPipe = (function () {
18774 function I18nSelectPipe() {
18775 }
18776 /**
18777 * @param {?} value
18778 * @param {?} mapping
18779 * @return {?}
18780 */
18781 I18nSelectPipe.prototype.transform = function (value, mapping) {
18782 if (value == null)
18783 return '';
18784 if (typeof mapping !== 'object' || typeof value !== 'string') {
18785 throw invalidPipeArgumentError(I18nSelectPipe, mapping);
18786 }
18787 if (mapping.hasOwnProperty(value)) {
18788 return mapping[value];
18789 }
18790 if (mapping.hasOwnProperty('other')) {
18791 return mapping['other'];
18792 }
18793 return '';
18794 };
18795 return I18nSelectPipe;
18796}());
18797I18nSelectPipe.decorators = [
18798 { type: Pipe, args: [{ name: 'i18nSelect', pure: true },] },
18799];
18800/**
18801 * @nocollapse
18802 */
18803I18nSelectPipe.ctorParameters = function () { return []; };
18804/**
18805 * @license
18806 * Copyright Google Inc. All Rights Reserved.
18807 *
18808 * Use of this source code is governed by an MIT-style license that can be
18809 * found in the LICENSE file at https://angular.io/license
18810 */
18811/**
18812 * \@ngModule CommonModule
18813 * \@whatItDoes Converts value into JSON string.
18814 * \@howToUse `expression | json`
18815 * \@description
18816 *
18817 * Converts value into string using `JSON.stringify`. Useful for debugging.
18818 *
18819 * ### Example
18820 * {\@example common/pipes/ts/json_pipe.ts region='JsonPipe'}
18821 *
18822 * \@stable
18823 */
18824var JsonPipe = (function () {
18825 function JsonPipe() {
18826 }
18827 /**
18828 * @param {?} value
18829 * @return {?}
18830 */
18831 JsonPipe.prototype.transform = function (value) { return JSON.stringify(value, null, 2); };
18832 return JsonPipe;
18833}());
18834JsonPipe.decorators = [
18835 { type: Pipe, args: [{ name: 'json', pure: false },] },
18836];
18837/**
18838 * @nocollapse
18839 */
18840JsonPipe.ctorParameters = function () { return []; };
18841/**
18842 * @license
18843 * Copyright Google Inc. All Rights Reserved.
18844 *
18845 * Use of this source code is governed by an MIT-style license that can be
18846 * found in the LICENSE file at https://angular.io/license
18847 */
18848/**
18849 * \@ngModule CommonModule
18850 * \@whatItDoes Creates a new List or String containing a subset (slice) of the elements.
18851 * \@howToUse `array_or_string_expression | slice:start[:end]`
18852 * \@description
18853 *
18854 * Where the input expression is a `List` or `String`, and:
18855 * - `start`: The starting index of the subset to return.
18856 * - **a positive integer**: return the item at `start` index and all items after
18857 * in the list or string expression.
18858 * - **a negative integer**: return the item at `start` index from the end and all items after
18859 * in the list or string expression.
18860 * - **if positive and greater than the size of the expression**: return an empty list or string.
18861 * - **if negative and greater than the size of the expression**: return entire list or string.
18862 * - `end`: The ending index of the subset to return.
18863 * - **omitted**: return all items until the end.
18864 * - **if positive**: return all items before `end` index of the list or string.
18865 * - **if negative**: return all items before `end` index from the end of the list or string.
18866 *
18867 * All behavior is based on the expected behavior of the JavaScript API `Array.prototype.slice()`
18868 * and `String.prototype.slice()`.
18869 *
18870 * When operating on a [List], the returned list is always a copy even when all
18871 * the elements are being returned.
18872 *
18873 * When operating on a blank value, the pipe returns the blank value.
18874 *
18875 * ## List Example
18876 *
18877 * This `ngFor` example:
18878 *
18879 * {\@example common/pipes/ts/slice_pipe.ts region='SlicePipe_list'}
18880 *
18881 * produces the following:
18882 *
18883 * <li>b</li>
18884 * <li>c</li>
18885 *
18886 * ## String Examples
18887 *
18888 * {\@example common/pipes/ts/slice_pipe.ts region='SlicePipe_string'}
18889 *
18890 * \@stable
18891 */
18892var SlicePipe = (function () {
18893 function SlicePipe() {
18894 }
18895 /**
18896 * @param {?} value
18897 * @param {?} start
18898 * @param {?=} end
18899 * @return {?}
18900 */
18901 SlicePipe.prototype.transform = function (value, start, end) {
18902 if (value == null)
18903 return value;
18904 if (!this.supports(value)) {
18905 throw invalidPipeArgumentError(SlicePipe, value);
18906 }
18907 return value.slice(start, end);
18908 };
18909 /**
18910 * @param {?} obj
18911 * @return {?}
18912 */
18913 SlicePipe.prototype.supports = function (obj) { return typeof obj === 'string' || Array.isArray(obj); };
18914 return SlicePipe;
18915}());
18916SlicePipe.decorators = [
18917 { type: Pipe, args: [{ name: 'slice', pure: false },] },
18918];
18919/**
18920 * @nocollapse
18921 */
18922SlicePipe.ctorParameters = function () { return []; };
18923/**
18924 * @license
18925 * Copyright Google Inc. All Rights Reserved.
18926 *
18927 * Use of this source code is governed by an MIT-style license that can be
18928 * found in the LICENSE file at https://angular.io/license
18929 */
18930/**
18931 * @module
18932 * @description
18933 * This module provides a set of common Pipes.
18934 */
18935/**
18936 * A collection of Angular pipes that are likely to be used in each and every application.
18937 */
18938var COMMON_PIPES = [
18939 AsyncPipe,
18940 UpperCasePipe,
18941 LowerCasePipe,
18942 JsonPipe,
18943 SlicePipe,
18944 DecimalPipe,
18945 PercentPipe,
18946 TitleCasePipe,
18947 CurrencyPipe,
18948 DatePipe,
18949 I18nPluralPipe,
18950 I18nSelectPipe,
18951];
18952/**
18953 * @license
18954 * Copyright Google Inc. All Rights Reserved.
18955 *
18956 * Use of this source code is governed by an MIT-style license that can be
18957 * found in the LICENSE file at https://angular.io/license
18958 */
18959/**
18960 * The module that includes all the basic Angular directives like {\@link NgIf}, {\@link NgForOf}, ...
18961 *
18962 * \@stable
18963 */
18964var CommonModule = (function () {
18965 function CommonModule() {
18966 }
18967 return CommonModule;
18968}());
18969CommonModule.decorators = [
18970 { type: NgModule, args: [{
18971 declarations: [COMMON_DIRECTIVES, COMMON_PIPES],
18972 exports: [COMMON_DIRECTIVES, COMMON_PIPES],
18973 providers: [
18974 { provide: NgLocalization, useClass: NgLocaleLocalization },
18975 ],
18976 },] },
18977];
18978/**
18979 * @nocollapse
18980 */
18981CommonModule.ctorParameters = function () { return []; };
18982/**
18983 * I18N pipes are being changed to move away from using the JS Intl API.
18984 *
18985 * The former pipes relying on the Intl API will be moved to this module while the `CommonModule`
18986 * will contain the new pipes that do not rely on Intl.
18987 *
18988 * As a first step this module is created empty to ease the migration.
18989 *
18990 * see https://github.com/angular/angular/pull/18284
18991 *
18992 * @deprecated from v5
18993 */
18994var DeprecatedI18NPipesModule = (function () {
18995 function DeprecatedI18NPipesModule() {
18996 }
18997 return DeprecatedI18NPipesModule;
18998}());
18999DeprecatedI18NPipesModule.decorators = [
19000 { type: NgModule, args: [{ declarations: [], exports: [] },] },
19001];
19002/**
19003 * @nocollapse
19004 */
19005DeprecatedI18NPipesModule.ctorParameters = function () { return []; };
19006/**
19007 * @license
19008 * Copyright Google Inc. All Rights Reserved.
19009 *
19010 * Use of this source code is governed by an MIT-style license that can be
19011 * found in the LICENSE file at https://angular.io/license
19012 */
19013/**
19014 * A DI Token representing the main rendering context. In a browser this is the DOM Document.
19015 *
19016 * Note: Document might not be available in the Application Context when Application and Rendering
19017 * Contexts are not the same (e.g. when running the application into a Web Worker).
19018 *
19019 * \@stable
19020 */
19021var DOCUMENT = new InjectionToken('DocumentToken');
19022/**
19023 * @license
19024 * Copyright Google Inc. All Rights Reserved.
19025 *
19026 * Use of this source code is governed by an MIT-style license that can be
19027 * found in the LICENSE file at https://angular.io/license
19028 */
19029var PLATFORM_BROWSER_ID = 'browser';
19030/**
19031 * @license
19032 * Copyright Google Inc. All Rights Reserved.
19033 *
19034 * Use of this source code is governed by an MIT-style license that can be
19035 * found in the LICENSE file at https://angular.io/license
19036 */
19037/**
19038 * @module
19039 * @description
19040 * Entry point for all public APIs of the common package.
19041 */
19042/**
19043 * \@stable
19044 */
19045var VERSION$2 = new Version('4.4.3');
19046
19047/**
19048 * @license Angular v4.4.3
19049 * (c) 2010-2017 Google, Inc. https://angular.io/
19050 * License: MIT
19051 */
19052/**
19053 * @license
19054 * Copyright Google Inc. All Rights Reserved.
19055 *
19056 * Use of this source code is governed by an MIT-style license that can be
19057 * found in the LICENSE file at https://angular.io/license
19058 */
19059var _DOM = ((null));
19060/**
19061 * @return {?}
19062 */
19063function getDOM() {
19064 return _DOM;
19065}
19066/**
19067 * @param {?} adapter
19068 * @return {?}
19069 */
19070/**
19071 * @param {?} adapter
19072 * @return {?}
19073 */
19074function setRootDomAdapter(adapter) {
19075 if (!_DOM) {
19076 _DOM = adapter;
19077 }
19078}
19079/**
19080 * Provides DOM operations in an environment-agnostic way.
19081 *
19082 * \@security Tread carefully! Interacting with the DOM directly is dangerous and
19083 * can introduce XSS risks.
19084 * @abstract
19085 */
19086var DomAdapter = (function () {
19087 function DomAdapter() {
19088 this.resourceLoaderType = ((null));
19089 }
19090 /**
19091 * @abstract
19092 * @param {?} element
19093 * @param {?} name
19094 * @return {?}
19095 */
19096 DomAdapter.prototype.hasProperty = function (element, name) { };
19097 /**
19098 * @abstract
19099 * @param {?} el
19100 * @param {?} name
19101 * @param {?} value
19102 * @return {?}
19103 */
19104 DomAdapter.prototype.setProperty = function (el, name, value) { };
19105 /**
19106 * @abstract
19107 * @param {?} el
19108 * @param {?} name
19109 * @return {?}
19110 */
19111 DomAdapter.prototype.getProperty = function (el, name) { };
19112 /**
19113 * @abstract
19114 * @param {?} el
19115 * @param {?} methodName
19116 * @param {?} args
19117 * @return {?}
19118 */
19119 DomAdapter.prototype.invoke = function (el, methodName, args) { };
19120 /**
19121 * @abstract
19122 * @param {?} error
19123 * @return {?}
19124 */
19125 DomAdapter.prototype.logError = function (error) { };
19126 /**
19127 * @abstract
19128 * @param {?} error
19129 * @return {?}
19130 */
19131 DomAdapter.prototype.log = function (error) { };
19132 /**
19133 * @abstract
19134 * @param {?} error
19135 * @return {?}
19136 */
19137 DomAdapter.prototype.logGroup = function (error) { };
19138 /**
19139 * @abstract
19140 * @return {?}
19141 */
19142 DomAdapter.prototype.logGroupEnd = function () { };
19143 Object.defineProperty(DomAdapter.prototype, "attrToPropMap", {
19144 /**
19145 * Maps attribute names to their corresponding property names for cases
19146 * where attribute name doesn't match property name.
19147 * @return {?}
19148 */
19149 get: function () { return this._attrToPropMap; },
19150 /**
19151 * @param {?} value
19152 * @return {?}
19153 */
19154 set: function (value) { this._attrToPropMap = value; },
19155 enumerable: true,
19156 configurable: true
19157 });
19158
19159
19160 /**
19161 * @abstract
19162 * @param {?} nodeA
19163 * @param {?} nodeB
19164 * @return {?}
19165 */
19166 DomAdapter.prototype.contains = function (nodeA, nodeB) { };
19167 /**
19168 * @abstract
19169 * @param {?} templateHtml
19170 * @return {?}
19171 */
19172 DomAdapter.prototype.parse = function (templateHtml) { };
19173 /**
19174 * @abstract
19175 * @param {?} el
19176 * @param {?} selector
19177 * @return {?}
19178 */
19179 DomAdapter.prototype.querySelector = function (el, selector) { };
19180 /**
19181 * @abstract
19182 * @param {?} el
19183 * @param {?} selector
19184 * @return {?}
19185 */
19186 DomAdapter.prototype.querySelectorAll = function (el, selector) { };
19187 /**
19188 * @abstract
19189 * @param {?} el
19190 * @param {?} evt
19191 * @param {?} listener
19192 * @return {?}
19193 */
19194 DomAdapter.prototype.on = function (el, evt, listener) { };
19195 /**
19196 * @abstract
19197 * @param {?} el
19198 * @param {?} evt
19199 * @param {?} listener
19200 * @return {?}
19201 */
19202 DomAdapter.prototype.onAndCancel = function (el, evt, listener) { };
19203 /**
19204 * @abstract
19205 * @param {?} el
19206 * @param {?} evt
19207 * @return {?}
19208 */
19209 DomAdapter.prototype.dispatchEvent = function (el, evt) { };
19210 /**
19211 * @abstract
19212 * @param {?} eventType
19213 * @return {?}
19214 */
19215 DomAdapter.prototype.createMouseEvent = function (eventType) { };
19216 /**
19217 * @abstract
19218 * @param {?} eventType
19219 * @return {?}
19220 */
19221 DomAdapter.prototype.createEvent = function (eventType) { };
19222 /**
19223 * @abstract
19224 * @param {?} evt
19225 * @return {?}
19226 */
19227 DomAdapter.prototype.preventDefault = function (evt) { };
19228 /**
19229 * @abstract
19230 * @param {?} evt
19231 * @return {?}
19232 */
19233 DomAdapter.prototype.isPrevented = function (evt) { };
19234 /**
19235 * @abstract
19236 * @param {?} el
19237 * @return {?}
19238 */
19239 DomAdapter.prototype.getInnerHTML = function (el) { };
19240 /**
19241 * Returns content if el is a <template> element, null otherwise.
19242 * @abstract
19243 * @param {?} el
19244 * @return {?}
19245 */
19246 DomAdapter.prototype.getTemplateContent = function (el) { };
19247 /**
19248 * @abstract
19249 * @param {?} el
19250 * @return {?}
19251 */
19252 DomAdapter.prototype.getOuterHTML = function (el) { };
19253 /**
19254 * @abstract
19255 * @param {?} node
19256 * @return {?}
19257 */
19258 DomAdapter.prototype.nodeName = function (node) { };
19259 /**
19260 * @abstract
19261 * @param {?} node
19262 * @return {?}
19263 */
19264 DomAdapter.prototype.nodeValue = function (node) { };
19265 /**
19266 * @abstract
19267 * @param {?} node
19268 * @return {?}
19269 */
19270 DomAdapter.prototype.type = function (node) { };
19271 /**
19272 * @abstract
19273 * @param {?} node
19274 * @return {?}
19275 */
19276 DomAdapter.prototype.content = function (node) { };
19277 /**
19278 * @abstract
19279 * @param {?} el
19280 * @return {?}
19281 */
19282 DomAdapter.prototype.firstChild = function (el) { };
19283 /**
19284 * @abstract
19285 * @param {?} el
19286 * @return {?}
19287 */
19288 DomAdapter.prototype.nextSibling = function (el) { };
19289 /**
19290 * @abstract
19291 * @param {?} el
19292 * @return {?}
19293 */
19294 DomAdapter.prototype.parentElement = function (el) { };
19295 /**
19296 * @abstract
19297 * @param {?} el
19298 * @return {?}
19299 */
19300 DomAdapter.prototype.childNodes = function (el) { };
19301 /**
19302 * @abstract
19303 * @param {?} el
19304 * @return {?}
19305 */
19306 DomAdapter.prototype.childNodesAsList = function (el) { };
19307 /**
19308 * @abstract
19309 * @param {?} el
19310 * @return {?}
19311 */
19312 DomAdapter.prototype.clearNodes = function (el) { };
19313 /**
19314 * @abstract
19315 * @param {?} el
19316 * @param {?} node
19317 * @return {?}
19318 */
19319 DomAdapter.prototype.appendChild = function (el, node) { };
19320 /**
19321 * @abstract
19322 * @param {?} el
19323 * @param {?} node
19324 * @return {?}
19325 */
19326 DomAdapter.prototype.removeChild = function (el, node) { };
19327 /**
19328 * @abstract
19329 * @param {?} el
19330 * @param {?} newNode
19331 * @param {?} oldNode
19332 * @return {?}
19333 */
19334 DomAdapter.prototype.replaceChild = function (el, newNode, oldNode) { };
19335 /**
19336 * @abstract
19337 * @param {?} el
19338 * @return {?}
19339 */
19340 DomAdapter.prototype.remove = function (el) { };
19341 /**
19342 * @abstract
19343 * @param {?} parent
19344 * @param {?} ref
19345 * @param {?} node
19346 * @return {?}
19347 */
19348 DomAdapter.prototype.insertBefore = function (parent, ref, node) { };
19349 /**
19350 * @abstract
19351 * @param {?} parent
19352 * @param {?} ref
19353 * @param {?} nodes
19354 * @return {?}
19355 */
19356 DomAdapter.prototype.insertAllBefore = function (parent, ref, nodes) { };
19357 /**
19358 * @abstract
19359 * @param {?} parent
19360 * @param {?} el
19361 * @param {?} node
19362 * @return {?}
19363 */
19364 DomAdapter.prototype.insertAfter = function (parent, el, node) { };
19365 /**
19366 * @abstract
19367 * @param {?} el
19368 * @param {?} value
19369 * @return {?}
19370 */
19371 DomAdapter.prototype.setInnerHTML = function (el, value) { };
19372 /**
19373 * @abstract
19374 * @param {?} el
19375 * @return {?}
19376 */
19377 DomAdapter.prototype.getText = function (el) { };
19378 /**
19379 * @abstract
19380 * @param {?} el
19381 * @param {?} value
19382 * @return {?}
19383 */
19384 DomAdapter.prototype.setText = function (el, value) { };
19385 /**
19386 * @abstract
19387 * @param {?} el
19388 * @return {?}
19389 */
19390 DomAdapter.prototype.getValue = function (el) { };
19391 /**
19392 * @abstract
19393 * @param {?} el
19394 * @param {?} value
19395 * @return {?}
19396 */
19397 DomAdapter.prototype.setValue = function (el, value) { };
19398 /**
19399 * @abstract
19400 * @param {?} el
19401 * @return {?}
19402 */
19403 DomAdapter.prototype.getChecked = function (el) { };
19404 /**
19405 * @abstract
19406 * @param {?} el
19407 * @param {?} value
19408 * @return {?}
19409 */
19410 DomAdapter.prototype.setChecked = function (el, value) { };
19411 /**
19412 * @abstract
19413 * @param {?} text
19414 * @return {?}
19415 */
19416 DomAdapter.prototype.createComment = function (text) { };
19417 /**
19418 * @abstract
19419 * @param {?} html
19420 * @return {?}
19421 */
19422 DomAdapter.prototype.createTemplate = function (html) { };
19423 /**
19424 * @abstract
19425 * @param {?} tagName
19426 * @param {?=} doc
19427 * @return {?}
19428 */
19429 DomAdapter.prototype.createElement = function (tagName, doc) { };
19430 /**
19431 * @abstract
19432 * @param {?} ns
19433 * @param {?} tagName
19434 * @param {?=} doc
19435 * @return {?}
19436 */
19437 DomAdapter.prototype.createElementNS = function (ns, tagName, doc) { };
19438 /**
19439 * @abstract
19440 * @param {?} text
19441 * @param {?=} doc
19442 * @return {?}
19443 */
19444 DomAdapter.prototype.createTextNode = function (text, doc) { };
19445 /**
19446 * @abstract
19447 * @param {?} attrName
19448 * @param {?} attrValue
19449 * @param {?=} doc
19450 * @return {?}
19451 */
19452 DomAdapter.prototype.createScriptTag = function (attrName, attrValue, doc) { };
19453 /**
19454 * @abstract
19455 * @param {?} css
19456 * @param {?=} doc
19457 * @return {?}
19458 */
19459 DomAdapter.prototype.createStyleElement = function (css, doc) { };
19460 /**
19461 * @abstract
19462 * @param {?} el
19463 * @return {?}
19464 */
19465 DomAdapter.prototype.createShadowRoot = function (el) { };
19466 /**
19467 * @abstract
19468 * @param {?} el
19469 * @return {?}
19470 */
19471 DomAdapter.prototype.getShadowRoot = function (el) { };
19472 /**
19473 * @abstract
19474 * @param {?} el
19475 * @return {?}
19476 */
19477 DomAdapter.prototype.getHost = function (el) { };
19478 /**
19479 * @abstract
19480 * @param {?} el
19481 * @return {?}
19482 */
19483 DomAdapter.prototype.getDistributedNodes = function (el) { };
19484 /**
19485 * @abstract
19486 * @param {?} node
19487 * @return {?}
19488 */
19489 DomAdapter.prototype.clone /*<T extends Node>*/ = function (node) { };
19490 /**
19491 * @abstract
19492 * @param {?} element
19493 * @param {?} name
19494 * @return {?}
19495 */
19496 DomAdapter.prototype.getElementsByClassName = function (element, name) { };
19497 /**
19498 * @abstract
19499 * @param {?} element
19500 * @param {?} name
19501 * @return {?}
19502 */
19503 DomAdapter.prototype.getElementsByTagName = function (element, name) { };
19504 /**
19505 * @abstract
19506 * @param {?} element
19507 * @return {?}
19508 */
19509 DomAdapter.prototype.classList = function (element) { };
19510 /**
19511 * @abstract
19512 * @param {?} element
19513 * @param {?} className
19514 * @return {?}
19515 */
19516 DomAdapter.prototype.addClass = function (element, className) { };
19517 /**
19518 * @abstract
19519 * @param {?} element
19520 * @param {?} className
19521 * @return {?}
19522 */
19523 DomAdapter.prototype.removeClass = function (element, className) { };
19524 /**
19525 * @abstract
19526 * @param {?} element
19527 * @param {?} className
19528 * @return {?}
19529 */
19530 DomAdapter.prototype.hasClass = function (element, className) { };
19531 /**
19532 * @abstract
19533 * @param {?} element
19534 * @param {?} styleName
19535 * @param {?} styleValue
19536 * @return {?}
19537 */
19538 DomAdapter.prototype.setStyle = function (element, styleName, styleValue) { };
19539 /**
19540 * @abstract
19541 * @param {?} element
19542 * @param {?} styleName
19543 * @return {?}
19544 */
19545 DomAdapter.prototype.removeStyle = function (element, styleName) { };
19546 /**
19547 * @abstract
19548 * @param {?} element
19549 * @param {?} styleName
19550 * @return {?}
19551 */
19552 DomAdapter.prototype.getStyle = function (element, styleName) { };
19553 /**
19554 * @abstract
19555 * @param {?} element
19556 * @param {?} styleName
19557 * @param {?=} styleValue
19558 * @return {?}
19559 */
19560 DomAdapter.prototype.hasStyle = function (element, styleName, styleValue) { };
19561 /**
19562 * @abstract
19563 * @param {?} element
19564 * @return {?}
19565 */
19566 DomAdapter.prototype.tagName = function (element) { };
19567 /**
19568 * @abstract
19569 * @param {?} element
19570 * @return {?}
19571 */
19572 DomAdapter.prototype.attributeMap = function (element) { };
19573 /**
19574 * @abstract
19575 * @param {?} element
19576 * @param {?} attribute
19577 * @return {?}
19578 */
19579 DomAdapter.prototype.hasAttribute = function (element, attribute) { };
19580 /**
19581 * @abstract
19582 * @param {?} element
19583 * @param {?} ns
19584 * @param {?} attribute
19585 * @return {?}
19586 */
19587 DomAdapter.prototype.hasAttributeNS = function (element, ns, attribute) { };
19588 /**
19589 * @abstract
19590 * @param {?} element
19591 * @param {?} attribute
19592 * @return {?}
19593 */
19594 DomAdapter.prototype.getAttribute = function (element, attribute) { };
19595 /**
19596 * @abstract
19597 * @param {?} element
19598 * @param {?} ns
19599 * @param {?} attribute
19600 * @return {?}
19601 */
19602 DomAdapter.prototype.getAttributeNS = function (element, ns, attribute) { };
19603 /**
19604 * @abstract
19605 * @param {?} element
19606 * @param {?} name
19607 * @param {?} value
19608 * @return {?}
19609 */
19610 DomAdapter.prototype.setAttribute = function (element, name, value) { };
19611 /**
19612 * @abstract
19613 * @param {?} element
19614 * @param {?} ns
19615 * @param {?} name
19616 * @param {?} value
19617 * @return {?}
19618 */
19619 DomAdapter.prototype.setAttributeNS = function (element, ns, name, value) { };
19620 /**
19621 * @abstract
19622 * @param {?} element
19623 * @param {?} attribute
19624 * @return {?}
19625 */
19626 DomAdapter.prototype.removeAttribute = function (element, attribute) { };
19627 /**
19628 * @abstract
19629 * @param {?} element
19630 * @param {?} ns
19631 * @param {?} attribute
19632 * @return {?}
19633 */
19634 DomAdapter.prototype.removeAttributeNS = function (element, ns, attribute) { };
19635 /**
19636 * @abstract
19637 * @param {?} el
19638 * @return {?}
19639 */
19640 DomAdapter.prototype.templateAwareRoot = function (el) { };
19641 /**
19642 * @abstract
19643 * @return {?}
19644 */
19645 DomAdapter.prototype.createHtmlDocument = function () { };
19646 /**
19647 * @abstract
19648 * @param {?} el
19649 * @return {?}
19650 */
19651 DomAdapter.prototype.getBoundingClientRect = function (el) { };
19652 /**
19653 * @abstract
19654 * @param {?} doc
19655 * @return {?}
19656 */
19657 DomAdapter.prototype.getTitle = function (doc) { };
19658 /**
19659 * @abstract
19660 * @param {?} doc
19661 * @param {?} newTitle
19662 * @return {?}
19663 */
19664 DomAdapter.prototype.setTitle = function (doc, newTitle) { };
19665 /**
19666 * @abstract
19667 * @param {?} n
19668 * @param {?} selector
19669 * @return {?}
19670 */
19671 DomAdapter.prototype.elementMatches = function (n, selector) { };
19672 /**
19673 * @abstract
19674 * @param {?} el
19675 * @return {?}
19676 */
19677 DomAdapter.prototype.isTemplateElement = function (el) { };
19678 /**
19679 * @abstract
19680 * @param {?} node
19681 * @return {?}
19682 */
19683 DomAdapter.prototype.isTextNode = function (node) { };
19684 /**
19685 * @abstract
19686 * @param {?} node
19687 * @return {?}
19688 */
19689 DomAdapter.prototype.isCommentNode = function (node) { };
19690 /**
19691 * @abstract
19692 * @param {?} node
19693 * @return {?}
19694 */
19695 DomAdapter.prototype.isElementNode = function (node) { };
19696 /**
19697 * @abstract
19698 * @param {?} node
19699 * @return {?}
19700 */
19701 DomAdapter.prototype.hasShadowRoot = function (node) { };
19702 /**
19703 * @abstract
19704 * @param {?} node
19705 * @return {?}
19706 */
19707 DomAdapter.prototype.isShadowRoot = function (node) { };
19708 /**
19709 * @abstract
19710 * @param {?} node
19711 * @return {?}
19712 */
19713 DomAdapter.prototype.importIntoDoc /*<T extends Node>*/ = function (node) { };
19714 /**
19715 * @abstract
19716 * @param {?} node
19717 * @return {?}
19718 */
19719 DomAdapter.prototype.adoptNode /*<T extends Node>*/ = function (node) { };
19720 /**
19721 * @abstract
19722 * @param {?} element
19723 * @return {?}
19724 */
19725 DomAdapter.prototype.getHref = function (element) { };
19726 /**
19727 * @abstract
19728 * @param {?} event
19729 * @return {?}
19730 */
19731 DomAdapter.prototype.getEventKey = function (event) { };
19732 /**
19733 * @abstract
19734 * @param {?} element
19735 * @param {?} baseUrl
19736 * @param {?} href
19737 * @return {?}
19738 */
19739 DomAdapter.prototype.resolveAndSetHref = function (element, baseUrl, href) { };
19740 /**
19741 * @abstract
19742 * @return {?}
19743 */
19744 DomAdapter.prototype.supportsDOMEvents = function () { };
19745 /**
19746 * @abstract
19747 * @return {?}
19748 */
19749 DomAdapter.prototype.supportsNativeShadowDOM = function () { };
19750 /**
19751 * @abstract
19752 * @param {?} doc
19753 * @param {?} target
19754 * @return {?}
19755 */
19756 DomAdapter.prototype.getGlobalEventTarget = function (doc, target) { };
19757 /**
19758 * @abstract
19759 * @return {?}
19760 */
19761 DomAdapter.prototype.getHistory = function () { };
19762 /**
19763 * @abstract
19764 * @return {?}
19765 */
19766 DomAdapter.prototype.getLocation = function () { };
19767 /**
19768 * @abstract
19769 * @param {?} doc
19770 * @return {?}
19771 */
19772 DomAdapter.prototype.getBaseHref = function (doc) { };
19773 /**
19774 * @abstract
19775 * @return {?}
19776 */
19777 DomAdapter.prototype.resetBaseElement = function () { };
19778 /**
19779 * @abstract
19780 * @return {?}
19781 */
19782 DomAdapter.prototype.getUserAgent = function () { };
19783 /**
19784 * @abstract
19785 * @param {?} element
19786 * @param {?} name
19787 * @param {?} value
19788 * @return {?}
19789 */
19790 DomAdapter.prototype.setData = function (element, name, value) { };
19791 /**
19792 * @abstract
19793 * @param {?} element
19794 * @return {?}
19795 */
19796 DomAdapter.prototype.getComputedStyle = function (element) { };
19797 /**
19798 * @abstract
19799 * @param {?} element
19800 * @param {?} name
19801 * @return {?}
19802 */
19803 DomAdapter.prototype.getData = function (element, name) { };
19804 /**
19805 * @abstract
19806 * @return {?}
19807 */
19808 DomAdapter.prototype.supportsWebAnimation = function () { };
19809 /**
19810 * @abstract
19811 * @return {?}
19812 */
19813 DomAdapter.prototype.performanceNow = function () { };
19814 /**
19815 * @abstract
19816 * @return {?}
19817 */
19818 DomAdapter.prototype.getAnimationPrefix = function () { };
19819 /**
19820 * @abstract
19821 * @return {?}
19822 */
19823 DomAdapter.prototype.getTransitionEnd = function () { };
19824 /**
19825 * @abstract
19826 * @return {?}
19827 */
19828 DomAdapter.prototype.supportsAnimation = function () { };
19829 /**
19830 * @abstract
19831 * @return {?}
19832 */
19833 DomAdapter.prototype.supportsCookies = function () { };
19834 /**
19835 * @abstract
19836 * @param {?} name
19837 * @return {?}
19838 */
19839 DomAdapter.prototype.getCookie = function (name) { };
19840 /**
19841 * @abstract
19842 * @param {?} name
19843 * @param {?} value
19844 * @return {?}
19845 */
19846 DomAdapter.prototype.setCookie = function (name, value) { };
19847 return DomAdapter;
19848}());
19849/**
19850 * @license
19851 * Copyright Google Inc. All Rights Reserved.
19852 *
19853 * Use of this source code is governed by an MIT-style license that can be
19854 * found in the LICENSE file at https://angular.io/license
19855 */
19856/**
19857 * Provides DOM operations in any browser environment.
19858 *
19859 * \@security Tread carefully! Interacting with the DOM directly is dangerous and
19860 * can introduce XSS risks.
19861 * @abstract
19862 */
19863var GenericBrowserDomAdapter = (function (_super) {
19864 __extends$1(GenericBrowserDomAdapter, _super);
19865 function GenericBrowserDomAdapter() {
19866 var _this = _super.call(this) || this;
19867 _this._animationPrefix = null;
19868 _this._transitionEnd = null;
19869 try {
19870 var element_1 = _this.createElement('div', document);
19871 if (_this.getStyle(element_1, 'animationName') != null) {
19872 _this._animationPrefix = '';
19873 }
19874 else {
19875 var domPrefixes = ['Webkit', 'Moz', 'O', 'ms'];
19876 for (var i = 0; i < domPrefixes.length; i++) {
19877 if (_this.getStyle(element_1, domPrefixes[i] + 'AnimationName') != null) {
19878 _this._animationPrefix = '-' + domPrefixes[i].toLowerCase() + '-';
19879 break;
19880 }
19881 }
19882 }
19883 var transEndEventNames_1 = {
19884 WebkitTransition: 'webkitTransitionEnd',
19885 MozTransition: 'transitionend',
19886 OTransition: 'oTransitionEnd otransitionend',
19887 transition: 'transitionend'
19888 };
19889 Object.keys(transEndEventNames_1).forEach(function (key) {
19890 if (_this.getStyle(element_1, key) != null) {
19891 _this._transitionEnd = transEndEventNames_1[key];
19892 }
19893 });
19894 }
19895 catch (e) {
19896 _this._animationPrefix = null;
19897 _this._transitionEnd = null;
19898 }
19899 return _this;
19900 }
19901 /**
19902 * @param {?} el
19903 * @return {?}
19904 */
19905 GenericBrowserDomAdapter.prototype.getDistributedNodes = function (el) { return ((el)).getDistributedNodes(); };
19906 /**
19907 * @param {?} el
19908 * @param {?} baseUrl
19909 * @param {?} href
19910 * @return {?}
19911 */
19912 GenericBrowserDomAdapter.prototype.resolveAndSetHref = function (el, baseUrl, href) {
19913 el.href = href == null ? baseUrl : baseUrl + '/../' + href;
19914 };
19915 /**
19916 * @return {?}
19917 */
19918 GenericBrowserDomAdapter.prototype.supportsDOMEvents = function () { return true; };
19919 /**
19920 * @return {?}
19921 */
19922 GenericBrowserDomAdapter.prototype.supportsNativeShadowDOM = function () {
19923 return typeof ((document.body)).createShadowRoot === 'function';
19924 };
19925 /**
19926 * @return {?}
19927 */
19928 GenericBrowserDomAdapter.prototype.getAnimationPrefix = function () { return this._animationPrefix ? this._animationPrefix : ''; };
19929 /**
19930 * @return {?}
19931 */
19932 GenericBrowserDomAdapter.prototype.getTransitionEnd = function () { return this._transitionEnd ? this._transitionEnd : ''; };
19933 /**
19934 * @return {?}
19935 */
19936 GenericBrowserDomAdapter.prototype.supportsAnimation = function () {
19937 return this._animationPrefix != null && this._transitionEnd != null;
19938 };
19939 return GenericBrowserDomAdapter;
19940}(DomAdapter));
19941/**
19942 * @license
19943 * Copyright Google Inc. All Rights Reserved.
19944 *
19945 * Use of this source code is governed by an MIT-style license that can be
19946 * found in the LICENSE file at https://angular.io/license
19947 */
19948var _attrToPropMap = {
19949 'class': 'className',
19950 'innerHtml': 'innerHTML',
19951 'readonly': 'readOnly',
19952 'tabindex': 'tabIndex',
19953};
19954var DOM_KEY_LOCATION_NUMPAD = 3;
19955// Map to convert some key or keyIdentifier values to what will be returned by getEventKey
19956var _keyMap = {
19957 // The following values are here for cross-browser compatibility and to match the W3C standard
19958 // cf http://www.w3.org/TR/DOM-Level-3-Events-key/
19959 '\b': 'Backspace',
19960 '\t': 'Tab',
19961 '\x7F': 'Delete',
19962 '\x1B': 'Escape',
19963 'Del': 'Delete',
19964 'Esc': 'Escape',
19965 'Left': 'ArrowLeft',
19966 'Right': 'ArrowRight',
19967 'Up': 'ArrowUp',
19968 'Down': 'ArrowDown',
19969 'Menu': 'ContextMenu',
19970 'Scroll': 'ScrollLock',
19971 'Win': 'OS'
19972};
19973// There is a bug in Chrome for numeric keypad keys:
19974// https://code.google.com/p/chromium/issues/detail?id=155654
19975// 1, 2, 3 ... are reported as A, B, C ...
19976var _chromeNumKeyPadMap = {
19977 'A': '1',
19978 'B': '2',
19979 'C': '3',
19980 'D': '4',
19981 'E': '5',
19982 'F': '6',
19983 'G': '7',
19984 'H': '8',
19985 'I': '9',
19986 'J': '*',
19987 'K': '+',
19988 'M': '-',
19989 'N': '.',
19990 'O': '/',
19991 '\x60': '0',
19992 '\x90': 'NumLock'
19993};
19994var nodeContains;
19995if (_global['Node']) {
19996 nodeContains = _global['Node'].prototype.contains || function (node) {
19997 return !!(this.compareDocumentPosition(node) & 16);
19998 };
19999}
20000var BrowserDomAdapter = (function (_super) {
20001 __extends$1(BrowserDomAdapter, _super);
20002 function BrowserDomAdapter() {
20003 return _super !== null && _super.apply(this, arguments) || this;
20004 }
20005 /**
20006 * @param {?} templateHtml
20007 * @return {?}
20008 */
20009 BrowserDomAdapter.prototype.parse = function (templateHtml) { throw new Error('parse not implemented'); };
20010 /**
20011 * @return {?}
20012 */
20013 BrowserDomAdapter.makeCurrent = function () { setRootDomAdapter(new BrowserDomAdapter()); };
20014 /**
20015 * @param {?} element
20016 * @param {?} name
20017 * @return {?}
20018 */
20019 BrowserDomAdapter.prototype.hasProperty = function (element, name) { return name in element; };
20020 /**
20021 * @param {?} el
20022 * @param {?} name
20023 * @param {?} value
20024 * @return {?}
20025 */
20026 BrowserDomAdapter.prototype.setProperty = function (el, name, value) { ((el))[name] = value; };
20027 /**
20028 * @param {?} el
20029 * @param {?} name
20030 * @return {?}
20031 */
20032 BrowserDomAdapter.prototype.getProperty = function (el, name) { return ((el))[name]; };
20033 /**
20034 * @param {?} el
20035 * @param {?} methodName
20036 * @param {?} args
20037 * @return {?}
20038 */
20039 BrowserDomAdapter.prototype.invoke = function (el, methodName, args) { ((el))[methodName].apply(((el)), args); };
20040 /**
20041 * @param {?} error
20042 * @return {?}
20043 */
20044 BrowserDomAdapter.prototype.logError = function (error) {
20045 if (window.console) {
20046 if (console.error) {
20047 console.error(error);
20048 }
20049 else {
20050 console.log(error);
20051 }
20052 }
20053 };
20054 /**
20055 * @param {?} error
20056 * @return {?}
20057 */
20058 BrowserDomAdapter.prototype.log = function (error) {
20059 if (window.console) {
20060 window.console.log && window.console.log(error);
20061 }
20062 };
20063 /**
20064 * @param {?} error
20065 * @return {?}
20066 */
20067 BrowserDomAdapter.prototype.logGroup = function (error) {
20068 if (window.console) {
20069 window.console.group && window.console.group(error);
20070 }
20071 };
20072 /**
20073 * @return {?}
20074 */
20075 BrowserDomAdapter.prototype.logGroupEnd = function () {
20076 if (window.console) {
20077 window.console.groupEnd && window.console.groupEnd();
20078 }
20079 };
20080 Object.defineProperty(BrowserDomAdapter.prototype, "attrToPropMap", {
20081 /**
20082 * @return {?}
20083 */
20084 get: function () { return _attrToPropMap; },
20085 enumerable: true,
20086 configurable: true
20087 });
20088 /**
20089 * @param {?} nodeA
20090 * @param {?} nodeB
20091 * @return {?}
20092 */
20093 BrowserDomAdapter.prototype.contains = function (nodeA, nodeB) { return nodeContains.call(nodeA, nodeB); };
20094 /**
20095 * @param {?} el
20096 * @param {?} selector
20097 * @return {?}
20098 */
20099 BrowserDomAdapter.prototype.querySelector = function (el, selector) { return el.querySelector(selector); };
20100 /**
20101 * @param {?} el
20102 * @param {?} selector
20103 * @return {?}
20104 */
20105 BrowserDomAdapter.prototype.querySelectorAll = function (el, selector) { return el.querySelectorAll(selector); };
20106 /**
20107 * @param {?} el
20108 * @param {?} evt
20109 * @param {?} listener
20110 * @return {?}
20111 */
20112 BrowserDomAdapter.prototype.on = function (el, evt, listener) { el.addEventListener(evt, listener, false); };
20113 /**
20114 * @param {?} el
20115 * @param {?} evt
20116 * @param {?} listener
20117 * @return {?}
20118 */
20119 BrowserDomAdapter.prototype.onAndCancel = function (el, evt, listener) {
20120 el.addEventListener(evt, listener, false);
20121 // Needed to follow Dart's subscription semantic, until fix of
20122 // https://code.google.com/p/dart/issues/detail?id=17406
20123 return function () { el.removeEventListener(evt, listener, false); };
20124 };
20125 /**
20126 * @param {?} el
20127 * @param {?} evt
20128 * @return {?}
20129 */
20130 BrowserDomAdapter.prototype.dispatchEvent = function (el, evt) { el.dispatchEvent(evt); };
20131 /**
20132 * @param {?} eventType
20133 * @return {?}
20134 */
20135 BrowserDomAdapter.prototype.createMouseEvent = function (eventType) {
20136 var /** @type {?} */ evt = document.createEvent('MouseEvent');
20137 evt.initEvent(eventType, true, true);
20138 return evt;
20139 };
20140 /**
20141 * @param {?} eventType
20142 * @return {?}
20143 */
20144 BrowserDomAdapter.prototype.createEvent = function (eventType) {
20145 var /** @type {?} */ evt = document.createEvent('Event');
20146 evt.initEvent(eventType, true, true);
20147 return evt;
20148 };
20149 /**
20150 * @param {?} evt
20151 * @return {?}
20152 */
20153 BrowserDomAdapter.prototype.preventDefault = function (evt) {
20154 evt.preventDefault();
20155 evt.returnValue = false;
20156 };
20157 /**
20158 * @param {?} evt
20159 * @return {?}
20160 */
20161 BrowserDomAdapter.prototype.isPrevented = function (evt) {
20162 return evt.defaultPrevented || evt.returnValue != null && !evt.returnValue;
20163 };
20164 /**
20165 * @param {?} el
20166 * @return {?}
20167 */
20168 BrowserDomAdapter.prototype.getInnerHTML = function (el) { return el.innerHTML; };
20169 /**
20170 * @param {?} el
20171 * @return {?}
20172 */
20173 BrowserDomAdapter.prototype.getTemplateContent = function (el) {
20174 return 'content' in el && el instanceof HTMLTemplateElement ? el.content : null;
20175 };
20176 /**
20177 * @param {?} el
20178 * @return {?}
20179 */
20180 BrowserDomAdapter.prototype.getOuterHTML = function (el) { return el.outerHTML; };
20181 /**
20182 * @param {?} node
20183 * @return {?}
20184 */
20185 BrowserDomAdapter.prototype.nodeName = function (node) { return node.nodeName; };
20186 /**
20187 * @param {?} node
20188 * @return {?}
20189 */
20190 BrowserDomAdapter.prototype.nodeValue = function (node) { return node.nodeValue; };
20191 /**
20192 * @param {?} node
20193 * @return {?}
20194 */
20195 BrowserDomAdapter.prototype.type = function (node) { return node.type; };
20196 /**
20197 * @param {?} node
20198 * @return {?}
20199 */
20200 BrowserDomAdapter.prototype.content = function (node) {
20201 if (this.hasProperty(node, 'content')) {
20202 return ((node)).content;
20203 }
20204 else {
20205 return node;
20206 }
20207 };
20208 /**
20209 * @param {?} el
20210 * @return {?}
20211 */
20212 BrowserDomAdapter.prototype.firstChild = function (el) { return el.firstChild; };
20213 /**
20214 * @param {?} el
20215 * @return {?}
20216 */
20217 BrowserDomAdapter.prototype.nextSibling = function (el) { return el.nextSibling; };
20218 /**
20219 * @param {?} el
20220 * @return {?}
20221 */
20222 BrowserDomAdapter.prototype.parentElement = function (el) { return el.parentNode; };
20223 /**
20224 * @param {?} el
20225 * @return {?}
20226 */
20227 BrowserDomAdapter.prototype.childNodes = function (el) { return el.childNodes; };
20228 /**
20229 * @param {?} el
20230 * @return {?}
20231 */
20232 BrowserDomAdapter.prototype.childNodesAsList = function (el) {
20233 var /** @type {?} */ childNodes = el.childNodes;
20234 var /** @type {?} */ res = new Array(childNodes.length);
20235 for (var /** @type {?} */ i = 0; i < childNodes.length; i++) {
20236 res[i] = childNodes[i];
20237 }
20238 return res;
20239 };
20240 /**
20241 * @param {?} el
20242 * @return {?}
20243 */
20244 BrowserDomAdapter.prototype.clearNodes = function (el) {
20245 while (el.firstChild) {
20246 el.removeChild(el.firstChild);
20247 }
20248 };
20249 /**
20250 * @param {?} el
20251 * @param {?} node
20252 * @return {?}
20253 */
20254 BrowserDomAdapter.prototype.appendChild = function (el, node) { el.appendChild(node); };
20255 /**
20256 * @param {?} el
20257 * @param {?} node
20258 * @return {?}
20259 */
20260 BrowserDomAdapter.prototype.removeChild = function (el, node) { el.removeChild(node); };
20261 /**
20262 * @param {?} el
20263 * @param {?} newChild
20264 * @param {?} oldChild
20265 * @return {?}
20266 */
20267 BrowserDomAdapter.prototype.replaceChild = function (el, newChild, oldChild) { el.replaceChild(newChild, oldChild); };
20268 /**
20269 * @param {?} node
20270 * @return {?}
20271 */
20272 BrowserDomAdapter.prototype.remove = function (node) {
20273 if (node.parentNode) {
20274 node.parentNode.removeChild(node);
20275 }
20276 return node;
20277 };
20278 /**
20279 * @param {?} parent
20280 * @param {?} ref
20281 * @param {?} node
20282 * @return {?}
20283 */
20284 BrowserDomAdapter.prototype.insertBefore = function (parent, ref, node) { parent.insertBefore(node, ref); };
20285 /**
20286 * @param {?} parent
20287 * @param {?} ref
20288 * @param {?} nodes
20289 * @return {?}
20290 */
20291 BrowserDomAdapter.prototype.insertAllBefore = function (parent, ref, nodes) {
20292 nodes.forEach(function (n) { return parent.insertBefore(n, ref); });
20293 };
20294 /**
20295 * @param {?} parent
20296 * @param {?} ref
20297 * @param {?} node
20298 * @return {?}
20299 */
20300 BrowserDomAdapter.prototype.insertAfter = function (parent, ref, node) { parent.insertBefore(node, ref.nextSibling); };
20301 /**
20302 * @param {?} el
20303 * @param {?} value
20304 * @return {?}
20305 */
20306 BrowserDomAdapter.prototype.setInnerHTML = function (el, value) { el.innerHTML = value; };
20307 /**
20308 * @param {?} el
20309 * @return {?}
20310 */
20311 BrowserDomAdapter.prototype.getText = function (el) { return el.textContent; };
20312 /**
20313 * @param {?} el
20314 * @param {?} value
20315 * @return {?}
20316 */
20317 BrowserDomAdapter.prototype.setText = function (el, value) { el.textContent = value; };
20318 /**
20319 * @param {?} el
20320 * @return {?}
20321 */
20322 BrowserDomAdapter.prototype.getValue = function (el) { return el.value; };
20323 /**
20324 * @param {?} el
20325 * @param {?} value
20326 * @return {?}
20327 */
20328 BrowserDomAdapter.prototype.setValue = function (el, value) { el.value = value; };
20329 /**
20330 * @param {?} el
20331 * @return {?}
20332 */
20333 BrowserDomAdapter.prototype.getChecked = function (el) { return el.checked; };
20334 /**
20335 * @param {?} el
20336 * @param {?} value
20337 * @return {?}
20338 */
20339 BrowserDomAdapter.prototype.setChecked = function (el, value) { el.checked = value; };
20340 /**
20341 * @param {?} text
20342 * @return {?}
20343 */
20344 BrowserDomAdapter.prototype.createComment = function (text) { return document.createComment(text); };
20345 /**
20346 * @param {?} html
20347 * @return {?}
20348 */
20349 BrowserDomAdapter.prototype.createTemplate = function (html) {
20350 var /** @type {?} */ t = document.createElement('template');
20351 t.innerHTML = html;
20352 return t;
20353 };
20354 /**
20355 * @param {?} tagName
20356 * @param {?=} doc
20357 * @return {?}
20358 */
20359 BrowserDomAdapter.prototype.createElement = function (tagName, doc) {
20360 if (doc === void 0) { doc = document; }
20361 return doc.createElement(tagName);
20362 };
20363 /**
20364 * @param {?} ns
20365 * @param {?} tagName
20366 * @param {?=} doc
20367 * @return {?}
20368 */
20369 BrowserDomAdapter.prototype.createElementNS = function (ns, tagName, doc) {
20370 if (doc === void 0) { doc = document; }
20371 return doc.createElementNS(ns, tagName);
20372 };
20373 /**
20374 * @param {?} text
20375 * @param {?=} doc
20376 * @return {?}
20377 */
20378 BrowserDomAdapter.prototype.createTextNode = function (text, doc) {
20379 if (doc === void 0) { doc = document; }
20380 return doc.createTextNode(text);
20381 };
20382 /**
20383 * @param {?} attrName
20384 * @param {?} attrValue
20385 * @param {?=} doc
20386 * @return {?}
20387 */
20388 BrowserDomAdapter.prototype.createScriptTag = function (attrName, attrValue, doc) {
20389 if (doc === void 0) { doc = document; }
20390 var /** @type {?} */ el = (doc.createElement('SCRIPT'));
20391 el.setAttribute(attrName, attrValue);
20392 return el;
20393 };
20394 /**
20395 * @param {?} css
20396 * @param {?=} doc
20397 * @return {?}
20398 */
20399 BrowserDomAdapter.prototype.createStyleElement = function (css, doc) {
20400 if (doc === void 0) { doc = document; }
20401 var /** @type {?} */ style$$1 = (doc.createElement('style'));
20402 this.appendChild(style$$1, this.createTextNode(css));
20403 return style$$1;
20404 };
20405 /**
20406 * @param {?} el
20407 * @return {?}
20408 */
20409 BrowserDomAdapter.prototype.createShadowRoot = function (el) { return ((el)).createShadowRoot(); };
20410 /**
20411 * @param {?} el
20412 * @return {?}
20413 */
20414 BrowserDomAdapter.prototype.getShadowRoot = function (el) { return ((el)).shadowRoot; };
20415 /**
20416 * @param {?} el
20417 * @return {?}
20418 */
20419 BrowserDomAdapter.prototype.getHost = function (el) { return ((el)).host; };
20420 /**
20421 * @param {?} node
20422 * @return {?}
20423 */
20424 BrowserDomAdapter.prototype.clone = function (node) { return node.cloneNode(true); };
20425 /**
20426 * @param {?} element
20427 * @param {?} name
20428 * @return {?}
20429 */
20430 BrowserDomAdapter.prototype.getElementsByClassName = function (element, name) {
20431 return element.getElementsByClassName(name);
20432 };
20433 /**
20434 * @param {?} element
20435 * @param {?} name
20436 * @return {?}
20437 */
20438 BrowserDomAdapter.prototype.getElementsByTagName = function (element, name) {
20439 return element.getElementsByTagName(name);
20440 };
20441 /**
20442 * @param {?} element
20443 * @return {?}
20444 */
20445 BrowserDomAdapter.prototype.classList = function (element) { return Array.prototype.slice.call(element.classList, 0); };
20446 /**
20447 * @param {?} element
20448 * @param {?} className
20449 * @return {?}
20450 */
20451 BrowserDomAdapter.prototype.addClass = function (element, className) { element.classList.add(className); };
20452 /**
20453 * @param {?} element
20454 * @param {?} className
20455 * @return {?}
20456 */
20457 BrowserDomAdapter.prototype.removeClass = function (element, className) { element.classList.remove(className); };
20458 /**
20459 * @param {?} element
20460 * @param {?} className
20461 * @return {?}
20462 */
20463 BrowserDomAdapter.prototype.hasClass = function (element, className) {
20464 return element.classList.contains(className);
20465 };
20466 /**
20467 * @param {?} element
20468 * @param {?} styleName
20469 * @param {?} styleValue
20470 * @return {?}
20471 */
20472 BrowserDomAdapter.prototype.setStyle = function (element, styleName, styleValue) {
20473 element.style[styleName] = styleValue;
20474 };
20475 /**
20476 * @param {?} element
20477 * @param {?} stylename
20478 * @return {?}
20479 */
20480 BrowserDomAdapter.prototype.removeStyle = function (element, stylename) {
20481 // IE requires '' instead of null
20482 // see https://github.com/angular/angular/issues/7916
20483 element.style[stylename] = '';
20484 };
20485 /**
20486 * @param {?} element
20487 * @param {?} stylename
20488 * @return {?}
20489 */
20490 BrowserDomAdapter.prototype.getStyle = function (element, stylename) { return element.style[stylename]; };
20491 /**
20492 * @param {?} element
20493 * @param {?} styleName
20494 * @param {?=} styleValue
20495 * @return {?}
20496 */
20497 BrowserDomAdapter.prototype.hasStyle = function (element, styleName, styleValue) {
20498 var /** @type {?} */ value = this.getStyle(element, styleName) || '';
20499 return styleValue ? value == styleValue : value.length > 0;
20500 };
20501 /**
20502 * @param {?} element
20503 * @return {?}
20504 */
20505 BrowserDomAdapter.prototype.tagName = function (element) { return element.tagName; };
20506 /**
20507 * @param {?} element
20508 * @return {?}
20509 */
20510 BrowserDomAdapter.prototype.attributeMap = function (element) {
20511 var /** @type {?} */ res = new Map();
20512 var /** @type {?} */ elAttrs = element.attributes;
20513 for (var /** @type {?} */ i = 0; i < elAttrs.length; i++) {
20514 var /** @type {?} */ attrib = elAttrs[i];
20515 res.set(attrib.name, attrib.value);
20516 }
20517 return res;
20518 };
20519 /**
20520 * @param {?} element
20521 * @param {?} attribute
20522 * @return {?}
20523 */
20524 BrowserDomAdapter.prototype.hasAttribute = function (element, attribute) {
20525 return element.hasAttribute(attribute);
20526 };
20527 /**
20528 * @param {?} element
20529 * @param {?} ns
20530 * @param {?} attribute
20531 * @return {?}
20532 */
20533 BrowserDomAdapter.prototype.hasAttributeNS = function (element, ns, attribute) {
20534 return element.hasAttributeNS(ns, attribute);
20535 };
20536 /**
20537 * @param {?} element
20538 * @param {?} attribute
20539 * @return {?}
20540 */
20541 BrowserDomAdapter.prototype.getAttribute = function (element, attribute) {
20542 return element.getAttribute(attribute);
20543 };
20544 /**
20545 * @param {?} element
20546 * @param {?} ns
20547 * @param {?} name
20548 * @return {?}
20549 */
20550 BrowserDomAdapter.prototype.getAttributeNS = function (element, ns, name) {
20551 return element.getAttributeNS(ns, name);
20552 };
20553 /**
20554 * @param {?} element
20555 * @param {?} name
20556 * @param {?} value
20557 * @return {?}
20558 */
20559 BrowserDomAdapter.prototype.setAttribute = function (element, name, value) { element.setAttribute(name, value); };
20560 /**
20561 * @param {?} element
20562 * @param {?} ns
20563 * @param {?} name
20564 * @param {?} value
20565 * @return {?}
20566 */
20567 BrowserDomAdapter.prototype.setAttributeNS = function (element, ns, name, value) {
20568 element.setAttributeNS(ns, name, value);
20569 };
20570 /**
20571 * @param {?} element
20572 * @param {?} attribute
20573 * @return {?}
20574 */
20575 BrowserDomAdapter.prototype.removeAttribute = function (element, attribute) { element.removeAttribute(attribute); };
20576 /**
20577 * @param {?} element
20578 * @param {?} ns
20579 * @param {?} name
20580 * @return {?}
20581 */
20582 BrowserDomAdapter.prototype.removeAttributeNS = function (element, ns, name) {
20583 element.removeAttributeNS(ns, name);
20584 };
20585 /**
20586 * @param {?} el
20587 * @return {?}
20588 */
20589 BrowserDomAdapter.prototype.templateAwareRoot = function (el) { return this.isTemplateElement(el) ? this.content(el) : el; };
20590 /**
20591 * @return {?}
20592 */
20593 BrowserDomAdapter.prototype.createHtmlDocument = function () {
20594 return document.implementation.createHTMLDocument('fakeTitle');
20595 };
20596 /**
20597 * @param {?} el
20598 * @return {?}
20599 */
20600 BrowserDomAdapter.prototype.getBoundingClientRect = function (el) {
20601 try {
20602 return el.getBoundingClientRect();
20603 }
20604 catch (e) {
20605 return { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
20606 }
20607 };
20608 /**
20609 * @param {?} doc
20610 * @return {?}
20611 */
20612 BrowserDomAdapter.prototype.getTitle = function (doc) { return document.title; };
20613 /**
20614 * @param {?} doc
20615 * @param {?} newTitle
20616 * @return {?}
20617 */
20618 BrowserDomAdapter.prototype.setTitle = function (doc, newTitle) { document.title = newTitle || ''; };
20619 /**
20620 * @param {?} n
20621 * @param {?} selector
20622 * @return {?}
20623 */
20624 BrowserDomAdapter.prototype.elementMatches = function (n, selector) {
20625 if (n instanceof HTMLElement) {
20626 return n.matches && n.matches(selector) ||
20627 n.msMatchesSelector && n.msMatchesSelector(selector) ||
20628 n.webkitMatchesSelector && n.webkitMatchesSelector(selector);
20629 }
20630 return false;
20631 };
20632 /**
20633 * @param {?} el
20634 * @return {?}
20635 */
20636 BrowserDomAdapter.prototype.isTemplateElement = function (el) {
20637 return el instanceof HTMLElement && el.nodeName == 'TEMPLATE';
20638 };
20639 /**
20640 * @param {?} node
20641 * @return {?}
20642 */
20643 BrowserDomAdapter.prototype.isTextNode = function (node) { return node.nodeType === Node.TEXT_NODE; };
20644 /**
20645 * @param {?} node
20646 * @return {?}
20647 */
20648 BrowserDomAdapter.prototype.isCommentNode = function (node) { return node.nodeType === Node.COMMENT_NODE; };
20649 /**
20650 * @param {?} node
20651 * @return {?}
20652 */
20653 BrowserDomAdapter.prototype.isElementNode = function (node) { return node.nodeType === Node.ELEMENT_NODE; };
20654 /**
20655 * @param {?} node
20656 * @return {?}
20657 */
20658 BrowserDomAdapter.prototype.hasShadowRoot = function (node) {
20659 return node.shadowRoot != null && node instanceof HTMLElement;
20660 };
20661 /**
20662 * @param {?} node
20663 * @return {?}
20664 */
20665 BrowserDomAdapter.prototype.isShadowRoot = function (node) { return node instanceof DocumentFragment; };
20666 /**
20667 * @param {?} node
20668 * @return {?}
20669 */
20670 BrowserDomAdapter.prototype.importIntoDoc = function (node) { return document.importNode(this.templateAwareRoot(node), true); };
20671 /**
20672 * @param {?} node
20673 * @return {?}
20674 */
20675 BrowserDomAdapter.prototype.adoptNode = function (node) { return document.adoptNode(node); };
20676 /**
20677 * @param {?} el
20678 * @return {?}
20679 */
20680 BrowserDomAdapter.prototype.getHref = function (el) { return ((el)).href; };
20681 /**
20682 * @param {?} event
20683 * @return {?}
20684 */
20685 BrowserDomAdapter.prototype.getEventKey = function (event) {
20686 var /** @type {?} */ key = event.key;
20687 if (key == null) {
20688 key = event.keyIdentifier;
20689 // keyIdentifier is defined in the old draft of DOM Level 3 Events implemented by Chrome and
20690 // Safari cf
20691 // http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/events.html#Events-KeyboardEvents-Interfaces
20692 if (key == null) {
20693 return 'Unidentified';
20694 }
20695 if (key.startsWith('U+')) {
20696 key = String.fromCharCode(parseInt(key.substring(2), 16));
20697 if (event.location === DOM_KEY_LOCATION_NUMPAD && _chromeNumKeyPadMap.hasOwnProperty(key)) {
20698 // There is a bug in Chrome for numeric keypad keys:
20699 // https://code.google.com/p/chromium/issues/detail?id=155654
20700 // 1, 2, 3 ... are reported as A, B, C ...
20701 key = ((_chromeNumKeyPadMap))[key];
20702 }
20703 }
20704 }
20705 return _keyMap[key] || key;
20706 };
20707 /**
20708 * @param {?} doc
20709 * @param {?} target
20710 * @return {?}
20711 */
20712 BrowserDomAdapter.prototype.getGlobalEventTarget = function (doc, target) {
20713 if (target === 'window') {
20714 return window;
20715 }
20716 if (target === 'document') {
20717 return document;
20718 }
20719 if (target === 'body') {
20720 return document.body;
20721 }
20722 return null;
20723 };
20724 /**
20725 * @return {?}
20726 */
20727 BrowserDomAdapter.prototype.getHistory = function () { return window.history; };
20728 /**
20729 * @return {?}
20730 */
20731 BrowserDomAdapter.prototype.getLocation = function () { return window.location; };
20732 /**
20733 * @param {?} doc
20734 * @return {?}
20735 */
20736 BrowserDomAdapter.prototype.getBaseHref = function (doc) {
20737 var /** @type {?} */ href = getBaseElementHref();
20738 return href == null ? null : relativePath(href);
20739 };
20740 /**
20741 * @return {?}
20742 */
20743 BrowserDomAdapter.prototype.resetBaseElement = function () { baseElement = null; };
20744 /**
20745 * @return {?}
20746 */
20747 BrowserDomAdapter.prototype.getUserAgent = function () { return window.navigator.userAgent; };
20748 /**
20749 * @param {?} element
20750 * @param {?} name
20751 * @param {?} value
20752 * @return {?}
20753 */
20754 BrowserDomAdapter.prototype.setData = function (element, name, value) {
20755 this.setAttribute(element, 'data-' + name, value);
20756 };
20757 /**
20758 * @param {?} element
20759 * @param {?} name
20760 * @return {?}
20761 */
20762 BrowserDomAdapter.prototype.getData = function (element, name) {
20763 return this.getAttribute(element, 'data-' + name);
20764 };
20765 /**
20766 * @param {?} element
20767 * @return {?}
20768 */
20769 BrowserDomAdapter.prototype.getComputedStyle = function (element) { return getComputedStyle(element); };
20770 /**
20771 * @return {?}
20772 */
20773 BrowserDomAdapter.prototype.supportsWebAnimation = function () {
20774 return typeof ((Element)).prototype['animate'] === 'function';
20775 };
20776 /**
20777 * @return {?}
20778 */
20779 BrowserDomAdapter.prototype.performanceNow = function () {
20780 // performance.now() is not available in all browsers, see
20781 // http://caniuse.com/#search=performance.now
20782 return window.performance && window.performance.now ? window.performance.now() :
20783 new Date().getTime();
20784 };
20785 /**
20786 * @return {?}
20787 */
20788 BrowserDomAdapter.prototype.supportsCookies = function () { return true; };
20789 /**
20790 * @param {?} name
20791 * @return {?}
20792 */
20793 BrowserDomAdapter.prototype.getCookie = function (name) { return parseCookieValue(document.cookie, name); };
20794 /**
20795 * @param {?} name
20796 * @param {?} value
20797 * @return {?}
20798 */
20799 BrowserDomAdapter.prototype.setCookie = function (name, value) {
20800 // document.cookie is magical, assigning into it assigns/overrides one cookie value, but does
20801 // not clear other cookies.
20802 document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
20803 };
20804 return BrowserDomAdapter;
20805}(GenericBrowserDomAdapter));
20806var baseElement = null;
20807/**
20808 * @return {?}
20809 */
20810function getBaseElementHref() {
20811 if (!baseElement) {
20812 baseElement = ((document.querySelector('base')));
20813 if (!baseElement) {
20814 return null;
20815 }
20816 }
20817 return baseElement.getAttribute('href');
20818}
20819// based on urlUtils.js in AngularJS 1
20820var urlParsingNode;
20821/**
20822 * @param {?} url
20823 * @return {?}
20824 */
20825function relativePath(url) {
20826 if (!urlParsingNode) {
20827 urlParsingNode = document.createElement('a');
20828 }
20829 urlParsingNode.setAttribute('href', url);
20830 return (urlParsingNode.pathname.charAt(0) === '/') ? urlParsingNode.pathname :
20831 '/' + urlParsingNode.pathname;
20832}
20833/**
20834 * @license
20835 * Copyright Google Inc. All Rights Reserved.
20836 *
20837 * Use of this source code is governed by an MIT-style license that can be
20838 * found in the LICENSE file at https://angular.io/license
20839 */
20840/**
20841 * A DI Token representing the main rendering context. In a browser this is the DOM Document.
20842 *
20843 * Note: Document might not be available in the Application Context when Application and Rendering
20844 * Contexts are not the same (e.g. when running the application into a Web Worker).
20845 *
20846 * @deprecated import from `\@angular/common` instead.
20847 */
20848var DOCUMENT$1 = DOCUMENT;
20849/**
20850 * @license
20851 * Copyright Google Inc. All Rights Reserved.
20852 *
20853 * Use of this source code is governed by an MIT-style license that can be
20854 * found in the LICENSE file at https://angular.io/license
20855 * @return {?}
20856 */
20857function supportsState() {
20858 return !!window.history.pushState;
20859}
20860/**
20861 * @license
20862 * Copyright Google Inc. All Rights Reserved.
20863 *
20864 * Use of this source code is governed by an MIT-style license that can be
20865 * found in the LICENSE file at https://angular.io/license
20866 */
20867/**
20868 * `PlatformLocation` encapsulates all of the direct calls to platform APIs.
20869 * This class should not be used directly by an application developer. Instead, use
20870 * {\@link Location}.
20871 */
20872var BrowserPlatformLocation = (function (_super) {
20873 __extends$1(BrowserPlatformLocation, _super);
20874 /**
20875 * @param {?} _doc
20876 */
20877 function BrowserPlatformLocation(_doc) {
20878 var _this = _super.call(this) || this;
20879 _this._doc = _doc;
20880 _this._init();
20881 return _this;
20882 }
20883 /**
20884 * \@internal
20885 * @return {?}
20886 */
20887 BrowserPlatformLocation.prototype._init = function () {
20888 this._location = getDOM().getLocation();
20889 this._history = getDOM().getHistory();
20890 };
20891 Object.defineProperty(BrowserPlatformLocation.prototype, "location", {
20892 /**
20893 * @return {?}
20894 */
20895 get: function () { return this._location; },
20896 enumerable: true,
20897 configurable: true
20898 });
20899 /**
20900 * @return {?}
20901 */
20902 BrowserPlatformLocation.prototype.getBaseHrefFromDOM = function () { return ((getDOM().getBaseHref(this._doc))); };
20903 /**
20904 * @param {?} fn
20905 * @return {?}
20906 */
20907 BrowserPlatformLocation.prototype.onPopState = function (fn) {
20908 getDOM().getGlobalEventTarget(this._doc, 'window').addEventListener('popstate', fn, false);
20909 };
20910 /**
20911 * @param {?} fn
20912 * @return {?}
20913 */
20914 BrowserPlatformLocation.prototype.onHashChange = function (fn) {
20915 getDOM().getGlobalEventTarget(this._doc, 'window').addEventListener('hashchange', fn, false);
20916 };
20917 Object.defineProperty(BrowserPlatformLocation.prototype, "pathname", {
20918 /**
20919 * @return {?}
20920 */
20921 get: function () { return this._location.pathname; },
20922 /**
20923 * @param {?} newPath
20924 * @return {?}
20925 */
20926 set: function (newPath) { this._location.pathname = newPath; },
20927 enumerable: true,
20928 configurable: true
20929 });
20930 Object.defineProperty(BrowserPlatformLocation.prototype, "search", {
20931 /**
20932 * @return {?}
20933 */
20934 get: function () { return this._location.search; },
20935 enumerable: true,
20936 configurable: true
20937 });
20938 Object.defineProperty(BrowserPlatformLocation.prototype, "hash", {
20939 /**
20940 * @return {?}
20941 */
20942 get: function () { return this._location.hash; },
20943 enumerable: true,
20944 configurable: true
20945 });
20946 /**
20947 * @param {?} state
20948 * @param {?} title
20949 * @param {?} url
20950 * @return {?}
20951 */
20952 BrowserPlatformLocation.prototype.pushState = function (state$$1, title, url) {
20953 if (supportsState()) {
20954 this._history.pushState(state$$1, title, url);
20955 }
20956 else {
20957 this._location.hash = url;
20958 }
20959 };
20960 /**
20961 * @param {?} state
20962 * @param {?} title
20963 * @param {?} url
20964 * @return {?}
20965 */
20966 BrowserPlatformLocation.prototype.replaceState = function (state$$1, title, url) {
20967 if (supportsState()) {
20968 this._history.replaceState(state$$1, title, url);
20969 }
20970 else {
20971 this._location.hash = url;
20972 }
20973 };
20974 /**
20975 * @return {?}
20976 */
20977 BrowserPlatformLocation.prototype.forward = function () { this._history.forward(); };
20978 /**
20979 * @return {?}
20980 */
20981 BrowserPlatformLocation.prototype.back = function () { this._history.back(); };
20982 return BrowserPlatformLocation;
20983}(PlatformLocation));
20984BrowserPlatformLocation.decorators = [
20985 { type: Injectable },
20986];
20987/**
20988 * @nocollapse
20989 */
20990BrowserPlatformLocation.ctorParameters = function () { return [
20991 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
20992]; };
20993/**
20994 * @license
20995 * Copyright Google Inc. All Rights Reserved.
20996 *
20997 * Use of this source code is governed by an MIT-style license that can be
20998 * found in the LICENSE file at https://angular.io/license
20999 */
21000/**
21001 * A service that can be used to get and add meta tags.
21002 *
21003 * \@experimental
21004 */
21005var Meta = (function () {
21006 /**
21007 * @param {?} _doc
21008 */
21009 function Meta(_doc) {
21010 this._doc = _doc;
21011 this._dom = getDOM();
21012 }
21013 /**
21014 * @param {?} tag
21015 * @param {?=} forceCreation
21016 * @return {?}
21017 */
21018 Meta.prototype.addTag = function (tag, forceCreation) {
21019 if (forceCreation === void 0) { forceCreation = false; }
21020 if (!tag)
21021 return null;
21022 return this._getOrCreateElement(tag, forceCreation);
21023 };
21024 /**
21025 * @param {?} tags
21026 * @param {?=} forceCreation
21027 * @return {?}
21028 */
21029 Meta.prototype.addTags = function (tags, forceCreation) {
21030 var _this = this;
21031 if (forceCreation === void 0) { forceCreation = false; }
21032 if (!tags)
21033 return [];
21034 return tags.reduce(function (result, tag) {
21035 if (tag) {
21036 result.push(_this._getOrCreateElement(tag, forceCreation));
21037 }
21038 return result;
21039 }, []);
21040 };
21041 /**
21042 * @param {?} attrSelector
21043 * @return {?}
21044 */
21045 Meta.prototype.getTag = function (attrSelector) {
21046 if (!attrSelector)
21047 return null;
21048 return this._dom.querySelector(this._doc, "meta[" + attrSelector + "]");
21049 };
21050 /**
21051 * @param {?} attrSelector
21052 * @return {?}
21053 */
21054 Meta.prototype.getTags = function (attrSelector) {
21055 if (!attrSelector)
21056 return [];
21057 var /** @type {?} */ list /*NodeList*/ = this._dom.querySelectorAll(this._doc, "meta[" + attrSelector + "]");
21058 return list ? [].slice.call(list) : [];
21059 };
21060 /**
21061 * @param {?} tag
21062 * @param {?=} selector
21063 * @return {?}
21064 */
21065 Meta.prototype.updateTag = function (tag, selector) {
21066 if (!tag)
21067 return null;
21068 selector = selector || this._parseSelector(tag);
21069 var /** @type {?} */ meta = ((this.getTag(selector)));
21070 if (meta) {
21071 return this._setMetaElementAttributes(tag, meta);
21072 }
21073 return this._getOrCreateElement(tag, true);
21074 };
21075 /**
21076 * @param {?} attrSelector
21077 * @return {?}
21078 */
21079 Meta.prototype.removeTag = function (attrSelector) { this.removeTagElement(/** @type {?} */ ((this.getTag(attrSelector)))); };
21080 /**
21081 * @param {?} meta
21082 * @return {?}
21083 */
21084 Meta.prototype.removeTagElement = function (meta) {
21085 if (meta) {
21086 this._dom.remove(meta);
21087 }
21088 };
21089 /**
21090 * @param {?} meta
21091 * @param {?=} forceCreation
21092 * @return {?}
21093 */
21094 Meta.prototype._getOrCreateElement = function (meta, forceCreation) {
21095 if (forceCreation === void 0) { forceCreation = false; }
21096 if (!forceCreation) {
21097 var /** @type {?} */ selector = this._parseSelector(meta);
21098 var /** @type {?} */ elem = ((this.getTag(selector)));
21099 // It's allowed to have multiple elements with the same name so it's not enough to
21100 // just check that element with the same name already present on the page. We also need to
21101 // check if element has tag attributes
21102 if (elem && this._containsAttributes(meta, elem))
21103 return elem;
21104 }
21105 var /** @type {?} */ element = (this._dom.createElement('meta'));
21106 this._setMetaElementAttributes(meta, element);
21107 var /** @type {?} */ head = this._dom.getElementsByTagName(this._doc, 'head')[0];
21108 this._dom.appendChild(head, element);
21109 return element;
21110 };
21111 /**
21112 * @param {?} tag
21113 * @param {?} el
21114 * @return {?}
21115 */
21116 Meta.prototype._setMetaElementAttributes = function (tag, el) {
21117 var _this = this;
21118 Object.keys(tag).forEach(function (prop) { return _this._dom.setAttribute(el, prop, tag[prop]); });
21119 return el;
21120 };
21121 /**
21122 * @param {?} tag
21123 * @return {?}
21124 */
21125 Meta.prototype._parseSelector = function (tag) {
21126 var /** @type {?} */ attr = tag.name ? 'name' : 'property';
21127 return attr + "=\"" + tag[attr] + "\"";
21128 };
21129 /**
21130 * @param {?} tag
21131 * @param {?} elem
21132 * @return {?}
21133 */
21134 Meta.prototype._containsAttributes = function (tag, elem) {
21135 var _this = this;
21136 return Object.keys(tag).every(function (key) { return _this._dom.getAttribute(elem, key) === tag[key]; });
21137 };
21138 return Meta;
21139}());
21140Meta.decorators = [
21141 { type: Injectable },
21142];
21143/**
21144 * @nocollapse
21145 */
21146Meta.ctorParameters = function () { return [
21147 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
21148]; };
21149/**
21150 * @license
21151 * Copyright Google Inc. All Rights Reserved.
21152 *
21153 * Use of this source code is governed by an MIT-style license that can be
21154 * found in the LICENSE file at https://angular.io/license
21155 */
21156/**
21157 * An id that identifies a particular application being bootstrapped, that should
21158 * match across the client/server boundary.
21159 */
21160var TRANSITION_ID = new InjectionToken('TRANSITION_ID');
21161/**
21162 * @param {?} transitionId
21163 * @param {?} document
21164 * @param {?} injector
21165 * @return {?}
21166 */
21167function appInitializerFactory(transitionId, document, injector) {
21168 return function () {
21169 // Wait for all application initializers to be completed before removing the styles set by
21170 // the server.
21171 injector.get(ApplicationInitStatus).donePromise.then(function () {
21172 var /** @type {?} */ dom = getDOM();
21173 var /** @type {?} */ styles = Array.prototype.slice.apply(dom.querySelectorAll(document, "style[ng-transition]"));
21174 styles.filter(function (el) { return dom.getAttribute(el, 'ng-transition') === transitionId; })
21175 .forEach(function (el) { return dom.remove(el); });
21176 });
21177 };
21178}
21179var SERVER_TRANSITION_PROVIDERS = [
21180 {
21181 provide: APP_INITIALIZER,
21182 useFactory: appInitializerFactory,
21183 deps: [TRANSITION_ID, DOCUMENT$1, Injector],
21184 multi: true
21185 },
21186];
21187/**
21188 * @license
21189 * Copyright Google Inc. All Rights Reserved.
21190 *
21191 * Use of this source code is governed by an MIT-style license that can be
21192 * found in the LICENSE file at https://angular.io/license
21193 */
21194var BrowserGetTestability = (function () {
21195 function BrowserGetTestability() {
21196 }
21197 /**
21198 * @return {?}
21199 */
21200 BrowserGetTestability.init = function () { setTestabilityGetter(new BrowserGetTestability()); };
21201 /**
21202 * @param {?} registry
21203 * @return {?}
21204 */
21205 BrowserGetTestability.prototype.addToWindow = function (registry) {
21206 _global['getAngularTestability'] = function (elem, findInAncestors) {
21207 if (findInAncestors === void 0) { findInAncestors = true; }
21208 var /** @type {?} */ testability = registry.findTestabilityInTree(elem, findInAncestors);
21209 if (testability == null) {
21210 throw new Error('Could not find testability for element.');
21211 }
21212 return testability;
21213 };
21214 _global['getAllAngularTestabilities'] = function () { return registry.getAllTestabilities(); };
21215 _global['getAllAngularRootElements'] = function () { return registry.getAllRootElements(); };
21216 var /** @type {?} */ whenAllStable = function (callback /** TODO #9100 */) {
21217 var /** @type {?} */ testabilities = _global['getAllAngularTestabilities']();
21218 var /** @type {?} */ count = testabilities.length;
21219 var /** @type {?} */ didWork = false;
21220 var /** @type {?} */ decrement = function (didWork_ /** TODO #9100 */) {
21221 didWork = didWork || didWork_;
21222 count--;
21223 if (count == 0) {
21224 callback(didWork);
21225 }
21226 };
21227 testabilities.forEach(function (testability /** TODO #9100 */) {
21228 testability.whenStable(decrement);
21229 });
21230 };
21231 if (!_global['frameworkStabilizers']) {
21232 _global['frameworkStabilizers'] = [];
21233 }
21234 _global['frameworkStabilizers'].push(whenAllStable);
21235 };
21236 /**
21237 * @param {?} registry
21238 * @param {?} elem
21239 * @param {?} findInAncestors
21240 * @return {?}
21241 */
21242 BrowserGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
21243 if (elem == null) {
21244 return null;
21245 }
21246 var /** @type {?} */ t = registry.getTestability(elem);
21247 if (t != null) {
21248 return t;
21249 }
21250 else if (!findInAncestors) {
21251 return null;
21252 }
21253 if (getDOM().isShadowRoot(elem)) {
21254 return this.findTestabilityInTree(registry, getDOM().getHost(elem), true);
21255 }
21256 return this.findTestabilityInTree(registry, getDOM().parentElement(elem), true);
21257 };
21258 return BrowserGetTestability;
21259}());
21260/**
21261 * @license
21262 * Copyright Google Inc. All Rights Reserved.
21263 *
21264 * Use of this source code is governed by an MIT-style license that can be
21265 * found in the LICENSE file at https://angular.io/license
21266 */
21267/**
21268 * A service that can be used to get and set the title of a current HTML document.
21269 *
21270 * Since an Angular application can't be bootstrapped on the entire HTML document (`<html>` tag)
21271 * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
21272 * (representing the `<title>` tag). Instead, this service can be used to set and get the current
21273 * title value.
21274 *
21275 * \@experimental
21276 */
21277var Title = (function () {
21278 /**
21279 * @param {?} _doc
21280 */
21281 function Title(_doc) {
21282 this._doc = _doc;
21283 }
21284 /**
21285 * Get the title of the current HTML document.
21286 * @return {?}
21287 */
21288 Title.prototype.getTitle = function () { return getDOM().getTitle(this._doc); };
21289 /**
21290 * Set the title of the current HTML document.
21291 * @param {?} newTitle
21292 * @return {?}
21293 */
21294 Title.prototype.setTitle = function (newTitle) { getDOM().setTitle(this._doc, newTitle); };
21295 return Title;
21296}());
21297Title.decorators = [
21298 { type: Injectable },
21299];
21300/**
21301 * @nocollapse
21302 */
21303Title.ctorParameters = function () { return [
21304 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
21305]; };
21306/**
21307 * @license
21308 * Copyright Google Inc. All Rights Reserved.
21309 *
21310 * Use of this source code is governed by an MIT-style license that can be
21311 * found in the LICENSE file at https://angular.io/license
21312 */
21313/**
21314 * @param {?} input
21315 * @return {?}
21316 */
21317/**
21318 * @param {?} input
21319 * @return {?}
21320 */
21321/**
21322 * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if
21323 * `name` is `'probe'`.
21324 * @param {?} name Name under which it will be exported. Keep in mind this will be a property of the
21325 * global `ng` object.
21326 * @param {?} value The value to export.
21327 * @return {?}
21328 */
21329function exportNgVar(name, value) {
21330 if (!ng) {
21331 _global['ng'] = ng = ((_global['ng'])) || {};
21332 }
21333 ng[name] = value;
21334}
21335var ng;
21336/**
21337 * @license
21338 * Copyright Google Inc. All Rights Reserved.
21339 *
21340 * Use of this source code is governed by an MIT-style license that can be
21341 * found in the LICENSE file at https://angular.io/license
21342 */
21343var CORE_TOKENS = {
21344 'ApplicationRef': ApplicationRef,
21345 'NgZone': NgZone,
21346};
21347var INSPECT_GLOBAL_NAME = 'probe';
21348var CORE_TOKENS_GLOBAL_NAME = 'coreTokens';
21349/**
21350 * Returns a {\@link DebugElement} for the given native DOM element, or
21351 * null if the given native element does not have an Angular view associated
21352 * with it.
21353 * @param {?} element
21354 * @return {?}
21355 */
21356function inspectNativeElement(element) {
21357 return getDebugNode(element);
21358}
21359/**
21360 * Deprecated. Use the one from '\@angular/core'.
21361 * @deprecated
21362 */
21363var NgProbeToken$1 = (function () {
21364 /**
21365 * @param {?} name
21366 * @param {?} token
21367 */
21368 function NgProbeToken$1(name, token) {
21369 this.name = name;
21370 this.token = token;
21371 }
21372 return NgProbeToken$1;
21373}());
21374/**
21375 * @param {?} extraTokens
21376 * @param {?} coreTokens
21377 * @return {?}
21378 */
21379function _createNgProbe(extraTokens, coreTokens) {
21380 var /** @type {?} */ tokens = (extraTokens || []).concat(coreTokens || []);
21381 exportNgVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
21382 exportNgVar(CORE_TOKENS_GLOBAL_NAME, Object.assign({}, CORE_TOKENS, _ngProbeTokensToMap(tokens || [])));
21383 return function () { return inspectNativeElement; };
21384}
21385/**
21386 * @param {?} tokens
21387 * @return {?}
21388 */
21389function _ngProbeTokensToMap(tokens) {
21390 return tokens.reduce(function (prev, t) { return (prev[t.name] = t.token, prev); }, {});
21391}
21392/**
21393 * Providers which support debugging Angular applications (e.g. via `ng.probe`).
21394 */
21395var ELEMENT_PROBE_PROVIDERS = [
21396 {
21397 provide: APP_INITIALIZER,
21398 useFactory: _createNgProbe,
21399 deps: [
21400 [NgProbeToken$1, new Optional()],
21401 [NgProbeToken, new Optional()],
21402 ],
21403 multi: true,
21404 },
21405];
21406/**
21407 * @license
21408 * Copyright Google Inc. All Rights Reserved.
21409 *
21410 * Use of this source code is governed by an MIT-style license that can be
21411 * found in the LICENSE file at https://angular.io/license
21412 */
21413/**
21414 * \@stable
21415 */
21416var EVENT_MANAGER_PLUGINS = new InjectionToken('EventManagerPlugins');
21417/**
21418 * \@stable
21419 */
21420var EventManager = (function () {
21421 /**
21422 * @param {?} plugins
21423 * @param {?} _zone
21424 */
21425 function EventManager(plugins, _zone) {
21426 var _this = this;
21427 this._zone = _zone;
21428 this._eventNameToPlugin = new Map();
21429 plugins.forEach(function (p) { return p.manager = _this; });
21430 this._plugins = plugins.slice().reverse();
21431 }
21432 /**
21433 * @param {?} element
21434 * @param {?} eventName
21435 * @param {?} handler
21436 * @return {?}
21437 */
21438 EventManager.prototype.addEventListener = function (element, eventName, handler) {
21439 var /** @type {?} */ plugin = this._findPluginFor(eventName);
21440 return plugin.addEventListener(element, eventName, handler);
21441 };
21442 /**
21443 * @param {?} target
21444 * @param {?} eventName
21445 * @param {?} handler
21446 * @return {?}
21447 */
21448 EventManager.prototype.addGlobalEventListener = function (target, eventName, handler) {
21449 var /** @type {?} */ plugin = this._findPluginFor(eventName);
21450 return plugin.addGlobalEventListener(target, eventName, handler);
21451 };
21452 /**
21453 * @return {?}
21454 */
21455 EventManager.prototype.getZone = function () { return this._zone; };
21456 /**
21457 * \@internal
21458 * @param {?} eventName
21459 * @return {?}
21460 */
21461 EventManager.prototype._findPluginFor = function (eventName) {
21462 var /** @type {?} */ plugin = this._eventNameToPlugin.get(eventName);
21463 if (plugin) {
21464 return plugin;
21465 }
21466 var /** @type {?} */ plugins = this._plugins;
21467 for (var /** @type {?} */ i = 0; i < plugins.length; i++) {
21468 var /** @type {?} */ plugin_1 = plugins[i];
21469 if (plugin_1.supports(eventName)) {
21470 this._eventNameToPlugin.set(eventName, plugin_1);
21471 return plugin_1;
21472 }
21473 }
21474 throw new Error("No event manager plugin found for event " + eventName);
21475 };
21476 return EventManager;
21477}());
21478EventManager.decorators = [
21479 { type: Injectable },
21480];
21481/**
21482 * @nocollapse
21483 */
21484EventManager.ctorParameters = function () { return [
21485 { type: Array, decorators: [{ type: Inject, args: [EVENT_MANAGER_PLUGINS,] },] },
21486 { type: NgZone, },
21487]; };
21488/**
21489 * @abstract
21490 */
21491var EventManagerPlugin = (function () {
21492 /**
21493 * @param {?} _doc
21494 */
21495 function EventManagerPlugin(_doc) {
21496 this._doc = _doc;
21497 }
21498 /**
21499 * @abstract
21500 * @param {?} eventName
21501 * @return {?}
21502 */
21503 EventManagerPlugin.prototype.supports = function (eventName) { };
21504 /**
21505 * @abstract
21506 * @param {?} element
21507 * @param {?} eventName
21508 * @param {?} handler
21509 * @return {?}
21510 */
21511 EventManagerPlugin.prototype.addEventListener = function (element, eventName, handler) { };
21512 /**
21513 * @param {?} element
21514 * @param {?} eventName
21515 * @param {?} handler
21516 * @return {?}
21517 */
21518 EventManagerPlugin.prototype.addGlobalEventListener = function (element, eventName, handler) {
21519 var /** @type {?} */ target = getDOM().getGlobalEventTarget(this._doc, element);
21520 if (!target) {
21521 throw new Error("Unsupported event target " + target + " for event " + eventName);
21522 }
21523 return this.addEventListener(target, eventName, handler);
21524 };
21525
21526 return EventManagerPlugin;
21527}());
21528/**
21529 * @license
21530 * Copyright Google Inc. All Rights Reserved.
21531 *
21532 * Use of this source code is governed by an MIT-style license that can be
21533 * found in the LICENSE file at https://angular.io/license
21534 */
21535var SharedStylesHost = (function () {
21536 function SharedStylesHost() {
21537 /**
21538 * \@internal
21539 */
21540 this._stylesSet = new Set();
21541 }
21542 /**
21543 * @param {?} styles
21544 * @return {?}
21545 */
21546 SharedStylesHost.prototype.addStyles = function (styles) {
21547 var _this = this;
21548 var /** @type {?} */ additions = new Set();
21549 styles.forEach(function (style$$1) {
21550 if (!_this._stylesSet.has(style$$1)) {
21551 _this._stylesSet.add(style$$1);
21552 additions.add(style$$1);
21553 }
21554 });
21555 this.onStylesAdded(additions);
21556 };
21557 /**
21558 * @param {?} additions
21559 * @return {?}
21560 */
21561 SharedStylesHost.prototype.onStylesAdded = function (additions) { };
21562 /**
21563 * @return {?}
21564 */
21565 SharedStylesHost.prototype.getAllStyles = function () { return Array.from(this._stylesSet); };
21566 return SharedStylesHost;
21567}());
21568SharedStylesHost.decorators = [
21569 { type: Injectable },
21570];
21571/**
21572 * @nocollapse
21573 */
21574SharedStylesHost.ctorParameters = function () { return []; };
21575var DomSharedStylesHost = (function (_super) {
21576 __extends$1(DomSharedStylesHost, _super);
21577 /**
21578 * @param {?} _doc
21579 */
21580 function DomSharedStylesHost(_doc) {
21581 var _this = _super.call(this) || this;
21582 _this._doc = _doc;
21583 _this._hostNodes = new Set();
21584 _this._styleNodes = new Set();
21585 _this._hostNodes.add(_doc.head);
21586 return _this;
21587 }
21588 /**
21589 * @param {?} styles
21590 * @param {?} host
21591 * @return {?}
21592 */
21593 DomSharedStylesHost.prototype._addStylesToHost = function (styles, host) {
21594 var _this = this;
21595 styles.forEach(function (style$$1) {
21596 var /** @type {?} */ styleEl = _this._doc.createElement('style');
21597 styleEl.textContent = style$$1;
21598 _this._styleNodes.add(host.appendChild(styleEl));
21599 });
21600 };
21601 /**
21602 * @param {?} hostNode
21603 * @return {?}
21604 */
21605 DomSharedStylesHost.prototype.addHost = function (hostNode) {
21606 this._addStylesToHost(this._stylesSet, hostNode);
21607 this._hostNodes.add(hostNode);
21608 };
21609 /**
21610 * @param {?} hostNode
21611 * @return {?}
21612 */
21613 DomSharedStylesHost.prototype.removeHost = function (hostNode) { this._hostNodes.delete(hostNode); };
21614 /**
21615 * @param {?} additions
21616 * @return {?}
21617 */
21618 DomSharedStylesHost.prototype.onStylesAdded = function (additions) {
21619 var _this = this;
21620 this._hostNodes.forEach(function (hostNode) { return _this._addStylesToHost(additions, hostNode); });
21621 };
21622 /**
21623 * @return {?}
21624 */
21625 DomSharedStylesHost.prototype.ngOnDestroy = function () { this._styleNodes.forEach(function (styleNode) { return getDOM().remove(styleNode); }); };
21626 return DomSharedStylesHost;
21627}(SharedStylesHost));
21628DomSharedStylesHost.decorators = [
21629 { type: Injectable },
21630];
21631/**
21632 * @nocollapse
21633 */
21634DomSharedStylesHost.ctorParameters = function () { return [
21635 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
21636]; };
21637/**
21638 * @license
21639 * Copyright Google Inc. All Rights Reserved.
21640 *
21641 * Use of this source code is governed by an MIT-style license that can be
21642 * found in the LICENSE file at https://angular.io/license
21643 */
21644var NAMESPACE_URIS = {
21645 'svg': 'http://www.w3.org/2000/svg',
21646 'xhtml': 'http://www.w3.org/1999/xhtml',
21647 'xlink': 'http://www.w3.org/1999/xlink',
21648 'xml': 'http://www.w3.org/XML/1998/namespace',
21649 'xmlns': 'http://www.w3.org/2000/xmlns/',
21650};
21651var COMPONENT_REGEX = /%COMP%/g;
21652var COMPONENT_VARIABLE = '%COMP%';
21653var HOST_ATTR = "_nghost-" + COMPONENT_VARIABLE;
21654var CONTENT_ATTR = "_ngcontent-" + COMPONENT_VARIABLE;
21655/**
21656 * @param {?} componentShortId
21657 * @return {?}
21658 */
21659function shimContentAttribute(componentShortId) {
21660 return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);
21661}
21662/**
21663 * @param {?} componentShortId
21664 * @return {?}
21665 */
21666function shimHostAttribute(componentShortId) {
21667 return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);
21668}
21669/**
21670 * @param {?} compId
21671 * @param {?} styles
21672 * @param {?} target
21673 * @return {?}
21674 */
21675function flattenStyles(compId, styles, target) {
21676 for (var /** @type {?} */ i = 0; i < styles.length; i++) {
21677 var /** @type {?} */ style$$1 = styles[i];
21678 if (Array.isArray(style$$1)) {
21679 flattenStyles(compId, style$$1, target);
21680 }
21681 else {
21682 style$$1 = style$$1.replace(COMPONENT_REGEX, compId);
21683 target.push(style$$1);
21684 }
21685 }
21686 return target;
21687}
21688/**
21689 * @param {?} eventHandler
21690 * @return {?}
21691 */
21692function decoratePreventDefault(eventHandler) {
21693 return function (event) {
21694 var /** @type {?} */ allowDefaultBehavior = eventHandler(event);
21695 if (allowDefaultBehavior === false) {
21696 // TODO(tbosch): move preventDefault into event plugins...
21697 event.preventDefault();
21698 event.returnValue = false;
21699 }
21700 };
21701}
21702var DomRendererFactory2 = (function () {
21703 /**
21704 * @param {?} eventManager
21705 * @param {?} sharedStylesHost
21706 */
21707 function DomRendererFactory2(eventManager, sharedStylesHost) {
21708 this.eventManager = eventManager;
21709 this.sharedStylesHost = sharedStylesHost;
21710 this.rendererByCompId = new Map();
21711 this.defaultRenderer = new DefaultDomRenderer2(eventManager);
21712 }
21713
21714 /**
21715 * @param {?} element
21716 * @param {?} type
21717 * @return {?}
21718 */
21719 DomRendererFactory2.prototype.createRenderer = function (element, type) {
21720 if (!element || !type) {
21721 return this.defaultRenderer;
21722 }
21723 switch (type.encapsulation) {
21724 case ViewEncapsulation.Emulated: {
21725 var /** @type {?} */ renderer = this.rendererByCompId.get(type.id);
21726 if (!renderer) {
21727 renderer =
21728 new EmulatedEncapsulationDomRenderer2(this.eventManager, this.sharedStylesHost, type);
21729 this.rendererByCompId.set(type.id, renderer);
21730 }
21731 ((renderer)).applyToHost(element);
21732 return renderer;
21733 }
21734 case ViewEncapsulation.Native:
21735 return new ShadowDomRenderer(this.eventManager, this.sharedStylesHost, element, type);
21736 default: {
21737 if (!this.rendererByCompId.has(type.id)) {
21738 var /** @type {?} */ styles = flattenStyles(type.id, type.styles, []);
21739 this.sharedStylesHost.addStyles(styles);
21740 this.rendererByCompId.set(type.id, this.defaultRenderer);
21741 }
21742 return this.defaultRenderer;
21743 }
21744 }
21745 };
21746 /**
21747 * @return {?}
21748 */
21749 DomRendererFactory2.prototype.begin = function () { };
21750 /**
21751 * @return {?}
21752 */
21753 DomRendererFactory2.prototype.end = function () { };
21754 return DomRendererFactory2;
21755}());
21756DomRendererFactory2.decorators = [
21757 { type: Injectable },
21758];
21759/**
21760 * @nocollapse
21761 */
21762DomRendererFactory2.ctorParameters = function () { return [
21763 { type: EventManager, },
21764 { type: DomSharedStylesHost, },
21765]; };
21766var DefaultDomRenderer2 = (function () {
21767 /**
21768 * @param {?} eventManager
21769 */
21770 function DefaultDomRenderer2(eventManager) {
21771 this.eventManager = eventManager;
21772 this.data = Object.create(null);
21773 }
21774 /**
21775 * @return {?}
21776 */
21777 DefaultDomRenderer2.prototype.destroy = function () { };
21778 /**
21779 * @param {?} name
21780 * @param {?=} namespace
21781 * @return {?}
21782 */
21783 DefaultDomRenderer2.prototype.createElement = function (name, namespace) {
21784 if (namespace) {
21785 return document.createElementNS(NAMESPACE_URIS[namespace], name);
21786 }
21787 return document.createElement(name);
21788 };
21789 /**
21790 * @param {?} value
21791 * @return {?}
21792 */
21793 DefaultDomRenderer2.prototype.createComment = function (value) { return document.createComment(value); };
21794 /**
21795 * @param {?} value
21796 * @return {?}
21797 */
21798 DefaultDomRenderer2.prototype.createText = function (value) { return document.createTextNode(value); };
21799 /**
21800 * @param {?} parent
21801 * @param {?} newChild
21802 * @return {?}
21803 */
21804 DefaultDomRenderer2.prototype.appendChild = function (parent, newChild) { parent.appendChild(newChild); };
21805 /**
21806 * @param {?} parent
21807 * @param {?} newChild
21808 * @param {?} refChild
21809 * @return {?}
21810 */
21811 DefaultDomRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
21812 if (parent) {
21813 parent.insertBefore(newChild, refChild);
21814 }
21815 };
21816 /**
21817 * @param {?} parent
21818 * @param {?} oldChild
21819 * @return {?}
21820 */
21821 DefaultDomRenderer2.prototype.removeChild = function (parent, oldChild) {
21822 if (parent) {
21823 parent.removeChild(oldChild);
21824 }
21825 };
21826 /**
21827 * @param {?} selectorOrNode
21828 * @return {?}
21829 */
21830 DefaultDomRenderer2.prototype.selectRootElement = function (selectorOrNode) {
21831 var /** @type {?} */ el = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) :
21832 selectorOrNode;
21833 if (!el) {
21834 throw new Error("The selector \"" + selectorOrNode + "\" did not match any elements");
21835 }
21836 el.textContent = '';
21837 return el;
21838 };
21839 /**
21840 * @param {?} node
21841 * @return {?}
21842 */
21843 DefaultDomRenderer2.prototype.parentNode = function (node) { return node.parentNode; };
21844 /**
21845 * @param {?} node
21846 * @return {?}
21847 */
21848 DefaultDomRenderer2.prototype.nextSibling = function (node) { return node.nextSibling; };
21849 /**
21850 * @param {?} el
21851 * @param {?} name
21852 * @param {?} value
21853 * @param {?=} namespace
21854 * @return {?}
21855 */
21856 DefaultDomRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
21857 if (namespace) {
21858 name = namespace + ":" + name;
21859 var /** @type {?} */ namespaceUri = NAMESPACE_URIS[namespace];
21860 if (namespaceUri) {
21861 el.setAttributeNS(namespaceUri, name, value);
21862 }
21863 else {
21864 el.setAttribute(name, value);
21865 }
21866 }
21867 else {
21868 el.setAttribute(name, value);
21869 }
21870 };
21871 /**
21872 * @param {?} el
21873 * @param {?} name
21874 * @param {?=} namespace
21875 * @return {?}
21876 */
21877 DefaultDomRenderer2.prototype.removeAttribute = function (el, name, namespace) {
21878 if (namespace) {
21879 var /** @type {?} */ namespaceUri = NAMESPACE_URIS[namespace];
21880 if (namespaceUri) {
21881 el.removeAttributeNS(namespaceUri, name);
21882 }
21883 else {
21884 el.removeAttribute(namespace + ":" + name);
21885 }
21886 }
21887 else {
21888 el.removeAttribute(name);
21889 }
21890 };
21891 /**
21892 * @param {?} el
21893 * @param {?} name
21894 * @return {?}
21895 */
21896 DefaultDomRenderer2.prototype.addClass = function (el, name) { el.classList.add(name); };
21897 /**
21898 * @param {?} el
21899 * @param {?} name
21900 * @return {?}
21901 */
21902 DefaultDomRenderer2.prototype.removeClass = function (el, name) { el.classList.remove(name); };
21903 /**
21904 * @param {?} el
21905 * @param {?} style
21906 * @param {?} value
21907 * @param {?} flags
21908 * @return {?}
21909 */
21910 DefaultDomRenderer2.prototype.setStyle = function (el, style$$1, value, flags) {
21911 if (flags & RendererStyleFlags2.DashCase) {
21912 el.style.setProperty(style$$1, value, !!(flags & RendererStyleFlags2.Important) ? 'important' : '');
21913 }
21914 else {
21915 el.style[style$$1] = value;
21916 }
21917 };
21918 /**
21919 * @param {?} el
21920 * @param {?} style
21921 * @param {?} flags
21922 * @return {?}
21923 */
21924 DefaultDomRenderer2.prototype.removeStyle = function (el, style$$1, flags) {
21925 if (flags & RendererStyleFlags2.DashCase) {
21926 el.style.removeProperty(style$$1);
21927 }
21928 else {
21929 // IE requires '' instead of null
21930 // see https://github.com/angular/angular/issues/7916
21931 el.style[style$$1] = '';
21932 }
21933 };
21934 /**
21935 * @param {?} el
21936 * @param {?} name
21937 * @param {?} value
21938 * @return {?}
21939 */
21940 DefaultDomRenderer2.prototype.setProperty = function (el, name, value) {
21941 checkNoSyntheticProp(name, 'property');
21942 el[name] = value;
21943 };
21944 /**
21945 * @param {?} node
21946 * @param {?} value
21947 * @return {?}
21948 */
21949 DefaultDomRenderer2.prototype.setValue = function (node, value) { node.nodeValue = value; };
21950 /**
21951 * @param {?} target
21952 * @param {?} event
21953 * @param {?} callback
21954 * @return {?}
21955 */
21956 DefaultDomRenderer2.prototype.listen = function (target, event, callback) {
21957 checkNoSyntheticProp(event, 'listener');
21958 if (typeof target === 'string') {
21959 return (this.eventManager.addGlobalEventListener(target, event, decoratePreventDefault(callback)));
21960 }
21961 return ((this.eventManager.addEventListener(target, event, decoratePreventDefault(callback))));
21962 };
21963 return DefaultDomRenderer2;
21964}());
21965var AT_CHARCODE = '@'.charCodeAt(0);
21966/**
21967 * @param {?} name
21968 * @param {?} nameKind
21969 * @return {?}
21970 */
21971function checkNoSyntheticProp(name, nameKind) {
21972 if (name.charCodeAt(0) === AT_CHARCODE) {
21973 throw new Error("Found the synthetic " + nameKind + " " + name + ". Please include either \"BrowserAnimationsModule\" or \"NoopAnimationsModule\" in your application.");
21974 }
21975}
21976var EmulatedEncapsulationDomRenderer2 = (function (_super) {
21977 __extends$1(EmulatedEncapsulationDomRenderer2, _super);
21978 /**
21979 * @param {?} eventManager
21980 * @param {?} sharedStylesHost
21981 * @param {?} component
21982 */
21983 function EmulatedEncapsulationDomRenderer2(eventManager, sharedStylesHost, component) {
21984 var _this = _super.call(this, eventManager) || this;
21985 _this.component = component;
21986 var styles = flattenStyles(component.id, component.styles, []);
21987 sharedStylesHost.addStyles(styles);
21988 _this.contentAttr = shimContentAttribute(component.id);
21989 _this.hostAttr = shimHostAttribute(component.id);
21990 return _this;
21991 }
21992 /**
21993 * @param {?} element
21994 * @return {?}
21995 */
21996 EmulatedEncapsulationDomRenderer2.prototype.applyToHost = function (element) { _super.prototype.setAttribute.call(this, element, this.hostAttr, ''); };
21997 /**
21998 * @param {?} parent
21999 * @param {?} name
22000 * @return {?}
22001 */
22002 EmulatedEncapsulationDomRenderer2.prototype.createElement = function (parent, name) {
22003 var /** @type {?} */ el = _super.prototype.createElement.call(this, parent, name);
22004 _super.prototype.setAttribute.call(this, el, this.contentAttr, '');
22005 return el;
22006 };
22007 return EmulatedEncapsulationDomRenderer2;
22008}(DefaultDomRenderer2));
22009var ShadowDomRenderer = (function (_super) {
22010 __extends$1(ShadowDomRenderer, _super);
22011 /**
22012 * @param {?} eventManager
22013 * @param {?} sharedStylesHost
22014 * @param {?} hostEl
22015 * @param {?} component
22016 */
22017 function ShadowDomRenderer(eventManager, sharedStylesHost, hostEl, component) {
22018 var _this = _super.call(this, eventManager) || this;
22019 _this.sharedStylesHost = sharedStylesHost;
22020 _this.hostEl = hostEl;
22021 _this.component = component;
22022 _this.shadowRoot = hostEl.createShadowRoot();
22023 _this.sharedStylesHost.addHost(_this.shadowRoot);
22024 var styles = flattenStyles(component.id, component.styles, []);
22025 for (var i = 0; i < styles.length; i++) {
22026 var styleEl = document.createElement('style');
22027 styleEl.textContent = styles[i];
22028 _this.shadowRoot.appendChild(styleEl);
22029 }
22030 return _this;
22031 }
22032 /**
22033 * @param {?} node
22034 * @return {?}
22035 */
22036 ShadowDomRenderer.prototype.nodeOrShadowRoot = function (node) { return node === this.hostEl ? this.shadowRoot : node; };
22037 /**
22038 * @return {?}
22039 */
22040 ShadowDomRenderer.prototype.destroy = function () { this.sharedStylesHost.removeHost(this.shadowRoot); };
22041 /**
22042 * @param {?} parent
22043 * @param {?} newChild
22044 * @return {?}
22045 */
22046 ShadowDomRenderer.prototype.appendChild = function (parent, newChild) {
22047 return _super.prototype.appendChild.call(this, this.nodeOrShadowRoot(parent), newChild);
22048 };
22049 /**
22050 * @param {?} parent
22051 * @param {?} newChild
22052 * @param {?} refChild
22053 * @return {?}
22054 */
22055 ShadowDomRenderer.prototype.insertBefore = function (parent, newChild, refChild) {
22056 return _super.prototype.insertBefore.call(this, this.nodeOrShadowRoot(parent), newChild, refChild);
22057 };
22058 /**
22059 * @param {?} parent
22060 * @param {?} oldChild
22061 * @return {?}
22062 */
22063 ShadowDomRenderer.prototype.removeChild = function (parent, oldChild) {
22064 return _super.prototype.removeChild.call(this, this.nodeOrShadowRoot(parent), oldChild);
22065 };
22066 /**
22067 * @param {?} node
22068 * @return {?}
22069 */
22070 ShadowDomRenderer.prototype.parentNode = function (node) {
22071 return this.nodeOrShadowRoot(_super.prototype.parentNode.call(this, this.nodeOrShadowRoot(node)));
22072 };
22073 return ShadowDomRenderer;
22074}(DefaultDomRenderer2));
22075/**
22076 * @license
22077 * Copyright Google Inc. All Rights Reserved.
22078 *
22079 * Use of this source code is governed by an MIT-style license that can be
22080 * found in the LICENSE file at https://angular.io/license
22081 */
22082var DomEventsPlugin = (function (_super) {
22083 __extends$1(DomEventsPlugin, _super);
22084 /**
22085 * @param {?} doc
22086 */
22087 function DomEventsPlugin(doc) {
22088 return _super.call(this, doc) || this;
22089 }
22090 /**
22091 * @param {?} eventName
22092 * @return {?}
22093 */
22094 DomEventsPlugin.prototype.supports = function (eventName) { return true; };
22095 /**
22096 * @param {?} element
22097 * @param {?} eventName
22098 * @param {?} handler
22099 * @return {?}
22100 */
22101 DomEventsPlugin.prototype.addEventListener = function (element, eventName, handler) {
22102 element.addEventListener(eventName, /** @type {?} */ (handler), false);
22103 return function () { return element.removeEventListener(eventName, /** @type {?} */ (handler), false); };
22104 };
22105 return DomEventsPlugin;
22106}(EventManagerPlugin));
22107DomEventsPlugin.decorators = [
22108 { type: Injectable },
22109];
22110/**
22111 * @nocollapse
22112 */
22113DomEventsPlugin.ctorParameters = function () { return [
22114 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
22115]; };
22116/**
22117 * @license
22118 * Copyright Google Inc. All Rights Reserved.
22119 *
22120 * Use of this source code is governed by an MIT-style license that can be
22121 * found in the LICENSE file at https://angular.io/license
22122 */
22123var EVENT_NAMES = {
22124 // pan
22125 'pan': true,
22126 'panstart': true,
22127 'panmove': true,
22128 'panend': true,
22129 'pancancel': true,
22130 'panleft': true,
22131 'panright': true,
22132 'panup': true,
22133 'pandown': true,
22134 // pinch
22135 'pinch': true,
22136 'pinchstart': true,
22137 'pinchmove': true,
22138 'pinchend': true,
22139 'pinchcancel': true,
22140 'pinchin': true,
22141 'pinchout': true,
22142 // press
22143 'press': true,
22144 'pressup': true,
22145 // rotate
22146 'rotate': true,
22147 'rotatestart': true,
22148 'rotatemove': true,
22149 'rotateend': true,
22150 'rotatecancel': true,
22151 // swipe
22152 'swipe': true,
22153 'swipeleft': true,
22154 'swiperight': true,
22155 'swipeup': true,
22156 'swipedown': true,
22157 // tap
22158 'tap': true,
22159};
22160/**
22161 * A DI token that you can use to provide{\@link HammerGestureConfig} to Angular. Use it to configure
22162 * Hammer gestures.
22163 *
22164 * \@experimental
22165 */
22166var HAMMER_GESTURE_CONFIG = new InjectionToken('HammerGestureConfig');
22167/**
22168 * \@experimental
22169 */
22170var HammerGestureConfig = (function () {
22171 function HammerGestureConfig() {
22172 this.events = [];
22173 this.overrides = {};
22174 }
22175 /**
22176 * @param {?} element
22177 * @return {?}
22178 */
22179 HammerGestureConfig.prototype.buildHammer = function (element) {
22180 var /** @type {?} */ mc = new Hammer(element);
22181 mc.get('pinch').set({ enable: true });
22182 mc.get('rotate').set({ enable: true });
22183 for (var /** @type {?} */ eventName in this.overrides) {
22184 mc.get(eventName).set(this.overrides[eventName]);
22185 }
22186 return mc;
22187 };
22188 return HammerGestureConfig;
22189}());
22190HammerGestureConfig.decorators = [
22191 { type: Injectable },
22192];
22193/**
22194 * @nocollapse
22195 */
22196HammerGestureConfig.ctorParameters = function () { return []; };
22197var HammerGesturesPlugin = (function (_super) {
22198 __extends$1(HammerGesturesPlugin, _super);
22199 /**
22200 * @param {?} doc
22201 * @param {?} _config
22202 */
22203 function HammerGesturesPlugin(doc, _config) {
22204 var _this = _super.call(this, doc) || this;
22205 _this._config = _config;
22206 return _this;
22207 }
22208 /**
22209 * @param {?} eventName
22210 * @return {?}
22211 */
22212 HammerGesturesPlugin.prototype.supports = function (eventName) {
22213 if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {
22214 return false;
22215 }
22216 if (!((window)).Hammer) {
22217 throw new Error("Hammer.js is not loaded, can not bind " + eventName + " event");
22218 }
22219 return true;
22220 };
22221 /**
22222 * @param {?} element
22223 * @param {?} eventName
22224 * @param {?} handler
22225 * @return {?}
22226 */
22227 HammerGesturesPlugin.prototype.addEventListener = function (element, eventName, handler) {
22228 var _this = this;
22229 var /** @type {?} */ zone = this.manager.getZone();
22230 eventName = eventName.toLowerCase();
22231 return zone.runOutsideAngular(function () {
22232 // Creating the manager bind events, must be done outside of angular
22233 var /** @type {?} */ mc = _this._config.buildHammer(element);
22234 var /** @type {?} */ callback = function (eventObj) {
22235 zone.runGuarded(function () { handler(eventObj); });
22236 };
22237 mc.on(eventName, callback);
22238 return function () { return mc.off(eventName, callback); };
22239 });
22240 };
22241 /**
22242 * @param {?} eventName
22243 * @return {?}
22244 */
22245 HammerGesturesPlugin.prototype.isCustomEvent = function (eventName) { return this._config.events.indexOf(eventName) > -1; };
22246 return HammerGesturesPlugin;
22247}(EventManagerPlugin));
22248HammerGesturesPlugin.decorators = [
22249 { type: Injectable },
22250];
22251/**
22252 * @nocollapse
22253 */
22254HammerGesturesPlugin.ctorParameters = function () { return [
22255 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
22256 { type: HammerGestureConfig, decorators: [{ type: Inject, args: [HAMMER_GESTURE_CONFIG,] },] },
22257]; };
22258/**
22259 * @license
22260 * Copyright Google Inc. All Rights Reserved.
22261 *
22262 * Use of this source code is governed by an MIT-style license that can be
22263 * found in the LICENSE file at https://angular.io/license
22264 */
22265var MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift'];
22266var MODIFIER_KEY_GETTERS = {
22267 'alt': function (event) { return event.altKey; },
22268 'control': function (event) { return event.ctrlKey; },
22269 'meta': function (event) { return event.metaKey; },
22270 'shift': function (event) { return event.shiftKey; }
22271};
22272/**
22273 * \@experimental
22274 */
22275var KeyEventsPlugin = (function (_super) {
22276 __extends$1(KeyEventsPlugin, _super);
22277 /**
22278 * @param {?} doc
22279 */
22280 function KeyEventsPlugin(doc) {
22281 return _super.call(this, doc) || this;
22282 }
22283 /**
22284 * @param {?} eventName
22285 * @return {?}
22286 */
22287 KeyEventsPlugin.prototype.supports = function (eventName) { return KeyEventsPlugin.parseEventName(eventName) != null; };
22288 /**
22289 * @param {?} element
22290 * @param {?} eventName
22291 * @param {?} handler
22292 * @return {?}
22293 */
22294 KeyEventsPlugin.prototype.addEventListener = function (element, eventName, handler) {
22295 var /** @type {?} */ parsedEvent = ((KeyEventsPlugin.parseEventName(eventName)));
22296 var /** @type {?} */ outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
22297 return this.manager.getZone().runOutsideAngular(function () {
22298 return getDOM().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);
22299 });
22300 };
22301 /**
22302 * @param {?} eventName
22303 * @return {?}
22304 */
22305 KeyEventsPlugin.parseEventName = function (eventName) {
22306 var /** @type {?} */ parts = eventName.toLowerCase().split('.');
22307 var /** @type {?} */ domEventName = parts.shift();
22308 if ((parts.length === 0) || !(domEventName === 'keydown' || domEventName === 'keyup')) {
22309 return null;
22310 }
22311 var /** @type {?} */ key = KeyEventsPlugin._normalizeKey(/** @type {?} */ ((parts.pop())));
22312 var /** @type {?} */ fullKey = '';
22313 MODIFIER_KEYS.forEach(function (modifierName) {
22314 var /** @type {?} */ index = parts.indexOf(modifierName);
22315 if (index > -1) {
22316 parts.splice(index, 1);
22317 fullKey += modifierName + '.';
22318 }
22319 });
22320 fullKey += key;
22321 if (parts.length != 0 || key.length === 0) {
22322 // returning null instead of throwing to let another plugin process the event
22323 return null;
22324 }
22325 var /** @type {?} */ result = {};
22326 result['domEventName'] = domEventName;
22327 result['fullKey'] = fullKey;
22328 return result;
22329 };
22330 /**
22331 * @param {?} event
22332 * @return {?}
22333 */
22334 KeyEventsPlugin.getEventFullKey = function (event) {
22335 var /** @type {?} */ fullKey = '';
22336 var /** @type {?} */ key = getDOM().getEventKey(event);
22337 key = key.toLowerCase();
22338 if (key === ' ') {
22339 key = 'space'; // for readability
22340 }
22341 else if (key === '.') {
22342 key = 'dot'; // because '.' is used as a separator in event names
22343 }
22344 MODIFIER_KEYS.forEach(function (modifierName) {
22345 if (modifierName != key) {
22346 var /** @type {?} */ modifierGetter = MODIFIER_KEY_GETTERS[modifierName];
22347 if (modifierGetter(event)) {
22348 fullKey += modifierName + '.';
22349 }
22350 }
22351 });
22352 fullKey += key;
22353 return fullKey;
22354 };
22355 /**
22356 * @param {?} fullKey
22357 * @param {?} handler
22358 * @param {?} zone
22359 * @return {?}
22360 */
22361 KeyEventsPlugin.eventCallback = function (fullKey, handler, zone) {
22362 return function (event /** TODO #9100 */) {
22363 if (KeyEventsPlugin.getEventFullKey(event) === fullKey) {
22364 zone.runGuarded(function () { return handler(event); });
22365 }
22366 };
22367 };
22368 /**
22369 * \@internal
22370 * @param {?} keyName
22371 * @return {?}
22372 */
22373 KeyEventsPlugin._normalizeKey = function (keyName) {
22374 // TODO: switch to a Map if the mapping grows too much
22375 switch (keyName) {
22376 case 'esc':
22377 return 'escape';
22378 default:
22379 return keyName;
22380 }
22381 };
22382 return KeyEventsPlugin;
22383}(EventManagerPlugin));
22384KeyEventsPlugin.decorators = [
22385 { type: Injectable },
22386];
22387/**
22388 * @nocollapse
22389 */
22390KeyEventsPlugin.ctorParameters = function () { return [
22391 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
22392]; };
22393/**
22394 * @license
22395 * Copyright Google Inc. All Rights Reserved.
22396 *
22397 * Use of this source code is governed by an MIT-style license that can be
22398 * found in the LICENSE file at https://angular.io/license
22399 */
22400/**
22401 * A pattern that recognizes a commonly useful subset of URLs that are safe.
22402 *
22403 * This regular expression matches a subset of URLs that will not cause script
22404 * execution if used in URL context within a HTML document. Specifically, this
22405 * regular expression matches if (comment from here on and regex copied from
22406 * Soy's EscapingConventions):
22407 * (1) Either a protocol in a whitelist (http, https, mailto or ftp).
22408 * (2) or no protocol. A protocol must be followed by a colon. The below
22409 * allows that by allowing colons only after one of the characters [/?#].
22410 * A colon after a hash (#) must be in the fragment.
22411 * Otherwise, a colon after a (?) must be in a query.
22412 * Otherwise, a colon after a single solidus (/) must be in a path.
22413 * Otherwise, a colon after a double solidus (//) must be in the authority
22414 * (before port).
22415 *
22416 * The pattern disallows &, used in HTML entity declarations before
22417 * one of the characters in [/?#]. This disallows HTML entities used in the
22418 * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
22419 * It also disallows HTML entities in the first path part of a relative path,
22420 * e.g. "foo&lt;bar/baz". Our existing escaping functions should not produce
22421 * that. More importantly, it disallows masking of a colon,
22422 * e.g. "javascript&#58;...".
22423 *
22424 * This regular expression was taken from the Closure sanitization library.
22425 */
22426var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
22427/**
22428 * A pattern that matches safe data URLs. Only matches image, video and audio types.
22429 */
22430var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;
22431/**
22432 * @param {?} url
22433 * @return {?}
22434 */
22435function sanitizeUrl(url) {
22436 url = String(url);
22437 if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN))
22438 return url;
22439 if (isDevMode()) {
22440 getDOM().log("WARNING: sanitizing unsafe URL value " + url + " (see http://g.co/ng/security#xss)");
22441 }
22442 return 'unsafe:' + url;
22443}
22444/**
22445 * @param {?} srcset
22446 * @return {?}
22447 */
22448function sanitizeSrcset(srcset) {
22449 srcset = String(srcset);
22450 return srcset.split(',').map(function (srcset) { return sanitizeUrl(srcset.trim()); }).join(', ');
22451}
22452/**
22453 * @license
22454 * Copyright Google Inc. All Rights Reserved.
22455 *
22456 * Use of this source code is governed by an MIT-style license that can be
22457 * found in the LICENSE file at https://angular.io/license
22458 */
22459/**
22460 * A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below.
22461 */
22462var inertElement = null;
22463/**
22464 * Lazily initialized to make sure the DOM adapter gets set before use.
22465 */
22466var DOM = null;
22467/**
22468 * Returns an HTML element that is guaranteed to not execute code when creating elements in it.
22469 * @return {?}
22470 */
22471function getInertElement() {
22472 if (inertElement)
22473 return inertElement;
22474 DOM = getDOM();
22475 // Prefer using <template> element if supported.
22476 var /** @type {?} */ templateEl = DOM.createElement('template');
22477 if ('content' in templateEl)
22478 return templateEl;
22479 var /** @type {?} */ doc = DOM.createHtmlDocument();
22480 inertElement = DOM.querySelector(doc, 'body');
22481 if (inertElement == null) {
22482 // usually there should be only one body element in the document, but IE doesn't have any, so we
22483 // need to create one.
22484 var /** @type {?} */ html = DOM.createElement('html', doc);
22485 inertElement = DOM.createElement('body', doc);
22486 DOM.appendChild(html, inertElement);
22487 DOM.appendChild(doc, html);
22488 }
22489 return inertElement;
22490}
22491/**
22492 * @param {?} tags
22493 * @return {?}
22494 */
22495function tagSet(tags) {
22496 var /** @type {?} */ res = {};
22497 for (var _i = 0, _a = tags.split(','); _i < _a.length; _i++) {
22498 var t = _a[_i];
22499 res[t] = true;
22500 }
22501 return res;
22502}
22503/**
22504 * @param {...?} sets
22505 * @return {?}
22506 */
22507function merge$3() {
22508 var sets = [];
22509 for (var _i = 0; _i < arguments.length; _i++) {
22510 sets[_i] = arguments[_i];
22511 }
22512 var /** @type {?} */ res = {};
22513 for (var _a = 0, sets_1 = sets; _a < sets_1.length; _a++) {
22514 var s = sets_1[_a];
22515 for (var /** @type {?} */ v in s) {
22516 if (s.hasOwnProperty(v))
22517 res[v] = true;
22518 }
22519 }
22520 return res;
22521}
22522// Good source of info about elements and attributes
22523// http://dev.w3.org/html5/spec/Overview.html#semantics
22524// http://simon.html5.org/html-elements
22525// Safe Void Elements - HTML5
22526// http://dev.w3.org/html5/spec/Overview.html#void-elements
22527var VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
22528// Elements that you can, intentionally, leave open (and which close themselves)
22529// http://dev.w3.org/html5/spec/Overview.html#optional-tags
22530var OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
22531var OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
22532var OPTIONAL_END_TAG_ELEMENTS = merge$3(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
22533// Safe Block Elements - HTML5
22534var BLOCK_ELEMENTS = merge$3(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' +
22535 'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
22536 'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
22537// Inline Elements - HTML5
22538var INLINE_ELEMENTS = merge$3(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' +
22539 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' +
22540 'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
22541var VALID_ELEMENTS = merge$3(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
22542// Attributes that have href and hence need to be sanitized
22543var URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
22544// Attributes that have special href set hence need to be sanitized
22545var SRCSET_ATTRS = tagSet('srcset');
22546var HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
22547 'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
22548 'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
22549 'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
22550 'valign,value,vspace,width');
22551// NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
22552// issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
22553// innerHTML is required, SVG attributes should be added here.
22554// NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
22555// can be sanitized, but they increase security surface area without a legitimate use case, so they
22556// are left out here.
22557var VALID_ATTRS = merge$3(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS);
22558/**
22559 * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
22560 * attributes.
22561 */
22562var SanitizingHtmlSerializer = (function () {
22563 function SanitizingHtmlSerializer() {
22564 this.sanitizedSomething = false;
22565 this.buf = [];
22566 }
22567 /**
22568 * @param {?} el
22569 * @return {?}
22570 */
22571 SanitizingHtmlSerializer.prototype.sanitizeChildren = function (el) {
22572 // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
22573 // However this code never accesses properties off of `document` before deleting its contents
22574 // again, so it shouldn't be vulnerable to DOM clobbering.
22575 var /** @type {?} */ current = ((el.firstChild));
22576 while (current) {
22577 if (DOM.isElementNode(current)) {
22578 this.startElement(/** @type {?} */ (current));
22579 }
22580 else if (DOM.isTextNode(current)) {
22581 this.chars(/** @type {?} */ ((DOM.nodeValue(current))));
22582 }
22583 else {
22584 // Strip non-element, non-text nodes.
22585 this.sanitizedSomething = true;
22586 }
22587 if (DOM.firstChild(current)) {
22588 current = ((DOM.firstChild(current)));
22589 continue;
22590 }
22591 while (current) {
22592 // Leaving the element. Walk up and to the right, closing tags as we go.
22593 if (DOM.isElementNode(current)) {
22594 this.endElement(/** @type {?} */ (current));
22595 }
22596 var /** @type {?} */ next = checkClobberedElement(current, /** @type {?} */ ((DOM.nextSibling(current))));
22597 if (next) {
22598 current = next;
22599 break;
22600 }
22601 current = checkClobberedElement(current, /** @type {?} */ ((DOM.parentElement(current))));
22602 }
22603 }
22604 return this.buf.join('');
22605 };
22606 /**
22607 * @param {?} element
22608 * @return {?}
22609 */
22610 SanitizingHtmlSerializer.prototype.startElement = function (element) {
22611 var _this = this;
22612 var /** @type {?} */ tagName = DOM.nodeName(element).toLowerCase();
22613 if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
22614 this.sanitizedSomething = true;
22615 return;
22616 }
22617 this.buf.push('<');
22618 this.buf.push(tagName);
22619 DOM.attributeMap(element).forEach(function (value, attrName) {
22620 var /** @type {?} */ lower = attrName.toLowerCase();
22621 if (!VALID_ATTRS.hasOwnProperty(lower)) {
22622 _this.sanitizedSomething = true;
22623 return;
22624 }
22625 // TODO(martinprobst): Special case image URIs for data:image/...
22626 if (URI_ATTRS[lower])
22627 value = sanitizeUrl(value);
22628 if (SRCSET_ATTRS[lower])
22629 value = sanitizeSrcset(value);
22630 _this.buf.push(' ');
22631 _this.buf.push(attrName);
22632 _this.buf.push('="');
22633 _this.buf.push(encodeEntities(value));
22634 _this.buf.push('"');
22635 });
22636 this.buf.push('>');
22637 };
22638 /**
22639 * @param {?} current
22640 * @return {?}
22641 */
22642 SanitizingHtmlSerializer.prototype.endElement = function (current) {
22643 var /** @type {?} */ tagName = DOM.nodeName(current).toLowerCase();
22644 if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
22645 this.buf.push('</');
22646 this.buf.push(tagName);
22647 this.buf.push('>');
22648 }
22649 };
22650 /**
22651 * @param {?} chars
22652 * @return {?}
22653 */
22654 SanitizingHtmlSerializer.prototype.chars = function (chars) { this.buf.push(encodeEntities(chars)); };
22655 return SanitizingHtmlSerializer;
22656}());
22657/**
22658 * @param {?} node
22659 * @param {?} nextNode
22660 * @return {?}
22661 */
22662function checkClobberedElement(node, nextNode) {
22663 if (nextNode && DOM.contains(node, nextNode)) {
22664 throw new Error("Failed to sanitize html because the element is clobbered: " + DOM.getOuterHTML(node));
22665 }
22666 return nextNode;
22667}
22668// Regular Expressions for parsing tags and attributes
22669var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
22670// ! to ~ is the ASCII range.
22671var NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
22672/**
22673 * Escapes all potentially dangerous characters, so that the
22674 * resulting string can be safely inserted into attribute or
22675 * element text.
22676 * @param {?} value
22677 * @return {?}
22678 */
22679function encodeEntities(value) {
22680 return value.replace(/&/g, '&amp;')
22681 .replace(SURROGATE_PAIR_REGEXP, function (match) {
22682 var /** @type {?} */ hi = match.charCodeAt(0);
22683 var /** @type {?} */ low = match.charCodeAt(1);
22684 return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
22685 })
22686 .replace(NON_ALPHANUMERIC_REGEXP, function (match) { return '&#' + match.charCodeAt(0) + ';'; })
22687 .replace(/</g, '&lt;')
22688 .replace(/>/g, '&gt;');
22689}
22690/**
22691 * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
22692 * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo').
22693 *
22694 * This is undesirable since we don't want to allow any of these custom attributes. This method
22695 * strips them all.
22696 * @param {?} el
22697 * @return {?}
22698 */
22699function stripCustomNsAttrs(el) {
22700 DOM.attributeMap(el).forEach(function (_, attrName) {
22701 if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
22702 DOM.removeAttribute(el, attrName);
22703 }
22704 });
22705 for (var _i = 0, _a = DOM.childNodesAsList(el); _i < _a.length; _i++) {
22706 var n = _a[_i];
22707 if (DOM.isElementNode(n))
22708 stripCustomNsAttrs(/** @type {?} */ (n));
22709 }
22710}
22711/**
22712 * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
22713 * the DOM in a browser environment.
22714 * @param {?} defaultDoc
22715 * @param {?} unsafeHtmlInput
22716 * @return {?}
22717 */
22718function sanitizeHtml(defaultDoc, unsafeHtmlInput) {
22719 try {
22720 var /** @type {?} */ containerEl = getInertElement();
22721 // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
22722 var /** @type {?} */ unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
22723 // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
22724 // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
22725 var /** @type {?} */ mXSSAttempts = 5;
22726 var /** @type {?} */ parsedHtml = unsafeHtml;
22727 do {
22728 if (mXSSAttempts === 0) {
22729 throw new Error('Failed to sanitize html because the input is unstable');
22730 }
22731 mXSSAttempts--;
22732 unsafeHtml = parsedHtml;
22733 DOM.setInnerHTML(containerEl, unsafeHtml);
22734 if (defaultDoc.documentMode) {
22735 // strip custom-namespaced attributes on IE<=11
22736 stripCustomNsAttrs(containerEl);
22737 }
22738 parsedHtml = DOM.getInnerHTML(containerEl);
22739 } while (unsafeHtml !== parsedHtml);
22740 var /** @type {?} */ sanitizer = new SanitizingHtmlSerializer();
22741 var /** @type {?} */ safeHtml = sanitizer.sanitizeChildren(DOM.getTemplateContent(containerEl) || containerEl);
22742 // Clear out the body element.
22743 var /** @type {?} */ parent = DOM.getTemplateContent(containerEl) || containerEl;
22744 for (var _i = 0, _a = DOM.childNodesAsList(parent); _i < _a.length; _i++) {
22745 var child = _a[_i];
22746 DOM.removeChild(parent, child);
22747 }
22748 if (isDevMode() && sanitizer.sanitizedSomething) {
22749 DOM.log('WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).');
22750 }
22751 return safeHtml;
22752 }
22753 catch (e) {
22754 // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
22755 inertElement = null;
22756 throw e;
22757 }
22758}
22759/**
22760 * @license
22761 * Copyright Google Inc. All Rights Reserved.
22762 *
22763 * Use of this source code is governed by an MIT-style license that can be
22764 * found in the LICENSE file at https://angular.io/license
22765 */
22766/**
22767 * Regular expression for safe style values.
22768 *
22769 * Quotes (" and ') are allowed, but a check must be done elsewhere to ensure they're balanced.
22770 *
22771 * ',' allows multiple values to be assigned to the same property (e.g. background-attachment or
22772 * font-family) and hence could allow multiple values to get injected, but that should pose no risk
22773 * of XSS.
22774 *
22775 * The function expression checks only for XSS safety, not for CSS validity.
22776 *
22777 * This regular expression was taken from the Closure sanitization library, and augmented for
22778 * transformation values.
22779 */
22780var VALUES = '[-,."\'%_!# a-zA-Z0-9]+';
22781var TRANSFORMATION_FNS = '(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|3d)?';
22782var COLOR_FNS = '(?:rgb|hsl)a?';
22783var GRADIENTS = '(?:repeating-)?(?:linear|radial)-gradient';
22784var CSS3_FNS = '(?:calc|attr)';
22785var FN_ARGS = '\\([-0-9.%, #a-zA-Z]+\\)';
22786var SAFE_STYLE_VALUE = new RegExp("^(" + VALUES + "|" +
22787 ("(?:" + TRANSFORMATION_FNS + "|" + COLOR_FNS + "|" + GRADIENTS + "|" + CSS3_FNS + ")") +
22788 (FN_ARGS + ")$"), 'g');
22789/**
22790 * Matches a `url(...)` value with an arbitrary argument as long as it does
22791 * not contain parentheses.
22792 *
22793 * The URL value still needs to be sanitized separately.
22794 *
22795 * `url(...)` values are a very common use case, e.g. for `background-image`. With carefully crafted
22796 * CSS style rules, it is possible to construct an information leak with `url` values in CSS, e.g.
22797 * by observing whether scroll bars are displayed, or character ranges used by a font face
22798 * definition.
22799 *
22800 * Angular only allows binding CSS values (as opposed to entire CSS rules), so it is unlikely that
22801 * binding a URL value without further cooperation from the page will cause an information leak, and
22802 * if so, it is just a leak, not a full blown XSS vulnerability.
22803 *
22804 * Given the common use case, low likelihood of attack vector, and low impact of an attack, this
22805 * code is permissive and allows URLs that sanitize otherwise.
22806 */
22807var URL_RE = /^url\(([^)]+)\)$/;
22808/**
22809 * Checks that quotes (" and ') are properly balanced inside a string. Assumes
22810 * that neither escape (\) nor any other character that could result in
22811 * breaking out of a string parsing context are allowed;
22812 * see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
22813 *
22814 * This code was taken from the Closure sanitization library.
22815 * @param {?} value
22816 * @return {?}
22817 */
22818function hasBalancedQuotes(value) {
22819 var /** @type {?} */ outsideSingle = true;
22820 var /** @type {?} */ outsideDouble = true;
22821 for (var /** @type {?} */ i = 0; i < value.length; i++) {
22822 var /** @type {?} */ c = value.charAt(i);
22823 if (c === '\'' && outsideDouble) {
22824 outsideSingle = !outsideSingle;
22825 }
22826 else if (c === '"' && outsideSingle) {
22827 outsideDouble = !outsideDouble;
22828 }
22829 }
22830 return outsideSingle && outsideDouble;
22831}
22832/**
22833 * Sanitizes the given untrusted CSS style property value (i.e. not an entire object, just a single
22834 * value) and returns a value that is safe to use in a browser environment.
22835 * @param {?} value
22836 * @return {?}
22837 */
22838function sanitizeStyle(value) {
22839 value = String(value).trim(); // Make sure it's actually a string.
22840 if (!value)
22841 return '';
22842 // Single url(...) values are supported, but only for URLs that sanitize cleanly. See above for
22843 // reasoning behind this.
22844 var /** @type {?} */ urlMatch = value.match(URL_RE);
22845 if ((urlMatch && sanitizeUrl(urlMatch[1]) === urlMatch[1]) ||
22846 value.match(SAFE_STYLE_VALUE) && hasBalancedQuotes(value)) {
22847 return value; // Safe style values.
22848 }
22849 if (isDevMode()) {
22850 getDOM().log("WARNING: sanitizing unsafe style value " + value + " (see http://g.co/ng/security#xss).");
22851 }
22852 return 'unsafe';
22853}
22854/**
22855 * @license
22856 * Copyright Google Inc. All Rights Reserved.
22857 *
22858 * Use of this source code is governed by an MIT-style license that can be
22859 * found in the LICENSE file at https://angular.io/license
22860 */
22861/**
22862 * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing
22863 * values to be safe to use in the different DOM contexts.
22864 *
22865 * For example, when binding a URL in an `<a [href]="someValue">` hyperlink, `someValue` will be
22866 * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on
22867 * the website.
22868 *
22869 * In specific situations, it might be necessary to disable sanitization, for example if the
22870 * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.
22871 * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`
22872 * methods, and then binding to that value from the template.
22873 *
22874 * These situations should be very rare, and extraordinary care must be taken to avoid creating a
22875 * Cross Site Scripting (XSS) security bug!
22876 *
22877 * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as
22878 * close as possible to the source of the value, to make it easy to verify no security bug is
22879 * created by its use.
22880 *
22881 * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that
22882 * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous
22883 * code. The sanitizer leaves safe values intact.
22884 *
22885 * \@security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in
22886 * sanitization for the value passed in. Carefully check and audit all values and code paths going
22887 * into this call. Make sure any user data is appropriately escaped for this security context.
22888 * For more detail, see the [Security Guide](http://g.co/ng/security).
22889 *
22890 * \@stable
22891 * @abstract
22892 */
22893var DomSanitizer = (function () {
22894 function DomSanitizer() {
22895 }
22896 /**
22897 * Sanitizes a value for use in the given SecurityContext.
22898 *
22899 * If value is trusted for the context, this method will unwrap the contained safe value and use
22900 * it directly. Otherwise, value will be sanitized to be safe in the given context, for example
22901 * by replacing URLs that have an unsafe protocol part (such as `javascript:`). The implementation
22902 * is responsible to make sure that the value can definitely be safely used in the given context.
22903 * @abstract
22904 * @param {?} context
22905 * @param {?} value
22906 * @return {?}
22907 */
22908 DomSanitizer.prototype.sanitize = function (context, value) { };
22909 /**
22910 * Bypass security and trust the given value to be safe HTML. Only use this when the bound HTML
22911 * is unsafe (e.g. contains `<script>` tags) and the code should be executed. The sanitizer will
22912 * leave safe HTML intact, so in most situations this method should not be used.
22913 *
22914 * **WARNING:** calling this method with untrusted user data exposes your application to XSS
22915 * security risks!
22916 * @abstract
22917 * @param {?} value
22918 * @return {?}
22919 */
22920 DomSanitizer.prototype.bypassSecurityTrustHtml = function (value) { };
22921 /**
22922 * Bypass security and trust the given value to be safe style value (CSS).
22923 *
22924 * **WARNING:** calling this method with untrusted user data exposes your application to XSS
22925 * security risks!
22926 * @abstract
22927 * @param {?} value
22928 * @return {?}
22929 */
22930 DomSanitizer.prototype.bypassSecurityTrustStyle = function (value) { };
22931 /**
22932 * Bypass security and trust the given value to be safe JavaScript.
22933 *
22934 * **WARNING:** calling this method with untrusted user data exposes your application to XSS
22935 * security risks!
22936 * @abstract
22937 * @param {?} value
22938 * @return {?}
22939 */
22940 DomSanitizer.prototype.bypassSecurityTrustScript = function (value) { };
22941 /**
22942 * Bypass security and trust the given value to be a safe style URL, i.e. a value that can be used
22943 * in hyperlinks or `<img src>`.
22944 *
22945 * **WARNING:** calling this method with untrusted user data exposes your application to XSS
22946 * security risks!
22947 * @abstract
22948 * @param {?} value
22949 * @return {?}
22950 */
22951 DomSanitizer.prototype.bypassSecurityTrustUrl = function (value) { };
22952 /**
22953 * Bypass security and trust the given value to be a safe resource URL, i.e. a location that may
22954 * be used to load executable code from, like `<script src>`, or `<iframe src>`.
22955 *
22956 * **WARNING:** calling this method with untrusted user data exposes your application to XSS
22957 * security risks!
22958 * @abstract
22959 * @param {?} value
22960 * @return {?}
22961 */
22962 DomSanitizer.prototype.bypassSecurityTrustResourceUrl = function (value) { };
22963 return DomSanitizer;
22964}());
22965var DomSanitizerImpl = (function (_super) {
22966 __extends$1(DomSanitizerImpl, _super);
22967 /**
22968 * @param {?} _doc
22969 */
22970 function DomSanitizerImpl(_doc) {
22971 var _this = _super.call(this) || this;
22972 _this._doc = _doc;
22973 return _this;
22974 }
22975 /**
22976 * @param {?} ctx
22977 * @param {?} value
22978 * @return {?}
22979 */
22980 DomSanitizerImpl.prototype.sanitize = function (ctx, value) {
22981 if (value == null)
22982 return null;
22983 switch (ctx) {
22984 case SecurityContext.NONE:
22985 return (value);
22986 case SecurityContext.HTML:
22987 if (value instanceof SafeHtmlImpl)
22988 return value.changingThisBreaksApplicationSecurity;
22989 this.checkNotSafeValue(value, 'HTML');
22990 return sanitizeHtml(this._doc, String(value));
22991 case SecurityContext.STYLE:
22992 if (value instanceof SafeStyleImpl)
22993 return value.changingThisBreaksApplicationSecurity;
22994 this.checkNotSafeValue(value, 'Style');
22995 return sanitizeStyle(/** @type {?} */ (value));
22996 case SecurityContext.SCRIPT:
22997 if (value instanceof SafeScriptImpl)
22998 return value.changingThisBreaksApplicationSecurity;
22999 this.checkNotSafeValue(value, 'Script');
23000 throw new Error('unsafe value used in a script context');
23001 case SecurityContext.URL:
23002 if (value instanceof SafeResourceUrlImpl || value instanceof SafeUrlImpl) {
23003 // Allow resource URLs in URL contexts, they are strictly more trusted.
23004 return value.changingThisBreaksApplicationSecurity;
23005 }
23006 this.checkNotSafeValue(value, 'URL');
23007 return sanitizeUrl(String(value));
23008 case SecurityContext.RESOURCE_URL:
23009 if (value instanceof SafeResourceUrlImpl) {
23010 return value.changingThisBreaksApplicationSecurity;
23011 }
23012 this.checkNotSafeValue(value, 'ResourceURL');
23013 throw new Error('unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
23014 default:
23015 throw new Error("Unexpected SecurityContext " + ctx + " (see http://g.co/ng/security#xss)");
23016 }
23017 };
23018 /**
23019 * @param {?} value
23020 * @param {?} expectedType
23021 * @return {?}
23022 */
23023 DomSanitizerImpl.prototype.checkNotSafeValue = function (value, expectedType) {
23024 if (value instanceof SafeValueImpl) {
23025 throw new Error("Required a safe " + expectedType + ", got a " + value.getTypeName() + " " +
23026 "(see http://g.co/ng/security#xss)");
23027 }
23028 };
23029 /**
23030 * @param {?} value
23031 * @return {?}
23032 */
23033 DomSanitizerImpl.prototype.bypassSecurityTrustHtml = function (value) { return new SafeHtmlImpl(value); };
23034 /**
23035 * @param {?} value
23036 * @return {?}
23037 */
23038 DomSanitizerImpl.prototype.bypassSecurityTrustStyle = function (value) { return new SafeStyleImpl(value); };
23039 /**
23040 * @param {?} value
23041 * @return {?}
23042 */
23043 DomSanitizerImpl.prototype.bypassSecurityTrustScript = function (value) { return new SafeScriptImpl(value); };
23044 /**
23045 * @param {?} value
23046 * @return {?}
23047 */
23048 DomSanitizerImpl.prototype.bypassSecurityTrustUrl = function (value) { return new SafeUrlImpl(value); };
23049 /**
23050 * @param {?} value
23051 * @return {?}
23052 */
23053 DomSanitizerImpl.prototype.bypassSecurityTrustResourceUrl = function (value) {
23054 return new SafeResourceUrlImpl(value);
23055 };
23056 return DomSanitizerImpl;
23057}(DomSanitizer));
23058DomSanitizerImpl.decorators = [
23059 { type: Injectable },
23060];
23061/**
23062 * @nocollapse
23063 */
23064DomSanitizerImpl.ctorParameters = function () { return [
23065 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
23066]; };
23067/**
23068 * @abstract
23069 */
23070var SafeValueImpl = (function () {
23071 /**
23072 * @param {?} changingThisBreaksApplicationSecurity
23073 */
23074 function SafeValueImpl(changingThisBreaksApplicationSecurity) {
23075 this.changingThisBreaksApplicationSecurity = changingThisBreaksApplicationSecurity;
23076 // empty
23077 }
23078 /**
23079 * @abstract
23080 * @return {?}
23081 */
23082 SafeValueImpl.prototype.getTypeName = function () { };
23083 /**
23084 * @return {?}
23085 */
23086 SafeValueImpl.prototype.toString = function () {
23087 return "SafeValue must use [property]=binding: " + this.changingThisBreaksApplicationSecurity +
23088 " (see http://g.co/ng/security#xss)";
23089 };
23090 return SafeValueImpl;
23091}());
23092var SafeHtmlImpl = (function (_super) {
23093 __extends$1(SafeHtmlImpl, _super);
23094 function SafeHtmlImpl() {
23095 return _super !== null && _super.apply(this, arguments) || this;
23096 }
23097 /**
23098 * @return {?}
23099 */
23100 SafeHtmlImpl.prototype.getTypeName = function () { return 'HTML'; };
23101 return SafeHtmlImpl;
23102}(SafeValueImpl));
23103var SafeStyleImpl = (function (_super) {
23104 __extends$1(SafeStyleImpl, _super);
23105 function SafeStyleImpl() {
23106 return _super !== null && _super.apply(this, arguments) || this;
23107 }
23108 /**
23109 * @return {?}
23110 */
23111 SafeStyleImpl.prototype.getTypeName = function () { return 'Style'; };
23112 return SafeStyleImpl;
23113}(SafeValueImpl));
23114var SafeScriptImpl = (function (_super) {
23115 __extends$1(SafeScriptImpl, _super);
23116 function SafeScriptImpl() {
23117 return _super !== null && _super.apply(this, arguments) || this;
23118 }
23119 /**
23120 * @return {?}
23121 */
23122 SafeScriptImpl.prototype.getTypeName = function () { return 'Script'; };
23123 return SafeScriptImpl;
23124}(SafeValueImpl));
23125var SafeUrlImpl = (function (_super) {
23126 __extends$1(SafeUrlImpl, _super);
23127 function SafeUrlImpl() {
23128 return _super !== null && _super.apply(this, arguments) || this;
23129 }
23130 /**
23131 * @return {?}
23132 */
23133 SafeUrlImpl.prototype.getTypeName = function () { return 'URL'; };
23134 return SafeUrlImpl;
23135}(SafeValueImpl));
23136var SafeResourceUrlImpl = (function (_super) {
23137 __extends$1(SafeResourceUrlImpl, _super);
23138 function SafeResourceUrlImpl() {
23139 return _super !== null && _super.apply(this, arguments) || this;
23140 }
23141 /**
23142 * @return {?}
23143 */
23144 SafeResourceUrlImpl.prototype.getTypeName = function () { return 'ResourceURL'; };
23145 return SafeResourceUrlImpl;
23146}(SafeValueImpl));
23147/**
23148 * @license
23149 * Copyright Google Inc. All Rights Reserved.
23150 *
23151 * Use of this source code is governed by an MIT-style license that can be
23152 * found in the LICENSE file at https://angular.io/license
23153 */
23154var INTERNAL_BROWSER_PLATFORM_PROVIDERS = [
23155 { provide: PLATFORM_ID, useValue: PLATFORM_BROWSER_ID },
23156 { provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true },
23157 { provide: PlatformLocation, useClass: BrowserPlatformLocation },
23158 { provide: DOCUMENT$1, useFactory: _document, deps: [] },
23159];
23160/**
23161 * \@security Replacing built-in sanitization providers exposes the application to XSS risks.
23162 * Attacker-controlled data introduced by an unsanitized provider could expose your
23163 * application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
23164 * \@experimental
23165 */
23166var BROWSER_SANITIZATION_PROVIDERS = [
23167 { provide: Sanitizer, useExisting: DomSanitizer },
23168 { provide: DomSanitizer, useClass: DomSanitizerImpl },
23169];
23170/**
23171 * \@stable
23172 */
23173var platformBrowser = createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
23174/**
23175 * @return {?}
23176 */
23177function initDomAdapter() {
23178 BrowserDomAdapter.makeCurrent();
23179 BrowserGetTestability.init();
23180}
23181/**
23182 * @return {?}
23183 */
23184function errorHandler() {
23185 return new ErrorHandler();
23186}
23187/**
23188 * @return {?}
23189 */
23190function _document() {
23191 return document;
23192}
23193/**
23194 * The ng module for the browser.
23195 *
23196 * \@stable
23197 */
23198var BrowserModule = (function () {
23199 /**
23200 * @param {?} parentModule
23201 */
23202 function BrowserModule(parentModule) {
23203 if (parentModule) {
23204 throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.");
23205 }
23206 }
23207 /**
23208 * Configures a browser-based application to transition from a server-rendered app, if
23209 * one is present on the page. The specified parameters must include an application id,
23210 * which must match between the client and server applications.
23211 *
23212 * \@experimental
23213 * @param {?} params
23214 * @return {?}
23215 */
23216 BrowserModule.withServerTransition = function (params) {
23217 return {
23218 ngModule: BrowserModule,
23219 providers: [
23220 { provide: APP_ID, useValue: params.appId },
23221 { provide: TRANSITION_ID, useExisting: APP_ID },
23222 SERVER_TRANSITION_PROVIDERS,
23223 ],
23224 };
23225 };
23226 return BrowserModule;
23227}());
23228BrowserModule.decorators = [
23229 { type: NgModule, args: [{
23230 providers: [
23231 BROWSER_SANITIZATION_PROVIDERS,
23232 { provide: ErrorHandler, useFactory: errorHandler, deps: [] },
23233 { provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true },
23234 { provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true },
23235 { provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true },
23236 { provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig },
23237 DomRendererFactory2,
23238 { provide: RendererFactory2, useExisting: DomRendererFactory2 },
23239 { provide: SharedStylesHost, useExisting: DomSharedStylesHost },
23240 DomSharedStylesHost,
23241 Testability,
23242 EventManager,
23243 ELEMENT_PROBE_PROVIDERS,
23244 Meta,
23245 Title,
23246 ],
23247 exports: [CommonModule, ApplicationModule]
23248 },] },
23249];
23250/**
23251 * @nocollapse
23252 */
23253BrowserModule.ctorParameters = function () { return [
23254 { type: BrowserModule, decorators: [{ type: Optional }, { type: SkipSelf },] },
23255]; };
23256/**
23257 * @license
23258 * Copyright Google Inc. All Rights Reserved.
23259 *
23260 * Use of this source code is governed by an MIT-style license that can be
23261 * found in the LICENSE file at https://angular.io/license
23262 */
23263var win = typeof window !== 'undefined' && window || {};
23264/**
23265 * @license
23266 * Copyright Google Inc. All Rights Reserved.
23267 *
23268 * Use of this source code is governed by an MIT-style license that can be
23269 * found in the LICENSE file at https://angular.io/license
23270 */
23271var ChangeDetectionPerfRecord = (function () {
23272 /**
23273 * @param {?} msPerTick
23274 * @param {?} numTicks
23275 */
23276 function ChangeDetectionPerfRecord(msPerTick, numTicks) {
23277 this.msPerTick = msPerTick;
23278 this.numTicks = numTicks;
23279 }
23280 return ChangeDetectionPerfRecord;
23281}());
23282/**
23283 * Entry point for all Angular profiling-related debug tools. This object
23284 * corresponds to the `ng.profiler` in the dev console.
23285 */
23286var AngularProfiler = (function () {
23287 /**
23288 * @param {?} ref
23289 */
23290 function AngularProfiler(ref) {
23291 this.appRef = ref.injector.get(ApplicationRef);
23292 }
23293 /**
23294 * Exercises change detection in a loop and then prints the average amount of
23295 * time in milliseconds how long a single round of change detection takes for
23296 * the current state of the UI. It runs a minimum of 5 rounds for a minimum
23297 * of 500 milliseconds.
23298 *
23299 * Optionally, a user may pass a `config` parameter containing a map of
23300 * options. Supported options are:
23301 *
23302 * `record` (boolean) - causes the profiler to record a CPU profile while
23303 * it exercises the change detector. Example:
23304 *
23305 * ```
23306 * ng.profiler.timeChangeDetection({record: true})
23307 * ```
23308 * @param {?} config
23309 * @return {?}
23310 */
23311 AngularProfiler.prototype.timeChangeDetection = function (config) {
23312 var /** @type {?} */ record = config && config['record'];
23313 var /** @type {?} */ profileName = 'Change Detection';
23314 // Profiler is not available in Android browsers, nor in IE 9 without dev tools opened
23315 var /** @type {?} */ isProfilerAvailable = win.console.profile != null;
23316 if (record && isProfilerAvailable) {
23317 win.console.profile(profileName);
23318 }
23319 var /** @type {?} */ start = getDOM().performanceNow();
23320 var /** @type {?} */ numTicks = 0;
23321 while (numTicks < 5 || (getDOM().performanceNow() - start) < 500) {
23322 this.appRef.tick();
23323 numTicks++;
23324 }
23325 var /** @type {?} */ end = getDOM().performanceNow();
23326 if (record && isProfilerAvailable) {
23327 // need to cast to <any> because type checker thinks there's no argument
23328 // while in fact there is:
23329 //
23330 // https://developer.mozilla.org/en-US/docs/Web/API/Console/profileEnd
23331 ((win.console.profileEnd))(profileName);
23332 }
23333 var /** @type {?} */ msPerTick = (end - start) / numTicks;
23334 win.console.log("ran " + numTicks + " change detection cycles");
23335 win.console.log(msPerTick.toFixed(2) + " ms per check");
23336 return new ChangeDetectionPerfRecord(msPerTick, numTicks);
23337 };
23338 return AngularProfiler;
23339}());
23340/**
23341 * @license
23342 * Copyright Google Inc. All Rights Reserved.
23343 *
23344 * Use of this source code is governed by an MIT-style license that can be
23345 * found in the LICENSE file at https://angular.io/license
23346 */
23347var PROFILER_GLOBAL_NAME = 'profiler';
23348/**
23349 * @license
23350 * Copyright Google Inc. All Rights Reserved.
23351 *
23352 * Use of this source code is governed by an MIT-style license that can be
23353 * found in the LICENSE file at https://angular.io/license
23354 */
23355/**
23356 * @license
23357 * Copyright Google Inc. All Rights Reserved.
23358 *
23359 * Use of this source code is governed by an MIT-style license that can be
23360 * found in the LICENSE file at https://angular.io/license
23361 */
23362/**
23363 * @module
23364 * @description
23365 * Entry point for all public APIs of the common package.
23366 */
23367/**
23368 * \@stable
23369 */
23370var VERSION$1 = new Version('4.4.3');
23371
23372var PORTAL_DEFAULT = 1;
23373var PORTAL_MODAL = 2;
23374var PORTAL_LOADING = 3;
23375var PORTAL_TOAST = 4;
23376
23377/**
23378 * @hidden
23379 * Given a min and max, restrict the given number
23380 * to the range.
23381 * @param {?} min the minimum
23382 * @param {?} n the value
23383 * @param {?} max the maximum
23384 * @return {?}
23385 */
23386function clamp(min, n, max) {
23387 return Math.max(min, Math.min(n, max));
23388}
23389/**
23390 * @hidden
23391 * @param {?} obj
23392 * @return {?}
23393 */
23394function deepCopy(obj) {
23395 return JSON.parse(JSON.stringify(obj));
23396}
23397/**
23398 * @hidden
23399 * @param {?} a
23400 * @param {?} b
23401 * @return {?}
23402 */
23403function deepEqual(a, b) {
23404 if (a === b) {
23405 return true;
23406 }
23407 return JSON.stringify(a) === JSON.stringify(b);
23408}
23409/**
23410 * @hidden
23411 * @param {?} fn
23412 * @param {?} wait
23413 * @param {?=} immediate
23414 * @return {?}
23415 */
23416
23417/**
23418 * @hidden
23419 * Rewrites an absolute URL so it works across file and http based engines
23420 * @param {?} url
23421 * @return {?}
23422 */
23423function normalizeURL(url) {
23424 var /** @type {?} */ ionic = ((window))['Ionic'];
23425 if (ionic && ionic.normalizeURL) {
23426 return ionic.normalizeURL(url);
23427 }
23428 return url;
23429}
23430/**
23431 * @hidden
23432 * Apply default arguments if they don't exist in
23433 * the first object.
23434 * @param {?} dest
23435 * @param {...?} _args
23436 * @return {?}
23437 */
23438function defaults(dest) {
23439 var _args = [];
23440 for (var _i = 1; _i < arguments.length; _i++) {
23441 _args[_i - 1] = arguments[_i];
23442 }
23443 for (var /** @type {?} */ i = arguments.length - 1; i >= 1; i--) {
23444 var /** @type {?} */ source = arguments[i];
23445 if (source) {
23446 for (var /** @type {?} */ key in source) {
23447 if (source.hasOwnProperty(key) && !dest.hasOwnProperty(key)) {
23448 dest[key] = source[key];
23449 }
23450 }
23451 }
23452 }
23453 return dest;
23454}
23455/**
23456 * @hidden
23457 * @param {?} val
23458 * @return {?}
23459 */
23460
23461/**
23462 * @hidden
23463 * @param {?} val
23464 * @return {?}
23465 */
23466function isString(val) { return typeof val === 'string'; }
23467/**
23468 * @hidden
23469 * @param {?} val
23470 * @return {?}
23471 */
23472function isNumber(val) { return typeof val === 'number'; }
23473/**
23474 * @hidden
23475 * @param {?} val
23476 * @return {?}
23477 */
23478function isFunction$1(val) { return typeof val === 'function'; }
23479/**
23480 * @hidden
23481 * @param {?} val
23482 * @return {?}
23483 */
23484function isDefined(val) { return typeof val !== 'undefined'; }
23485/**
23486 * @hidden
23487 * @param {?} val
23488 * @return {?}
23489 */
23490function isUndefined(val) { return typeof val === 'undefined'; }
23491/**
23492 * @hidden
23493 * @param {?} val
23494 * @return {?}
23495 */
23496function isPresent(val) { return val !== undefined && val !== null; }
23497/**
23498 * @hidden
23499 * @param {?} val
23500 * @return {?}
23501 */
23502function isBlank$1(val) { return val === undefined || val === null; }
23503/**
23504 * @hidden
23505 * @param {?} val
23506 * @return {?}
23507 */
23508function isObject$1(val) { return typeof val === 'object'; }
23509/**
23510 * @hidden
23511 * @param {?} val
23512 * @return {?}
23513 */
23514function isArray$2(val) { return Array.isArray(val); }
23515/**
23516 * @hidden
23517 * @param {?} val
23518 * @return {?}
23519 */
23520
23521/**
23522 * @hidden
23523 * @param {?} val
23524 * @return {?}
23525 */
23526function isTrueProperty(val) {
23527 if (typeof val === 'string') {
23528 val = val.toLowerCase().trim();
23529 return (val === 'true' || val === 'on' || val === '');
23530 }
23531 return !!val;
23532}
23533/**
23534 * @hidden
23535 * @param {?} a
23536 * @param {?} b
23537 * @return {?}
23538 */
23539function isCheckedProperty(a, b) {
23540 if (a === undefined || a === null || a === '') {
23541 return (b === undefined || b === null || b === '');
23542 }
23543 else if (a === true || a === 'true') {
23544 return (b === true || b === 'true');
23545 }
23546 else if (a === false || a === 'false') {
23547 return (b === false || b === 'false');
23548 }
23549 else if (a === 0 || a === '0') {
23550 return (b === 0 || b === '0');
23551 }
23552 // not using strict comparison on purpose
23553 return (a == b); // tslint:disable-line
23554}
23555/**
23556 * @hidden
23557 * Given a side, return if it should be on the right
23558 * based on the value of dir
23559 * @param {?} side the side
23560 * @param {?} isRTL whether the application dir is rtl
23561 * @param {?=} defaultRight whether the default side is right
23562 * @return {?}
23563 */
23564function isRightSide(side, isRTL, defaultRight) {
23565 if (defaultRight === void 0) { defaultRight = false; }
23566 switch (side) {
23567 case 'right': return true;
23568 case 'left': return false;
23569 case 'end': return !isRTL;
23570 case 'start': return isRTL;
23571 default: return defaultRight ? !isRTL : isRTL;
23572 }
23573}
23574/**
23575 * @hidden
23576 * @param {?} array
23577 * @param {?} indexes
23578 * @return {?}
23579 */
23580function reorderArray(array, indexes) {
23581 var /** @type {?} */ element = array[indexes.from];
23582 array.splice(indexes.from, 1);
23583 array.splice(indexes.to, 0, element);
23584 return array;
23585}
23586/**
23587 * @hidden
23588 * @param {?} array
23589 * @param {?} item
23590 * @return {?}
23591 */
23592function removeArrayItem(array, item) {
23593 var /** @type {?} */ index = array.indexOf(item);
23594 return !!~index && !!array.splice(index, 1);
23595}
23596/**
23597 * @hidden
23598 * @param {?} isResetDirection
23599 * @param {?} isMovingFast
23600 * @param {?} isOnResetZone
23601 * @return {?}
23602 */
23603function swipeShouldReset(isResetDirection, isMovingFast, isOnResetZone) {
23604 // The logic required to know when the sliding item should close (openAmount=0)
23605 // depends on three booleans (isCloseDirection, isMovingFast, isOnCloseZone)
23606 // and it ended up being too complicated to be written manually without errors
23607 // so the truth table is attached below: (0=false, 1=true)
23608 // isCloseDirection | isMovingFast | isOnCloseZone || shouldClose
23609 // 0 | 0 | 0 || 0
23610 // 0 | 0 | 1 || 1
23611 // 0 | 1 | 0 || 0
23612 // 0 | 1 | 1 || 0
23613 // 1 | 0 | 0 || 0
23614 // 1 | 0 | 1 || 1
23615 // 1 | 1 | 0 || 1
23616 // 1 | 1 | 1 || 1
23617 // The resulting expression was generated by resolving the K-map (Karnaugh map):
23618 var /** @type {?} */ shouldClose = (!isMovingFast && isOnResetZone) || (isResetDirection && isMovingFast);
23619 return shouldClose;
23620}
23621/**
23622 * @hidden
23623 */
23624var ASSERT_ENABLED = true;
23625/**
23626 * @hidden
23627 * @param {?} functionToLazy
23628 * @return {?}
23629 */
23630function requestIonicCallback(functionToLazy) {
23631 if ('requestIdleCallback' in window) {
23632 return ((window)).requestIdleCallback(functionToLazy);
23633 }
23634 else {
23635 return setTimeout(functionToLazy, 500);
23636 }
23637}
23638
23639/**
23640 * \@name Config
23641 * \@demo /docs/demos/src/config/
23642 * \@description
23643 * The Config lets you configure your entire app or specific platforms.
23644 * You can set the tab placement, icon mode, animations, and more here.
23645 *
23646 * ```ts
23647 * import { IonicApp, IonicModule } from 'ionic-angular';
23648 *
23649 * \@NgModule({
23650 * declarations: [ MyApp ],
23651 * imports: [
23652 * BrowserModule,
23653 * IonicModule.forRoot(MyApp, {
23654 * backButtonText: 'Go Back',
23655 * iconMode: 'ios',
23656 * modalEnter: 'modal-slide-in',
23657 * modalLeave: 'modal-slide-out',
23658 * tabsPlacement: 'bottom',
23659 * pageTransition: 'ios-transition'
23660 * }, {}
23661 * )],
23662 * bootstrap: [IonicApp],
23663 * entryComponents: [ MyApp ],
23664 * providers: []
23665 * })
23666 * ```
23667 *
23668 *
23669 * Config can be overwritten at multiple levels allowing for more granular configuration.
23670 * Below is an example where an app can override any setting we want based on a platform.
23671 *
23672 * ```ts
23673 * import { IonicModule } from 'ionic-angular';
23674 *
23675 * \@NgModule({
23676 * ...
23677 * imports: [
23678 * BrowserModule,
23679 * IonicModule.forRoot(MyApp, {
23680 * tabsPlacement: 'bottom',
23681 * platforms: {
23682 * ios: {
23683 * tabsPlacement: 'top',
23684 * }
23685 * }
23686 * }, {}
23687 * )],
23688 * ...
23689 * })
23690 * ```
23691 *
23692 * We could also configure these values at a component level. Take `tabsPlacement`,
23693 * we can configure this as a property on our `ion-tabs`.
23694 *
23695 * ```html
23696 * <ion-tabs tabsPlacement="top">
23697 * <ion-tab tabTitle="Dash" tabIcon="pulse" [root]="tabRoot"></ion-tab>
23698 * </ion-tabs>
23699 * ```
23700 *
23701 * The last way we could configure is through URL query strings. This is useful for testing
23702 * while in the browser. Simply add `?ionic<PROPERTYNAME>=<value>` to the url.
23703 *
23704 * ```bash
23705 * http://localhost:8100/?ionicTabsPlacement=bottom
23706 * ```
23707 *
23708 * Any value can be added to config, and looked up at a later in any component.
23709 *
23710 * ```js
23711 * config.set('ios', 'favoriteColor', 'green');
23712 *
23713 * // from any page in your app:
23714 * config.get('favoriteColor'); // 'green' when iOS
23715 * ```
23716 *
23717 *
23718 * A config value can come from anywhere and be anything, but there are default
23719 * values for each mode. The [theming](../../../theming/platform-specific-styles/)
23720 * documentation has a chart of the default mode configuration. The following
23721 * chart displays each property with a description of what it controls.
23722 *
23723 *
23724 * | Config Property | Type | Details |
23725 * |--------------------------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
23726 * | `activator` | `string` | Used for buttons, changes the effect of pressing on a button. Available options: `"ripple"`, `"highlight"`. |
23727 * | `actionSheetEnter` | `string` | The name of the transition to use while an action sheet is presented. |
23728 * | `actionSheetLeave` | `string` | The name of the transition to use while an action sheet is dismissed. |
23729 * | `alertEnter` | `string` | The name of the transition to use while an alert is presented. |
23730 * | `alertLeave` | `string` | The name of the transition to use while an alert is dismissed. |
23731 * | `backButtonText` | `string` | The text to display by the back button icon in the navbar. |
23732 * | `backButtonIcon` | `string` | The icon to use as the back button icon. |
23733 * | `iconMode` | `string` | The mode to use for all icons throughout the application. Available options: `"ios"`, `"md"` |
23734 * | `locationStrategy` | `string` | Set to 'path' to remove hashbangs when using Deeplinking. |
23735 * | `loadingEnter` | `string` | The name of the transition to use while a loading indicator is presented. |
23736 * | `loadingLeave` | `string` | The name of the transition to use while a loading indicator is dismissed. |
23737 * | `menuType` | `string` | Type of menu to display. Available options: `"overlay"`, `"reveal"`, `"push"`. |
23738 * | `modalEnter` | `string` | The name of the transition to use while a modal is presented. |
23739 * | `modalLeave` | `string` | The name of the transition to use while a modal is dismiss. |
23740 * | `mode` | `string` | The mode to use throughout the application. |
23741 * | `pageTransition` | `string` | The name of the transition to use while changing pages. Available options: `"ios-transition"`, `"md-transition"`, `"wp-transition"`. |
23742 * | `pickerEnter` | `string` | The name of the transition to use while a picker is presented. |
23743 * | `pickerLeave` | `string` | The name of the transition to use while a picker is dismissed. |
23744 * | `popoverEnter` | `string` | The name of the transition to use while a popover is presented. |
23745 * | `popoverLeave` | `string` | The name of the transition to use while a popover is dismissed. |
23746 * | `spinner` | `string` | The default spinner to use when a name is not defined. |
23747 * | `statusbarPadding` | `boolean` | Whether to hide extra padding for statusbar. |
23748 * | `swipeBackEnabled` | `boolean` | Whether native iOS swipe to go back functionality is enabled. |
23749 * | `tabsHighlight` | `boolean` | Whether to show a highlight line under the tab when it is selected. |
23750 * | `tabsLayout` | `string` | The layout to use for all tabs. Available options: `"icon-top"`, `"icon-start"`, `"icon-end"`, `"icon-bottom"`, `"icon-hide"`, `"title-hide"`. |
23751 * | `tabsPlacement` | `string` | The position of the tabs relative to the content. Available options: `"top"`, `"bottom"` |
23752 * | `tabsHideOnSubPages` | `boolean` | Whether to hide the tabs on child pages or not. If `true` it will not show the tabs on child pages. |
23753 * | `toastEnter` | `string` | The name of the transition to use while a toast is presented. |
23754 * | `toastLeave` | `string` | The name of the transition to use while a toast is dismissed. |
23755 *
23756 *
23757 */
23758var Config = (function () {
23759 function Config() {
23760 this._c = {};
23761 this._s = {};
23762 this._modes = {};
23763 this._trns = {};
23764 }
23765 /**
23766 * @hidden
23767 * @param {?} config
23768 * @param {?} plt
23769 * @return {?}
23770 */
23771 Config.prototype.init = function (config, plt) {
23772 this._s = config && isObject$1(config) && !isArray$2(config) ? config : {};
23773 this.plt = plt;
23774 };
23775 /**
23776 * \@name get
23777 * \@description
23778 * Returns a single config value, given a key.
23779 *
23780 * value was not found, or is config value is `null`. Fallback value
23781 * defaults to `null`.
23782 * @param {?} key
23783 * @param {?=} fallbackValue
23784 * @return {?}
23785 */
23786 Config.prototype.get = function (key, fallbackValue) {
23787 if (fallbackValue === void 0) { fallbackValue = null; }
23788 var /** @type {?} */ platform = this.plt;
23789 if (!isDefined(this._c[key])) {
23790 if (!isDefined(key)) {
23791 throw 'config key is not defined';
23792 }
23793 // if the value was already set this will all be skipped
23794 // if there was no user config then it'll check each of
23795 // the user config's platforms, which already contains
23796 // settings from default platform configs
23797 var /** @type {?} */ userPlatformValue = undefined;
23798 var /** @type {?} */ userDefaultValue = this._s[key];
23799 var /** @type {?} */ userPlatformModeValue = undefined;
23800 var /** @type {?} */ userDefaultModeValue = undefined;
23801 var /** @type {?} */ platformValue = undefined;
23802 var /** @type {?} */ platformModeValue = undefined;
23803 var /** @type {?} */ configObj = null;
23804 if (platform) {
23805 var /** @type {?} */ queryStringValue = platform.getQueryParam('ionic' + key);
23806 if (isDefined(queryStringValue)) {
23807 return this._c[key] = (queryStringValue === 'true' ? true : queryStringValue === 'false' ? false : queryStringValue);
23808 }
23809 // check the platform settings object for this value
23810 // loop though each of the active platforms
23811 // array of active platforms, which also knows the hierarchy,
23812 // with the last one the most important
23813 var /** @type {?} */ activePlatformKeys = platform.platforms();
23814 // loop through all of the active platforms we're on
23815 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = activePlatformKeys.length; i < ilen; i++) {
23816 // get user defined platform values
23817 if (this._s.platforms) {
23818 configObj = this._s.platforms[activePlatformKeys[i]];
23819 if (configObj) {
23820 if (isDefined(configObj[key])) {
23821 userPlatformValue = configObj[key];
23822 }
23823 configObj = this.getModeConfig(configObj.mode);
23824 if (configObj && isDefined(configObj[key])) {
23825 userPlatformModeValue = configObj[key];
23826 }
23827 }
23828 }
23829 // get default platform's setting
23830 configObj = platform.getPlatformConfig(activePlatformKeys[i]);
23831 if (configObj && configObj.settings) {
23832 if (isDefined(configObj.settings[key])) {
23833 // found a setting for this platform
23834 platformValue = configObj.settings[key];
23835 }
23836 configObj = this.getModeConfig(configObj.settings.mode);
23837 if (configObj && isDefined(configObj[key])) {
23838 // found setting for this platform's mode
23839 platformModeValue = configObj[key];
23840 }
23841 }
23842 }
23843 }
23844 configObj = this.getModeConfig(this._s.mode);
23845 if (configObj && isDefined(configObj[key])) {
23846 userDefaultModeValue = configObj[key];
23847 }
23848 // cache the value
23849 this._c[key] = isDefined(userPlatformValue) ? userPlatformValue :
23850 isDefined(userDefaultValue) ? userDefaultValue :
23851 isDefined(userPlatformModeValue) ? userPlatformModeValue :
23852 isDefined(userDefaultModeValue) ? userDefaultModeValue :
23853 isDefined(platformValue) ? platformValue :
23854 isDefined(platformModeValue) ? platformModeValue :
23855 null;
23856 }
23857 // return key's value
23858 // either it came directly from the user config
23859 // or it was from the users platform configs
23860 // or it was from the default platform configs
23861 // in that order
23862 var /** @type {?} */ rtnVal = this._c[key];
23863 if (isFunction$1(rtnVal)) {
23864 rtnVal = rtnVal(platform);
23865 }
23866 return (rtnVal !== null ? rtnVal : fallbackValue);
23867 };
23868 /**
23869 * \@name getBoolean
23870 * \@description
23871 * Same as `get()`, however always returns a boolean value. If the
23872 * value from `get()` is `null`, then it'll return the `fallbackValue`
23873 * which defaults to `false`. Otherwise, `getBoolean()` will return
23874 * if the config value is truthy or not. It also returns `true` if
23875 * the config value was the string value `"true"`.
23876 * value was `null`. Fallback value defaults to `false`.
23877 * @param {?} key
23878 * @param {?=} fallbackValue
23879 * @return {?}
23880 */
23881 Config.prototype.getBoolean = function (key, fallbackValue) {
23882 if (fallbackValue === void 0) { fallbackValue = false; }
23883 var /** @type {?} */ val = this.get(key);
23884 if (val === null) {
23885 return fallbackValue;
23886 }
23887 if (typeof val === 'string') {
23888 return val === 'true';
23889 }
23890 return !!val;
23891 };
23892 /**
23893 * \@name getNumber
23894 * \@description
23895 * Same as `get()`, however always returns a number value. Uses `parseFloat()`
23896 * on the value received from `get()`. If the result from the parse is `NaN`,
23897 * then it will return the value passed to `fallbackValue`. If no fallback
23898 * value was provided then it'll default to returning `NaN` when the result
23899 * is not a valid number.
23900 * value turned out to be `NaN`. Fallback value defaults to `NaN`.
23901 * @param {?} key
23902 * @param {?=} fallbackValue
23903 * @return {?}
23904 */
23905 Config.prototype.getNumber = function (key, fallbackValue) {
23906 if (fallbackValue === void 0) { fallbackValue = NaN; }
23907 var /** @type {?} */ val = parseFloat(this.get(key));
23908 return isNaN(val) ? fallbackValue : val;
23909 };
23910 /**
23911 * \@name set
23912 * \@description
23913 * Sets a single config value.
23914 *
23915 * @param {...?} args
23916 * @return {?}
23917 */
23918 Config.prototype.set = function () {
23919 var args = [];
23920 for (var _i = 0; _i < arguments.length; _i++) {
23921 args[_i] = arguments[_i];
23922 }
23923 var /** @type {?} */ arg0 = args[0];
23924 var /** @type {?} */ arg1 = args[1];
23925 switch (args.length) {
23926 case 2:
23927 // set('key', 'value') = set key/value pair
23928 // arg1 = value
23929 this._s[arg0] = arg1;
23930 delete this._c[arg0]; // clear cache
23931 break;
23932 case 3:
23933 // setting('ios', 'key', 'value') = set key/value pair for platform
23934 // arg0 = platform
23935 // arg1 = key
23936 // arg2 = value
23937 this._s.platforms = this._s.platforms || {};
23938 this._s.platforms[arg0] = this._s.platforms[arg0] || {};
23939 this._s.platforms[arg0][arg1] = args[2];
23940 delete this._c[arg1]; // clear cache
23941 break;
23942 }
23943 return this;
23944 };
23945 /**
23946 * @hidden
23947 * \@name settings()
23948 * \@description
23949 * @param {?=} arg0
23950 * @param {?=} arg1
23951 * @return {?}
23952 */
23953 Config.prototype.settings = function (arg0, arg1) {
23954 switch (arguments.length) {
23955 case 0:
23956 return this._s;
23957 case 1:
23958 // settings({...})
23959 this._s = arg0;
23960 this._c = {}; // clear cache
23961 break;
23962 case 2:
23963 // settings('ios', {...})
23964 this._s.platforms = this._s.platforms || {};
23965 this._s.platforms[arg0] = arg1;
23966 this._c = {}; // clear cache
23967 break;
23968 }
23969 return this;
23970 };
23971 /**
23972 * @hidden
23973 * @param {?} modeName
23974 * @param {?} modeConfig
23975 * @return {?}
23976 */
23977 Config.prototype.setModeConfig = function (modeName, modeConfig) {
23978 this._modes[modeName] = modeConfig;
23979 };
23980 /**
23981 * @hidden
23982 * @param {?} modeName
23983 * @return {?}
23984 */
23985 Config.prototype.getModeConfig = function (modeName) {
23986 return this._modes[modeName] || null;
23987 };
23988 /**
23989 * @hidden
23990 * @param {?} trnsName
23991 * @param {?} trnsClass
23992 * @return {?}
23993 */
23994 Config.prototype.setTransition = function (trnsName, trnsClass) {
23995 this._trns[trnsName] = trnsClass;
23996 };
23997 /**
23998 * @hidden
23999 * @param {?} trnsName
24000 * @return {?}
24001 */
24002 Config.prototype.getTransition = function (trnsName) {
24003 return this._trns[trnsName] || null;
24004 };
24005 return Config;
24006}());
24007/**
24008 * @hidden
24009 * @param {?} userConfig
24010 * @param {?} plt
24011 * @return {?}
24012 */
24013function setupConfig(userConfig, plt) {
24014 var /** @type {?} */ config = new Config();
24015 config.init(userConfig, plt);
24016 // add the config obj to the window
24017 var /** @type {?} */ win = plt.win();
24018 win['Ionic'] = win['Ionic'] || {};
24019 win['Ionic']['config'] = config;
24020 return config;
24021}
24022/**
24023 * @hidden
24024 */
24025var ConfigToken = new OpaqueToken('USERCONFIG');
24026
24027/**
24028 * \@name NavParams
24029 * \@description
24030 * NavParams are an object that exists on a page and can contain data for that particular view.
24031 * Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible
24032 * option with a simple `get` method.
24033 *
24034 * \@usage
24035 * ```ts
24036 * import { NavParams } from 'ionic-angular';
24037 *
24038 * export class MyClass{
24039 *
24040 * constructor(navParams: NavParams){
24041 * // userParams is an object we have in our nav-parameters
24042 * navParams.get('userParams');
24043 * }
24044 *
24045 * }
24046 * ```
24047 * \@demo /docs/demos/src/nav-params/
24048 * @see {\@link /docs/components#navigation Navigation Component Docs}
24049 * @see {\@link ../NavController/ NavController API Docs}
24050 * @see {\@link /docs/api/components/nav/Nav/ Nav API Docs}
24051 * @see {\@link /docs/api/components/nav/NavPush/ NavPush API Docs}
24052 */
24053var NavParams = (function () {
24054 /**
24055 * @hidden
24056 * @param {?=} data
24057 */
24058 function NavParams(data) {
24059 if (data === void 0) { data = {}; }
24060 this.data = data;
24061 }
24062 /**
24063 * Get the value of a nav-parameter for the current view
24064 *
24065 * ```ts
24066 * import { NavParams } from 'ionic-angular';
24067 *
24068 * export class MyClass{
24069 * constructor(public navParams: NavParams){
24070 * // userParams is an object we have in our nav-parameters
24071 * this.navParams.get('userParams');
24072 * }
24073 * }
24074 * ```
24075 *
24076 *
24077 * @param {?} param
24078 * @return {?}
24079 */
24080 NavParams.prototype.get = function (param) {
24081 return this.data[param];
24082 };
24083 return NavParams;
24084}());
24085
24086/**
24087 * \@name ViewController
24088 * \@description
24089 * Access various features and information about the current view.
24090 * \@usage
24091 * ```ts
24092 * import { Component } from '\@angular/core';
24093 * import { ViewController } from 'ionic-angular';
24094 *
24095 * \@Component({...})
24096 * export class MyPage{
24097 *
24098 * constructor(public viewCtrl: ViewController) {}
24099 *
24100 * }
24101 * ```
24102 */
24103var ViewController = (function () {
24104 /**
24105 * @param {?=} component
24106 * @param {?=} data
24107 * @param {?=} rootCssClass
24108 */
24109 function ViewController(component, data, rootCssClass) {
24110 if (rootCssClass === void 0) { rootCssClass = DEFAULT_CSS_CLASS; }
24111 this.component = component;
24112 this._isHidden = false;
24113 this._state = STATE_NEW;
24114 /**
24115 * Observable to be subscribed to when the current component will become active
24116 */
24117 this.willEnter = new EventEmitter();
24118 /**
24119 * Observable to be subscribed to when the current component has become active
24120 */
24121 this.didEnter = new EventEmitter();
24122 /**
24123 * Observable to be subscribed to when the current component will no longer be active
24124 */
24125 this.willLeave = new EventEmitter();
24126 /**
24127 * Observable to be subscribed to when the current component is no long active
24128 */
24129 this.didLeave = new EventEmitter();
24130 /**
24131 * Observable to be subscribed to when the current component has been destroyed
24132 */
24133 this.willUnload = new EventEmitter();
24134 /**
24135 * @hidden
24136 */
24137 this.readReady = new EventEmitter();
24138 /**
24139 * @hidden
24140 */
24141 this.writeReady = new EventEmitter();
24142 /**
24143 * @hidden
24144 */
24145 this.isOverlay = false;
24146 /**
24147 * @hidden
24148 */
24149 this._emitter = new EventEmitter();
24150 // passed in data could be NavParams, but all we care about is its data object
24151 this.data = (data instanceof NavParams ? data.data : (isPresent(data) ? data : {}));
24152 this._cssClass = rootCssClass;
24153 this._ts = Date.now();
24154 }
24155 /**
24156 * @hidden
24157 * @param {?} componentRef
24158 * @return {?}
24159 */
24160 ViewController.prototype.init = function (componentRef) {
24161 (void 0) /* assert */;
24162 this._ts = Date.now();
24163 this._cmp = componentRef;
24164 this.instance = this.instance || componentRef.instance;
24165 this._detached = false;
24166 };
24167 /**
24168 * @param {?} navCtrl
24169 * @return {?}
24170 */
24171 ViewController.prototype._setNav = function (navCtrl) {
24172 this._nav = navCtrl;
24173 };
24174 /**
24175 * @param {?} instance
24176 * @return {?}
24177 */
24178 ViewController.prototype._setInstance = function (instance) {
24179 this.instance = instance;
24180 };
24181 /**
24182 * @hidden
24183 * @param {?=} generatorOrNext
24184 * @return {?}
24185 */
24186 ViewController.prototype.subscribe = function (generatorOrNext) {
24187 return this._emitter.subscribe(generatorOrNext);
24188 };
24189 /**
24190 * @hidden
24191 * @param {?=} data
24192 * @return {?}
24193 */
24194 ViewController.prototype.emit = function (data) {
24195 this._emitter.emit(data);
24196 };
24197 /**
24198 * Called when the current viewController has be successfully dismissed
24199 * @param {?} callback
24200 * @return {?}
24201 */
24202 ViewController.prototype.onDidDismiss = function (callback) {
24203 this._onDidDismiss = callback;
24204 };
24205 /**
24206 * Called when the current viewController will be dismissed
24207 * @param {?} callback
24208 * @return {?}
24209 */
24210 ViewController.prototype.onWillDismiss = function (callback) {
24211 this._onWillDismiss = callback;
24212 };
24213 /**
24214 * Dismiss the current viewController
24215 * @param {?=} data
24216 * @param {?=} role
24217 * @param {?=} navOptions
24218 * @return {?}
24219 */
24220 ViewController.prototype.dismiss = function (data, role, navOptions) {
24221 if (navOptions === void 0) { navOptions = {}; }
24222 if (!this._nav) {
24223 (void 0) /* assert */;
24224 return Promise.resolve(false);
24225 }
24226 if (this.isOverlay && !navOptions.minClickBlockDuration) {
24227 // This is a Modal being dismissed so we need
24228 // to add the minClickBlockDuration option
24229 // for UIWebView
24230 navOptions.minClickBlockDuration = 400;
24231 }
24232 this._dismissData = data;
24233 this._dismissRole = role;
24234 var /** @type {?} */ options = Object.assign({}, this._leavingOpts, navOptions);
24235 return this._nav.removeView(this, options).then(function () { return data; });
24236 };
24237 /**
24238 * @hidden
24239 * @return {?}
24240 */
24241 ViewController.prototype.getNav = function () {
24242 return this._nav;
24243 };
24244 /**
24245 * @hidden
24246 * @param {?} _direction
24247 * @return {?}
24248 */
24249 ViewController.prototype.getTransitionName = function (_direction) {
24250 return this._nav && this._nav.config.get('pageTransition');
24251 };
24252 /**
24253 * @hidden
24254 * @return {?}
24255 */
24256 ViewController.prototype.getNavParams = function () {
24257 return new NavParams(this.data);
24258 };
24259 /**
24260 * @hidden
24261 * @param {?} opts
24262 * @return {?}
24263 */
24264 ViewController.prototype.setLeavingOpts = function (opts) {
24265 this._leavingOpts = opts;
24266 };
24267 /**
24268 * Check to see if you can go back in the navigation stack.
24269 * @return {?}
24270 */
24271 ViewController.prototype.enableBack = function () {
24272 // update if it's possible to go back from this nav item
24273 if (!this._nav) {
24274 return false;
24275 }
24276 // the previous view may exist, but if it's about to be destroyed
24277 // it shouldn't be able to go back to
24278 var /** @type {?} */ previousItem = this._nav.getPrevious(this);
24279 return !!(previousItem);
24280 };
24281 Object.defineProperty(ViewController.prototype, "name", {
24282 /**
24283 * @hidden
24284 * @return {?}
24285 */
24286 get: function () {
24287 return (this.component ? this.component.name : '');
24288 },
24289 enumerable: true,
24290 configurable: true
24291 });
24292 Object.defineProperty(ViewController.prototype, "index", {
24293 /**
24294 * Get the index of the current component in the current navigation stack.
24295 * @return {?}
24296 */
24297 get: function () {
24298 return (this._nav ? this._nav.indexOf(this) : -1);
24299 },
24300 enumerable: true,
24301 configurable: true
24302 });
24303 /**
24304 * @return {?}
24305 */
24306 ViewController.prototype.isFirst = function () {
24307 return (this._nav ? this._nav.first() === this : false);
24308 };
24309 /**
24310 * @return {?}
24311 */
24312 ViewController.prototype.isLast = function () {
24313 return (this._nav ? this._nav.last() === this : false);
24314 };
24315 /**
24316 * @hidden
24317 * DOM WRITE
24318 * @param {?} shouldShow
24319 * @param {?} renderer
24320 * @return {?}
24321 */
24322 ViewController.prototype._domShow = function (shouldShow, renderer) {
24323 // using hidden element attribute to display:none and not render views
24324 // _hidden value of '' means the hidden attribute will be added
24325 // _hidden value of null means the hidden attribute will be removed
24326 // doing checks to make sure we only update the DOM when actually needed
24327 // if it should render, then the hidden attribute should not be on the element
24328 if (this._cmp && shouldShow === this._isHidden) {
24329 this._isHidden = !shouldShow;
24330 var /** @type {?} */ value = (shouldShow ? null : '');
24331 // ******** DOM WRITE ****************
24332 renderer.setElementAttribute(this.pageRef().nativeElement, 'hidden', value);
24333 }
24334 };
24335 /**
24336 * @hidden
24337 * @return {?}
24338 */
24339 ViewController.prototype.getZIndex = function () {
24340 return this._zIndex;
24341 };
24342 /**
24343 * @hidden
24344 * DOM WRITE
24345 * @param {?} zIndex
24346 * @param {?} renderer
24347 * @return {?}
24348 */
24349 ViewController.prototype._setZIndex = function (zIndex, renderer) {
24350 if (zIndex !== this._zIndex) {
24351 this._zIndex = zIndex;
24352 var /** @type {?} */ pageRef = this.pageRef();
24353 if (pageRef) {
24354 // ******** DOM WRITE ****************
24355 renderer.setElementStyle(pageRef.nativeElement, 'z-index', ((zIndex)));
24356 }
24357 }
24358 };
24359 /**
24360 * @return {?}
24361 */
24362 ViewController.prototype.pageRef = function () {
24363 return this._cmp && this._cmp.location;
24364 };
24365 /**
24366 * @param {?} directive
24367 * @return {?}
24368 */
24369 ViewController.prototype._setContent = function (directive) {
24370 this._cntDir = directive;
24371 };
24372 /**
24373 * @return {?}
24374 */
24375 ViewController.prototype.getContent = function () {
24376 return this._cntDir;
24377 };
24378 /**
24379 * @param {?} elementRef
24380 * @return {?}
24381 */
24382 ViewController.prototype._setContentRef = function (elementRef) {
24383 this._cntRef = elementRef;
24384 };
24385 /**
24386 * @return {?}
24387 */
24388 ViewController.prototype.contentRef = function () {
24389 return this._cntRef;
24390 };
24391 /**
24392 * @param {?} content
24393 * @return {?}
24394 */
24395 ViewController.prototype._setIONContent = function (content) {
24396 this._setContent(content);
24397 this._ionCntDir = content;
24398 };
24399 /**
24400 * @hidden
24401 * @return {?}
24402 */
24403 ViewController.prototype.getIONContent = function () {
24404 return this._ionCntDir;
24405 };
24406 /**
24407 * @param {?} elementRef
24408 * @return {?}
24409 */
24410 ViewController.prototype._setIONContentRef = function (elementRef) {
24411 this._setContentRef(elementRef);
24412 this._ionCntRef = elementRef;
24413 };
24414 /**
24415 * @hidden
24416 * @return {?}
24417 */
24418 ViewController.prototype.getIONContentRef = function () {
24419 return this._ionCntRef;
24420 };
24421 /**
24422 * @param {?} directive
24423 * @return {?}
24424 */
24425 ViewController.prototype._setHeader = function (directive) {
24426 this._hdrDir = directive;
24427 };
24428 /**
24429 * @hidden
24430 * @return {?}
24431 */
24432 ViewController.prototype.getHeader = function () {
24433 return this._hdrDir;
24434 };
24435 /**
24436 * @param {?} directive
24437 * @return {?}
24438 */
24439 ViewController.prototype._setFooter = function (directive) {
24440 this._ftrDir = directive;
24441 };
24442 /**
24443 * @hidden
24444 * @return {?}
24445 */
24446 ViewController.prototype.getFooter = function () {
24447 return this._ftrDir;
24448 };
24449 /**
24450 * @param {?} directive
24451 * @return {?}
24452 */
24453 ViewController.prototype._setNavbar = function (directive) {
24454 this._nb = directive;
24455 };
24456 /**
24457 * @hidden
24458 * @return {?}
24459 */
24460 ViewController.prototype.getNavbar = function () {
24461 return this._nb;
24462 };
24463 /**
24464 * Find out if the current component has a NavBar or not. Be sure
24465 * to wrap this in an `ionViewWillEnter` method in order to make sure
24466 * the view has rendered fully.
24467 * @return {?}
24468 */
24469 ViewController.prototype.hasNavbar = function () {
24470 return !!this._nb;
24471 };
24472 /**
24473 * Change the title of the back-button. Be sure to call this
24474 * after `ionViewWillEnter` to make sure the DOM has been rendered.
24475 * @param {?} val
24476 * @return {?}
24477 */
24478 ViewController.prototype.setBackButtonText = function (val) {
24479 this._nb && this._nb.setBackButtonText(val);
24480 };
24481 /**
24482 * Set if the back button for the current view is visible or not. Be sure to call this
24483 * after `ionViewWillEnter` to make sure the DOM has been rendered.
24484 * @param {?} shouldShow
24485 * @return {?}
24486 */
24487 ViewController.prototype.showBackButton = function (shouldShow) {
24488 if (this._nb) {
24489 this._nb.hideBackButton = !shouldShow;
24490 }
24491 };
24492 /**
24493 * @return {?}
24494 */
24495 ViewController.prototype._preLoad = function () {
24496 (void 0) /* assert */;
24497 this._lifecycle('PreLoad');
24498 };
24499 /**
24500 * @hidden
24501 * The view has loaded. This event only happens once per view will be created.
24502 * This event is fired before the component and his children have been initialized.
24503 * @return {?}
24504 */
24505 ViewController.prototype._willLoad = function () {
24506 (void 0) /* assert */;
24507 this._lifecycle('WillLoad');
24508 };
24509 /**
24510 * @hidden
24511 * The view has loaded. This event only happens once per view being
24512 * created. If a view leaves but is cached, then this will not
24513 * fire again on a subsequent viewing. This method is a good place
24514 * to put your setup code for the view; however, it is not the
24515 * recommended method to use when a view becomes active.
24516 * @return {?}
24517 */
24518 ViewController.prototype._didLoad = function () {
24519 (void 0) /* assert */;
24520 this._lifecycle('DidLoad');
24521 };
24522 /**
24523 * @hidden
24524 * The view is about to enter and become the active view.
24525 * @return {?}
24526 */
24527 ViewController.prototype._willEnter = function () {
24528 (void 0) /* assert */;
24529 if (this._detached && this._cmp) {
24530 // ensure this has been re-attached to the change detector
24531 this._cmp.changeDetectorRef.reattach();
24532 this._detached = false;
24533 }
24534 this.willEnter.emit(null);
24535 this._lifecycle('WillEnter');
24536 };
24537 /**
24538 * @hidden
24539 * The view has fully entered and is now the active view. This
24540 * will fire, whether it was the first load or loaded from the cache.
24541 * @return {?}
24542 */
24543 ViewController.prototype._didEnter = function () {
24544 (void 0) /* assert */;
24545 this._nb && this._nb.didEnter();
24546 this.didEnter.emit(null);
24547 this._lifecycle('DidEnter');
24548 };
24549 /**
24550 * @hidden
24551 * The view is about to leave and no longer be the active view.
24552 * @param {?} willUnload
24553 * @return {?}
24554 */
24555 ViewController.prototype._willLeave = function (willUnload) {
24556 this.willLeave.emit(null);
24557 this._lifecycle('WillLeave');
24558 if (willUnload && this._onWillDismiss) {
24559 this._onWillDismiss(this._dismissData, this._dismissRole);
24560 this._onWillDismiss = null;
24561 }
24562 };
24563 /**
24564 * @hidden
24565 * The view has finished leaving and is no longer the active view. This
24566 * will fire, whether it is cached or unloaded.
24567 * @return {?}
24568 */
24569 ViewController.prototype._didLeave = function () {
24570 this.didLeave.emit(null);
24571 this._lifecycle('DidLeave');
24572 // when this is not the active page
24573 // we no longer need to detect changes
24574 if (!this._detached && this._cmp) {
24575 this._cmp.changeDetectorRef.detach();
24576 this._detached = true;
24577 }
24578 };
24579 /**
24580 * @hidden
24581 * @return {?}
24582 */
24583 ViewController.prototype._willUnload = function () {
24584 this.willUnload.emit(null);
24585 this._lifecycle('WillUnload');
24586 this._onDidDismiss && this._onDidDismiss(this._dismissData, this._dismissRole);
24587 this._onDidDismiss = null;
24588 this._dismissData = null;
24589 this._dismissRole = null;
24590 };
24591 /**
24592 * @hidden
24593 * DOM WRITE
24594 * @param {?} renderer
24595 * @return {?}
24596 */
24597 ViewController.prototype._destroy = function (renderer) {
24598 (void 0) /* assert */;
24599 if (this._cmp) {
24600 if (renderer) {
24601 // ensure the element is cleaned up for when the view pool reuses this element
24602 // ******** DOM WRITE ****************
24603 var /** @type {?} */ cmpEle = this._cmp.location.nativeElement;
24604 renderer.setElementAttribute(cmpEle, 'class', null);
24605 renderer.setElementAttribute(cmpEle, 'style', null);
24606 }
24607 // completely destroy this component. boom.
24608 this._cmp.destroy();
24609 }
24610 this._nav = this._cmp = this.instance = this._cntDir = this._cntRef = this._leavingOpts = this._hdrDir = this._ftrDir = this._nb = this._onDidDismiss = this._onWillDismiss = null;
24611 this._state = STATE_DESTROYED;
24612 };
24613 /**
24614 * @hidden
24615 * @param {?} lifecycle
24616 * @return {?}
24617 */
24618 ViewController.prototype._lifecycleTest = function (lifecycle) {
24619 var /** @type {?} */ instance = this.instance;
24620 var /** @type {?} */ methodName = 'ionViewCan' + lifecycle;
24621 if (instance && instance[methodName]) {
24622 try {
24623 var /** @type {?} */ result = instance[methodName]();
24624 if (result instanceof Promise) {
24625 return result;
24626 }
24627 else {
24628 // Any value but explitic false, should be true
24629 return Promise.resolve(result !== false);
24630 }
24631 }
24632 catch (e) {
24633 return Promise.reject(this.name + " " + methodName + " error: " + e.message);
24634 }
24635 }
24636 return Promise.resolve(true);
24637 };
24638 /**
24639 * @hidden
24640 * @param {?} lifecycle
24641 * @return {?}
24642 */
24643 ViewController.prototype._lifecycle = function (lifecycle) {
24644 var /** @type {?} */ instance = this.instance;
24645 var /** @type {?} */ methodName = 'ionView' + lifecycle;
24646 if (instance && instance[methodName]) {
24647 instance[methodName]();
24648 }
24649 };
24650 return ViewController;
24651}());
24652ViewController.propDecorators = {
24653 '_emitter': [{ type: Output },],
24654};
24655/**
24656 * @param {?} viewCtrl
24657 * @return {?}
24658 */
24659function isViewController(viewCtrl) {
24660 return !!(viewCtrl && ((viewCtrl))._didLoad && ((viewCtrl))._willUnload);
24661}
24662var DEFAULT_CSS_CLASS = 'ion-page';
24663
24664/**
24665 * @param {?} linker
24666 * @param {?} nameOrPageOrView
24667 * @param {?=} params
24668 * @return {?}
24669 */
24670function getComponent(linker, nameOrPageOrView, params) {
24671 if (typeof nameOrPageOrView === 'function') {
24672 return Promise.resolve(new ViewController(nameOrPageOrView, params));
24673 }
24674 if (typeof nameOrPageOrView === 'string') {
24675 return linker.getComponentFromName(nameOrPageOrView).then(function (component) {
24676 var /** @type {?} */ vc = new ViewController(component, params);
24677 vc.id = nameOrPageOrView;
24678 return vc;
24679 });
24680 }
24681 return Promise.resolve(null);
24682}
24683/**
24684 * @param {?} linker
24685 * @param {?} nameOrPageOrView
24686 * @param {?} params
24687 * @return {?}
24688 */
24689function convertToView(linker, nameOrPageOrView, params) {
24690 if (nameOrPageOrView) {
24691 if (isViewController(nameOrPageOrView)) {
24692 // is already a ViewController
24693 return Promise.resolve(/** @type {?} */ (nameOrPageOrView));
24694 }
24695 return getComponent(linker, nameOrPageOrView, params);
24696 }
24697 return Promise.resolve(null);
24698}
24699/**
24700 * @param {?} linker
24701 * @param {?} pages
24702 * @return {?}
24703 */
24704function convertToViews(linker, pages) {
24705 var /** @type {?} */ views = [];
24706 if (isArray$2(pages)) {
24707 for (var /** @type {?} */ i = 0; i < pages.length; i++) {
24708 var /** @type {?} */ page = pages[i];
24709 if (page) {
24710 if (isViewController(page)) {
24711 views.push(page);
24712 }
24713 else if (page.page) {
24714 views.push(convertToView(linker, page.page, page.params));
24715 }
24716 else {
24717 views.push(convertToView(linker, page, null));
24718 }
24719 }
24720 }
24721 }
24722 return Promise.all(views);
24723}
24724var portalZindex = 9999;
24725/**
24726 * @param {?} nav
24727 * @param {?} enteringView
24728 * @param {?} leavingView
24729 * @param {?} direction
24730 * @param {?} renderer
24731 * @return {?}
24732 */
24733function setZIndex(nav, enteringView, leavingView, direction, renderer) {
24734 if (enteringView) {
24735 if (nav._isPortal) {
24736 if (direction === DIRECTION_FORWARD) {
24737 enteringView._setZIndex(nav._zIndexOffset + portalZindex, renderer);
24738 }
24739 portalZindex++;
24740 return;
24741 }
24742 leavingView = leavingView || nav.getPrevious(enteringView);
24743 if (leavingView && isPresent(leavingView._zIndex)) {
24744 if (direction === DIRECTION_BACK) {
24745 enteringView._setZIndex(leavingView._zIndex - 1, renderer);
24746 }
24747 else {
24748 enteringView._setZIndex(leavingView._zIndex + 1, renderer);
24749 }
24750 }
24751 else {
24752 enteringView._setZIndex(INIT_ZINDEX + nav._zIndexOffset, renderer);
24753 }
24754 }
24755}
24756/**
24757 * @param {?} nav
24758 * @return {?}
24759 */
24760function isTabs(nav) {
24761 // Tabs (ion-tabs)
24762 return !!nav && !!nav.getSelected;
24763}
24764/**
24765 * @param {?} nav
24766 * @return {?}
24767 */
24768function isTab(nav) {
24769 // Tab (ion-tab)
24770 return !!nav && isPresent(nav._tabId);
24771}
24772/**
24773 * @param {?} nav
24774 * @return {?}
24775 */
24776function isNav(nav) {
24777 // Nav (ion-nav), Tab (ion-tab), Portal (ion-portal)
24778 return !!nav && !!nav.push && nav.getType() === 'nav';
24779}
24780/**
24781 * @param {?} navId
24782 * @param {?} type
24783 * @param {?} secondaryId
24784 * @param {?} link
24785 * @return {?}
24786 */
24787
24788/**
24789 * @hidden
24790 */
24791var DeepLinkMetadata = (function () {
24792 function DeepLinkMetadata() {
24793 }
24794 return DeepLinkMetadata;
24795}());
24796/**
24797 * @hidden
24798 */
24799var DeepLinkMetadataFactory;
24800var STATE_NEW = 1;
24801var STATE_INITIALIZED = 2;
24802var STATE_ATTACHED = 3;
24803var STATE_DESTROYED = 4;
24804var INIT_ZINDEX = 100;
24805var DIRECTION_BACK = 'back';
24806var DIRECTION_FORWARD = 'forward';
24807var DIRECTION_SWITCH = 'switch';
24808
24809/**
24810 * \@name MenuController
24811 * \@description
24812 * The MenuController is a provider which makes it easy to control a [Menu](../../Menu/Menu/).
24813 * Its methods can be used to display the menu, enable the menu, toggle the menu, and more.
24814 * The controller will grab a reference to the menu by the `side`, `id`, or, if neither
24815 * of these are passed to it, it will grab the first menu it finds.
24816 *
24817 *
24818 * \@usage
24819 *
24820 * Add a basic menu component to start with. See the [Menu](../../Menu/Menu/) API docs
24821 * for more information on adding menu components.
24822 *
24823 * ```html
24824 * <ion-menu [content]="mycontent">
24825 * <ion-content>
24826 * <ion-list>
24827 * ...
24828 * </ion-list>
24829 * </ion-content>
24830 * </ion-menu>
24831 *
24832 * <ion-nav #mycontent [root]="rootPage"></ion-nav>
24833 * ```
24834 *
24835 * To call the controller methods, inject the `MenuController` provider
24836 * into the page. Then, create some methods for opening, closing, and
24837 * toggling the menu.
24838 *
24839 * ```ts
24840 * import { Component } from '\@angular/core';
24841 * import { MenuController } from 'ionic-angular';
24842 *
24843 * \@Component({...})
24844 * export class MyPage {
24845 *
24846 * constructor(public menuCtrl: MenuController) {
24847 *
24848 * }
24849 *
24850 * openMenu() {
24851 * this.menuCtrl.open();
24852 * }
24853 *
24854 * closeMenu() {
24855 * this.menuCtrl.close();
24856 * }
24857 *
24858 * toggleMenu() {
24859 * this.menuCtrl.toggle();
24860 * }
24861 *
24862 * }
24863 * ```
24864 *
24865 * Since only one menu exists, the `MenuController` will grab the
24866 * correct menu and call the correct method for each.
24867 *
24868 *
24869 * ### Multiple Menus on Different Sides
24870 *
24871 * For applications with both a left and right menu, the desired menu can be
24872 * grabbed by passing the `side` of the menu. If nothing is passed, it will
24873 * default to the `"left"` menu.
24874 *
24875 * ```html
24876 * <ion-menu side="left" [content]="mycontent">...</ion-menu>
24877 * <ion-menu side="right" [content]="mycontent">...</ion-menu>
24878 * <ion-nav #mycontent [root]="rootPage"></ion-nav>
24879 * ```
24880 *
24881 * ```ts
24882 * toggleLeftMenu() {
24883 * this.menuCtrl.toggle();
24884 * }
24885 *
24886 * toggleRightMenu() {
24887 * this.menuCtrl.toggle('right');
24888 * }
24889 * ```
24890 *
24891 *
24892 * ### Multiple Menus on the Same Side
24893 *
24894 * An application can have multiple menus on the same side. In order to determine
24895 * the menu to control, an `id` should be passed. In the example below, the menu
24896 * with the `authenticated` id will be enabled, and the menu with the `unauthenticated`
24897 * id will be disabled.
24898 *
24899 * ```html
24900 * <ion-menu id="authenticated" side="left" [content]="mycontent">...</ion-menu>
24901 * <ion-menu id="unauthenticated" side="left" [content]="mycontent">...</ion-menu>
24902 * <ion-nav #mycontent [root]="rootPage"></ion-nav>
24903 * ```
24904 *
24905 * ```ts
24906 * enableAuthenticatedMenu() {
24907 * this.menuCtrl.enable(true, 'authenticated');
24908 * this.menuCtrl.enable(false, 'unauthenticated');
24909 * }
24910 * ```
24911 *
24912 * Note: if an app only has one menu, there is no reason to pass an `id`.
24913 *
24914 *
24915 * \@demo /docs/demos/src/menu/
24916 *
24917 * @see {\@link /docs/components#menus Menu Component Docs}
24918 * @see {\@link ../Menu Menu API Docs}
24919 *
24920 */
24921var MenuController = (function () {
24922 function MenuController() {
24923 this._menus = [];
24924 }
24925 /**
24926 * Programatically open the Menu.
24927 * @param {?=} menuId
24928 * @return {?}
24929 */
24930 MenuController.prototype.open = function (menuId) {
24931 var /** @type {?} */ menu = this.get(menuId);
24932 if (menu && !this.isAnimating()) {
24933 var /** @type {?} */ openedMenu = this.getOpen();
24934 if (openedMenu && menu !== openedMenu) {
24935 openedMenu.setOpen(false, false);
24936 }
24937 return menu.open();
24938 }
24939 return Promise.resolve(false);
24940 };
24941 /**
24942 * Programatically close the Menu. If no `menuId` is given as the first
24943 * argument then it'll close any menu which is open. If a `menuId`
24944 * is given then it'll close that exact menu.
24945 * @param {?=} menuId
24946 * @return {?}
24947 */
24948 MenuController.prototype.close = function (menuId) {
24949 var /** @type {?} */ menu;
24950 if (menuId) {
24951 // find the menu by its id
24952 menu = this.get(menuId);
24953 }
24954 else {
24955 // find the menu that is open
24956 menu = this.getOpen();
24957 }
24958 if (menu) {
24959 // close the menu
24960 return menu.close();
24961 }
24962 return Promise.resolve(false);
24963 };
24964 /**
24965 * Toggle the menu. If it's closed, it will open, and if opened, it
24966 * will close.
24967 * @param {?=} menuId
24968 * @return {?}
24969 */
24970 MenuController.prototype.toggle = function (menuId) {
24971 var /** @type {?} */ menu = this.get(menuId);
24972 if (menu && !this.isAnimating()) {
24973 var /** @type {?} */ openedMenu = this.getOpen();
24974 if (openedMenu && menu !== openedMenu) {
24975 openedMenu.setOpen(false, false);
24976 }
24977 return menu.toggle();
24978 }
24979 return Promise.resolve(false);
24980 };
24981 /**
24982 * Used to enable or disable a menu. For example, there could be multiple
24983 * left menus, but only one of them should be able to be opened at the same
24984 * time. If there are multiple menus on the same side, then enabling one menu
24985 * will also automatically disable all the others that are on the same side.
24986 * @param {?} shouldEnable
24987 * @param {?=} menuId
24988 * @return {?}
24989 */
24990 MenuController.prototype.enable = function (shouldEnable, menuId) {
24991 var /** @type {?} */ menu = this.get(menuId);
24992 if (menu) {
24993 return menu.enable(shouldEnable);
24994 }
24995 };
24996 /**
24997 * Used to enable or disable the ability to swipe open the menu.
24998 * @param {?} shouldEnable
24999 * @param {?=} menuId
25000 * @return {?}
25001 */
25002 MenuController.prototype.swipeEnable = function (shouldEnable, menuId) {
25003 var /** @type {?} */ menu = this.get(menuId);
25004 if (menu) {
25005 return menu.swipeEnable(shouldEnable);
25006 }
25007 };
25008 /**
25009 * If the menuId is not specified, it returns true if ANY menu is currenly open.
25010 * @param {?=} menuId
25011 * @return {?}
25012 */
25013 MenuController.prototype.isOpen = function (menuId) {
25014 if (menuId) {
25015 var /** @type {?} */ menu = this.get(menuId);
25016 return menu && menu.isOpen || false;
25017 }
25018 else {
25019 return !!this.getOpen();
25020 }
25021 };
25022 /**
25023 * @param {?=} menuId
25024 * @return {?}
25025 */
25026 MenuController.prototype.isEnabled = function (menuId) {
25027 var /** @type {?} */ menu = this.get(menuId);
25028 return menu && menu.enabled || false;
25029 };
25030 /**
25031 * Used to get a menu instance. If a `menuId` is not provided then it'll
25032 * return the first menu found. If a `menuId` is `left` or `right`, then
25033 * it'll return the enabled menu on that side. Otherwise, if a `menuId` is
25034 * provided, then it'll try to find the menu using the menu's `id`
25035 * property. If a menu is not found then it'll return `null`.
25036 * @param {?=} menuId
25037 * @return {?}
25038 */
25039 MenuController.prototype.get = function (menuId) {
25040 var /** @type {?} */ menu;
25041 if (menuId === 'left' || menuId === 'right') {
25042 // there could be more than one menu on the same side
25043 // so first try to get the enabled one
25044 menu = this._menus.find(function (m) { return m.side === menuId && m.enabled; });
25045 if (menu) {
25046 return menu;
25047 }
25048 // didn't find a menu side that is enabled
25049 // so try to get the first menu side found
25050 return this._menus.find(function (m) { return m.side === menuId; }) || null;
25051 }
25052 else if (menuId) {
25053 // the menuId was not left or right
25054 // so try to get the menu by its "id"
25055 return this._menus.find(function (m) { return m.id === menuId; }) || null;
25056 }
25057 // return the first enabled menu
25058 menu = this._menus.find(function (m) { return m.enabled; });
25059 if (menu) {
25060 return menu;
25061 }
25062 // get the first menu in the array, if one exists
25063 return (this._menus.length ? this._menus[0] : null);
25064 };
25065 /**
25066 * @return {?}
25067 */
25068 MenuController.prototype.getOpen = function () {
25069 return this._menus.find(function (m) { return m.isOpen; });
25070 };
25071 /**
25072 * @return {?}
25073 */
25074 MenuController.prototype.getMenus = function () {
25075 return this._menus;
25076 };
25077 /**
25078 * @hidden
25079 * @return {?}
25080 */
25081 MenuController.prototype.isAnimating = function () {
25082 return this._menus.some(function (menu) { return menu.isAnimating(); });
25083 };
25084 /**
25085 * @hidden
25086 * @param {?} menu
25087 * @return {?}
25088 */
25089 MenuController.prototype._register = function (menu) {
25090 (void 0) /* assert */;
25091 this._menus.push(menu);
25092 };
25093 /**
25094 * @hidden
25095 * @param {?} menu
25096 * @return {?}
25097 */
25098 MenuController.prototype._unregister = function (menu) {
25099 (void 0) /* assert */;
25100 removeArrayItem(this._menus, menu);
25101 };
25102 /**
25103 * @hidden
25104 * @param {?} menu
25105 * @return {?}
25106 */
25107 MenuController.prototype._setActiveMenu = function (menu) {
25108 (void 0) /* assert */;
25109 (void 0) /* assert */;
25110 // if this menu should be enabled
25111 // then find all the other menus on this same side
25112 // and automatically disable other same side menus
25113 var /** @type {?} */ side = menu.side;
25114 this._menus
25115 .filter(function (m) { return m.side === side && m !== menu; })
25116 .map(function (m) { return m.enable(false); });
25117 };
25118 /**
25119 * @hidden
25120 * @param {?} name
25121 * @param {?} cls
25122 * @return {?}
25123 */
25124 MenuController.registerType = function (name, cls) {
25125 menuTypes[name] = cls;
25126 };
25127 /**
25128 * @hidden
25129 * @param {?} type
25130 * @param {?} menuCmp
25131 * @param {?} plt
25132 * @return {?}
25133 */
25134 MenuController.create = function (type, menuCmp, plt) {
25135 return new menuTypes[type](menuCmp, plt);
25136 };
25137 return MenuController;
25138}());
25139var menuTypes = {};
25140
25141/**
25142 * @param {?} docEle
25143 * @return {?}
25144 */
25145function getCss(docEle) {
25146 var /** @type {?} */ css = {};
25147 // transform
25148 var /** @type {?} */ i;
25149 var /** @type {?} */ keys = ['webkitTransform', '-webkit-transform', 'webkit-transform', 'transform'];
25150 for (i = 0; i < keys.length; i++) {
25151 if (((docEle.style))[keys[i]] !== undefined) {
25152 css.transform = keys[i];
25153 break;
25154 }
25155 }
25156 // transition
25157 keys = ['webkitTransition', 'transition'];
25158 for (i = 0; i < keys.length; i++) {
25159 if (((docEle.style))[keys[i]] !== undefined) {
25160 css.transition = keys[i];
25161 break;
25162 }
25163 }
25164 // The only prefix we care about is webkit for transitions.
25165 var /** @type {?} */ isWebkit = css.transition.indexOf('webkit') > -1;
25166 // transition duration
25167 css.transitionDuration = (isWebkit ? '-webkit-' : '') + 'transition-duration';
25168 // transition timing function
25169 css.transitionTimingFn = (isWebkit ? '-webkit-' : '') + 'transition-timing-function';
25170 // transition delay
25171 css.transitionDelay = (isWebkit ? '-webkit-' : '') + 'transition-delay';
25172 // To be sure transitionend works everywhere, include *both* the webkit and non-webkit events
25173 css.transitionEnd = (isWebkit ? 'webkitTransitionEnd ' : '') + 'transitionend';
25174 // transform origin
25175 css.transformOrigin = (isWebkit ? '-webkit-' : '') + 'transform-origin';
25176 // animation delay
25177 css.animationDelay = (isWebkit ? 'webkitAnimationDelay' : 'animationDelay');
25178 return css;
25179}
25180/**
25181 * @param {?} ev
25182 * @return {?}
25183 */
25184function pointerCoord(ev) {
25185 // get coordinates for either a mouse click
25186 // or a touch depending on the given event
25187 if (ev) {
25188 var /** @type {?} */ changedTouches = ev.changedTouches;
25189 if (changedTouches && changedTouches.length > 0) {
25190 var /** @type {?} */ touch = changedTouches[0];
25191 return { x: touch.clientX, y: touch.clientY };
25192 }
25193 var /** @type {?} */ pageX = ev.pageX;
25194 if (pageX !== undefined) {
25195 return { x: pageX, y: ev.pageY };
25196 }
25197 }
25198 return { x: 0, y: 0 };
25199}
25200/**
25201 * @param {?} threshold
25202 * @param {?} startCoord
25203 * @param {?} endCoord
25204 * @return {?}
25205 */
25206function hasPointerMoved(threshold, startCoord, endCoord) {
25207 if (startCoord && endCoord) {
25208 var /** @type {?} */ deltaX = (startCoord.x - endCoord.x);
25209 var /** @type {?} */ deltaY = (startCoord.y - endCoord.y);
25210 var /** @type {?} */ distance = deltaX * deltaX + deltaY * deltaY;
25211 return distance > (threshold * threshold);
25212 }
25213 return false;
25214}
25215/**
25216 * @param {?} ele
25217 * @return {?}
25218 */
25219function isTextInput(ele) {
25220 return !!ele &&
25221 (ele.tagName === 'TEXTAREA' ||
25222 ele.contentEditable === 'true' ||
25223 (ele.tagName === 'INPUT' && !(NON_TEXT_INPUT_REGEX.test(ele.type))));
25224}
25225var NON_TEXT_INPUT_REGEX = /^(radio|checkbox|range|file|submit|reset|color|image|button)$/i;
25226var SKIP_INPUT_ATTR = ['value', 'checked', 'disabled', 'readonly', 'placeholder', 'type', 'class', 'style', 'id', 'autofocus', 'autocomplete', 'autocorrect'];
25227/**
25228 * @param {?} srcElement
25229 * @param {?} destElement
25230 * @return {?}
25231 */
25232function copyInputAttributes(srcElement, destElement) {
25233 // copy attributes from one element to another
25234 // however, skip over a few of them as they're already
25235 // handled in the angular world
25236 var /** @type {?} */ attrs = srcElement.attributes;
25237 for (var /** @type {?} */ i = 0; i < attrs.length; i++) {
25238 var /** @type {?} */ attr = attrs[i];
25239 if (SKIP_INPUT_ATTR.indexOf(attr.name) === -1) {
25240 destElement.setAttribute(attr.name, attr.value);
25241 }
25242 }
25243}
25244
25245/**
25246 * @hidden
25247 */
25248var QueryParams = (function () {
25249 function QueryParams() {
25250 this.data = {};
25251 }
25252 /**
25253 * @param {?} url
25254 * @return {?}
25255 */
25256 QueryParams.prototype.parseUrl = function (url) {
25257 if (url) {
25258 var /** @type {?} */ startIndex = url.indexOf('?');
25259 if (startIndex > -1) {
25260 var /** @type {?} */ queries = url.slice(startIndex + 1).split('&');
25261 for (var /** @type {?} */ i = 0; i < queries.length; i++) {
25262 if (queries[i].indexOf('=') > 0) {
25263 var /** @type {?} */ split = queries[i].split('=');
25264 if (split.length > 1) {
25265 this.data[split[0].toLowerCase()] = split[1].split('#')[0];
25266 }
25267 }
25268 }
25269 }
25270 }
25271 };
25272 /**
25273 * @param {?} key
25274 * @return {?}
25275 */
25276 QueryParams.prototype.get = function (key) {
25277 return this.data[key.toLowerCase()];
25278 };
25279 return QueryParams;
25280}());
25281
25282/**
25283 * \@name Platform
25284 * \@description
25285 * The Platform service can be used to get information about your current device.
25286 * You can get all of the platforms associated with the device using the [platforms](#platforms)
25287 * method, including whether the app is being viewed from a tablet, if it's
25288 * on a mobile device or browser, and the exact platform (iOS, Android, etc).
25289 * You can also get the orientation of the device, if it uses right-to-left
25290 * language direction, and much much more. With this information you can completely
25291 * customize your app to fit any device.
25292 *
25293 * \@usage
25294 * ```ts
25295 * import { Platform } from 'ionic-angular';
25296 *
25297 * \@Component({...})
25298 * export MyPage {
25299 * constructor(public platform: Platform) {
25300 *
25301 * }
25302 * }
25303 * ```
25304 * \@demo /docs/demos/src/platform/
25305 */
25306var Platform = (function () {
25307 function Platform() {
25308 var _this = this;
25309 this._versions = {};
25310 this._qp = new QueryParams();
25311 this._bbActions = [];
25312 this._pW = 0;
25313 this._pH = 0;
25314 this._lW = 0;
25315 this._lH = 0;
25316 this._isPortrait = null;
25317 this._uiEvtOpts = false;
25318 /**
25319 * \@internal
25320 */
25321 this._platforms = [];
25322 /**
25323 * @hidden
25324 */
25325 this.backButton = new EventEmitter();
25326 /**
25327 * The pause event emits when the native platform puts the application
25328 * into the background, typically when the user switches to a different
25329 * application. This event would emit when a Cordova app is put into
25330 * the background, however, it would not fire on a standard web browser.
25331 */
25332 this.pause = new EventEmitter();
25333 /**
25334 * The resume event emits when the native platform pulls the application
25335 * out from the background. This event would emit when a Cordova app comes
25336 * out from the background, however, it would not fire on a standard web browser.
25337 */
25338 this.resume = new EventEmitter();
25339 /**
25340 * The resize event emits when the native platform pulls the application
25341 * out from the background. This event would emit when a Cordova app comes
25342 * out from the background, however, it would not fire on a standard web browser.
25343 */
25344 this.resize = new EventEmitter();
25345 this._readyPromise = new Promise(function (res) { _this._readyResolve = res; });
25346 this.backButton.subscribe(function () {
25347 // the hardware back button event has been fired
25348 (void 0) /* console.debug */;
25349 // decide which backbutton action should run
25350 _this.runBackButtonAction();
25351 });
25352 }
25353 /**
25354 * @hidden
25355 * @param {?} win
25356 * @return {?}
25357 */
25358 Platform.prototype.setWindow = function (win) {
25359 this._win = win;
25360 };
25361 /**
25362 * @hidden
25363 * @return {?}
25364 */
25365 Platform.prototype.win = function () {
25366 return this._win;
25367 };
25368 /**
25369 * @hidden
25370 * @param {?} doc
25371 * @return {?}
25372 */
25373 Platform.prototype.setDocument = function (doc) {
25374 this._doc = doc;
25375 };
25376 /**
25377 * @hidden
25378 * @return {?}
25379 */
25380 Platform.prototype.doc = function () {
25381 return this._doc;
25382 };
25383 /**
25384 * @hidden
25385 * @param {?} zone
25386 * @return {?}
25387 */
25388 Platform.prototype.setZone = function (zone) {
25389 this.zone = zone;
25390 };
25391 /**
25392 * @hidden
25393 * @param {?} docElement
25394 * @return {?}
25395 */
25396 Platform.prototype.setCssProps = function (docElement) {
25397 this.Css = getCss(docElement);
25398 };
25399 /**
25400 * \@description
25401 * Depending on the platform the user is on, `is(platformName)` will
25402 * return `true` or `false`. Note that the same app can return `true`
25403 * for more than one platform name. For example, an app running from
25404 * an iPad would return `true` for the platform names: `mobile`,
25405 * `ios`, `ipad`, and `tablet`. Additionally, if the app was running
25406 * from Cordova then `cordova` would be true, and if it was running
25407 * from a web browser on the iPad then `mobileweb` would be `true`.
25408 *
25409 * ```
25410 * import { Platform } from 'ionic-angular';
25411 *
25412 * \@Component({...})
25413 * export MyPage {
25414 * constructor(public platform: Platform) {
25415 * if (this.platform.is('ios')) {
25416 * // This will only print when on iOS
25417 * console.log('I am an iOS device!');
25418 * }
25419 * }
25420 * }
25421 * ```
25422 *
25423 * | Platform Name | Description |
25424 * |-----------------|------------------------------------|
25425 * | android | on a device running Android. |
25426 * | cordova | on a device running Cordova. |
25427 * | core | on a desktop device. |
25428 * | ios | on a device running iOS. |
25429 * | ipad | on an iPad device. |
25430 * | iphone | on an iPhone device. |
25431 * | mobile | on a mobile device. |
25432 * | mobileweb | in a browser on a mobile device. |
25433 * | phablet | on a phablet device. |
25434 * | tablet | on a tablet device. |
25435 * | windows | on a device running Windows. |
25436 *
25437 * @param {?} platformName
25438 * @return {?}
25439 */
25440 Platform.prototype.is = function (platformName) {
25441 return (this._platforms.indexOf(platformName) > -1);
25442 };
25443 /**
25444 * \@description
25445 * Depending on what device you are on, `platforms` can return multiple values.
25446 * Each possible value is a hierarchy of platforms. For example, on an iPhone,
25447 * it would return `mobile`, `ios`, and `iphone`.
25448 *
25449 * ```
25450 * import { Platform } from 'ionic-angular';
25451 *
25452 * \@Component({...})
25453 * export MyPage {
25454 * constructor(public platform: Platform) {
25455 * // This will print an array of the current platforms
25456 * console.log(this.platform.platforms());
25457 * }
25458 * }
25459 * ```
25460 * @return {?}
25461 */
25462 Platform.prototype.platforms = function () {
25463 // get the array of active platforms, which also knows the hierarchy,
25464 // with the last one the most important
25465 return this._platforms;
25466 };
25467 /**
25468 * Returns an object containing version information about all of the platforms.
25469 *
25470 * ```
25471 * import { Platform } from 'ionic-angular';
25472 *
25473 * \@Component({...})
25474 * export MyPage {
25475 * constructor(public platform: Platform) {
25476 * // This will print an object containing
25477 * // all of the platforms and their versions
25478 * console.log(platform.versions());
25479 * }
25480 * }
25481 * ```
25482 *
25483 * @return {?}
25484 */
25485 Platform.prototype.versions = function () {
25486 // get all the platforms that have a valid parsed version
25487 return this._versions;
25488 };
25489 /**
25490 * @hidden
25491 * @return {?}
25492 */
25493 Platform.prototype.version = function () {
25494 for (var /** @type {?} */ platformName in this._versions) {
25495 if (this._versions[platformName]) {
25496 return this._versions[platformName];
25497 }
25498 }
25499 return {};
25500 };
25501 /**
25502 * Returns a promise when the platform is ready and native functionality
25503 * can be called. If the app is running from within a web browser, then
25504 * the promise will resolve when the DOM is ready. When the app is running
25505 * from an application engine such as Cordova, then the promise will
25506 * resolve when Cordova triggers the `deviceready` event.
25507 *
25508 * The resolved value is the `readySource`, which states which platform
25509 * ready was used. For example, when Cordova is ready, the resolved ready
25510 * source is `cordova`. The default ready source value will be `dom`. The
25511 * `readySource` is useful if different logic should run depending on the
25512 * platform the app is running from. For example, only Cordova can execute
25513 * the status bar plugin, so the web should not run status bar plugin logic.
25514 *
25515 * ```
25516 * import { Component } from '\@angular/core';
25517 * import { Platform } from 'ionic-angular';
25518 *
25519 * \@Component({...})
25520 * export MyApp {
25521 * constructor(public platform: Platform) {
25522 * this.platform.ready().then((readySource) => {
25523 * console.log('Platform ready from', readySource);
25524 * // Platform now ready, execute any required native code
25525 * });
25526 * }
25527 * }
25528 * ```
25529 * @return {?}
25530 */
25531 Platform.prototype.ready = function () {
25532 return this._readyPromise;
25533 };
25534 /**
25535 * @hidden
25536 * This should be triggered by the engine when the platform is
25537 * ready. If there was no custom prepareReady method from the engine,
25538 * such as Cordova or Electron, then it uses the default DOM ready.
25539 * @param {?} readySource
25540 * @return {?}
25541 */
25542 Platform.prototype.triggerReady = function (readySource) {
25543 var _this = this;
25544 this.zone.run(function () {
25545 _this._readyResolve(readySource);
25546 });
25547 };
25548 /**
25549 * @hidden
25550 * This is the default prepareReady if it's not replaced by an engine,
25551 * such as Cordova or Electron. If there was no custom prepareReady
25552 * method from an engine then it uses the method below, which triggers
25553 * the platform ready on the DOM ready event, and the default resolved
25554 * value is `dom`.
25555 * @return {?}
25556 */
25557 Platform.prototype.prepareReady = function () {
25558 var /** @type {?} */ self = this;
25559 if (self._doc.readyState === 'complete' || self._doc.readyState === 'interactive') {
25560 self.triggerReady('dom');
25561 }
25562 else {
25563 self._doc.addEventListener('DOMContentLoaded', completed, false);
25564 self._win.addEventListener('load', completed, false);
25565 }
25566 /**
25567 * @return {?}
25568 */
25569 function completed() {
25570 self._doc.removeEventListener('DOMContentLoaded', completed, false);
25571 self._win.removeEventListener('load', completed, false);
25572 self.triggerReady('dom');
25573 }
25574 };
25575 /**
25576 * Set the app's language direction, which will update the `dir` attribute
25577 * on the app's root `<html>` element. We recommend the app's `index.html`
25578 * file already has the correct `dir` attribute value set, such as
25579 * `<html dir="ltr">` or `<html dir="rtl">`. This method is useful if the
25580 * direction needs to be dynamically changed per user/session.
25581 * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
25582 * @param {?} dir
25583 * @param {?} updateDocument
25584 * @return {?}
25585 */
25586 Platform.prototype.setDir = function (dir, updateDocument) {
25587 this._dir = dir;
25588 this.isRTL = (dir === 'rtl');
25589 if (updateDocument !== false) {
25590 this._doc['documentElement'].setAttribute('dir', dir);
25591 }
25592 };
25593 /**
25594 * Returns app's language direction.
25595 * We recommend the app's `index.html` file already has the correct `dir`
25596 * attribute value set, such as `<html dir="ltr">` or `<html dir="rtl">`.
25597 * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
25598 * @return {?}
25599 */
25600 Platform.prototype.dir = function () {
25601 return this._dir;
25602 };
25603 /**
25604 * Set the app's language and optionally the country code, which will update
25605 * the `lang` attribute on the app's root `<html>` element.
25606 * We recommend the app's `index.html` file already has the correct `lang`
25607 * attribute value set, such as `<html lang="en">`. This method is useful if
25608 * the language needs to be dynamically changed per user/session.
25609 * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
25610 * @param {?} language
25611 * @param {?} updateDocument
25612 * @return {?}
25613 */
25614 Platform.prototype.setLang = function (language, updateDocument) {
25615 this._lang = language;
25616 if (updateDocument !== false) {
25617 this._doc['documentElement'].setAttribute('lang', language);
25618 }
25619 };
25620 /**
25621 * Returns app's language and optional country code.
25622 * We recommend the app's `index.html` file already has the correct `lang`
25623 * attribute value set, such as `<html lang="en">`.
25624 * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
25625 * @return {?}
25626 */
25627 Platform.prototype.lang = function () {
25628 return this._lang;
25629 };
25630 /**
25631 * @hidden
25632 * @return {?}
25633 */
25634 Platform.prototype.exitApp = function () { };
25635 /**
25636 * The back button event is triggered when the user presses the native
25637 * platform's back button, also referred to as the "hardware" back button.
25638 * This event is only used within Cordova apps running on Android and
25639 * Windows platforms. This event is not fired on iOS since iOS doesn't come
25640 * with a hardware back button in the same sense an Android or Windows device
25641 * does.
25642 *
25643 * Registering a hardware back button action and setting a priority allows
25644 * apps to control which action should be called when the hardware back
25645 * button is pressed. This method decides which of the registered back button
25646 * actions has the highest priority and should be called.
25647 *
25648 * if this registered action has the highest priority.
25649 * the back button action.
25650 * @param {?} fn
25651 * @param {?=} priority
25652 * @return {?}
25653 */
25654 Platform.prototype.registerBackButtonAction = function (fn, priority) {
25655 var _this = this;
25656 if (priority === void 0) { priority = 0; }
25657 var /** @type {?} */ action = { fn: fn, priority: priority };
25658 this._bbActions.push(action);
25659 // return a function to unregister this back button action
25660 return function () {
25661 removeArrayItem(_this._bbActions, action);
25662 };
25663 };
25664 /**
25665 * @hidden
25666 * @return {?}
25667 */
25668 Platform.prototype.runBackButtonAction = function () {
25669 // decide which one back button action should run
25670 var /** @type {?} */ winner = null;
25671 this._bbActions.forEach(function (action) {
25672 if (!winner || action.priority >= winner.priority) {
25673 winner = action;
25674 }
25675 });
25676 // run the winning action if there is one
25677 winner && winner.fn && winner.fn();
25678 };
25679 /**
25680 * @hidden
25681 * @param {?} userAgent
25682 * @return {?}
25683 */
25684 Platform.prototype.setUserAgent = function (userAgent) {
25685 this._ua = userAgent;
25686 };
25687 /**
25688 * @hidden
25689 * @param {?} url
25690 * @return {?}
25691 */
25692 Platform.prototype.setQueryParams = function (url) {
25693 this._qp.parseUrl(url);
25694 };
25695 /**
25696 * Get the query string parameter
25697 * @param {?} key
25698 * @return {?}
25699 */
25700 Platform.prototype.getQueryParam = function (key) {
25701 return this._qp.get(key);
25702 };
25703 /**
25704 * Get the current url.
25705 * @return {?}
25706 */
25707 Platform.prototype.url = function () {
25708 return this._win['location']['href'];
25709 };
25710 /**
25711 * @hidden
25712 * @return {?}
25713 */
25714 Platform.prototype.userAgent = function () {
25715 return this._ua || '';
25716 };
25717 /**
25718 * @hidden
25719 * @param {?} navigatorPlt
25720 * @return {?}
25721 */
25722 Platform.prototype.setNavigatorPlatform = function (navigatorPlt) {
25723 this._nPlt = navigatorPlt;
25724 };
25725 /**
25726 * @hidden
25727 * @return {?}
25728 */
25729 Platform.prototype.navigatorPlatform = function () {
25730 return this._nPlt || '';
25731 };
25732 /**
25733 * Gets the width of the platform's viewport using `window.innerWidth`.
25734 * Using this method is preferred since the dimension is a cached value,
25735 * which reduces the chance of multiple and expensive DOM reads.
25736 * @return {?}
25737 */
25738 Platform.prototype.width = function () {
25739 this._calcDim();
25740 return this._isPortrait ? this._pW : this._lW;
25741 };
25742 /**
25743 * Gets the height of the platform's viewport using `window.innerHeight`.
25744 * Using this method is preferred since the dimension is a cached value,
25745 * which reduces the chance of multiple and expensive DOM reads.
25746 * @return {?}
25747 */
25748 Platform.prototype.height = function () {
25749 this._calcDim();
25750 return this._isPortrait ? this._pH : this._lH;
25751 };
25752 /**
25753 * @hidden
25754 * @param {?} ele
25755 * @param {?=} pseudoEle
25756 * @return {?}
25757 */
25758 Platform.prototype.getElementComputedStyle = function (ele, pseudoEle) {
25759 return this._win['getComputedStyle'](ele, pseudoEle);
25760 };
25761 /**
25762 * @hidden
25763 * @param {?} x
25764 * @param {?} y
25765 * @return {?}
25766 */
25767 Platform.prototype.getElementFromPoint = function (x, y) {
25768 return (this._doc['elementFromPoint'](x, y));
25769 };
25770 /**
25771 * @hidden
25772 * @param {?} ele
25773 * @return {?}
25774 */
25775 Platform.prototype.getElementBoundingClientRect = function (ele) {
25776 return ele['getBoundingClientRect']();
25777 };
25778 /**
25779 * Returns `true` if the app is in portait mode.
25780 * @return {?}
25781 */
25782 Platform.prototype.isPortrait = function () {
25783 this._calcDim();
25784 return this._isPortrait;
25785 };
25786 /**
25787 * Returns `true` if the app is in landscape mode.
25788 * @return {?}
25789 */
25790 Platform.prototype.isLandscape = function () {
25791 return !this.isPortrait();
25792 };
25793 /**
25794 * @return {?}
25795 */
25796 Platform.prototype._calcDim = function () {
25797 // we're caching window dimensions so that
25798 // we're not forcing many layouts
25799 // if _isPortrait is null then that means
25800 // the dimensions needs to be looked up again
25801 // this also has to cover an edge case that only
25802 // happens on iOS 10 (not other versions of iOS)
25803 // where window.innerWidth is always bigger than
25804 // window.innerHeight when it is first measured,
25805 // even when the device is in portrait but
25806 // the second time it is measured it is correct.
25807 // Hopefully this check will not be needed in the future
25808 if (this._isPortrait === null || this._isPortrait === false && this._win['innerWidth'] < this._win['innerHeight']) {
25809 var /** @type {?} */ win = this._win;
25810 var /** @type {?} */ innerWidth = win['innerWidth'];
25811 var /** @type {?} */ innerHeight = win['innerHeight'];
25812 // we're keeping track of portrait and landscape dimensions
25813 // separately because the virtual keyboard can really mess
25814 // up accurate values when the keyboard is up
25815 if (win.screen.width > 0 && win.screen.height > 0) {
25816 if (innerWidth < innerHeight) {
25817 // the device is in portrait
25818 // we have to do fancier checking here
25819 // because of the virtual keyboard resizing
25820 // the window
25821 if (this._pW <= innerWidth) {
25822 (void 0) /* console.debug */;
25823 this._isPortrait = true;
25824 this._pW = innerWidth;
25825 }
25826 if (this._pH <= innerHeight) {
25827 (void 0) /* console.debug */;
25828 this._isPortrait = true;
25829 this._pH = innerHeight;
25830 }
25831 }
25832 else {
25833 // the device is in landscape
25834 if (this._lW !== innerWidth) {
25835 (void 0) /* console.debug */;
25836 this._isPortrait = false;
25837 this._lW = innerWidth;
25838 }
25839 if (this._lH !== innerHeight) {
25840 (void 0) /* console.debug */;
25841 this._isPortrait = false;
25842 this._lH = innerHeight;
25843 }
25844 }
25845 }
25846 }
25847 };
25848 /**
25849 * @hidden
25850 * This requestAnimationFrame will NOT be wrapped by zone.
25851 * @param {?} callback
25852 * @return {?}
25853 */
25854 Platform.prototype.raf = function (callback) {
25855 var /** @type {?} */ win = this._win;
25856 return win['__zone_symbol__requestAnimationFrame'](callback);
25857 };
25858 /**
25859 * @hidden
25860 * @param {?} rafId
25861 * @return {?}
25862 */
25863 Platform.prototype.cancelRaf = function (rafId) {
25864 var /** @type {?} */ win = this._win;
25865 return win['__zone_symbol__cancelAnimationFrame'](rafId);
25866 };
25867 /**
25868 * @hidden
25869 * This setTimeout will NOT be wrapped by zone.
25870 * @param {?} callback
25871 * @param {?=} timeout
25872 * @return {?}
25873 */
25874 Platform.prototype.timeout = function (callback, timeout) {
25875 var /** @type {?} */ win = this._win;
25876 return win['__zone_symbol__setTimeout'](callback, timeout);
25877 };
25878 /**
25879 * @hidden
25880 * This setTimeout will NOT be wrapped by zone.
25881 * @param {?} timeoutId
25882 * @return {?}
25883 */
25884 Platform.prototype.cancelTimeout = function (timeoutId) {
25885 var /** @type {?} */ win = this._win;
25886 win['__zone_symbol__clearTimeout'](timeoutId);
25887 };
25888 /**
25889 * @hidden
25890 * Built to use modern event listener options, like "passive".
25891 * If options are not supported, then just return a boolean which
25892 * represents "capture". Returns a method to remove the listener.
25893 * @param {?} ele
25894 * @param {?} eventName
25895 * @param {?} callback
25896 * @param {?} opts
25897 * @param {?=} unregisterListenersCollection
25898 * @return {?}
25899 */
25900 Platform.prototype.registerListener = function (ele, eventName, callback, opts, unregisterListenersCollection) {
25901 // use event listener options when supported
25902 // otherwise it's just a boolean for the "capture" arg
25903 var /** @type {?} */ listenerOpts = this._uiEvtOpts ? {
25904 'capture': !!opts.capture,
25905 'passive': !!opts.passive,
25906 } : !!opts.capture;
25907 var /** @type {?} */ unReg;
25908 if (!opts.zone && ele['__zone_symbol__addEventListener']) {
25909 // do not wrap this event in zone and we've verified we can use the raw addEventListener
25910 ele['__zone_symbol__addEventListener'](eventName, callback, listenerOpts);
25911 unReg = function unregisterListener() {
25912 ele['__zone_symbol__removeEventListener'](eventName, callback, listenerOpts);
25913 };
25914 }
25915 else {
25916 // use the native addEventListener, which is wrapped with zone
25917 ele['addEventListener'](eventName, callback, listenerOpts);
25918 unReg = function unregisterListener() {
25919 ele['removeEventListener'](eventName, callback, listenerOpts);
25920 };
25921 }
25922 if (unregisterListenersCollection) {
25923 unregisterListenersCollection.push(unReg);
25924 }
25925 return unReg;
25926 };
25927 /**
25928 * @hidden
25929 * @param {?} el
25930 * @param {?} callback
25931 * @param {?=} zone
25932 * @return {?}
25933 */
25934 Platform.prototype.transitionEnd = function (el, callback, zone) {
25935 if (zone === void 0) { zone = true; }
25936 var /** @type {?} */ unRegs = [];
25937 /**
25938 * @return {?}
25939 */
25940 function unregister() {
25941 unRegs.forEach(function (unReg) {
25942 unReg();
25943 });
25944 }
25945 /**
25946 * @param {?} ev
25947 * @return {?}
25948 */
25949 function onTransitionEnd(ev) {
25950 if (el === ev.target) {
25951 unregister();
25952 callback(ev);
25953 }
25954 }
25955 if (el) {
25956 this.registerListener(el, 'webkitTransitionEnd', /** @type {?} */ (onTransitionEnd), { zone: zone }, unRegs);
25957 this.registerListener(el, 'transitionend', /** @type {?} */ (onTransitionEnd), { zone: zone }, unRegs);
25958 }
25959 return unregister;
25960 };
25961 /**
25962 * @hidden
25963 * @param {?} callback
25964 * @return {?}
25965 */
25966 Platform.prototype.windowLoad = function (callback) {
25967 var /** @type {?} */ win = this._win;
25968 var /** @type {?} */ doc = this._doc;
25969 var /** @type {?} */ unreg;
25970 if (doc.readyState === 'complete') {
25971 callback(win, doc);
25972 }
25973 else {
25974 unreg = this.registerListener(win, 'load', function () {
25975 unreg && unreg();
25976 callback(win, doc);
25977 }, { zone: false });
25978 }
25979 };
25980 /**
25981 * @hidden
25982 * @param {?} ele
25983 * @return {?}
25984 */
25985 Platform.prototype.isActiveElement = function (ele) {
25986 return !!(ele && (this.getActiveElement() === ele));
25987 };
25988 /**
25989 * @hidden
25990 * @return {?}
25991 */
25992 Platform.prototype.getActiveElement = function () {
25993 return this._doc['activeElement'];
25994 };
25995 /**
25996 * @hidden
25997 * @param {?} ele
25998 * @return {?}
25999 */
26000 Platform.prototype.hasFocus = function (ele) {
26001 return !!((ele && (this.getActiveElement() === ele)) && (ele.parentElement.querySelector(':focus') === ele));
26002 };
26003 /**
26004 * @hidden
26005 * @return {?}
26006 */
26007 Platform.prototype.hasFocusedTextInput = function () {
26008 var /** @type {?} */ ele = this.getActiveElement();
26009 if (isTextInput(ele)) {
26010 return (ele.parentElement.querySelector(':focus') === ele);
26011 }
26012 return false;
26013 };
26014 /**
26015 * @hidden
26016 * @return {?}
26017 */
26018 Platform.prototype.focusOutActiveElement = function () {
26019 var /** @type {?} */ activeElement = this.getActiveElement();
26020 activeElement && activeElement.blur && activeElement.blur();
26021 };
26022 /**
26023 * @return {?}
26024 */
26025 Platform.prototype._initEvents = function () {
26026 var _this = this;
26027 // Test via a getter in the options object to see if the passive property is accessed
26028 try {
26029 var /** @type {?} */ opts = Object.defineProperty({}, 'passive', {
26030 get: function () {
26031 _this._uiEvtOpts = true;
26032 }
26033 });
26034 this._win.addEventListener('optsTest', null, opts);
26035 }
26036 catch (e) { }
26037 // add the window resize event listener XXms after
26038 this.timeout(function () {
26039 var /** @type {?} */ timerId;
26040 _this.registerListener(_this._win, 'resize', function () {
26041 clearTimeout(timerId);
26042 timerId = setTimeout(function () {
26043 // setting _isPortrait to null means the
26044 // dimensions will need to be looked up again
26045 if (_this.hasFocusedTextInput() === false) {
26046 _this._isPortrait = null;
26047 }
26048 _this.zone.run(function () { return _this.resize.emit(); });
26049 }, 200);
26050 }, { passive: true, zone: false });
26051 }, 2000);
26052 };
26053 /**
26054 * @hidden
26055 * @param {?} platformConfigs
26056 * @return {?}
26057 */
26058 Platform.prototype.setPlatformConfigs = function (platformConfigs) {
26059 this._registry = platformConfigs || {};
26060 };
26061 /**
26062 * @hidden
26063 * @param {?} platformName
26064 * @return {?}
26065 */
26066 Platform.prototype.getPlatformConfig = function (platformName) {
26067 return this._registry[platformName] || {};
26068 };
26069 /**
26070 * @hidden
26071 * @return {?}
26072 */
26073 Platform.prototype.registry = function () {
26074 return this._registry;
26075 };
26076 /**
26077 * @hidden
26078 * @param {?} platformName
26079 * @return {?}
26080 */
26081 Platform.prototype.setDefault = function (platformName) {
26082 this._default = platformName;
26083 };
26084 /**
26085 * @hidden
26086 * @param {?} queryValue
26087 * @param {?} queryTestValue
26088 * @return {?}
26089 */
26090 Platform.prototype.testQuery = function (queryValue, queryTestValue) {
26091 var /** @type {?} */ valueSplit = queryValue.toLowerCase().split(';');
26092 return valueSplit.indexOf(queryTestValue) > -1;
26093 };
26094 /**
26095 * @hidden
26096 * @param {?} navigatorPlatformExpression
26097 * @return {?}
26098 */
26099 Platform.prototype.testNavigatorPlatform = function (navigatorPlatformExpression) {
26100 var /** @type {?} */ rgx = new RegExp(navigatorPlatformExpression, 'i');
26101 return rgx.test(this._nPlt);
26102 };
26103 /**
26104 * @hidden
26105 * @param {?} userAgentExpression
26106 * @return {?}
26107 */
26108 Platform.prototype.matchUserAgentVersion = function (userAgentExpression) {
26109 if (this._ua && userAgentExpression) {
26110 var /** @type {?} */ val = this._ua.match(userAgentExpression);
26111 if (val) {
26112 return {
26113 major: val[1],
26114 minor: val[2]
26115 };
26116 }
26117 }
26118 };
26119 /**
26120 * @param {?} expression
26121 * @return {?}
26122 */
26123 Platform.prototype.testUserAgent = function (expression) {
26124 if (this._ua) {
26125 return this._ua.indexOf(expression) >= 0;
26126 }
26127 return false;
26128 };
26129 /**
26130 * @hidden
26131 * @param {?} queryStringName
26132 * @param {?=} userAgentAtLeastHas
26133 * @param {?=} userAgentMustNotHave
26134 * @return {?}
26135 */
26136 Platform.prototype.isPlatformMatch = function (queryStringName, userAgentAtLeastHas, userAgentMustNotHave) {
26137 if (userAgentMustNotHave === void 0) { userAgentMustNotHave = []; }
26138 var /** @type {?} */ queryValue = this._qp.get('ionicplatform');
26139 if (queryValue) {
26140 return this.testQuery(queryValue, queryStringName);
26141 }
26142 userAgentAtLeastHas = userAgentAtLeastHas || [queryStringName];
26143 var /** @type {?} */ userAgent = this._ua.toLowerCase();
26144 for (var /** @type {?} */ i = 0; i < userAgentAtLeastHas.length; i++) {
26145 if (userAgent.indexOf(userAgentAtLeastHas[i]) > -1) {
26146 for (var /** @type {?} */ j = 0; j < userAgentMustNotHave.length; j++) {
26147 if (userAgent.indexOf(userAgentMustNotHave[j]) > -1) {
26148 return false;
26149 }
26150 }
26151 return true;
26152 }
26153 }
26154 return false;
26155 };
26156 /**
26157 * @hidden
26158 * @return {?}
26159 */
26160 Platform.prototype.init = function () {
26161 this._initEvents();
26162 var /** @type {?} */ rootPlatformNode;
26163 var /** @type {?} */ enginePlatformNode;
26164 // figure out the most specific platform and active engine
26165 var /** @type {?} */ tmpPlt;
26166 for (var /** @type {?} */ platformName in this._registry) {
26167 tmpPlt = this.matchPlatform(platformName);
26168 if (tmpPlt) {
26169 // we found a platform match!
26170 // check if its more specific than the one we already have
26171 if (tmpPlt.isEngine) {
26172 // because it matched then this should be the active engine
26173 // you cannot have more than one active engine
26174 enginePlatformNode = tmpPlt;
26175 }
26176 else if (!rootPlatformNode || tmpPlt.depth > rootPlatformNode.depth) {
26177 // only find the root node for platforms that are not engines
26178 // set this node as the root since we either don't already
26179 // have one, or this one is more specific that the current one
26180 rootPlatformNode = tmpPlt;
26181 }
26182 }
26183 }
26184 if (!rootPlatformNode) {
26185 rootPlatformNode = new PlatformNode(this._registry, this._default);
26186 }
26187 // build a Platform instance filled with the
26188 // hierarchy of active platforms and settings
26189 if (rootPlatformNode) {
26190 // check if we found an engine node (cordova/node-webkit/etc)
26191 if (enginePlatformNode) {
26192 // add the engine to the first in the platform hierarchy
26193 // the original rootPlatformNode now becomes a child
26194 // of the engineNode, which is not the new root
26195 enginePlatformNode.child = rootPlatformNode;
26196 rootPlatformNode.parent = enginePlatformNode;
26197 rootPlatformNode = enginePlatformNode;
26198 }
26199 var /** @type {?} */ platformNode = rootPlatformNode;
26200 while (platformNode) {
26201 insertSuperset(this._registry, platformNode);
26202 platformNode = platformNode.child;
26203 }
26204 // make sure the root noot is actually the root
26205 // incase a node was inserted before the root
26206 platformNode = rootPlatformNode.parent;
26207 while (platformNode) {
26208 rootPlatformNode = platformNode;
26209 platformNode = platformNode.parent;
26210 }
26211 platformNode = rootPlatformNode;
26212 while (platformNode) {
26213 platformNode.initialize(this);
26214 // extra check for ipad pro issue
26215 // https://forums.developer.apple.com/thread/25948
26216 if (platformNode.name === 'iphone' && this.navigatorPlatform() === 'iPad') {
26217 // this is an ipad pro so push ipad and tablet to platforms
26218 // and then return as we are done
26219 this._platforms.push('tablet');
26220 this._platforms.push('ipad');
26221 return;
26222 }
26223 // set the array of active platforms with
26224 // the last one in the array the most important
26225 this._platforms.push(platformNode.name);
26226 // get the platforms version if a version parser was provided
26227 this._versions[platformNode.name] = platformNode.version(this);
26228 // go to the next platform child
26229 platformNode = platformNode.child;
26230 }
26231 }
26232 if (this._platforms.indexOf('mobile') > -1 && this._platforms.indexOf('cordova') === -1) {
26233 this._platforms.push('mobileweb');
26234 }
26235 };
26236 /**
26237 * @hidden
26238 * @param {?} platformName
26239 * @return {?}
26240 */
26241 Platform.prototype.matchPlatform = function (platformName) {
26242 // build a PlatformNode and assign config data to it
26243 // use it's getRoot method to build up its hierarchy
26244 // depending on which platforms match
26245 var /** @type {?} */ platformNode = new PlatformNode(this._registry, platformName);
26246 var /** @type {?} */ rootNode = platformNode.getRoot(this);
26247 if (rootNode) {
26248 rootNode.depth = 0;
26249 var /** @type {?} */ childPlatform = rootNode.child;
26250 while (childPlatform) {
26251 rootNode.depth++;
26252 childPlatform = childPlatform.child;
26253 }
26254 }
26255 return rootNode;
26256 };
26257 return Platform;
26258}());
26259/**
26260 * @param {?} registry
26261 * @param {?} platformNode
26262 * @return {?}
26263 */
26264function insertSuperset(registry, platformNode) {
26265 var /** @type {?} */ supersetPlaformName = platformNode.superset();
26266 if (supersetPlaformName) {
26267 // add a platform in between two exist platforms
26268 // so we can build the correct hierarchy of active platforms
26269 var /** @type {?} */ supersetPlatform = new PlatformNode(registry, supersetPlaformName);
26270 supersetPlatform.parent = platformNode.parent;
26271 supersetPlatform.child = platformNode;
26272 if (supersetPlatform.parent) {
26273 supersetPlatform.parent.child = supersetPlatform;
26274 }
26275 platformNode.parent = supersetPlatform;
26276 }
26277}
26278/**
26279 * @hidden
26280 */
26281var PlatformNode = (function () {
26282 /**
26283 * @param {?} registry
26284 * @param {?} platformName
26285 */
26286 function PlatformNode(registry, platformName) {
26287 this.registry = registry;
26288 this.c = registry[platformName];
26289 this.name = platformName;
26290 this.isEngine = this.c.isEngine;
26291 }
26292 /**
26293 * @return {?}
26294 */
26295 PlatformNode.prototype.settings = function () {
26296 return this.c.settings || {};
26297 };
26298 /**
26299 * @return {?}
26300 */
26301 PlatformNode.prototype.superset = function () {
26302 return this.c.superset;
26303 };
26304 /**
26305 * @param {?} p
26306 * @return {?}
26307 */
26308 PlatformNode.prototype.isMatch = function (p) {
26309 return this.c.isMatch && this.c.isMatch(p) || false;
26310 };
26311 /**
26312 * @param {?} plt
26313 * @return {?}
26314 */
26315 PlatformNode.prototype.initialize = function (plt) {
26316 this.c.initialize && this.c.initialize(plt);
26317 };
26318 /**
26319 * @param {?} plt
26320 * @return {?}
26321 */
26322 PlatformNode.prototype.version = function (plt) {
26323 if (this.c.versionParser) {
26324 var /** @type {?} */ v = this.c.versionParser(plt);
26325 if (v) {
26326 var /** @type {?} */ str = v.major + '.' + v.minor;
26327 return {
26328 str: str,
26329 num: parseFloat(str),
26330 major: parseInt(v.major, 10),
26331 minor: parseInt(v.minor, 10)
26332 };
26333 }
26334 }
26335 };
26336 /**
26337 * @param {?} plt
26338 * @return {?}
26339 */
26340 PlatformNode.prototype.getRoot = function (plt) {
26341 if (this.isMatch(plt)) {
26342 var /** @type {?} */ parents = this.getSubsetParents(this.name);
26343 if (!parents.length) {
26344 return this;
26345 }
26346 var /** @type {?} */ platformNode = null;
26347 var /** @type {?} */ rootPlatformNode = null;
26348 for (var /** @type {?} */ i = 0; i < parents.length; i++) {
26349 platformNode = new PlatformNode(this.registry, parents[i]);
26350 platformNode.child = this;
26351 rootPlatformNode = platformNode.getRoot(plt);
26352 if (rootPlatformNode) {
26353 this.parent = platformNode;
26354 return rootPlatformNode;
26355 }
26356 }
26357 }
26358 return null;
26359 };
26360 /**
26361 * @param {?} subsetPlatformName
26362 * @return {?}
26363 */
26364 PlatformNode.prototype.getSubsetParents = function (subsetPlatformName) {
26365 var /** @type {?} */ parentPlatformNames = [];
26366 var /** @type {?} */ pltConfig = null;
26367 for (var /** @type {?} */ platformName in this.registry) {
26368 pltConfig = this.registry[platformName];
26369 if (pltConfig.subsets && pltConfig.subsets.indexOf(subsetPlatformName) > -1) {
26370 parentPlatformNames.push(platformName);
26371 }
26372 }
26373 return parentPlatformNames;
26374 };
26375 return PlatformNode;
26376}());
26377/**
26378 * @hidden
26379 * @param {?} doc
26380 * @param {?} platformConfigs
26381 * @param {?} zone
26382 * @return {?}
26383 */
26384function setupPlatform(doc, platformConfigs, zone) {
26385 var /** @type {?} */ plt = new Platform();
26386 plt.setDefault('core');
26387 plt.setPlatformConfigs(platformConfigs);
26388 plt.setZone(zone);
26389 // set values from "document"
26390 var /** @type {?} */ docElement = doc.documentElement;
26391 plt.setDocument(doc);
26392 var /** @type {?} */ dir = docElement.dir;
26393 plt.setDir(dir === 'rtl' ? 'rtl' : 'ltr', !dir);
26394 plt.setLang(docElement.lang, false);
26395 // set css properties
26396 plt.setCssProps(docElement);
26397 // set values from "window"
26398 var /** @type {?} */ win = doc.defaultView;
26399 plt.setWindow(win);
26400 plt.setNavigatorPlatform(win.navigator.platform);
26401 plt.setUserAgent(win.navigator.userAgent);
26402 // set location values
26403 plt.setQueryParams(win.location.href);
26404 plt.init();
26405 // add the platform obj to the window
26406 ((win))['Ionic'] = ((win))['Ionic'] || {};
26407 ((win))['Ionic']['platform'] = plt;
26408 return plt;
26409}
26410
26411/**
26412 * @hidden
26413 */
26414var Animation = (function () {
26415 /**
26416 * @param {?} plt
26417 * @param {?=} ele
26418 * @param {?=} opts
26419 */
26420 function Animation(plt, ele, opts) {
26421 this._dur = null;
26422 this._es = null;
26423 this._rvEs = null;
26424 this.hasChildren = false;
26425 this.isPlaying = false;
26426 this.hasCompleted = false;
26427 this.plt = plt;
26428 this.element(ele);
26429 this.opts = opts;
26430 }
26431 /**
26432 * @param {?} ele
26433 * @return {?}
26434 */
26435 Animation.prototype.element = function (ele) {
26436 if (ele) {
26437 if (typeof ele === 'string') {
26438 ele = this.plt.doc().querySelectorAll(ele);
26439 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
26440 this._addEle(ele[i]);
26441 }
26442 }
26443 else if (ele.length) {
26444 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
26445 this._addEle(ele[i]);
26446 }
26447 }
26448 else {
26449 this._addEle(ele);
26450 }
26451 }
26452 return this;
26453 };
26454 /**
26455 * NO DOM
26456 * @param {?} ele
26457 * @return {?}
26458 */
26459 Animation.prototype._addEle = function (ele) {
26460 if (ele.nativeElement) {
26461 ele = ele.nativeElement;
26462 }
26463 if (((ele)).nodeType === 1) {
26464 this._eL = (this._e = this._e || []).push(ele);
26465 }
26466 };
26467 /**
26468 * Add a child animation to this animation.
26469 * @param {?} childAnimation
26470 * @return {?}
26471 */
26472 Animation.prototype.add = function (childAnimation) {
26473 childAnimation.parent = this;
26474 this.hasChildren = true;
26475 this._cL = (this._c = this._c || []).push(childAnimation);
26476 return this;
26477 };
26478 /**
26479 * Get the duration of this animation. If this animation does
26480 * not have a duration, then it'll get the duration from its parent.
26481 * @param {?=} opts
26482 * @return {?}
26483 */
26484 Animation.prototype.getDuration = function (opts) {
26485 if (opts && isDefined(opts.duration)) {
26486 return opts.duration;
26487 }
26488 else if (this._dur !== null) {
26489 return this._dur;
26490 }
26491 else if (this.parent) {
26492 return this.parent.getDuration();
26493 }
26494 return 0;
26495 };
26496 /**
26497 * Returns if the animation is a root one.
26498 * @return {?}
26499 */
26500 Animation.prototype.isRoot = function () {
26501 return !this.parent;
26502 };
26503 /**
26504 * Set the duration for this animation.
26505 * @param {?} milliseconds
26506 * @return {?}
26507 */
26508 Animation.prototype.duration = function (milliseconds) {
26509 this._dur = milliseconds;
26510 return this;
26511 };
26512 /**
26513 * Get the easing of this animation. If this animation does
26514 * not have an easing, then it'll get the easing from its parent.
26515 * @return {?}
26516 */
26517 Animation.prototype.getEasing = function () {
26518 if (this._rv && this._rvEs) {
26519 return this._rvEs;
26520 }
26521 return this._es !== null ? this._es : (this.parent && this.parent.getEasing()) || null;
26522 };
26523 /**
26524 * Set the easing for this animation.
26525 * @param {?} name
26526 * @return {?}
26527 */
26528 Animation.prototype.easing = function (name) {
26529 this._es = name;
26530 return this;
26531 };
26532 /**
26533 * Set the easing for this reversed animation.
26534 * @param {?} name
26535 * @return {?}
26536 */
26537 Animation.prototype.easingReverse = function (name) {
26538 this._rvEs = name;
26539 return this;
26540 };
26541 /**
26542 * Add the "from" value for a specific property.
26543 * @param {?} prop
26544 * @param {?} val
26545 * @return {?}
26546 */
26547 Animation.prototype.from = function (prop, val) {
26548 this._addProp('from', prop, val);
26549 return this;
26550 };
26551 /**
26552 * Add the "to" value for a specific property.
26553 * @param {?} prop
26554 * @param {?} val
26555 * @param {?=} clearProperyAfterTransition
26556 * @return {?}
26557 */
26558 Animation.prototype.to = function (prop, val, clearProperyAfterTransition) {
26559 var /** @type {?} */ fx = this._addProp('to', prop, val);
26560 if (clearProperyAfterTransition) {
26561 // if this effect is a transform then clear the transform effect
26562 // otherwise just clear the actual property
26563 this.afterClearStyles([fx.trans ? this.plt.Css.transform : prop]);
26564 }
26565 return this;
26566 };
26567 /**
26568 * Shortcut to add both the "from" and "to" for the same property.
26569 * @param {?} prop
26570 * @param {?} fromVal
26571 * @param {?} toVal
26572 * @param {?=} clearProperyAfterTransition
26573 * @return {?}
26574 */
26575 Animation.prototype.fromTo = function (prop, fromVal, toVal, clearProperyAfterTransition) {
26576 return this.from(prop, fromVal).to(prop, toVal, clearProperyAfterTransition);
26577 };
26578 /**
26579 * @hidden
26580 * NO DOM
26581 * @param {?} name
26582 * @return {?}
26583 */
26584 Animation.prototype._getProp = function (name) {
26585 if (this._fx) {
26586 return this._fx.find(function (prop) { return prop.name === name; });
26587 }
26588 else {
26589 this._fx = [];
26590 }
26591 return null;
26592 };
26593 /**
26594 * @param {?} state
26595 * @param {?} prop
26596 * @param {?} val
26597 * @return {?}
26598 */
26599 Animation.prototype._addProp = function (state, prop, val) {
26600 var /** @type {?} */ fxProp = this._getProp(prop);
26601 if (!fxProp) {
26602 // first time we've see this EffectProperty
26603 var /** @type {?} */ shouldTrans = (ANIMATION_TRANSFORMS[prop] === 1);
26604 fxProp = {
26605 name: prop,
26606 trans: shouldTrans,
26607 // add the will-change property for transforms or opacity
26608 wc: (shouldTrans ? this.plt.Css.transform : prop)
26609 };
26610 this._fx.push(fxProp);
26611 }
26612 // add from/to EffectState to the EffectProperty
26613 var /** @type {?} */ fxState = {
26614 val: val,
26615 num: null,
26616 unit: '',
26617 };
26618 fxProp[state] = fxState;
26619 if (typeof val === 'string' && val.indexOf(' ') < 0) {
26620 var /** @type {?} */ r = val.match(ANIMATION_CSS_VALUE_REGEX);
26621 var /** @type {?} */ num = parseFloat(r[1]);
26622 if (!isNaN(num)) {
26623 fxState.num = num;
26624 }
26625 fxState.unit = (r[0] !== r[2] ? r[2] : '');
26626 }
26627 else if (typeof val === 'number') {
26628 fxState.num = val;
26629 }
26630 return fxProp;
26631 };
26632 /**
26633 * Add CSS class to this animation's elements
26634 * before the animation begins.
26635 * @param {?} className
26636 * @return {?}
26637 */
26638 Animation.prototype.beforeAddClass = function (className) {
26639 (this._bfAdd = this._bfAdd || []).push(className);
26640 return this;
26641 };
26642 /**
26643 * Remove CSS class from this animation's elements
26644 * before the animation begins.
26645 * @param {?} className
26646 * @return {?}
26647 */
26648 Animation.prototype.beforeRemoveClass = function (className) {
26649 (this._bfRm = this._bfRm || []).push(className);
26650 return this;
26651 };
26652 /**
26653 * Set CSS inline styles to this animation's elements
26654 * before the animation begins.
26655 * @param {?} styles
26656 * @return {?}
26657 */
26658 Animation.prototype.beforeStyles = function (styles) {
26659 this._bfSty = styles;
26660 return this;
26661 };
26662 /**
26663 * Clear CSS inline styles from this animation's elements
26664 * before the animation begins.
26665 * @param {?} propertyNames
26666 * @return {?}
26667 */
26668 Animation.prototype.beforeClearStyles = function (propertyNames) {
26669 this._bfSty = this._bfSty || {};
26670 for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
26671 this._bfSty[propertyNames[i]] = '';
26672 }
26673 return this;
26674 };
26675 /**
26676 * Add a function which contains DOM reads, which will run
26677 * before the animation begins.
26678 * @param {?} domReadFn
26679 * @return {?}
26680 */
26681 Animation.prototype.beforeAddRead = function (domReadFn) {
26682 (this._rdFn = this._rdFn || []).push(domReadFn);
26683 return this;
26684 };
26685 /**
26686 * Add a function which contains DOM writes, which will run
26687 * before the animation begins.
26688 * @param {?} domWriteFn
26689 * @return {?}
26690 */
26691 Animation.prototype.beforeAddWrite = function (domWriteFn) {
26692 (this._wrFn = this._wrFn || []).push(domWriteFn);
26693 return this;
26694 };
26695 /**
26696 * Add CSS class to this animation's elements
26697 * after the animation finishes.
26698 * @param {?} className
26699 * @return {?}
26700 */
26701 Animation.prototype.afterAddClass = function (className) {
26702 (this._afAdd = this._afAdd || []).push(className);
26703 return this;
26704 };
26705 /**
26706 * Remove CSS class from this animation's elements
26707 * after the animation finishes.
26708 * @param {?} className
26709 * @return {?}
26710 */
26711 Animation.prototype.afterRemoveClass = function (className) {
26712 (this._afRm = this._afRm || []).push(className);
26713 return this;
26714 };
26715 /**
26716 * Set CSS inline styles to this animation's elements
26717 * after the animation finishes.
26718 * @param {?} styles
26719 * @return {?}
26720 */
26721 Animation.prototype.afterStyles = function (styles) {
26722 this._afSty = styles;
26723 return this;
26724 };
26725 /**
26726 * Clear CSS inline styles from this animation's elements
26727 * after the animation finishes.
26728 * @param {?} propertyNames
26729 * @return {?}
26730 */
26731 Animation.prototype.afterClearStyles = function (propertyNames) {
26732 this._afSty = this._afSty || {};
26733 for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
26734 this._afSty[propertyNames[i]] = '';
26735 }
26736 return this;
26737 };
26738 /**
26739 * Play the animation.
26740 * @param {?=} opts
26741 * @return {?}
26742 */
26743 Animation.prototype.play = function (opts) {
26744 var _this = this;
26745 // If the animation was already invalidated (it did finish), do nothing
26746 if (!this.plt) {
26747 return;
26748 }
26749 // this is the top level animation and is in full control
26750 // of when the async play() should actually kick off
26751 // if there is no duration then it'll set the TO property immediately
26752 // if there is a duration, then it'll stage all animations at the
26753 // FROM property and transition duration, wait a few frames, then
26754 // kick off the animation by setting the TO property for each animation
26755 this._isAsync = this._hasDuration(opts);
26756 // ensure all past transition end events have been cleared
26757 this._clearAsync();
26758 // recursively kicks off the correct progress step for each child animation
26759 // ******** DOM WRITE ****************
26760 this._playInit(opts);
26761 // doubling up RAFs since this animation was probably triggered
26762 // from an input event, and just having one RAF would have this code
26763 // run within the same frame as the triggering input event, and the
26764 // input event probably already did way too much work for one frame
26765 this.plt.raf(function () {
26766 _this.plt.raf(_this._playDomInspect.bind(_this, opts));
26767 });
26768 };
26769 /**
26770 * @return {?}
26771 */
26772 Animation.prototype.syncPlay = function () {
26773 // If the animation was already invalidated (it did finish), do nothing
26774 if (!this.plt) {
26775 return;
26776 }
26777 var /** @type {?} */ opts = { duration: 0 };
26778 this._isAsync = false;
26779 this._clearAsync();
26780 this._playInit(opts);
26781 this._playDomInspect(opts);
26782 };
26783 /**
26784 * @hidden
26785 * DOM WRITE
26786 * RECURSION
26787 * @param {?} opts
26788 * @return {?}
26789 */
26790 Animation.prototype._playInit = function (opts) {
26791 // always default that an animation does not tween
26792 // a tween requires that an Animation class has an element
26793 // and that it has at least one FROM/TO effect
26794 // and that the FROM/TO effect can tween numeric values
26795 this._twn = false;
26796 this.isPlaying = true;
26797 this.hasCompleted = false;
26798 this._hasDur = (this.getDuration(opts) > ANIMATION_DURATION_MIN);
26799 var /** @type {?} */ children = this._c;
26800 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
26801 // ******** DOM WRITE ****************
26802 children[i]._playInit(opts);
26803 }
26804 if (this._hasDur) {
26805 // if there is a duration then we want to start at step 0
26806 // ******** DOM WRITE ****************
26807 this._progress(0);
26808 // add the will-change properties
26809 // ******** DOM WRITE ****************
26810 this._willChg(true);
26811 }
26812 };
26813 /**
26814 * @hidden
26815 * DOM WRITE
26816 * NO RECURSION
26817 * ROOT ANIMATION
26818 * @param {?} opts
26819 * @return {?}
26820 */
26821 Animation.prototype._playDomInspect = function (opts) {
26822 // fire off all the "before" function that have DOM READS in them
26823 // elements will be in the DOM, however visibily hidden
26824 // so we can read their dimensions if need be
26825 // ******** DOM READ ****************
26826 // ******** DOM WRITE ****************
26827 this._beforeAnimation();
26828 // for the root animation only
26829 // set the async TRANSITION END event
26830 // and run onFinishes when the transition ends
26831 var /** @type {?} */ dur = this.getDuration(opts);
26832 if (this._isAsync) {
26833 this._asyncEnd(dur, true);
26834 }
26835 // ******** DOM WRITE ****************
26836 this._playProgress(opts);
26837 if (this._isAsync && this.plt) {
26838 // this animation has a duration so we need another RAF
26839 // for the CSS TRANSITION properties to kick in
26840 this.plt.raf(this._playToStep.bind(this, 1));
26841 }
26842 };
26843 /**
26844 * @hidden
26845 * DOM WRITE
26846 * RECURSION
26847 * @param {?} opts
26848 * @return {?}
26849 */
26850 Animation.prototype._playProgress = function (opts) {
26851 var /** @type {?} */ children = this._c;
26852 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
26853 // ******** DOM WRITE ****************
26854 children[i]._playProgress(opts);
26855 }
26856 if (this._hasDur) {
26857 // set the CSS TRANSITION duration/easing
26858 // ******** DOM WRITE ****************
26859 this._setTrans(this.getDuration(opts), false);
26860 }
26861 else {
26862 // this animation does not have a duration, so it should not animate
26863 // just go straight to the TO properties and call it done
26864 // ******** DOM WRITE ****************
26865 this._progress(1);
26866 // since there was no animation, immediately run the after
26867 // ******** DOM WRITE ****************
26868 this._setAfterStyles();
26869 // this animation has no duration, so it has finished
26870 // other animations could still be running
26871 this._didFinish(true);
26872 }
26873 };
26874 /**
26875 * @hidden
26876 * DOM WRITE
26877 * RECURSION
26878 * @param {?} stepValue
26879 * @return {?}
26880 */
26881 Animation.prototype._playToStep = function (stepValue) {
26882 var /** @type {?} */ children = this._c;
26883 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
26884 // ******** DOM WRITE ****************
26885 children[i]._playToStep(stepValue);
26886 }
26887 if (this._hasDur) {
26888 // browser had some time to render everything in place
26889 // and the transition duration/easing is set
26890 // now set the TO properties which will trigger the transition to begin
26891 // ******** DOM WRITE ****************
26892 this._progress(stepValue);
26893 }
26894 };
26895 /**
26896 * @hidden
26897 * DOM WRITE
26898 * NO RECURSION
26899 * ROOT ANIMATION
26900 * @param {?} dur
26901 * @param {?} shouldComplete
26902 * @return {?}
26903 */
26904 Animation.prototype._asyncEnd = function (dur, shouldComplete) {
26905 (void 0) /* assert */;
26906 (void 0) /* assert */;
26907 (void 0) /* assert */;
26908 var /** @type {?} */ self = this;
26909 /**
26910 * @return {?}
26911 */
26912 function onTransitionEnd() {
26913 // congrats! a successful transition completed!
26914 // ensure transition end events and timeouts have been cleared
26915 self._clearAsync();
26916 // ******** DOM WRITE ****************
26917 self._playEnd();
26918 // transition finished
26919 self._didFinishAll(shouldComplete, true, false);
26920 }
26921 /**
26922 * @return {?}
26923 */
26924 function onTransitionFallback() {
26925 (void 0) /* console.debug */;
26926 // oh noz! the transition end event didn't fire in time!
26927 // instead the fallback timer when first
26928 // if all goes well this fallback should never fire
26929 // clear the other async end events from firing
26930 self._tm = undefined;
26931 self._clearAsync();
26932 // set the after styles
26933 // ******** DOM WRITE ****************
26934 self._playEnd(shouldComplete ? 1 : 0);
26935 // transition finished
26936 self._didFinishAll(shouldComplete, true, false);
26937 }
26938 // set the TRANSITION END event on one of the transition elements
26939 self._unrgTrns = this.plt.transitionEnd(self._transEl(), onTransitionEnd, false);
26940 // set a fallback timeout if the transition end event never fires, or is too slow
26941 // transition end fallback: (animation duration + XXms)
26942 self._tm = self.plt.timeout(onTransitionFallback, (dur + ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS));
26943 };
26944 /**
26945 * @hidden
26946 * DOM WRITE
26947 * RECURSION
26948 * @param {?=} stepValue
26949 * @return {?}
26950 */
26951 Animation.prototype._playEnd = function (stepValue) {
26952 var /** @type {?} */ children = this._c;
26953 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
26954 // ******** DOM WRITE ****************
26955 children[i]._playEnd(stepValue);
26956 }
26957 if (this._hasDur) {
26958 if (isDefined(stepValue)) {
26959 // too late to have a smooth animation, just finish it
26960 // ******** DOM WRITE ****************
26961 this._setTrans(0, true);
26962 // ensure the ending progress step gets rendered
26963 // ******** DOM WRITE ****************
26964 this._progress(stepValue);
26965 }
26966 // set the after styles
26967 // ******** DOM WRITE ****************
26968 this._setAfterStyles();
26969 // remove the will-change properties
26970 // ******** DOM WRITE ****************
26971 this._willChg(false);
26972 }
26973 };
26974 /**
26975 * @hidden
26976 * NO DOM
26977 * RECURSION
26978 * @param {?} opts
26979 * @return {?}
26980 */
26981 Animation.prototype._hasDuration = function (opts) {
26982 if (this.getDuration(opts) > ANIMATION_DURATION_MIN) {
26983 return true;
26984 }
26985 var /** @type {?} */ children = this._c;
26986 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
26987 if (children[i]._hasDuration(opts)) {
26988 return true;
26989 }
26990 }
26991 return false;
26992 };
26993 /**
26994 * @hidden
26995 * NO DOM
26996 * RECURSION
26997 * @return {?}
26998 */
26999 Animation.prototype._hasDomReads = function () {
27000 if (this._rdFn && this._rdFn.length) {
27001 return true;
27002 }
27003 var /** @type {?} */ children = this._c;
27004 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27005 if (children[i]._hasDomReads()) {
27006 return true;
27007 }
27008 }
27009 return false;
27010 };
27011 /**
27012 * Immediately stop at the end of the animation.
27013 * @param {?=} stepValue
27014 * @return {?}
27015 */
27016 Animation.prototype.stop = function (stepValue) {
27017 if (stepValue === void 0) { stepValue = 1; }
27018 // ensure all past transition end events have been cleared
27019 this._clearAsync();
27020 this._hasDur = true;
27021 this._playEnd(stepValue);
27022 };
27023 /**
27024 * @hidden
27025 * NO DOM
27026 * NO RECURSION
27027 * @return {?}
27028 */
27029 Animation.prototype._clearAsync = function () {
27030 this._unrgTrns && this._unrgTrns();
27031 this._tm && clearTimeout(this._tm);
27032 this._tm = this._unrgTrns = undefined;
27033 };
27034 /**
27035 * @hidden
27036 * DOM WRITE
27037 * NO RECURSION
27038 * @param {?} stepValue
27039 * @return {?}
27040 */
27041 Animation.prototype._progress = function (stepValue) {
27042 // bread 'n butter
27043 var /** @type {?} */ val;
27044 var /** @type {?} */ effects = this._fx;
27045 var /** @type {?} */ nuElements = this._eL;
27046 if (!effects || !nuElements) {
27047 return;
27048 }
27049 // flip the number if we're going in reverse
27050 if (this._rv) {
27051 stepValue = ((stepValue * -1) + 1);
27052 }
27053 var /** @type {?} */ i, /** @type {?} */ j;
27054 var /** @type {?} */ finalTransform = '';
27055 var /** @type {?} */ elements = this._e;
27056 for (i = 0; i < effects.length; i++) {
27057 var /** @type {?} */ fx = effects[i];
27058 if (fx.from && fx.to) {
27059 var /** @type {?} */ fromNum = fx.from.num;
27060 var /** @type {?} */ toNum = fx.to.num;
27061 var /** @type {?} */ tweenEffect = (fromNum !== toNum);
27062 (void 0) /* assert */;
27063 if (tweenEffect) {
27064 this._twn = true;
27065 }
27066 if (stepValue === 0) {
27067 // FROM
27068 val = fx.from.val;
27069 }
27070 else if (stepValue === 1) {
27071 // TO
27072 val = fx.to.val;
27073 }
27074 else if (tweenEffect) {
27075 // EVERYTHING IN BETWEEN
27076 var /** @type {?} */ valNum = (((toNum - fromNum) * stepValue) + fromNum);
27077 var /** @type {?} */ unit = fx.to.unit;
27078 if (unit === 'px') {
27079 valNum = Math.round(valNum);
27080 }
27081 val = valNum + unit;
27082 }
27083 if (val !== null) {
27084 var /** @type {?} */ prop = fx.name;
27085 if (fx.trans) {
27086 finalTransform += prop + '(' + val + ') ';
27087 }
27088 else {
27089 for (j = 0; j < nuElements; j++) {
27090 // ******** DOM WRITE ****************
27091 ((elements[j].style))[prop] = val;
27092 }
27093 }
27094 }
27095 }
27096 }
27097 // place all transforms on the same property
27098 if (finalTransform.length) {
27099 if (!this._rv && stepValue !== 1 || this._rv && stepValue !== 0) {
27100 finalTransform += 'translateZ(0px)';
27101 }
27102 var /** @type {?} */ cssTransform = this.plt.Css.transform;
27103 for (i = 0; i < elements.length; i++) {
27104 // ******** DOM WRITE ****************
27105 ((elements[i].style))[cssTransform] = finalTransform;
27106 }
27107 }
27108 };
27109 /**
27110 * @hidden
27111 * DOM WRITE
27112 * NO RECURSION
27113 * @param {?} dur
27114 * @param {?} forcedLinearEasing
27115 * @return {?}
27116 */
27117 Animation.prototype._setTrans = function (dur, forcedLinearEasing) {
27118 // Transition is not enabled if there are not effects
27119 if (!this._fx) {
27120 return;
27121 }
27122 // set the TRANSITION properties inline on the element
27123 var /** @type {?} */ elements = this._e;
27124 var /** @type {?} */ easing = (forcedLinearEasing ? 'linear' : this.getEasing());
27125 var /** @type {?} */ durString = dur + 'ms';
27126 var /** @type {?} */ Css = this.plt.Css;
27127 var /** @type {?} */ cssTransform = Css.transition;
27128 var /** @type {?} */ cssTransitionDuration = Css.transitionDuration;
27129 var /** @type {?} */ cssTransitionTimingFn = Css.transitionTimingFn;
27130 var /** @type {?} */ eleStyle;
27131 for (var /** @type {?} */ i = 0; i < this._eL; i++) {
27132 eleStyle = elements[i].style;
27133 if (dur > 0) {
27134 // ******** DOM WRITE ****************
27135 eleStyle[cssTransform] = '';
27136 eleStyle[cssTransitionDuration] = durString;
27137 // each animation can have a different easing
27138 if (easing) {
27139 // ******** DOM WRITE ****************
27140 eleStyle[cssTransitionTimingFn] = easing;
27141 }
27142 }
27143 else {
27144 eleStyle[cssTransform] = 'none';
27145 }
27146 }
27147 };
27148 /**
27149 * @hidden
27150 * DOM READ
27151 * DOM WRITE
27152 * RECURSION
27153 * @return {?}
27154 */
27155 Animation.prototype._beforeAnimation = function () {
27156 // fire off all the "before" function that have DOM READS in them
27157 // elements will be in the DOM, however visibily hidden
27158 // so we can read their dimensions if need be
27159 // ******** DOM READ ****************
27160 this._fireBeforeReadFunc();
27161 // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
27162 // fire off all the "before" function that have DOM WRITES in them
27163 // ******** DOM WRITE ****************
27164 this._fireBeforeWriteFunc();
27165 // stage all of the before css classes and inline styles
27166 // ******** DOM WRITE ****************
27167 this._setBeforeStyles();
27168 };
27169 /**
27170 * @hidden
27171 * DOM WRITE
27172 * RECURSION
27173 * @return {?}
27174 */
27175 Animation.prototype._setBeforeStyles = function () {
27176 var /** @type {?} */ i, /** @type {?} */ j;
27177 var /** @type {?} */ children = this._c;
27178 for (i = 0; i < this._cL; i++) {
27179 children[i]._setBeforeStyles();
27180 }
27181 // before the animations have started
27182 // only set before styles if animation is not reversed
27183 if (this._rv) {
27184 return;
27185 }
27186 var /** @type {?} */ addClasses = this._bfAdd;
27187 var /** @type {?} */ removeClasses = this._bfRm;
27188 var /** @type {?} */ ele;
27189 var /** @type {?} */ eleClassList;
27190 var /** @type {?} */ prop;
27191 for (i = 0; i < this._eL; i++) {
27192 ele = this._e[i];
27193 eleClassList = ele.classList;
27194 // css classes to add before the animation
27195 if (addClasses) {
27196 for (j = 0; j < addClasses.length; j++) {
27197 // ******** DOM WRITE ****************
27198 eleClassList.add(addClasses[j]);
27199 }
27200 }
27201 // css classes to remove before the animation
27202 if (removeClasses) {
27203 for (j = 0; j < removeClasses.length; j++) {
27204 // ******** DOM WRITE ****************
27205 eleClassList.remove(removeClasses[j]);
27206 }
27207 }
27208 // inline styles to add before the animation
27209 if (this._bfSty) {
27210 for (prop in this._bfSty) {
27211 // ******** DOM WRITE ****************
27212 ((ele)).style[prop] = this._bfSty[prop];
27213 }
27214 }
27215 }
27216 };
27217 /**
27218 * @hidden
27219 * DOM READ
27220 * RECURSION
27221 * @return {?}
27222 */
27223 Animation.prototype._fireBeforeReadFunc = function () {
27224 var /** @type {?} */ children = this._c;
27225 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27226 // ******** DOM READ ****************
27227 children[i]._fireBeforeReadFunc();
27228 }
27229 var /** @type {?} */ readFunctions = this._rdFn;
27230 if (readFunctions) {
27231 for (var /** @type {?} */ i = 0; i < readFunctions.length; i++) {
27232 // ******** DOM READ ****************
27233 readFunctions[i]();
27234 }
27235 }
27236 };
27237 /**
27238 * @hidden
27239 * DOM WRITE
27240 * RECURSION
27241 * @return {?}
27242 */
27243 Animation.prototype._fireBeforeWriteFunc = function () {
27244 var /** @type {?} */ children = this._c;
27245 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27246 // ******** DOM WRITE ****************
27247 children[i]._fireBeforeWriteFunc();
27248 }
27249 var /** @type {?} */ writeFunctions = this._wrFn;
27250 if (this._wrFn) {
27251 for (var /** @type {?} */ i = 0; i < writeFunctions.length; i++) {
27252 // ******** DOM WRITE ****************
27253 writeFunctions[i]();
27254 }
27255 }
27256 };
27257 /**
27258 * @hidden
27259 * DOM WRITE
27260 * @return {?}
27261 */
27262 Animation.prototype._setAfterStyles = function () {
27263 var /** @type {?} */ i, /** @type {?} */ j;
27264 var /** @type {?} */ ele;
27265 var /** @type {?} */ eleClassList;
27266 var /** @type {?} */ elements = this._e;
27267 for (i = 0; i < this._eL; i++) {
27268 ele = elements[i];
27269 eleClassList = ele.classList;
27270 // remove the transition duration/easing
27271 // ******** DOM WRITE ****************
27272 ((ele)).style[this.plt.Css.transitionDuration] = ((ele)).style[this.plt.Css.transitionTimingFn] = '';
27273 if (this._rv) {
27274 // finished in reverse direction
27275 // css classes that were added before the animation should be removed
27276 if (this._bfAdd) {
27277 for (j = 0; j < this._bfAdd.length; j++) {
27278 // ******** DOM WRITE ****************
27279 eleClassList.remove(this._bfAdd[j]);
27280 }
27281 }
27282 // css classes that were removed before the animation should be added
27283 if (this._bfRm) {
27284 for (j = 0; j < this._bfRm.length; j++) {
27285 // ******** DOM WRITE ****************
27286 eleClassList.add(this._bfRm[j]);
27287 }
27288 }
27289 // inline styles that were added before the animation should be removed
27290 if (this._bfSty) {
27291 for (var /** @type {?} */ prop in this._bfSty) {
27292 // ******** DOM WRITE ****************
27293 ((ele)).style[prop] = '';
27294 }
27295 }
27296 }
27297 else {
27298 // finished in forward direction
27299 // css classes to add after the animation
27300 if (this._afAdd) {
27301 for (j = 0; j < this._afAdd.length; j++) {
27302 // ******** DOM WRITE ****************
27303 eleClassList.add(this._afAdd[j]);
27304 }
27305 }
27306 // css classes to remove after the animation
27307 if (this._afRm) {
27308 for (j = 0; j < this._afRm.length; j++) {
27309 // ******** DOM WRITE ****************
27310 eleClassList.remove(this._afRm[j]);
27311 }
27312 }
27313 // inline styles to add after the animation
27314 if (this._afSty) {
27315 for (var /** @type {?} */ prop in this._afSty) {
27316 // ******** DOM WRITE ****************
27317 ((ele)).style[prop] = this._afSty[prop];
27318 }
27319 }
27320 }
27321 }
27322 };
27323 /**
27324 * @hidden
27325 * DOM WRITE
27326 * NO RECURSION
27327 * @param {?} addWillChange
27328 * @return {?}
27329 */
27330 Animation.prototype._willChg = function (addWillChange) {
27331 var /** @type {?} */ wc;
27332 var /** @type {?} */ effects = this._fx;
27333 var /** @type {?} */ willChange;
27334 if (addWillChange && effects) {
27335 wc = [];
27336 for (var /** @type {?} */ i = 0; i < effects.length; i++) {
27337 var /** @type {?} */ propWC = effects[i].wc;
27338 if (propWC === 'webkitTransform') {
27339 wc.push('transform', '-webkit-transform');
27340 }
27341 else {
27342 wc.push(propWC);
27343 }
27344 }
27345 willChange = wc.join(',');
27346 }
27347 else {
27348 willChange = '';
27349 }
27350 for (var /** @type {?} */ i = 0; i < this._eL; i++) {
27351 // ******** DOM WRITE ****************
27352 ((this._e[i])).style.willChange = willChange;
27353 }
27354 };
27355 /**
27356 * Start the animation with a user controlled progress.
27357 * @return {?}
27358 */
27359 Animation.prototype.progressStart = function () {
27360 // ensure all past transition end events have been cleared
27361 this._clearAsync();
27362 // ******** DOM READ/WRITE ****************
27363 this._beforeAnimation();
27364 // ******** DOM WRITE ****************
27365 this._progressStart();
27366 };
27367 /**
27368 * @hidden
27369 * DOM WRITE
27370 * RECURSION
27371 * @return {?}
27372 */
27373 Animation.prototype._progressStart = function () {
27374 var /** @type {?} */ children = this._c;
27375 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27376 // ******** DOM WRITE ****************
27377 children[i]._progressStart();
27378 }
27379 // force no duration, linear easing
27380 // ******** DOM WRITE ****************
27381 this._setTrans(0, true);
27382 // ******** DOM WRITE ****************
27383 this._willChg(true);
27384 };
27385 /**
27386 * Set the progress step for this animation.
27387 * progressStep() is not debounced, so it should not be called faster than 60FPS.
27388 * @param {?} stepValue
27389 * @return {?}
27390 */
27391 Animation.prototype.progressStep = function (stepValue) {
27392 // only update if the last update was more than 16ms ago
27393 stepValue = Math.min(1, Math.max(0, stepValue));
27394 var /** @type {?} */ children = this._c;
27395 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27396 // ******** DOM WRITE ****************
27397 children[i].progressStep(stepValue);
27398 }
27399 if (this._rv) {
27400 // if the animation is going in reverse then
27401 // flip the step value: 0 becomes 1, 1 becomes 0
27402 stepValue = ((stepValue * -1) + 1);
27403 }
27404 // ******** DOM WRITE ****************
27405 this._progress(stepValue);
27406 };
27407 /**
27408 * End the progress animation.
27409 * @param {?} shouldComplete
27410 * @param {?} currentStepValue
27411 * @param {?=} dur
27412 * @return {?}
27413 */
27414 Animation.prototype.progressEnd = function (shouldComplete, currentStepValue, dur) {
27415 if (dur === void 0) { dur = -1; }
27416 (void 0) /* console.debug */;
27417 if (this._rv) {
27418 // if the animation is going in reverse then
27419 // flip the step value: 0 becomes 1, 1 becomes 0
27420 currentStepValue = ((currentStepValue * -1) + 1);
27421 }
27422 var /** @type {?} */ stepValue = shouldComplete ? 1 : 0;
27423 var /** @type {?} */ diff = Math.abs(currentStepValue - stepValue);
27424 if (diff < 0.05) {
27425 dur = 0;
27426 }
27427 else if (dur < 0) {
27428 dur = this._dur;
27429 }
27430 this._isAsync = (dur > 30);
27431 this._progressEnd(shouldComplete, stepValue, dur, this._isAsync);
27432 if (this._isAsync) {
27433 // for the root animation only
27434 // set the async TRANSITION END event
27435 // and run onFinishes when the transition ends
27436 // ******** DOM WRITE ****************
27437 this._asyncEnd(dur, shouldComplete);
27438 // this animation has a duration so we need another RAF
27439 // for the CSS TRANSITION properties to kick in
27440 this.plt && this.plt.raf(this._playToStep.bind(this, stepValue));
27441 }
27442 };
27443 /**
27444 * @hidden
27445 * DOM WRITE
27446 * RECURSION
27447 * @param {?} shouldComplete
27448 * @param {?} stepValue
27449 * @param {?} dur
27450 * @param {?} isAsync
27451 * @return {?}
27452 */
27453 Animation.prototype._progressEnd = function (shouldComplete, stepValue, dur, isAsync) {
27454 var /** @type {?} */ children = this._c;
27455 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27456 // ******** DOM WRITE ****************
27457 children[i]._progressEnd(shouldComplete, stepValue, dur, isAsync);
27458 }
27459 if (!isAsync) {
27460 // stop immediately
27461 // set all the animations to their final position
27462 // ******** DOM WRITE ****************
27463 this._progress(stepValue);
27464 this._willChg(false);
27465 this._setAfterStyles();
27466 this._didFinish(shouldComplete);
27467 }
27468 else {
27469 // animate it back to it's ending position
27470 this.isPlaying = true;
27471 this.hasCompleted = false;
27472 this._hasDur = true;
27473 // ******** DOM WRITE ****************
27474 this._willChg(true);
27475 this._setTrans(dur, false);
27476 }
27477 };
27478 /**
27479 * Add a callback to fire when the animation has finished.
27480 * @param {?} callback
27481 * @param {?=} onceTimeCallback
27482 * @param {?=} clearOnFinishCallacks
27483 * @return {?}
27484 */
27485 Animation.prototype.onFinish = function (callback, onceTimeCallback, clearOnFinishCallacks) {
27486 if (onceTimeCallback === void 0) { onceTimeCallback = false; }
27487 if (clearOnFinishCallacks === void 0) { clearOnFinishCallacks = false; }
27488 if (clearOnFinishCallacks) {
27489 this._fFn = this._fOneFn = undefined;
27490 }
27491 if (onceTimeCallback) {
27492 this._fOneFn = this._fOneFn || [];
27493 this._fOneFn.push(callback);
27494 }
27495 else {
27496 this._fFn = this._fFn || [];
27497 this._fFn.push(callback);
27498 }
27499 return this;
27500 };
27501 /**
27502 * @hidden
27503 * NO DOM
27504 * RECURSION
27505 * @param {?} hasCompleted
27506 * @param {?} finishAsyncAnimations
27507 * @param {?} finishNoDurationAnimations
27508 * @return {?}
27509 */
27510 Animation.prototype._didFinishAll = function (hasCompleted, finishAsyncAnimations, finishNoDurationAnimations) {
27511 var /** @type {?} */ children = this._c;
27512 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27513 children[i]._didFinishAll(hasCompleted, finishAsyncAnimations, finishNoDurationAnimations);
27514 }
27515 if (finishAsyncAnimations && this._isAsync || finishNoDurationAnimations && !this._isAsync) {
27516 this._didFinish(hasCompleted);
27517 }
27518 };
27519 /**
27520 * @hidden
27521 * NO RECURSION
27522 * @param {?} hasCompleted
27523 * @return {?}
27524 */
27525 Animation.prototype._didFinish = function (hasCompleted) {
27526 this.isPlaying = false;
27527 this.hasCompleted = hasCompleted;
27528 if (this._fFn) {
27529 // run all finish callbacks
27530 for (var /** @type {?} */ i = 0; i < this._fFn.length; i++) {
27531 this._fFn[i](this);
27532 }
27533 }
27534 if (this._fOneFn) {
27535 // run all "onetime" finish callbacks
27536 for (var /** @type {?} */ i = 0; i < this._fOneFn.length; i++) {
27537 this._fOneFn[i](this);
27538 }
27539 this._fOneFn.length = 0;
27540 }
27541 };
27542 /**
27543 * Reverse the animation.
27544 * @param {?=} shouldReverse
27545 * @return {?}
27546 */
27547 Animation.prototype.reverse = function (shouldReverse) {
27548 if (shouldReverse === void 0) { shouldReverse = true; }
27549 var /** @type {?} */ children = this._c;
27550 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27551 children[i].reverse(shouldReverse);
27552 }
27553 this._rv = shouldReverse;
27554 return this;
27555 };
27556 /**
27557 * Recursively destroy this animation and all child animations.
27558 * @return {?}
27559 */
27560 Animation.prototype.destroy = function () {
27561 var /** @type {?} */ children = this._c;
27562 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27563 children[i].destroy();
27564 }
27565 this._clearAsync();
27566 this.parent = this.plt = this._e = this._rdFn = this._wrFn = null;
27567 if (this._c) {
27568 this._c.length = this._cL = 0;
27569 }
27570 if (this._fFn) {
27571 this._fFn.length = 0;
27572 }
27573 if (this._fOneFn) {
27574 this._fOneFn.length = 0;
27575 }
27576 };
27577 /**
27578 * @hidden
27579 * NO DOM
27580 * @return {?}
27581 */
27582 Animation.prototype._transEl = function () {
27583 // get the lowest level element that has an Animation
27584 var /** @type {?} */ targetEl;
27585 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
27586 targetEl = this._c[i]._transEl();
27587 if (targetEl) {
27588 return targetEl;
27589 }
27590 }
27591 return (this._twn && this._hasDur && this._eL ? this._e[0] : null);
27592 };
27593 return Animation;
27594}());
27595var ANIMATION_TRANSFORMS = {
27596 'translateX': 1,
27597 'translateY': 1,
27598 'translateZ': 1,
27599 'scale': 1,
27600 'scaleX': 1,
27601 'scaleY': 1,
27602 'scaleZ': 1,
27603 'rotate': 1,
27604 'rotateX': 1,
27605 'rotateY': 1,
27606 'rotateZ': 1,
27607 'skewX': 1,
27608 'skewY': 1,
27609 'perspective': 1
27610};
27611var ANIMATION_CSS_VALUE_REGEX = /(^-?\d*\.?\d*)(.*)/;
27612var ANIMATION_DURATION_MIN = 32;
27613var ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS = 400;
27614
27615var __extends$16 = (undefined && undefined.__extends) || (function () {
27616 var extendStatics = Object.setPrototypeOf ||
27617 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27618 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27619 return function (d, b) {
27620 extendStatics(d, b);
27621 function __() { this.constructor = d; }
27622 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
27623 };
27624})();
27625/**
27626 * @hidden
27627 *
27628 * - play
27629 * - Add before classes - DOM WRITE
27630 * - Remove before classes - DOM WRITE
27631 * - Add before inline styles - DOM WRITE
27632 * - set inline FROM styles - DOM WRITE
27633 * - RAF
27634 * - read toolbar dimensions - DOM READ
27635 * - write content top/bottom padding - DOM WRITE
27636 * - set css transition duration/easing - DOM WRITE
27637 * - RAF
27638 * - set inline TO styles - DOM WRITE
27639 */
27640var Transition = (function (_super) {
27641 __extends$16(Transition, _super);
27642 /**
27643 * @param {?} plt
27644 * @param {?} enteringView
27645 * @param {?} leavingView
27646 * @param {?} opts
27647 */
27648 function Transition(plt, enteringView, leavingView, opts) {
27649 var _this = _super.call(this, plt, null, opts) || this;
27650 _this.enteringView = enteringView;
27651 _this.leavingView = leavingView;
27652 return _this;
27653 }
27654 /**
27655 * @return {?}
27656 */
27657 Transition.prototype.init = function () { };
27658 /**
27659 * @param {?} trnsStart
27660 * @return {?}
27661 */
27662 Transition.prototype.registerStart = function (trnsStart) {
27663 this._trnsStart = trnsStart;
27664 };
27665 /**
27666 * @return {?}
27667 */
27668 Transition.prototype.start = function () {
27669 this._trnsStart && this._trnsStart();
27670 this._trnsStart = null;
27671 // bubble up start
27672 this.parent && this.parent.start();
27673 };
27674 /**
27675 * @return {?}
27676 */
27677 Transition.prototype.destroy = function () {
27678 _super.prototype.destroy.call(this);
27679 this.parent = this.enteringView = this.leavingView = this._trnsStart = null;
27680 };
27681 return Transition;
27682}(Animation));
27683
27684var __extends$15 = (undefined && undefined.__extends) || (function () {
27685 var extendStatics = Object.setPrototypeOf ||
27686 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27687 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27688 return function (d, b) {
27689 extendStatics(d, b);
27690 function __() { this.constructor = d; }
27691 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
27692 };
27693})();
27694/**
27695 * @hidden
27696 */
27697var PageTransition = (function (_super) {
27698 __extends$15(PageTransition, _super);
27699 function PageTransition() {
27700 return _super !== null && _super.apply(this, arguments) || this;
27701 }
27702 /**
27703 * @return {?}
27704 */
27705 PageTransition.prototype.init = function () {
27706 var _this = this;
27707 if (this.enteringView) {
27708 this.enteringPage = new Animation(this.plt, this.enteringView.pageRef());
27709 this.add(this.enteringPage.beforeAddClass('show-page'));
27710 // Resize content before transition starts
27711 this.beforeAddRead(function () {
27712 _this.enteringView.readReady.emit();
27713 });
27714 this.beforeAddWrite(function () {
27715 _this.enteringView.writeReady.emit();
27716 });
27717 }
27718 };
27719 /**
27720 * @return {?}
27721 */
27722 PageTransition.prototype.destroy = function () {
27723 _super.prototype.destroy.call(this);
27724 this.enteringPage && this.enteringPage.destroy();
27725 this.enteringPage = null;
27726 };
27727 return PageTransition;
27728}(Transition));
27729
27730var __extends$14 = (undefined && undefined.__extends) || (function () {
27731 var extendStatics = Object.setPrototypeOf ||
27732 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27733 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27734 return function (d, b) {
27735 extendStatics(d, b);
27736 function __() { this.constructor = d; }
27737 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
27738 };
27739})();
27740var DURATION = 500;
27741var EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
27742var OPACITY = 'opacity';
27743var TRANSFORM = 'transform';
27744var TRANSLATEX = 'translateX';
27745var CENTER = '0%';
27746var OFF_OPACITY = 0.8;
27747var SHOW_BACK_BTN_CSS = 'show-back-button';
27748var IOSTransition = (function (_super) {
27749 __extends$14(IOSTransition, _super);
27750 function IOSTransition() {
27751 return _super !== null && _super.apply(this, arguments) || this;
27752 }
27753 /**
27754 * @return {?}
27755 */
27756 IOSTransition.prototype.init = function () {
27757 _super.prototype.init.call(this);
27758 var /** @type {?} */ plt = this.plt;
27759 var /** @type {?} */ OFF_RIGHT = plt.isRTL ? '-99.5%' : '99.5%';
27760 var /** @type {?} */ OFF_LEFT = plt.isRTL ? '33%' : '-33%';
27761 var /** @type {?} */ enteringView = this.enteringView;
27762 var /** @type {?} */ leavingView = this.leavingView;
27763 var /** @type {?} */ opts = this.opts;
27764 this.duration(isPresent(opts.duration) ? opts.duration : DURATION);
27765 this.easing(isPresent(opts.easing) ? opts.easing : EASING);
27766 var /** @type {?} */ backDirection = (opts.direction === 'back');
27767 var /** @type {?} */ enteringHasNavbar = (enteringView && enteringView.hasNavbar());
27768 var /** @type {?} */ leavingHasNavbar = (leavingView && leavingView.hasNavbar());
27769 if (enteringView) {
27770 // get the native element for the entering page
27771 var /** @type {?} */ enteringPageEle = enteringView.pageRef().nativeElement;
27772 // entering content
27773 var /** @type {?} */ enteringContent = new Animation(plt, enteringView.contentRef());
27774 enteringContent.element(enteringPageEle.querySelectorAll('ion-header > *:not(ion-navbar),ion-footer > *'));
27775 this.add(enteringContent);
27776 if (backDirection) {
27777 // entering content, back direction
27778 enteringContent
27779 .fromTo(TRANSLATEX, OFF_LEFT, CENTER, true)
27780 .fromTo(OPACITY, OFF_OPACITY, 1, true);
27781 }
27782 else {
27783 // entering content, forward direction
27784 enteringContent
27785 .beforeClearStyles([OPACITY])
27786 .fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
27787 }
27788 if (enteringHasNavbar) {
27789 // entering page has a navbar
27790 var /** @type {?} */ enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
27791 var /** @type {?} */ enteringNavBar = new Animation(plt, enteringNavbarEle);
27792 this.add(enteringNavBar);
27793 var /** @type {?} */ enteringTitle = new Animation(plt, enteringNavbarEle.querySelector('ion-title'));
27794 var /** @type {?} */ enteringNavbarItems = new Animation(plt, enteringNavbarEle.querySelectorAll('ion-buttons,[menuToggle]'));
27795 var /** @type {?} */ enteringNavbarBg = new Animation(plt, enteringNavbarEle.querySelector('.toolbar-background'));
27796 var /** @type {?} */ enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
27797 enteringNavBar
27798 .add(enteringTitle)
27799 .add(enteringNavbarItems)
27800 .add(enteringNavbarBg)
27801 .add(enteringBackButton);
27802 enteringTitle.fromTo(OPACITY, 0.01, 1, true);
27803 enteringNavbarItems.fromTo(OPACITY, 0.01, 1, true);
27804 // set properties depending on direction
27805 if (backDirection) {
27806 // entering navbar, back direction
27807 enteringTitle.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true);
27808 if (enteringView.enableBack()) {
27809 // back direction, entering page has a back button
27810 enteringBackButton
27811 .beforeAddClass(SHOW_BACK_BTN_CSS)
27812 .fromTo(OPACITY, 0.01, 1, true);
27813 }
27814 }
27815 else {
27816 // entering navbar, forward direction
27817 enteringTitle.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
27818 enteringNavbarBg
27819 .beforeClearStyles([OPACITY])
27820 .fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
27821 if (enteringView.enableBack()) {
27822 // forward direction, entering page has a back button
27823 enteringBackButton
27824 .beforeAddClass(SHOW_BACK_BTN_CSS)
27825 .fromTo(OPACITY, 0.01, 1, true);
27826 var /** @type {?} */ enteringBackBtnText = new Animation(plt, enteringNavbarEle.querySelector('.back-button-text'));
27827 enteringBackBtnText.fromTo(TRANSLATEX, (plt.isRTL ? '-100px' : '100px'), '0px');
27828 enteringNavBar.add(enteringBackBtnText);
27829 }
27830 else {
27831 enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS);
27832 }
27833 }
27834 }
27835 }
27836 // setup leaving view
27837 if (leavingView && leavingView.pageRef()) {
27838 // leaving content
27839 var /** @type {?} */ leavingPageEle = leavingView.pageRef().nativeElement;
27840 var /** @type {?} */ leavingContent = new Animation(plt, leavingView.contentRef());
27841 leavingContent.element(leavingPageEle.querySelectorAll('ion-header > *:not(ion-navbar),ion-footer > *'));
27842 this.add(leavingContent);
27843 if (backDirection) {
27844 // leaving content, back direction
27845 leavingContent
27846 .beforeClearStyles([OPACITY])
27847 .fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
27848 }
27849 else {
27850 // leaving content, forward direction
27851 leavingContent
27852 .fromTo(TRANSLATEX, CENTER, OFF_LEFT)
27853 .fromTo(OPACITY, 1, OFF_OPACITY)
27854 .afterClearStyles([TRANSFORM, OPACITY]);
27855 }
27856 if (leavingHasNavbar) {
27857 // leaving page has a navbar
27858 var /** @type {?} */ leavingNavbarEle = leavingPageEle.querySelector('ion-navbar');
27859 var /** @type {?} */ leavingNavBar = new Animation(plt, leavingNavbarEle);
27860 var /** @type {?} */ leavingTitle = new Animation(plt, leavingNavbarEle.querySelector('ion-title'));
27861 var /** @type {?} */ leavingNavbarItems = new Animation(plt, leavingNavbarEle.querySelectorAll('ion-buttons,[menuToggle]'));
27862 var /** @type {?} */ leavingNavbarBg = new Animation(plt, leavingNavbarEle.querySelector('.toolbar-background'));
27863 var /** @type {?} */ leavingBackButton = new Animation(plt, leavingNavbarEle.querySelector('.back-button'));
27864 leavingNavBar
27865 .add(leavingTitle)
27866 .add(leavingNavbarItems)
27867 .add(leavingBackButton)
27868 .add(leavingNavbarBg);
27869 this.add(leavingNavBar);
27870 // fade out leaving navbar items
27871 leavingBackButton.fromTo(OPACITY, 0.99, 0);
27872 leavingTitle.fromTo(OPACITY, 0.99, 0);
27873 leavingNavbarItems.fromTo(OPACITY, 0.99, 0);
27874 if (backDirection) {
27875 // leaving navbar, back direction
27876 leavingTitle.fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
27877 // leaving navbar, back direction, and there's no entering navbar
27878 // should just slide out, no fading out
27879 leavingNavbarBg
27880 .beforeClearStyles([OPACITY])
27881 .fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
27882 var /** @type {?} */ leavingBackBtnText = new Animation(plt, leavingNavbarEle.querySelector('.back-button-text'));
27883 leavingBackBtnText.fromTo(TRANSLATEX, CENTER, (plt.isRTL ? -300 : 300) + 'px');
27884 leavingNavBar.add(leavingBackBtnText);
27885 }
27886 else {
27887 // leaving navbar, forward direction
27888 leavingTitle
27889 .fromTo(TRANSLATEX, CENTER, OFF_LEFT)
27890 .afterClearStyles([TRANSFORM]);
27891 leavingBackButton.afterClearStyles([OPACITY]);
27892 leavingTitle.afterClearStyles([OPACITY]);
27893 leavingNavbarItems.afterClearStyles([OPACITY]);
27894 }
27895 }
27896 }
27897 };
27898 return IOSTransition;
27899}(PageTransition));
27900
27901var __extends$17 = (undefined && undefined.__extends) || (function () {
27902 var extendStatics = Object.setPrototypeOf ||
27903 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27904 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27905 return function (d, b) {
27906 extendStatics(d, b);
27907 function __() { this.constructor = d; }
27908 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
27909 };
27910})();
27911var TRANSLATEY = 'translateY';
27912var OFF_BOTTOM = '40px';
27913var CENTER$1 = '0px';
27914var SHOW_BACK_BTN_CSS$1 = 'show-back-button';
27915var MDTransition = (function (_super) {
27916 __extends$17(MDTransition, _super);
27917 function MDTransition() {
27918 return _super !== null && _super.apply(this, arguments) || this;
27919 }
27920 /**
27921 * @return {?}
27922 */
27923 MDTransition.prototype.init = function () {
27924 _super.prototype.init.call(this);
27925 var /** @type {?} */ plt = this.plt;
27926 var /** @type {?} */ enteringView = this.enteringView;
27927 var /** @type {?} */ leavingView = this.leavingView;
27928 var /** @type {?} */ opts = this.opts;
27929 // what direction is the transition going
27930 var /** @type {?} */ backDirection = (opts.direction === 'back');
27931 if (enteringView) {
27932 if (backDirection) {
27933 this.duration(isPresent(opts.duration) ? opts.duration : 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
27934 }
27935 else {
27936 this.duration(isPresent(opts.duration) ? opts.duration : 280).easing('cubic-bezier(0.36,0.66,0.04,1)');
27937 this.enteringPage
27938 .fromTo(TRANSLATEY, OFF_BOTTOM, CENTER$1, true)
27939 .fromTo('opacity', 0.01, 1, true);
27940 }
27941 if (enteringView.hasNavbar()) {
27942 var /** @type {?} */ enteringPageEle = enteringView.pageRef().nativeElement;
27943 var /** @type {?} */ enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
27944 var /** @type {?} */ enteringNavBar = new Animation(plt, enteringNavbarEle);
27945 this.add(enteringNavBar);
27946 var /** @type {?} */ enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
27947 this.add(enteringBackButton);
27948 if (enteringView.enableBack()) {
27949 enteringBackButton.beforeAddClass(SHOW_BACK_BTN_CSS$1);
27950 }
27951 else {
27952 enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS$1);
27953 }
27954 }
27955 }
27956 // setup leaving view
27957 if (leavingView && backDirection) {
27958 // leaving content
27959 this.duration(opts.duration || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
27960 var /** @type {?} */ leavingPage = new Animation(plt, leavingView.pageRef());
27961 this.add(leavingPage.fromTo(TRANSLATEY, CENTER$1, OFF_BOTTOM).fromTo('opacity', 1, 0));
27962 }
27963 };
27964 return MDTransition;
27965}(PageTransition));
27966
27967var __extends$18 = (undefined && undefined.__extends) || (function () {
27968 var extendStatics = Object.setPrototypeOf ||
27969 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27970 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27971 return function (d, b) {
27972 extendStatics(d, b);
27973 function __() { this.constructor = d; }
27974 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
27975 };
27976})();
27977var SHOW_BACK_BTN_CSS$2 = 'show-back-button';
27978var SCALE_SMALL = .95;
27979var WPTransition = (function (_super) {
27980 __extends$18(WPTransition, _super);
27981 function WPTransition() {
27982 return _super !== null && _super.apply(this, arguments) || this;
27983 }
27984 /**
27985 * @return {?}
27986 */
27987 WPTransition.prototype.init = function () {
27988 _super.prototype.init.call(this);
27989 var /** @type {?} */ plt = this.plt;
27990 var /** @type {?} */ enteringView = this.enteringView;
27991 var /** @type {?} */ leavingView = this.leavingView;
27992 var /** @type {?} */ opts = this.opts;
27993 // what direction is the transition going
27994 var /** @type {?} */ backDirection = (opts.direction === 'back');
27995 if (enteringView) {
27996 if (backDirection) {
27997 this.duration(isPresent(opts.duration) ? opts.duration : 120).easing('cubic-bezier(0.47,0,0.745,0.715)');
27998 this.enteringPage.beforeClearStyles(['scale']);
27999 }
28000 else {
28001 this.duration(isPresent(opts.duration) ? opts.duration : 280).easing('cubic-bezier(0,0,0.05,1)');
28002 this.enteringPage
28003 .fromTo('scale', SCALE_SMALL, 1, true)
28004 .fromTo('opacity', 0.01, 1, true);
28005 }
28006 if (enteringView.hasNavbar()) {
28007 var /** @type {?} */ enteringPageEle = enteringView.pageRef().nativeElement;
28008 var /** @type {?} */ enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
28009 var /** @type {?} */ enteringNavBar = new Animation(plt, enteringNavbarEle);
28010 this.add(enteringNavBar);
28011 var /** @type {?} */ enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
28012 this.add(enteringBackButton);
28013 if (enteringView.enableBack()) {
28014 enteringBackButton.beforeAddClass(SHOW_BACK_BTN_CSS$2);
28015 }
28016 else {
28017 enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS$2);
28018 }
28019 }
28020 }
28021 // setup leaving view
28022 if (leavingView && backDirection) {
28023 // leaving content
28024 this.duration(opts.duration || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
28025 var /** @type {?} */ leavingPage = new Animation(plt, leavingView.pageRef());
28026 this.add(leavingPage.fromTo('scale', 1, SCALE_SMALL).fromTo('opacity', 0.99, 0));
28027 }
28028 };
28029 return WPTransition;
28030}(PageTransition));
28031
28032/**
28033 * \@name App
28034 * \@description
28035 * App is a utility class used in Ionic to get information about various aspects of an app
28036 */
28037var App = (function () {
28038 /**
28039 * @param {?} _config
28040 * @param {?} _plt
28041 * @param {?=} _menuCtrl
28042 */
28043 function App(_config, _plt, _menuCtrl) {
28044 this._config = _config;
28045 this._plt = _plt;
28046 this._menuCtrl = _menuCtrl;
28047 this._disTime = 0;
28048 this._scrollTime = 0;
28049 this._title = '';
28050 this._titleSrv = new Title(DOCUMENT$1);
28051 this._rootNavs = new Map();
28052 this._didScroll = false;
28053 /**
28054 * Observable that emits whenever a view loads in the app.
28055 */
28056 this.viewDidLoad = new EventEmitter();
28057 /**
28058 * Observable that emits before any view is entered in the app.
28059 */
28060 this.viewWillEnter = new EventEmitter();
28061 /**
28062 * Observable that emits after any view is entered in the app.
28063 */
28064 this.viewDidEnter = new EventEmitter();
28065 /**
28066 * Observable that emits before any view is exited in the app.
28067 */
28068 this.viewWillLeave = new EventEmitter();
28069 /**
28070 * Observable that emits after any view is exited in the app.
28071 */
28072 this.viewDidLeave = new EventEmitter();
28073 /**
28074 * Observable that emits before any view unloads in the app.
28075 */
28076 this.viewWillUnload = new EventEmitter();
28077 // listen for hardware back button events
28078 // register this back button action with a default priority
28079 _plt.registerBackButtonAction(this.goBack.bind(this));
28080 this._disableScrollAssist = _config.getBoolean('disableScrollAssist', false);
28081 var blurring = _config.getBoolean('inputBlurring', false);
28082 if (blurring) {
28083 this._enableInputBlurring();
28084 }
28085 (void 0) /* runInDev */;
28086 _config.setTransition('ios-transition', IOSTransition);
28087 _config.setTransition('md-transition', MDTransition);
28088 _config.setTransition('wp-transition', WPTransition);
28089 }
28090 /**
28091 * Sets the document title.
28092 * @param {?} val
28093 * @return {?}
28094 */
28095 App.prototype.setTitle = function (val) {
28096 if (val !== this._title) {
28097 this._title = val;
28098 this._titleSrv.setTitle(val);
28099 }
28100 };
28101 /**
28102 * @hidden
28103 * @param {?} className
28104 * @param {?} isAdd
28105 * @return {?}
28106 */
28107 App.prototype.setElementClass = function (className, isAdd) {
28108 this._appRoot.setElementClass(className, isAdd);
28109 };
28110 /**
28111 * @hidden
28112 * Sets if the app is currently enabled or not, meaning if it's
28113 * available to accept new user commands. For example, this is set to `false`
28114 * while views transition, a modal slides up, an action-sheet
28115 * slides up, etc. After the transition completes it is set back to `true`.
28116 * is used to set the maximum number of milliseconds that app will wait until
28117 * it will automatically enable the app again. It's basically a fallback incase
28118 * something goes wrong during a transition and the app wasn't re-enabled correctly.
28119 * @param {?} isEnabled
28120 * @param {?=} duration
28121 * @param {?=} minDuration
28122 * @return {?}
28123 */
28124 App.prototype.setEnabled = function (isEnabled, duration, minDuration) {
28125 if (duration === void 0) { duration = 700; }
28126 if (minDuration === void 0) { minDuration = 0; }
28127 this._disTime = (isEnabled ? 0 : Date.now() + duration);
28128 if (this._clickBlock) {
28129 if (isEnabled) {
28130 // disable the click block if it's enabled, or the duration is tiny
28131 this._clickBlock.activate(false, CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
28132 }
28133 else {
28134 // show the click block for duration + some number
28135 this._clickBlock.activate(true, duration + CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
28136 }
28137 }
28138 };
28139 /**
28140 * @hidden
28141 * Toggles whether an application can be scrolled
28142 * scrolling is enabled. When set to `true`, scrolling is disabled.
28143 * @param {?} disableScroll
28144 * @return {?}
28145 */
28146 App.prototype._setDisableScroll = function (disableScroll) {
28147 if (this._disableScrollAssist) {
28148 this._appRoot._disableScroll(disableScroll);
28149 }
28150 };
28151 /**
28152 * @hidden
28153 * Boolean if the app is actively enabled or not.
28154 * @return {?}
28155 */
28156 App.prototype.isEnabled = function () {
28157 var /** @type {?} */ disTime = this._disTime;
28158 if (disTime === 0) {
28159 return true;
28160 }
28161 return (disTime < Date.now());
28162 };
28163 /**
28164 * @hidden
28165 * @return {?}
28166 */
28167 App.prototype.setScrolling = function () {
28168 this._scrollTime = Date.now() + ACTIVE_SCROLLING_TIME;
28169 this._didScroll = true;
28170 };
28171 /**
28172 * Boolean if the app is actively scrolling or not.
28173 * @return {?}
28174 */
28175 App.prototype.isScrolling = function () {
28176 var /** @type {?} */ scrollTime = this._scrollTime;
28177 if (scrollTime === 0) {
28178 return false;
28179 }
28180 if (scrollTime < Date.now()) {
28181 this._scrollTime = 0;
28182 return false;
28183 }
28184 return true;
28185 };
28186 /**
28187 * @return {?}
28188 */
28189 App.prototype.getActiveNav = function () {
28190 console.warn('(getActiveNav) is deprecated and will be removed in the next major release. Use getActiveNavs instead.');
28191 var /** @type {?} */ navs = this.getActiveNavs();
28192 if (navs && navs.length) {
28193 return navs[0];
28194 }
28195 return null;
28196 };
28197 /**
28198 * @param {?=} rootNavId
28199 * @return {?}
28200 */
28201 App.prototype.getActiveNavs = function (rootNavId) {
28202 var /** @type {?} */ portal = this._appRoot._getPortal(PORTAL_MODAL);
28203 if (portal.length() > 0) {
28204 return (findTopNavs(portal));
28205 }
28206 if (!this._rootNavs || !this._rootNavs.size) {
28207 return [];
28208 }
28209 if (this._rootNavs.size === 1) {
28210 return (findTopNavs(this._rootNavs.values().next().value));
28211 }
28212 if (rootNavId) {
28213 return (findTopNavs(this._rootNavs.get(rootNavId)));
28214 }
28215 // fallback to just using all root names
28216 var /** @type {?} */ activeNavs = [];
28217 this._rootNavs.forEach(function (nav) {
28218 var /** @type {?} */ topNavs = findTopNavs(nav);
28219 activeNavs = activeNavs.concat(topNavs);
28220 });
28221 return (activeNavs);
28222 };
28223 /**
28224 * @return {?}
28225 */
28226 App.prototype.getRootNav = function () {
28227 console.warn('(getRootNav) is deprecated and will be removed in the next major release. Use getRootNavById instead.');
28228 var /** @type {?} */ rootNavs = this.getRootNavs();
28229 if (rootNavs.length === 0) {
28230 return null;
28231 }
28232 else if (rootNavs.length > 1) {
28233 console.warn('(getRootNav) there are multiple root navs, use getRootNavs instead');
28234 }
28235 return rootNavs[0];
28236 };
28237 /**
28238 * @return {?}
28239 */
28240 App.prototype.getRootNavs = function () {
28241 var /** @type {?} */ navs = [];
28242 this._rootNavs.forEach(function (nav) { return navs.push(nav); });
28243 return navs;
28244 };
28245 /**
28246 * @param {?} navId
28247 * @return {?}
28248 */
28249 App.prototype.getRootNavById = function (navId) {
28250 return this._rootNavs.get(navId);
28251 };
28252 /**
28253 * @hidden
28254 * @param {?} nav
28255 * @return {?}
28256 */
28257 App.prototype.registerRootNav = function (nav) {
28258 this._rootNavs.set(nav.id, nav);
28259 };
28260 /**
28261 * @return {?}
28262 */
28263 App.prototype.getActiveNavContainers = function () {
28264 // for each root nav container, get it's active nav
28265 var /** @type {?} */ list = [];
28266 this._rootNavs.forEach(function (container) {
28267 list = list.concat(findTopNavs(container));
28268 });
28269 return list;
28270 };
28271 /**
28272 * @hidden
28273 * @param {?} enteringView
28274 * @param {?} opts
28275 * @param {?=} appPortal
28276 * @return {?}
28277 */
28278 App.prototype.present = function (enteringView, opts, appPortal) {
28279 (void 0) /* assert */;
28280 var /** @type {?} */ portal = this._appRoot._getPortal(appPortal);
28281 // Set Nav must be set here in order to dimiss() work synchnously.
28282 // TODO: move _setNav() to the earlier stages of NavController. _queueTrns()
28283 enteringView._setNav(portal);
28284 opts.direction = DIRECTION_FORWARD;
28285 if (!opts.animation) {
28286 opts.animation = enteringView.getTransitionName(DIRECTION_FORWARD);
28287 }
28288 enteringView.setLeavingOpts({
28289 keyboardClose: opts.keyboardClose,
28290 direction: DIRECTION_BACK,
28291 animation: enteringView.getTransitionName(DIRECTION_BACK),
28292 ev: opts.ev
28293 });
28294 return portal.insertPages(-1, [enteringView], opts);
28295 };
28296 /**
28297 * @hidden
28298 * @return {?}
28299 */
28300 App.prototype.goBack = function () {
28301 if (this._menuCtrl && this._menuCtrl.isOpen()) {
28302 return this._menuCtrl.close();
28303 }
28304 var /** @type {?} */ navPromise = this.navPop();
28305 if (!navPromise) {
28306 // no views to go back to
28307 // let's exit the app
28308 if (this._config.getBoolean('navExitApp', true)) {
28309 (void 0) /* console.debug */;
28310 this._plt.exitApp();
28311 }
28312 }
28313 return navPromise;
28314 };
28315 /**
28316 * @hidden
28317 * @return {?}
28318 */
28319 App.prototype.navPop = function () {
28320 var _this = this;
28321 if (!this._rootNavs || this._rootNavs.size === 0 || !this.isEnabled()) {
28322 return Promise.resolve();
28323 }
28324 // If there are any alert/actionsheet open, let's do nothing
28325 var /** @type {?} */ portal = this._appRoot._getPortal(PORTAL_DEFAULT);
28326 if (portal.length() > 0) {
28327 return Promise.resolve();
28328 }
28329 var /** @type {?} */ navToPop = null;
28330 var /** @type {?} */ mostRecentVC = null;
28331 this._rootNavs.forEach(function (navContainer) {
28332 var /** @type {?} */ activeNavs = _this.getActiveNavs(navContainer.id);
28333 var /** @type {?} */ poppableNavs = activeNavs.map(function (activeNav) { return getPoppableNav(activeNav); }).filter(function (nav) { return !!nav; });
28334 poppableNavs.forEach(function (poppable) {
28335 var /** @type {?} */ topViewController = poppable.last();
28336 if (poppable._isPortal || (topViewController && poppable.length() > 1 && (!mostRecentVC || topViewController._ts >= mostRecentVC._ts))) {
28337 mostRecentVC = topViewController;
28338 navToPop = poppable;
28339 }
28340 });
28341 });
28342 if (navToPop) {
28343 return navToPop.pop();
28344 }
28345 };
28346 /**
28347 * @hidden
28348 * @return {?}
28349 */
28350 App.prototype._enableInputBlurring = function () {
28351 (void 0) /* console.debug */;
28352 var /** @type {?} */ focused = true;
28353 var /** @type {?} */ self = this;
28354 var /** @type {?} */ platform = this._plt;
28355 platform.registerListener(platform.doc(), 'focusin', onFocusin, { capture: true, zone: false, passive: true });
28356 platform.registerListener(platform.doc(), 'touchend', onTouchend, { capture: false, zone: false, passive: true });
28357 /**
28358 * @return {?}
28359 */
28360 function onFocusin() {
28361 focused = true;
28362 }
28363 /**
28364 * @param {?} ev
28365 * @return {?}
28366 */
28367 function onTouchend(ev) {
28368 // if app did scroll return early
28369 if (self._didScroll) {
28370 self._didScroll = false;
28371 return;
28372 }
28373 var /** @type {?} */ active = (self._plt.getActiveElement());
28374 if (!active) {
28375 return;
28376 }
28377 // only blur if the active element is a text-input or a textarea
28378 if (SKIP_BLURRING.indexOf(active.tagName) === -1) {
28379 return;
28380 }
28381 // if the selected target is the active element, do not blur
28382 var /** @type {?} */ tapped = ev.target;
28383 if (tapped === active) {
28384 return;
28385 }
28386 if (SKIP_BLURRING.indexOf(tapped.tagName) >= 0) {
28387 return;
28388 }
28389 // skip if div is a cover
28390 if (tapped.classList.contains('input-cover')) {
28391 return;
28392 }
28393 focused = false;
28394 // TODO: find a better way, why 50ms?
28395 platform.timeout(function () {
28396 if (!focused) {
28397 active.blur();
28398 }
28399 }, 50);
28400 }
28401 };
28402 /**
28403 * @param {?} id
28404 * @return {?}
28405 */
28406 App.prototype.getNavByIdOrName = function (id) {
28407 var /** @type {?} */ navs = Array.from(this._rootNavs.values());
28408 for (var _i = 0, navs_1 = navs; _i < navs_1.length; _i++) {
28409 var navContainer = navs_1[_i];
28410 var /** @type {?} */ match = getNavByIdOrName(navContainer, id);
28411 if (match) {
28412 return match;
28413 }
28414 }
28415 return null;
28416 };
28417 return App;
28418}());
28419App.decorators = [
28420 { type: Injectable },
28421];
28422/**
28423 * @nocollapse
28424 */
28425App.ctorParameters = function () { return [
28426 { type: Config, },
28427 { type: Platform, },
28428 { type: MenuController, decorators: [{ type: Optional },] },
28429]; };
28430/**
28431 * @param {?} nav
28432 * @param {?} id
28433 * @return {?}
28434 */
28435function getNavByIdOrName(nav, id) {
28436 if (nav.id === id || nav.name === id) {
28437 return nav;
28438 }
28439 for (var _i = 0, _a = nav.getAllChildNavs(); _i < _a.length; _i++) {
28440 var child = _a[_i];
28441 var /** @type {?} */ tmp = getNavByIdOrName(child, id);
28442 if (tmp) {
28443 return tmp;
28444 }
28445 }
28446 return null;
28447}
28448/**
28449 * @param {?} nav
28450 * @return {?}
28451 */
28452function getPoppableNav(nav) {
28453 if (!nav) {
28454 return null;
28455 }
28456 if (isTabs(nav)) {
28457 // tabs aren't a nav, so just call this function again immediately on the parent on tabs
28458 return getPoppableNav(nav.parent);
28459 }
28460 var /** @type {?} */ len = nav.length();
28461 if (len > 1 || (nav._isPortal && len > 0)) {
28462 // this nav controller has more than one view
28463 // use this nav!
28464 return nav;
28465 }
28466 // try again using the parent nav (if there is one)
28467 return getPoppableNav(nav.parent);
28468}
28469/**
28470 * @param {?} nav
28471 * @return {?}
28472 */
28473function findTopNavs(nav) {
28474 var /** @type {?} */ containers = [];
28475 var /** @type {?} */ childNavs = nav.getActiveChildNavs();
28476 if (!childNavs || !childNavs.length) {
28477 containers.push(nav);
28478 }
28479 else {
28480 childNavs.forEach(function (childNav) {
28481 var /** @type {?} */ topNavs = findTopNavs(childNav);
28482 containers = containers.concat(topNavs);
28483 });
28484 }
28485 return containers;
28486}
28487var SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];
28488var ACTIVE_SCROLLING_TIME = 100;
28489var CLICK_BLOCK_BUFFER_IN_MILLIS = 64;
28490
28491/**
28492 * @hidden
28493 */
28494var Ion = (function () {
28495 /**
28496 * @param {?} config
28497 * @param {?} elementRef
28498 * @param {?} renderer
28499 * @param {?=} componentName
28500 */
28501 function Ion(config, elementRef, renderer, componentName) {
28502 this._config = config;
28503 this._elementRef = elementRef;
28504 this._renderer = renderer;
28505 this._componentName = componentName;
28506 if (componentName) {
28507 this._setComponentName();
28508 this._setMode(config.get('mode'));
28509 }
28510 }
28511 Object.defineProperty(Ion.prototype, "color", {
28512 /**
28513 * @return {?}
28514 */
28515 get: function () {
28516 return this._color;
28517 },
28518 /**
28519 * \@input {string} The color to use from your Sass `$colors` map.
28520 * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
28521 * For more information, see [Theming your App](/docs/theming/theming-your-app).
28522 * @param {?} val
28523 * @return {?}
28524 */
28525 set: function (val) {
28526 this._setColor(val);
28527 },
28528 enumerable: true,
28529 configurable: true
28530 });
28531 Object.defineProperty(Ion.prototype, "mode", {
28532 /**
28533 * @return {?}
28534 */
28535 get: function () {
28536 return this._mode;
28537 },
28538 /**
28539 * \@input {string} The mode determines which platform styles to use.
28540 * Possible values are: `"ios"`, `"md"`, or `"wp"`.
28541 * For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
28542 * @param {?} val
28543 * @return {?}
28544 */
28545 set: function (val) {
28546 this._setMode(val);
28547 },
28548 enumerable: true,
28549 configurable: true
28550 });
28551 /**
28552 * @hidden
28553 * @param {?} className
28554 * @param {?} isAdd
28555 * @return {?}
28556 */
28557 Ion.prototype.setElementClass = function (className, isAdd) {
28558 this._renderer.setElementClass(this._elementRef.nativeElement, className, isAdd);
28559 };
28560 /**
28561 * @hidden
28562 * @param {?} attributeName
28563 * @param {?} attributeValue
28564 * @return {?}
28565 */
28566 Ion.prototype.setElementAttribute = function (attributeName, attributeValue) {
28567 this._renderer.setElementAttribute(this._elementRef.nativeElement, attributeName, attributeValue);
28568 };
28569 /**
28570 * @hidden
28571 * @param {?} property
28572 * @param {?} value
28573 * @return {?}
28574 */
28575 Ion.prototype.setElementStyle = function (property, value) {
28576 this._renderer.setElementStyle(this._elementRef.nativeElement, property, value);
28577 };
28578 /**
28579 * @hidden
28580 * @param {?} newColor
28581 * @param {?=} componentName
28582 * @return {?}
28583 */
28584 Ion.prototype._setColor = function (newColor, componentName) {
28585 if (componentName) {
28586 // This is needed for the item-radio
28587 this._componentName = componentName;
28588 }
28589 if (this._color) {
28590 this.setElementClass(this._componentName + "-" + this._mode + "-" + this._color, false);
28591 }
28592 if (newColor) {
28593 this.setElementClass(this._componentName + "-" + this._mode + "-" + newColor, true);
28594 this._color = newColor;
28595 }
28596 };
28597 /**
28598 * @hidden
28599 * @param {?} newMode
28600 * @return {?}
28601 */
28602 Ion.prototype._setMode = function (newMode) {
28603 if (this._mode) {
28604 this.setElementClass(this._componentName + "-" + this._mode, false);
28605 }
28606 if (newMode) {
28607 this.setElementClass(this._componentName + "-" + newMode, true);
28608 // Remove the color class associated with the previous mode,
28609 // change the mode, then add the new color class
28610 this._setColor(null);
28611 this._mode = newMode;
28612 this._setColor(this._color);
28613 }
28614 };
28615 /**
28616 * @hidden
28617 * @return {?}
28618 */
28619 Ion.prototype._setComponentName = function () {
28620 this.setElementClass(this._componentName, true);
28621 };
28622 /**
28623 * @hidden
28624 * @return {?}
28625 */
28626 Ion.prototype.getElementRef = function () {
28627 return this._elementRef;
28628 };
28629 /**
28630 * @hidden
28631 * @return {?}
28632 */
28633 Ion.prototype.getNativeElement = function () {
28634 return this._elementRef.nativeElement;
28635 };
28636 return Ion;
28637}());
28638Ion.propDecorators = {
28639 'color': [{ type: Input },],
28640 'mode': [{ type: Input },],
28641};
28642
28643/**
28644 * @hidden
28645 */
28646var UrlSerializer = (function () {
28647 /**
28648 * @param {?} _app
28649 * @param {?} config
28650 */
28651 function UrlSerializer(_app, config) {
28652 this._app = _app;
28653 if (config && isArray$2(config.links)) {
28654 this.links = normalizeLinks(config.links);
28655 }
28656 else {
28657 this.links = [];
28658 }
28659 }
28660 /**
28661 * Parse the URL into a Path, which is made up of multiple NavSegments.
28662 * Match which components belong to each segment.
28663 * @param {?} browserUrl
28664 * @return {?}
28665 */
28666 UrlSerializer.prototype.parse = function (browserUrl) {
28667 if (browserUrl.charAt(0) === '/') {
28668 browserUrl = browserUrl.substr(1);
28669 }
28670 // trim off data after ? and #
28671 browserUrl = browserUrl.split('?')[0].split('#')[0];
28672 return convertUrlToSegments(this._app, browserUrl, this.links);
28673 };
28674 /**
28675 * @param {?} navContainer
28676 * @param {?} nameOrComponent
28677 * @return {?}
28678 */
28679 UrlSerializer.prototype.createSegmentFromName = function (navContainer, nameOrComponent) {
28680 var /** @type {?} */ configLink = this.getLinkFromName(nameOrComponent);
28681 if (configLink) {
28682 return this._createSegment(this._app, navContainer, configLink, null);
28683 }
28684 return null;
28685 };
28686 /**
28687 * @param {?} nameOrComponent
28688 * @return {?}
28689 */
28690 UrlSerializer.prototype.getLinkFromName = function (nameOrComponent) {
28691 return this.links.find(function (link) {
28692 return (link.component === nameOrComponent) ||
28693 (link.name === nameOrComponent);
28694 });
28695 };
28696 /**
28697 * Serialize a path, which is made up of multiple NavSegments,
28698 * into a URL string. Turn each segment into a string and concat them to a URL.
28699 * @param {?} segments
28700 * @return {?}
28701 */
28702 UrlSerializer.prototype.serialize = function (segments) {
28703 if (!segments || !segments.length) {
28704 return '/';
28705 }
28706 var /** @type {?} */ sections = segments.map(function (segment) {
28707 if (segment.type === 'tabs') {
28708 if (segment.requiresExplicitNavPrefix) {
28709 return "/" + segment.type + "/" + segment.navId + "/" + segment.secondaryId + "/" + segment.id;
28710 }
28711 return "/" + segment.secondaryId + "/" + segment.id;
28712 }
28713 // it's a nav
28714 if (segment.requiresExplicitNavPrefix) {
28715 return "/" + segment.type + "/" + segment.navId + "/" + segment.id;
28716 }
28717 return "/" + segment.id;
28718 });
28719 return sections.join('');
28720 };
28721 /**
28722 * Serializes a component and its data into a NavSegment.
28723 * @param {?} navContainer
28724 * @param {?} component
28725 * @param {?} data
28726 * @return {?}
28727 */
28728 UrlSerializer.prototype.serializeComponent = function (navContainer, component, data) {
28729 if (component) {
28730 var /** @type {?} */ link = findLinkByComponentData(this.links, component, data);
28731 if (link) {
28732 return this._createSegment(this._app, navContainer, link, data);
28733 }
28734 }
28735 return null;
28736 };
28737 /**
28738 * \@internal
28739 * @param {?} app
28740 * @param {?} navContainer
28741 * @param {?} configLink
28742 * @param {?} data
28743 * @return {?}
28744 */
28745 UrlSerializer.prototype._createSegment = function (app, navContainer, configLink, data) {
28746 var /** @type {?} */ urlParts = configLink.segmentParts;
28747 if (isPresent(data)) {
28748 // create a copy of the original parts in the link config
28749 urlParts = urlParts.slice();
28750 // loop through all the data and convert it to a string
28751 var /** @type {?} */ keys = Object.keys(data);
28752 var /** @type {?} */ keysLength = keys.length;
28753 if (keysLength) {
28754 for (var /** @type {?} */ i = 0; i < urlParts.length; i++) {
28755 if (urlParts[i].charAt(0) === ':') {
28756 for (var /** @type {?} */ j = 0; j < keysLength; j++) {
28757 if (urlParts[i] === ":" + keys[j]) {
28758 // this data goes into the URL part (between slashes)
28759 urlParts[i] = encodeURIComponent(data[keys[j]]);
28760 break;
28761 }
28762 }
28763 }
28764 }
28765 }
28766 }
28767 var /** @type {?} */ requiresExplicitPrefix = true;
28768 if (navContainer.parent) {
28769 requiresExplicitPrefix = navContainer.parent && navContainer.parent.getAllChildNavs().length > 1;
28770 }
28771 else {
28772 // if it's a root nav, and there are multiple root navs, we need an explicit prefix
28773 requiresExplicitPrefix = app.getRootNavById(navContainer.id) && app.getRootNavs().length > 1;
28774 }
28775 return {
28776 id: urlParts.join('/'),
28777 name: configLink.name,
28778 component: configLink.component,
28779 loadChildren: configLink.loadChildren,
28780 data: data,
28781 defaultHistory: configLink.defaultHistory,
28782 navId: navContainer.name || navContainer.id,
28783 type: navContainer.getType(),
28784 secondaryId: navContainer.getSecondaryIdentifier(),
28785 requiresExplicitNavPrefix: requiresExplicitPrefix
28786 };
28787 };
28788 return UrlSerializer;
28789}());
28790/**
28791 * @param {?} name
28792 * @return {?}
28793 */
28794function formatUrlPart(name) {
28795 name = name.replace(URL_REPLACE_REG, '-');
28796 name = name.charAt(0).toLowerCase() + name.substring(1).replace(/[A-Z]/g, function (match) {
28797 return '-' + match.toLowerCase();
28798 });
28799 while (name.indexOf('--') > -1) {
28800 name = name.replace('--', '-');
28801 }
28802 if (name.charAt(0) === '-') {
28803 name = name.substring(1);
28804 }
28805 if (name.substring(name.length - 1) === '-') {
28806 name = name.substring(0, name.length - 1);
28807 }
28808 return encodeURIComponent(name);
28809}
28810var isPartMatch = function (urlPart, configLinkPart) {
28811 if (isPresent(urlPart) && isPresent(configLinkPart)) {
28812 if (configLinkPart.charAt(0) === ':') {
28813 return true;
28814 }
28815 return (urlPart === configLinkPart);
28816 }
28817 return false;
28818};
28819var createMatchedData = function (matchedUrlParts, link) {
28820 var /** @type {?} */ data = null;
28821 for (var /** @type {?} */ i = 0; i < link.segmentPartsLen; i++) {
28822 if (link.segmentParts[i].charAt(0) === ':') {
28823 data = data || {};
28824 data[link.segmentParts[i].substring(1)] = decodeURIComponent(matchedUrlParts[i]);
28825 }
28826 }
28827 return data;
28828};
28829var findLinkByComponentData = function (links, component, instanceData) {
28830 var /** @type {?} */ foundLink = null;
28831 var /** @type {?} */ foundLinkDataMatches = -1;
28832 for (var /** @type {?} */ i = 0; i < links.length; i++) {
28833 var /** @type {?} */ link = links[i];
28834 if (link.component === component) {
28835 // ok, so the component matched, but multiple links can point
28836 // to the same component, so let's make sure this is the right link
28837 var /** @type {?} */ dataMatches = 0;
28838 if (instanceData) {
28839 var /** @type {?} */ instanceDataKeys = Object.keys(instanceData);
28840 // this link has data
28841 for (var /** @type {?} */ j = 0; j < instanceDataKeys.length; j++) {
28842 if (isPresent(link.dataKeys[instanceDataKeys[j]])) {
28843 dataMatches++;
28844 }
28845 }
28846 }
28847 else if (link.dataLen) {
28848 // this component does not have data but the link does
28849 continue;
28850 }
28851 if (dataMatches >= foundLinkDataMatches) {
28852 foundLink = link;
28853 foundLinkDataMatches = dataMatches;
28854 }
28855 }
28856 }
28857 return foundLink;
28858};
28859var normalizeLinks = function (links) {
28860 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = links.length; i < ilen; i++) {
28861 var /** @type {?} */ link = links[i];
28862 if (isBlank$1(link.segment)) {
28863 link.segment = link.name;
28864 }
28865 link.dataKeys = {};
28866 link.segmentParts = link.segment.split('/');
28867 link.segmentPartsLen = link.segmentParts.length;
28868 // used for sorting
28869 link.staticLen = link.dataLen = 0;
28870 var /** @type {?} */ stillCountingStatic = true;
28871 for (var /** @type {?} */ j = 0; j < link.segmentPartsLen; j++) {
28872 if (link.segmentParts[j].charAt(0) === ':') {
28873 link.dataLen++;
28874 stillCountingStatic = false;
28875 link.dataKeys[link.segmentParts[j].substring(1)] = true;
28876 }
28877 else if (stillCountingStatic) {
28878 link.staticLen++;
28879 }
28880 }
28881 }
28882 // sort by the number of parts, with the links
28883 // with the most parts first
28884 return links.sort(sortConfigLinks);
28885};
28886/**
28887 * @param {?} a
28888 * @param {?} b
28889 * @return {?}
28890 */
28891function sortConfigLinks(a, b) {
28892 // sort by the number of parts
28893 if (a.segmentPartsLen > b.segmentPartsLen) {
28894 return -1;
28895 }
28896 if (a.segmentPartsLen < b.segmentPartsLen) {
28897 return 1;
28898 }
28899 // sort by the number of static parts in a row
28900 if (a.staticLen > b.staticLen) {
28901 return -1;
28902 }
28903 if (a.staticLen < b.staticLen) {
28904 return 1;
28905 }
28906 // sort by the number of total data parts
28907 if (a.dataLen < b.dataLen) {
28908 return -1;
28909 }
28910 if (a.dataLen > b.dataLen) {
28911 return 1;
28912 }
28913 return 0;
28914}
28915var URL_REPLACE_REG = /\s+|\?|\!|\$|\,|\.|\+|\"|\'|\*|\^|\||\/|\\|\[|\]|#|%|`|>|<|;|:|@|&|=/g;
28916/**
28917 * @hidden
28918 */
28919var DeepLinkConfigToken = new OpaqueToken('USERLINKS');
28920/**
28921 * @param {?} app
28922 * @param {?} userDeepLinkConfig
28923 * @return {?}
28924 */
28925function setupUrlSerializer(app, userDeepLinkConfig) {
28926 return new UrlSerializer(app, userDeepLinkConfig);
28927}
28928/**
28929 * @param {?} navGroupStrings
28930 * @return {?}
28931 */
28932function navGroupStringtoObjects(navGroupStrings) {
28933 // each string has a known format-ish, convert it to it
28934 return navGroupStrings.map(function (navGroupString) {
28935 var /** @type {?} */ sections = navGroupString.split('/');
28936 if (sections[0] === 'nav') {
28937 return {
28938 type: 'nav',
28939 navId: sections[1],
28940 niceId: sections[1],
28941 secondaryId: null,
28942 segmentPieces: sections.splice(2)
28943 };
28944 }
28945 else if (sections[0] === 'tabs') {
28946 return {
28947 type: 'tabs',
28948 navId: sections[1],
28949 niceId: sections[1],
28950 secondaryId: sections[2],
28951 segmentPieces: sections.splice(3)
28952 };
28953 }
28954 return {
28955 type: null,
28956 navId: null,
28957 niceId: null,
28958 secondaryId: null,
28959 segmentPieces: sections
28960 };
28961 });
28962}
28963/**
28964 * @param {?} url
28965 * @return {?}
28966 */
28967function urlToNavGroupStrings(url) {
28968 var /** @type {?} */ tokens = url.split('/');
28969 var /** @type {?} */ keywordIndexes = [];
28970 for (var /** @type {?} */ i = 0; i < tokens.length; i++) {
28971 if (i !== 0 && (tokens[i] === 'nav' || tokens[i] === 'tabs')) {
28972 keywordIndexes.push(i);
28973 }
28974 }
28975 // append the last index + 1 to the list no matter what
28976 keywordIndexes.push(tokens.length);
28977 var /** @type {?} */ groupings = [];
28978 var /** @type {?} */ activeKeywordIndex = 0;
28979 var /** @type {?} */ tmpArray = [];
28980 for (var /** @type {?} */ i = 0; i < tokens.length; i++) {
28981 if (i >= keywordIndexes[activeKeywordIndex]) {
28982 groupings.push(tmpArray.join('/'));
28983 tmpArray = [];
28984 activeKeywordIndex++;
28985 }
28986 tmpArray.push(tokens[i]);
28987 }
28988 // okay, after the loop we've gotta push one more time just to be safe
28989 groupings.push(tmpArray.join('/'));
28990 return groupings;
28991}
28992/**
28993 * @param {?} app
28994 * @param {?} url
28995 * @param {?} navLinks
28996 * @return {?}
28997 */
28998function convertUrlToSegments(app, url, navLinks) {
28999 var /** @type {?} */ pairs = convertUrlToDehydratedSegments(url, navLinks);
29000 return hydrateSegmentsWithNav(app, pairs);
29001}
29002/**
29003 * @param {?} url
29004 * @param {?} navLinks
29005 * @return {?}
29006 */
29007function convertUrlToDehydratedSegments(url, navLinks) {
29008 var /** @type {?} */ navGroupStrings = urlToNavGroupStrings(url);
29009 var /** @type {?} */ navGroups = navGroupStringtoObjects(navGroupStrings);
29010 return getSegmentsFromNavGroups(navGroups, navLinks);
29011}
29012/**
29013 * @param {?} app
29014 * @param {?} dehydratedSegmentPairs
29015 * @return {?}
29016 */
29017function hydrateSegmentsWithNav(app, dehydratedSegmentPairs) {
29018 var /** @type {?} */ segments = [];
29019 for (var /** @type {?} */ i = 0; i < dehydratedSegmentPairs.length; i++) {
29020 var /** @type {?} */ navs = getNavFromNavGroup(dehydratedSegmentPairs[i].navGroup, app);
29021 // okay, cool, let's walk through the segments and hydrate them
29022 for (var _i = 0, _a = dehydratedSegmentPairs[i].segments; _i < _a.length; _i++) {
29023 var dehydratedSegment = _a[_i];
29024 if (navs.length === 1) {
29025 segments.push(hydrateSegment(dehydratedSegment, navs[0]));
29026 navs = navs[0].getActiveChildNavs();
29027 }
29028 else if (navs.length > 1) {
29029 // this is almost certainly an async race condition bug in userland
29030 // if you're in this state, it would be nice to just bail here
29031 // but alas we must perservere and handle the issue
29032 // the simple solution is to just use the last child
29033 // because that is probably what the user wants anyway
29034 // remember, do not harm, even if it makes our shizzle ugly
29035 segments.push(hydrateSegment(dehydratedSegment, navs[navs.length - 1]));
29036 navs = navs[navs.length - 1].getActiveChildNavs();
29037 }
29038 else {
29039 break;
29040 }
29041 }
29042 }
29043 return segments;
29044}
29045/**
29046 * @param {?} navGroup
29047 * @param {?} app
29048 * @return {?}
29049 */
29050function getNavFromNavGroup(navGroup, app) {
29051 if (navGroup.navId) {
29052 var /** @type {?} */ rootNav = app.getNavByIdOrName(navGroup.navId);
29053 if (rootNav) {
29054 return [rootNav];
29055 }
29056 return [];
29057 }
29058 // we don't know what nav to use, so just use the root nav.
29059 // if there is more than one root nav, throw an error
29060 return app.getRootNavs();
29061}
29062/**
29063 * @param {?} navGroups
29064 * @param {?} navLinks
29065 * @return {?}
29066 */
29067function getSegmentsFromNavGroups(navGroups, navLinks) {
29068 var /** @type {?} */ pairs = [];
29069 var /** @type {?} */ usedNavLinks = new Set();
29070 for (var _i = 0, navGroups_1 = navGroups; _i < navGroups_1.length; _i++) {
29071 var navGroup = navGroups_1[_i];
29072 var /** @type {?} */ segments = [];
29073 var /** @type {?} */ segmentPieces = navGroup.segmentPieces.concat([]);
29074 for (var /** @type {?} */ i = segmentPieces.length; i >= 0; i--) {
29075 var /** @type {?} */ created = false;
29076 for (var /** @type {?} */ j = 0; j < i; j++) {
29077 var /** @type {?} */ startIndex = i - j - 1;
29078 var /** @type {?} */ endIndex = i;
29079 var /** @type {?} */ subsetOfUrl = segmentPieces.slice(startIndex, endIndex);
29080 for (var _a = 0, navLinks_1 = navLinks; _a < navLinks_1.length; _a++) {
29081 var navLink = navLinks_1[_a];
29082 if (!usedNavLinks.has(navLink.name)) {
29083 var /** @type {?} */ segment = getSegmentsFromUrlPieces(subsetOfUrl, navLink);
29084 if (segment) {
29085 i = startIndex + 1;
29086 usedNavLinks.add(navLink.name);
29087 created = true;
29088 // sweet, we found a segment
29089 segments.push(segment);
29090 // now we want to null out the url subsection in the segmentPieces
29091 for (var /** @type {?} */ k = startIndex; k < endIndex; k++) {
29092 segmentPieces[k] = null;
29093 }
29094 break;
29095 }
29096 }
29097 }
29098 if (created) {
29099 break;
29100 }
29101 }
29102 if (!created && segmentPieces[i - 1]) {
29103 // this is very likely a tab's secondary identifier
29104 segments.push({
29105 id: null,
29106 name: null,
29107 secondaryId: segmentPieces[i - 1],
29108 component: null,
29109 loadChildren: null,
29110 data: null,
29111 defaultHistory: null
29112 });
29113 }
29114 }
29115 // since we're getting segments in from right-to-left in the url, reverse them
29116 // so they're in the correct order. Also filter out and bogus segments
29117 var /** @type {?} */ orderedSegments = segments.reverse();
29118 // okay, this is the lazy persons approach here.
29119 // so here's the deal! Right now if section of the url is not a part of a segment
29120 // it is almost certainly the secondaryId for a tabs component
29121 // basically, knowing the segment for the `tab` itself is good, but we also need to know
29122 // which tab is selected, so we have an identifer in the url that is associated with the tabs component
29123 // telling us which tab is selected. With that in mind, we are going to go through and find the segments with only secondary identifiers,
29124 // and simply add the secondaryId to the next segment, and then remove the empty segment from the list
29125 for (var /** @type {?} */ i = 0; i < orderedSegments.length; i++) {
29126 if (orderedSegments[i].secondaryId && !orderedSegments[i].id && ((i + 1) <= orderedSegments.length - 1)) {
29127 orderedSegments[i + 1].secondaryId = orderedSegments[i].secondaryId;
29128 orderedSegments[i] = null;
29129 }
29130 }
29131 var /** @type {?} */ cleanedSegments = segments.filter(function (segment) { return !!segment; });
29132 // if the nav group has a secondary id, make sure the first segment also has it set
29133 if (navGroup.secondaryId && segments.length) {
29134 cleanedSegments[0].secondaryId = navGroup.secondaryId;
29135 }
29136 pairs.push({
29137 navGroup: navGroup,
29138 segments: cleanedSegments
29139 });
29140 }
29141 return pairs;
29142}
29143/**
29144 * @param {?} urlSections
29145 * @param {?} navLink
29146 * @return {?}
29147 */
29148function getSegmentsFromUrlPieces(urlSections, navLink) {
29149 if (navLink.segmentPartsLen !== urlSections.length) {
29150 return null;
29151 }
29152 for (var /** @type {?} */ i = 0; i < urlSections.length; i++) {
29153 if (!isPartMatch(urlSections[i], navLink.segmentParts[i])) {
29154 // just return an empty array if the part doesn't match
29155 return null;
29156 }
29157 }
29158 return {
29159 id: urlSections.join('/'),
29160 name: navLink.name,
29161 component: navLink.component,
29162 loadChildren: navLink.loadChildren,
29163 data: createMatchedData(urlSections, navLink),
29164 defaultHistory: navLink.defaultHistory
29165 };
29166}
29167/**
29168 * @param {?} segment
29169 * @param {?} nav
29170 * @return {?}
29171 */
29172function hydrateSegment(segment, nav) {
29173 var /** @type {?} */ hydratedSegment = (Object.assign({}, segment));
29174 hydratedSegment.type = nav.getType();
29175 hydratedSegment.navId = nav.name || nav.id;
29176 // secondaryId is set on an empty dehydrated segment in the case of tabs to identify which tab is selected
29177 hydratedSegment.secondaryId = segment.secondaryId;
29178 return hydratedSegment;
29179}
29180/**
29181 * @param {?} urlChunks
29182 * @param {?} navLink
29183 * @return {?}
29184 */
29185
29186/**
29187 * @hidden
29188 */
29189var DeepLinker = (function () {
29190 /**
29191 * @param {?} _app
29192 * @param {?} _serializer
29193 * @param {?} _location
29194 * @param {?} _moduleLoader
29195 * @param {?} _baseCfr
29196 */
29197 function DeepLinker(_app, _serializer, _location, _moduleLoader, _baseCfr) {
29198 this._app = _app;
29199 this._serializer = _serializer;
29200 this._location = _location;
29201 this._moduleLoader = _moduleLoader;
29202 this._baseCfr = _baseCfr;
29203 /**
29204 * \@internal
29205 */
29206 this._history = [];
29207 }
29208 /**
29209 * \@internal
29210 * @return {?}
29211 */
29212 DeepLinker.prototype.init = function () {
29213 var _this = this;
29214 // scenario 1: Initial load of all navs from the initial browser URL
29215 var /** @type {?} */ browserUrl = normalizeUrl(this._location.path());
29216 (void 0) /* console.debug */;
29217 // remember this URL in our internal history stack
29218 this._historyPush(browserUrl);
29219 // listen for browser URL changes
29220 this._location.subscribe(function (locationChg) {
29221 _this._urlChange(normalizeUrl(locationChg.url));
29222 });
29223 };
29224 /**
29225 * The browser's location has been updated somehow.
29226 * \@internal
29227 * @param {?} browserUrl
29228 * @return {?}
29229 */
29230 DeepLinker.prototype._urlChange = function (browserUrl) {
29231 var _this = this;
29232 // do nothing if this url is the same as the current one
29233 if (!this._isCurrentUrl(browserUrl)) {
29234 var /** @type {?} */ isGoingBack = true;
29235 if (this._isBackUrl(browserUrl)) {
29236 // scenario 2: user clicked the browser back button
29237 // scenario 4: user changed the browser URL to what was the back url was
29238 // scenario 5: user clicked a link href that was the back url
29239 (void 0) /* console.debug */;
29240 this._historyPop();
29241 }
29242 else {
29243 // scenario 3: user click forward button
29244 // scenario 4: user changed browser URL that wasn't the back url
29245 // scenario 5: user clicked a link href that wasn't the back url
29246 isGoingBack = false;
29247 (void 0) /* console.debug */;
29248 this._historyPush(browserUrl);
29249 }
29250 // get the app's root nav container
29251 var /** @type {?} */ activeNavContainers_1 = this._app.getActiveNavContainers();
29252 if (activeNavContainers_1 && activeNavContainers_1.length) {
29253 if (browserUrl === '/') {
29254 // a url change to the index url
29255 if (isPresent(this._indexAliasUrl)) {
29256 // we already know the indexAliasUrl
29257 // update the url to use the know alias
29258 browserUrl = this._indexAliasUrl;
29259 }
29260 else {
29261 // the url change is to the root but we don't
29262 // already know the url used. So let's just
29263 // reset the root nav to its root page
29264 activeNavContainers_1.forEach(function (navContainer) {
29265 navContainer.goToRoot({
29266 updateUrl: false,
29267 isNavRoot: true
29268 });
29269 });
29270 return;
29271 }
29272 }
29273 // normal url
29274 var /** @type {?} */ segments = this.getCurrentSegments(browserUrl);
29275 segments
29276 .map(function (segment) {
29277 // find the matching nav container
29278 for (var _i = 0, activeNavContainers_2 = activeNavContainers_1; _i < activeNavContainers_2.length; _i++) {
29279 var navContainer = activeNavContainers_2[_i];
29280 var /** @type {?} */ nav = getNavFromTree(navContainer, segment.navId);
29281 if (nav) {
29282 return {
29283 segment: segment,
29284 navContainer: nav
29285 };
29286 }
29287 }
29288 })
29289 .filter(function (pair) { return !!pair; })
29290 .forEach(function (pair) {
29291 _this._loadViewForSegment(pair.navContainer, pair.segment, function () { });
29292 });
29293 }
29294 }
29295 };
29296 /**
29297 * @param {?=} browserUrl
29298 * @return {?}
29299 */
29300 DeepLinker.prototype.getCurrentSegments = function (browserUrl) {
29301 if (!browserUrl) {
29302 browserUrl = normalizeUrl(this._location.path());
29303 }
29304 return this._serializer.parse(browserUrl);
29305 };
29306 /**
29307 * Update the deep linker using the NavController's current active view.
29308 * \@internal
29309 * @param {?} direction
29310 * @return {?}
29311 */
29312 DeepLinker.prototype.navChange = function (direction) {
29313 if (direction) {
29314 var /** @type {?} */ activeNavContainers = this._app.getActiveNavContainers();
29315 // the only time you'll ever get a TABS here is when loading directly from a URL
29316 // this method will be called again when the TAB is loaded
29317 // so just don't worry about the TABS for now
29318 // if you encounter a TABS, just return
29319 for (var _i = 0, activeNavContainers_3 = activeNavContainers; _i < activeNavContainers_3.length; _i++) {
29320 var activeNavContainer = activeNavContainers_3[_i];
29321 if (isTabs(activeNavContainer) || ((activeNavContainer)).isTransitioning()) {
29322 return;
29323 }
29324 }
29325 // okay, get the root navs and build the segments up
29326 var /** @type {?} */ segments = [];
29327 var /** @type {?} */ navContainers = this._app.getRootNavs();
29328 for (var _a = 0, navContainers_1 = navContainers; _a < navContainers_1.length; _a++) {
29329 var navContainer = navContainers_1[_a];
29330 var /** @type {?} */ segmentsForNav = this.getSegmentsFromNav(navContainer);
29331 segments = segments.concat(segmentsForNav);
29332 }
29333 segments = segments.filter(function (segment) { return !!segment; });
29334 if (segments.length) {
29335 var /** @type {?} */ browserUrl = this._serializer.serialize(segments);
29336 this._updateLocation(browserUrl, direction);
29337 }
29338 }
29339 };
29340 /**
29341 * @param {?} nav
29342 * @return {?}
29343 */
29344 DeepLinker.prototype.getSegmentsFromNav = function (nav) {
29345 var _this = this;
29346 var /** @type {?} */ segments = [];
29347 if (isNav(nav)) {
29348 segments.push(this.getSegmentFromNav(/** @type {?} */ (nav)));
29349 }
29350 else if (isTab(nav)) {
29351 segments.push(this.getSegmentFromTab(nav));
29352 }
29353 nav.getActiveChildNavs().forEach(function (child) {
29354 segments = segments.concat(_this.getSegmentsFromNav(child));
29355 });
29356 return segments;
29357 };
29358 /**
29359 * @param {?} nav
29360 * @param {?=} component
29361 * @param {?=} data
29362 * @return {?}
29363 */
29364 DeepLinker.prototype.getSegmentFromNav = function (nav, component, data) {
29365 if (!component) {
29366 var /** @type {?} */ viewController = nav.getActive(true);
29367 if (viewController) {
29368 component = viewController.component;
29369 data = viewController.data;
29370 }
29371 }
29372 return this._serializer.serializeComponent(nav, component, data);
29373 };
29374 /**
29375 * @param {?} navContainer
29376 * @param {?=} component
29377 * @param {?=} data
29378 * @return {?}
29379 */
29380 DeepLinker.prototype.getSegmentFromTab = function (navContainer, component, data) {
29381 if (navContainer && navContainer.parent) {
29382 var /** @type {?} */ tabsNavContainer = (navContainer.parent);
29383 var /** @type {?} */ activeChildNavs = tabsNavContainer.getActiveChildNavs();
29384 if (activeChildNavs && activeChildNavs.length) {
29385 var /** @type {?} */ activeChildNav = activeChildNavs[0];
29386 var /** @type {?} */ viewController = ((activeChildNav)).getActive(true);
29387 if (viewController) {
29388 component = viewController.component;
29389 data = viewController.data;
29390 }
29391 return this._serializer.serializeComponent(tabsNavContainer, component, data);
29392 }
29393 }
29394 };
29395 /**
29396 * \@internal
29397 * @param {?} browserUrl
29398 * @param {?} direction
29399 * @return {?}
29400 */
29401 DeepLinker.prototype._updateLocation = function (browserUrl, direction) {
29402 if (this._indexAliasUrl === browserUrl) {
29403 browserUrl = '/';
29404 }
29405 if (direction === DIRECTION_BACK && this._isBackUrl(browserUrl)) {
29406 // this URL is exactly the same as the back URL
29407 // it's safe to use the browser's location.back()
29408 (void 0) /* console.debug */;
29409 this._historyPop();
29410 this._location.back();
29411 }
29412 else if (!this._isCurrentUrl(browserUrl)) {
29413 // probably navigating forward
29414 (void 0) /* console.debug */;
29415 this._historyPush(browserUrl);
29416 this._location.go(browserUrl);
29417 }
29418 };
29419 /**
29420 * @param {?} componentName
29421 * @return {?}
29422 */
29423 DeepLinker.prototype.getComponentFromName = function (componentName) {
29424 var /** @type {?} */ link = this._serializer.getLinkFromName(componentName);
29425 if (link) {
29426 // cool, we found the right link for this component name
29427 return this.getNavLinkComponent(link);
29428 }
29429 // umm, idk
29430 return Promise.reject("invalid link: " + componentName);
29431 };
29432 /**
29433 * @param {?} link
29434 * @return {?}
29435 */
29436 DeepLinker.prototype.getNavLinkComponent = function (link) {
29437 if (link.component) {
29438 // sweet, we're already got a component loaded for this link
29439 return Promise.resolve(link.component);
29440 }
29441 if (link.loadChildren) {
29442 // awesome, looks like we'll lazy load this component
29443 // using loadChildren as the URL to request
29444 return this._moduleLoader.load(link.loadChildren).then(function (response) {
29445 link.component = response.component;
29446 return response.component;
29447 });
29448 }
29449 return Promise.reject("invalid link component: " + link.name);
29450 };
29451 /**
29452 * \@internal
29453 * @param {?} component
29454 * @return {?}
29455 */
29456 DeepLinker.prototype.resolveComponent = function (component) {
29457 var /** @type {?} */ cfr = this._moduleLoader.getComponentFactoryResolver(component);
29458 if (!cfr) {
29459 cfr = this._baseCfr;
29460 }
29461 return cfr.resolveComponentFactory(component);
29462 };
29463 /**
29464 * \@internal
29465 * @param {?} navContainer
29466 * @param {?} nameOrComponent
29467 * @param {?} _data
29468 * @param {?=} prepareExternalUrl
29469 * @return {?}
29470 */
29471 DeepLinker.prototype.createUrl = function (navContainer, nameOrComponent, _data, prepareExternalUrl) {
29472 if (prepareExternalUrl === void 0) { prepareExternalUrl = true; }
29473 // create a segment out of just the passed in name
29474 var /** @type {?} */ segment = this._serializer.createSegmentFromName(navContainer, nameOrComponent);
29475 var /** @type {?} */ allSegments = this.getCurrentSegments();
29476 if (segment) {
29477 for (var /** @type {?} */ i = 0; i < allSegments.length; i++) {
29478 if (allSegments[i].navId === navContainer.name || allSegments[i].navId === navContainer.id) {
29479 allSegments[i] = segment;
29480 var /** @type {?} */ url = this._serializer.serialize(allSegments);
29481 return prepareExternalUrl ? this._location.prepareExternalUrl(url) : url;
29482 }
29483 }
29484 }
29485 return '';
29486 };
29487 /**
29488 * Each NavController will call this method when it initializes for
29489 * the first time. This allows each NavController to figure out
29490 * where it lives in the path and load up the correct component.
29491 * \@internal
29492 * @param {?} navId
29493 * @param {?} name
29494 * @return {?}
29495 */
29496 DeepLinker.prototype.getSegmentByNavIdOrName = function (navId, name) {
29497 var /** @type {?} */ browserUrl = normalizeUrl(this._location.path());
29498 var /** @type {?} */ segments = this._serializer.parse(browserUrl);
29499 for (var _i = 0, segments_1 = segments; _i < segments_1.length; _i++) {
29500 var segment = segments_1[_i];
29501 if (segment.navId === navId || segment.navId === name) {
29502 return segment;
29503 }
29504 }
29505 return null;
29506 };
29507 /**
29508 * \@internal
29509 * @param {?} segment
29510 * @return {?}
29511 */
29512 DeepLinker.prototype.initViews = function (segment) {
29513 var _this = this;
29514 var /** @type {?} */ link = this._serializer.getLinkFromName(segment.name);
29515 return this.getNavLinkComponent(link).then(function (component) {
29516 segment.component = component;
29517 var /** @type {?} */ view = new ViewController(component, segment.data);
29518 view.id = segment.id;
29519 if (isArray$2(segment.defaultHistory)) {
29520 return convertToViews(_this, segment.defaultHistory).then(function (views) {
29521 views.push(view);
29522 return views;
29523 });
29524 }
29525 return [view];
29526 });
29527 };
29528 /**
29529 * \@internal
29530 * @param {?} browserUrl
29531 * @return {?}
29532 */
29533 DeepLinker.prototype._isBackUrl = function (browserUrl) {
29534 return (browserUrl === this._history[this._history.length - 2]);
29535 };
29536 /**
29537 * \@internal
29538 * @param {?} browserUrl
29539 * @return {?}
29540 */
29541 DeepLinker.prototype._isCurrentUrl = function (browserUrl) {
29542 return (browserUrl === this._history[this._history.length - 1]);
29543 };
29544 /**
29545 * \@internal
29546 * @param {?} browserUrl
29547 * @return {?}
29548 */
29549 DeepLinker.prototype._historyPush = function (browserUrl) {
29550 if (!this._isCurrentUrl(browserUrl)) {
29551 this._history.push(browserUrl);
29552 if (this._history.length > 30) {
29553 this._history.shift();
29554 }
29555 }
29556 };
29557 /**
29558 * \@internal
29559 * @return {?}
29560 */
29561 DeepLinker.prototype._historyPop = function () {
29562 this._history.pop();
29563 if (!this._history.length) {
29564 this._historyPush(this._location.path());
29565 }
29566 };
29567 /**
29568 * \@internal
29569 * @param {?} tab
29570 * @return {?}
29571 */
29572 DeepLinker.prototype._getTabSelector = function (tab) {
29573 if (isPresent(tab.tabUrlPath)) {
29574 return tab.tabUrlPath;
29575 }
29576 if (isPresent(tab.tabTitle)) {
29577 return formatUrlPart(tab.tabTitle);
29578 }
29579 return "tab-" + tab.index;
29580 };
29581 /**
29582 * Using the known Path of Segments, walk down all descendents
29583 * from the root NavController and load each NavController according
29584 * to each Segment. This is usually called after a browser URL and
29585 * Path changes and needs to update all NavControllers to match
29586 * the new browser URL. Because the URL is already known, it will
29587 * not update the browser's URL when transitions have completed.
29588 *
29589 * \@internal
29590 * @param {?} navContainer
29591 * @param {?} segment
29592 * @param {?} done
29593 * @return {?}
29594 */
29595 DeepLinker.prototype._loadViewForSegment = function (navContainer, segment, done) {
29596 if (!segment) {
29597 return done(false, false);
29598 }
29599 if (isTabs(navContainer) || (isTab(navContainer) && navContainer.parent)) {
29600 var /** @type {?} */ tabs = (((isTabs(navContainer) ? navContainer : navContainer.parent)));
29601 var /** @type {?} */ selectedIndex = tabs._getSelectedTabIndex(segment.secondaryId);
29602 var /** @type {?} */ tab = tabs.getByIndex(selectedIndex);
29603 tab._lazyRootFromUrl = segment.name;
29604 tab._lazyRootFromUrlData = segment.data;
29605 tabs.select(tab, {
29606 updateUrl: false,
29607 animate: false
29608 }, true);
29609 return done(false, false);
29610 }
29611 var /** @type {?} */ navController = ((navContainer));
29612 var /** @type {?} */ numViews = navController.length() - 1;
29613 // walk backwards to see if the exact view we want to show here
29614 // is already in the stack that we can just pop back to
29615 for (var /** @type {?} */ i = numViews; i >= 0; i--) {
29616 var /** @type {?} */ viewController = navController.getByIndex(i);
29617 if (viewController && (viewController.id === segment.id || viewController.id === segment.name)) {
29618 // hooray! we've already got a view loaded in the stack
29619 // matching the view they wanted to show
29620 if (i === numViews) {
29621 // this is the last view in the stack and it's the same
29622 // as the segment so there's no change needed
29623 return done(false, false);
29624 }
29625 else {
29626 // it's not the exact view as the end
29627 // let's have this nav go back to this exact view
29628 return navController.popTo(viewController, {
29629 animate: false,
29630 updateUrl: false,
29631 }, done);
29632 }
29633 }
29634 }
29635 // ok, so we don't know about a view that they're navigating to
29636 // so we might as well just call setRoot and make tthe view the first view
29637 // this seems like the least bad option
29638 return navController.setRoot(segment.component || segment.name, segment.data, {
29639 id: segment.id, animate: false, updateUrl: false
29640 }, done);
29641 };
29642 return DeepLinker;
29643}());
29644/**
29645 * @param {?} app
29646 * @param {?} serializer
29647 * @param {?} location
29648 * @param {?} moduleLoader
29649 * @param {?} cfr
29650 * @return {?}
29651 */
29652function setupDeepLinker(app, serializer, location, moduleLoader, cfr) {
29653 var /** @type {?} */ deepLinker = new DeepLinker(app, serializer, location, moduleLoader, cfr);
29654 deepLinker.init();
29655 return deepLinker;
29656}
29657/**
29658 * @param {?} browserUrl
29659 * @return {?}
29660 */
29661function normalizeUrl(browserUrl) {
29662 browserUrl = browserUrl.trim();
29663 if (browserUrl.charAt(0) !== '/') {
29664 // ensure first char is a /
29665 browserUrl = '/' + browserUrl;
29666 }
29667 if (browserUrl.length > 1 && browserUrl.charAt(browserUrl.length - 1) === '/') {
29668 // ensure last char is not a /
29669 browserUrl = browserUrl.substr(0, browserUrl.length - 1);
29670 }
29671 return browserUrl;
29672}
29673/**
29674 * @param {?} nav
29675 * @param {?} id
29676 * @return {?}
29677 */
29678function getNavFromTree(nav, id) {
29679 while (nav) {
29680 if (nav.id === id || nav.name === id) {
29681 return nav;
29682 }
29683 nav = nav.parent;
29684 }
29685 return null;
29686}
29687
29688/**
29689 * Adopted from FastDom
29690 * https://github.com/wilsonpage/fastdom
29691 * MIT License
29692 */
29693/**
29694 * @hidden
29695 */
29696var DomDebouncer = (function () {
29697 /**
29698 * @param {?} dom
29699 */
29700 function DomDebouncer(dom) {
29701 this.dom = dom;
29702 this.writeTask = null;
29703 this.readTask = null;
29704 }
29705 /**
29706 * @param {?} fn
29707 * @return {?}
29708 */
29709 DomDebouncer.prototype.read = function (fn) {
29710 var _this = this;
29711 if (this.readTask) {
29712 return;
29713 }
29714 return this.readTask = this.dom.read(function (t) {
29715 _this.readTask = null;
29716 fn(t);
29717 });
29718 };
29719 /**
29720 * @param {?} fn
29721 * @return {?}
29722 */
29723 DomDebouncer.prototype.write = function (fn) {
29724 var _this = this;
29725 if (this.writeTask) {
29726 return;
29727 }
29728 return this.writeTask = this.dom.write(function (t) {
29729 _this.writeTask = null;
29730 fn(t);
29731 });
29732 };
29733 /**
29734 * @return {?}
29735 */
29736 DomDebouncer.prototype.cancel = function () {
29737 var /** @type {?} */ writeTask = this.writeTask;
29738 writeTask && this.dom.cancel(writeTask);
29739 var /** @type {?} */ readTask = this.readTask;
29740 readTask && this.dom.cancel(readTask);
29741 this.readTask = this.writeTask = null;
29742 };
29743 return DomDebouncer;
29744}());
29745/**
29746 * @hidden
29747 */
29748var DomController = (function () {
29749 /**
29750 * @param {?} plt
29751 */
29752 function DomController(plt) {
29753 this.plt = plt;
29754 this.r = [];
29755 this.w = [];
29756 }
29757 /**
29758 * @return {?}
29759 */
29760 DomController.prototype.debouncer = function () {
29761 return new DomDebouncer(this);
29762 };
29763 /**
29764 * @param {?} fn
29765 * @param {?=} timeout
29766 * @return {?}
29767 */
29768 DomController.prototype.read = function (fn, timeout) {
29769 var _this = this;
29770 if (timeout) {
29771 ((fn)).timeoutId = this.plt.timeout(function () {
29772 _this.r.push(fn);
29773 _this._queue();
29774 }, timeout);
29775 }
29776 else {
29777 this.r.push(fn);
29778 this._queue();
29779 }
29780 return fn;
29781 };
29782 /**
29783 * @param {?} fn
29784 * @param {?=} timeout
29785 * @return {?}
29786 */
29787 DomController.prototype.write = function (fn, timeout) {
29788 var _this = this;
29789 if (timeout) {
29790 ((fn)).timeoutId = this.plt.timeout(function () {
29791 _this.w.push(fn);
29792 _this._queue();
29793 }, timeout);
29794 }
29795 else {
29796 this.w.push(fn);
29797 this._queue();
29798 }
29799 return fn;
29800 };
29801 /**
29802 * @param {?} fn
29803 * @return {?}
29804 */
29805 DomController.prototype.cancel = function (fn) {
29806 if (fn) {
29807 if (fn.timeoutId) {
29808 this.plt.cancelTimeout(fn.timeoutId);
29809 }
29810 removeArrayItem(this.r, fn) || removeArrayItem(this.w, fn);
29811 }
29812 };
29813 /**
29814 * @return {?}
29815 */
29816 DomController.prototype._queue = function () {
29817 var /** @type {?} */ self = this;
29818 if (!self.q) {
29819 self.q = true;
29820 self.plt.raf(function rafCallback(timeStamp) {
29821 self._flush(timeStamp);
29822 });
29823 }
29824 };
29825 /**
29826 * @param {?} timeStamp
29827 * @return {?}
29828 */
29829 DomController.prototype._flush = function (timeStamp) {
29830 var /** @type {?} */ err;
29831 try {
29832 dispatch(timeStamp, this.r, this.w);
29833 }
29834 catch (e) {
29835 err = e;
29836 }
29837 this.q = false;
29838 if (this.r.length || this.w.length) {
29839 this._queue();
29840 }
29841 if (err) {
29842 throw err;
29843 }
29844 };
29845 return DomController;
29846}());
29847DomController.decorators = [
29848 { type: Injectable },
29849];
29850/**
29851 * @nocollapse
29852 */
29853DomController.ctorParameters = function () { return [
29854 { type: Platform, },
29855]; };
29856/**
29857 * @param {?} timeStamp
29858 * @param {?} r
29859 * @param {?} w
29860 * @return {?}
29861 */
29862function dispatch(timeStamp, r, w) {
29863 var /** @type {?} */ fn;
29864 // ******** DOM READS ****************
29865 while (fn = r.shift()) {
29866 fn(timeStamp);
29867 }
29868 // ******** DOM WRITES ****************
29869 while (fn = w.shift()) {
29870 fn(timeStamp);
29871 }
29872}
29873
29874/**
29875 * @hidden
29876 */
29877var GESTURE_GO_BACK_SWIPE = 'goback-swipe';
29878/**
29879 * @hidden
29880 */
29881var GESTURE_MENU_SWIPE = 'menu-swipe';
29882/**
29883 * @hidden
29884 */
29885var GESTURE_ITEM_SWIPE = 'item-swipe';
29886/**
29887 * @hidden
29888 */
29889var GESTURE_REFRESHER = 'refresher';
29890/**
29891 * @hidden
29892 */
29893var GESTURE_TOGGLE = 'toggle';
29894/**
29895 * @hidden
29896 */
29897var GESTURE_PRIORITY_SLIDING_ITEM = -10;
29898/**
29899 * @hidden
29900 */
29901var GESTURE_PRIORITY_REFRESHER = 0;
29902/**
29903 * @hidden
29904 */
29905var GESTURE_PRIORITY_MENU_SWIPE = 10;
29906/**
29907 * @hidden
29908 */
29909var GESTURE_PRIORITY_GO_BACK_SWIPE = 20;
29910/**
29911 * @hidden
29912 */
29913var GESTURE_PRIORITY_TOGGLE = 30;
29914/**
29915 * @hidden
29916 */
29917var BLOCK_ALL = {
29918 disable: [GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE],
29919 disableScroll: true
29920};
29921/**
29922 * @hidden
29923 */
29924var GestureController = (function () {
29925 /**
29926 * @param {?} _app
29927 */
29928 function GestureController(_app) {
29929 this._app = _app;
29930 this.id = 1;
29931 this.requestedStart = {};
29932 this.disabledGestures = {};
29933 this.disabledScroll = new Set();
29934 this.capturedID = null;
29935 }
29936 /**
29937 * @param {?} opts
29938 * @return {?}
29939 */
29940 GestureController.prototype.createGesture = function (opts) {
29941 if (!opts.name) {
29942 throw new Error('name is undefined');
29943 }
29944 return new GestureDelegate(opts.name, this.newID(), this, opts.priority || 0, !!opts.disableScroll);
29945 };
29946 /**
29947 * @param {?=} opts
29948 * @return {?}
29949 */
29950 GestureController.prototype.createBlocker = function (opts) {
29951 if (opts === void 0) { opts = {}; }
29952 return new BlockerDelegate(this.newID(), this, opts.disable, !!opts.disableScroll);
29953 };
29954 /**
29955 * @return {?}
29956 */
29957 GestureController.prototype.newID = function () {
29958 var /** @type {?} */ id = this.id;
29959 this.id++;
29960 return id;
29961 };
29962 /**
29963 * @param {?} gestureName
29964 * @param {?} id
29965 * @param {?} priority
29966 * @return {?}
29967 */
29968 GestureController.prototype.start = function (gestureName, id, priority) {
29969 if (!this.canStart(gestureName)) {
29970 delete this.requestedStart[id];
29971 return false;
29972 }
29973 this.requestedStart[id] = priority;
29974 return true;
29975 };
29976 /**
29977 * @param {?} gestureName
29978 * @param {?} id
29979 * @param {?} priority
29980 * @return {?}
29981 */
29982 GestureController.prototype.capture = function (gestureName, id, priority) {
29983 if (!this.start(gestureName, id, priority)) {
29984 return false;
29985 }
29986 var /** @type {?} */ requestedStart = this.requestedStart;
29987 var /** @type {?} */ maxPriority = -10000;
29988 for (var /** @type {?} */ gestureID in requestedStart) {
29989 maxPriority = Math.max(maxPriority, requestedStart[gestureID]);
29990 }
29991 if (maxPriority === priority) {
29992 this.capturedID = id;
29993 this.requestedStart = {};
29994 (void 0) /* console.debug */;
29995 return true;
29996 }
29997 delete requestedStart[id];
29998 (void 0) /* console.debug */;
29999 return false;
30000 };
30001 /**
30002 * @param {?} id
30003 * @return {?}
30004 */
30005 GestureController.prototype.release = function (id) {
30006 delete this.requestedStart[id];
30007 if (this.capturedID && id === this.capturedID) {
30008 this.capturedID = null;
30009 }
30010 };
30011 /**
30012 * @param {?} gestureName
30013 * @param {?} id
30014 * @return {?}
30015 */
30016 GestureController.prototype.disableGesture = function (gestureName, id) {
30017 var /** @type {?} */ set = this.disabledGestures[gestureName];
30018 if (!set) {
30019 set = new Set();
30020 this.disabledGestures[gestureName] = set;
30021 }
30022 set.add(id);
30023 };
30024 /**
30025 * @param {?} gestureName
30026 * @param {?} id
30027 * @return {?}
30028 */
30029 GestureController.prototype.enableGesture = function (gestureName, id) {
30030 var /** @type {?} */ set = this.disabledGestures[gestureName];
30031 if (set) {
30032 set.delete(id);
30033 }
30034 };
30035 /**
30036 * @param {?} id
30037 * @return {?}
30038 */
30039 GestureController.prototype.disableScroll = function (id) {
30040 var /** @type {?} */ isEnabled = !this.isScrollDisabled();
30041 this.disabledScroll.add(id);
30042 if (this._app && isEnabled && this.isScrollDisabled()) {
30043 (void 0) /* console.debug */;
30044 this._app._setDisableScroll(true);
30045 }
30046 };
30047 /**
30048 * @param {?} id
30049 * @return {?}
30050 */
30051 GestureController.prototype.enableScroll = function (id) {
30052 var /** @type {?} */ isDisabled = this.isScrollDisabled();
30053 this.disabledScroll.delete(id);
30054 if (this._app && isDisabled && !this.isScrollDisabled()) {
30055 (void 0) /* console.debug */;
30056 this._app._setDisableScroll(false);
30057 }
30058 };
30059 /**
30060 * @param {?} gestureName
30061 * @return {?}
30062 */
30063 GestureController.prototype.canStart = function (gestureName) {
30064 if (this.capturedID) {
30065 (void 0) /* console.debug */;
30066 // a gesture already captured
30067 return false;
30068 }
30069 if (this.isDisabled(gestureName)) {
30070 (void 0) /* console.debug */;
30071 return false;
30072 }
30073 return true;
30074 };
30075 /**
30076 * @return {?}
30077 */
30078 GestureController.prototype.isCaptured = function () {
30079 return !!this.capturedID;
30080 };
30081 /**
30082 * @return {?}
30083 */
30084 GestureController.prototype.isScrollDisabled = function () {
30085 return this.disabledScroll.size > 0;
30086 };
30087 /**
30088 * @param {?} gestureName
30089 * @return {?}
30090 */
30091 GestureController.prototype.isDisabled = function (gestureName) {
30092 var /** @type {?} */ disabled = this.disabledGestures[gestureName];
30093 return !!(disabled && disabled.size > 0);
30094 };
30095 return GestureController;
30096}());
30097GestureController.decorators = [
30098 { type: Injectable },
30099];
30100/**
30101 * @nocollapse
30102 */
30103GestureController.ctorParameters = function () { return [
30104 { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
30105]; };
30106/**
30107 * @hidden
30108 */
30109var GestureDelegate = (function () {
30110 /**
30111 * @param {?} name
30112 * @param {?} id
30113 * @param {?} controller
30114 * @param {?} priority
30115 * @param {?} disableScroll
30116 */
30117 function GestureDelegate(name, id, controller, priority, disableScroll) {
30118 this.name = name;
30119 this.id = id;
30120 this.controller = controller;
30121 this.priority = priority;
30122 this.disableScroll = disableScroll;
30123 }
30124 /**
30125 * @return {?}
30126 */
30127 GestureDelegate.prototype.canStart = function () {
30128 if (!this.controller) {
30129 (void 0) /* assert */;
30130 return false;
30131 }
30132 return this.controller.canStart(this.name);
30133 };
30134 /**
30135 * @return {?}
30136 */
30137 GestureDelegate.prototype.start = function () {
30138 if (!this.controller) {
30139 (void 0) /* assert */;
30140 return false;
30141 }
30142 return this.controller.start(this.name, this.id, this.priority);
30143 };
30144 /**
30145 * @return {?}
30146 */
30147 GestureDelegate.prototype.capture = function () {
30148 if (!this.controller) {
30149 (void 0) /* assert */;
30150 return false;
30151 }
30152 var /** @type {?} */ captured = this.controller.capture(this.name, this.id, this.priority);
30153 if (captured && this.disableScroll) {
30154 this.controller.disableScroll(this.id);
30155 }
30156 return captured;
30157 };
30158 /**
30159 * @return {?}
30160 */
30161 GestureDelegate.prototype.release = function () {
30162 if (!this.controller) {
30163 (void 0) /* assert */;
30164 return;
30165 }
30166 this.controller.release(this.id);
30167 if (this.disableScroll) {
30168 this.controller.enableScroll(this.id);
30169 }
30170 };
30171 /**
30172 * @return {?}
30173 */
30174 GestureDelegate.prototype.destroy = function () {
30175 this.release();
30176 this.controller = null;
30177 };
30178 return GestureDelegate;
30179}());
30180/**
30181 * @hidden
30182 */
30183var BlockerDelegate = (function () {
30184 /**
30185 * @param {?} id
30186 * @param {?} controller
30187 * @param {?} disable
30188 * @param {?} disableScroll
30189 */
30190 function BlockerDelegate(id, controller, disable, disableScroll) {
30191 this.id = id;
30192 this.controller = controller;
30193 this.disable = disable;
30194 this.disableScroll = disableScroll;
30195 this.blocked = false;
30196 }
30197 /**
30198 * @return {?}
30199 */
30200 BlockerDelegate.prototype.block = function () {
30201 var _this = this;
30202 if (!this.controller) {
30203 (void 0) /* assert */;
30204 return;
30205 }
30206 if (this.disable) {
30207 this.disable.forEach(function (gesture) {
30208 _this.controller.disableGesture(gesture, _this.id);
30209 });
30210 }
30211 if (this.disableScroll) {
30212 this.controller.disableScroll(this.id);
30213 }
30214 this.blocked = true;
30215 };
30216 /**
30217 * @return {?}
30218 */
30219 BlockerDelegate.prototype.unblock = function () {
30220 var _this = this;
30221 if (!this.controller) {
30222 (void 0) /* assert */;
30223 return;
30224 }
30225 if (this.disable) {
30226 this.disable.forEach(function (gesture) {
30227 _this.controller.enableGesture(gesture, _this.id);
30228 });
30229 }
30230 if (this.disableScroll) {
30231 this.controller.enableScroll(this.id);
30232 }
30233 this.blocked = false;
30234 };
30235 /**
30236 * @return {?}
30237 */
30238 BlockerDelegate.prototype.destroy = function () {
30239 this.unblock();
30240 this.controller = null;
30241 };
30242 return BlockerDelegate;
30243}());
30244
30245/**
30246 * \@name NavController
30247 * \@description
30248 *
30249 * NavController is the base class for navigation controller components like
30250 * [`Nav`](../../components/nav/Nav/) and [`Tab`](../../components/tabs/Tab/). You use navigation controllers
30251 * to navigate to [pages](#view-creation) in your app. At a basic level, a
30252 * navigation controller is an array of pages representing a particular history
30253 * (of a Tab for example). This array can be manipulated to navigate throughout
30254 * an app by pushing and popping pages or inserting and removing them at
30255 * arbitrary locations in history.
30256 *
30257 * The current page is the last one in the array, or the top of the stack if we
30258 * think of it that way. [Pushing](#push) a new page onto the top of the
30259 * navigation stack causes the new page to be animated in, while [popping](#pop)
30260 * the current page will navigate to the previous page in the stack.
30261 *
30262 * Unless you are using a directive like [NavPush](../../components/nav/NavPush/), or need a
30263 * specific NavController, most times you will inject and use a reference to the
30264 * nearest NavController to manipulate the navigation stack.
30265 *
30266 * ## Basic usage
30267 * The simplest way to navigate through an app is to create and initialize a new
30268 * nav controller using the `<ion-nav>` component. `ion-nav` extends the `NavController`
30269 * class.
30270 *
30271 * ```typescript
30272 * import { Component } from `\@angular/core`;
30273 * import { StartPage } from './start-page';
30274 *
30275 * \@Component(
30276 * template: `<ion-nav [root]="rootPage"></ion-nav>`
30277 * })
30278 * class MyApp {
30279 * // set the rootPage to the first page we want displayed
30280 * public rootPage: any = StartPage;
30281 *
30282 * constructor(){
30283 * }
30284 * }
30285 *
30286 * ```
30287 *
30288 * ### Injecting NavController
30289 * Injecting NavController will always get you an instance of the nearest
30290 * NavController, regardless of whether it is a Tab or a Nav.
30291 *
30292 * Behind the scenes, when Ionic instantiates a new NavController, it creates an
30293 * injector with NavController bound to that instance (usually either a Nav or
30294 * Tab) and adds the injector to its own providers. For more information on
30295 * providers and dependency injection, see [Dependency Injection](https://angular.io/docs/ts/latest/guide/dependency-injection.html).
30296 *
30297 * Instead, you can inject NavController and know that it is the correct
30298 * navigation controller for most situations (for more advanced situations, see
30299 * [Menu](../../menu/Menu/) and [Tab](../../tab/Tab/)).
30300 *
30301 * ```ts
30302 * import { NavController } from 'ionic-angular';
30303 *
30304 * class MyComponent {
30305 * constructor(public navCtrl: NavController) {
30306 *
30307 * }
30308 * }
30309 * ```
30310 *
30311 * ### Navigating from the Root component
30312 * What if you want to control navigation from your root app component?
30313 * You can't inject `NavController` because any components that are navigation
30314 * controllers are _children_ of the root component so they aren't available
30315 * to be injected.
30316 *
30317 * By adding a reference variable to the `ion-nav`, you can use `\@ViewChild` to
30318 * get an instance of the `Nav` component, which is a navigation controller
30319 * (it extends `NavController`):
30320 *
30321 * ```typescript
30322 *
30323 * import { Component, ViewChild } from '\@angular/core';
30324 * import { NavController } from 'ionic-angular';
30325 *
30326 * \@Component({
30327 * template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
30328 * })
30329 * export class MyApp {
30330 * \@ViewChild('myNav') nav: NavController
30331 * public rootPage: any = TabsPage;
30332 *
30333 * // Wait for the components in MyApp's template to be initialized
30334 * // In this case, we are waiting for the Nav with reference variable of "#myNav"
30335 * ngOnInit() {
30336 * // Let's navigate from TabsPage to Page1
30337 * this.nav.push(Page1);
30338 * }
30339 * }
30340 * ```
30341 *
30342 * ### Navigating from an Overlay Component
30343 * What if you wanted to navigate from an overlay component (popover, modal, alert, etc)?
30344 * In this example, we've displayed a popover in our app. From the popover, we'll get a
30345 * reference of the root `NavController` in our app, using the `getRootNav()` method.
30346 *
30347 *
30348 * ```typescript
30349 * import { Component } from '\@angular/core';
30350 * import { App, ViewController } from 'ionic-angular';
30351 *
30352 * \@Component({
30353 * template: `
30354 * <ion-content>
30355 * <h1>My PopoverPage</h1>
30356 * <button ion-button (click)="pushPage()">Call pushPage</button>
30357 * </ion-content>
30358 * `
30359 * })
30360 * class PopoverPage {
30361 * constructor(
30362 * public viewCtrl: ViewController
30363 * public appCtrl: App
30364 * ) {}
30365 *
30366 * pushPage() {
30367 * this.viewCtrl.dismiss();
30368 * this.appCtrl.getRootNav().push(SecondPage);
30369 * }
30370 * }
30371 * ```
30372 *
30373 *
30374 * ## View creation
30375 * Views are created when they are added to the navigation stack. For methods
30376 * like [push()](#push), the NavController takes any component class that is
30377 * decorated with `\@Component` as its first argument. The NavController then
30378 * compiles that component, adds it to the app and animates it into view.
30379 *
30380 * By default, pages are cached and left in the DOM if they are navigated away
30381 * from but still in the navigation stack (the exiting page on a `push()` for
30382 * example). They are destroyed when removed from the navigation stack (on
30383 * [pop()](#pop) or [setRoot()](#setRoot)).
30384 *
30385 * ## Pushing a View
30386 * To push a new view onto the navigation stack, use the `push` method.
30387 * If the page has an [`<ion-navbar>`](../../navbar/Navbar/),
30388 * a back button will automatically be added to the pushed view.
30389 *
30390 * Data can also be passed to a view by passing an object to the `push` method.
30391 * The pushed view can then receive the data by accessing it via the `NavParams`
30392 * class.
30393 *
30394 * ```typescript
30395 * import { Component } from '\@angular/core';
30396 * import { NavController } from 'ionic-angular';
30397 * import { OtherPage } from './other-page';
30398 * \@Component({
30399 * template: `
30400 * <ion-header>
30401 * <ion-navbar>
30402 * <ion-title>Login</ion-title>
30403 * </ion-navbar>
30404 * </ion-header>
30405 *
30406 * <ion-content>
30407 * <button ion-button (click)="pushPage()">
30408 * Go to OtherPage
30409 * </button>
30410 * </ion-content>
30411 * `
30412 * })
30413 * export class StartPage {
30414 * constructor(public navCtrl: NavController) {
30415 * }
30416 *
30417 * pushPage(){
30418 * // push another page onto the navigation stack
30419 * // causing the nav controller to transition to the new page
30420 * // optional data can also be passed to the pushed page.
30421 * this.navCtrl.push(OtherPage, {
30422 * id: "123",
30423 * name: "Carl"
30424 * });
30425 * }
30426 * }
30427 *
30428 * import { NavParams } from 'ionic-angular';
30429 *
30430 * \@Component({
30431 * template: `
30432 * <ion-header>
30433 * <ion-navbar>
30434 * <ion-title>Other Page</ion-title>
30435 * </ion-navbar>
30436 * </ion-header>
30437 * <ion-content>I'm the other page!</ion-content>`
30438 * })
30439 * class OtherPage {
30440 * constructor(private navParams: NavParams) {
30441 * let id = navParams.get('id');
30442 * let name = navParams.get('name');
30443 * }
30444 * }
30445 * ```
30446 *
30447 * ## Removing a view
30448 * To remove a view from the stack, use the `pop` method.
30449 * Popping a view will transition to the previous view.
30450 *
30451 * ```ts
30452 * import { Component } from '\@angular/core';
30453 * import { NavController } from 'ionic-angular';
30454 *
30455 * \@Component({
30456 * template: `
30457 * <ion-header>
30458 * <ion-navbar>
30459 * <ion-title>Other Page</ion-title>
30460 * </ion-navbar>
30461 * </ion-header>
30462 * <ion-content>I'm the other page!</ion-content>`
30463 * })
30464 * class OtherPage {
30465 * constructor(public navCtrl: NavController ){
30466 * }
30467 *
30468 * popView(){
30469 * this.navCtrl.pop();
30470 * }
30471 * }
30472 * ```
30473 *
30474 * ## Lifecycle events
30475 * Lifecycle events are fired during various stages of navigation. They can be
30476 * defined in any component type which is pushed/popped from a `NavController`.
30477 *
30478 * ```ts
30479 * import { Component } from '\@angular/core';
30480 *
30481 * \@Component({
30482 * template: 'Hello World'
30483 * })
30484 * class HelloWorld {
30485 * ionViewDidLoad() {
30486 * console.log("I'm alive!");
30487 * }
30488 * ionViewWillLeave() {
30489 * console.log("Looks like I'm about to leave :(");
30490 * }
30491 * }
30492 * ```
30493 *
30494 * | Page Event | Returns | Description |
30495 * |---------------------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
30496 * | `ionViewDidLoad` | void | Runs when the page has loaded. This event only happens once per page being created. If a page leaves but is cached, then this event will not fire again on a subsequent viewing. The `ionViewDidLoad` event is good place to put your setup code for the page. |
30497 * | `ionViewWillEnter` | void | Runs when the page is about to enter and become the active page. |
30498 * | `ionViewDidEnter` | void | Runs when the page has fully entered and is now the active page. This event will fire, whether it was the first load or a cached page. |
30499 * | `ionViewWillLeave` | void | Runs when the page is about to leave and no longer be the active page. |
30500 * | `ionViewDidLeave` | void | Runs when the page has finished leaving and is no longer the active page. |
30501 * | `ionViewWillUnload` | void | Runs when the page is about to be destroyed and have its elements removed. |
30502 * | `ionViewCanEnter` | boolean/Promise&lt;void&gt; | Runs before the view can enter. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can enter |
30503 * | `ionViewCanLeave` | boolean/Promise&lt;void&gt; | Runs before the view can leave. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can leave |
30504 *
30505 *
30506 * ## Nav Guards
30507 *
30508 * In some cases, a developer should be able to control views leaving and entering. To allow for this, NavController has the `ionViewCanEnter` and `ionViewCanLeave` methods.
30509 * Similar to Angular route guards, but are more integrated with NavController. For example, if you wanted to prevent a user from leaving a view:
30510 *
30511 * ```ts
30512 * export class MyClass{
30513 * constructor(
30514 * public navCtrl: NavController
30515 * ){}
30516 *
30517 * pushPage(){
30518 * this.navCtrl.push(DetailPage);
30519 * }
30520 *
30521 * ionViewCanLeave(): boolean{
30522 * // here we can either return true or false
30523 * // depending on if we want to leave this view
30524 * if(isValid(randomValue)){
30525 * return true;
30526 * } else {
30527 * return false;
30528 * }
30529 * }
30530 * }
30531 * ```
30532 *
30533 * We need to make sure that our `navCtrl.push` has a catch in order to catch the and handle the error.
30534 * If you need to prevent a view from entering, you can do the same thing
30535 *
30536 * ```ts
30537 * export class MyClass{
30538 * constructor(
30539 * public navCtrl: NavController
30540 * ){}
30541 *
30542 * pushPage(){
30543 * this.navCtrl.push(DetailPage);
30544 * }
30545 *
30546 * }
30547 *
30548 * export class DetailPage(){
30549 * constructor(
30550 * public navCtrl: NavController
30551 * ){}
30552 * ionViewCanEnter(): boolean{
30553 * // here we can either return true or false
30554 * // depending on if we want to leave this view
30555 * if(isValid(randomValue)){
30556 * return true;
30557 * } else {
30558 * return false;
30559 * }
30560 * }
30561 * }
30562 * ```
30563 *
30564 * Similar to `ionViewCanLeave` we still need a catch on the original `navCtrl.push` in order to handle it properly.
30565 * When handling the back button in the `ion-navbar`, the catch is already taken care of for you by the framework.
30566 *
30567 * ## NavOptions
30568 *
30569 * Some methods on `NavController` allow for customizing the current transition.
30570 * To do this, we can pass an object with the modified properites.
30571 *
30572 *
30573 * | Property | Value | Description |
30574 * |-----------|-----------|------------------------------------------------------------------------------------------------------------|
30575 * | animate | `boolean` | Whether or not the transition should animate. |
30576 * | animation | `string` | What kind of animation should be used. |
30577 * | direction | `string` | The conceptual direction the user is navigating. For example, is the user navigating `forward`, or `back`? |
30578 * | duration | `number` | The length in milliseconds the animation should take. |
30579 * | easing | `string` | The easing for the animation. |
30580 *
30581 * The property 'animation' understands the following values: `md-transition`, `ios-transition` and `wp-transition`.
30582 *
30583 * @see {\@link /docs/components#navigation Navigation Component Docs}
30584 * @abstract
30585 */
30586var NavController = (function () {
30587 function NavController() {
30588 }
30589 /**
30590 * Push a new component onto the current navigation stack. Pass any aditional information
30591 * along as an object. This additional information is accessible through NavParams
30592 *
30593 * @abstract
30594 * @param {?} page
30595 * @param {?=} params
30596 * @param {?=} opts
30597 * @param {?=} done
30598 * @return {?}
30599 */
30600 NavController.prototype.push = function (page, params, opts, done) { };
30601 /**
30602 * Inserts a component into the nav stack at the specified index. This is useful if
30603 * you need to add a component at any point in your navigation stack.
30604 *
30605 *
30606 * @abstract
30607 * @param {?} insertIndex
30608 * @param {?} page
30609 * @param {?=} params
30610 * @param {?=} opts
30611 * @param {?=} done
30612 * @return {?}
30613 */
30614 NavController.prototype.insert = function (insertIndex, page, params, opts, done) { };
30615 /**
30616 * Inserts an array of components into the nav stack at the specified index.
30617 * The last component in the array will become instantiated as a view,
30618 * and animate in to become the active view.
30619 *
30620 * @abstract
30621 * @param {?} insertIndex
30622 * @param {?} insertPages
30623 * @param {?=} opts
30624 * @param {?=} done
30625 * @return {?}
30626 */
30627 NavController.prototype.insertPages = function (insertIndex, insertPages, opts, done) { };
30628 /**
30629 * Call to navigate back from a current component. Similar to `push()`, you
30630 * can also pass navigation options.
30631 *
30632 * @abstract
30633 * @param {?=} opts
30634 * @param {?=} done
30635 * @return {?}
30636 */
30637 NavController.prototype.pop = function (opts, done) { };
30638 /**
30639 * Navigate back to the root of the stack, no matter how far back that is.
30640 *
30641 * @abstract
30642 * @param {?=} opts
30643 * @param {?=} done
30644 * @return {?}
30645 */
30646 NavController.prototype.popToRoot = function (opts, done) { };
30647 /**
30648 * @hidden
30649 * Pop to a specific view in the history stack. If an already created
30650 * instance of the page is not found in the stack, then it'll `setRoot`
30651 * to the nav stack by removing all current pages and pushing on a
30652 * new instance of the given page. Note that any params passed to
30653 * this method are not used when an existing page instance has already
30654 * been found in the stack. Nav params are only used by this method
30655 * when a new instance needs to be created.
30656 *
30657 * @abstract
30658 * @param {?} page
30659 * @param {?=} opts
30660 * @param {?=} done
30661 * @return {?}
30662 */
30663 NavController.prototype.popTo = function (page, opts, done) { };
30664 /**
30665 * @hidden
30666 * Pop sequently all the pages in the stack.
30667 *
30668 * @abstract
30669 * @return {?}
30670 */
30671 NavController.prototype.popAll = function () { };
30672 /**
30673 * Removes a page from the nav stack at the specified index.
30674 *
30675 * @abstract
30676 * @param {?} startIndex
30677 * @param {?=} removeCount
30678 * @param {?=} opts
30679 * @param {?=} done
30680 * @return {?}
30681 */
30682 NavController.prototype.remove = function (startIndex, removeCount, opts, done) { };
30683 /**
30684 * Removes the specified view controller from the nav stack.
30685 *
30686 * @abstract
30687 * @param {?} viewController
30688 * @param {?=} opts
30689 * @param {?=} done
30690 * @return {?}
30691 */
30692 NavController.prototype.removeView = function (viewController, opts, done) { };
30693 /**
30694 * Set the root for the current navigation stack.
30695 * @abstract
30696 * @param {?} pageOrViewCtrl
30697 * @param {?=} params
30698 * @param {?=} opts
30699 * @param {?=} done
30700 * @return {?}
30701 */
30702 NavController.prototype.setRoot = function (pageOrViewCtrl, params, opts, done) { };
30703 /**
30704 * @abstract
30705 * @param {?} options
30706 * @return {?}
30707 */
30708 NavController.prototype.goToRoot = function (options) { };
30709 /**
30710 * Set the views of the current navigation stack and navigate to the
30711 * last view. By default animations are disabled, but they can be enabled
30712 * by passing options to the navigation controller.You can also pass any
30713 * navigation params to the individual pages in the array.
30714 *
30715 * @abstract
30716 * @param {?} pages
30717 * @param {?=} opts
30718 * @param {?=} done
30719 * @return {?}
30720 */
30721 NavController.prototype.setPages = function (pages, opts, done) { };
30722 /**
30723 * @abstract
30724 * @param {?} index
30725 * @return {?}
30726 */
30727 NavController.prototype.getByIndex = function (index) { };
30728 /**
30729 * @abstract
30730 * @param {?=} includeEntering
30731 * @return {?}
30732 */
30733 NavController.prototype.getActive = function (includeEntering) { };
30734 /**
30735 * Returns if the given view is the active view or not.
30736 * @abstract
30737 * @param {?} view
30738 * @return {?}
30739 */
30740 NavController.prototype.isActive = function (view) { };
30741 /**
30742 * Returns the view controller which is before the given view controller.
30743 * If no view controller is passed in, then it'll default to the active view.
30744 * @abstract
30745 * @param {?=} view
30746 * @return {?}
30747 */
30748 NavController.prototype.getPrevious = function (view) { };
30749 /**
30750 * Returns the first view controller in this nav controller's stack.
30751 * @abstract
30752 * @return {?}
30753 */
30754 NavController.prototype.first = function () { };
30755 /**
30756 * Returns the last page in this nav controller's stack.
30757 * @abstract
30758 * @return {?}
30759 */
30760 NavController.prototype.last = function () { };
30761 /**
30762 * Returns the index number of the given view controller.
30763 * @abstract
30764 * @param {?} view
30765 * @return {?}
30766 */
30767 NavController.prototype.indexOf = function (view) { };
30768 /**
30769 * Returns the number of views in this nav controller.
30770 * @abstract
30771 * @return {?}
30772 */
30773 NavController.prototype.length = function () { };
30774 /**
30775 * Returns the current stack of views in this nav controller.
30776 * @abstract
30777 * @return {?}
30778 */
30779 NavController.prototype.getViews = function () { };
30780 /**
30781 * Returns a list of the active child navigation.
30782 * @abstract
30783 * @return {?}
30784 */
30785 NavController.prototype.getActiveChildNavs = function () { };
30786 /**
30787 * Returns the active child navigation.
30788 * @abstract
30789 * @return {?}
30790 */
30791 NavController.prototype.getActiveChildNav = function () { };
30792 /**
30793 * Returns a list of all child navigation containers
30794 * @abstract
30795 * @return {?}
30796 */
30797 NavController.prototype.getAllChildNavs = function () { };
30798 /**
30799 * Returns if the nav controller is actively transitioning or not.
30800 * @abstract
30801 * @param {?=} includeAncestors
30802 * @return {?}
30803 */
30804 NavController.prototype.isTransitioning = function (includeAncestors) { };
30805 /**
30806 * If it's possible to use swipe back or not. If it's not possible
30807 * to go back, or swipe back is not enabled, then this will return `false`.
30808 * If it is possible to go back, and swipe back is enabled, then this
30809 * will return `true`.
30810 * @abstract
30811 * @return {?}
30812 */
30813 NavController.prototype.canSwipeBack = function () { };
30814 /**
30815 * Returns `true` if there's a valid previous page that we can pop
30816 * back to. Otherwise returns `false`.
30817 * @abstract
30818 * @return {?}
30819 */
30820 NavController.prototype.canGoBack = function () { };
30821 /**
30822 * @hidden
30823 * @abstract
30824 * @param {?} nav
30825 * @return {?}
30826 */
30827 NavController.prototype.registerChildNav = function (nav) { };
30828 /**
30829 * @hidden
30830 * @abstract
30831 * @return {?}
30832 */
30833 NavController.prototype.resize = function () { };
30834 /**
30835 * @abstract
30836 * @return {?}
30837 */
30838 NavController.prototype.getType = function () { };
30839 /**
30840 * @abstract
30841 * @return {?}
30842 */
30843 NavController.prototype.getSecondaryIdentifier = function () { };
30844 return NavController;
30845}());
30846
30847var PanRecognizer = (function () {
30848 /**
30849 * @param {?} direction
30850 * @param {?} threshold
30851 * @param {?} maxAngle
30852 */
30853 function PanRecognizer(direction, threshold, maxAngle) {
30854 this.direction = direction;
30855 this.dirty = false;
30856 this._angle = 0;
30857 this._isPan = 0;
30858 var radians = maxAngle * (Math.PI / 180);
30859 this.maxCosine = Math.cos(radians);
30860 this.threshold = threshold * threshold;
30861 }
30862 /**
30863 * @param {?} coord
30864 * @return {?}
30865 */
30866 PanRecognizer.prototype.start = function (coord) {
30867 this.startCoord = coord;
30868 this._angle = 0;
30869 this._isPan = 0;
30870 this.dirty = true;
30871 };
30872 /**
30873 * @param {?} coord
30874 * @return {?}
30875 */
30876 PanRecognizer.prototype.detect = function (coord) {
30877 if (!this.dirty) {
30878 return false;
30879 }
30880 var /** @type {?} */ deltaX = (coord.x - this.startCoord.x);
30881 var /** @type {?} */ deltaY = (coord.y - this.startCoord.y);
30882 var /** @type {?} */ distance = deltaX * deltaX + deltaY * deltaY;
30883 if (distance >= this.threshold) {
30884 var /** @type {?} */ angle = Math.atan2(deltaY, deltaX);
30885 var /** @type {?} */ cosine = (this.direction === 'y')
30886 ? Math.sin(angle)
30887 : Math.cos(angle);
30888 this._angle = angle;
30889 if (cosine > this.maxCosine) {
30890 this._isPan = 1;
30891 }
30892 else if (cosine < -this.maxCosine) {
30893 this._isPan = -1;
30894 }
30895 else {
30896 this._isPan = 0;
30897 }
30898 this.dirty = false;
30899 return true;
30900 }
30901 return false;
30902 };
30903 /**
30904 * @return {?}
30905 */
30906 PanRecognizer.prototype.angle = function () {
30907 return this._angle;
30908 };
30909 /**
30910 * @return {?}
30911 */
30912 PanRecognizer.prototype.pan = function () {
30913 return this._isPan;
30914 };
30915 return PanRecognizer;
30916}());
30917
30918/**
30919 * @hidden
30920 */
30921var PointerEvents = (function () {
30922 /**
30923 * @param {?} plt
30924 * @param {?} ele
30925 * @param {?} pointerDown
30926 * @param {?} pointerMove
30927 * @param {?} pointerUp
30928 * @param {?} option
30929 */
30930 function PointerEvents(plt, ele, pointerDown, pointerMove, pointerUp, option) {
30931 this.plt = plt;
30932 this.ele = ele;
30933 this.pointerDown = pointerDown;
30934 this.pointerMove = pointerMove;
30935 this.pointerUp = pointerUp;
30936 this.option = option;
30937 this.rmTouchStart = null;
30938 this.rmTouchMove = null;
30939 this.rmTouchEnd = null;
30940 this.rmTouchCancel = null;
30941 this.rmMouseStart = null;
30942 this.rmMouseMove = null;
30943 this.rmMouseUp = null;
30944 this.lastTouchEvent = 0;
30945 this.mouseWait = 2 * 1000;
30946 (void 0) /* assert */;
30947 (void 0) /* assert */;
30948 this.bindTouchEnd = this.handleTouchEnd.bind(this);
30949 this.bindMouseUp = this.handleMouseUp.bind(this);
30950 this.rmTouchStart = this.plt.registerListener(ele, 'touchstart', this.handleTouchStart.bind(this), option);
30951 this.rmMouseStart = this.plt.registerListener(ele, 'mousedown', this.handleMouseDown.bind(this), option);
30952 }
30953 /**
30954 * @param {?} ev
30955 * @return {?}
30956 */
30957 PointerEvents.prototype.handleTouchStart = function (ev) {
30958 (void 0) /* assert */;
30959 (void 0) /* assert */;
30960 this.lastTouchEvent = Date.now() + this.mouseWait;
30961 this.lastEventType = POINTER_EVENT_TYPE_TOUCH;
30962 if (!this.pointerDown(ev, POINTER_EVENT_TYPE_TOUCH)) {
30963 return;
30964 }
30965 if (!this.rmTouchMove && this.pointerMove) {
30966 this.rmTouchMove = this.plt.registerListener(this.ele, 'touchmove', this.pointerMove, this.option);
30967 }
30968 if (!this.rmTouchEnd) {
30969 this.rmTouchEnd = this.plt.registerListener(this.ele, 'touchend', this.bindTouchEnd, this.option);
30970 }
30971 if (!this.rmTouchCancel) {
30972 this.rmTouchCancel = this.plt.registerListener(this.ele, 'touchcancel', this.bindTouchEnd, this.option);
30973 }
30974 };
30975 /**
30976 * @param {?} ev
30977 * @return {?}
30978 */
30979 PointerEvents.prototype.handleMouseDown = function (ev) {
30980 (void 0) /* assert */;
30981 (void 0) /* assert */;
30982 if (this.lastTouchEvent > Date.now()) {
30983 (void 0) /* console.debug */;
30984 return;
30985 }
30986 this.lastEventType = POINTER_EVENT_TYPE_MOUSE;
30987 if (!this.pointerDown(ev, POINTER_EVENT_TYPE_MOUSE)) {
30988 return;
30989 }
30990 if (!this.rmMouseMove && this.pointerMove) {
30991 this.rmMouseMove = this.plt.registerListener(this.plt.doc(), 'mousemove', this.pointerMove, this.option);
30992 }
30993 if (!this.rmMouseUp) {
30994 this.rmMouseUp = this.plt.registerListener(this.plt.doc(), 'mouseup', this.bindMouseUp, this.option);
30995 }
30996 };
30997 /**
30998 * @param {?} ev
30999 * @return {?}
31000 */
31001 PointerEvents.prototype.handleTouchEnd = function (ev) {
31002 this.stopTouch();
31003 this.pointerUp && this.pointerUp(ev, POINTER_EVENT_TYPE_TOUCH);
31004 };
31005 /**
31006 * @param {?} ev
31007 * @return {?}
31008 */
31009 PointerEvents.prototype.handleMouseUp = function (ev) {
31010 this.stopMouse();
31011 this.pointerUp && this.pointerUp(ev, POINTER_EVENT_TYPE_MOUSE);
31012 };
31013 /**
31014 * @return {?}
31015 */
31016 PointerEvents.prototype.stopTouch = function () {
31017 this.rmTouchMove && this.rmTouchMove();
31018 this.rmTouchEnd && this.rmTouchEnd();
31019 this.rmTouchCancel && this.rmTouchCancel();
31020 this.rmTouchMove = this.rmTouchEnd = this.rmTouchCancel = null;
31021 };
31022 /**
31023 * @return {?}
31024 */
31025 PointerEvents.prototype.stopMouse = function () {
31026 this.rmMouseMove && this.rmMouseMove();
31027 this.rmMouseUp && this.rmMouseUp();
31028 this.rmMouseMove = this.rmMouseUp = null;
31029 };
31030 /**
31031 * @return {?}
31032 */
31033 PointerEvents.prototype.stop = function () {
31034 this.stopTouch();
31035 this.stopMouse();
31036 };
31037 /**
31038 * @return {?}
31039 */
31040 PointerEvents.prototype.destroy = function () {
31041 this.rmTouchStart && this.rmTouchStart();
31042 this.rmMouseStart && this.rmMouseStart();
31043 this.stop();
31044 this.ele = this.pointerUp = this.pointerMove = this.pointerDown = this.rmTouchStart = this.rmMouseStart = null;
31045 };
31046 return PointerEvents;
31047}());
31048var POINTER_EVENT_TYPE_MOUSE = 1;
31049var POINTER_EVENT_TYPE_TOUCH = 2;
31050
31051/**
31052 * @hidden
31053 */
31054var UIEventManager = (function () {
31055 /**
31056 * @param {?} plt
31057 */
31058 function UIEventManager(plt) {
31059 this.plt = plt;
31060 this.evts = [];
31061 }
31062 /**
31063 * @param {?} config
31064 * @return {?}
31065 */
31066 UIEventManager.prototype.pointerEvents = function (config) {
31067 if (!config.element || !config.pointerDown) {
31068 console.error('PointerEvents config is invalid');
31069 return;
31070 }
31071 var /** @type {?} */ eventListnerOpts = {
31072 capture: config.capture,
31073 passive: config.passive,
31074 zone: config.zone
31075 };
31076 var /** @type {?} */ pointerEvents = new PointerEvents(this.plt, config.element, config.pointerDown, config.pointerMove, config.pointerUp, eventListnerOpts);
31077 var /** @type {?} */ removeFunc = function () { return pointerEvents.destroy(); };
31078 this.evts.push(removeFunc);
31079 return pointerEvents;
31080 };
31081 /**
31082 * @param {?} ele
31083 * @param {?} eventName
31084 * @param {?} callback
31085 * @param {?} opts
31086 * @return {?}
31087 */
31088 UIEventManager.prototype.listen = function (ele, eventName, callback, opts) {
31089 if (ele) {
31090 var /** @type {?} */ removeFunc = this.plt.registerListener(ele, eventName, callback, opts);
31091 this.evts.push(removeFunc);
31092 return removeFunc;
31093 }
31094 };
31095 /**
31096 * @return {?}
31097 */
31098 UIEventManager.prototype.unlistenAll = function () {
31099 this.evts.forEach(function (unRegEvent) {
31100 unRegEvent();
31101 });
31102 this.evts.length = 0;
31103 };
31104 /**
31105 * @return {?}
31106 */
31107 UIEventManager.prototype.destroy = function () {
31108 this.unlistenAll();
31109 this.evts = null;
31110 };
31111 return UIEventManager;
31112}());
31113
31114/**
31115 * @hidden
31116 */
31117var PanGesture = (function () {
31118 /**
31119 * @param {?} plt
31120 * @param {?} element
31121 * @param {?=} opts
31122 */
31123 function PanGesture(plt, element, opts) {
31124 if (opts === void 0) { opts = {}; }
31125 this.plt = plt;
31126 this.element = element;
31127 defaults(opts, {
31128 threshold: 20,
31129 maxAngle: 40,
31130 direction: 'x',
31131 zone: true,
31132 capture: false,
31133 passive: false,
31134 });
31135 this.events = new UIEventManager(plt);
31136 if (opts.domController) {
31137 this.debouncer = opts.domController.debouncer();
31138 }
31139 this.gestute = opts.gesture;
31140 this.direction = opts.direction;
31141 this.eventsConfig = {
31142 element: this.element,
31143 pointerDown: this.pointerDown.bind(this),
31144 pointerMove: this.pointerMove.bind(this),
31145 pointerUp: this.pointerUp.bind(this),
31146 zone: opts.zone,
31147 capture: opts.capture,
31148 passive: opts.passive
31149 };
31150 if (opts.threshold > 0) {
31151 this.detector = new PanRecognizer(opts.direction, opts.threshold, opts.maxAngle);
31152 }
31153 }
31154 /**
31155 * @return {?}
31156 */
31157 PanGesture.prototype.listen = function () {
31158 if (!this.isListening) {
31159 this.pointerEvents = this.events.pointerEvents(this.eventsConfig);
31160 this.isListening = true;
31161 }
31162 };
31163 /**
31164 * @return {?}
31165 */
31166 PanGesture.prototype.unlisten = function () {
31167 if (this.isListening) {
31168 this.gestute && this.gestute.release();
31169 this.events.unlistenAll();
31170 this.isListening = false;
31171 }
31172 };
31173 /**
31174 * @return {?}
31175 */
31176 PanGesture.prototype.destroy = function () {
31177 this.gestute && this.gestute.destroy();
31178 this.gestute = null;
31179 this.unlisten();
31180 this.events.destroy();
31181 this.events = this.element = this.gestute = null;
31182 };
31183 /**
31184 * @param {?} ev
31185 * @return {?}
31186 */
31187 PanGesture.prototype.pointerDown = function (ev) {
31188 if (this.started) {
31189 return;
31190 }
31191 if (!this.canStart(ev)) {
31192 return false;
31193 }
31194 if (this.gestute) {
31195 // Release fallback
31196 this.gestute.release();
31197 // Start gesture
31198 if (!this.gestute.start()) {
31199 return false;
31200 }
31201 }
31202 this.started = true;
31203 this.captured = false;
31204 var /** @type {?} */ coord = pointerCoord(ev);
31205 if (this.detector) {
31206 this.detector.start(coord);
31207 }
31208 else {
31209 if (!this.tryToCapture(ev)) {
31210 this.started = false;
31211 this.captured = false;
31212 this.gestute.release();
31213 return false;
31214 }
31215 }
31216 return true;
31217 };
31218 /**
31219 * @param {?} ev
31220 * @return {?}
31221 */
31222 PanGesture.prototype.pointerMove = function (ev) {
31223 var _this = this;
31224 (void 0) /* assert */;
31225 if (this.captured) {
31226 this.debouncer.write(function () {
31227 _this.onDragMove(ev);
31228 });
31229 return;
31230 }
31231 (void 0) /* assert */;
31232 var /** @type {?} */ coord = pointerCoord(ev);
31233 if (this.detector.detect(coord)) {
31234 if (this.detector.pan() !== 0) {
31235 if (!this.tryToCapture(ev)) {
31236 this.abort(ev);
31237 }
31238 }
31239 }
31240 };
31241 /**
31242 * @param {?} ev
31243 * @return {?}
31244 */
31245 PanGesture.prototype.pointerUp = function (ev) {
31246 (void 0) /* assert */;
31247 this.debouncer.cancel();
31248 this.gestute && this.gestute.release();
31249 if (this.captured) {
31250 this.onDragEnd(ev);
31251 }
31252 else {
31253 this.notCaptured(ev);
31254 }
31255 this.captured = false;
31256 this.started = false;
31257 };
31258 /**
31259 * @param {?} ev
31260 * @return {?}
31261 */
31262 PanGesture.prototype.tryToCapture = function (ev) {
31263 (void 0) /* assert */;
31264 (void 0) /* assert */;
31265 if (this.gestute && !this.gestute.capture()) {
31266 return false;
31267 }
31268 this.onDragStart(ev);
31269 this.captured = true;
31270 return true;
31271 };
31272 /**
31273 * @param {?} ev
31274 * @return {?}
31275 */
31276 PanGesture.prototype.abort = function (ev) {
31277 this.started = false;
31278 this.captured = false;
31279 this.gestute.release();
31280 this.pointerEvents.stop();
31281 this.notCaptured(ev);
31282 };
31283 /**
31284 * @return {?}
31285 */
31286 PanGesture.prototype.getNativeElement = function () {
31287 return this.element;
31288 };
31289 /**
31290 * @param {?} _ev
31291 * @return {?}
31292 */
31293 PanGesture.prototype.canStart = function (_ev) { return true; };
31294 /**
31295 * @param {?} _ev
31296 * @return {?}
31297 */
31298 PanGesture.prototype.onDragStart = function (_ev) { };
31299 /**
31300 * @param {?} _ev
31301 * @return {?}
31302 */
31303 PanGesture.prototype.onDragMove = function (_ev) { };
31304 /**
31305 * @param {?} _ev
31306 * @return {?}
31307 */
31308 PanGesture.prototype.onDragEnd = function (_ev) { };
31309 /**
31310 * @param {?} _ev
31311 * @return {?}
31312 */
31313 PanGesture.prototype.notCaptured = function (_ev) { };
31314 return PanGesture;
31315}());
31316
31317var __extends$23 = (undefined && undefined.__extends) || (function () {
31318 var extendStatics = Object.setPrototypeOf ||
31319 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31320 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
31321 return function (d, b) {
31322 extendStatics(d, b);
31323 function __() { this.constructor = d; }
31324 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
31325 };
31326})();
31327/**
31328 * @hidden
31329 */
31330var SlideGesture = (function (_super) {
31331 __extends$23(SlideGesture, _super);
31332 /**
31333 * @param {?} plt
31334 * @param {?} element
31335 * @param {?=} opts
31336 */
31337 function SlideGesture(plt, element, opts) {
31338 if (opts === void 0) { opts = {}; }
31339 var _this = _super.call(this, plt, element, opts) || this;
31340 _this.slide = null;
31341 return _this;
31342 }
31343 /**
31344 * @param {?} _slide
31345 * @param {?} _ev
31346 * @return {?}
31347 */
31348 SlideGesture.prototype.getSlideBoundaries = function (_slide, _ev) {
31349 return {
31350 min: 0,
31351 max: this.getNativeElement().offsetWidth
31352 };
31353 };
31354 /**
31355 * @param {?} _slide
31356 * @param {?} _ev
31357 * @return {?}
31358 */
31359 SlideGesture.prototype.getElementStartPos = function (_slide, _ev) {
31360 return 0;
31361 };
31362 /**
31363 * @param {?} ev
31364 * @return {?}
31365 */
31366 SlideGesture.prototype.onDragStart = function (ev) {
31367 this.onSlideBeforeStart(ev);
31368 var /** @type {?} */ coord = (pointerCoord(ev));
31369 var /** @type {?} */ pos = coord[this.direction];
31370 this.slide = {
31371 min: 0,
31372 max: 0,
31373 pointerStartPos: pos,
31374 pos: pos,
31375 timestamp: Date.now(),
31376 elementStartPos: 0,
31377 started: true,
31378 delta: 0,
31379 distance: 0,
31380 velocity: 0,
31381 };
31382 // TODO: we should run this in the next frame
31383 var _a = this.getSlideBoundaries(this.slide, ev), min = _a.min, max = _a.max;
31384 this.slide.min = min;
31385 this.slide.max = max;
31386 this.slide.elementStartPos = this.getElementStartPos(this.slide, ev);
31387 this.onSlideStart(this.slide, ev);
31388 };
31389 /**
31390 * @param {?} ev
31391 * @return {?}
31392 */
31393 SlideGesture.prototype.onDragMove = function (ev) {
31394 var /** @type {?} */ slide = this.slide;
31395 (void 0) /* assert */;
31396 var /** @type {?} */ coord = (pointerCoord(ev));
31397 var /** @type {?} */ newPos = coord[this.direction];
31398 var /** @type {?} */ newTimestamp = Date.now();
31399 var /** @type {?} */ velocity = (this.plt.isRTL ? (slide.pos - newPos) : (newPos - slide.pos)) / (newTimestamp - slide.timestamp);
31400 slide.pos = newPos;
31401 slide.timestamp = newTimestamp;
31402 slide.distance = clamp(slide.min, (this.plt.isRTL ? slide.pointerStartPos - newPos : newPos - slide.pointerStartPos) + slide.elementStartPos, slide.max);
31403 slide.velocity = velocity;
31404 slide.delta = (this.plt.isRTL ? slide.pointerStartPos - newPos : newPos - slide.pointerStartPos);
31405 this.onSlide(slide, ev);
31406 };
31407 /**
31408 * @param {?} ev
31409 * @return {?}
31410 */
31411 SlideGesture.prototype.onDragEnd = function (ev) {
31412 this.onSlideEnd(this.slide, ev);
31413 this.slide = null;
31414 };
31415 /**
31416 * @param {?=} _ev
31417 * @return {?}
31418 */
31419 SlideGesture.prototype.onSlideBeforeStart = function (_ev) { };
31420 /**
31421 * @param {?=} _slide
31422 * @param {?=} _ev
31423 * @return {?}
31424 */
31425 SlideGesture.prototype.onSlideStart = function (_slide, _ev) { };
31426 /**
31427 * @param {?=} _slide
31428 * @param {?=} _ev
31429 * @return {?}
31430 */
31431 SlideGesture.prototype.onSlide = function (_slide, _ev) { };
31432 /**
31433 * @param {?=} _slide
31434 * @param {?=} _ev
31435 * @return {?}
31436 */
31437 SlideGesture.prototype.onSlideEnd = function (_slide, _ev) { };
31438 return SlideGesture;
31439}(PanGesture));
31440
31441var __extends$22 = (undefined && undefined.__extends) || (function () {
31442 var extendStatics = Object.setPrototypeOf ||
31443 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31444 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
31445 return function (d, b) {
31446 extendStatics(d, b);
31447 function __() { this.constructor = d; }
31448 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
31449 };
31450})();
31451/**
31452 * @hidden
31453 */
31454var SlideEdgeGesture = (function (_super) {
31455 __extends$22(SlideEdgeGesture, _super);
31456 /**
31457 * @param {?} plt
31458 * @param {?} element
31459 * @param {?=} opts
31460 */
31461 function SlideEdgeGesture(plt, element, opts) {
31462 if (opts === void 0) { opts = {}; }
31463 var _this = this;
31464 defaults(opts, {
31465 edge: 'start',
31466 maxEdgeStart: 50
31467 });
31468 _this = _super.call(this, plt, element, opts) || this;
31469 // Can check corners through use of eg 'left top'
31470 _this.setEdges(opts.edge);
31471 _this.maxEdgeStart = opts.maxEdgeStart;
31472 return _this;
31473 }
31474 /**
31475 * @param {?} edges
31476 * @return {?}
31477 */
31478 SlideEdgeGesture.prototype.setEdges = function (edges) {
31479 var /** @type {?} */ isRTL = this.plt.isRTL;
31480 this.edges = edges.split(' ').map(function (value) {
31481 switch (value) {
31482 case 'start': return isRTL ? 'right' : 'left';
31483 case 'end': return isRTL ? 'left' : 'right';
31484 default: return value;
31485 }
31486 });
31487 };
31488 /**
31489 * @param {?} ev
31490 * @return {?}
31491 */
31492 SlideEdgeGesture.prototype.canStart = function (ev) {
31493 var _this = this;
31494 var /** @type {?} */ coord = pointerCoord(ev);
31495 this._d = this.getContainerDimensions();
31496 return this.edges.every(function (edge) { return _this._checkEdge(edge, coord); });
31497 };
31498 /**
31499 * @return {?}
31500 */
31501 SlideEdgeGesture.prototype.getContainerDimensions = function () {
31502 var /** @type {?} */ plt = this.plt;
31503 return {
31504 left: 0,
31505 top: 0,
31506 width: plt.width(),
31507 height: plt.height()
31508 };
31509 };
31510 /**
31511 * @param {?} edge
31512 * @param {?} pos
31513 * @return {?}
31514 */
31515 SlideEdgeGesture.prototype._checkEdge = function (edge, pos) {
31516 var /** @type {?} */ data = this._d;
31517 var /** @type {?} */ maxEdgeStart = this.maxEdgeStart;
31518 switch (edge) {
31519 case 'left': return pos.x <= data.left + maxEdgeStart;
31520 case 'right': return pos.x >= data.width - maxEdgeStart;
31521 case 'top': return pos.y <= data.top + maxEdgeStart;
31522 case 'bottom': return pos.y >= data.height - maxEdgeStart;
31523 }
31524 return false;
31525 };
31526 return SlideEdgeGesture;
31527}(SlideGesture));
31528
31529var __extends$21 = (undefined && undefined.__extends) || (function () {
31530 var extendStatics = Object.setPrototypeOf ||
31531 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31532 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
31533 return function (d, b) {
31534 extendStatics(d, b);
31535 function __() { this.constructor = d; }
31536 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
31537 };
31538})();
31539/**
31540 * @hidden
31541 */
31542var SwipeBackGesture = (function (_super) {
31543 __extends$21(SwipeBackGesture, _super);
31544 /**
31545 * @param {?} plt
31546 * @param {?} _nav
31547 * @param {?} gestureCtlr
31548 * @param {?} domCtrl
31549 */
31550 function SwipeBackGesture(plt, _nav, gestureCtlr, domCtrl) {
31551 var _this = _super.call(this, plt, plt.doc().body, {
31552 direction: 'x',
31553 edge: 'start',
31554 maxEdgeStart: 75,
31555 threshold: 5,
31556 zone: false,
31557 domController: domCtrl,
31558 gesture: gestureCtlr.createGesture({
31559 name: GESTURE_GO_BACK_SWIPE,
31560 priority: GESTURE_PRIORITY_GO_BACK_SWIPE,
31561 disableScroll: true
31562 })
31563 }) || this;
31564 _this._nav = _nav;
31565 return _this;
31566 }
31567 /**
31568 * @param {?} ev
31569 * @return {?}
31570 */
31571 SwipeBackGesture.prototype.canStart = function (ev) {
31572 // the gesture swipe angle must be mainly horizontal and the
31573 // gesture distance would be relatively short for a swipe back
31574 // and swipe back must be possible on this nav controller
31575 return (this._nav.canSwipeBack() &&
31576 _super.prototype.canStart.call(this, ev));
31577 };
31578 /**
31579 * @param {?} _ev
31580 * @return {?}
31581 */
31582 SwipeBackGesture.prototype.onSlideBeforeStart = function (_ev) {
31583 this._nav.swipeBackStart();
31584 };
31585 /**
31586 * @param {?} slide
31587 * @param {?} ev
31588 * @return {?}
31589 */
31590 SwipeBackGesture.prototype.onSlide = function (slide, ev) {
31591 ev.preventDefault();
31592 ev.stopPropagation();
31593 var /** @type {?} */ stepValue = (slide.distance / slide.max);
31594 this._nav.swipeBackProgress(stepValue);
31595 };
31596 /**
31597 * @param {?} slide
31598 * @param {?} _ev
31599 * @return {?}
31600 */
31601 SwipeBackGesture.prototype.onSlideEnd = function (slide, _ev) {
31602 var /** @type {?} */ velocity = slide.velocity;
31603 var /** @type {?} */ currentStepValue = (slide.distance / slide.max);
31604 var /** @type {?} */ isResetDirecction = velocity < 0;
31605 var /** @type {?} */ isMovingFast = Math.abs(slide.velocity) > 0.4;
31606 var /** @type {?} */ isInResetZone = Math.abs(slide.delta) < Math.abs(slide.max) * 0.5;
31607 var /** @type {?} */ shouldComplete = !swipeShouldReset(isResetDirecction, isMovingFast, isInResetZone);
31608 this._nav.swipeBackEnd(shouldComplete, currentStepValue, velocity);
31609 };
31610 return SwipeBackGesture;
31611}(SlideEdgeGesture));
31612
31613var __extends$20 = (undefined && undefined.__extends) || (function () {
31614 var extendStatics = Object.setPrototypeOf ||
31615 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31616 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
31617 return function (d, b) {
31618 extendStatics(d, b);
31619 function __() { this.constructor = d; }
31620 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
31621 };
31622})();
31623/**
31624 * @hidden
31625 * This class is for internal use only. It is not exported publicly.
31626 */
31627var NavControllerBase = (function (_super) {
31628 __extends$20(NavControllerBase, _super);
31629 /**
31630 * @param {?} parent
31631 * @param {?} _app
31632 * @param {?} config
31633 * @param {?} plt
31634 * @param {?} elementRef
31635 * @param {?} _zone
31636 * @param {?} renderer
31637 * @param {?} _cfr
31638 * @param {?} _gestureCtrl
31639 * @param {?} _trnsCtrl
31640 * @param {?} _linker
31641 * @param {?} _domCtrl
31642 * @param {?} _errHandler
31643 */
31644 function NavControllerBase(parent, _app, config, plt, elementRef, _zone, renderer, _cfr, _gestureCtrl, _trnsCtrl, _linker, _domCtrl, _errHandler) {
31645 var _this = _super.call(this, config, elementRef, renderer) || this;
31646 _this.parent = parent;
31647 _this._app = _app;
31648 _this.config = config;
31649 _this.plt = plt;
31650 _this._zone = _zone;
31651 _this._cfr = _cfr;
31652 _this._gestureCtrl = _gestureCtrl;
31653 _this._trnsCtrl = _trnsCtrl;
31654 _this._linker = _linker;
31655 _this._domCtrl = _domCtrl;
31656 _this._errHandler = _errHandler;
31657 _this._ids = -1;
31658 _this._init = false;
31659 _this._queue = [];
31660 _this._trnsId = null;
31661 _this._trnsTm = false;
31662 _this._views = [];
31663 _this._zIndexOffset = 0;
31664 _this.viewDidLoad = new EventEmitter();
31665 _this.viewWillEnter = new EventEmitter();
31666 _this.viewDidEnter = new EventEmitter();
31667 _this.viewWillLeave = new EventEmitter();
31668 _this.viewDidLeave = new EventEmitter();
31669 _this.viewWillUnload = new EventEmitter();
31670 _this._sbEnabled = config.getBoolean('swipeBackEnabled');
31671 _this._children = [];
31672 _this.id = 'n' + (++ctrlIds);
31673 _this._destroyed = false;
31674 return _this;
31675 }
31676 Object.defineProperty(NavControllerBase.prototype, "swipeBackEnabled", {
31677 /**
31678 * @return {?}
31679 */
31680 get: function () {
31681 return this._sbEnabled;
31682 },
31683 /**
31684 * @param {?} val
31685 * @return {?}
31686 */
31687 set: function (val) {
31688 this._sbEnabled = isTrueProperty(val);
31689 this._swipeBackCheck();
31690 },
31691 enumerable: true,
31692 configurable: true
31693 });
31694 /**
31695 * @param {?} page
31696 * @param {?=} params
31697 * @param {?=} opts
31698 * @param {?=} done
31699 * @return {?}
31700 */
31701 NavControllerBase.prototype.push = function (page, params, opts, done) {
31702 return this._queueTrns({
31703 insertStart: -1,
31704 insertViews: [{ page: page, params: params }],
31705 opts: opts,
31706 }, done);
31707 };
31708 /**
31709 * @param {?} insertIndex
31710 * @param {?} page
31711 * @param {?=} params
31712 * @param {?=} opts
31713 * @param {?=} done
31714 * @return {?}
31715 */
31716 NavControllerBase.prototype.insert = function (insertIndex, page, params, opts, done) {
31717 return this._queueTrns({
31718 insertStart: insertIndex,
31719 insertViews: [{ page: page, params: params }],
31720 opts: opts,
31721 }, done);
31722 };
31723 /**
31724 * @param {?} insertIndex
31725 * @param {?} insertPages
31726 * @param {?=} opts
31727 * @param {?=} done
31728 * @return {?}
31729 */
31730 NavControllerBase.prototype.insertPages = function (insertIndex, insertPages, opts, done) {
31731 return this._queueTrns({
31732 insertStart: insertIndex,
31733 insertViews: insertPages,
31734 opts: opts,
31735 }, done);
31736 };
31737 /**
31738 * @param {?=} opts
31739 * @param {?=} done
31740 * @return {?}
31741 */
31742 NavControllerBase.prototype.pop = function (opts, done) {
31743 return this._queueTrns({
31744 removeStart: -1,
31745 removeCount: 1,
31746 opts: opts,
31747 }, done);
31748 };
31749 /**
31750 * @param {?} indexOrViewCtrl
31751 * @param {?=} opts
31752 * @param {?=} done
31753 * @return {?}
31754 */
31755 NavControllerBase.prototype.popTo = function (indexOrViewCtrl, opts, done) {
31756 var /** @type {?} */ config = {
31757 removeStart: -1,
31758 removeCount: -1,
31759 opts: opts
31760 };
31761 if (isViewController(indexOrViewCtrl)) {
31762 config.removeView = indexOrViewCtrl;
31763 config.removeStart = 1;
31764 }
31765 else if (isNumber(indexOrViewCtrl)) {
31766 config.removeStart = indexOrViewCtrl + 1;
31767 }
31768 return this._queueTrns(config, done);
31769 };
31770 /**
31771 * @param {?=} opts
31772 * @param {?=} done
31773 * @return {?}
31774 */
31775 NavControllerBase.prototype.popToRoot = function (opts, done) {
31776 return this._queueTrns({
31777 removeStart: 1,
31778 removeCount: -1,
31779 opts: opts,
31780 }, done);
31781 };
31782 /**
31783 * @return {?}
31784 */
31785 NavControllerBase.prototype.popAll = function () {
31786 var /** @type {?} */ promises = [];
31787 for (var /** @type {?} */ i = this._views.length - 1; i >= 0; i--) {
31788 promises.push(this.pop(null));
31789 }
31790 return Promise.all(promises);
31791 };
31792 /**
31793 * @param {?} startIndex
31794 * @param {?=} removeCount
31795 * @param {?=} opts
31796 * @param {?=} done
31797 * @return {?}
31798 */
31799 NavControllerBase.prototype.remove = function (startIndex, removeCount, opts, done) {
31800 if (removeCount === void 0) { removeCount = 1; }
31801 return this._queueTrns({
31802 removeStart: startIndex,
31803 removeCount: removeCount,
31804 opts: opts,
31805 }, done);
31806 };
31807 /**
31808 * @param {?} viewController
31809 * @param {?=} opts
31810 * @param {?=} done
31811 * @return {?}
31812 */
31813 NavControllerBase.prototype.removeView = function (viewController, opts, done) {
31814 return this._queueTrns({
31815 removeView: viewController,
31816 removeStart: 0,
31817 removeCount: 1,
31818 opts: opts,
31819 }, done);
31820 };
31821 /**
31822 * @param {?} pageOrViewCtrl
31823 * @param {?=} params
31824 * @param {?=} opts
31825 * @param {?=} done
31826 * @return {?}
31827 */
31828 NavControllerBase.prototype.setRoot = function (pageOrViewCtrl, params, opts, done) {
31829 return this.setPages([{ page: pageOrViewCtrl, params: params }], opts, done);
31830 };
31831 /**
31832 * @param {?} viewControllers
31833 * @param {?=} opts
31834 * @param {?=} done
31835 * @return {?}
31836 */
31837 NavControllerBase.prototype.setPages = function (viewControllers, opts, done) {
31838 if (isBlank$1(opts)) {
31839 opts = {};
31840 }
31841 // if animation wasn't set to true then default it to NOT animate
31842 if (opts.animate !== true) {
31843 opts.animate = false;
31844 }
31845 return this._queueTrns({
31846 insertStart: 0,
31847 insertViews: viewControllers,
31848 removeStart: 0,
31849 removeCount: -1,
31850 opts: opts
31851 }, done);
31852 };
31853 /**
31854 * @param {?} ti
31855 * @param {?} done
31856 * @return {?}
31857 */
31858 NavControllerBase.prototype._queueTrns = function (ti, done) {
31859 var /** @type {?} */ promise = new Promise(function (resolve, reject) {
31860 ti.resolve = resolve;
31861 ti.reject = reject;
31862 });
31863 ti.done = done;
31864 // Normalize empty
31865 if (ti.insertViews && ti.insertViews.length === 0) {
31866 ti.insertViews = undefined;
31867 }
31868 // Enqueue transition instruction
31869 this._queue.push(ti);
31870 // if there isn't a transition already happening
31871 // then this will kick off this transition
31872 this._nextTrns();
31873 return promise;
31874 };
31875 /**
31876 * @param {?} result
31877 * @param {?} ti
31878 * @return {?}
31879 */
31880 NavControllerBase.prototype._success = function (result, ti) {
31881 if (this._queue === null) {
31882 this._fireError('nav controller was destroyed', ti);
31883 return;
31884 }
31885 this._init = true;
31886 this._trnsId = null;
31887 // ensure we're not transitioning here
31888 this.setTransitioning(false);
31889 this._swipeBackCheck();
31890 // let's see if there's another to kick off
31891 this._nextTrns();
31892 if (ti.done) {
31893 ti.done(result.hasCompleted, result.requiresTransition, result.enteringName, result.leavingName, result.direction);
31894 }
31895 ti.resolve(result.hasCompleted);
31896 };
31897 /**
31898 * @param {?} rejectReason
31899 * @param {?} ti
31900 * @return {?}
31901 */
31902 NavControllerBase.prototype._failed = function (rejectReason, ti) {
31903 if (this._queue === null) {
31904 this._fireError('nav controller was destroyed', ti);
31905 return;
31906 }
31907 this._trnsId = null;
31908 this._queue.length = 0;
31909 // let's see if there's another to kick off
31910 this.setTransitioning(false);
31911 this._swipeBackCheck();
31912 this._nextTrns();
31913 this._fireError(rejectReason, ti);
31914 };
31915 /**
31916 * @param {?} rejectReason
31917 * @param {?} ti
31918 * @return {?}
31919 */
31920 NavControllerBase.prototype._fireError = function (rejectReason, ti) {
31921 if (ti.done) {
31922 ti.done(false, false, rejectReason);
31923 }
31924 if (ti.reject && !this._destroyed) {
31925 ti.reject(rejectReason);
31926 }
31927 else {
31928 ti.resolve(false);
31929 }
31930 };
31931 /**
31932 * @return {?}
31933 */
31934 NavControllerBase.prototype._nextTrns = function () {
31935 var _this = this;
31936 // this is the framework's bread 'n butta function
31937 // only one transition is allowed at any given time
31938 if (this.isTransitioning()) {
31939 return false;
31940 }
31941 // there is no transition happening right now
31942 // get the next instruction
31943 var /** @type {?} */ ti = this._queue.shift();
31944 if (!ti) {
31945 return false;
31946 }
31947 // set that this nav is actively transitioning
31948 var /** @type {?} */ enteringView;
31949 var /** @type {?} */ leavingView;
31950 this._startTI(ti)
31951 .then(function () { return _this._loadLazyLoading(ti); })
31952 .then(function () {
31953 leavingView = _this.getActive();
31954 enteringView = _this._getEnteringView(ti, leavingView);
31955 if (!leavingView && !enteringView) {
31956 throw 'no views in the stack to be removed';
31957 }
31958 if (enteringView && enteringView._state === STATE_NEW) {
31959 _this._viewInit(enteringView);
31960 }
31961 // Needs transition?
31962 ti.requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
31963 })
31964 .then(function () { return _this._viewTest(enteringView, leavingView, ti); })
31965 .then(function () { return _this._postViewInit(enteringView, leavingView, ti); })
31966 .then(function () { return _this._transition(enteringView, leavingView, ti); })
31967 .then(function (result) { return _this._success(result, ti); })
31968 .catch(function (rejectReason) { return _this._failed(rejectReason, ti); });
31969 return true;
31970 };
31971 /**
31972 * @param {?} ti
31973 * @return {?}
31974 */
31975 NavControllerBase.prototype._startTI = function (ti) {
31976 var /** @type {?} */ viewsLength = this._views.length;
31977 if (isPresent(ti.removeView)) {
31978 (void 0) /* assert */;
31979 (void 0) /* assert */;
31980 var /** @type {?} */ index = this.indexOf(ti.removeView);
31981 if (index < 0) {
31982 return Promise.reject('removeView was not found');
31983 }
31984 ti.removeStart += index;
31985 }
31986 if (isPresent(ti.removeStart)) {
31987 if (ti.removeStart < 0) {
31988 ti.removeStart = (viewsLength - 1);
31989 }
31990 if (ti.removeCount < 0) {
31991 ti.removeCount = (viewsLength - ti.removeStart);
31992 }
31993 ti.leavingRequiresTransition = (ti.removeCount > 0) && ((ti.removeStart + ti.removeCount) === viewsLength);
31994 }
31995 if (ti.insertViews) {
31996 // allow -1 to be passed in to auto push it on the end
31997 // and clean up the index if it's larger then the size of the stack
31998 if (ti.insertStart < 0 || ti.insertStart > viewsLength) {
31999 ti.insertStart = viewsLength;
32000 }
32001 ti.enteringRequiresTransition = (ti.insertStart === viewsLength);
32002 }
32003 this.setTransitioning(true);
32004 return Promise.resolve();
32005 };
32006 /**
32007 * @param {?} ti
32008 * @return {?}
32009 */
32010 NavControllerBase.prototype._loadLazyLoading = function (ti) {
32011 var _this = this;
32012 var /** @type {?} */ insertViews = ti.insertViews;
32013 if (insertViews) {
32014 (void 0) /* assert */;
32015 return convertToViews(this._linker, insertViews).then(function (viewControllers) {
32016 (void 0) /* assert */;
32017 viewControllers = viewControllers.filter(function (v) { return v !== null; });
32018 if (viewControllers.length === 0) {
32019 throw 'invalid views to insert';
32020 }
32021 // Check all the inserted view are correct
32022 for (var /** @type {?} */ i = 0; i < viewControllers.length; i++) {
32023 var /** @type {?} */ view = viewControllers[i];
32024 var /** @type {?} */ nav = view._nav;
32025 if (nav && nav !== _this) {
32026 throw 'inserted view was already inserted';
32027 }
32028 if (view._state === STATE_DESTROYED) {
32029 throw 'inserted view was already destroyed';
32030 }
32031 }
32032 ti.insertViews = viewControllers;
32033 });
32034 }
32035 return Promise.resolve();
32036 };
32037 /**
32038 * @param {?} ti
32039 * @param {?} leavingView
32040 * @return {?}
32041 */
32042 NavControllerBase.prototype._getEnteringView = function (ti, leavingView) {
32043 var /** @type {?} */ insertViews = ti.insertViews;
32044 if (insertViews) {
32045 // grab the very last view of the views to be inserted
32046 // and initialize it as the new entering view
32047 return insertViews[insertViews.length - 1];
32048 }
32049 var /** @type {?} */ removeStart = ti.removeStart;
32050 if (isPresent(removeStart)) {
32051 var /** @type {?} */ views = this._views;
32052 var /** @type {?} */ removeEnd = removeStart + ti.removeCount;
32053 var /** @type {?} */ i;
32054 var /** @type {?} */ view;
32055 for (i = views.length - 1; i >= 0; i--) {
32056 view = views[i];
32057 if ((i < removeStart || i >= removeEnd) && view !== leavingView) {
32058 return view;
32059 }
32060 }
32061 }
32062 return null;
32063 };
32064 /**
32065 * @param {?} enteringView
32066 * @param {?} leavingView
32067 * @param {?} ti
32068 * @return {?}
32069 */
32070 NavControllerBase.prototype._postViewInit = function (enteringView, leavingView, ti) {
32071 var _this = this;
32072 (void 0) /* assert */;
32073 (void 0) /* assert */;
32074 (void 0) /* assert */;
32075 var /** @type {?} */ opts = ti.opts || {};
32076 var /** @type {?} */ insertViews = ti.insertViews;
32077 var /** @type {?} */ removeStart = ti.removeStart;
32078 var /** @type {?} */ removeCount = ti.removeCount;
32079 var /** @type {?} */ view;
32080 var /** @type {?} */ i;
32081 var /** @type {?} */ destroyQueue;
32082 // there are views to remove
32083 if (isPresent(removeStart)) {
32084 (void 0) /* assert */;
32085 (void 0) /* assert */;
32086 destroyQueue = [];
32087 for (i = 0; i < removeCount; i++) {
32088 view = this._views[i + removeStart];
32089 if (view && view !== enteringView && view !== leavingView) {
32090 destroyQueue.push(view);
32091 }
32092 }
32093 // default the direction to "back"
32094 opts.direction = opts.direction || DIRECTION_BACK;
32095 }
32096 var /** @type {?} */ finalBalance = this._views.length + (insertViews ? insertViews.length : 0) - (removeCount ? removeCount : 0);
32097 (void 0) /* assert */;
32098 if (finalBalance === 0 && !this._isPortal) {
32099 console.warn("You can't remove all the pages in the navigation stack. nav.pop() is probably called too many times.", this, this.getNativeElement());
32100 throw 'navigation stack needs at least one root page';
32101 }
32102 // At this point the transition can not be rejected, any throw should be an error
32103 // there are views to insert
32104 if (insertViews) {
32105 // manually set the new view's id if an id was passed in the options
32106 if (isPresent(opts.id)) {
32107 enteringView.id = opts.id;
32108 }
32109 // add the views to the
32110 for (i = 0; i < insertViews.length; i++) {
32111 view = insertViews[i];
32112 this._insertViewAt(view, ti.insertStart + i);
32113 }
32114 if (ti.enteringRequiresTransition) {
32115 // default to forward if not already set
32116 opts.direction = opts.direction || DIRECTION_FORWARD;
32117 }
32118 }
32119 // if the views to be removed are in the beginning or middle
32120 // and there is not a view that needs to visually transition out
32121 // then just destroy them and don't transition anything
32122 // batch all of lifecycles together
32123 // let's make sure, callbacks are zoned
32124 if (destroyQueue && destroyQueue.length > 0) {
32125 this._zone.run(function () {
32126 for (i = 0; i < destroyQueue.length; i++) {
32127 view = destroyQueue[i];
32128 _this._willLeave(view, true);
32129 _this._didLeave(view);
32130 _this._willUnload(view);
32131 }
32132 });
32133 // once all lifecycle events has been delivered, we can safely detroy the views
32134 for (i = 0; i < destroyQueue.length; i++) {
32135 this._destroyView(destroyQueue[i]);
32136 }
32137 }
32138 // set which animation it should use if it wasn't set yet
32139 if (ti.requiresTransition && !opts.animation) {
32140 if (isPresent(ti.removeStart)) {
32141 opts.animation = (leavingView || enteringView).getTransitionName(opts.direction);
32142 }
32143 else {
32144 opts.animation = (enteringView || leavingView).getTransitionName(opts.direction);
32145 }
32146 }
32147 ti.opts = opts;
32148 };
32149 /**
32150 * DOM WRITE
32151 * @param {?} enteringView
32152 * @return {?}
32153 */
32154 NavControllerBase.prototype._viewInit = function (enteringView) {
32155 (void 0) /* assert */;
32156 (void 0) /* assert */;
32157 // render the entering view, and all child navs and views
32158 // entering view has not been initialized yet
32159 var /** @type {?} */ componentProviders = ReflectiveInjector.resolve([
32160 { provide: NavController, useValue: this },
32161 { provide: ViewController, useValue: enteringView },
32162 { provide: NavParams, useValue: enteringView.getNavParams() }
32163 ]);
32164 var /** @type {?} */ componentFactory = this._linker.resolveComponent(enteringView.component);
32165 var /** @type {?} */ childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, this._viewport.parentInjector);
32166 // create ComponentRef and set it to the entering view
32167 enteringView.init(componentFactory.create(childInjector, []));
32168 enteringView._state = STATE_INITIALIZED;
32169 this._preLoad(enteringView);
32170 };
32171 /**
32172 * @param {?} view
32173 * @param {?} componentRef
32174 * @param {?} viewport
32175 * @return {?}
32176 */
32177 NavControllerBase.prototype._viewAttachToDOM = function (view, componentRef, viewport) {
32178 (void 0) /* assert */;
32179 (void 0) /* assert */;
32180 // fire willLoad before change detection runs
32181 this._willLoad(view);
32182 // render the component ref instance to the DOM
32183 // ******** DOM WRITE ****************
32184 viewport.insert(componentRef.hostView, viewport.length);
32185 view._state = STATE_ATTACHED;
32186 if (view._cssClass) {
32187 // the ElementRef of the actual ion-page created
32188 var /** @type {?} */ pageElement = componentRef.location.nativeElement;
32189 // ******** DOM WRITE ****************
32190 this._renderer.setElementClass(pageElement, view._cssClass, true);
32191 }
32192 componentRef.changeDetectorRef.detectChanges();
32193 // successfully finished loading the entering view
32194 // fire off the "didLoad" lifecycle events
32195 this._zone.run(this._didLoad.bind(this, view));
32196 };
32197 /**
32198 * @param {?} enteringView
32199 * @param {?} leavingView
32200 * @param {?} ti
32201 * @return {?}
32202 */
32203 NavControllerBase.prototype._viewTest = function (enteringView, leavingView, ti) {
32204 // Only test canLeave/canEnter if there is transition
32205 if (!ti.requiresTransition) {
32206 return Promise.resolve();
32207 }
32208 var /** @type {?} */ promises = [];
32209 if (leavingView) {
32210 promises.push(leavingView._lifecycleTest('Leave'));
32211 }
32212 if (enteringView) {
32213 promises.push(enteringView._lifecycleTest('Enter'));
32214 }
32215 if (promises.length === 0) {
32216 return Promise.resolve();
32217 }
32218 // darn, async promises, gotta wait for them to resolve
32219 return Promise.all(promises).then(function (values) {
32220 if (values.some(function (result) { return result === false; })) {
32221 throw 'canEnter/Leave returned false';
32222 }
32223 }).catch(function (reason) {
32224 // Do not
32225 ti.reject = null;
32226 throw reason;
32227 });
32228 };
32229 /**
32230 * @param {?} enteringView
32231 * @param {?} leavingView
32232 * @param {?} ti
32233 * @return {?}
32234 */
32235 NavControllerBase.prototype._transition = function (enteringView, leavingView, ti) {
32236 var _this = this;
32237 if (!ti.requiresTransition) {
32238 // transition is not required, so we are already done!
32239 // they're inserting/removing the views somewhere in the middle or
32240 // beginning, so visually nothing needs to animate/transition
32241 // resolve immediately because there's no animation that's happening
32242 return Promise.resolve({
32243 hasCompleted: true,
32244 requiresTransition: false
32245 });
32246 }
32247 var /** @type {?} */ opts = ti.opts;
32248 // figure out if this transition is the root one or a
32249 // child of a parent nav that has the root transition
32250 this._trnsId = this._trnsCtrl.getRootTrnsId(this);
32251 if (this._trnsId === null) {
32252 // this is the root transition, meaning all child navs and their views
32253 // should be added as a child transition to this one
32254 this._trnsId = this._trnsCtrl.nextId();
32255 }
32256 // create the transition options
32257 var /** @type {?} */ animationOpts = {
32258 animation: opts.animation,
32259 direction: opts.direction,
32260 duration: (opts.animate === false ? 0 : opts.duration),
32261 easing: opts.easing,
32262 isRTL: this._config.plt.isRTL,
32263 ev: opts.ev,
32264 };
32265 // create the transition animation from the TransitionController
32266 // this will either create the root transition, or add it as a child transition
32267 var /** @type {?} */ transition$$1 = this._trnsCtrl.get(this._trnsId, enteringView, leavingView, animationOpts);
32268 // ensure any swipeback transitions are cleared out
32269 this._sbTrns && this._sbTrns.destroy();
32270 this._sbTrns = null;
32271 // swipe to go back root transition
32272 if (transition$$1.isRoot() && opts.progressAnimation) {
32273 this._sbTrns = transition$$1;
32274 }
32275 // transition start has to be registered before attaching the view to the DOM!
32276 var /** @type {?} */ promise = new Promise(function (resolve) { return transition$$1.registerStart(resolve); }).then(function () {
32277 return _this._transitionStart(transition$$1, enteringView, leavingView, opts);
32278 });
32279 if (enteringView && (enteringView._state === STATE_INITIALIZED)) {
32280 // render the entering component in the DOM
32281 // this would also render new child navs/views
32282 // which may have their very own async canEnter/Leave tests
32283 // ******** DOM WRITE ****************
32284 this._viewAttachToDOM(enteringView, enteringView._cmp, this._viewport);
32285 }
32286 if (!transition$$1.hasChildren) {
32287 // lowest level transition, so kick it off and let it bubble up to start all of them
32288 transition$$1.start();
32289 }
32290 return promise;
32291 };
32292 /**
32293 * @param {?} transition
32294 * @param {?} enteringView
32295 * @param {?} leavingView
32296 * @param {?} opts
32297 * @return {?}
32298 */
32299 NavControllerBase.prototype._transitionStart = function (transition$$1, enteringView, leavingView, opts) {
32300 var _this = this;
32301 (void 0) /* assert */;
32302 this._trnsId = null;
32303 // set the correct zIndex for the entering and leaving views
32304 // ******** DOM WRITE ****************
32305 setZIndex(this, enteringView, leavingView, opts.direction, this._renderer);
32306 // always ensure the entering view is viewable
32307 // ******** DOM WRITE ****************
32308 enteringView && enteringView._domShow(true, this._renderer);
32309 // always ensure the leaving view is viewable
32310 // ******** DOM WRITE ****************
32311 leavingView && leavingView._domShow(true, this._renderer);
32312 // initialize the transition
32313 transition$$1.init();
32314 // we should animate (duration > 0) if the pushed page is not the first one (startup)
32315 // or if it is a portal (modal, actionsheet, etc.)
32316 var /** @type {?} */ isFirstPage = !this._init && this._views.length === 1;
32317 var /** @type {?} */ shouldNotAnimate = isFirstPage && !this._isPortal;
32318 var /** @type {?} */ canNotAnimate = this._config.get('animate') === false;
32319 if (shouldNotAnimate || canNotAnimate) {
32320 opts.animate = false;
32321 }
32322 if (opts.animate === false) {
32323 // if it was somehow set to not animation, then make the duration zero
32324 transition$$1.duration(0);
32325 }
32326 // create a callback that needs to run within zone
32327 // that will fire off the willEnter/Leave lifecycle events at the right time
32328 transition$$1.beforeAddRead(this._viewsWillLifecycles.bind(this, enteringView, leavingView));
32329 // get the set duration of this transition
32330 var /** @type {?} */ duration = transition$$1.getDuration();
32331 // create a callback for when the animation is done
32332 var /** @type {?} */ promise = new Promise(function (resolve) {
32333 transition$$1.onFinish(resolve);
32334 });
32335 if (transition$$1.isRoot()) {
32336 // this is the top most, or only active transition, so disable the app
32337 // add XXms to the duration the app is disabled when the keyboard is open
32338 if (duration > DISABLE_APP_MINIMUM_DURATION && opts.disableApp !== false) {
32339 // if this transition has a duration and this is the root transition
32340 // then set that the app is actively disabled
32341 this._app.setEnabled(false, duration + ACTIVE_TRANSITION_OFFSET, opts.minClickBlockDuration);
32342 }
32343 else {
32344 (void 0) /* console.debug */;
32345 }
32346 // cool, let's do this, start the transition
32347 if (opts.progressAnimation) {
32348 // this is a swipe to go back, just get the transition progress ready
32349 // kick off the swipe animation start
32350 transition$$1.progressStart();
32351 }
32352 else {
32353 // only the top level transition should actually start "play"
32354 // kick it off and let it play through
32355 // ******** DOM WRITE ****************
32356 transition$$1.play();
32357 }
32358 }
32359 return promise.then(function () { return _this._zone.run(function () {
32360 return _this._transitionFinish(transition$$1, opts);
32361 }); });
32362 };
32363 /**
32364 * @param {?} transition
32365 * @param {?} opts
32366 * @return {?}
32367 */
32368 NavControllerBase.prototype._transitionFinish = function (transition$$1, opts) {
32369 var /** @type {?} */ hasCompleted = transition$$1.hasCompleted;
32370 var /** @type {?} */ enteringView = transition$$1.enteringView;
32371 var /** @type {?} */ leavingView = transition$$1.leavingView;
32372 // mainly for testing
32373 var /** @type {?} */ enteringName;
32374 var /** @type {?} */ leavingName;
32375 if (hasCompleted) {
32376 // transition has completed (went from 0 to 1)
32377 if (enteringView) {
32378 enteringName = enteringView.name;
32379 this._didEnter(enteringView);
32380 }
32381 if (leavingView) {
32382 leavingName = leavingView.name;
32383 this._didLeave(leavingView);
32384 }
32385 this._cleanup(enteringView);
32386 }
32387 else {
32388 // If transition does not complete, we have to cleanup anyway, because
32389 // previous pages in the stack are not hidden probably.
32390 this._cleanup(leavingView);
32391 }
32392 if (transition$$1.isRoot()) {
32393 // this is the root transition
32394 // it's safe to destroy this transition
32395 this._trnsCtrl.destroy(transition$$1.trnsId);
32396 // it's safe to enable the app again
32397 this._app.setEnabled(true);
32398 // mark ourselves as not transitioning - `deepLinker navchange` requires this
32399 // TODO - probably could be resolved in a better way
32400 this.setTransitioning(false);
32401 if (!this.hasChildren() && opts.updateUrl !== false) {
32402 // notify deep linker of the nav change
32403 // if a direction was provided and should update url
32404 this._linker.navChange(opts.direction);
32405 }
32406 if (opts.keyboardClose !== false) {
32407 // the keyboard is still open!
32408 // no problem, let's just close for them
32409 this.plt.focusOutActiveElement();
32410 }
32411 }
32412 return {
32413 hasCompleted: hasCompleted,
32414 requiresTransition: true,
32415 enteringName: enteringName,
32416 leavingName: leavingName,
32417 direction: opts.direction
32418 };
32419 };
32420 /**
32421 * @param {?} enteringView
32422 * @param {?} leavingView
32423 * @return {?}
32424 */
32425 NavControllerBase.prototype._viewsWillLifecycles = function (enteringView, leavingView) {
32426 var _this = this;
32427 if (enteringView || leavingView) {
32428 this._zone.run(function () {
32429 // Here, the order is important. WillLeave must be called before WillEnter.
32430 leavingView && _this._willLeave(leavingView, !enteringView);
32431 enteringView && _this._willEnter(enteringView);
32432 });
32433 }
32434 };
32435 /**
32436 * @param {?} view
32437 * @param {?} index
32438 * @return {?}
32439 */
32440 NavControllerBase.prototype._insertViewAt = function (view, index) {
32441 var /** @type {?} */ existingIndex = this._views.indexOf(view);
32442 if (existingIndex > -1) {
32443 // this view is already in the stack!!
32444 // move it to its new location
32445 (void 0) /* assert */;
32446 this._views.splice(index, 0, this._views.splice(existingIndex, 1)[0]);
32447 }
32448 else {
32449 (void 0) /* assert */;
32450 // this is a new view to add to the stack
32451 // create the new entering view
32452 view._setNav(this);
32453 // give this inserted view an ID
32454 this._ids++;
32455 if (!view.id) {
32456 view.id = this.id + "-" + this._ids;
32457 }
32458 // insert the entering view into the correct index in the stack
32459 this._views.splice(index, 0, view);
32460 }
32461 };
32462 /**
32463 * @param {?} view
32464 * @return {?}
32465 */
32466 NavControllerBase.prototype._removeView = function (view) {
32467 (void 0) /* assert */;
32468 var /** @type {?} */ views = this._views;
32469 var /** @type {?} */ index = views.indexOf(view);
32470 (void 0) /* assert */;
32471 if (index >= 0) {
32472 views.splice(index, 1);
32473 }
32474 };
32475 /**
32476 * @param {?} view
32477 * @return {?}
32478 */
32479 NavControllerBase.prototype._destroyView = function (view) {
32480 view._destroy(this._renderer);
32481 this._removeView(view);
32482 };
32483 /**
32484 * DOM WRITE
32485 * @param {?} activeView
32486 * @return {?}
32487 */
32488 NavControllerBase.prototype._cleanup = function (activeView) {
32489 // ok, cleanup time!! Destroy all of the views that are
32490 // INACTIVE and come after the active view
32491 // only do this if the views exist, though
32492 if (!this._destroyed) {
32493 var /** @type {?} */ activeViewIndex = this._views.indexOf(activeView);
32494 var /** @type {?} */ views = this._views;
32495 var /** @type {?} */ reorderZIndexes = false;
32496 var /** @type {?} */ view = void 0;
32497 var /** @type {?} */ i = void 0;
32498 for (i = views.length - 1; i >= 0; i--) {
32499 view = views[i];
32500 if (i > activeViewIndex) {
32501 // this view comes after the active view
32502 // let's unload it
32503 this._willUnload(view);
32504 this._destroyView(view);
32505 }
32506 else if (i < activeViewIndex && !this._isPortal) {
32507 // this view comes before the active view
32508 // and it is not a portal then ensure it is hidden
32509 view._domShow(false, this._renderer);
32510 }
32511 if (view._zIndex <= 0) {
32512 reorderZIndexes = true;
32513 }
32514 }
32515 if (!this._isPortal && reorderZIndexes) {
32516 for (i = 0; i < views.length; i++) {
32517 view = views[i];
32518 // ******** DOM WRITE ****************
32519 view._setZIndex(view._zIndex + INIT_ZINDEX + 1, this._renderer);
32520 }
32521 }
32522 }
32523 };
32524 /**
32525 * @param {?} view
32526 * @return {?}
32527 */
32528 NavControllerBase.prototype._preLoad = function (view) {
32529 (void 0) /* assert */;
32530 view._preLoad();
32531 };
32532 /**
32533 * @param {?} view
32534 * @return {?}
32535 */
32536 NavControllerBase.prototype._willLoad = function (view) {
32537 (void 0) /* assert */;
32538 try {
32539 view._willLoad();
32540 }
32541 catch (e) {
32542 this._errHandler && this._errHandler.handleError(e);
32543 }
32544 };
32545 /**
32546 * @param {?} view
32547 * @return {?}
32548 */
32549 NavControllerBase.prototype._didLoad = function (view) {
32550 (void 0) /* assert */;
32551 (void 0) /* assert */;
32552 try {
32553 view._didLoad();
32554 this.viewDidLoad.emit(view);
32555 this._app.viewDidLoad.emit(view);
32556 }
32557 catch (e) {
32558 this._errHandler && this._errHandler.handleError(e);
32559 }
32560 };
32561 /**
32562 * @param {?} view
32563 * @return {?}
32564 */
32565 NavControllerBase.prototype._willEnter = function (view) {
32566 (void 0) /* assert */;
32567 (void 0) /* assert */;
32568 try {
32569 view._willEnter();
32570 this.viewWillEnter.emit(view);
32571 this._app.viewWillEnter.emit(view);
32572 }
32573 catch (e) {
32574 this._errHandler && this._errHandler.handleError(e);
32575 }
32576 };
32577 /**
32578 * @param {?} view
32579 * @return {?}
32580 */
32581 NavControllerBase.prototype._didEnter = function (view) {
32582 (void 0) /* assert */;
32583 (void 0) /* assert */;
32584 try {
32585 view._didEnter();
32586 this.viewDidEnter.emit(view);
32587 this._app.viewDidEnter.emit(view);
32588 }
32589 catch (e) {
32590 this._errHandler && this._errHandler.handleError(e);
32591 }
32592 };
32593 /**
32594 * @param {?} view
32595 * @param {?} willUnload
32596 * @return {?}
32597 */
32598 NavControllerBase.prototype._willLeave = function (view, willUnload) {
32599 (void 0) /* assert */;
32600 (void 0) /* assert */;
32601 try {
32602 view._willLeave(willUnload);
32603 this.viewWillLeave.emit(view);
32604 this._app.viewWillLeave.emit(view);
32605 }
32606 catch (e) {
32607 this._errHandler && this._errHandler.handleError(e);
32608 }
32609 };
32610 /**
32611 * @param {?} view
32612 * @return {?}
32613 */
32614 NavControllerBase.prototype._didLeave = function (view) {
32615 (void 0) /* assert */;
32616 (void 0) /* assert */;
32617 try {
32618 view._didLeave();
32619 this.viewDidLeave.emit(view);
32620 this._app.viewDidLeave.emit(view);
32621 }
32622 catch (e) {
32623 this._errHandler && this._errHandler.handleError(e);
32624 }
32625 };
32626 /**
32627 * @param {?} view
32628 * @return {?}
32629 */
32630 NavControllerBase.prototype._willUnload = function (view) {
32631 (void 0) /* assert */;
32632 (void 0) /* assert */;
32633 try {
32634 view._willUnload();
32635 this.viewWillUnload.emit(view);
32636 this._app.viewWillUnload.emit(view);
32637 }
32638 catch (e) {
32639 this._errHandler && this._errHandler.handleError(e);
32640 }
32641 };
32642 /**
32643 * @return {?}
32644 */
32645 NavControllerBase.prototype.hasChildren = function () {
32646 return this._children && this._children.length > 0;
32647 };
32648 /**
32649 * @return {?}
32650 */
32651 NavControllerBase.prototype.getActiveChildNavs = function () {
32652 return this._children;
32653 };
32654 /**
32655 * @return {?}
32656 */
32657 NavControllerBase.prototype.getAllChildNavs = function () {
32658 return this._children;
32659 };
32660 /**
32661 * @param {?} container
32662 * @return {?}
32663 */
32664 NavControllerBase.prototype.registerChildNav = function (container) {
32665 this._children.push(container);
32666 };
32667 /**
32668 * @param {?} nav
32669 * @return {?}
32670 */
32671 NavControllerBase.prototype.unregisterChildNav = function (nav) {
32672 this._children = this._children.filter(function (child) { return child !== nav; });
32673 };
32674 /**
32675 * @return {?}
32676 */
32677 NavControllerBase.prototype.destroy = function () {
32678 var /** @type {?} */ views = this._views;
32679 var /** @type {?} */ view;
32680 for (var /** @type {?} */ i = 0; i < views.length; i++) {
32681 view = views[i];
32682 view._willUnload();
32683 view._destroy(this._renderer);
32684 }
32685 // release swipe back gesture and transition
32686 this._sbGesture && this._sbGesture.destroy();
32687 this._sbTrns && this._sbTrns.destroy();
32688 this._queue = this._views = this._sbGesture = this._sbTrns = null;
32689 // Unregister navcontroller
32690 if (this.parent && this.parent.unregisterChildNav) {
32691 this.parent.unregisterChildNav(this);
32692 }
32693 this._destroyed = true;
32694 };
32695 /**
32696 * @return {?}
32697 */
32698 NavControllerBase.prototype.swipeBackStart = function () {
32699 if (this.isTransitioning() || this._queue.length > 0) {
32700 return;
32701 }
32702 // default the direction to "back";
32703 var /** @type {?} */ opts = {
32704 direction: DIRECTION_BACK,
32705 progressAnimation: true
32706 };
32707 this._queueTrns({
32708 removeStart: -1,
32709 removeCount: 1,
32710 opts: opts,
32711 }, null);
32712 };
32713 /**
32714 * @param {?} stepValue
32715 * @return {?}
32716 */
32717 NavControllerBase.prototype.swipeBackProgress = function (stepValue) {
32718 if (this._sbTrns && this._sbGesture) {
32719 // continue to disable the app while actively dragging
32720 this._app.setEnabled(false, ACTIVE_TRANSITION_DEFAULT);
32721 this.setTransitioning(true);
32722 // set the transition animation's progress
32723 this._sbTrns.progressStep(stepValue);
32724 }
32725 };
32726 /**
32727 * @param {?} shouldComplete
32728 * @param {?} currentStepValue
32729 * @param {?} velocity
32730 * @return {?}
32731 */
32732 NavControllerBase.prototype.swipeBackEnd = function (shouldComplete, currentStepValue, velocity) {
32733 if (this._sbTrns && this._sbGesture) {
32734 // the swipe back gesture has ended
32735 var /** @type {?} */ dur = this._sbTrns.getDuration() / (Math.abs(velocity) + 1);
32736 this._sbTrns.progressEnd(shouldComplete, currentStepValue, dur);
32737 }
32738 };
32739 /**
32740 * @return {?}
32741 */
32742 NavControllerBase.prototype._swipeBackCheck = function () {
32743 if (this.canSwipeBack()) {
32744 if (!this._sbGesture) {
32745 this._sbGesture = new SwipeBackGesture(this.plt, this, this._gestureCtrl, this._domCtrl);
32746 }
32747 this._sbGesture.listen();
32748 }
32749 else if (this._sbGesture) {
32750 this._sbGesture.unlisten();
32751 }
32752 };
32753 /**
32754 * @return {?}
32755 */
32756 NavControllerBase.prototype.canSwipeBack = function () {
32757 return (this._sbEnabled &&
32758 !this._isPortal &&
32759 !this._children.length &&
32760 !this.isTransitioning() &&
32761 this._app.isEnabled() &&
32762 this.canGoBack());
32763 };
32764 /**
32765 * @return {?}
32766 */
32767 NavControllerBase.prototype.canGoBack = function () {
32768 var /** @type {?} */ activeView = this.getActive();
32769 return !!(activeView && activeView.enableBack());
32770 };
32771 /**
32772 * @return {?}
32773 */
32774 NavControllerBase.prototype.isTransitioning = function () {
32775 return this._trnsTm;
32776 };
32777 /**
32778 * @param {?} isTransitioning
32779 * @return {?}
32780 */
32781 NavControllerBase.prototype.setTransitioning = function (isTransitioning) {
32782 this._trnsTm = isTransitioning;
32783 };
32784 /**
32785 * @return {?}
32786 */
32787 NavControllerBase.prototype.getActive = function () {
32788 return this._views[this._views.length - 1];
32789 };
32790 /**
32791 * @param {?} view
32792 * @return {?}
32793 */
32794 NavControllerBase.prototype.isActive = function (view) {
32795 return (view === this.getActive());
32796 };
32797 /**
32798 * @param {?} index
32799 * @return {?}
32800 */
32801 NavControllerBase.prototype.getByIndex = function (index) {
32802 return this._views[index];
32803 };
32804 /**
32805 * @param {?=} view
32806 * @return {?}
32807 */
32808 NavControllerBase.prototype.getPrevious = function (view) {
32809 // returns the view controller which is before the given view controller.
32810 if (!view) {
32811 view = this.getActive();
32812 }
32813 var /** @type {?} */ views = this._views;
32814 return views[views.indexOf(view) - 1];
32815 };
32816 /**
32817 * @return {?}
32818 */
32819 NavControllerBase.prototype.first = function () {
32820 // returns the first view controller in this nav controller's stack.
32821 return this._views[0];
32822 };
32823 /**
32824 * @return {?}
32825 */
32826 NavControllerBase.prototype.last = function () {
32827 // returns the last page in this nav controller's stack.
32828 return this._views[this._views.length - 1];
32829 };
32830 /**
32831 * @param {?} view
32832 * @return {?}
32833 */
32834 NavControllerBase.prototype.indexOf = function (view) {
32835 // returns the index number of the given view controller.
32836 return this._views.indexOf(view);
32837 };
32838 /**
32839 * @return {?}
32840 */
32841 NavControllerBase.prototype.length = function () {
32842 return this._views.length;
32843 };
32844 /**
32845 * Return the stack of views in this NavController.
32846 * @return {?}
32847 */
32848 NavControllerBase.prototype.getViews = function () {
32849 return this._views;
32850 };
32851 /**
32852 * Return a view controller
32853 * @param {?} id
32854 * @return {?}
32855 */
32856 NavControllerBase.prototype.getViewById = function (id) {
32857 for (var _i = 0, _a = this._views; _i < _a.length; _i++) {
32858 var vc = _a[_i];
32859 if (vc && vc.id === id) {
32860 return vc;
32861 }
32862 }
32863 return null;
32864 };
32865 /**
32866 * @return {?}
32867 */
32868 NavControllerBase.prototype.isSwipeBackEnabled = function () {
32869 return this._sbEnabled;
32870 };
32871 /**
32872 * @return {?}
32873 */
32874 NavControllerBase.prototype.dismissPageChangeViews = function () {
32875 for (var _i = 0, _a = this._views; _i < _a.length; _i++) {
32876 var view = _a[_i];
32877 if (view.data && view.data.dismissOnPageChange) {
32878 view.dismiss().catch(function () { });
32879 }
32880 }
32881 };
32882 /**
32883 * @param {?} val
32884 * @return {?}
32885 */
32886 NavControllerBase.prototype.setViewport = function (val) {
32887 this._viewport = val;
32888 };
32889 /**
32890 * @return {?}
32891 */
32892 NavControllerBase.prototype.resize = function () {
32893 var /** @type {?} */ active = this.getActive();
32894 if (!active) {
32895 return;
32896 }
32897 var /** @type {?} */ content = active.getIONContent();
32898 content && content.resize();
32899 };
32900 /**
32901 * @param {?} _opts
32902 * @return {?}
32903 */
32904 NavControllerBase.prototype.goToRoot = function (_opts) {
32905 return Promise.reject(new Error('goToRoot needs to be implemented by child class'));
32906 };
32907 /**
32908 * @return {?}
32909 */
32910 NavControllerBase.prototype.getType = function () {
32911 return 'nav';
32912 };
32913 /**
32914 * @return {?}
32915 */
32916 NavControllerBase.prototype.getSecondaryIdentifier = function () {
32917 return null;
32918 };
32919 /**
32920 * Returns the active child navigation.
32921 * @return {?}
32922 */
32923 NavControllerBase.prototype.getActiveChildNav = function () {
32924 console.warn('(getActiveChildNav) is deprecated and will be removed in the next major release. Use getActiveChildNavs instead.');
32925 return this._children[this._children.length - 1];
32926 };
32927 return NavControllerBase;
32928}(Ion));
32929NavControllerBase.propDecorators = {
32930 'swipeBackEnabled': [{ type: Input },],
32931};
32932var ctrlIds = -1;
32933var DISABLE_APP_MINIMUM_DURATION = 64;
32934var ACTIVE_TRANSITION_DEFAULT = 5000;
32935var ACTIVE_TRANSITION_OFFSET = 2000;
32936
32937/**
32938 * @hidden
32939 */
32940var TransitionController = (function () {
32941 /**
32942 * @param {?} plt
32943 * @param {?} _config
32944 */
32945 function TransitionController(plt, _config) {
32946 this.plt = plt;
32947 this._config = _config;
32948 this._ids = 0;
32949 this._trns = {};
32950 }
32951 /**
32952 * @param {?} nav
32953 * @return {?}
32954 */
32955 TransitionController.prototype.getRootTrnsId = function (nav) {
32956 nav = (nav.parent);
32957 while (nav) {
32958 if (isPresent(nav._trnsId)) {
32959 return nav._trnsId;
32960 }
32961 nav = nav.parent;
32962 }
32963 return null;
32964 };
32965 /**
32966 * @return {?}
32967 */
32968 TransitionController.prototype.nextId = function () {
32969 return this._ids++;
32970 };
32971 /**
32972 * @param {?} trnsId
32973 * @param {?} enteringView
32974 * @param {?} leavingView
32975 * @param {?} opts
32976 * @return {?}
32977 */
32978 TransitionController.prototype.get = function (trnsId, enteringView, leavingView, opts) {
32979 var /** @type {?} */ TransitionClass = this._config.getTransition(opts.animation);
32980 if (!TransitionClass) {
32981 // didn't find a transition animation, default to ios-transition
32982 TransitionClass = this._config.getTransition('ios-transition');
32983 }
32984 var /** @type {?} */ trns = new TransitionClass(this.plt, enteringView, leavingView, opts);
32985 trns.trnsId = trnsId;
32986 if (!this._trns[trnsId]) {
32987 // we haven't created the root transition yet
32988 this._trns[trnsId] = trns;
32989 }
32990 else {
32991 // we already have a root transition created
32992 // add this new transition as a child to the root
32993 this._trns[trnsId].add(trns);
32994 }
32995 return trns;
32996 };
32997 /**
32998 * @param {?} trnsId
32999 * @return {?}
33000 */
33001 TransitionController.prototype.destroy = function (trnsId) {
33002 var /** @type {?} */ trans = this._trns[trnsId];
33003 if (trans) {
33004 trans.destroy();
33005 delete this._trns[trnsId];
33006 }
33007 };
33008 return TransitionController;
33009}());
33010TransitionController.decorators = [
33011 { type: Injectable },
33012];
33013/**
33014 * @nocollapse
33015 */
33016TransitionController.ctorParameters = function () { return [
33017 { type: Platform, },
33018 { type: Config, },
33019]; };
33020
33021var __extends$19 = (undefined && undefined.__extends) || (function () {
33022 var extendStatics = Object.setPrototypeOf ||
33023 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33024 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
33025 return function (d, b) {
33026 extendStatics(d, b);
33027 function __() { this.constructor = d; }
33028 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33029 };
33030})();
33031/**
33032 * @hidden
33033 */
33034var OverlayPortal = (function (_super) {
33035 __extends$19(OverlayPortal, _super);
33036 /**
33037 * @param {?} app
33038 * @param {?} config
33039 * @param {?} plt
33040 * @param {?} elementRef
33041 * @param {?} zone
33042 * @param {?} renderer
33043 * @param {?} cfr
33044 * @param {?} gestureCtrl
33045 * @param {?} transCtrl
33046 * @param {?} linker
33047 * @param {?} viewPort
33048 * @param {?} domCtrl
33049 * @param {?} errHandler
33050 */
33051 function OverlayPortal(app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, viewPort, domCtrl, errHandler) {
33052 var _this = _super.call(this, null, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) || this;
33053 _this._isPortal = true;
33054 _this._init = true;
33055 _this.setViewport(viewPort);
33056 // on every page change make sure the portal has
33057 // dismissed any views that should be auto dismissed on page change
33058 app.viewDidLeave.subscribe(function (view) {
33059 if (!view.isOverlay) {
33060 _this.dismissPageChangeViews();
33061 }
33062 });
33063 return _this;
33064 }
33065 Object.defineProperty(OverlayPortal.prototype, "_overlayPortal", {
33066 /**
33067 * @param {?} val
33068 * @return {?}
33069 */
33070 set: function (val) {
33071 this._zIndexOffset = (val || 0);
33072 },
33073 enumerable: true,
33074 configurable: true
33075 });
33076 /**
33077 * @return {?}
33078 */
33079 OverlayPortal.prototype.ngOnDestroy = function () {
33080 this.destroy();
33081 };
33082 /**
33083 * @return {?}
33084 */
33085 OverlayPortal.prototype.getType = function () {
33086 return 'portal';
33087 };
33088 /**
33089 * @return {?}
33090 */
33091 OverlayPortal.prototype.getSecondaryIdentifier = function () {
33092 return null;
33093 };
33094 return OverlayPortal;
33095}(NavControllerBase));
33096OverlayPortal.decorators = [
33097 { type: Directive, args: [{
33098 selector: '[overlay-portal]',
33099 },] },
33100];
33101/**
33102 * @nocollapse
33103 */
33104OverlayPortal.ctorParameters = function () { return [
33105 { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
33106 { type: Config, },
33107 { type: Platform, },
33108 { type: ElementRef, },
33109 { type: NgZone, },
33110 { type: Renderer, },
33111 { type: ComponentFactoryResolver, },
33112 { type: GestureController, },
33113 { type: TransitionController, },
33114 { type: DeepLinker, decorators: [{ type: Optional },] },
33115 { type: ViewContainerRef, },
33116 { type: DomController, },
33117 { type: ErrorHandler, },
33118]; };
33119OverlayPortal.propDecorators = {
33120 '_overlayPortal': [{ type: Input, args: ['overlay-portal',] },],
33121};
33122
33123var __extends = (undefined && undefined.__extends) || (function () {
33124 var extendStatics = Object.setPrototypeOf ||
33125 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33126 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
33127 return function (d, b) {
33128 extendStatics(d, b);
33129 function __() { this.constructor = d; }
33130 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33131 };
33132})();
33133var AppRootToken = new OpaqueToken('USERROOT');
33134/**
33135 * @hidden
33136 */
33137var IonicApp = (function (_super) {
33138 __extends(IonicApp, _super);
33139 /**
33140 * @param {?} _userCmp
33141 * @param {?} _cfr
33142 * @param {?} elementRef
33143 * @param {?} renderer
33144 * @param {?} config
33145 * @param {?} _plt
33146 * @param {?} app
33147 */
33148 function IonicApp(_userCmp, _cfr, elementRef, renderer, config, _plt, app) {
33149 var _this = _super.call(this, config, elementRef, renderer, 'app-root') || this;
33150 _this._userCmp = _userCmp;
33151 _this._cfr = _cfr;
33152 _this._plt = _plt;
33153 // register with App that this is Ionic's appRoot component. tada!
33154 app._appRoot = _this;
33155 _this._stopScrollPlugin = window['IonicStopScroll'];
33156 return _this;
33157 }
33158 /**
33159 * @return {?}
33160 */
33161 IonicApp.prototype.ngOnInit = function () {
33162 var _this = this;
33163 // load the user root component
33164 // into Ionic's root component
33165 var /** @type {?} */ factory = this._cfr.resolveComponentFactory(this._userCmp);
33166 var /** @type {?} */ componentRef = this._viewport.createComponent(factory);
33167 this._renderer.setElementClass(componentRef.location.nativeElement, 'app-root', true);
33168 componentRef.changeDetectorRef.detectChanges();
33169 // set the mode class name
33170 // ios/md/wp
33171 this.setElementClass(this._config.get('mode'), true);
33172 var /** @type {?} */ versions = this._plt.versions();
33173 this._plt.platforms().forEach(function (platformName) {
33174 // platform-ios
33175 var /** @type {?} */ platformClass = 'platform-' + platformName;
33176 _this.setElementClass(platformClass, true);
33177 var /** @type {?} */ platformVersion = versions[platformName];
33178 if (platformVersion) {
33179 // platform-ios9
33180 platformClass += platformVersion.major;
33181 _this.setElementClass(platformClass, true);
33182 // platform-ios9_3
33183 _this.setElementClass(platformClass + '_' + platformVersion.minor, true);
33184 }
33185 });
33186 // touch devices should not use :hover CSS pseudo
33187 // enable :hover CSS when the "hoverCSS" setting is not false
33188 if (this._config.getBoolean('hoverCSS', true)) {
33189 this.setElementClass('enable-hover', true);
33190 }
33191 // sweet, the app root has loaded!
33192 // which means angular and ionic has fully loaded!
33193 // fire off the platform prepare ready, which could
33194 // have been switched out by any of the platform engines
33195 this._plt.prepareReady();
33196 };
33197 /**
33198 * @hidden
33199 * @param {?=} portal
33200 * @return {?}
33201 */
33202 IonicApp.prototype._getPortal = function (portal) {
33203 if (portal === PORTAL_LOADING) {
33204 return this._loadingPortal;
33205 }
33206 if (portal === PORTAL_TOAST) {
33207 return this._toastPortal;
33208 }
33209 // Modals need their own overlay becuase we don't want an ActionSheet
33210 // or Alert to trigger lifecycle events inside a modal
33211 if (portal === PORTAL_MODAL) {
33212 return this._modalPortal;
33213 }
33214 return this._overlayPortal;
33215 };
33216 /**
33217 * @return {?}
33218 */
33219 IonicApp.prototype._getActivePortal = function () {
33220 var /** @type {?} */ defaultPortal = this._overlayPortal;
33221 var /** @type {?} */ modalPortal = this._modalPortal;
33222 var /** @type {?} */ hasModal = modalPortal.length() > 0;
33223 var /** @type {?} */ hasDefault = defaultPortal.length() > 0;
33224 if (!hasModal && !hasDefault) {
33225 return null;
33226 }
33227 else if (hasModal && hasDefault) {
33228 var /** @type {?} */ defaultIndex = defaultPortal.getActive().getZIndex();
33229 var /** @type {?} */ modalIndex = modalPortal.getActive().getZIndex();
33230 if (defaultIndex > modalIndex) {
33231 return defaultPortal;
33232 }
33233 else {
33234 (void 0) /* assert */;
33235 return modalPortal;
33236 }
33237 }
33238 if (hasModal) {
33239 return modalPortal;
33240 }
33241 else if (hasDefault) {
33242 return defaultPortal;
33243 }
33244 };
33245 /**
33246 * @param {?} shouldDisableScroll
33247 * @return {?}
33248 */
33249 IonicApp.prototype._disableScroll = function (shouldDisableScroll) {
33250 var _this = this;
33251 if (shouldDisableScroll) {
33252 this.stopScroll().then(function () {
33253 _this._tmr = _this._plt.timeout(function () {
33254 (void 0) /* console.debug */;
33255 _this.setElementClass('disable-scroll', true);
33256 }, 32);
33257 });
33258 }
33259 else {
33260 var /** @type {?} */ plugin = this._stopScrollPlugin;
33261 if (plugin && plugin.cancel) {
33262 plugin.cancel();
33263 }
33264 clearTimeout(this._tmr);
33265 (void 0) /* console.debug */;
33266 this.setElementClass('disable-scroll', false);
33267 }
33268 };
33269 /**
33270 * @return {?}
33271 */
33272 IonicApp.prototype.stopScroll = function () {
33273 var _this = this;
33274 if (this._stopScrollPlugin) {
33275 return new Promise(function (resolve) {
33276 _this._stopScrollPlugin.stop(function () { return resolve(true); });
33277 });
33278 }
33279 else {
33280 return Promise.resolve(false);
33281 }
33282 };
33283 return IonicApp;
33284}(Ion));
33285IonicApp.decorators = [
33286 { type: Component, args: [{
33287 selector: 'ion-app',
33288 template: '<div #viewport app-viewport></div>' +
33289 '<div #modalPortal overlay-portal></div>' +
33290 '<div #overlayPortal overlay-portal></div>' +
33291 '<div #loadingPortal class="loading-portal" overlay-portal></div>' +
33292 '<div #toastPortal class="toast-portal" [overlay-portal]="10000"></div>' +
33293 '<div class="click-block"></div>'
33294 },] },
33295];
33296/**
33297 * @nocollapse
33298 */
33299IonicApp.ctorParameters = function () { return [
33300 { type: undefined, decorators: [{ type: Inject, args: [AppRootToken,] },] },
33301 { type: ComponentFactoryResolver, },
33302 { type: ElementRef, },
33303 { type: Renderer, },
33304 { type: Config, },
33305 { type: Platform, },
33306 { type: App, },
33307]; };
33308IonicApp.propDecorators = {
33309 '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
33310 '_modalPortal': [{ type: ViewChild, args: ['modalPortal', { read: OverlayPortal },] },],
33311 '_overlayPortal': [{ type: ViewChild, args: ['overlayPortal', { read: OverlayPortal },] },],
33312 '_loadingPortal': [{ type: ViewChild, args: ['loadingPortal', { read: OverlayPortal },] },],
33313 '_toastPortal': [{ type: ViewChild, args: ['toastPortal', { read: OverlayPortal },] },],
33314};
33315
33316var KEY_LEFT = 37;
33317var KEY_UP = 38;
33318var KEY_RIGHT = 39;
33319var KEY_DOWN = 40;
33320var KEY_ENTER = 13;
33321var KEY_ESCAPE = 27;
33322var KEY_SPACE = 32;
33323var KEY_TAB = 9;
33324
33325/**
33326 * @hidden
33327 */
33328var ActionSheetCmp = (function () {
33329 /**
33330 * @param {?} _viewCtrl
33331 * @param {?} config
33332 * @param {?} _elementRef
33333 * @param {?} gestureCtrl
33334 * @param {?} params
33335 * @param {?} renderer
33336 */
33337 function ActionSheetCmp(_viewCtrl, config, _elementRef, gestureCtrl, params, renderer) {
33338 this._viewCtrl = _viewCtrl;
33339 this._elementRef = _elementRef;
33340 this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
33341 this.d = params.data;
33342 this.mode = config.get('mode');
33343 renderer.setElementClass(_elementRef.nativeElement, "action-sheet-" + this.mode, true);
33344 if (this.d.cssClass) {
33345 this.d.cssClass.split(' ').forEach(function (cssClass) {
33346 // Make sure the class isn't whitespace, otherwise it throws exceptions
33347 if (cssClass.trim() !== '')
33348 renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
33349 });
33350 }
33351 this.id = (++actionSheetIds);
33352 if (this.d.title) {
33353 this.hdrId = 'acst-hdr-' + this.id;
33354 }
33355 if (this.d.subTitle) {
33356 this.descId = 'acst-subhdr-' + this.id;
33357 }
33358 }
33359 /**
33360 * @return {?}
33361 */
33362 ActionSheetCmp.prototype.ionViewDidLoad = function () {
33363 var _this = this;
33364 // normalize the data
33365 this.d.buttons = this.d.buttons.map(function (button) {
33366 if (typeof button === 'string') {
33367 button = { text: button };
33368 }
33369 if (!button.cssClass) {
33370 button.cssClass = '';
33371 }
33372 switch (button.role) {
33373 case 'cancel':
33374 _this.cancelButton = button;
33375 return null;
33376 case 'destructive':
33377 button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
33378 break;
33379 case 'selected':
33380 button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-selected';
33381 break;
33382 }
33383 return button;
33384 }).filter(function (button) { return button !== null; });
33385 };
33386 /**
33387 * @return {?}
33388 */
33389 ActionSheetCmp.prototype.ionViewWillEnter = function () {
33390 this.gestureBlocker.block();
33391 };
33392 /**
33393 * @return {?}
33394 */
33395 ActionSheetCmp.prototype.ionViewDidLeave = function () {
33396 this.gestureBlocker.unblock();
33397 };
33398 /**
33399 * @return {?}
33400 */
33401 ActionSheetCmp.prototype.ionViewDidEnter = function () {
33402 var /** @type {?} */ focusableEle = this._elementRef.nativeElement.querySelector('button');
33403 if (focusableEle) {
33404 focusableEle.focus();
33405 }
33406 this.enabled = true;
33407 };
33408 /**
33409 * @param {?} ev
33410 * @return {?}
33411 */
33412 ActionSheetCmp.prototype.keyUp = function (ev) {
33413 if (this.enabled && ev.keyCode === KEY_ESCAPE && this._viewCtrl.isLast()) {
33414 (void 0) /* console.debug */;
33415 this.bdClick();
33416 }
33417 };
33418 /**
33419 * @param {?} button
33420 * @return {?}
33421 */
33422 ActionSheetCmp.prototype.click = function (button) {
33423 if (!this.enabled) {
33424 return;
33425 }
33426 var /** @type {?} */ shouldDismiss = true;
33427 if (button.handler) {
33428 // a handler has been provided, execute it
33429 if (button.handler() === false) {
33430 // if the return value of the handler is false then do not dismiss
33431 shouldDismiss = false;
33432 }
33433 }
33434 if (shouldDismiss) {
33435 this.dismiss(button.role);
33436 }
33437 };
33438 /**
33439 * @return {?}
33440 */
33441 ActionSheetCmp.prototype.bdClick = function () {
33442 if (this.enabled && this.d.enableBackdropDismiss) {
33443 if (this.cancelButton) {
33444 this.click(this.cancelButton);
33445 }
33446 else {
33447 this.dismiss('backdrop');
33448 }
33449 }
33450 };
33451 /**
33452 * @param {?} role
33453 * @return {?}
33454 */
33455 ActionSheetCmp.prototype.dismiss = function (role) {
33456 var /** @type {?} */ opts = {
33457 minClickBlockDuration: 400
33458 };
33459 return this._viewCtrl.dismiss(null, role, opts);
33460 };
33461 /**
33462 * @return {?}
33463 */
33464 ActionSheetCmp.prototype.ngOnDestroy = function () {
33465 (void 0) /* assert */;
33466 this.d = this.cancelButton = null;
33467 this.gestureBlocker.destroy();
33468 };
33469 return ActionSheetCmp;
33470}());
33471ActionSheetCmp.decorators = [
33472 { type: Component, args: [{
33473 selector: 'ion-action-sheet',
33474 template: '<ion-backdrop (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
33475 '<div class="action-sheet-wrapper">' +
33476 '<div class="action-sheet-container">' +
33477 '<div class="action-sheet-group">' +
33478 '<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>' +
33479 '<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
33480 '<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [attr.icon-start]="b.icon ? \'\' : null" [ngClass]="b.cssClass">' +
33481 '<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon>' +
33482 '{{b.text}}' +
33483 '</button>' +
33484 '</div>' +
33485 '<div class="action-sheet-group" *ngIf="cancelButton">' +
33486 '<button ion-button="action-sheet-button" (click)="click(cancelButton)" class="action-sheet-cancel disable-hover" [attr.icon-start]="cancelButton.icon ? \'\' : null" [ngClass]="cancelButton.cssClass">' +
33487 '<ion-icon [name]="cancelButton.icon" *ngIf="cancelButton.icon" class="action-sheet-icon"></ion-icon>' +
33488 '{{cancelButton.text}}' +
33489 '</button>' +
33490 '</div>' +
33491 '</div>' +
33492 '</div>',
33493 host: {
33494 'role': 'dialog',
33495 '[attr.aria-labelledby]': 'hdrId',
33496 '[attr.aria-describedby]': 'descId'
33497 },
33498 encapsulation: ViewEncapsulation.None,
33499 },] },
33500];
33501/**
33502 * @nocollapse
33503 */
33504ActionSheetCmp.ctorParameters = function () { return [
33505 { type: ViewController, },
33506 { type: Config, },
33507 { type: ElementRef, },
33508 { type: GestureController, },
33509 { type: NavParams, },
33510 { type: Renderer, },
33511]; };
33512ActionSheetCmp.propDecorators = {
33513 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
33514};
33515var actionSheetIds = -1;
33516
33517var __extends$25 = (undefined && undefined.__extends) || (function () {
33518 var extendStatics = Object.setPrototypeOf ||
33519 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33520 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
33521 return function (d, b) {
33522 extendStatics(d, b);
33523 function __() { this.constructor = d; }
33524 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33525 };
33526})();
33527var ActionSheetSlideIn = (function (_super) {
33528 __extends$25(ActionSheetSlideIn, _super);
33529 function ActionSheetSlideIn() {
33530 return _super !== null && _super.apply(this, arguments) || this;
33531 }
33532 /**
33533 * @return {?}
33534 */
33535 ActionSheetSlideIn.prototype.init = function () {
33536 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
33537 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33538 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33539 backdrop.fromTo('opacity', 0.01, 0.4);
33540 wrapper.fromTo('translateY', '100%', '0%');
33541 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
33542 };
33543 return ActionSheetSlideIn;
33544}(Transition));
33545var ActionSheetSlideOut = (function (_super) {
33546 __extends$25(ActionSheetSlideOut, _super);
33547 function ActionSheetSlideOut() {
33548 return _super !== null && _super.apply(this, arguments) || this;
33549 }
33550 /**
33551 * @return {?}
33552 */
33553 ActionSheetSlideOut.prototype.init = function () {
33554 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
33555 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33556 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33557 backdrop.fromTo('opacity', 0.4, 0);
33558 wrapper.fromTo('translateY', '0%', '100%');
33559 this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(backdrop).add(wrapper);
33560 };
33561 return ActionSheetSlideOut;
33562}(Transition));
33563var ActionSheetMdSlideIn = (function (_super) {
33564 __extends$25(ActionSheetMdSlideIn, _super);
33565 function ActionSheetMdSlideIn() {
33566 return _super !== null && _super.apply(this, arguments) || this;
33567 }
33568 /**
33569 * @return {?}
33570 */
33571 ActionSheetMdSlideIn.prototype.init = function () {
33572 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
33573 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33574 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33575 backdrop.fromTo('opacity', 0.01, 0.26);
33576 wrapper.fromTo('translateY', '100%', '0%');
33577 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
33578 };
33579 return ActionSheetMdSlideIn;
33580}(Transition));
33581var ActionSheetMdSlideOut = (function (_super) {
33582 __extends$25(ActionSheetMdSlideOut, _super);
33583 function ActionSheetMdSlideOut() {
33584 return _super !== null && _super.apply(this, arguments) || this;
33585 }
33586 /**
33587 * @return {?}
33588 */
33589 ActionSheetMdSlideOut.prototype.init = function () {
33590 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
33591 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33592 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33593 backdrop.fromTo('opacity', 0.26, 0);
33594 wrapper.fromTo('translateY', '0%', '100%');
33595 this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
33596 };
33597 return ActionSheetMdSlideOut;
33598}(Transition));
33599var ActionSheetWpSlideIn = (function (_super) {
33600 __extends$25(ActionSheetWpSlideIn, _super);
33601 function ActionSheetWpSlideIn() {
33602 return _super !== null && _super.apply(this, arguments) || this;
33603 }
33604 /**
33605 * @return {?}
33606 */
33607 ActionSheetWpSlideIn.prototype.init = function () {
33608 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
33609 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33610 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33611 backdrop.fromTo('opacity', 0.01, 0.16);
33612 wrapper.fromTo('translateY', '100%', '0%');
33613 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
33614 };
33615 return ActionSheetWpSlideIn;
33616}(Transition));
33617var ActionSheetWpSlideOut = (function (_super) {
33618 __extends$25(ActionSheetWpSlideOut, _super);
33619 function ActionSheetWpSlideOut() {
33620 return _super !== null && _super.apply(this, arguments) || this;
33621 }
33622 /**
33623 * @return {?}
33624 */
33625 ActionSheetWpSlideOut.prototype.init = function () {
33626 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
33627 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
33628 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
33629 backdrop.fromTo('opacity', 0.1, 0);
33630 wrapper.fromTo('translateY', '0%', '100%');
33631 this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
33632 };
33633 return ActionSheetWpSlideOut;
33634}(Transition));
33635
33636var __extends$24 = (undefined && undefined.__extends) || (function () {
33637 var extendStatics = Object.setPrototypeOf ||
33638 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33639 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
33640 return function (d, b) {
33641 extendStatics(d, b);
33642 function __() { this.constructor = d; }
33643 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33644 };
33645})();
33646/**
33647 * @hidden
33648 */
33649var ActionSheet = (function (_super) {
33650 __extends$24(ActionSheet, _super);
33651 /**
33652 * @param {?} app
33653 * @param {?} opts
33654 * @param {?} config
33655 */
33656 function ActionSheet(app, opts, config) {
33657 var _this = this;
33658 opts.buttons = opts.buttons || [];
33659 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
33660 _this = _super.call(this, ActionSheetCmp, opts, null) || this;
33661 _this._app = app;
33662 _this.isOverlay = true;
33663 config.setTransition('action-sheet-slide-in', ActionSheetSlideIn);
33664 config.setTransition('action-sheet-slide-out', ActionSheetSlideOut);
33665 config.setTransition('action-sheet-md-slide-in', ActionSheetMdSlideIn);
33666 config.setTransition('action-sheet-md-slide-out', ActionSheetMdSlideOut);
33667 config.setTransition('action-sheet-wp-slide-in', ActionSheetWpSlideIn);
33668 config.setTransition('action-sheet-wp-slide-out', ActionSheetWpSlideOut);
33669 return _this;
33670 }
33671 /**
33672 * @hidden
33673 * @param {?} direction
33674 * @return {?}
33675 */
33676 ActionSheet.prototype.getTransitionName = function (direction) {
33677 var /** @type {?} */ key = 'actionSheet' + (direction === 'back' ? 'Leave' : 'Enter');
33678 return this._nav && this._nav.config.get(key);
33679 };
33680 /**
33681 * @param {?} title
33682 * @return {?}
33683 */
33684 ActionSheet.prototype.setTitle = function (title) {
33685 this.data.title = title;
33686 return this;
33687 };
33688 /**
33689 * @param {?} subTitle
33690 * @return {?}
33691 */
33692 ActionSheet.prototype.setSubTitle = function (subTitle) {
33693 this.data.subTitle = subTitle;
33694 return this;
33695 };
33696 /**
33697 * @param {?} button
33698 * @return {?}
33699 */
33700 ActionSheet.prototype.addButton = function (button) {
33701 this.data.buttons.push(button);
33702 return this;
33703 };
33704 /**
33705 * Present the action sheet instance.
33706 *
33707 * @param {?=} navOptions
33708 * @return {?}
33709 */
33710 ActionSheet.prototype.present = function (navOptions) {
33711 if (navOptions === void 0) { navOptions = {}; }
33712 navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
33713 return this._app.present(this, navOptions);
33714 };
33715 return ActionSheet;
33716}(ViewController));
33717
33718/**
33719 * \@name ActionSheetController
33720 * \@description
33721 * An Action Sheet is a dialog that lets the user choose from a set of
33722 * options. It appears on top of the app's content, and must be manually
33723 * dismissed by the user before they can resume interaction with the app.
33724 * Dangerous (destructive) options are made obvious in `ios` mode. There are easy
33725 * ways to cancel out of the action sheet, such as tapping the backdrop or
33726 * hitting the escape key on desktop.
33727 *
33728 * An action sheet is created from an array of `buttons`, with each button
33729 * including properties for its `text`, and optionally a `handler` and `role`.
33730 * If a handler returns `false` then the action sheet will not be dismissed. An
33731 * action sheet can also optionally have a `title`, `subTitle` and an `icon`.
33732 *
33733 * A button's `role` property can either be `destructive` or `cancel`. Buttons
33734 * without a role property will have the default look for the platform. Buttons
33735 * with the `cancel` role will always load as the bottom button, no matter where
33736 * they are in the array. All other buttons will be displayed in the order they
33737 * have been added to the `buttons` array. Note: We recommend that `destructive`
33738 * buttons are always the first button in the array, making them the top button.
33739 * Additionally, if the action sheet is dismissed by tapping the backdrop, then
33740 * it will fire the handler from the button with the cancel role.
33741 *
33742 * You can pass all of the action sheet's options in the first argument of
33743 * the create method: `ActionSheet.create(opts)`. Otherwise the action sheet's
33744 * instance has methods to add options, like `setTitle()` or `addButton()`.
33745 *
33746 * \@usage
33747 * ```ts
33748 * import { ActionSheetController } from 'ionic-angular'
33749 *
33750 * export class MyClass{
33751 *
33752 * constructor(public actionSheetCtrl: ActionSheetController) { }
33753 *
33754 * presentActionSheet() {
33755 * const actionSheet = this.actionSheetCtrl.create({
33756 * title: 'Modify your album',
33757 * buttons: [
33758 * {
33759 * text: 'Destructive',
33760 * role: 'destructive',
33761 * handler: () => {
33762 * console.log('Destructive clicked');
33763 * }
33764 * },
33765 * {
33766 * text: 'Archive',
33767 * handler: () => {
33768 * console.log('Archive clicked');
33769 * }
33770 * },
33771 * {
33772 * text: 'Cancel',
33773 * role: 'cancel',
33774 * handler: () => {
33775 * console.log('Cancel clicked');
33776 * }
33777 * }
33778 * ]
33779 * });
33780 *
33781 * actionSheet.present();
33782 * }
33783 * }
33784 * ```
33785 *
33786 * \@advanced
33787 *
33788 * ActionSheet create options
33789 *
33790 * | Option | Type | Description |
33791 * |-----------------------|------------|--------------------------------------------------------------------|
33792 * | title |`string` | The title for the Action Sheet. |
33793 * | subTitle |`string` | The sub-title for the Action Sheet. |
33794 * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
33795 * | enableBackdropDismiss |`boolean` | If the Action Sheet should close when the user taps the backdrop. |
33796 * | buttons |`array<any>`| An array of buttons to display. |
33797 *
33798 * ActionSheet button options
33799 *
33800 * | Option | Type | Description |
33801 * |----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------|
33802 * | text | `string` | The buttons text. |
33803 * | icon | `icon` | The buttons icons. |
33804 * | handler | `any` | An express the button should evaluate. |
33805 * | cssClass | `string` | Additional classes for custom styles, separated by spaces. |
33806 * | role | `string` | How the button should be displayed, `destructive` or `cancel`. If not role is provided, it will display the button without any additional styles.|
33807 *
33808 *
33809 * ### Dismissing And Async Navigation
33810 *
33811 * After an action sheet has been dismissed, the app may need to also transition
33812 * to another page depending on the handler's logic. However, because multiple
33813 * transitions were fired at roughly the same time, it's difficult for the
33814 * nav controller to cleanly animate multiple transitions that may
33815 * have been kicked off asynchronously. This is further described in the
33816 * [`Nav Transition Promises`](../../nav/NavController/#nav-transition-promises) section. For action sheets,
33817 * this means it's best to wait for the action sheet to finish its transition
33818 * out before starting a new transition on the same nav controller.
33819 *
33820 * In the example below, after the button has been clicked, its handler
33821 * waits on async operation to complete, *then* it uses `pop` to navigate
33822 * back a page in the same stack. The potential problem is that the async operation
33823 * may have been completed before the action sheet has even finished its transition
33824 * out. In this case, it's best to ensure the action sheet has finished its transition
33825 * out first, *then* start the next transition.
33826 *
33827 * ```ts
33828 * const actionSheet = this.actionSheetCtrl.create({
33829 * title: 'Hello',
33830 * buttons: [{
33831 * text: 'Ok',
33832 * handler: () => {
33833 * // user has clicked the action sheet button
33834 * // begin the action sheet's dimiss transition
33835 * let navTransition = actionSheet.dismiss();
33836 *
33837 * // start some async method
33838 * someAsyncOperation().then(() => {
33839 * // once the async operation has completed
33840 * // then run the next nav transition after the
33841 * // first transition has finished animating out
33842 *
33843 * navTransition.then(() => {
33844 * this.nav.pop();
33845 * });
33846 * });
33847 * return false;
33848 * }
33849 * }]
33850 * });
33851 *
33852 * actionSheet.present();
33853 * ```
33854 *
33855 * It's important to note that the handler returns `false`. A feature of
33856 * button handlers is that they automatically dismiss the action sheet when their button
33857 * was clicked, however, we'll need more control regarding the transition. Because
33858 * the handler returns `false`, then the action sheet does not automatically dismiss
33859 * itself. Instead, you now have complete control of when the action sheet has finished
33860 * transitioning, and the ability to wait for the action sheet to finish transitioning
33861 * out before starting a new transition.
33862 *
33863 *
33864 * \@demo /docs/demos/src/action-sheet/
33865 * @see {\@link /docs/components#action-sheets ActionSheet Component Docs}
33866 */
33867var ActionSheetController = (function () {
33868 /**
33869 * @param {?} _app
33870 * @param {?} config
33871 */
33872 function ActionSheetController(_app, config) {
33873 this._app = _app;
33874 this.config = config;
33875 }
33876 /**
33877 * Open an action sheet with a title, subTitle, and an array of buttons
33878 * @param {?=} opts
33879 * @return {?}
33880 */
33881 ActionSheetController.prototype.create = function (opts) {
33882 if (opts === void 0) { opts = {}; }
33883 return new ActionSheet(this._app, opts, this.config);
33884 };
33885 return ActionSheetController;
33886}());
33887ActionSheetController.decorators = [
33888 { type: Injectable },
33889];
33890/**
33891 * @nocollapse
33892 */
33893ActionSheetController.ctorParameters = function () { return [
33894 { type: App, },
33895 { type: Config, },
33896]; };
33897
33898/**
33899 * @hidden
33900 */
33901var AlertCmp = (function () {
33902 /**
33903 * @param {?} _viewCtrl
33904 * @param {?} _elementRef
33905 * @param {?} config
33906 * @param {?} gestureCtrl
33907 * @param {?} params
33908 * @param {?} _renderer
33909 * @param {?} _plt
33910 */
33911 function AlertCmp(_viewCtrl, _elementRef, config, gestureCtrl, params, _renderer, _plt) {
33912 this._viewCtrl = _viewCtrl;
33913 this._elementRef = _elementRef;
33914 this._renderer = _renderer;
33915 this._plt = _plt;
33916 // gesture blocker is used to disable gestures dynamically
33917 this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
33918 this.d = params.data;
33919 this.mode = this.d.mode || config.get('mode');
33920 this.keyboardResizes = config.getBoolean('keyboardResizes', false);
33921 _renderer.setElementClass(_elementRef.nativeElement, "alert-" + this.mode, true);
33922 if (this.d.cssClass) {
33923 this.d.cssClass.split(' ').forEach(function (cssClass) {
33924 // Make sure the class isn't whitespace, otherwise it throws exceptions
33925 if (cssClass.trim() !== '')
33926 _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
33927 });
33928 }
33929 this.id = (++alertIds);
33930 this.descId = '';
33931 this.hdrId = 'alert-hdr-' + this.id;
33932 this.subHdrId = 'alert-subhdr-' + this.id;
33933 this.msgId = 'alert-msg-' + this.id;
33934 this.activeId = '';
33935 this.lastClick = 0;
33936 if (this.d.message) {
33937 this.descId = this.msgId;
33938 }
33939 else if (this.d.subTitle) {
33940 this.descId = this.subHdrId;
33941 }
33942 if (!this.d.message) {
33943 this.d.message = '';
33944 }
33945 }
33946 /**
33947 * @return {?}
33948 */
33949 AlertCmp.prototype.ionViewDidLoad = function () {
33950 var _this = this;
33951 // normalize the data
33952 var /** @type {?} */ data = this.d;
33953 data.buttons = data.buttons.map(function (button) {
33954 if (typeof button === 'string') {
33955 return { text: button };
33956 }
33957 return button;
33958 });
33959 data.inputs = data.inputs.map(function (input, index) {
33960 var /** @type {?} */ r = {
33961 type: input.type || 'text',
33962 name: isPresent(input.name) ? input.name : index + '',
33963 placeholder: isPresent(input.placeholder) ? input.placeholder : '',
33964 value: isPresent(input.value) ? input.value : '',
33965 label: input.label,
33966 checked: !!input.checked,
33967 disabled: !!input.disabled,
33968 id: isPresent(input.id) ? input.id : "alert-input-" + _this.id + "-" + index,
33969 handler: isPresent(input.handler) ? input.handler : null,
33970 min: isPresent(input.min) ? input.min : null,
33971 max: isPresent(input.max) ? input.max : null
33972 };
33973 return r;
33974 });
33975 // An alert can be created with several different inputs. Radios,
33976 // checkboxes and inputs are all accepted, but they cannot be mixed.
33977 var /** @type {?} */ inputTypes = [];
33978 data.inputs.forEach(function (input) {
33979 if (inputTypes.indexOf(input.type) < 0) {
33980 inputTypes.push(input.type);
33981 }
33982 });
33983 if (inputTypes.length > 1 && (inputTypes.indexOf('checkbox') > -1 || inputTypes.indexOf('radio') > -1)) {
33984 console.warn("Alert cannot mix input types: " + (inputTypes.join('/')) + ". Please see alert docs for more info.");
33985 }
33986 this.inputType = inputTypes.length ? inputTypes[0] : null;
33987 var /** @type {?} */ checkedInput = this.d.inputs.find(function (input) { return input.checked; });
33988 if (checkedInput) {
33989 this.activeId = checkedInput.id;
33990 }
33991 var /** @type {?} */ hasTextInput = (this.d.inputs.length && this.d.inputs.some(function (i) { return !(NON_TEXT_INPUT_REGEX.test(i.type)); }));
33992 if (!this.keyboardResizes && hasTextInput && this._plt.is('mobile')) {
33993 // this alert has a text input and it's on a mobile device so we should align
33994 // the alert up high because we need to leave space for the virtual keboard
33995 // this also helps prevent the layout getting all messed up from
33996 // the browser trying to scroll the input into a safe area
33997 this._renderer.setElementClass(this._elementRef.nativeElement, 'alert-top', true);
33998 }
33999 };
34000 /**
34001 * @return {?}
34002 */
34003 AlertCmp.prototype.ionViewWillEnter = function () {
34004 this.gestureBlocker.block();
34005 };
34006 /**
34007 * @return {?}
34008 */
34009 AlertCmp.prototype.ionViewDidLeave = function () {
34010 this.gestureBlocker.unblock();
34011 };
34012 /**
34013 * @return {?}
34014 */
34015 AlertCmp.prototype.ionViewDidEnter = function () {
34016 // set focus on the first input or button in the alert
34017 // note that this does not always work and bring up the keyboard on
34018 // devices since the focus command must come from the user's touch event
34019 // and ionViewDidEnter is not in the same callstack as the touch event :(
34020 var /** @type {?} */ focusableEle = this._elementRef.nativeElement.querySelector('input,button');
34021 if (focusableEle) {
34022 focusableEle.focus();
34023 }
34024 this.enabled = true;
34025 };
34026 /**
34027 * @param {?} ev
34028 * @return {?}
34029 */
34030 AlertCmp.prototype.keyUp = function (ev) {
34031 if (this.enabled && this._viewCtrl.isLast()) {
34032 if (ev.keyCode === KEY_ENTER) {
34033 if (this.lastClick + 1000 < Date.now()) {
34034 // do not fire this click if there recently was already a click
34035 // this can happen when the button has focus and used the enter
34036 // key to click the button. However, both the click handler and
34037 // this keyup event will fire, so only allow one of them to go.
34038 (void 0) /* console.debug */;
34039 var /** @type {?} */ button = this.d.buttons[this.d.buttons.length - 1];
34040 this.btnClick(button);
34041 }
34042 }
34043 else if (ev.keyCode === KEY_ESCAPE) {
34044 (void 0) /* console.debug */;
34045 this.bdClick();
34046 }
34047 }
34048 };
34049 /**
34050 * @param {?} button
34051 * @return {?}
34052 */
34053 AlertCmp.prototype.btnClick = function (button) {
34054 if (!this.enabled) {
34055 return;
34056 }
34057 // keep the time of the most recent button click
34058 this.lastClick = Date.now();
34059 var /** @type {?} */ shouldDismiss = true;
34060 if (button.handler) {
34061 // a handler has been provided, execute it
34062 // pass the handler the values from the inputs
34063 if (button.handler(this.getValues()) === false) {
34064 // if the return value of the handler is false then do not dismiss
34065 shouldDismiss = false;
34066 }
34067 }
34068 if (shouldDismiss) {
34069 this.dismiss(button.role);
34070 }
34071 };
34072 /**
34073 * @param {?} checkedInput
34074 * @return {?}
34075 */
34076 AlertCmp.prototype.rbClick = function (checkedInput) {
34077 if (this.enabled) {
34078 this.d.inputs.forEach(function (input) {
34079 input.checked = (checkedInput === input);
34080 });
34081 this.activeId = checkedInput.id;
34082 if (checkedInput.handler) {
34083 checkedInput.handler(checkedInput);
34084 }
34085 }
34086 };
34087 /**
34088 * @param {?} checkedInput
34089 * @return {?}
34090 */
34091 AlertCmp.prototype.cbClick = function (checkedInput) {
34092 if (this.enabled) {
34093 checkedInput.checked = !checkedInput.checked;
34094 if (checkedInput.handler) {
34095 checkedInput.handler(checkedInput);
34096 }
34097 }
34098 };
34099 /**
34100 * @return {?}
34101 */
34102 AlertCmp.prototype.bdClick = function () {
34103 if (this.enabled && this.d.enableBackdropDismiss) {
34104 var /** @type {?} */ cancelBtn = this.d.buttons.find(function (b) { return ((b)).role === 'cancel'; });
34105 if (cancelBtn) {
34106 this.btnClick(cancelBtn);
34107 }
34108 else {
34109 this.dismiss('backdrop');
34110 }
34111 }
34112 };
34113 /**
34114 * @param {?} role
34115 * @return {?}
34116 */
34117 AlertCmp.prototype.dismiss = function (role) {
34118 var /** @type {?} */ opts = {
34119 minClickBlockDuration: 400
34120 };
34121 return this._viewCtrl.dismiss(this.getValues(), role, opts);
34122 };
34123 /**
34124 * @return {?}
34125 */
34126 AlertCmp.prototype.getValues = function () {
34127 if (this.inputType === 'radio') {
34128 // this is an alert with radio buttons (single value select)
34129 // return the one value which is checked, otherwise undefined
34130 var /** @type {?} */ checkedInput = this.d.inputs.find(function (i) { return i.checked; });
34131 return checkedInput ? checkedInput.value : undefined;
34132 }
34133 if (this.inputType === 'checkbox') {
34134 // this is an alert with checkboxes (multiple value select)
34135 // return an array of all the checked values
34136 return this.d.inputs.filter(function (i) { return i.checked; }).map(function (i) { return i.value; });
34137 }
34138 if (this.d.inputs.length === 0) {
34139 // this is an alert without any options/inputs at all
34140 return undefined;
34141 }
34142 // this is an alert with text inputs
34143 // return an object of all the values with the input name as the key
34144 var /** @type {?} */ values = {};
34145 this.d.inputs.forEach(function (i) {
34146 values[i.name] = i.value;
34147 });
34148 return values;
34149 };
34150 /**
34151 * @return {?}
34152 */
34153 AlertCmp.prototype.ngOnDestroy = function () {
34154 (void 0) /* assert */;
34155 this.gestureBlocker.destroy();
34156 };
34157 return AlertCmp;
34158}());
34159AlertCmp.decorators = [
34160 { type: Component, args: [{
34161 selector: 'ion-alert',
34162 template: '<ion-backdrop (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
34163 '<div class="alert-wrapper">' +
34164 '<div class="alert-head">' +
34165 '<h2 id="{{hdrId}}" class="alert-title" *ngIf="d.title" [innerHTML]="d.title"></h2>' +
34166 '<h3 id="{{subHdrId}}" class="alert-sub-title" *ngIf="d.subTitle" [innerHTML]="d.subTitle"></h3>' +
34167 '</div>' +
34168 '<div id="{{msgId}}" class="alert-message" [innerHTML]="d.message"></div>' +
34169 '<div *ngIf="d.inputs.length" [ngSwitch]="inputType">' +
34170 '<ng-template ngSwitchCase="radio">' +
34171 '<div class="alert-radio-group" role="radiogroup" [attr.aria-labelledby]="hdrId" [attr.aria-activedescendant]="activeId">' +
34172 '<button ion-button="alert-radio-button" *ngFor="let i of d.inputs" (click)="rbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" [attr.id]="i.id" class="alert-tappable alert-radio" role="radio">' +
34173 '<div class="alert-radio-icon"><div class="alert-radio-inner"></div></div>' +
34174 '<div class="alert-radio-label">' +
34175 '{{i.label}}' +
34176 '</div>' +
34177 '</button>' +
34178 '</div>' +
34179 '</ng-template>' +
34180 '<ng-template ngSwitchCase="checkbox">' +
34181 '<div class="alert-checkbox-group">' +
34182 '<button ion-button="alert-checkbox-button" *ngFor="let i of d.inputs" (click)="cbClick(i)" [attr.aria-checked]="i.checked" [attr.id]="i.id" [disabled]="i.disabled" class="alert-tappable alert-checkbox" role="checkbox">' +
34183 '<div class="alert-checkbox-icon"><div class="alert-checkbox-inner"></div></div>' +
34184 '<div class="alert-checkbox-label">' +
34185 '{{i.label}}' +
34186 '</div>' +
34187 '</button>' +
34188 '</div>' +
34189 '</ng-template>' +
34190 '<ng-template ngSwitchDefault>' +
34191 '<div class="alert-input-group">' +
34192 '<div *ngFor="let i of d.inputs" class="alert-input-wrapper">' +
34193 '<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
34194 '</div>' +
34195 '</div>' +
34196 '</ng-template>' +
34197 '</div>' +
34198 '<div class="alert-button-group" [ngClass]="{\'alert-button-group-vertical\':d.buttons.length>2}">' +
34199 '<button ion-button="alert-button" *ngFor="let b of d.buttons" (click)="btnClick(b)" [ngClass]="b.cssClass">' +
34200 '{{b.text}}' +
34201 '</button>' +
34202 '</div>' +
34203 '</div>',
34204 host: {
34205 'role': 'dialog',
34206 '[attr.aria-labelledby]': 'hdrId',
34207 '[attr.aria-describedby]': 'descId'
34208 },
34209 encapsulation: ViewEncapsulation.None,
34210 },] },
34211];
34212/**
34213 * @nocollapse
34214 */
34215AlertCmp.ctorParameters = function () { return [
34216 { type: ViewController, },
34217 { type: ElementRef, },
34218 { type: Config, },
34219 { type: GestureController, },
34220 { type: NavParams, },
34221 { type: Renderer, },
34222 { type: Platform, },
34223]; };
34224AlertCmp.propDecorators = {
34225 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
34226};
34227var alertIds = -1;
34228
34229var __extends$27 = (undefined && undefined.__extends) || (function () {
34230 var extendStatics = Object.setPrototypeOf ||
34231 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
34232 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
34233 return function (d, b) {
34234 extendStatics(d, b);
34235 function __() { this.constructor = d; }
34236 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34237 };
34238})();
34239/**
34240 * Animations for alerts
34241 */
34242var AlertPopIn = (function (_super) {
34243 __extends$27(AlertPopIn, _super);
34244 function AlertPopIn() {
34245 return _super !== null && _super.apply(this, arguments) || this;
34246 }
34247 /**
34248 * @return {?}
34249 */
34250 AlertPopIn.prototype.init = function () {
34251 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
34252 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34253 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34254 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
34255 backdrop.fromTo('opacity', 0.01, 0.3);
34256 this
34257 .easing('ease-in-out')
34258 .duration(200)
34259 .add(backdrop)
34260 .add(wrapper);
34261 };
34262 return AlertPopIn;
34263}(Transition));
34264var AlertPopOut = (function (_super) {
34265 __extends$27(AlertPopOut, _super);
34266 function AlertPopOut() {
34267 return _super !== null && _super.apply(this, arguments) || this;
34268 }
34269 /**
34270 * @return {?}
34271 */
34272 AlertPopOut.prototype.init = function () {
34273 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
34274 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34275 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34276 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
34277 backdrop.fromTo('opacity', 0.3, 0);
34278 this
34279 .easing('ease-in-out')
34280 .duration(200)
34281 .add(backdrop)
34282 .add(wrapper);
34283 };
34284 return AlertPopOut;
34285}(Transition));
34286var AlertMdPopIn = (function (_super) {
34287 __extends$27(AlertMdPopIn, _super);
34288 function AlertMdPopIn() {
34289 return _super !== null && _super.apply(this, arguments) || this;
34290 }
34291 /**
34292 * @return {?}
34293 */
34294 AlertMdPopIn.prototype.init = function () {
34295 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
34296 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34297 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34298 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
34299 backdrop.fromTo('opacity', 0.01, 0.5);
34300 this
34301 .easing('ease-in-out')
34302 .duration(200)
34303 .add(backdrop)
34304 .add(wrapper);
34305 };
34306 return AlertMdPopIn;
34307}(Transition));
34308var AlertMdPopOut = (function (_super) {
34309 __extends$27(AlertMdPopOut, _super);
34310 function AlertMdPopOut() {
34311 return _super !== null && _super.apply(this, arguments) || this;
34312 }
34313 /**
34314 * @return {?}
34315 */
34316 AlertMdPopOut.prototype.init = function () {
34317 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
34318 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34319 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34320 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
34321 backdrop.fromTo('opacity', 0.5, 0);
34322 this
34323 .easing('ease-in-out')
34324 .duration(200)
34325 .add(backdrop)
34326 .add(wrapper);
34327 };
34328 return AlertMdPopOut;
34329}(Transition));
34330var AlertWpPopIn = (function (_super) {
34331 __extends$27(AlertWpPopIn, _super);
34332 function AlertWpPopIn() {
34333 return _super !== null && _super.apply(this, arguments) || this;
34334 }
34335 /**
34336 * @return {?}
34337 */
34338 AlertWpPopIn.prototype.init = function () {
34339 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
34340 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34341 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34342 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
34343 backdrop.fromTo('opacity', 0.01, 0.5);
34344 this
34345 .easing('cubic-bezier(0,0,0.05,1)')
34346 .duration(200)
34347 .add(backdrop)
34348 .add(wrapper);
34349 };
34350 return AlertWpPopIn;
34351}(Transition));
34352var AlertWpPopOut = (function (_super) {
34353 __extends$27(AlertWpPopOut, _super);
34354 function AlertWpPopOut() {
34355 return _super !== null && _super.apply(this, arguments) || this;
34356 }
34357 /**
34358 * @return {?}
34359 */
34360 AlertWpPopOut.prototype.init = function () {
34361 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
34362 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
34363 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
34364 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
34365 backdrop.fromTo('opacity', 0.5, 0);
34366 this
34367 .easing('ease-out')
34368 .duration(150)
34369 .add(backdrop)
34370 .add(wrapper);
34371 };
34372 return AlertWpPopOut;
34373}(Transition));
34374
34375var __extends$26 = (undefined && undefined.__extends) || (function () {
34376 var extendStatics = Object.setPrototypeOf ||
34377 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
34378 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
34379 return function (d, b) {
34380 extendStatics(d, b);
34381 function __() { this.constructor = d; }
34382 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34383 };
34384})();
34385/**
34386 * @hidden
34387 */
34388var Alert = (function (_super) {
34389 __extends$26(Alert, _super);
34390 /**
34391 * @param {?} app
34392 * @param {?=} opts
34393 * @param {?=} config
34394 */
34395 function Alert(app, opts, config) {
34396 if (opts === void 0) { opts = {}; }
34397 var _this = this;
34398 opts.inputs = opts.inputs || [];
34399 opts.buttons = opts.buttons || [];
34400 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
34401 _this = _super.call(this, AlertCmp, opts, null) || this;
34402 _this._app = app;
34403 _this.isOverlay = true;
34404 config.setTransition('alert-pop-in', AlertPopIn);
34405 config.setTransition('alert-pop-out', AlertPopOut);
34406 config.setTransition('alert-md-pop-in', AlertMdPopIn);
34407 config.setTransition('alert-md-pop-out', AlertMdPopOut);
34408 config.setTransition('alert-wp-pop-in', AlertWpPopIn);
34409 config.setTransition('alert-wp-pop-out', AlertWpPopOut);
34410 return _this;
34411 }
34412 /**
34413 * @hidden
34414 * @param {?} direction
34415 * @return {?}
34416 */
34417 Alert.prototype.getTransitionName = function (direction) {
34418 var /** @type {?} */ key = (direction === 'back' ? 'alertLeave' : 'alertEnter');
34419 return this._nav && this._nav.config.get(key);
34420 };
34421 /**
34422 * @param {?} title
34423 * @return {?}
34424 */
34425 Alert.prototype.setTitle = function (title) {
34426 this.data.title = title;
34427 return this;
34428 };
34429 /**
34430 * @param {?} subTitle
34431 * @return {?}
34432 */
34433 Alert.prototype.setSubTitle = function (subTitle) {
34434 this.data.subTitle = subTitle;
34435 return this;
34436 };
34437 /**
34438 * @param {?} message
34439 * @return {?}
34440 */
34441 Alert.prototype.setMessage = function (message) {
34442 this.data.message = message;
34443 return this;
34444 };
34445 /**
34446 * @param {?} input
34447 * @return {?}
34448 */
34449 Alert.prototype.addInput = function (input) {
34450 this.data.inputs.push(input);
34451 return this;
34452 };
34453 /**
34454 * @param {?} button
34455 * @return {?}
34456 */
34457 Alert.prototype.addButton = function (button) {
34458 this.data.buttons.push(button);
34459 return this;
34460 };
34461 /**
34462 * @param {?} cssClass
34463 * @return {?}
34464 */
34465 Alert.prototype.setCssClass = function (cssClass) {
34466 this.data.cssClass = cssClass;
34467 return this;
34468 };
34469 /**
34470 * @param {?} mode
34471 * @return {?}
34472 */
34473 Alert.prototype.setMode = function (mode) {
34474 this.data.mode = mode;
34475 };
34476 /**
34477 * Present the alert instance.
34478 *
34479 * @param {?=} navOptions
34480 * @return {?}
34481 */
34482 Alert.prototype.present = function (navOptions) {
34483 if (navOptions === void 0) { navOptions = {}; }
34484 navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
34485 return this._app.present(this, navOptions);
34486 };
34487 return Alert;
34488}(ViewController));
34489
34490/**
34491 * \@name AlertController
34492 * \@description
34493 * An Alert is a dialog that presents users with information or collects
34494 * information from the user using inputs. An alert appears on top
34495 * of the app's content, and must be manually dismissed by the user before
34496 * they can resume interaction with the app. It can also optionally have a
34497 * `title`, `subTitle` and `message`.
34498 *
34499 * You can pass all of the alert's options in the first argument of
34500 * the create method: `create(opts)`. Otherwise the alert's instance
34501 * has methods to add options, such as `setTitle()` or `addButton()`.
34502 *
34503 *
34504 * ### Alert Buttons
34505 *
34506 * In the array of `buttons`, each button includes properties for its `text`,
34507 * and optionally a `handler`. If a handler returns `false` then the alert
34508 * will not automatically be dismissed when the button is clicked. All
34509 * buttons will show up in the order they have been added to the `buttons`
34510 * array, from left to right. Note: The right most button (the last one in
34511 * the array) is the main button.
34512 *
34513 * Optionally, a `role` property can be added to a button, such as `cancel`.
34514 * If a `cancel` role is on one of the buttons, then if the alert is
34515 * dismissed by tapping the backdrop, then it will fire the handler from
34516 * the button with a cancel role.
34517 *
34518 *
34519 * ### Alert Inputs
34520 *
34521 * Alerts can also include several different inputs whose data can be passed
34522 * back to the app. Inputs can be used as a simple way to prompt users for
34523 * information. Radios, checkboxes and text inputs are all accepted, but they
34524 * cannot be mixed. For example, an alert could have all radio button inputs,
34525 * or all checkbox inputs, but the same alert cannot mix radio and checkbox
34526 * inputs. Do note however, different types of "text"" inputs can be mixed,
34527 * such as `url`, `email`, `text`, etc. If you require a complex form UI
34528 * which doesn't fit within the guidelines of an alert then we recommend
34529 * building the form within a modal instead.
34530 *
34531 *
34532 * \@usage
34533 * ```ts
34534 * import { AlertController } from 'ionic-angular';
34535 *
34536 * constructor(public alertCtrl: AlertController) { }
34537 *
34538 * presentAlert() {
34539 * const alert = this.alertCtrl.create({
34540 * title: 'Low battery',
34541 * subTitle: '10% of battery remaining',
34542 * buttons: ['Dismiss']
34543 * });
34544 * alert.present();
34545 * }
34546 *
34547 * presentConfirm() {
34548 * const alert = this.alertCtrl.create({
34549 * title: 'Confirm purchase',
34550 * message: 'Do you want to buy this book?',
34551 * buttons: [
34552 * {
34553 * text: 'Cancel',
34554 * role: 'cancel',
34555 * handler: () => {
34556 * console.log('Cancel clicked');
34557 * }
34558 * },
34559 * {
34560 * text: 'Buy',
34561 * handler: () => {
34562 * console.log('Buy clicked');
34563 * }
34564 * }
34565 * ]
34566 * });
34567 * alert.present();
34568 * }
34569 *
34570 * presentPrompt() {
34571 * const alert = this.alertCtrl.create({
34572 * title: 'Login',
34573 * inputs: [
34574 * {
34575 * name: 'username',
34576 * placeholder: 'Username'
34577 * },
34578 * {
34579 * name: 'password',
34580 * placeholder: 'Password',
34581 * type: 'password'
34582 * }
34583 * ],
34584 * buttons: [
34585 * {
34586 * text: 'Cancel',
34587 * role: 'cancel',
34588 * handler: data => {
34589 * console.log('Cancel clicked');
34590 * }
34591 * },
34592 * {
34593 * text: 'Login',
34594 * handler: data => {
34595 * if (User.isValid(data.username, data.password)) {
34596 * // logged in!
34597 * } else {
34598 * // invalid login
34599 * return false;
34600 * }
34601 * }
34602 * }
34603 * ]
34604 * });
34605 * alert.present();
34606 * }
34607 * ```
34608 * \@advanced
34609 *
34610 *
34611 * Alert options
34612 *
34613 * | Property | Type | Description |
34614 * |-----------------------|-----------|------------------------------------------------------------------------------|
34615 * | title | `string` | The title for the alert. |
34616 * | subTitle | `string` | The subtitle for the alert. |
34617 * | message | `string` | The message for the alert. |
34618 * | cssClass | `string` | Additional classes for custom styles, separated by spaces. |
34619 * | inputs | `array` | An array of inputs for the alert. See input options. |
34620 * | buttons | `array` | An array of buttons for the alert. See buttons options. |
34621 * | enableBackdropDismiss | `boolean` | Whether the alert should be dismissed by tapping the backdrop. Default true. |
34622 *
34623 *
34624 * Input options
34625 *
34626 * | Property | Type | Description |
34627 * |-------------|-----------|-----------------------------------------------------------------|
34628 * | type | `string` | The type the input should be: text, tel, number, etc. |
34629 * | name | `string` | The name for the input. |
34630 * | placeholder | `string` | The input's placeholder (for textual/numeric inputs) |
34631 * | value | `string` | The input's value. |
34632 * | label | `string` | The input's label (only for radio/checkbox inputs) |
34633 * | checked | `boolean` | Whether or not the input is checked. |
34634 * | id | `string` | The input's id. |
34635 *
34636 * Button options
34637 *
34638 * | Property | Type | Description |
34639 * |----------|----------|-----------------------------------------------------------------|
34640 * | text | `string` | The buttons displayed text. |
34641 * | handler | `any` | Emitted when the button is pressed. |
34642 * | cssClass | `string` | An additional CSS class for the button. |
34643 * | role | `string` | The buttons role, null or `cancel`. |
34644 *
34645 * ### Dismissing And Async Navigation
34646 *
34647 * After an alert has been dismissed, the app may need to also transition
34648 * to another page depending on the handler's logic. However, because multiple
34649 * transitions were fired at roughly the same time, it's difficult for the
34650 * nav controller to cleanly animate multiple transitions that may
34651 * have been kicked off asynchronously. This is further described in the
34652 * [`Nav Transition Promises`](../../nav/NavController) section. For alerts,
34653 * this means it's best to wait for the alert to finish its transition
34654 * out before starting a new transition on the same nav controller.
34655 *
34656 * In the example below, after the alert button has been clicked, its handler
34657 * waits on async operation to complete, *then* it uses `pop` to navigate
34658 * back a page in the same stack. The potential problem is that the async operation
34659 * may have been completed before the alert has even finished its transition
34660 * out. In this case, it's best to ensure the alert has finished its transition
34661 * out first, *then* start the next transition.
34662 *
34663 * ```ts
34664 * const alert = this.alertCtrl.create({
34665 * title: 'Hello',
34666 * buttons: [{
34667 * text: 'Ok',
34668 * handler: () => {
34669 * // user has clicked the alert button
34670 * // begin the alert's dismiss transition
34671 * const navTransition = alert.dismiss();
34672 *
34673 * // start some async method
34674 * someAsyncOperation().then(() => {
34675 * // once the async operation has completed
34676 * // then run the next nav transition after the
34677 * // first transition has finished animating out
34678 *
34679 * navTransition.then(() => {
34680 * this.nav.pop();
34681 * });
34682 * });
34683 * return false;
34684 * }
34685 * }]
34686 * });
34687 *
34688 * alert.present();
34689 * ```
34690 *
34691 * It's important to note that the handler returns `false`. A feature of
34692 * button handlers is that they automatically dismiss the alert when their button
34693 * was clicked, however, we'll need more control regarding the transition. Because
34694 * the handler returns `false`, then the alert does not automatically dismiss
34695 * itself. Instead, you now have complete control of when the alert has finished
34696 * transitioning, and the ability to wait for the alert to finish transitioning
34697 * out before starting a new transition.
34698 *
34699 *
34700 * \@demo /docs/demos/src/alert/
34701 */
34702var AlertController = (function () {
34703 /**
34704 * @param {?} _app
34705 * @param {?} config
34706 */
34707 function AlertController(_app, config) {
34708 this._app = _app;
34709 this.config = config;
34710 }
34711 /**
34712 * Display an alert with a title, inputs, and buttons
34713 * @param {?=} opts
34714 * @return {?}
34715 */
34716 AlertController.prototype.create = function (opts) {
34717 if (opts === void 0) { opts = {}; }
34718 return new Alert(this._app, opts, this.config);
34719 };
34720 return AlertController;
34721}());
34722AlertController.decorators = [
34723 { type: Injectable },
34724];
34725/**
34726 * @nocollapse
34727 */
34728AlertController.ctorParameters = function () { return [
34729 { type: App, },
34730 { type: Config, },
34731]; };
34732
34733/**
34734 * \@name Avatar
34735 * \@module ionic
34736 * \@description
34737 * An Avatar is a component that creates a circular image for an item.
34738 * Avatars can be placed on the left or right side of an item with the `item-start` or `item-end` directive.
34739 * @see {\@link /docs/components/#avatar-list Avatar Component Docs}
34740 */
34741var Avatar = (function () {
34742 function Avatar() {
34743 }
34744 return Avatar;
34745}());
34746Avatar.decorators = [
34747 { type: Directive, args: [{
34748 selector: 'ion-avatar'
34749 },] },
34750];
34751/**
34752 * @nocollapse
34753 */
34754Avatar.ctorParameters = function () { return []; };
34755
34756/**
34757 * @hidden
34758 */
34759var Backdrop = (function () {
34760 /**
34761 * @param {?} _elementRef
34762 * @param {?} _renderer
34763 */
34764 function Backdrop(_elementRef, _renderer) {
34765 this._elementRef = _elementRef;
34766 this._renderer = _renderer;
34767 }
34768 /**
34769 * @return {?}
34770 */
34771 Backdrop.prototype.getNativeElement = function () {
34772 return this._elementRef.nativeElement;
34773 };
34774 /**
34775 * @param {?} className
34776 * @param {?} add
34777 * @return {?}
34778 */
34779 Backdrop.prototype.setElementClass = function (className, add) {
34780 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
34781 };
34782 return Backdrop;
34783}());
34784Backdrop.decorators = [
34785 { type: Directive, args: [{
34786 selector: 'ion-backdrop',
34787 host: {
34788 'role': 'presentation',
34789 'tappable': '',
34790 'disable-activated': ''
34791 },
34792 },] },
34793];
34794/**
34795 * @nocollapse
34796 */
34797Backdrop.ctorParameters = function () { return [
34798 { type: ElementRef, },
34799 { type: Renderer, },
34800]; };
34801
34802var __extends$28 = (undefined && undefined.__extends) || (function () {
34803 var extendStatics = Object.setPrototypeOf ||
34804 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
34805 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
34806 return function (d, b) {
34807 extendStatics(d, b);
34808 function __() { this.constructor = d; }
34809 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34810 };
34811})();
34812/**
34813 * \@name Badge
34814 * \@module ionic
34815 * \@description
34816 * Badges are simple components in Ionic containing numbers or text. You can display a badge to indicate that there is new information associated with the item it is on.
34817 * @see {\@link /docs/components/#badges Badges Component Docs}
34818 */
34819var Badge = (function (_super) {
34820 __extends$28(Badge, _super);
34821 /**
34822 * @param {?} config
34823 * @param {?} elementRef
34824 * @param {?} renderer
34825 */
34826 function Badge(config, elementRef, renderer) {
34827 return _super.call(this, config, elementRef, renderer, 'badge') || this;
34828 }
34829 return Badge;
34830}(Ion));
34831Badge.decorators = [
34832 { type: Directive, args: [{
34833 selector: 'ion-badge'
34834 },] },
34835];
34836/**
34837 * @nocollapse
34838 */
34839Badge.ctorParameters = function () { return [
34840 { type: Config, },
34841 { type: ElementRef, },
34842 { type: Renderer, },
34843]; };
34844
34845var __extends$29 = (undefined && undefined.__extends) || (function () {
34846 var extendStatics = Object.setPrototypeOf ||
34847 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
34848 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
34849 return function (d, b) {
34850 extendStatics(d, b);
34851 function __() { this.constructor = d; }
34852 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34853 };
34854})();
34855/**
34856 * \@name Button
34857 * \@module ionic
34858 * \@description
34859 * Buttons are simple components in Ionic. They can consist of text and icons
34860 * and be enhanced by a wide range of attributes.
34861 *
34862 * \@usage
34863 *
34864 * ```html
34865 *
34866 * <!-- Colors -->
34867 * <button ion-button>Default</button>
34868 *
34869 * <button ion-button color="secondary">Secondary</button>
34870 *
34871 * <button ion-button color="danger">Danger</button>
34872 *
34873 * <button ion-button color="light">Light</button>
34874 *
34875 * <button ion-button color="dark">Dark</button>
34876 *
34877 * <!-- Shapes -->
34878 * <button ion-button full>Full Button</button>
34879 *
34880 * <button ion-button block>Block Button</button>
34881 *
34882 * <button ion-button round>Round Button</button>
34883 *
34884 * <!-- Outline -->
34885 * <button ion-button full outline>Outline + Full</button>
34886 *
34887 * <button ion-button block outline>Outline + Block</button>
34888 *
34889 * <button ion-button round outline>Outline + Round</button>
34890 *
34891 * <!-- Icons -->
34892 * <button ion-button icon-start>
34893 * <ion-icon name="star"></ion-icon>
34894 * Left Icon
34895 * </button>
34896 *
34897 * <button ion-button icon-end>
34898 * Right Icon
34899 * <ion-icon name="star"></ion-icon>
34900 * </button>
34901 *
34902 * <button ion-button icon-only>
34903 * <ion-icon name="star"></ion-icon>
34904 * </button>
34905 *
34906 * <!-- Sizes -->
34907 * <button ion-button large>Large</button>
34908 *
34909 * <button ion-button>Default</button>
34910 *
34911 * <button ion-button small>Small</button>
34912 * ```
34913 *
34914 * \@advanced
34915 *
34916 * ```html
34917 *
34918 * <!-- Bind the color and outline inputs to an expression -->
34919 * <button ion-button [color]="isDanger ? 'danger' : 'primary'" [outline]="isOutline">
34920 * Danger (Solid)
34921 * </button>
34922 *
34923 * <!-- Bind the color and round inputs to an expression -->
34924 * <button ion-button [color]="myColor" [round]="isRound">
34925 * Secondary (Round)
34926 * </button>
34927 *
34928 * <!-- Bind the color and clear inputs to an expression -->
34929 * <button ion-button [color]="isSecondary ? 'secondary' : 'primary'" [clear]="isClear">
34930 * Primary (Clear)
34931 * </button>
34932 *
34933 * <!-- Bind the color, outline and round inputs to an expression -->
34934 * <button ion-button [color]="myColor2" [outline]="isOutline" [round]="isRound">
34935 * Dark (Solid + Round)
34936 * </button>
34937 *
34938 * <!-- Bind the click event to a method -->
34939 * <button ion-button (click)="logEvent($event)">
34940 * Click me!
34941 * </button>
34942 * ```
34943 *
34944 * ```ts
34945 * \@Component({
34946 * templateUrl: 'main.html'
34947 * })
34948 * class E2EPage {
34949 * isDanger: boolean = true;
34950 * isSecondary: boolean = false;
34951 * isRound: boolean = true;
34952 * isOutline: boolean = false;
34953 * isClear: boolean = true;
34954 * myColor: string = 'secondary';
34955 * myColor2: string = 'dark';
34956 *
34957 * logEvent(event) {
34958 * console.log(event)
34959 * }
34960 * }
34961 *
34962 * ```
34963 *
34964 * \@demo /docs/demos/src/button/
34965 * @see {\@link /docs/components#buttons Button Component Docs}
34966 * @see {\@link /docs/components#fabs FabButton Docs}
34967 * @see {\@link ../../fab/FabButton FabButton API Docs}
34968 * @see {\@link ../../fab/FabContainer FabContainer API Docs}
34969 */
34970var Button = (function (_super) {
34971 __extends$29(Button, _super);
34972 /**
34973 * @param {?} ionButton
34974 * @param {?} config
34975 * @param {?} elementRef
34976 * @param {?} renderer
34977 */
34978 function Button(ionButton, config, elementRef, renderer) {
34979 var _this = _super.call(this, config, elementRef, renderer) || this;
34980 /**
34981 * @hidden
34982 */
34983 _this._role = 'button';
34984 /**
34985 * @hidden
34986 */
34987 _this._style = 'default';
34988 _this._mode = config.get('mode');
34989 if (config.get('hoverCSS') === false) {
34990 _this.setElementClass('disable-hover', true);
34991 }
34992 if (ionButton.trim().length > 0) {
34993 _this.setRole(ionButton);
34994 }
34995 return _this;
34996 }
34997 Object.defineProperty(Button.prototype, "large", {
34998 /**
34999 * \@input {boolean} If true, activates the large button size.
35000 * @param {?} val
35001 * @return {?}
35002 */
35003 set: function (val) {
35004 this._attr('_size', 'large', val);
35005 },
35006 enumerable: true,
35007 configurable: true
35008 });
35009 Object.defineProperty(Button.prototype, "small", {
35010 /**
35011 * \@input {boolean} If true, activates the small button size.
35012 * @param {?} val
35013 * @return {?}
35014 */
35015 set: function (val) {
35016 this._attr('_size', 'small', val);
35017 },
35018 enumerable: true,
35019 configurable: true
35020 });
35021 Object.defineProperty(Button.prototype, "default", {
35022 /**
35023 * \@input {boolean} If true, activates the default button size. Normally the default, useful for buttons in an item.
35024 * @param {?} val
35025 * @return {?}
35026 */
35027 set: function (val) {
35028 this._attr('_size', 'default', val);
35029 },
35030 enumerable: true,
35031 configurable: true
35032 });
35033 Object.defineProperty(Button.prototype, "outline", {
35034 /**
35035 * \@input {boolean} If true, activates a transparent button style with a border.
35036 * @param {?} val
35037 * @return {?}
35038 */
35039 set: function (val) {
35040 this._attr('_style', 'outline', val);
35041 },
35042 enumerable: true,
35043 configurable: true
35044 });
35045 Object.defineProperty(Button.prototype, "clear", {
35046 /**
35047 * \@input {boolean} If true, activates a transparent button style without a border.
35048 * @param {?} val
35049 * @return {?}
35050 */
35051 set: function (val) {
35052 this._attr('_style', 'clear', val);
35053 },
35054 enumerable: true,
35055 configurable: true
35056 });
35057 Object.defineProperty(Button.prototype, "solid", {
35058 /**
35059 * \@input {boolean} If true, activates a solid button style. Normally the default, useful for buttons in a toolbar.
35060 * @param {?} val
35061 * @return {?}
35062 */
35063 set: function (val) {
35064 this._attr('_style', 'solid', val);
35065 },
35066 enumerable: true,
35067 configurable: true
35068 });
35069 Object.defineProperty(Button.prototype, "round", {
35070 /**
35071 * \@input {boolean} If true, activates a button with rounded corners.
35072 * @param {?} val
35073 * @return {?}
35074 */
35075 set: function (val) {
35076 this._attr('_shape', 'round', val);
35077 },
35078 enumerable: true,
35079 configurable: true
35080 });
35081 Object.defineProperty(Button.prototype, "block", {
35082 /**
35083 * \@input {boolean} If true, activates a button style that fills the available width.
35084 * @param {?} val
35085 * @return {?}
35086 */
35087 set: function (val) {
35088 this._attr('_display', 'block', val);
35089 },
35090 enumerable: true,
35091 configurable: true
35092 });
35093 Object.defineProperty(Button.prototype, "full", {
35094 /**
35095 * \@input {boolean} If true, activates a button style that fills the available width without
35096 * a left and right border.
35097 * @param {?} val
35098 * @return {?}
35099 */
35100 set: function (val) {
35101 this._attr('_display', 'full', val);
35102 },
35103 enumerable: true,
35104 configurable: true
35105 });
35106 Object.defineProperty(Button.prototype, "strong", {
35107 /**
35108 * \@input {boolean} If true, activates a button with a heavier font weight.
35109 * @param {?} val
35110 * @return {?}
35111 */
35112 set: function (val) {
35113 this._attr('_decorator', 'strong', val);
35114 },
35115 enumerable: true,
35116 configurable: true
35117 });
35118 Object.defineProperty(Button.prototype, "mode", {
35119 /**
35120 * \@input {string} The mode determines which platform styles to use.
35121 * Possible values are: `"ios"`, `"md"`, or `"wp"`.
35122 * For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
35123 * @param {?} val
35124 * @return {?}
35125 */
35126 set: function (val) {
35127 this._assignCss(false);
35128 this._mode = val;
35129 this._assignCss(true);
35130 },
35131 enumerable: true,
35132 configurable: true
35133 });
35134 /**
35135 * @hidden
35136 * @param {?} type
35137 * @param {?} attrName
35138 * @param {?} attrValue
35139 * @return {?}
35140 */
35141 Button.prototype._attr = function (type, attrName, attrValue) {
35142 if (type === '_style') {
35143 this._updateColor(this._color, false);
35144 }
35145 this._setClass(((this))[type], false);
35146 if (isTrueProperty(attrValue)) {
35147 ((this))[type] = attrName;
35148 this._setClass(attrName, true);
35149 }
35150 else {
35151 // Special handling for '_style' which defaults to 'default'.
35152 ((this))[type] = (type === '_style' ? 'default' : null);
35153 this._setClass(((this))[type], true);
35154 }
35155 if (type === '_style') {
35156 this._updateColor(this._color, true);
35157 }
35158 };
35159 Object.defineProperty(Button.prototype, "color", {
35160 /**
35161 * \@input {string} The color to use from your Sass `$colors` map.
35162 * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
35163 * For more information, see [Theming your App](/docs/theming/theming-your-app).
35164 * @param {?} val
35165 * @return {?}
35166 */
35167 set: function (val) {
35168 this._updateColor(this._color, false);
35169 this._updateColor(val, true);
35170 this._color = val;
35171 },
35172 enumerable: true,
35173 configurable: true
35174 });
35175 /**
35176 * @hidden
35177 * @return {?}
35178 */
35179 Button.prototype.ngAfterContentInit = function () {
35180 this._init = true;
35181 this._assignCss(true);
35182 };
35183 /**
35184 * @hidden
35185 * @param {?} val
35186 * @return {?}
35187 */
35188 Button.prototype.setRole = function (val) {
35189 this._assignCss(false);
35190 this._role = val;
35191 this._assignCss(true);
35192 };
35193 /**
35194 * @hidden
35195 * @param {?} assignCssClass
35196 * @return {?}
35197 */
35198 Button.prototype._assignCss = function (assignCssClass) {
35199 var /** @type {?} */ role = this._role;
35200 if (role) {
35201 this.setElementClass(role, assignCssClass); // button
35202 this.setElementClass(role + "-" + this._mode, assignCssClass); // button
35203 this._setClass(this._style, assignCssClass); // button-clear
35204 this._setClass(this._shape, assignCssClass); // button-round
35205 this._setClass(this._display, assignCssClass); // button-full
35206 this._setClass(this._size, assignCssClass); // button-small
35207 this._setClass(this._decorator, assignCssClass); // button-strong
35208 this._updateColor(this._color, assignCssClass); // button-secondary, bar-button-secondary
35209 }
35210 };
35211 /**
35212 * @hidden
35213 * @param {?} type
35214 * @param {?} assignCssClass
35215 * @return {?}
35216 */
35217 Button.prototype._setClass = function (type, assignCssClass) {
35218 if (type && this._init) {
35219 type = type.toLocaleLowerCase();
35220 this.setElementClass(this._role + "-" + type, assignCssClass);
35221 this.setElementClass(this._role + "-" + type + "-" + this._mode, assignCssClass);
35222 }
35223 };
35224 /**
35225 * @hidden
35226 * @param {?} color
35227 * @param {?} isAdd
35228 * @return {?}
35229 */
35230 Button.prototype._updateColor = function (color, isAdd) {
35231 if (color && this._init) {
35232 // The class should begin with the button role
35233 // button, bar-button
35234 var /** @type {?} */ className = this._role;
35235 // If the role is not a bar-button, don't apply the solid style
35236 var /** @type {?} */ style$$1 = this._style;
35237 style$$1 = (this._role !== 'bar-button' && style$$1 === 'solid' ? 'default' : style$$1);
35238 className += (style$$1 !== null && style$$1 !== '' && style$$1 !== 'default' ? '-' + style$$1.toLowerCase() : '');
35239 if (color !== null && color !== '') {
35240 this.setElementClass(className + "-" + this._mode + "-" + color, isAdd);
35241 }
35242 }
35243 };
35244 return Button;
35245}(Ion));
35246Button.decorators = [
35247 { type: Component, args: [{
35248 selector: '[ion-button]',
35249 template: '<span class="button-inner">' +
35250 '<ng-content></ng-content>' +
35251 '</span>' +
35252 '<div class="button-effect"></div>',
35253 changeDetection: ChangeDetectionStrategy.OnPush,
35254 encapsulation: ViewEncapsulation.None,
35255 },] },
35256];
35257/**
35258 * @nocollapse
35259 */
35260Button.ctorParameters = function () { return [
35261 { type: undefined, decorators: [{ type: Attribute, args: ['ion-button',] },] },
35262 { type: Config, },
35263 { type: ElementRef, },
35264 { type: Renderer, },
35265]; };
35266Button.propDecorators = {
35267 'large': [{ type: Input },],
35268 'small': [{ type: Input },],
35269 'default': [{ type: Input },],
35270 'outline': [{ type: Input },],
35271 'clear': [{ type: Input },],
35272 'solid': [{ type: Input },],
35273 'round': [{ type: Input },],
35274 'block': [{ type: Input },],
35275 'full': [{ type: Input },],
35276 'strong': [{ type: Input },],
35277 'mode': [{ type: Input },],
35278 'color': [{ type: Input },],
35279};
35280
35281var __extends$30 = (undefined && undefined.__extends) || (function () {
35282 var extendStatics = Object.setPrototypeOf ||
35283 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
35284 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
35285 return function (d, b) {
35286 extendStatics(d, b);
35287 function __() { this.constructor = d; }
35288 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35289 };
35290})();
35291/**
35292 * @hidden
35293 */
35294var Card = (function (_super) {
35295 __extends$30(Card, _super);
35296 /**
35297 * @param {?} config
35298 * @param {?} elementRef
35299 * @param {?} renderer
35300 */
35301 function Card(config, elementRef, renderer) {
35302 return _super.call(this, config, elementRef, renderer, 'card') || this;
35303 }
35304 return Card;
35305}(Ion));
35306Card.decorators = [
35307 { type: Directive, args: [{
35308 selector: 'ion-card'
35309 },] },
35310];
35311/**
35312 * @nocollapse
35313 */
35314Card.ctorParameters = function () { return [
35315 { type: Config, },
35316 { type: ElementRef, },
35317 { type: Renderer, },
35318]; };
35319
35320var __extends$31 = (undefined && undefined.__extends) || (function () {
35321 var extendStatics = Object.setPrototypeOf ||
35322 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
35323 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
35324 return function (d, b) {
35325 extendStatics(d, b);
35326 function __() { this.constructor = d; }
35327 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35328 };
35329})();
35330/**
35331 * @hidden
35332 */
35333var CardContent = (function (_super) {
35334 __extends$31(CardContent, _super);
35335 /**
35336 * @param {?} config
35337 * @param {?} elementRef
35338 * @param {?} renderer
35339 */
35340 function CardContent(config, elementRef, renderer) {
35341 return _super.call(this, config, elementRef, renderer, 'card-content') || this;
35342 }
35343 return CardContent;
35344}(Ion));
35345CardContent.decorators = [
35346 { type: Directive, args: [{
35347 selector: 'ion-card-content'
35348 },] },
35349];
35350/**
35351 * @nocollapse
35352 */
35353CardContent.ctorParameters = function () { return [
35354 { type: Config, },
35355 { type: ElementRef, },
35356 { type: Renderer, },
35357]; };
35358
35359var __extends$32 = (undefined && undefined.__extends) || (function () {
35360 var extendStatics = Object.setPrototypeOf ||
35361 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
35362 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
35363 return function (d, b) {
35364 extendStatics(d, b);
35365 function __() { this.constructor = d; }
35366 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35367 };
35368})();
35369/**
35370 * @hidden
35371 */
35372var CardHeader = (function (_super) {
35373 __extends$32(CardHeader, _super);
35374 /**
35375 * @param {?} config
35376 * @param {?} elementRef
35377 * @param {?} renderer
35378 */
35379 function CardHeader(config, elementRef, renderer) {
35380 return _super.call(this, config, elementRef, renderer, 'card-header') || this;
35381 }
35382 return CardHeader;
35383}(Ion));
35384CardHeader.decorators = [
35385 { type: Directive, args: [{
35386 selector: 'ion-card-header'
35387 },] },
35388];
35389/**
35390 * @nocollapse
35391 */
35392CardHeader.ctorParameters = function () { return [
35393 { type: Config, },
35394 { type: ElementRef, },
35395 { type: Renderer, },
35396]; };
35397
35398var __extends$33 = (undefined && undefined.__extends) || (function () {
35399 var extendStatics = Object.setPrototypeOf ||
35400 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
35401 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
35402 return function (d, b) {
35403 extendStatics(d, b);
35404 function __() { this.constructor = d; }
35405 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35406 };
35407})();
35408/**
35409 * @hidden
35410 */
35411var CardTitle = (function (_super) {
35412 __extends$33(CardTitle, _super);
35413 /**
35414 * @param {?} config
35415 * @param {?} elementRef
35416 * @param {?} renderer
35417 */
35418 function CardTitle(config, elementRef, renderer) {
35419 return _super.call(this, config, elementRef, renderer, 'card-title') || this;
35420 }
35421 return CardTitle;
35422}(Ion));
35423CardTitle.decorators = [
35424 { type: Directive, args: [{
35425 selector: 'ion-card-title'
35426 },] },
35427];
35428/**
35429 * @nocollapse
35430 */
35431CardTitle.ctorParameters = function () { return [
35432 { type: Config, },
35433 { type: ElementRef, },
35434 { type: Renderer, },
35435]; };
35436
35437var __extends$35 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
35438 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
35439 function __() { this.constructor = d; }
35440 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35441};
35442
35443
35444
35445
35446
35447/**
35448 * We need this JSDoc comment for affecting ESDoc.
35449 * @extends {Ignored}
35450 * @hide true
35451 */
35452var ForkJoinObservable = (function (_super) {
35453 __extends$35(ForkJoinObservable, _super);
35454 function ForkJoinObservable(sources, resultSelector) {
35455 _super.call(this);
35456 this.sources = sources;
35457 this.resultSelector = resultSelector;
35458 }
35459 /* tslint:enable:max-line-length */
35460 /**
35461 * @param sources
35462 * @return {any}
35463 * @static true
35464 * @name forkJoin
35465 * @owner Observable
35466 */
35467 ForkJoinObservable.create = function () {
35468 var sources = [];
35469 for (var _i = 0; _i < arguments.length; _i++) {
35470 sources[_i - 0] = arguments[_i];
35471 }
35472 if (sources === null || arguments.length === 0) {
35473 return new EmptyObservable_1.EmptyObservable();
35474 }
35475 var resultSelector = null;
35476 if (typeof sources[sources.length - 1] === 'function') {
35477 resultSelector = sources.pop();
35478 }
35479 // if the first and only other argument besides the resultSelector is an array
35480 // assume it's been called with `forkJoin([obs1, obs2, obs3], resultSelector)`
35481 if (sources.length === 1 && isArray.isArray(sources[0])) {
35482 sources = sources[0];
35483 }
35484 if (sources.length === 0) {
35485 return new EmptyObservable_1.EmptyObservable();
35486 }
35487 return new ForkJoinObservable(sources, resultSelector);
35488 };
35489 ForkJoinObservable.prototype._subscribe = function (subscriber) {
35490 return new ForkJoinSubscriber(subscriber, this.sources, this.resultSelector);
35491 };
35492 return ForkJoinObservable;
35493}(Observable_1.Observable));
35494var ForkJoinObservable_2 = ForkJoinObservable;
35495/**
35496 * We need this JSDoc comment for affecting ESDoc.
35497 * @ignore
35498 * @extends {Ignored}
35499 */
35500var ForkJoinSubscriber = (function (_super) {
35501 __extends$35(ForkJoinSubscriber, _super);
35502 function ForkJoinSubscriber(destination, sources, resultSelector) {
35503 _super.call(this, destination);
35504 this.sources = sources;
35505 this.resultSelector = resultSelector;
35506 this.completed = 0;
35507 this.haveValues = 0;
35508 var len = sources.length;
35509 this.total = len;
35510 this.values = new Array(len);
35511 for (var i = 0; i < len; i++) {
35512 var source = sources[i];
35513 var innerSubscription = subscribeToResult_1.subscribeToResult(this, source, null, i);
35514 if (innerSubscription) {
35515 innerSubscription.outerIndex = i;
35516 this.add(innerSubscription);
35517 }
35518 }
35519 }
35520 ForkJoinSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
35521 this.values[outerIndex] = innerValue;
35522 if (!innerSub._hasValue) {
35523 innerSub._hasValue = true;
35524 this.haveValues++;
35525 }
35526 };
35527 ForkJoinSubscriber.prototype.notifyComplete = function (innerSub) {
35528 var destination = this.destination;
35529 var _a = this, haveValues = _a.haveValues, resultSelector = _a.resultSelector, values = _a.values;
35530 var len = values.length;
35531 if (!innerSub._hasValue) {
35532 destination.complete();
35533 return;
35534 }
35535 this.completed++;
35536 if (this.completed !== len) {
35537 return;
35538 }
35539 if (haveValues === len) {
35540 var value = resultSelector ? resultSelector.apply(this, values) : values;
35541 destination.next(value);
35542 }
35543 destination.complete();
35544 };
35545 return ForkJoinSubscriber;
35546}(OuterSubscriber_1.OuterSubscriber));
35547
35548var ForkJoinObservable_1 = {
35549 ForkJoinObservable: ForkJoinObservable_2
35550};
35551
35552var forkJoin_1 = ForkJoinObservable_1.ForkJoinObservable.create;
35553
35554var __extends$36 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
35555 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
35556 function __() { this.constructor = d; }
35557 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35558};
35559
35560
35561/**
35562 * We need this JSDoc comment for affecting ESDoc.
35563 * @extends {Ignored}
35564 * @hide true
35565 */
35566var PromiseObservable = (function (_super) {
35567 __extends$36(PromiseObservable, _super);
35568 function PromiseObservable(promise, scheduler) {
35569 _super.call(this);
35570 this.promise = promise;
35571 this.scheduler = scheduler;
35572 }
35573 /**
35574 * Converts a Promise to an Observable.
35575 *
35576 * <span class="informal">Returns an Observable that just emits the Promise's
35577 * resolved value, then completes.</span>
35578 *
35579 * Converts an ES2015 Promise or a Promises/A+ spec compliant Promise to an
35580 * Observable. If the Promise resolves with a value, the output Observable
35581 * emits that resolved value as a `next`, and then completes. If the Promise
35582 * is rejected, then the output Observable emits the corresponding Error.
35583 *
35584 * @example <caption>Convert the Promise returned by Fetch to an Observable</caption>
35585 * var result = Rx.Observable.fromPromise(fetch('http://myserver.com/'));
35586 * result.subscribe(x => console.log(x), e => console.error(e));
35587 *
35588 * @see {@link bindCallback}
35589 * @see {@link from}
35590 *
35591 * @param {PromiseLike<T>} promise The promise to be converted.
35592 * @param {Scheduler} [scheduler] An optional IScheduler to use for scheduling
35593 * the delivery of the resolved value (or the rejection).
35594 * @return {Observable<T>} An Observable which wraps the Promise.
35595 * @static true
35596 * @name fromPromise
35597 * @owner Observable
35598 */
35599 PromiseObservable.create = function (promise, scheduler) {
35600 return new PromiseObservable(promise, scheduler);
35601 };
35602 PromiseObservable.prototype._subscribe = function (subscriber) {
35603 var _this = this;
35604 var promise = this.promise;
35605 var scheduler = this.scheduler;
35606 if (scheduler == null) {
35607 if (this._isScalar) {
35608 if (!subscriber.closed) {
35609 subscriber.next(this.value);
35610 subscriber.complete();
35611 }
35612 }
35613 else {
35614 promise.then(function (value) {
35615 _this.value = value;
35616 _this._isScalar = true;
35617 if (!subscriber.closed) {
35618 subscriber.next(value);
35619 subscriber.complete();
35620 }
35621 }, function (err) {
35622 if (!subscriber.closed) {
35623 subscriber.error(err);
35624 }
35625 })
35626 .then(null, function (err) {
35627 // escape the promise trap, throw unhandled errors
35628 root.root.setTimeout(function () { throw err; });
35629 });
35630 }
35631 }
35632 else {
35633 if (this._isScalar) {
35634 if (!subscriber.closed) {
35635 return scheduler.schedule(dispatchNext, 0, { value: this.value, subscriber: subscriber });
35636 }
35637 }
35638 else {
35639 promise.then(function (value) {
35640 _this.value = value;
35641 _this._isScalar = true;
35642 if (!subscriber.closed) {
35643 subscriber.add(scheduler.schedule(dispatchNext, 0, { value: value, subscriber: subscriber }));
35644 }
35645 }, function (err) {
35646 if (!subscriber.closed) {
35647 subscriber.add(scheduler.schedule(dispatchError, 0, { err: err, subscriber: subscriber }));
35648 }
35649 })
35650 .then(null, function (err) {
35651 // escape the promise trap, throw unhandled errors
35652 root.root.setTimeout(function () { throw err; });
35653 });
35654 }
35655 }
35656 };
35657 return PromiseObservable;
35658}(Observable_1.Observable));
35659var PromiseObservable_2 = PromiseObservable;
35660function dispatchNext(arg) {
35661 var value = arg.value, subscriber = arg.subscriber;
35662 if (!subscriber.closed) {
35663 subscriber.next(value);
35664 subscriber.complete();
35665 }
35666}
35667function dispatchError(arg) {
35668 var err = arg.err, subscriber = arg.subscriber;
35669 if (!subscriber.closed) {
35670 subscriber.error(err);
35671 }
35672}
35673
35674var PromiseObservable_1 = {
35675 PromiseObservable: PromiseObservable_2
35676};
35677
35678var fromPromise_1 = PromiseObservable_1.PromiseObservable.create;
35679
35680var __extends$37 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
35681 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
35682 function __() { this.constructor = d; }
35683 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
35684};
35685
35686/**
35687 * Applies a given `project` function to each value emitted by the source
35688 * Observable, and emits the resulting values as an Observable.
35689 *
35690 * <span class="informal">Like [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),
35691 * it passes each source value through a transformation function to get
35692 * corresponding output values.</span>
35693 *
35694 * <img src="./img/map.png" width="100%">
35695 *
35696 * Similar to the well known `Array.prototype.map` function, this operator
35697 * applies a projection to each value and emits that projection in the output
35698 * Observable.
35699 *
35700 * @example <caption>Map every click to the clientX position of that click</caption>
35701 * var clicks = Rx.Observable.fromEvent(document, 'click');
35702 * var positions = clicks.map(ev => ev.clientX);
35703 * positions.subscribe(x => console.log(x));
35704 *
35705 * @see {@link mapTo}
35706 * @see {@link pluck}
35707 *
35708 * @param {function(value: T, index: number): R} project The function to apply
35709 * to each `value` emitted by the source Observable. The `index` parameter is
35710 * the number `i` for the i-th emission that has happened since the
35711 * subscription, starting from the number `0`.
35712 * @param {any} [thisArg] An optional argument to define what `this` is in the
35713 * `project` function.
35714 * @return {Observable<R>} An Observable that emits the values from the source
35715 * Observable transformed by the given `project` function.
35716 * @method map
35717 * @owner Observable
35718 */
35719function map(project, thisArg) {
35720 if (typeof project !== 'function') {
35721 throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');
35722 }
35723 return this.lift(new MapOperator(project, thisArg));
35724}
35725var map_2 = map;
35726var MapOperator = (function () {
35727 function MapOperator(project, thisArg) {
35728 this.project = project;
35729 this.thisArg = thisArg;
35730 }
35731 MapOperator.prototype.call = function (subscriber, source) {
35732 return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
35733 };
35734 return MapOperator;
35735}());
35736/**
35737 * We need this JSDoc comment for affecting ESDoc.
35738 * @ignore
35739 * @extends {Ignored}
35740 */
35741var MapSubscriber = (function (_super) {
35742 __extends$37(MapSubscriber, _super);
35743 function MapSubscriber(destination, project, thisArg) {
35744 _super.call(this, destination);
35745 this.project = project;
35746 this.count = 0;
35747 this.thisArg = thisArg || this;
35748 }
35749 // NOTE: This looks unoptimized, but it's actually purposefully NOT
35750 // using try/catch optimizations.
35751 MapSubscriber.prototype._next = function (value) {
35752 var result;
35753 try {
35754 result = this.project.call(this.thisArg, value, this.count++);
35755 }
35756 catch (err) {
35757 this.destination.error(err);
35758 return;
35759 }
35760 this.destination.next(result);
35761 };
35762 return MapSubscriber;
35763}(Subscriber_1.Subscriber));
35764
35765/**
35766 * @license Angular v4.4.3
35767 * (c) 2010-2017 Google, Inc. https://angular.io/
35768 * License: MIT
35769 */
35770/**
35771 * @license
35772 * Copyright Google Inc. All Rights Reserved.
35773 *
35774 * Use of this source code is governed by an MIT-style license that can be
35775 * found in the LICENSE file at https://angular.io/license
35776 */
35777/**
35778 * Base class for control directives.
35779 *
35780 * Only used internally in the forms module.
35781 *
35782 * \@stable
35783 * @abstract
35784 */
35785var AbstractControlDirective = (function () {
35786 function AbstractControlDirective() {
35787 }
35788 /**
35789 * The {\@link FormControl}, {\@link FormGroup}, or {\@link FormArray}
35790 * that backs this directive. Most properties fall through to that
35791 * instance.
35792 * @abstract
35793 * @return {?}
35794 */
35795 AbstractControlDirective.prototype.control = function () { };
35796 Object.defineProperty(AbstractControlDirective.prototype, "value", {
35797 /**
35798 * The value of the control.
35799 * @return {?}
35800 */
35801 get: function () { return this.control ? this.control.value : null; },
35802 enumerable: true,
35803 configurable: true
35804 });
35805 Object.defineProperty(AbstractControlDirective.prototype, "valid", {
35806 /**
35807 * A control is `valid` when its `status === VALID`.
35808 *
35809 * In order to have this status, the control must have passed all its
35810 * validation checks.
35811 * @return {?}
35812 */
35813 get: function () { return this.control ? this.control.valid : null; },
35814 enumerable: true,
35815 configurable: true
35816 });
35817 Object.defineProperty(AbstractControlDirective.prototype, "invalid", {
35818 /**
35819 * A control is `invalid` when its `status === INVALID`.
35820 *
35821 * In order to have this status, the control must have failed
35822 * at least one of its validation checks.
35823 * @return {?}
35824 */
35825 get: function () { return this.control ? this.control.invalid : null; },
35826 enumerable: true,
35827 configurable: true
35828 });
35829 Object.defineProperty(AbstractControlDirective.prototype, "pending", {
35830 /**
35831 * A control is `pending` when its `status === PENDING`.
35832 *
35833 * In order to have this status, the control must be in the
35834 * middle of conducting a validation check.
35835 * @return {?}
35836 */
35837 get: function () { return this.control ? this.control.pending : null; },
35838 enumerable: true,
35839 configurable: true
35840 });
35841 Object.defineProperty(AbstractControlDirective.prototype, "disabled", {
35842 /**
35843 * A control is `disabled` when its `status === DISABLED`.
35844 *
35845 * Disabled controls are exempt from validation checks and
35846 * are not included in the aggregate value of their ancestor
35847 * controls.
35848 * @return {?}
35849 */
35850 get: function () { return this.control ? this.control.disabled : null; },
35851 enumerable: true,
35852 configurable: true
35853 });
35854 Object.defineProperty(AbstractControlDirective.prototype, "enabled", {
35855 /**
35856 * A control is `enabled` as long as its `status !== DISABLED`.
35857 *
35858 * In other words, it has a status of `VALID`, `INVALID`, or
35859 * `PENDING`.
35860 * @return {?}
35861 */
35862 get: function () { return this.control ? this.control.enabled : null; },
35863 enumerable: true,
35864 configurable: true
35865 });
35866 Object.defineProperty(AbstractControlDirective.prototype, "errors", {
35867 /**
35868 * Returns any errors generated by failing validation. If there
35869 * are no errors, it will return null.
35870 * @return {?}
35871 */
35872 get: function () { return this.control ? this.control.errors : null; },
35873 enumerable: true,
35874 configurable: true
35875 });
35876 Object.defineProperty(AbstractControlDirective.prototype, "pristine", {
35877 /**
35878 * A control is `pristine` if the user has not yet changed
35879 * the value in the UI.
35880 *
35881 * Note that programmatic changes to a control's value will
35882 * *not* mark it dirty.
35883 * @return {?}
35884 */
35885 get: function () { return this.control ? this.control.pristine : null; },
35886 enumerable: true,
35887 configurable: true
35888 });
35889 Object.defineProperty(AbstractControlDirective.prototype, "dirty", {
35890 /**
35891 * A control is `dirty` if the user has changed the value
35892 * in the UI.
35893 *
35894 * Note that programmatic changes to a control's value will
35895 * *not* mark it dirty.
35896 * @return {?}
35897 */
35898 get: function () { return this.control ? this.control.dirty : null; },
35899 enumerable: true,
35900 configurable: true
35901 });
35902 Object.defineProperty(AbstractControlDirective.prototype, "touched", {
35903 /**
35904 * A control is marked `touched` once the user has triggered
35905 * a `blur` event on it.
35906 * @return {?}
35907 */
35908 get: function () { return this.control ? this.control.touched : null; },
35909 enumerable: true,
35910 configurable: true
35911 });
35912 Object.defineProperty(AbstractControlDirective.prototype, "untouched", {
35913 /**
35914 * A control is `untouched` if the user has not yet triggered
35915 * a `blur` event on it.
35916 * @return {?}
35917 */
35918 get: function () { return this.control ? this.control.untouched : null; },
35919 enumerable: true,
35920 configurable: true
35921 });
35922 Object.defineProperty(AbstractControlDirective.prototype, "statusChanges", {
35923 /**
35924 * Emits an event every time the validation status of the control
35925 * is re-calculated.
35926 * @return {?}
35927 */
35928 get: function () {
35929 return this.control ? this.control.statusChanges : null;
35930 },
35931 enumerable: true,
35932 configurable: true
35933 });
35934 Object.defineProperty(AbstractControlDirective.prototype, "valueChanges", {
35935 /**
35936 * Emits an event every time the value of the control changes, in
35937 * the UI or programmatically.
35938 * @return {?}
35939 */
35940 get: function () {
35941 return this.control ? this.control.valueChanges : null;
35942 },
35943 enumerable: true,
35944 configurable: true
35945 });
35946 Object.defineProperty(AbstractControlDirective.prototype, "path", {
35947 /**
35948 * Returns an array that represents the path from the top-level form
35949 * to this control. Each index is the string name of the control on
35950 * that level.
35951 * @return {?}
35952 */
35953 get: function () { return null; },
35954 enumerable: true,
35955 configurable: true
35956 });
35957 /**
35958 * Resets the form control. This means by default:
35959 *
35960 * * it is marked as `pristine`
35961 * * it is marked as `untouched`
35962 * * value is set to null
35963 *
35964 * For more information, see {\@link AbstractControl}.
35965 * @param {?=} value
35966 * @return {?}
35967 */
35968 AbstractControlDirective.prototype.reset = function (value) {
35969 if (value === void 0) { value = undefined; }
35970 if (this.control)
35971 this.control.reset(value);
35972 };
35973 /**
35974 * Returns true if the control with the given path has the error specified. Otherwise
35975 * returns false.
35976 *
35977 * If no path is given, it checks for the error on the present control.
35978 * @param {?} errorCode
35979 * @param {?=} path
35980 * @return {?}
35981 */
35982 AbstractControlDirective.prototype.hasError = function (errorCode, path) {
35983 return this.control ? this.control.hasError(errorCode, path) : false;
35984 };
35985 /**
35986 * Returns error data if the control with the given path has the error specified. Otherwise
35987 * returns null or undefined.
35988 *
35989 * If no path is given, it checks for the error on the present control.
35990 * @param {?} errorCode
35991 * @param {?=} path
35992 * @return {?}
35993 */
35994 AbstractControlDirective.prototype.getError = function (errorCode, path) {
35995 return this.control ? this.control.getError(errorCode, path) : null;
35996 };
35997 return AbstractControlDirective;
35998}());
35999/**
36000 * @license
36001 * Copyright Google Inc. All Rights Reserved.
36002 *
36003 * Use of this source code is governed by an MIT-style license that can be
36004 * found in the LICENSE file at https://angular.io/license
36005 */
36006/**
36007 * A directive that contains multiple {\@link NgControl}s.
36008 *
36009 * Only used by the forms module.
36010 *
36011 * \@stable
36012 * @abstract
36013 */
36014var ControlContainer = (function (_super) {
36015 __extends$1(ControlContainer, _super);
36016 function ControlContainer() {
36017 return _super !== null && _super.apply(this, arguments) || this;
36018 }
36019 Object.defineProperty(ControlContainer.prototype, "formDirective", {
36020 /**
36021 * Get the form to which this container belongs.
36022 * @return {?}
36023 */
36024 get: function () { return null; },
36025 enumerable: true,
36026 configurable: true
36027 });
36028 Object.defineProperty(ControlContainer.prototype, "path", {
36029 /**
36030 * Get the path to this container.
36031 * @return {?}
36032 */
36033 get: function () { return null; },
36034 enumerable: true,
36035 configurable: true
36036 });
36037 return ControlContainer;
36038}(AbstractControlDirective));
36039/**
36040 * @license
36041 * Copyright Google Inc. All Rights Reserved.
36042 *
36043 * Use of this source code is governed by an MIT-style license that can be
36044 * found in the LICENSE file at https://angular.io/license
36045 */
36046/**
36047 * @param {?} value
36048 * @return {?}
36049 */
36050function isEmptyInputValue(value) {
36051 // we don't check for string here so it also works with arrays
36052 return value == null || value.length === 0;
36053}
36054/**
36055 * Providers for validators to be used for {\@link FormControl}s in a form.
36056 *
36057 * Provide this using `multi: true` to add validators.
36058 *
36059 * \@stable
36060 */
36061var NG_VALIDATORS = new InjectionToken('NgValidators');
36062/**
36063 * Providers for asynchronous validators to be used for {\@link FormControl}s
36064 * in a form.
36065 *
36066 * Provide this using `multi: true` to add validators.
36067 *
36068 * See {\@link NG_VALIDATORS} for more details.
36069 *
36070 * \@stable
36071 */
36072var NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators');
36073var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
36074/**
36075 * Provides a set of validators used by form controls.
36076 *
36077 * A validator is a function that processes a {\@link FormControl} or collection of
36078 * controls and returns a map of errors. A null map means that validation has passed.
36079 *
36080 * ### Example
36081 *
36082 * ```typescript
36083 * var loginControl = new FormControl("", Validators.required)
36084 * ```
36085 *
36086 * \@stable
36087 */
36088var Validators = (function () {
36089 function Validators() {
36090 }
36091 /**
36092 * Validator that requires controls to have a value greater than a number.
36093 * @param {?} min
36094 * @return {?}
36095 */
36096 Validators.min = function (min) {
36097 return function (control) {
36098 if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
36099 return null; // don't validate empty values to allow optional controls
36100 }
36101 var /** @type {?} */ value = parseFloat(control.value);
36102 // Controls with NaN values after parsing should be treated as not having a
36103 // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
36104 return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null;
36105 };
36106 };
36107 /**
36108 * Validator that requires controls to have a value less than a number.
36109 * @param {?} max
36110 * @return {?}
36111 */
36112 Validators.max = function (max) {
36113 return function (control) {
36114 if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
36115 return null; // don't validate empty values to allow optional controls
36116 }
36117 var /** @type {?} */ value = parseFloat(control.value);
36118 // Controls with NaN values after parsing should be treated as not having a
36119 // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
36120 return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null;
36121 };
36122 };
36123 /**
36124 * Validator that requires controls to have a non-empty value.
36125 * @param {?} control
36126 * @return {?}
36127 */
36128 Validators.required = function (control) {
36129 return isEmptyInputValue(control.value) ? { 'required': true } : null;
36130 };
36131 /**
36132 * Validator that requires control value to be true.
36133 * @param {?} control
36134 * @return {?}
36135 */
36136 Validators.requiredTrue = function (control) {
36137 return control.value === true ? null : { 'required': true };
36138 };
36139 /**
36140 * Validator that performs email validation.
36141 * @param {?} control
36142 * @return {?}
36143 */
36144 Validators.email = function (control) {
36145 return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };
36146 };
36147 /**
36148 * Validator that requires controls to have a value of a minimum length.
36149 * @param {?} minLength
36150 * @return {?}
36151 */
36152 Validators.minLength = function (minLength) {
36153 return function (control) {
36154 if (isEmptyInputValue(control.value)) {
36155 return null; // don't validate empty values to allow optional controls
36156 }
36157 var /** @type {?} */ length = control.value ? control.value.length : 0;
36158 return length < minLength ?
36159 { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } :
36160 null;
36161 };
36162 };
36163 /**
36164 * Validator that requires controls to have a value of a maximum length.
36165 * @param {?} maxLength
36166 * @return {?}
36167 */
36168 Validators.maxLength = function (maxLength) {
36169 return function (control) {
36170 var /** @type {?} */ length = control.value ? control.value.length : 0;
36171 return length > maxLength ?
36172 { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } :
36173 null;
36174 };
36175 };
36176 /**
36177 * Validator that requires a control to match a regex to its value.
36178 * @param {?} pattern
36179 * @return {?}
36180 */
36181 Validators.pattern = function (pattern) {
36182 if (!pattern)
36183 return Validators.nullValidator;
36184 var /** @type {?} */ regex;
36185 var /** @type {?} */ regexStr;
36186 if (typeof pattern === 'string') {
36187 regexStr = "^" + pattern + "$";
36188 regex = new RegExp(regexStr);
36189 }
36190 else {
36191 regexStr = pattern.toString();
36192 regex = pattern;
36193 }
36194 return function (control) {
36195 if (isEmptyInputValue(control.value)) {
36196 return null; // don't validate empty values to allow optional controls
36197 }
36198 var /** @type {?} */ value = control.value;
36199 return regex.test(value) ? null :
36200 { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } };
36201 };
36202 };
36203 /**
36204 * No-op validator.
36205 * @param {?} c
36206 * @return {?}
36207 */
36208 Validators.nullValidator = function (c) { return null; };
36209 /**
36210 * @param {?} validators
36211 * @return {?}
36212 */
36213 Validators.compose = function (validators) {
36214 if (!validators)
36215 return null;
36216 var /** @type {?} */ presentValidators = (validators.filter(isPresent$1));
36217 if (presentValidators.length == 0)
36218 return null;
36219 return function (control) {
36220 return _mergeErrors(_executeValidators(control, presentValidators));
36221 };
36222 };
36223 /**
36224 * @param {?} validators
36225 * @return {?}
36226 */
36227 Validators.composeAsync = function (validators) {
36228 if (!validators)
36229 return null;
36230 var /** @type {?} */ presentValidators = (validators.filter(isPresent$1));
36231 if (presentValidators.length == 0)
36232 return null;
36233 return function (control) {
36234 var /** @type {?} */ observables = _executeAsyncValidators(control, presentValidators).map(toObservable);
36235 return map_2.call(forkJoin_1(observables), _mergeErrors);
36236 };
36237 };
36238 return Validators;
36239}());
36240/**
36241 * @param {?} o
36242 * @return {?}
36243 */
36244function isPresent$1(o) {
36245 return o != null;
36246}
36247/**
36248 * @param {?} r
36249 * @return {?}
36250 */
36251function toObservable(r) {
36252 var /** @type {?} */ obs = isPromise(r) ? fromPromise_1(r) : r;
36253 if (!(isObservable(obs))) {
36254 throw new Error("Expected validator to return Promise or Observable.");
36255 }
36256 return obs;
36257}
36258/**
36259 * @param {?} control
36260 * @param {?} validators
36261 * @return {?}
36262 */
36263function _executeValidators(control, validators) {
36264 return validators.map(function (v) { return v(control); });
36265}
36266/**
36267 * @param {?} control
36268 * @param {?} validators
36269 * @return {?}
36270 */
36271function _executeAsyncValidators(control, validators) {
36272 return validators.map(function (v) { return v(control); });
36273}
36274/**
36275 * @param {?} arrayOfErrors
36276 * @return {?}
36277 */
36278function _mergeErrors(arrayOfErrors) {
36279 var /** @type {?} */ res = arrayOfErrors.reduce(function (res, errors) {
36280 return errors != null ? Object.assign({}, /** @type {?} */ ((res)), errors) : ((res));
36281 }, {});
36282 return Object.keys(res).length === 0 ? null : res;
36283}
36284/**
36285 * @license
36286 * Copyright Google Inc. All Rights Reserved.
36287 *
36288 * Use of this source code is governed by an MIT-style license that can be
36289 * found in the LICENSE file at https://angular.io/license
36290 */
36291/**
36292 * Used to provide a {\@link ControlValueAccessor} for form controls.
36293 *
36294 * See {\@link DefaultValueAccessor} for how to implement one.
36295 * \@stable
36296 */
36297var NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor');
36298/**
36299 * @license
36300 * Copyright Google Inc. All Rights Reserved.
36301 *
36302 * Use of this source code is governed by an MIT-style license that can be
36303 * found in the LICENSE file at https://angular.io/license
36304 */
36305var CHECKBOX_VALUE_ACCESSOR = {
36306 provide: NG_VALUE_ACCESSOR,
36307 useExisting: forwardRef(function () { return CheckboxControlValueAccessor; }),
36308 multi: true,
36309};
36310/**
36311 * The accessor for writing a value and listening to changes on a checkbox input element.
36312 *
36313 * ### Example
36314 * ```
36315 * <input type="checkbox" name="rememberLogin" ngModel>
36316 * ```
36317 *
36318 * \@stable
36319 */
36320var CheckboxControlValueAccessor = (function () {
36321 /**
36322 * @param {?} _renderer
36323 * @param {?} _elementRef
36324 */
36325 function CheckboxControlValueAccessor(_renderer, _elementRef) {
36326 this._renderer = _renderer;
36327 this._elementRef = _elementRef;
36328 this.onChange = function (_) { };
36329 this.onTouched = function () { };
36330 }
36331 /**
36332 * @param {?} value
36333 * @return {?}
36334 */
36335 CheckboxControlValueAccessor.prototype.writeValue = function (value) {
36336 this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value);
36337 };
36338 /**
36339 * @param {?} fn
36340 * @return {?}
36341 */
36342 CheckboxControlValueAccessor.prototype.registerOnChange = function (fn) { this.onChange = fn; };
36343 /**
36344 * @param {?} fn
36345 * @return {?}
36346 */
36347 CheckboxControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
36348 /**
36349 * @param {?} isDisabled
36350 * @return {?}
36351 */
36352 CheckboxControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
36353 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
36354 };
36355 return CheckboxControlValueAccessor;
36356}());
36357CheckboxControlValueAccessor.decorators = [
36358 { type: Directive, args: [{
36359 selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
36360 host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' },
36361 providers: [CHECKBOX_VALUE_ACCESSOR]
36362 },] },
36363];
36364/**
36365 * @nocollapse
36366 */
36367CheckboxControlValueAccessor.ctorParameters = function () { return [
36368 { type: Renderer2, },
36369 { type: ElementRef, },
36370]; };
36371/**
36372 * @license
36373 * Copyright Google Inc. All Rights Reserved.
36374 *
36375 * Use of this source code is governed by an MIT-style license that can be
36376 * found in the LICENSE file at https://angular.io/license
36377 */
36378var DEFAULT_VALUE_ACCESSOR = {
36379 provide: NG_VALUE_ACCESSOR,
36380 useExisting: forwardRef(function () { return DefaultValueAccessor; }),
36381 multi: true
36382};
36383/**
36384 * We must check whether the agent is Android because composition events
36385 * behave differently between iOS and Android.
36386 * @return {?}
36387 */
36388function _isAndroid() {
36389 var /** @type {?} */ userAgent = getDOM() ? getDOM().getUserAgent() : '';
36390 return /android (\d+)/.test(userAgent.toLowerCase());
36391}
36392/**
36393 * Turn this mode on if you want form directives to buffer IME input until compositionend
36394 * \@experimental
36395 */
36396var COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode');
36397/**
36398 * The default accessor for writing a value and listening to changes that is used by the
36399 * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
36400 *
36401 * ### Example
36402 * ```
36403 * <input type="text" name="searchQuery" ngModel>
36404 * ```
36405 *
36406 * \@stable
36407 */
36408var DefaultValueAccessor = (function () {
36409 /**
36410 * @param {?} _renderer
36411 * @param {?} _elementRef
36412 * @param {?} _compositionMode
36413 */
36414 function DefaultValueAccessor(_renderer, _elementRef, _compositionMode) {
36415 this._renderer = _renderer;
36416 this._elementRef = _elementRef;
36417 this._compositionMode = _compositionMode;
36418 this.onChange = function (_) { };
36419 this.onTouched = function () { };
36420 /**
36421 * Whether the user is creating a composition string (IME events).
36422 */
36423 this._composing = false;
36424 if (this._compositionMode == null) {
36425 this._compositionMode = !_isAndroid();
36426 }
36427 }
36428 /**
36429 * @param {?} value
36430 * @return {?}
36431 */
36432 DefaultValueAccessor.prototype.writeValue = function (value) {
36433 var /** @type {?} */ normalizedValue = value == null ? '' : value;
36434 this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
36435 };
36436 /**
36437 * @param {?} fn
36438 * @return {?}
36439 */
36440 DefaultValueAccessor.prototype.registerOnChange = function (fn) { this.onChange = fn; };
36441 /**
36442 * @param {?} fn
36443 * @return {?}
36444 */
36445 DefaultValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
36446 /**
36447 * @param {?} isDisabled
36448 * @return {?}
36449 */
36450 DefaultValueAccessor.prototype.setDisabledState = function (isDisabled) {
36451 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
36452 };
36453 /**
36454 * \@internal
36455 * @param {?} value
36456 * @return {?}
36457 */
36458 DefaultValueAccessor.prototype._handleInput = function (value) {
36459 if (!this._compositionMode || (this._compositionMode && !this._composing)) {
36460 this.onChange(value);
36461 }
36462 };
36463 /**
36464 * \@internal
36465 * @return {?}
36466 */
36467 DefaultValueAccessor.prototype._compositionStart = function () { this._composing = true; };
36468 /**
36469 * \@internal
36470 * @param {?} value
36471 * @return {?}
36472 */
36473 DefaultValueAccessor.prototype._compositionEnd = function (value) {
36474 this._composing = false;
36475 this._compositionMode && this.onChange(value);
36476 };
36477 return DefaultValueAccessor;
36478}());
36479DefaultValueAccessor.decorators = [
36480 { type: Directive, args: [{
36481 selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
36482 // TODO: vsavkin replace the above selector with the one below it once
36483 // https://github.com/angular/angular/issues/3011 is implemented
36484 // selector: '[ngModel],[formControl],[formControlName]',
36485 host: {
36486 '(input)': '_handleInput($event.target.value)',
36487 '(blur)': 'onTouched()',
36488 '(compositionstart)': '_compositionStart()',
36489 '(compositionend)': '_compositionEnd($event.target.value)'
36490 },
36491 providers: [DEFAULT_VALUE_ACCESSOR]
36492 },] },
36493];
36494/**
36495 * @nocollapse
36496 */
36497DefaultValueAccessor.ctorParameters = function () { return [
36498 { type: Renderer2, },
36499 { type: ElementRef, },
36500 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] },] },
36501]; };
36502/**
36503 * @license
36504 * Copyright Google Inc. All Rights Reserved.
36505 *
36506 * Use of this source code is governed by an MIT-style license that can be
36507 * found in the LICENSE file at https://angular.io/license
36508 */
36509/**
36510 * @param {?} validator
36511 * @return {?}
36512 */
36513function normalizeValidator(validator) {
36514 if (((validator)).validate) {
36515 return function (c) { return ((validator)).validate(c); };
36516 }
36517 else {
36518 return (validator);
36519 }
36520}
36521/**
36522 * @param {?} validator
36523 * @return {?}
36524 */
36525function normalizeAsyncValidator(validator) {
36526 if (((validator)).validate) {
36527 return function (c) { return ((validator)).validate(c); };
36528 }
36529 else {
36530 return (validator);
36531 }
36532}
36533/**
36534 * @license
36535 * Copyright Google Inc. All Rights Reserved.
36536 *
36537 * Use of this source code is governed by an MIT-style license that can be
36538 * found in the LICENSE file at https://angular.io/license
36539 */
36540var NUMBER_VALUE_ACCESSOR = {
36541 provide: NG_VALUE_ACCESSOR,
36542 useExisting: forwardRef(function () { return NumberValueAccessor; }),
36543 multi: true
36544};
36545/**
36546 * The accessor for writing a number value and listening to changes that is used by the
36547 * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
36548 *
36549 * ### Example
36550 * ```
36551 * <input type="number" [(ngModel)]="age">
36552 * ```
36553 */
36554var NumberValueAccessor = (function () {
36555 /**
36556 * @param {?} _renderer
36557 * @param {?} _elementRef
36558 */
36559 function NumberValueAccessor(_renderer, _elementRef) {
36560 this._renderer = _renderer;
36561 this._elementRef = _elementRef;
36562 this.onChange = function (_) { };
36563 this.onTouched = function () { };
36564 }
36565 /**
36566 * @param {?} value
36567 * @return {?}
36568 */
36569 NumberValueAccessor.prototype.writeValue = function (value) {
36570 // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
36571 var /** @type {?} */ normalizedValue = value == null ? '' : value;
36572 this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
36573 };
36574 /**
36575 * @param {?} fn
36576 * @return {?}
36577 */
36578 NumberValueAccessor.prototype.registerOnChange = function (fn) {
36579 this.onChange = function (value) { fn(value == '' ? null : parseFloat(value)); };
36580 };
36581 /**
36582 * @param {?} fn
36583 * @return {?}
36584 */
36585 NumberValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
36586 /**
36587 * @param {?} isDisabled
36588 * @return {?}
36589 */
36590 NumberValueAccessor.prototype.setDisabledState = function (isDisabled) {
36591 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
36592 };
36593 return NumberValueAccessor;
36594}());
36595NumberValueAccessor.decorators = [
36596 { type: Directive, args: [{
36597 selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
36598 host: {
36599 '(change)': 'onChange($event.target.value)',
36600 '(input)': 'onChange($event.target.value)',
36601 '(blur)': 'onTouched()'
36602 },
36603 providers: [NUMBER_VALUE_ACCESSOR]
36604 },] },
36605];
36606/**
36607 * @nocollapse
36608 */
36609NumberValueAccessor.ctorParameters = function () { return [
36610 { type: Renderer2, },
36611 { type: ElementRef, },
36612]; };
36613/**
36614 * @license
36615 * Copyright Google Inc. All Rights Reserved.
36616 *
36617 * Use of this source code is governed by an MIT-style license that can be
36618 * found in the LICENSE file at https://angular.io/license
36619 */
36620/**
36621 * @return {?}
36622 */
36623function unimplemented() {
36624 throw new Error('unimplemented');
36625}
36626/**
36627 * A base class that all control directive extend.
36628 * It binds a {\@link FormControl} object to a DOM element.
36629 *
36630 * Used internally by Angular forms.
36631 *
36632 * \@stable
36633 * @abstract
36634 */
36635var NgControl = (function (_super) {
36636 __extends$1(NgControl, _super);
36637 function NgControl() {
36638 var _this = _super.apply(this, arguments) || this;
36639 /**
36640 * \@internal
36641 */
36642 _this._parent = null;
36643 _this.name = null;
36644 _this.valueAccessor = null;
36645 /**
36646 * \@internal
36647 */
36648 _this._rawValidators = [];
36649 /**
36650 * \@internal
36651 */
36652 _this._rawAsyncValidators = [];
36653 return _this;
36654 }
36655 Object.defineProperty(NgControl.prototype, "validator", {
36656 /**
36657 * @return {?}
36658 */
36659 get: function () { return (unimplemented()); },
36660 enumerable: true,
36661 configurable: true
36662 });
36663 Object.defineProperty(NgControl.prototype, "asyncValidator", {
36664 /**
36665 * @return {?}
36666 */
36667 get: function () { return (unimplemented()); },
36668 enumerable: true,
36669 configurable: true
36670 });
36671 /**
36672 * @abstract
36673 * @param {?} newValue
36674 * @return {?}
36675 */
36676 NgControl.prototype.viewToModelUpdate = function (newValue) { };
36677 return NgControl;
36678}(AbstractControlDirective));
36679/**
36680 * @license
36681 * Copyright Google Inc. All Rights Reserved.
36682 *
36683 * Use of this source code is governed by an MIT-style license that can be
36684 * found in the LICENSE file at https://angular.io/license
36685 */
36686var RADIO_VALUE_ACCESSOR = {
36687 provide: NG_VALUE_ACCESSOR,
36688 useExisting: forwardRef(function () { return RadioControlValueAccessor; }),
36689 multi: true
36690};
36691/**
36692 * Internal class used by Angular to uncheck radio buttons with the matching name.
36693 */
36694var RadioControlRegistry = (function () {
36695 function RadioControlRegistry() {
36696 this._accessors = [];
36697 }
36698 /**
36699 * @param {?} control
36700 * @param {?} accessor
36701 * @return {?}
36702 */
36703 RadioControlRegistry.prototype.add = function (control, accessor) {
36704 this._accessors.push([control, accessor]);
36705 };
36706 /**
36707 * @param {?} accessor
36708 * @return {?}
36709 */
36710 RadioControlRegistry.prototype.remove = function (accessor) {
36711 for (var /** @type {?} */ i = this._accessors.length - 1; i >= 0; --i) {
36712 if (this._accessors[i][1] === accessor) {
36713 this._accessors.splice(i, 1);
36714 return;
36715 }
36716 }
36717 };
36718 /**
36719 * @param {?} accessor
36720 * @return {?}
36721 */
36722 RadioControlRegistry.prototype.select = function (accessor) {
36723 var _this = this;
36724 this._accessors.forEach(function (c) {
36725 if (_this._isSameGroup(c, accessor) && c[1] !== accessor) {
36726 c[1].fireUncheck(accessor.value);
36727 }
36728 });
36729 };
36730 /**
36731 * @param {?} controlPair
36732 * @param {?} accessor
36733 * @return {?}
36734 */
36735 RadioControlRegistry.prototype._isSameGroup = function (controlPair, accessor) {
36736 if (!controlPair[0].control)
36737 return false;
36738 return controlPair[0]._parent === accessor._control._parent &&
36739 controlPair[1].name === accessor.name;
36740 };
36741 return RadioControlRegistry;
36742}());
36743RadioControlRegistry.decorators = [
36744 { type: Injectable },
36745];
36746/**
36747 * @nocollapse
36748 */
36749RadioControlRegistry.ctorParameters = function () { return []; };
36750/**
36751 * \@whatItDoes Writes radio control values and listens to radio control changes.
36752 *
36753 * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
36754 * to keep the view synced with the {\@link FormControl} model.
36755 *
36756 * \@howToUse
36757 *
36758 * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
36759 * value accessor will be active on any radio control that has a form directive. You do
36760 * **not** need to add a special selector to activate it.
36761 *
36762 * ### How to use radio buttons with form directives
36763 *
36764 * To use radio buttons in a template-driven form, you'll want to ensure that radio buttons
36765 * in the same group have the same `name` attribute. Radio buttons with different `name`
36766 * attributes do not affect each other.
36767 *
36768 * {\@example forms/ts/radioButtons/radio_button_example.ts region='TemplateDriven'}
36769 *
36770 * When using radio buttons in a reactive form, radio buttons in the same group should have the
36771 * same `formControlName`. You can also add a `name` attribute, but it's optional.
36772 *
36773 * {\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
36774 *
36775 * * **npm package**: `\@angular/forms`
36776 *
36777 * \@stable
36778 */
36779var RadioControlValueAccessor = (function () {
36780 /**
36781 * @param {?} _renderer
36782 * @param {?} _elementRef
36783 * @param {?} _registry
36784 * @param {?} _injector
36785 */
36786 function RadioControlValueAccessor(_renderer, _elementRef, _registry, _injector) {
36787 this._renderer = _renderer;
36788 this._elementRef = _elementRef;
36789 this._registry = _registry;
36790 this._injector = _injector;
36791 this.onChange = function () { };
36792 this.onTouched = function () { };
36793 }
36794 /**
36795 * @return {?}
36796 */
36797 RadioControlValueAccessor.prototype.ngOnInit = function () {
36798 this._control = this._injector.get(NgControl);
36799 this._checkName();
36800 this._registry.add(this._control, this);
36801 };
36802 /**
36803 * @return {?}
36804 */
36805 RadioControlValueAccessor.prototype.ngOnDestroy = function () { this._registry.remove(this); };
36806 /**
36807 * @param {?} value
36808 * @return {?}
36809 */
36810 RadioControlValueAccessor.prototype.writeValue = function (value) {
36811 this._state = value === this.value;
36812 this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state);
36813 };
36814 /**
36815 * @param {?} fn
36816 * @return {?}
36817 */
36818 RadioControlValueAccessor.prototype.registerOnChange = function (fn) {
36819 var _this = this;
36820 this._fn = fn;
36821 this.onChange = function () {
36822 fn(_this.value);
36823 _this._registry.select(_this);
36824 };
36825 };
36826 /**
36827 * @param {?} value
36828 * @return {?}
36829 */
36830 RadioControlValueAccessor.prototype.fireUncheck = function (value) { this.writeValue(value); };
36831 /**
36832 * @param {?} fn
36833 * @return {?}
36834 */
36835 RadioControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
36836 /**
36837 * @param {?} isDisabled
36838 * @return {?}
36839 */
36840 RadioControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
36841 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
36842 };
36843 /**
36844 * @return {?}
36845 */
36846 RadioControlValueAccessor.prototype._checkName = function () {
36847 if (this.name && this.formControlName && this.name !== this.formControlName) {
36848 this._throwNameError();
36849 }
36850 if (!this.name && this.formControlName)
36851 this.name = this.formControlName;
36852 };
36853 /**
36854 * @return {?}
36855 */
36856 RadioControlValueAccessor.prototype._throwNameError = function () {
36857 throw new Error("\n If you define both a name and a formControlName attribute on your radio button, their values\n must match. Ex: <input type=\"radio\" formControlName=\"food\" name=\"food\">\n ");
36858 };
36859 return RadioControlValueAccessor;
36860}());
36861RadioControlValueAccessor.decorators = [
36862 { type: Directive, args: [{
36863 selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
36864 host: { '(change)': 'onChange()', '(blur)': 'onTouched()' },
36865 providers: [RADIO_VALUE_ACCESSOR]
36866 },] },
36867];
36868/**
36869 * @nocollapse
36870 */
36871RadioControlValueAccessor.ctorParameters = function () { return [
36872 { type: Renderer2, },
36873 { type: ElementRef, },
36874 { type: RadioControlRegistry, },
36875 { type: Injector, },
36876]; };
36877RadioControlValueAccessor.propDecorators = {
36878 'name': [{ type: Input },],
36879 'formControlName': [{ type: Input },],
36880 'value': [{ type: Input },],
36881};
36882/**
36883 * @license
36884 * Copyright Google Inc. All Rights Reserved.
36885 *
36886 * Use of this source code is governed by an MIT-style license that can be
36887 * found in the LICENSE file at https://angular.io/license
36888 */
36889var RANGE_VALUE_ACCESSOR = {
36890 provide: NG_VALUE_ACCESSOR,
36891 useExisting: forwardRef(function () { return RangeValueAccessor; }),
36892 multi: true
36893};
36894/**
36895 * The accessor for writing a range value and listening to changes that is used by the
36896 * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
36897 *
36898 * ### Example
36899 * ```
36900 * <input type="range" [(ngModel)]="age" >
36901 * ```
36902 */
36903var RangeValueAccessor = (function () {
36904 /**
36905 * @param {?} _renderer
36906 * @param {?} _elementRef
36907 */
36908 function RangeValueAccessor(_renderer, _elementRef) {
36909 this._renderer = _renderer;
36910 this._elementRef = _elementRef;
36911 this.onChange = function (_) { };
36912 this.onTouched = function () { };
36913 }
36914 /**
36915 * @param {?} value
36916 * @return {?}
36917 */
36918 RangeValueAccessor.prototype.writeValue = function (value) {
36919 this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value));
36920 };
36921 /**
36922 * @param {?} fn
36923 * @return {?}
36924 */
36925 RangeValueAccessor.prototype.registerOnChange = function (fn) {
36926 this.onChange = function (value) { fn(value == '' ? null : parseFloat(value)); };
36927 };
36928 /**
36929 * @param {?} fn
36930 * @return {?}
36931 */
36932 RangeValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
36933 /**
36934 * @param {?} isDisabled
36935 * @return {?}
36936 */
36937 RangeValueAccessor.prototype.setDisabledState = function (isDisabled) {
36938 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
36939 };
36940 return RangeValueAccessor;
36941}());
36942RangeValueAccessor.decorators = [
36943 { type: Directive, args: [{
36944 selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
36945 host: {
36946 '(change)': 'onChange($event.target.value)',
36947 '(input)': 'onChange($event.target.value)',
36948 '(blur)': 'onTouched()'
36949 },
36950 providers: [RANGE_VALUE_ACCESSOR]
36951 },] },
36952];
36953/**
36954 * @nocollapse
36955 */
36956RangeValueAccessor.ctorParameters = function () { return [
36957 { type: Renderer2, },
36958 { type: ElementRef, },
36959]; };
36960/**
36961 * @license
36962 * Copyright Google Inc. All Rights Reserved.
36963 *
36964 * Use of this source code is governed by an MIT-style license that can be
36965 * found in the LICENSE file at https://angular.io/license
36966 */
36967var SELECT_VALUE_ACCESSOR = {
36968 provide: NG_VALUE_ACCESSOR,
36969 useExisting: forwardRef(function () { return SelectControlValueAccessor; }),
36970 multi: true
36971};
36972/**
36973 * @param {?} id
36974 * @param {?} value
36975 * @return {?}
36976 */
36977function _buildValueString(id, value) {
36978 if (id == null)
36979 return "" + value;
36980 if (value && typeof value === 'object')
36981 value = 'Object';
36982 return (id + ": " + value).slice(0, 50);
36983}
36984/**
36985 * @param {?} valueString
36986 * @return {?}
36987 */
36988function _extractId(valueString) {
36989 return valueString.split(':')[0];
36990}
36991/**
36992 * \@whatItDoes Writes values and listens to changes on a select element.
36993 *
36994 * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
36995 * to keep the view synced with the {\@link FormControl} model.
36996 *
36997 * \@howToUse
36998 *
36999 * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
37000 * value accessor will be active on any select control that has a form directive. You do
37001 * **not** need to add a special selector to activate it.
37002 *
37003 * ### How to use select controls with form directives
37004 *
37005 * To use a select in a template-driven form, simply add an `ngModel` and a `name`
37006 * attribute to the main `<select>` tag.
37007 *
37008 * If your option values are simple strings, you can bind to the normal `value` property
37009 * on the option. If your option values happen to be objects (and you'd like to save the
37010 * selection in your form as an object), use `ngValue` instead:
37011 *
37012 * {\@example forms/ts/selectControl/select_control_example.ts region='Component'}
37013 *
37014 * In reactive forms, you'll also want to add your form directive (`formControlName` or
37015 * `formControl`) on the main `<select>` tag. Like in the former example, you have the
37016 * choice of binding to the `value` or `ngValue` property on the select's options.
37017 *
37018 * {\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
37019 *
37020 * ### Caveat: Option selection
37021 *
37022 * Angular uses object identity to select option. It's possible for the identities of items
37023 * to change while the data does not. This can happen, for example, if the items are produced
37024 * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
37025 * second response will produce objects with different identities.
37026 *
37027 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
37028 * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
37029 * If `compareWith` is given, Angular selects option by the return value of the function.
37030 *
37031 * #### Syntax
37032 *
37033 * ```
37034 * <select [compareWith]="compareFn" [(ngModel)]="selectedCountries">
37035 * <option *ngFor="let country of countries" [ngValue]="country">
37036 * {{country.name}}
37037 * </option>
37038 * </select>
37039 *
37040 * compareFn(c1: Country, c2: Country): boolean {
37041 * return c1 && c2 ? c1.id === c2.id : c1 === c2;
37042 * }
37043 * ```
37044 *
37045 * Note: We listen to the 'change' event because 'input' events aren't fired
37046 * for selects in Firefox and IE:
37047 * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350
37048 * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/
37049 *
37050 * * **npm package**: `\@angular/forms`
37051 *
37052 * \@stable
37053 */
37054var SelectControlValueAccessor = (function () {
37055 /**
37056 * @param {?} _renderer
37057 * @param {?} _elementRef
37058 */
37059 function SelectControlValueAccessor(_renderer, _elementRef) {
37060 this._renderer = _renderer;
37061 this._elementRef = _elementRef;
37062 /**
37063 * \@internal
37064 */
37065 this._optionMap = new Map();
37066 /**
37067 * \@internal
37068 */
37069 this._idCounter = 0;
37070 this.onChange = function (_) { };
37071 this.onTouched = function () { };
37072 this._compareWith = looseIdentical;
37073 }
37074 Object.defineProperty(SelectControlValueAccessor.prototype, "compareWith", {
37075 /**
37076 * @param {?} fn
37077 * @return {?}
37078 */
37079 set: function (fn) {
37080 if (typeof fn !== 'function') {
37081 throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
37082 }
37083 this._compareWith = fn;
37084 },
37085 enumerable: true,
37086 configurable: true
37087 });
37088 /**
37089 * @param {?} value
37090 * @return {?}
37091 */
37092 SelectControlValueAccessor.prototype.writeValue = function (value) {
37093 this.value = value;
37094 var /** @type {?} */ id = this._getOptionId(value);
37095 if (id == null) {
37096 this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);
37097 }
37098 var /** @type {?} */ valueString = _buildValueString(id, value);
37099 this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString);
37100 };
37101 /**
37102 * @param {?} fn
37103 * @return {?}
37104 */
37105 SelectControlValueAccessor.prototype.registerOnChange = function (fn) {
37106 var _this = this;
37107 this.onChange = function (valueString) {
37108 _this.value = _this._getOptionValue(valueString);
37109 fn(_this.value);
37110 };
37111 };
37112 /**
37113 * @param {?} fn
37114 * @return {?}
37115 */
37116 SelectControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
37117 /**
37118 * @param {?} isDisabled
37119 * @return {?}
37120 */
37121 SelectControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
37122 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
37123 };
37124 /**
37125 * \@internal
37126 * @return {?}
37127 */
37128 SelectControlValueAccessor.prototype._registerOption = function () { return (this._idCounter++).toString(); };
37129 /**
37130 * \@internal
37131 * @param {?} value
37132 * @return {?}
37133 */
37134 SelectControlValueAccessor.prototype._getOptionId = function (value) {
37135 for (var _i = 0, _a = Array.from(this._optionMap.keys()); _i < _a.length; _i++) {
37136 var id = _a[_i];
37137 if (this._compareWith(this._optionMap.get(id), value))
37138 return id;
37139 }
37140 return null;
37141 };
37142 /**
37143 * \@internal
37144 * @param {?} valueString
37145 * @return {?}
37146 */
37147 SelectControlValueAccessor.prototype._getOptionValue = function (valueString) {
37148 var /** @type {?} */ id = _extractId(valueString);
37149 return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
37150 };
37151 return SelectControlValueAccessor;
37152}());
37153SelectControlValueAccessor.decorators = [
37154 { type: Directive, args: [{
37155 selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
37156 host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' },
37157 providers: [SELECT_VALUE_ACCESSOR]
37158 },] },
37159];
37160/**
37161 * @nocollapse
37162 */
37163SelectControlValueAccessor.ctorParameters = function () { return [
37164 { type: Renderer2, },
37165 { type: ElementRef, },
37166]; };
37167SelectControlValueAccessor.propDecorators = {
37168 'compareWith': [{ type: Input },],
37169};
37170/**
37171 * \@whatItDoes Marks `<option>` as dynamic, so Angular can be notified when options change.
37172 *
37173 * \@howToUse
37174 *
37175 * See docs for {\@link SelectControlValueAccessor} for usage examples.
37176 *
37177 * \@stable
37178 */
37179var NgSelectOption = (function () {
37180 /**
37181 * @param {?} _element
37182 * @param {?} _renderer
37183 * @param {?} _select
37184 */
37185 function NgSelectOption(_element, _renderer, _select) {
37186 this._element = _element;
37187 this._renderer = _renderer;
37188 this._select = _select;
37189 if (this._select)
37190 this.id = this._select._registerOption();
37191 }
37192 Object.defineProperty(NgSelectOption.prototype, "ngValue", {
37193 /**
37194 * @param {?} value
37195 * @return {?}
37196 */
37197 set: function (value) {
37198 if (this._select == null)
37199 return;
37200 this._select._optionMap.set(this.id, value);
37201 this._setElementValue(_buildValueString(this.id, value));
37202 this._select.writeValue(this._select.value);
37203 },
37204 enumerable: true,
37205 configurable: true
37206 });
37207 Object.defineProperty(NgSelectOption.prototype, "value", {
37208 /**
37209 * @param {?} value
37210 * @return {?}
37211 */
37212 set: function (value) {
37213 this._setElementValue(value);
37214 if (this._select)
37215 this._select.writeValue(this._select.value);
37216 },
37217 enumerable: true,
37218 configurable: true
37219 });
37220 /**
37221 * \@internal
37222 * @param {?} value
37223 * @return {?}
37224 */
37225 NgSelectOption.prototype._setElementValue = function (value) {
37226 this._renderer.setProperty(this._element.nativeElement, 'value', value);
37227 };
37228 /**
37229 * @return {?}
37230 */
37231 NgSelectOption.prototype.ngOnDestroy = function () {
37232 if (this._select) {
37233 this._select._optionMap.delete(this.id);
37234 this._select.writeValue(this._select.value);
37235 }
37236 };
37237 return NgSelectOption;
37238}());
37239NgSelectOption.decorators = [
37240 { type: Directive, args: [{ selector: 'option' },] },
37241];
37242/**
37243 * @nocollapse
37244 */
37245NgSelectOption.ctorParameters = function () { return [
37246 { type: ElementRef, },
37247 { type: Renderer2, },
37248 { type: SelectControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
37249]; };
37250NgSelectOption.propDecorators = {
37251 'ngValue': [{ type: Input, args: ['ngValue',] },],
37252 'value': [{ type: Input, args: ['value',] },],
37253};
37254/**
37255 * @license
37256 * Copyright Google Inc. All Rights Reserved.
37257 *
37258 * Use of this source code is governed by an MIT-style license that can be
37259 * found in the LICENSE file at https://angular.io/license
37260 */
37261var SELECT_MULTIPLE_VALUE_ACCESSOR = {
37262 provide: NG_VALUE_ACCESSOR,
37263 useExisting: forwardRef(function () { return SelectMultipleControlValueAccessor; }),
37264 multi: true
37265};
37266/**
37267 * @param {?} id
37268 * @param {?} value
37269 * @return {?}
37270 */
37271function _buildValueString$1(id, value) {
37272 if (id == null)
37273 return "" + value;
37274 if (typeof value === 'string')
37275 value = "'" + value + "'";
37276 if (value && typeof value === 'object')
37277 value = 'Object';
37278 return (id + ": " + value).slice(0, 50);
37279}
37280/**
37281 * @param {?} valueString
37282 * @return {?}
37283 */
37284function _extractId$1(valueString) {
37285 return valueString.split(':')[0];
37286}
37287/**
37288 * The accessor for writing a value and listening to changes on a select element.
37289 *
37290 * ### Caveat: Options selection
37291 *
37292 * Angular uses object identity to select options. It's possible for the identities of items
37293 * to change while the data does not. This can happen, for example, if the items are produced
37294 * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
37295 * second response will produce objects with different identities.
37296 *
37297 * To customize the default option comparison algorithm, `<select multiple>` supports `compareWith`
37298 * input. `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
37299 * If `compareWith` is given, Angular selects options by the return value of the function.
37300 *
37301 * #### Syntax
37302 *
37303 * ```
37304 * <select multiple [compareWith]="compareFn" [(ngModel)]="selectedCountries">
37305 * <option *ngFor="let country of countries" [ngValue]="country">
37306 * {{country.name}}
37307 * </option>
37308 * </select>
37309 *
37310 * compareFn(c1: Country, c2: Country): boolean {
37311 * return c1 && c2 ? c1.id === c2.id : c1 === c2;
37312 * }
37313 * ```
37314 *
37315 * \@stable
37316 */
37317var SelectMultipleControlValueAccessor = (function () {
37318 /**
37319 * @param {?} _renderer
37320 * @param {?} _elementRef
37321 */
37322 function SelectMultipleControlValueAccessor(_renderer, _elementRef) {
37323 this._renderer = _renderer;
37324 this._elementRef = _elementRef;
37325 /**
37326 * \@internal
37327 */
37328 this._optionMap = new Map();
37329 /**
37330 * \@internal
37331 */
37332 this._idCounter = 0;
37333 this.onChange = function (_) { };
37334 this.onTouched = function () { };
37335 this._compareWith = looseIdentical;
37336 }
37337 Object.defineProperty(SelectMultipleControlValueAccessor.prototype, "compareWith", {
37338 /**
37339 * @param {?} fn
37340 * @return {?}
37341 */
37342 set: function (fn) {
37343 if (typeof fn !== 'function') {
37344 throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
37345 }
37346 this._compareWith = fn;
37347 },
37348 enumerable: true,
37349 configurable: true
37350 });
37351 /**
37352 * @param {?} value
37353 * @return {?}
37354 */
37355 SelectMultipleControlValueAccessor.prototype.writeValue = function (value) {
37356 var _this = this;
37357 this.value = value;
37358 var /** @type {?} */ optionSelectedStateSetter;
37359 if (Array.isArray(value)) {
37360 // convert values to ids
37361 var /** @type {?} */ ids_1 = value.map(function (v) { return _this._getOptionId(v); });
37362 optionSelectedStateSetter = function (opt, o) { opt._setSelected(ids_1.indexOf(o.toString()) > -1); };
37363 }
37364 else {
37365 optionSelectedStateSetter = function (opt, o) { opt._setSelected(false); };
37366 }
37367 this._optionMap.forEach(optionSelectedStateSetter);
37368 };
37369 /**
37370 * @param {?} fn
37371 * @return {?}
37372 */
37373 SelectMultipleControlValueAccessor.prototype.registerOnChange = function (fn) {
37374 var _this = this;
37375 this.onChange = function (_) {
37376 var /** @type {?} */ selected = [];
37377 if (_.hasOwnProperty('selectedOptions')) {
37378 var /** @type {?} */ options = _.selectedOptions;
37379 for (var /** @type {?} */ i = 0; i < options.length; i++) {
37380 var /** @type {?} */ opt = options.item(i);
37381 var /** @type {?} */ val = _this._getOptionValue(opt.value);
37382 selected.push(val);
37383 }
37384 }
37385 else {
37386 var /** @type {?} */ options = (_.options);
37387 for (var /** @type {?} */ i = 0; i < options.length; i++) {
37388 var /** @type {?} */ opt = options.item(i);
37389 if (opt.selected) {
37390 var /** @type {?} */ val = _this._getOptionValue(opt.value);
37391 selected.push(val);
37392 }
37393 }
37394 }
37395 _this.value = selected;
37396 fn(selected);
37397 };
37398 };
37399 /**
37400 * @param {?} fn
37401 * @return {?}
37402 */
37403 SelectMultipleControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
37404 /**
37405 * @param {?} isDisabled
37406 * @return {?}
37407 */
37408 SelectMultipleControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
37409 this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
37410 };
37411 /**
37412 * \@internal
37413 * @param {?} value
37414 * @return {?}
37415 */
37416 SelectMultipleControlValueAccessor.prototype._registerOption = function (value) {
37417 var /** @type {?} */ id = (this._idCounter++).toString();
37418 this._optionMap.set(id, value);
37419 return id;
37420 };
37421 /**
37422 * \@internal
37423 * @param {?} value
37424 * @return {?}
37425 */
37426 SelectMultipleControlValueAccessor.prototype._getOptionId = function (value) {
37427 for (var _i = 0, _a = Array.from(this._optionMap.keys()); _i < _a.length; _i++) {
37428 var id = _a[_i];
37429 if (this._compareWith(/** @type {?} */ ((this._optionMap.get(id)))._value, value))
37430 return id;
37431 }
37432 return null;
37433 };
37434 /**
37435 * \@internal
37436 * @param {?} valueString
37437 * @return {?}
37438 */
37439 SelectMultipleControlValueAccessor.prototype._getOptionValue = function (valueString) {
37440 var /** @type {?} */ id = _extractId$1(valueString);
37441 return this._optionMap.has(id) ? ((this._optionMap.get(id)))._value : valueString;
37442 };
37443 return SelectMultipleControlValueAccessor;
37444}());
37445SelectMultipleControlValueAccessor.decorators = [
37446 { type: Directive, args: [{
37447 selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
37448 host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' },
37449 providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
37450 },] },
37451];
37452/**
37453 * @nocollapse
37454 */
37455SelectMultipleControlValueAccessor.ctorParameters = function () { return [
37456 { type: Renderer2, },
37457 { type: ElementRef, },
37458]; };
37459SelectMultipleControlValueAccessor.propDecorators = {
37460 'compareWith': [{ type: Input },],
37461};
37462/**
37463 * Marks `<option>` as dynamic, so Angular can be notified when options change.
37464 *
37465 * ### Example
37466 *
37467 * ```
37468 * <select multiple name="city" ngModel>
37469 * <option *ngFor="let c of cities" [value]="c"></option>
37470 * </select>
37471 * ```
37472 */
37473var NgSelectMultipleOption = (function () {
37474 /**
37475 * @param {?} _element
37476 * @param {?} _renderer
37477 * @param {?} _select
37478 */
37479 function NgSelectMultipleOption(_element, _renderer, _select) {
37480 this._element = _element;
37481 this._renderer = _renderer;
37482 this._select = _select;
37483 if (this._select) {
37484 this.id = this._select._registerOption(this);
37485 }
37486 }
37487 Object.defineProperty(NgSelectMultipleOption.prototype, "ngValue", {
37488 /**
37489 * @param {?} value
37490 * @return {?}
37491 */
37492 set: function (value) {
37493 if (this._select == null)
37494 return;
37495 this._value = value;
37496 this._setElementValue(_buildValueString$1(this.id, value));
37497 this._select.writeValue(this._select.value);
37498 },
37499 enumerable: true,
37500 configurable: true
37501 });
37502 Object.defineProperty(NgSelectMultipleOption.prototype, "value", {
37503 /**
37504 * @param {?} value
37505 * @return {?}
37506 */
37507 set: function (value) {
37508 if (this._select) {
37509 this._value = value;
37510 this._setElementValue(_buildValueString$1(this.id, value));
37511 this._select.writeValue(this._select.value);
37512 }
37513 else {
37514 this._setElementValue(value);
37515 }
37516 },
37517 enumerable: true,
37518 configurable: true
37519 });
37520 /**
37521 * \@internal
37522 * @param {?} value
37523 * @return {?}
37524 */
37525 NgSelectMultipleOption.prototype._setElementValue = function (value) {
37526 this._renderer.setProperty(this._element.nativeElement, 'value', value);
37527 };
37528 /**
37529 * \@internal
37530 * @param {?} selected
37531 * @return {?}
37532 */
37533 NgSelectMultipleOption.prototype._setSelected = function (selected) {
37534 this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
37535 };
37536 /**
37537 * @return {?}
37538 */
37539 NgSelectMultipleOption.prototype.ngOnDestroy = function () {
37540 if (this._select) {
37541 this._select._optionMap.delete(this.id);
37542 this._select.writeValue(this._select.value);
37543 }
37544 };
37545 return NgSelectMultipleOption;
37546}());
37547NgSelectMultipleOption.decorators = [
37548 { type: Directive, args: [{ selector: 'option' },] },
37549];
37550/**
37551 * @nocollapse
37552 */
37553NgSelectMultipleOption.ctorParameters = function () { return [
37554 { type: ElementRef, },
37555 { type: Renderer2, },
37556 { type: SelectMultipleControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
37557]; };
37558NgSelectMultipleOption.propDecorators = {
37559 'ngValue': [{ type: Input, args: ['ngValue',] },],
37560 'value': [{ type: Input, args: ['value',] },],
37561};
37562/**
37563 * @license
37564 * Copyright Google Inc. All Rights Reserved.
37565 *
37566 * Use of this source code is governed by an MIT-style license that can be
37567 * found in the LICENSE file at https://angular.io/license
37568 */
37569/**
37570 * @param {?} name
37571 * @param {?} parent
37572 * @return {?}
37573 */
37574function controlPath(name, parent) {
37575 return ((parent.path)).concat([name]);
37576}
37577/**
37578 * @param {?} control
37579 * @param {?} dir
37580 * @return {?}
37581 */
37582function setUpControl(control, dir) {
37583 if (!control)
37584 _throwError$1(dir, 'Cannot find control with');
37585 if (!dir.valueAccessor)
37586 _throwError$1(dir, 'No value accessor for form control with');
37587 control.validator = Validators.compose([/** @type {?} */ ((control.validator)), dir.validator]);
37588 control.asyncValidator = Validators.composeAsync([/** @type {?} */ ((control.asyncValidator)), dir.asyncValidator]); /** @type {?} */
37589 ((dir.valueAccessor)).writeValue(control.value); /** @type {?} */
37590 ((
37591 // view -> model
37592 dir.valueAccessor)).registerOnChange(function (newValue) {
37593 dir.viewToModelUpdate(newValue);
37594 control.markAsDirty();
37595 control.setValue(newValue, { emitModelToViewChange: false });
37596 }); /** @type {?} */
37597 ((
37598 // touched
37599 dir.valueAccessor)).registerOnTouched(function () { return control.markAsTouched(); });
37600 control.registerOnChange(function (newValue, emitModelEvent) {
37601 ((
37602 // control -> view
37603 dir.valueAccessor)).writeValue(newValue);
37604 // control -> ngModel
37605 if (emitModelEvent)
37606 dir.viewToModelUpdate(newValue);
37607 });
37608 if (((dir.valueAccessor)).setDisabledState) {
37609 control.registerOnDisabledChange(function (isDisabled) { /** @type {?} */ ((((dir.valueAccessor)).setDisabledState))(isDisabled); });
37610 }
37611 // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
37612 dir._rawValidators.forEach(function (validator) {
37613 if (((validator)).registerOnValidatorChange)
37614 ((((validator)).registerOnValidatorChange))(function () { return control.updateValueAndValidity(); });
37615 });
37616 dir._rawAsyncValidators.forEach(function (validator) {
37617 if (((validator)).registerOnValidatorChange)
37618 ((((validator)).registerOnValidatorChange))(function () { return control.updateValueAndValidity(); });
37619 });
37620}
37621/**
37622 * @param {?} control
37623 * @param {?} dir
37624 * @return {?}
37625 */
37626function cleanUpControl(control, dir) {
37627 ((dir.valueAccessor)).registerOnChange(function () { return _noControlError(dir); }); /** @type {?} */
37628 ((dir.valueAccessor)).registerOnTouched(function () { return _noControlError(dir); });
37629 dir._rawValidators.forEach(function (validator) {
37630 if (validator.registerOnValidatorChange) {
37631 validator.registerOnValidatorChange(null);
37632 }
37633 });
37634 dir._rawAsyncValidators.forEach(function (validator) {
37635 if (validator.registerOnValidatorChange) {
37636 validator.registerOnValidatorChange(null);
37637 }
37638 });
37639 if (control)
37640 control._clearChangeFns();
37641}
37642/**
37643 * @param {?} control
37644 * @param {?} dir
37645 * @return {?}
37646 */
37647function setUpFormContainer(control, dir) {
37648 if (control == null)
37649 _throwError$1(dir, 'Cannot find control with');
37650 control.validator = Validators.compose([control.validator, dir.validator]);
37651 control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
37652}
37653/**
37654 * @param {?} dir
37655 * @return {?}
37656 */
37657function _noControlError(dir) {
37658 return _throwError$1(dir, 'There is no FormControl instance attached to form control element with');
37659}
37660/**
37661 * @param {?} dir
37662 * @param {?} message
37663 * @return {?}
37664 */
37665function _throwError$1(dir, message) {
37666 var /** @type {?} */ messageEnd;
37667 if (((dir.path)).length > 1) {
37668 messageEnd = "path: '" + ((dir.path)).join(' -> ') + "'";
37669 }
37670 else if (((dir.path))[0]) {
37671 messageEnd = "name: '" + dir.path + "'";
37672 }
37673 else {
37674 messageEnd = 'unspecified name attribute';
37675 }
37676 throw new Error(message + " " + messageEnd);
37677}
37678/**
37679 * @param {?} validators
37680 * @return {?}
37681 */
37682function composeValidators(validators) {
37683 return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
37684}
37685/**
37686 * @param {?} validators
37687 * @return {?}
37688 */
37689function composeAsyncValidators(validators) {
37690 return validators != null ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
37691 null;
37692}
37693/**
37694 * @param {?} changes
37695 * @param {?} viewModel
37696 * @return {?}
37697 */
37698function isPropertyUpdated(changes, viewModel) {
37699 if (!changes.hasOwnProperty('model'))
37700 return false;
37701 var /** @type {?} */ change = changes['model'];
37702 if (change.isFirstChange())
37703 return true;
37704 return !looseIdentical(viewModel, change.currentValue);
37705}
37706var BUILTIN_ACCESSORS = [
37707 CheckboxControlValueAccessor,
37708 RangeValueAccessor,
37709 NumberValueAccessor,
37710 SelectControlValueAccessor,
37711 SelectMultipleControlValueAccessor,
37712 RadioControlValueAccessor,
37713];
37714/**
37715 * @param {?} valueAccessor
37716 * @return {?}
37717 */
37718function isBuiltInAccessor(valueAccessor) {
37719 return BUILTIN_ACCESSORS.some(function (a) { return valueAccessor.constructor === a; });
37720}
37721/**
37722 * @param {?} dir
37723 * @param {?} valueAccessors
37724 * @return {?}
37725 */
37726function selectValueAccessor(dir, valueAccessors) {
37727 if (!valueAccessors)
37728 return null;
37729 var /** @type {?} */ defaultAccessor = undefined;
37730 var /** @type {?} */ builtinAccessor = undefined;
37731 var /** @type {?} */ customAccessor = undefined;
37732 valueAccessors.forEach(function (v) {
37733 if (v.constructor === DefaultValueAccessor) {
37734 defaultAccessor = v;
37735 }
37736 else if (isBuiltInAccessor(v)) {
37737 if (builtinAccessor)
37738 _throwError$1(dir, 'More than one built-in value accessor matches form control with');
37739 builtinAccessor = v;
37740 }
37741 else {
37742 if (customAccessor)
37743 _throwError$1(dir, 'More than one custom value accessor matches form control with');
37744 customAccessor = v;
37745 }
37746 });
37747 if (customAccessor)
37748 return customAccessor;
37749 if (builtinAccessor)
37750 return builtinAccessor;
37751 if (defaultAccessor)
37752 return defaultAccessor;
37753 _throwError$1(dir, 'No valid value accessor for form control with');
37754 return null;
37755}
37756/**
37757 * @license
37758 * Copyright Google Inc. All Rights Reserved.
37759 *
37760 * Use of this source code is governed by an MIT-style license that can be
37761 * found in the LICENSE file at https://angular.io/license
37762 */
37763/**
37764 * This is a base class for code shared between {\@link NgModelGroup} and {\@link FormGroupName}.
37765 *
37766 * \@stable
37767 */
37768var AbstractFormGroupDirective = (function (_super) {
37769 __extends$1(AbstractFormGroupDirective, _super);
37770 function AbstractFormGroupDirective() {
37771 return _super !== null && _super.apply(this, arguments) || this;
37772 }
37773 /**
37774 * @return {?}
37775 */
37776 AbstractFormGroupDirective.prototype.ngOnInit = function () {
37777 this._checkParentType(); /** @type {?} */
37778 ((this.formDirective)).addFormGroup(this);
37779 };
37780 /**
37781 * @return {?}
37782 */
37783 AbstractFormGroupDirective.prototype.ngOnDestroy = function () {
37784 if (this.formDirective) {
37785 this.formDirective.removeFormGroup(this);
37786 }
37787 };
37788 Object.defineProperty(AbstractFormGroupDirective.prototype, "control", {
37789 /**
37790 * Get the {\@link FormGroup} backing this binding.
37791 * @return {?}
37792 */
37793 get: function () { return ((this.formDirective)).getFormGroup(this); },
37794 enumerable: true,
37795 configurable: true
37796 });
37797 Object.defineProperty(AbstractFormGroupDirective.prototype, "path", {
37798 /**
37799 * Get the path to this control group.
37800 * @return {?}
37801 */
37802 get: function () { return controlPath(this.name, this._parent); },
37803 enumerable: true,
37804 configurable: true
37805 });
37806 Object.defineProperty(AbstractFormGroupDirective.prototype, "formDirective", {
37807 /**
37808 * Get the {\@link Form} to which this group belongs.
37809 * @return {?}
37810 */
37811 get: function () { return this._parent ? this._parent.formDirective : null; },
37812 enumerable: true,
37813 configurable: true
37814 });
37815 Object.defineProperty(AbstractFormGroupDirective.prototype, "validator", {
37816 /**
37817 * @return {?}
37818 */
37819 get: function () { return composeValidators(this._validators); },
37820 enumerable: true,
37821 configurable: true
37822 });
37823 Object.defineProperty(AbstractFormGroupDirective.prototype, "asyncValidator", {
37824 /**
37825 * @return {?}
37826 */
37827 get: function () {
37828 return composeAsyncValidators(this._asyncValidators);
37829 },
37830 enumerable: true,
37831 configurable: true
37832 });
37833 /**
37834 * \@internal
37835 * @return {?}
37836 */
37837 AbstractFormGroupDirective.prototype._checkParentType = function () { };
37838 return AbstractFormGroupDirective;
37839}(ControlContainer));
37840/**
37841 * @license
37842 * Copyright Google Inc. All Rights Reserved.
37843 *
37844 * Use of this source code is governed by an MIT-style license that can be
37845 * found in the LICENSE file at https://angular.io/license
37846 */
37847var AbstractControlStatus = (function () {
37848 /**
37849 * @param {?} cd
37850 */
37851 function AbstractControlStatus(cd) {
37852 this._cd = cd;
37853 }
37854 Object.defineProperty(AbstractControlStatus.prototype, "ngClassUntouched", {
37855 /**
37856 * @return {?}
37857 */
37858 get: function () { return this._cd.control ? this._cd.control.untouched : false; },
37859 enumerable: true,
37860 configurable: true
37861 });
37862 Object.defineProperty(AbstractControlStatus.prototype, "ngClassTouched", {
37863 /**
37864 * @return {?}
37865 */
37866 get: function () { return this._cd.control ? this._cd.control.touched : false; },
37867 enumerable: true,
37868 configurable: true
37869 });
37870 Object.defineProperty(AbstractControlStatus.prototype, "ngClassPristine", {
37871 /**
37872 * @return {?}
37873 */
37874 get: function () { return this._cd.control ? this._cd.control.pristine : false; },
37875 enumerable: true,
37876 configurable: true
37877 });
37878 Object.defineProperty(AbstractControlStatus.prototype, "ngClassDirty", {
37879 /**
37880 * @return {?}
37881 */
37882 get: function () { return this._cd.control ? this._cd.control.dirty : false; },
37883 enumerable: true,
37884 configurable: true
37885 });
37886 Object.defineProperty(AbstractControlStatus.prototype, "ngClassValid", {
37887 /**
37888 * @return {?}
37889 */
37890 get: function () { return this._cd.control ? this._cd.control.valid : false; },
37891 enumerable: true,
37892 configurable: true
37893 });
37894 Object.defineProperty(AbstractControlStatus.prototype, "ngClassInvalid", {
37895 /**
37896 * @return {?}
37897 */
37898 get: function () { return this._cd.control ? this._cd.control.invalid : false; },
37899 enumerable: true,
37900 configurable: true
37901 });
37902 Object.defineProperty(AbstractControlStatus.prototype, "ngClassPending", {
37903 /**
37904 * @return {?}
37905 */
37906 get: function () { return this._cd.control ? this._cd.control.pending : false; },
37907 enumerable: true,
37908 configurable: true
37909 });
37910 return AbstractControlStatus;
37911}());
37912var ngControlStatusHost = {
37913 '[class.ng-untouched]': 'ngClassUntouched',
37914 '[class.ng-touched]': 'ngClassTouched',
37915 '[class.ng-pristine]': 'ngClassPristine',
37916 '[class.ng-dirty]': 'ngClassDirty',
37917 '[class.ng-valid]': 'ngClassValid',
37918 '[class.ng-invalid]': 'ngClassInvalid',
37919 '[class.ng-pending]': 'ngClassPending',
37920};
37921/**
37922 * Directive automatically applied to Angular form controls that sets CSS classes
37923 * based on control status. The following classes are applied as the properties
37924 * become true:
37925 *
37926 * * ng-valid
37927 * * ng-invalid
37928 * * ng-pending
37929 * * ng-pristine
37930 * * ng-dirty
37931 * * ng-untouched
37932 * * ng-touched
37933 *
37934 * \@stable
37935 */
37936var NgControlStatus = (function (_super) {
37937 __extends$1(NgControlStatus, _super);
37938 /**
37939 * @param {?} cd
37940 */
37941 function NgControlStatus(cd) {
37942 return _super.call(this, cd) || this;
37943 }
37944 return NgControlStatus;
37945}(AbstractControlStatus));
37946NgControlStatus.decorators = [
37947 { type: Directive, args: [{ selector: '[formControlName],[ngModel],[formControl]', host: ngControlStatusHost },] },
37948];
37949/**
37950 * @nocollapse
37951 */
37952NgControlStatus.ctorParameters = function () { return [
37953 { type: NgControl, decorators: [{ type: Self },] },
37954]; };
37955/**
37956 * Directive automatically applied to Angular form groups that sets CSS classes
37957 * based on control status (valid/invalid/dirty/etc).
37958 *
37959 * \@stable
37960 */
37961var NgControlStatusGroup = (function (_super) {
37962 __extends$1(NgControlStatusGroup, _super);
37963 /**
37964 * @param {?} cd
37965 */
37966 function NgControlStatusGroup(cd) {
37967 return _super.call(this, cd) || this;
37968 }
37969 return NgControlStatusGroup;
37970}(AbstractControlStatus));
37971NgControlStatusGroup.decorators = [
37972 { type: Directive, args: [{
37973 selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
37974 host: ngControlStatusHost
37975 },] },
37976];
37977/**
37978 * @nocollapse
37979 */
37980NgControlStatusGroup.ctorParameters = function () { return [
37981 { type: ControlContainer, decorators: [{ type: Self },] },
37982]; };
37983/**
37984 * @license
37985 * Copyright Google Inc. All Rights Reserved.
37986 *
37987 * Use of this source code is governed by an MIT-style license that can be
37988 * found in the LICENSE file at https://angular.io/license
37989 */
37990/**
37991 * Indicates that a FormControl is valid, i.e. that no errors exist in the input value.
37992 */
37993var VALID = 'VALID';
37994/**
37995 * Indicates that a FormControl is invalid, i.e. that an error exists in the input value.
37996 */
37997var INVALID = 'INVALID';
37998/**
37999 * Indicates that a FormControl is pending, i.e. that async validation is occurring and
38000 * errors are not yet available for the input value.
38001 */
38002var PENDING = 'PENDING';
38003/**
38004 * Indicates that a FormControl is disabled, i.e. that the control is exempt from ancestor
38005 * calculations of validity or value.
38006 */
38007var DISABLED = 'DISABLED';
38008/**
38009 * @param {?} control
38010 * @param {?} path
38011 * @param {?} delimiter
38012 * @return {?}
38013 */
38014function _find(control, path, delimiter) {
38015 if (path == null)
38016 return null;
38017 if (!(path instanceof Array)) {
38018 path = ((path)).split(delimiter);
38019 }
38020 if (path instanceof Array && (path.length === 0))
38021 return null;
38022 return ((path)).reduce(function (v, name) {
38023 if (v instanceof FormGroup) {
38024 return v.controls[name] || null;
38025 }
38026 if (v instanceof FormArray) {
38027 return v.at(/** @type {?} */ (name)) || null;
38028 }
38029 return null;
38030 }, control);
38031}
38032/**
38033 * @param {?=} validator
38034 * @return {?}
38035 */
38036function coerceToValidator(validator) {
38037 return Array.isArray(validator) ? composeValidators(validator) : validator || null;
38038}
38039/**
38040 * @param {?=} asyncValidator
38041 * @return {?}
38042 */
38043function coerceToAsyncValidator(asyncValidator) {
38044 return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) :
38045 asyncValidator || null;
38046}
38047/**
38048 * \@whatItDoes This is the base class for {\@link FormControl}, {\@link FormGroup}, and
38049 * {\@link FormArray}.
38050 *
38051 * It provides some of the shared behavior that all controls and groups of controls have, like
38052 * running validators, calculating status, and resetting state. It also defines the properties
38053 * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
38054 * instantiated directly.
38055 *
38056 * \@stable
38057 * @abstract
38058 */
38059var AbstractControl = (function () {
38060 /**
38061 * @param {?} validator
38062 * @param {?} asyncValidator
38063 */
38064 function AbstractControl(validator, asyncValidator) {
38065 this.validator = validator;
38066 this.asyncValidator = asyncValidator;
38067 /**
38068 * \@internal
38069 */
38070 this._onCollectionChange = function () { };
38071 this._pristine = true;
38072 this._touched = false;
38073 /**
38074 * \@internal
38075 */
38076 this._onDisabledChange = [];
38077 }
38078 Object.defineProperty(AbstractControl.prototype, "value", {
38079 /**
38080 * The value of the control.
38081 * @return {?}
38082 */
38083 get: function () { return this._value; },
38084 enumerable: true,
38085 configurable: true
38086 });
38087 Object.defineProperty(AbstractControl.prototype, "parent", {
38088 /**
38089 * The parent control.
38090 * @return {?}
38091 */
38092 get: function () { return this._parent; },
38093 enumerable: true,
38094 configurable: true
38095 });
38096 Object.defineProperty(AbstractControl.prototype, "status", {
38097 /**
38098 * The validation status of the control. There are four possible
38099 * validation statuses:
38100 *
38101 * * **VALID**: control has passed all validation checks
38102 * * **INVALID**: control has failed at least one validation check
38103 * * **PENDING**: control is in the midst of conducting a validation check
38104 * * **DISABLED**: control is exempt from validation checks
38105 *
38106 * These statuses are mutually exclusive, so a control cannot be
38107 * both valid AND invalid or invalid AND disabled.
38108 * @return {?}
38109 */
38110 get: function () { return this._status; },
38111 enumerable: true,
38112 configurable: true
38113 });
38114 Object.defineProperty(AbstractControl.prototype, "valid", {
38115 /**
38116 * A control is `valid` when its `status === VALID`.
38117 *
38118 * In order to have this status, the control must have passed all its
38119 * validation checks.
38120 * @return {?}
38121 */
38122 get: function () { return this._status === VALID; },
38123 enumerable: true,
38124 configurable: true
38125 });
38126 Object.defineProperty(AbstractControl.prototype, "invalid", {
38127 /**
38128 * A control is `invalid` when its `status === INVALID`.
38129 *
38130 * In order to have this status, the control must have failed
38131 * at least one of its validation checks.
38132 * @return {?}
38133 */
38134 get: function () { return this._status === INVALID; },
38135 enumerable: true,
38136 configurable: true
38137 });
38138 Object.defineProperty(AbstractControl.prototype, "pending", {
38139 /**
38140 * A control is `pending` when its `status === PENDING`.
38141 *
38142 * In order to have this status, the control must be in the
38143 * middle of conducting a validation check.
38144 * @return {?}
38145 */
38146 get: function () { return this._status == PENDING; },
38147 enumerable: true,
38148 configurable: true
38149 });
38150 Object.defineProperty(AbstractControl.prototype, "disabled", {
38151 /**
38152 * A control is `disabled` when its `status === DISABLED`.
38153 *
38154 * Disabled controls are exempt from validation checks and
38155 * are not included in the aggregate value of their ancestor
38156 * controls.
38157 * @return {?}
38158 */
38159 get: function () { return this._status === DISABLED; },
38160 enumerable: true,
38161 configurable: true
38162 });
38163 Object.defineProperty(AbstractControl.prototype, "enabled", {
38164 /**
38165 * A control is `enabled` as long as its `status !== DISABLED`.
38166 *
38167 * In other words, it has a status of `VALID`, `INVALID`, or
38168 * `PENDING`.
38169 * @return {?}
38170 */
38171 get: function () { return this._status !== DISABLED; },
38172 enumerable: true,
38173 configurable: true
38174 });
38175 Object.defineProperty(AbstractControl.prototype, "errors", {
38176 /**
38177 * Returns any errors generated by failing validation. If there
38178 * are no errors, it will return null.
38179 * @return {?}
38180 */
38181 get: function () { return this._errors; },
38182 enumerable: true,
38183 configurable: true
38184 });
38185 Object.defineProperty(AbstractControl.prototype, "pristine", {
38186 /**
38187 * A control is `pristine` if the user has not yet changed
38188 * the value in the UI.
38189 *
38190 * Note that programmatic changes to a control's value will
38191 * *not* mark it dirty.
38192 * @return {?}
38193 */
38194 get: function () { return this._pristine; },
38195 enumerable: true,
38196 configurable: true
38197 });
38198 Object.defineProperty(AbstractControl.prototype, "dirty", {
38199 /**
38200 * A control is `dirty` if the user has changed the value
38201 * in the UI.
38202 *
38203 * Note that programmatic changes to a control's value will
38204 * *not* mark it dirty.
38205 * @return {?}
38206 */
38207 get: function () { return !this.pristine; },
38208 enumerable: true,
38209 configurable: true
38210 });
38211 Object.defineProperty(AbstractControl.prototype, "touched", {
38212 /**
38213 * A control is marked `touched` once the user has triggered
38214 * a `blur` event on it.
38215 * @return {?}
38216 */
38217 get: function () { return this._touched; },
38218 enumerable: true,
38219 configurable: true
38220 });
38221 Object.defineProperty(AbstractControl.prototype, "untouched", {
38222 /**
38223 * A control is `untouched` if the user has not yet triggered
38224 * a `blur` event on it.
38225 * @return {?}
38226 */
38227 get: function () { return !this._touched; },
38228 enumerable: true,
38229 configurable: true
38230 });
38231 Object.defineProperty(AbstractControl.prototype, "valueChanges", {
38232 /**
38233 * Emits an event every time the value of the control changes, in
38234 * the UI or programmatically.
38235 * @return {?}
38236 */
38237 get: function () { return this._valueChanges; },
38238 enumerable: true,
38239 configurable: true
38240 });
38241 Object.defineProperty(AbstractControl.prototype, "statusChanges", {
38242 /**
38243 * Emits an event every time the validation status of the control
38244 * is re-calculated.
38245 * @return {?}
38246 */
38247 get: function () { return this._statusChanges; },
38248 enumerable: true,
38249 configurable: true
38250 });
38251 /**
38252 * Sets the synchronous validators that are active on this control. Calling
38253 * this will overwrite any existing sync validators.
38254 * @param {?} newValidator
38255 * @return {?}
38256 */
38257 AbstractControl.prototype.setValidators = function (newValidator) {
38258 this.validator = coerceToValidator(newValidator);
38259 };
38260 /**
38261 * Sets the async validators that are active on this control. Calling this
38262 * will overwrite any existing async validators.
38263 * @param {?} newValidator
38264 * @return {?}
38265 */
38266 AbstractControl.prototype.setAsyncValidators = function (newValidator) {
38267 this.asyncValidator = coerceToAsyncValidator(newValidator);
38268 };
38269 /**
38270 * Empties out the sync validator list.
38271 * @return {?}
38272 */
38273 AbstractControl.prototype.clearValidators = function () { this.validator = null; };
38274 /**
38275 * Empties out the async validator list.
38276 * @return {?}
38277 */
38278 AbstractControl.prototype.clearAsyncValidators = function () { this.asyncValidator = null; };
38279 /**
38280 * Marks the control as `touched`.
38281 *
38282 * This will also mark all direct ancestors as `touched` to maintain
38283 * the model.
38284 * @param {?=} opts
38285 * @return {?}
38286 */
38287 AbstractControl.prototype.markAsTouched = function (opts) {
38288 if (opts === void 0) { opts = {}; }
38289 this._touched = true;
38290 if (this._parent && !opts.onlySelf) {
38291 this._parent.markAsTouched(opts);
38292 }
38293 };
38294 /**
38295 * Marks the control as `untouched`.
38296 *
38297 * If the control has any children, it will also mark all children as `untouched`
38298 * to maintain the model, and re-calculate the `touched` status of all parent
38299 * controls.
38300 * @param {?=} opts
38301 * @return {?}
38302 */
38303 AbstractControl.prototype.markAsUntouched = function (opts) {
38304 if (opts === void 0) { opts = {}; }
38305 this._touched = false;
38306 this._forEachChild(function (control) { control.markAsUntouched({ onlySelf: true }); });
38307 if (this._parent && !opts.onlySelf) {
38308 this._parent._updateTouched(opts);
38309 }
38310 };
38311 /**
38312 * Marks the control as `dirty`.
38313 *
38314 * This will also mark all direct ancestors as `dirty` to maintain
38315 * the model.
38316 * @param {?=} opts
38317 * @return {?}
38318 */
38319 AbstractControl.prototype.markAsDirty = function (opts) {
38320 if (opts === void 0) { opts = {}; }
38321 this._pristine = false;
38322 if (this._parent && !opts.onlySelf) {
38323 this._parent.markAsDirty(opts);
38324 }
38325 };
38326 /**
38327 * Marks the control as `pristine`.
38328 *
38329 * If the control has any children, it will also mark all children as `pristine`
38330 * to maintain the model, and re-calculate the `pristine` status of all parent
38331 * controls.
38332 * @param {?=} opts
38333 * @return {?}
38334 */
38335 AbstractControl.prototype.markAsPristine = function (opts) {
38336 if (opts === void 0) { opts = {}; }
38337 this._pristine = true;
38338 this._forEachChild(function (control) { control.markAsPristine({ onlySelf: true }); });
38339 if (this._parent && !opts.onlySelf) {
38340 this._parent._updatePristine(opts);
38341 }
38342 };
38343 /**
38344 * Marks the control as `pending`.
38345 * @param {?=} opts
38346 * @return {?}
38347 */
38348 AbstractControl.prototype.markAsPending = function (opts) {
38349 if (opts === void 0) { opts = {}; }
38350 this._status = PENDING;
38351 if (this._parent && !opts.onlySelf) {
38352 this._parent.markAsPending(opts);
38353 }
38354 };
38355 /**
38356 * Disables the control. This means the control will be exempt from validation checks and
38357 * excluded from the aggregate value of any parent. Its status is `DISABLED`.
38358 *
38359 * If the control has children, all children will be disabled to maintain the model.
38360 * @param {?=} opts
38361 * @return {?}
38362 */
38363 AbstractControl.prototype.disable = function (opts) {
38364 if (opts === void 0) { opts = {}; }
38365 this._status = DISABLED;
38366 this._errors = null;
38367 this._forEachChild(function (control) { control.disable({ onlySelf: true }); });
38368 this._updateValue();
38369 if (opts.emitEvent !== false) {
38370 this._valueChanges.emit(this._value);
38371 this._statusChanges.emit(this._status);
38372 }
38373 this._updateAncestors(!!opts.onlySelf);
38374 this._onDisabledChange.forEach(function (changeFn) { return changeFn(true); });
38375 };
38376 /**
38377 * Enables the control. This means the control will be included in validation checks and
38378 * the aggregate value of its parent. Its status is re-calculated based on its value and
38379 * its validators.
38380 *
38381 * If the control has children, all children will be enabled.
38382 * @param {?=} opts
38383 * @return {?}
38384 */
38385 AbstractControl.prototype.enable = function (opts) {
38386 if (opts === void 0) { opts = {}; }
38387 this._status = VALID;
38388 this._forEachChild(function (control) { control.enable({ onlySelf: true }); });
38389 this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
38390 this._updateAncestors(!!opts.onlySelf);
38391 this._onDisabledChange.forEach(function (changeFn) { return changeFn(false); });
38392 };
38393 /**
38394 * @param {?} onlySelf
38395 * @return {?}
38396 */
38397 AbstractControl.prototype._updateAncestors = function (onlySelf) {
38398 if (this._parent && !onlySelf) {
38399 this._parent.updateValueAndValidity();
38400 this._parent._updatePristine();
38401 this._parent._updateTouched();
38402 }
38403 };
38404 /**
38405 * @param {?} parent
38406 * @return {?}
38407 */
38408 AbstractControl.prototype.setParent = function (parent) { this._parent = parent; };
38409 /**
38410 * Sets the value of the control. Abstract method (implemented in sub-classes).
38411 * @abstract
38412 * @param {?} value
38413 * @param {?=} options
38414 * @return {?}
38415 */
38416 AbstractControl.prototype.setValue = function (value, options) { };
38417 /**
38418 * Patches the value of the control. Abstract method (implemented in sub-classes).
38419 * @abstract
38420 * @param {?} value
38421 * @param {?=} options
38422 * @return {?}
38423 */
38424 AbstractControl.prototype.patchValue = function (value, options) { };
38425 /**
38426 * Resets the control. Abstract method (implemented in sub-classes).
38427 * @abstract
38428 * @param {?=} value
38429 * @param {?=} options
38430 * @return {?}
38431 */
38432 AbstractControl.prototype.reset = function (value, options) { };
38433 /**
38434 * Re-calculates the value and validation status of the control.
38435 *
38436 * By default, it will also update the value and validity of its ancestors.
38437 * @param {?=} opts
38438 * @return {?}
38439 */
38440 AbstractControl.prototype.updateValueAndValidity = function (opts) {
38441 if (opts === void 0) { opts = {}; }
38442 this._setInitialStatus();
38443 this._updateValue();
38444 if (this.enabled) {
38445 this._cancelExistingSubscription();
38446 this._errors = this._runValidator();
38447 this._status = this._calculateStatus();
38448 if (this._status === VALID || this._status === PENDING) {
38449 this._runAsyncValidator(opts.emitEvent);
38450 }
38451 }
38452 if (opts.emitEvent !== false) {
38453 this._valueChanges.emit(this._value);
38454 this._statusChanges.emit(this._status);
38455 }
38456 if (this._parent && !opts.onlySelf) {
38457 this._parent.updateValueAndValidity(opts);
38458 }
38459 };
38460 /**
38461 * \@internal
38462 * @param {?=} opts
38463 * @return {?}
38464 */
38465 AbstractControl.prototype._updateTreeValidity = function (opts) {
38466 if (opts === void 0) { opts = { emitEvent: true }; }
38467 this._forEachChild(function (ctrl) { return ctrl._updateTreeValidity(opts); });
38468 this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
38469 };
38470 /**
38471 * @return {?}
38472 */
38473 AbstractControl.prototype._setInitialStatus = function () { this._status = this._allControlsDisabled() ? DISABLED : VALID; };
38474 /**
38475 * @return {?}
38476 */
38477 AbstractControl.prototype._runValidator = function () {
38478 return this.validator ? this.validator(this) : null;
38479 };
38480 /**
38481 * @param {?=} emitEvent
38482 * @return {?}
38483 */
38484 AbstractControl.prototype._runAsyncValidator = function (emitEvent) {
38485 var _this = this;
38486 if (this.asyncValidator) {
38487 this._status = PENDING;
38488 var /** @type {?} */ obs = toObservable(this.asyncValidator(this));
38489 this._asyncValidationSubscription =
38490 obs.subscribe(function (errors) { return _this.setErrors(errors, { emitEvent: emitEvent }); });
38491 }
38492 };
38493 /**
38494 * @return {?}
38495 */
38496 AbstractControl.prototype._cancelExistingSubscription = function () {
38497 if (this._asyncValidationSubscription) {
38498 this._asyncValidationSubscription.unsubscribe();
38499 }
38500 };
38501 /**
38502 * Sets errors on a form control.
38503 *
38504 * This is used when validations are run manually by the user, rather than automatically.
38505 *
38506 * Calling `setErrors` will also update the validity of the parent control.
38507 *
38508 * ### Example
38509 *
38510 * ```
38511 * const login = new FormControl("someLogin");
38512 * login.setErrors({
38513 * "notUnique": true
38514 * });
38515 *
38516 * expect(login.valid).toEqual(false);
38517 * expect(login.errors).toEqual({"notUnique": true});
38518 *
38519 * login.setValue("someOtherLogin");
38520 *
38521 * expect(login.valid).toEqual(true);
38522 * ```
38523 * @param {?} errors
38524 * @param {?=} opts
38525 * @return {?}
38526 */
38527 AbstractControl.prototype.setErrors = function (errors, opts) {
38528 if (opts === void 0) { opts = {}; }
38529 this._errors = errors;
38530 this._updateControlsErrors(opts.emitEvent !== false);
38531 };
38532 /**
38533 * Retrieves a child control given the control's name or path.
38534 *
38535 * Paths can be passed in as an array or a string delimited by a dot.
38536 *
38537 * To get a control nested within a `person` sub-group:
38538 *
38539 * * `this.form.get('person.name');`
38540 *
38541 * -OR-
38542 *
38543 * * `this.form.get(['person', 'name']);`
38544 * @param {?} path
38545 * @return {?}
38546 */
38547 AbstractControl.prototype.get = function (path) { return _find(this, path, '.'); };
38548 /**
38549 * Returns error data if the control with the given path has the error specified. Otherwise
38550 * returns null or undefined.
38551 *
38552 * If no path is given, it checks for the error on the present control.
38553 * @param {?} errorCode
38554 * @param {?=} path
38555 * @return {?}
38556 */
38557 AbstractControl.prototype.getError = function (errorCode, path) {
38558 var /** @type {?} */ control = path ? this.get(path) : this;
38559 return control && control._errors ? control._errors[errorCode] : null;
38560 };
38561 /**
38562 * Returns true if the control with the given path has the error specified. Otherwise
38563 * returns false.
38564 *
38565 * If no path is given, it checks for the error on the present control.
38566 * @param {?} errorCode
38567 * @param {?=} path
38568 * @return {?}
38569 */
38570 AbstractControl.prototype.hasError = function (errorCode, path) { return !!this.getError(errorCode, path); };
38571 Object.defineProperty(AbstractControl.prototype, "root", {
38572 /**
38573 * Retrieves the top-level ancestor of this control.
38574 * @return {?}
38575 */
38576 get: function () {
38577 var /** @type {?} */ x = this;
38578 while (x._parent) {
38579 x = x._parent;
38580 }
38581 return x;
38582 },
38583 enumerable: true,
38584 configurable: true
38585 });
38586 /**
38587 * \@internal
38588 * @param {?} emitEvent
38589 * @return {?}
38590 */
38591 AbstractControl.prototype._updateControlsErrors = function (emitEvent) {
38592 this._status = this._calculateStatus();
38593 if (emitEvent) {
38594 this._statusChanges.emit(this._status);
38595 }
38596 if (this._parent) {
38597 this._parent._updateControlsErrors(emitEvent);
38598 }
38599 };
38600 /**
38601 * \@internal
38602 * @return {?}
38603 */
38604 AbstractControl.prototype._initObservables = function () {
38605 this._valueChanges = new EventEmitter();
38606 this._statusChanges = new EventEmitter();
38607 };
38608 /**
38609 * @return {?}
38610 */
38611 AbstractControl.prototype._calculateStatus = function () {
38612 if (this._allControlsDisabled())
38613 return DISABLED;
38614 if (this._errors)
38615 return INVALID;
38616 if (this._anyControlsHaveStatus(PENDING))
38617 return PENDING;
38618 if (this._anyControlsHaveStatus(INVALID))
38619 return INVALID;
38620 return VALID;
38621 };
38622 /**
38623 * \@internal
38624 * @abstract
38625 * @return {?}
38626 */
38627 AbstractControl.prototype._updateValue = function () { };
38628 /**
38629 * \@internal
38630 * @abstract
38631 * @param {?} cb
38632 * @return {?}
38633 */
38634 AbstractControl.prototype._forEachChild = function (cb) { };
38635 /**
38636 * \@internal
38637 * @abstract
38638 * @param {?} condition
38639 * @return {?}
38640 */
38641 AbstractControl.prototype._anyControls = function (condition) { };
38642 /**
38643 * \@internal
38644 * @abstract
38645 * @return {?}
38646 */
38647 AbstractControl.prototype._allControlsDisabled = function () { };
38648 /**
38649 * \@internal
38650 * @param {?} status
38651 * @return {?}
38652 */
38653 AbstractControl.prototype._anyControlsHaveStatus = function (status) {
38654 return this._anyControls(function (control) { return control.status === status; });
38655 };
38656 /**
38657 * \@internal
38658 * @return {?}
38659 */
38660 AbstractControl.prototype._anyControlsDirty = function () {
38661 return this._anyControls(function (control) { return control.dirty; });
38662 };
38663 /**
38664 * \@internal
38665 * @return {?}
38666 */
38667 AbstractControl.prototype._anyControlsTouched = function () {
38668 return this._anyControls(function (control) { return control.touched; });
38669 };
38670 /**
38671 * \@internal
38672 * @param {?=} opts
38673 * @return {?}
38674 */
38675 AbstractControl.prototype._updatePristine = function (opts) {
38676 if (opts === void 0) { opts = {}; }
38677 this._pristine = !this._anyControlsDirty();
38678 if (this._parent && !opts.onlySelf) {
38679 this._parent._updatePristine(opts);
38680 }
38681 };
38682 /**
38683 * \@internal
38684 * @param {?=} opts
38685 * @return {?}
38686 */
38687 AbstractControl.prototype._updateTouched = function (opts) {
38688 if (opts === void 0) { opts = {}; }
38689 this._touched = this._anyControlsTouched();
38690 if (this._parent && !opts.onlySelf) {
38691 this._parent._updateTouched(opts);
38692 }
38693 };
38694 /**
38695 * \@internal
38696 * @param {?} formState
38697 * @return {?}
38698 */
38699 AbstractControl.prototype._isBoxedValue = function (formState) {
38700 return typeof formState === 'object' && formState !== null &&
38701 Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
38702 };
38703 /**
38704 * \@internal
38705 * @param {?} fn
38706 * @return {?}
38707 */
38708 AbstractControl.prototype._registerOnCollectionChange = function (fn) { this._onCollectionChange = fn; };
38709 return AbstractControl;
38710}());
38711/**
38712 * \@whatItDoes Tracks the value and validation status of an individual form control.
38713 *
38714 * It is one of the three fundamental building blocks of Angular forms, along with
38715 * {\@link FormGroup} and {\@link FormArray}.
38716 *
38717 * \@howToUse
38718 *
38719 * When instantiating a {\@link FormControl}, you can pass in an initial value as the
38720 * first argument. Example:
38721 *
38722 * ```ts
38723 * const ctrl = new FormControl('some value');
38724 * console.log(ctrl.value); // 'some value'
38725 * ```
38726 *
38727 * You can also initialize the control with a form state object on instantiation,
38728 * which includes both the value and whether or not the control is disabled.
38729 * You can't use the value key without the disabled key; both are required
38730 * to use this way of initialization.
38731 *
38732 * ```ts
38733 * const ctrl = new FormControl({value: 'n/a', disabled: true});
38734 * console.log(ctrl.value); // 'n/a'
38735 * console.log(ctrl.status); // 'DISABLED'
38736 * ```
38737 *
38738 * To include a sync validator (or an array of sync validators) with the control,
38739 * pass it in as the second argument. Async validators are also supported, but
38740 * have to be passed in separately as the third arg.
38741 *
38742 * ```ts
38743 * const ctrl = new FormControl('', Validators.required);
38744 * console.log(ctrl.value); // ''
38745 * console.log(ctrl.status); // 'INVALID'
38746 * ```
38747 *
38748 * See its superclass, {\@link AbstractControl}, for more properties and methods.
38749 *
38750 * * **npm package**: `\@angular/forms`
38751 *
38752 * \@stable
38753 */
38754var FormControl = (function (_super) {
38755 __extends$1(FormControl, _super);
38756 /**
38757 * @param {?=} formState
38758 * @param {?=} validator
38759 * @param {?=} asyncValidator
38760 */
38761 function FormControl(formState, validator, asyncValidator) {
38762 if (formState === void 0) { formState = null; }
38763 var _this = _super.call(this, coerceToValidator(validator), coerceToAsyncValidator(asyncValidator)) || this;
38764 /**
38765 * \@internal
38766 */
38767 _this._onChange = [];
38768 _this._applyFormState(formState);
38769 _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
38770 _this._initObservables();
38771 return _this;
38772 }
38773 /**
38774 * Set the value of the form control to `value`.
38775 *
38776 * If `onlySelf` is `true`, this change will only affect the validation of this `FormControl`
38777 * and not its parent component. This defaults to false.
38778 *
38779 * If `emitEvent` is `true`, this
38780 * change will cause a `valueChanges` event on the `FormControl` to be emitted. This defaults
38781 * to true (as it falls through to `updateValueAndValidity`).
38782 *
38783 * If `emitModelToViewChange` is `true`, the view will be notified about the new value
38784 * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
38785 * specified.
38786 *
38787 * If `emitViewToModelChange` is `true`, an ngModelChange event will be fired to update the
38788 * model. This is the default behavior if `emitViewToModelChange` is not specified.
38789 * @param {?} value
38790 * @param {?=} options
38791 * @return {?}
38792 */
38793 FormControl.prototype.setValue = function (value, options) {
38794 var _this = this;
38795 if (options === void 0) { options = {}; }
38796 this._value = value;
38797 if (this._onChange.length && options.emitModelToViewChange !== false) {
38798 this._onChange.forEach(function (changeFn) { return changeFn(_this._value, options.emitViewToModelChange !== false); });
38799 }
38800 this.updateValueAndValidity(options);
38801 };
38802 /**
38803 * Patches the value of a control.
38804 *
38805 * This function is functionally the same as {\@link FormControl#setValue} at this level.
38806 * It exists for symmetry with {\@link FormGroup#patchValue} on `FormGroups` and `FormArrays`,
38807 * where it does behave differently.
38808 * @param {?} value
38809 * @param {?=} options
38810 * @return {?}
38811 */
38812 FormControl.prototype.patchValue = function (value, options) {
38813 if (options === void 0) { options = {}; }
38814 this.setValue(value, options);
38815 };
38816 /**
38817 * Resets the form control. This means by default:
38818 *
38819 * * it is marked as `pristine`
38820 * * it is marked as `untouched`
38821 * * value is set to null
38822 *
38823 * You can also reset to a specific form state by passing through a standalone
38824 * value or a form state object that contains both a value and a disabled state
38825 * (these are the only two properties that cannot be calculated).
38826 *
38827 * Ex:
38828 *
38829 * ```ts
38830 * this.control.reset('Nancy');
38831 *
38832 * console.log(this.control.value); // 'Nancy'
38833 * ```
38834 *
38835 * OR
38836 *
38837 * ```
38838 * this.control.reset({value: 'Nancy', disabled: true});
38839 *
38840 * console.log(this.control.value); // 'Nancy'
38841 * console.log(this.control.status); // 'DISABLED'
38842 * ```
38843 * @param {?=} formState
38844 * @param {?=} options
38845 * @return {?}
38846 */
38847 FormControl.prototype.reset = function (formState, options) {
38848 if (formState === void 0) { formState = null; }
38849 if (options === void 0) { options = {}; }
38850 this._applyFormState(formState);
38851 this.markAsPristine(options);
38852 this.markAsUntouched(options);
38853 this.setValue(this._value, options);
38854 };
38855 /**
38856 * \@internal
38857 * @return {?}
38858 */
38859 FormControl.prototype._updateValue = function () { };
38860 /**
38861 * \@internal
38862 * @param {?} condition
38863 * @return {?}
38864 */
38865 FormControl.prototype._anyControls = function (condition) { return false; };
38866 /**
38867 * \@internal
38868 * @return {?}
38869 */
38870 FormControl.prototype._allControlsDisabled = function () { return this.disabled; };
38871 /**
38872 * Register a listener for change events.
38873 * @param {?} fn
38874 * @return {?}
38875 */
38876 FormControl.prototype.registerOnChange = function (fn) { this._onChange.push(fn); };
38877 /**
38878 * \@internal
38879 * @return {?}
38880 */
38881 FormControl.prototype._clearChangeFns = function () {
38882 this._onChange = [];
38883 this._onDisabledChange = [];
38884 this._onCollectionChange = function () { };
38885 };
38886 /**
38887 * Register a listener for disabled events.
38888 * @param {?} fn
38889 * @return {?}
38890 */
38891 FormControl.prototype.registerOnDisabledChange = function (fn) {
38892 this._onDisabledChange.push(fn);
38893 };
38894 /**
38895 * \@internal
38896 * @param {?} cb
38897 * @return {?}
38898 */
38899 FormControl.prototype._forEachChild = function (cb) { };
38900 /**
38901 * @param {?} formState
38902 * @return {?}
38903 */
38904 FormControl.prototype._applyFormState = function (formState) {
38905 if (this._isBoxedValue(formState)) {
38906 this._value = formState.value;
38907 formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) :
38908 this.enable({ onlySelf: true, emitEvent: false });
38909 }
38910 else {
38911 this._value = formState;
38912 }
38913 };
38914 return FormControl;
38915}(AbstractControl));
38916/**
38917 * \@whatItDoes Tracks the value and validity state of a group of {\@link FormControl}
38918 * instances.
38919 *
38920 * A `FormGroup` aggregates the values of each child {\@link FormControl} into one object,
38921 * with each control name as the key. It calculates its status by reducing the statuses
38922 * of its children. For example, if one of the controls in a group is invalid, the entire
38923 * group becomes invalid.
38924 *
38925 * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular,
38926 * along with {\@link FormControl} and {\@link FormArray}.
38927 *
38928 * \@howToUse
38929 *
38930 * When instantiating a {\@link FormGroup}, pass in a collection of child controls as the first
38931 * argument. The key for each child will be the name under which it is registered.
38932 *
38933 * ### Example
38934 *
38935 * ```
38936 * const form = new FormGroup({
38937 * first: new FormControl('Nancy', Validators.minLength(2)),
38938 * last: new FormControl('Drew'),
38939 * });
38940 *
38941 * console.log(form.value); // {first: 'Nancy', last; 'Drew'}
38942 * console.log(form.status); // 'VALID'
38943 * ```
38944 *
38945 * You can also include group-level validators as the second arg, or group-level async
38946 * validators as the third arg. These come in handy when you want to perform validation
38947 * that considers the value of more than one child control.
38948 *
38949 * ### Example
38950 *
38951 * ```
38952 * const form = new FormGroup({
38953 * password: new FormControl('', Validators.minLength(2)),
38954 * passwordConfirm: new FormControl('', Validators.minLength(2)),
38955 * }, passwordMatchValidator);
38956 *
38957 *
38958 * function passwordMatchValidator(g: FormGroup) {
38959 * return g.get('password').value === g.get('passwordConfirm').value
38960 * ? null : {'mismatch': true};
38961 * }
38962 * ```
38963 *
38964 * * **npm package**: `\@angular/forms`
38965 *
38966 * \@stable
38967 */
38968var FormGroup = (function (_super) {
38969 __extends$1(FormGroup, _super);
38970 /**
38971 * @param {?} controls
38972 * @param {?=} validator
38973 * @param {?=} asyncValidator
38974 */
38975 function FormGroup(controls, validator, asyncValidator) {
38976 var _this = _super.call(this, validator || null, asyncValidator || null) || this;
38977 _this.controls = controls;
38978 _this._initObservables();
38979 _this._setUpControls();
38980 _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
38981 return _this;
38982 }
38983 /**
38984 * Registers a control with the group's list of controls.
38985 *
38986 * This method does not update value or validity of the control, so for
38987 * most cases you'll want to use {\@link FormGroup#addControl} instead.
38988 * @param {?} name
38989 * @param {?} control
38990 * @return {?}
38991 */
38992 FormGroup.prototype.registerControl = function (name, control) {
38993 if (this.controls[name])
38994 return this.controls[name];
38995 this.controls[name] = control;
38996 control.setParent(this);
38997 control._registerOnCollectionChange(this._onCollectionChange);
38998 return control;
38999 };
39000 /**
39001 * Add a control to this group.
39002 * @param {?} name
39003 * @param {?} control
39004 * @return {?}
39005 */
39006 FormGroup.prototype.addControl = function (name, control) {
39007 this.registerControl(name, control);
39008 this.updateValueAndValidity();
39009 this._onCollectionChange();
39010 };
39011 /**
39012 * Remove a control from this group.
39013 * @param {?} name
39014 * @return {?}
39015 */
39016 FormGroup.prototype.removeControl = function (name) {
39017 if (this.controls[name])
39018 this.controls[name]._registerOnCollectionChange(function () { });
39019 delete (this.controls[name]);
39020 this.updateValueAndValidity();
39021 this._onCollectionChange();
39022 };
39023 /**
39024 * Replace an existing control.
39025 * @param {?} name
39026 * @param {?} control
39027 * @return {?}
39028 */
39029 FormGroup.prototype.setControl = function (name, control) {
39030 if (this.controls[name])
39031 this.controls[name]._registerOnCollectionChange(function () { });
39032 delete (this.controls[name]);
39033 if (control)
39034 this.registerControl(name, control);
39035 this.updateValueAndValidity();
39036 this._onCollectionChange();
39037 };
39038 /**
39039 * Check whether there is an enabled control with the given name in the group.
39040 *
39041 * It will return false for disabled controls. If you'd like to check for
39042 * existence in the group only, use {\@link AbstractControl#get} instead.
39043 * @param {?} controlName
39044 * @return {?}
39045 */
39046 FormGroup.prototype.contains = function (controlName) {
39047 return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
39048 };
39049 /**
39050 * Sets the value of the {\@link FormGroup}. It accepts an object that matches
39051 * the structure of the group, with control names as keys.
39052 *
39053 * This method performs strict checks, so it will throw an error if you try
39054 * to set the value of a control that doesn't exist or if you exclude the
39055 * value of a control.
39056 *
39057 * ### Example
39058 *
39059 * ```
39060 * const form = new FormGroup({
39061 * first: new FormControl(),
39062 * last: new FormControl()
39063 * });
39064 * console.log(form.value); // {first: null, last: null}
39065 *
39066 * form.setValue({first: 'Nancy', last: 'Drew'});
39067 * console.log(form.value); // {first: 'Nancy', last: 'Drew'}
39068 *
39069 * ```
39070 * @param {?} value
39071 * @param {?=} options
39072 * @return {?}
39073 */
39074 FormGroup.prototype.setValue = function (value, options) {
39075 var _this = this;
39076 if (options === void 0) { options = {}; }
39077 this._checkAllValuesPresent(value);
39078 Object.keys(value).forEach(function (name) {
39079 _this._throwIfControlMissing(name);
39080 _this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
39081 });
39082 this.updateValueAndValidity(options);
39083 };
39084 /**
39085 * Patches the value of the {\@link FormGroup}. It accepts an object with control
39086 * names as keys, and will do its best to match the values to the correct controls
39087 * in the group.
39088 *
39089 * It accepts both super-sets and sub-sets of the group without throwing an error.
39090 *
39091 * ### Example
39092 *
39093 * ```
39094 * const form = new FormGroup({
39095 * first: new FormControl(),
39096 * last: new FormControl()
39097 * });
39098 * console.log(form.value); // {first: null, last: null}
39099 *
39100 * form.patchValue({first: 'Nancy'});
39101 * console.log(form.value); // {first: 'Nancy', last: null}
39102 *
39103 * ```
39104 * @param {?} value
39105 * @param {?=} options
39106 * @return {?}
39107 */
39108 FormGroup.prototype.patchValue = function (value, options) {
39109 var _this = this;
39110 if (options === void 0) { options = {}; }
39111 Object.keys(value).forEach(function (name) {
39112 if (_this.controls[name]) {
39113 _this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
39114 }
39115 });
39116 this.updateValueAndValidity(options);
39117 };
39118 /**
39119 * Resets the {\@link FormGroup}. This means by default:
39120 *
39121 * * The group and all descendants are marked `pristine`
39122 * * The group and all descendants are marked `untouched`
39123 * * The value of all descendants will be null or null maps
39124 *
39125 * You can also reset to a specific form state by passing in a map of states
39126 * that matches the structure of your form, with control names as keys. The state
39127 * can be a standalone value or a form state object with both a value and a disabled
39128 * status.
39129 *
39130 * ### Example
39131 *
39132 * ```ts
39133 * this.form.reset({first: 'name', last: 'last name'});
39134 *
39135 * console.log(this.form.value); // {first: 'name', last: 'last name'}
39136 * ```
39137 *
39138 * - OR -
39139 *
39140 * ```
39141 * this.form.reset({
39142 * first: {value: 'name', disabled: true},
39143 * last: 'last'
39144 * });
39145 *
39146 * console.log(this.form.value); // {first: 'name', last: 'last name'}
39147 * console.log(this.form.get('first').status); // 'DISABLED'
39148 * ```
39149 * @param {?=} value
39150 * @param {?=} options
39151 * @return {?}
39152 */
39153 FormGroup.prototype.reset = function (value, options) {
39154 if (value === void 0) { value = {}; }
39155 if (options === void 0) { options = {}; }
39156 this._forEachChild(function (control, name) {
39157 control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent });
39158 });
39159 this.updateValueAndValidity(options);
39160 this._updatePristine(options);
39161 this._updateTouched(options);
39162 };
39163 /**
39164 * The aggregate value of the {\@link FormGroup}, including any disabled controls.
39165 *
39166 * If you'd like to include all values regardless of disabled status, use this method.
39167 * Otherwise, the `value` property is the best way to get the value of the group.
39168 * @return {?}
39169 */
39170 FormGroup.prototype.getRawValue = function () {
39171 return this._reduceChildren({}, function (acc, control, name) {
39172 acc[name] = control instanceof FormControl ? control.value : ((control)).getRawValue();
39173 return acc;
39174 });
39175 };
39176 /**
39177 * \@internal
39178 * @param {?} name
39179 * @return {?}
39180 */
39181 FormGroup.prototype._throwIfControlMissing = function (name) {
39182 if (!Object.keys(this.controls).length) {
39183 throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");
39184 }
39185 if (!this.controls[name]) {
39186 throw new Error("Cannot find form control with name: " + name + ".");
39187 }
39188 };
39189 /**
39190 * \@internal
39191 * @param {?} cb
39192 * @return {?}
39193 */
39194 FormGroup.prototype._forEachChild = function (cb) {
39195 var _this = this;
39196 Object.keys(this.controls).forEach(function (k) { return cb(_this.controls[k], k); });
39197 };
39198 /**
39199 * \@internal
39200 * @return {?}
39201 */
39202 FormGroup.prototype._setUpControls = function () {
39203 var _this = this;
39204 this._forEachChild(function (control) {
39205 control.setParent(_this);
39206 control._registerOnCollectionChange(_this._onCollectionChange);
39207 });
39208 };
39209 /**
39210 * \@internal
39211 * @return {?}
39212 */
39213 FormGroup.prototype._updateValue = function () { this._value = this._reduceValue(); };
39214 /**
39215 * \@internal
39216 * @param {?} condition
39217 * @return {?}
39218 */
39219 FormGroup.prototype._anyControls = function (condition) {
39220 var _this = this;
39221 var /** @type {?} */ res = false;
39222 this._forEachChild(function (control, name) {
39223 res = res || (_this.contains(name) && condition(control));
39224 });
39225 return res;
39226 };
39227 /**
39228 * \@internal
39229 * @return {?}
39230 */
39231 FormGroup.prototype._reduceValue = function () {
39232 var _this = this;
39233 return this._reduceChildren({}, function (acc, control, name) {
39234 if (control.enabled || _this.disabled) {
39235 acc[name] = control.value;
39236 }
39237 return acc;
39238 });
39239 };
39240 /**
39241 * \@internal
39242 * @param {?} initValue
39243 * @param {?} fn
39244 * @return {?}
39245 */
39246 FormGroup.prototype._reduceChildren = function (initValue, fn) {
39247 var /** @type {?} */ res = initValue;
39248 this._forEachChild(function (control, name) { res = fn(res, control, name); });
39249 return res;
39250 };
39251 /**
39252 * \@internal
39253 * @return {?}
39254 */
39255 FormGroup.prototype._allControlsDisabled = function () {
39256 for (var _i = 0, _a = Object.keys(this.controls); _i < _a.length; _i++) {
39257 var controlName = _a[_i];
39258 if (this.controls[controlName].enabled) {
39259 return false;
39260 }
39261 }
39262 return Object.keys(this.controls).length > 0 || this.disabled;
39263 };
39264 /**
39265 * \@internal
39266 * @param {?} value
39267 * @return {?}
39268 */
39269 FormGroup.prototype._checkAllValuesPresent = function (value) {
39270 this._forEachChild(function (control, name) {
39271 if (value[name] === undefined) {
39272 throw new Error("Must supply a value for form control with name: '" + name + "'.");
39273 }
39274 });
39275 };
39276 return FormGroup;
39277}(AbstractControl));
39278/**
39279 * \@whatItDoes Tracks the value and validity state of an array of {\@link FormControl},
39280 * {\@link FormGroup} or {\@link FormArray} instances.
39281 *
39282 * A `FormArray` aggregates the values of each child {\@link FormControl} into an array.
39283 * It calculates its status by reducing the statuses of its children. For example, if one of
39284 * the controls in a `FormArray` is invalid, the entire array becomes invalid.
39285 *
39286 * `FormArray` is one of the three fundamental building blocks used to define forms in Angular,
39287 * along with {\@link FormControl} and {\@link FormGroup}.
39288 *
39289 * \@howToUse
39290 *
39291 * When instantiating a {\@link FormArray}, pass in an array of child controls as the first
39292 * argument.
39293 *
39294 * ### Example
39295 *
39296 * ```
39297 * const arr = new FormArray([
39298 * new FormControl('Nancy', Validators.minLength(2)),
39299 * new FormControl('Drew'),
39300 * ]);
39301 *
39302 * console.log(arr.value); // ['Nancy', 'Drew']
39303 * console.log(arr.status); // 'VALID'
39304 * ```
39305 *
39306 * You can also include array-level validators as the second arg, or array-level async
39307 * validators as the third arg. These come in handy when you want to perform validation
39308 * that considers the value of more than one child control.
39309 *
39310 * ### Adding or removing controls
39311 *
39312 * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
39313 * in `FormArray` itself. These methods ensure the controls are properly tracked in the
39314 * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
39315 * the `FormArray` directly, as that will result in strange and unexpected behavior such
39316 * as broken change detection.
39317 *
39318 * * **npm package**: `\@angular/forms`
39319 *
39320 * \@stable
39321 */
39322var FormArray = (function (_super) {
39323 __extends$1(FormArray, _super);
39324 /**
39325 * @param {?} controls
39326 * @param {?=} validator
39327 * @param {?=} asyncValidator
39328 */
39329 function FormArray(controls, validator, asyncValidator) {
39330 var _this = _super.call(this, validator || null, asyncValidator || null) || this;
39331 _this.controls = controls;
39332 _this._initObservables();
39333 _this._setUpControls();
39334 _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
39335 return _this;
39336 }
39337 /**
39338 * Get the {\@link AbstractControl} at the given `index` in the array.
39339 * @param {?} index
39340 * @return {?}
39341 */
39342 FormArray.prototype.at = function (index) { return this.controls[index]; };
39343 /**
39344 * Insert a new {\@link AbstractControl} at the end of the array.
39345 * @param {?} control
39346 * @return {?}
39347 */
39348 FormArray.prototype.push = function (control) {
39349 this.controls.push(control);
39350 this._registerControl(control);
39351 this.updateValueAndValidity();
39352 this._onCollectionChange();
39353 };
39354 /**
39355 * Insert a new {\@link AbstractControl} at the given `index` in the array.
39356 * @param {?} index
39357 * @param {?} control
39358 * @return {?}
39359 */
39360 FormArray.prototype.insert = function (index, control) {
39361 this.controls.splice(index, 0, control);
39362 this._registerControl(control);
39363 this.updateValueAndValidity();
39364 this._onCollectionChange();
39365 };
39366 /**
39367 * Remove the control at the given `index` in the array.
39368 * @param {?} index
39369 * @return {?}
39370 */
39371 FormArray.prototype.removeAt = function (index) {
39372 if (this.controls[index])
39373 this.controls[index]._registerOnCollectionChange(function () { });
39374 this.controls.splice(index, 1);
39375 this.updateValueAndValidity();
39376 this._onCollectionChange();
39377 };
39378 /**
39379 * Replace an existing control.
39380 * @param {?} index
39381 * @param {?} control
39382 * @return {?}
39383 */
39384 FormArray.prototype.setControl = function (index, control) {
39385 if (this.controls[index])
39386 this.controls[index]._registerOnCollectionChange(function () { });
39387 this.controls.splice(index, 1);
39388 if (control) {
39389 this.controls.splice(index, 0, control);
39390 this._registerControl(control);
39391 }
39392 this.updateValueAndValidity();
39393 this._onCollectionChange();
39394 };
39395 Object.defineProperty(FormArray.prototype, "length", {
39396 /**
39397 * Length of the control array.
39398 * @return {?}
39399 */
39400 get: function () { return this.controls.length; },
39401 enumerable: true,
39402 configurable: true
39403 });
39404 /**
39405 * Sets the value of the {\@link FormArray}. It accepts an array that matches
39406 * the structure of the control.
39407 *
39408 * This method performs strict checks, so it will throw an error if you try
39409 * to set the value of a control that doesn't exist or if you exclude the
39410 * value of a control.
39411 *
39412 * ### Example
39413 *
39414 * ```
39415 * const arr = new FormArray([
39416 * new FormControl(),
39417 * new FormControl()
39418 * ]);
39419 * console.log(arr.value); // [null, null]
39420 *
39421 * arr.setValue(['Nancy', 'Drew']);
39422 * console.log(arr.value); // ['Nancy', 'Drew']
39423 * ```
39424 * @param {?} value
39425 * @param {?=} options
39426 * @return {?}
39427 */
39428 FormArray.prototype.setValue = function (value, options) {
39429 var _this = this;
39430 if (options === void 0) { options = {}; }
39431 this._checkAllValuesPresent(value);
39432 value.forEach(function (newValue, index) {
39433 _this._throwIfControlMissing(index);
39434 _this.at(index).setValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
39435 });
39436 this.updateValueAndValidity(options);
39437 };
39438 /**
39439 * Patches the value of the {\@link FormArray}. It accepts an array that matches the
39440 * structure of the control, and will do its best to match the values to the correct
39441 * controls in the group.
39442 *
39443 * It accepts both super-sets and sub-sets of the array without throwing an error.
39444 *
39445 * ### Example
39446 *
39447 * ```
39448 * const arr = new FormArray([
39449 * new FormControl(),
39450 * new FormControl()
39451 * ]);
39452 * console.log(arr.value); // [null, null]
39453 *
39454 * arr.patchValue(['Nancy']);
39455 * console.log(arr.value); // ['Nancy', null]
39456 * ```
39457 * @param {?} value
39458 * @param {?=} options
39459 * @return {?}
39460 */
39461 FormArray.prototype.patchValue = function (value, options) {
39462 var _this = this;
39463 if (options === void 0) { options = {}; }
39464 value.forEach(function (newValue, index) {
39465 if (_this.at(index)) {
39466 _this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
39467 }
39468 });
39469 this.updateValueAndValidity(options);
39470 };
39471 /**
39472 * Resets the {\@link FormArray}. This means by default:
39473 *
39474 * * The array and all descendants are marked `pristine`
39475 * * The array and all descendants are marked `untouched`
39476 * * The value of all descendants will be null or null maps
39477 *
39478 * You can also reset to a specific form state by passing in an array of states
39479 * that matches the structure of the control. The state can be a standalone value
39480 * or a form state object with both a value and a disabled status.
39481 *
39482 * ### Example
39483 *
39484 * ```ts
39485 * this.arr.reset(['name', 'last name']);
39486 *
39487 * console.log(this.arr.value); // ['name', 'last name']
39488 * ```
39489 *
39490 * - OR -
39491 *
39492 * ```
39493 * this.arr.reset([
39494 * {value: 'name', disabled: true},
39495 * 'last'
39496 * ]);
39497 *
39498 * console.log(this.arr.value); // ['name', 'last name']
39499 * console.log(this.arr.get(0).status); // 'DISABLED'
39500 * ```
39501 * @param {?=} value
39502 * @param {?=} options
39503 * @return {?}
39504 */
39505 FormArray.prototype.reset = function (value, options) {
39506 if (value === void 0) { value = []; }
39507 if (options === void 0) { options = {}; }
39508 this._forEachChild(function (control, index) {
39509 control.reset(value[index], { onlySelf: true, emitEvent: options.emitEvent });
39510 });
39511 this.updateValueAndValidity(options);
39512 this._updatePristine(options);
39513 this._updateTouched(options);
39514 };
39515 /**
39516 * The aggregate value of the array, including any disabled controls.
39517 *
39518 * If you'd like to include all values regardless of disabled status, use this method.
39519 * Otherwise, the `value` property is the best way to get the value of the array.
39520 * @return {?}
39521 */
39522 FormArray.prototype.getRawValue = function () {
39523 return this.controls.map(function (control) {
39524 return control instanceof FormControl ? control.value : ((control)).getRawValue();
39525 });
39526 };
39527 /**
39528 * \@internal
39529 * @param {?} index
39530 * @return {?}
39531 */
39532 FormArray.prototype._throwIfControlMissing = function (index) {
39533 if (!this.controls.length) {
39534 throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");
39535 }
39536 if (!this.at(index)) {
39537 throw new Error("Cannot find form control at index " + index);
39538 }
39539 };
39540 /**
39541 * \@internal
39542 * @param {?} cb
39543 * @return {?}
39544 */
39545 FormArray.prototype._forEachChild = function (cb) {
39546 this.controls.forEach(function (control, index) { cb(control, index); });
39547 };
39548 /**
39549 * \@internal
39550 * @return {?}
39551 */
39552 FormArray.prototype._updateValue = function () {
39553 var _this = this;
39554 this._value = this.controls.filter(function (control) { return control.enabled || _this.disabled; })
39555 .map(function (control) { return control.value; });
39556 };
39557 /**
39558 * \@internal
39559 * @param {?} condition
39560 * @return {?}
39561 */
39562 FormArray.prototype._anyControls = function (condition) {
39563 return this.controls.some(function (control) { return control.enabled && condition(control); });
39564 };
39565 /**
39566 * \@internal
39567 * @return {?}
39568 */
39569 FormArray.prototype._setUpControls = function () {
39570 var _this = this;
39571 this._forEachChild(function (control) { return _this._registerControl(control); });
39572 };
39573 /**
39574 * \@internal
39575 * @param {?} value
39576 * @return {?}
39577 */
39578 FormArray.prototype._checkAllValuesPresent = function (value) {
39579 this._forEachChild(function (control, i) {
39580 if (value[i] === undefined) {
39581 throw new Error("Must supply a value for form control at index: " + i + ".");
39582 }
39583 });
39584 };
39585 /**
39586 * \@internal
39587 * @return {?}
39588 */
39589 FormArray.prototype._allControlsDisabled = function () {
39590 for (var _i = 0, _a = this.controls; _i < _a.length; _i++) {
39591 var control = _a[_i];
39592 if (control.enabled)
39593 return false;
39594 }
39595 return this.controls.length > 0 || this.disabled;
39596 };
39597 /**
39598 * @param {?} control
39599 * @return {?}
39600 */
39601 FormArray.prototype._registerControl = function (control) {
39602 control.setParent(this);
39603 control._registerOnCollectionChange(this._onCollectionChange);
39604 };
39605 return FormArray;
39606}(AbstractControl));
39607/**
39608 * @license
39609 * Copyright Google Inc. All Rights Reserved.
39610 *
39611 * Use of this source code is governed by an MIT-style license that can be
39612 * found in the LICENSE file at https://angular.io/license
39613 */
39614var formDirectiveProvider = {
39615 provide: ControlContainer,
39616 useExisting: forwardRef(function () { return NgForm; })
39617};
39618var resolvedPromise = Promise.resolve(null);
39619/**
39620 * \@whatItDoes Creates a top-level {\@link FormGroup} instance and binds it to a form
39621 * to track aggregate form value and validation status.
39622 *
39623 * \@howToUse
39624 *
39625 * As soon as you import the `FormsModule`, this directive becomes active by default on
39626 * all `<form>` tags. You don't need to add a special selector.
39627 *
39628 * You can export the directive into a local template variable using `ngForm` as the key
39629 * (ex: `#myForm="ngForm"`). This is optional, but useful. Many properties from the underlying
39630 * {\@link FormGroup} instance are duplicated on the directive itself, so a reference to it
39631 * will give you access to the aggregate value and validity status of the form, as well as
39632 * user interaction properties like `dirty` and `touched`.
39633 *
39634 * To register child controls with the form, you'll want to use {\@link NgModel} with a
39635 * `name` attribute. You can also use {\@link NgModelGroup} if you'd like to create
39636 * sub-groups within the form.
39637 *
39638 * You can listen to the directive's `ngSubmit` event to be notified when the user has
39639 * triggered a form submission. The `ngSubmit` event will be emitted with the original form
39640 * submission event.
39641 *
39642 * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
39643 *
39644 * * **npm package**: `\@angular/forms`
39645 *
39646 * * **NgModule**: `FormsModule`
39647 *
39648 * \@stable
39649 */
39650var NgForm = (function (_super) {
39651 __extends$1(NgForm, _super);
39652 /**
39653 * @param {?} validators
39654 * @param {?} asyncValidators
39655 */
39656 function NgForm(validators, asyncValidators) {
39657 var _this = _super.call(this) || this;
39658 _this._submitted = false;
39659 _this.ngSubmit = new EventEmitter();
39660 _this.form =
39661 new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
39662 return _this;
39663 }
39664 Object.defineProperty(NgForm.prototype, "submitted", {
39665 /**
39666 * @return {?}
39667 */
39668 get: function () { return this._submitted; },
39669 enumerable: true,
39670 configurable: true
39671 });
39672 Object.defineProperty(NgForm.prototype, "formDirective", {
39673 /**
39674 * @return {?}
39675 */
39676 get: function () { return this; },
39677 enumerable: true,
39678 configurable: true
39679 });
39680 Object.defineProperty(NgForm.prototype, "control", {
39681 /**
39682 * @return {?}
39683 */
39684 get: function () { return this.form; },
39685 enumerable: true,
39686 configurable: true
39687 });
39688 Object.defineProperty(NgForm.prototype, "path", {
39689 /**
39690 * @return {?}
39691 */
39692 get: function () { return []; },
39693 enumerable: true,
39694 configurable: true
39695 });
39696 Object.defineProperty(NgForm.prototype, "controls", {
39697 /**
39698 * @return {?}
39699 */
39700 get: function () { return this.form.controls; },
39701 enumerable: true,
39702 configurable: true
39703 });
39704 /**
39705 * @param {?} dir
39706 * @return {?}
39707 */
39708 NgForm.prototype.addControl = function (dir) {
39709 var _this = this;
39710 resolvedPromise.then(function () {
39711 var /** @type {?} */ container = _this._findContainer(dir.path);
39712 dir._control = (container.registerControl(dir.name, dir.control));
39713 setUpControl(dir.control, dir);
39714 dir.control.updateValueAndValidity({ emitEvent: false });
39715 });
39716 };
39717 /**
39718 * @param {?} dir
39719 * @return {?}
39720 */
39721 NgForm.prototype.getControl = function (dir) { return (this.form.get(dir.path)); };
39722 /**
39723 * @param {?} dir
39724 * @return {?}
39725 */
39726 NgForm.prototype.removeControl = function (dir) {
39727 var _this = this;
39728 resolvedPromise.then(function () {
39729 var /** @type {?} */ container = _this._findContainer(dir.path);
39730 if (container) {
39731 container.removeControl(dir.name);
39732 }
39733 });
39734 };
39735 /**
39736 * @param {?} dir
39737 * @return {?}
39738 */
39739 NgForm.prototype.addFormGroup = function (dir) {
39740 var _this = this;
39741 resolvedPromise.then(function () {
39742 var /** @type {?} */ container = _this._findContainer(dir.path);
39743 var /** @type {?} */ group$$1 = new FormGroup({});
39744 setUpFormContainer(group$$1, dir);
39745 container.registerControl(dir.name, group$$1);
39746 group$$1.updateValueAndValidity({ emitEvent: false });
39747 });
39748 };
39749 /**
39750 * @param {?} dir
39751 * @return {?}
39752 */
39753 NgForm.prototype.removeFormGroup = function (dir) {
39754 var _this = this;
39755 resolvedPromise.then(function () {
39756 var /** @type {?} */ container = _this._findContainer(dir.path);
39757 if (container) {
39758 container.removeControl(dir.name);
39759 }
39760 });
39761 };
39762 /**
39763 * @param {?} dir
39764 * @return {?}
39765 */
39766 NgForm.prototype.getFormGroup = function (dir) { return (this.form.get(dir.path)); };
39767 /**
39768 * @param {?} dir
39769 * @param {?} value
39770 * @return {?}
39771 */
39772 NgForm.prototype.updateModel = function (dir, value) {
39773 var _this = this;
39774 resolvedPromise.then(function () {
39775 var /** @type {?} */ ctrl = (_this.form.get(/** @type {?} */ ((dir.path))));
39776 ctrl.setValue(value);
39777 });
39778 };
39779 /**
39780 * @param {?} value
39781 * @return {?}
39782 */
39783 NgForm.prototype.setValue = function (value) { this.control.setValue(value); };
39784 /**
39785 * @param {?} $event
39786 * @return {?}
39787 */
39788 NgForm.prototype.onSubmit = function ($event) {
39789 this._submitted = true;
39790 this.ngSubmit.emit($event);
39791 return false;
39792 };
39793 /**
39794 * @return {?}
39795 */
39796 NgForm.prototype.onReset = function () { this.resetForm(); };
39797 /**
39798 * @param {?=} value
39799 * @return {?}
39800 */
39801 NgForm.prototype.resetForm = function (value) {
39802 if (value === void 0) { value = undefined; }
39803 this.form.reset(value);
39804 this._submitted = false;
39805 };
39806 /**
39807 * \@internal
39808 * @param {?} path
39809 * @return {?}
39810 */
39811 NgForm.prototype._findContainer = function (path) {
39812 path.pop();
39813 return path.length ? (this.form.get(path)) : this.form;
39814 };
39815 return NgForm;
39816}(ControlContainer));
39817NgForm.decorators = [
39818 { type: Directive, args: [{
39819 selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',
39820 providers: [formDirectiveProvider],
39821 host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
39822 outputs: ['ngSubmit'],
39823 exportAs: 'ngForm'
39824 },] },
39825];
39826/**
39827 * @nocollapse
39828 */
39829NgForm.ctorParameters = function () { return [
39830 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
39831 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
39832]; };
39833/**
39834 * @license
39835 * Copyright Google Inc. All Rights Reserved.
39836 *
39837 * Use of this source code is governed by an MIT-style license that can be
39838 * found in the LICENSE file at https://angular.io/license
39839 */
39840var FormErrorExamples = {
39841 formControlName: "\n <div [formGroup]=\"myGroup\">\n <input formControlName=\"firstName\">\n </div>\n\n In your class:\n\n this.myGroup = new FormGroup({\n firstName: new FormControl()\n });",
39842 formGroupName: "\n <div [formGroup]=\"myGroup\">\n <div formGroupName=\"person\">\n <input formControlName=\"firstName\">\n </div>\n </div>\n\n In your class:\n\n this.myGroup = new FormGroup({\n person: new FormGroup({ firstName: new FormControl() })\n });",
39843 formArrayName: "\n <div [formGroup]=\"myGroup\">\n <div formArrayName=\"cities\">\n <div *ngFor=\"let city of cityArray.controls; index as i\">\n <input [formControlName]=\"i\">\n </div>\n </div>\n </div>\n\n In your class:\n\n this.cityArray = new FormArray([new FormControl('SF')]);\n this.myGroup = new FormGroup({\n cities: this.cityArray\n });",
39844 ngModelGroup: "\n <form>\n <div ngModelGroup=\"person\">\n <input [(ngModel)]=\"person.name\" name=\"firstName\">\n </div>\n </form>",
39845 ngModelWithFormGroup: "\n <div [formGroup]=\"myGroup\">\n <input formControlName=\"firstName\">\n <input [(ngModel)]=\"showMoreControls\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n "
39846};
39847/**
39848 * @license
39849 * Copyright Google Inc. All Rights Reserved.
39850 *
39851 * Use of this source code is governed by an MIT-style license that can be
39852 * found in the LICENSE file at https://angular.io/license
39853 */
39854var TemplateDrivenErrors = (function () {
39855 function TemplateDrivenErrors() {
39856 }
39857 /**
39858 * @return {?}
39859 */
39860 TemplateDrivenErrors.modelParentException = function () {
39861 throw new Error("\n ngModel cannot be used to register form controls with a parent formGroup directive. Try using\n formGroup's partner directive \"formControlName\" instead. Example:\n\n " + FormErrorExamples.formControlName + "\n\n Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:\n\n Example:\n\n " + FormErrorExamples.ngModelWithFormGroup);
39862 };
39863 /**
39864 * @return {?}
39865 */
39866 TemplateDrivenErrors.formGroupNameException = function () {
39867 throw new Error("\n ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.\n\n Option 1: Use formControlName instead of ngModel (reactive strategy):\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy):\n\n " + FormErrorExamples.ngModelGroup);
39868 };
39869 /**
39870 * @return {?}
39871 */
39872 TemplateDrivenErrors.missingNameException = function () {
39873 throw new Error("If ngModel is used within a form tag, either the name attribute must be set or the form\n control must be defined as 'standalone' in ngModelOptions.\n\n Example 1: <input [(ngModel)]=\"person.firstName\" name=\"first\">\n Example 2: <input [(ngModel)]=\"person.firstName\" [ngModelOptions]=\"{standalone: true}\">");
39874 };
39875 /**
39876 * @return {?}
39877 */
39878 TemplateDrivenErrors.modelGroupParentException = function () {
39879 throw new Error("\n ngModelGroup cannot be used with a parent formGroup directive.\n\n Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy):\n\n " + FormErrorExamples.ngModelGroup);
39880 };
39881 return TemplateDrivenErrors;
39882}());
39883/**
39884 * @license
39885 * Copyright Google Inc. All Rights Reserved.
39886 *
39887 * Use of this source code is governed by an MIT-style license that can be
39888 * found in the LICENSE file at https://angular.io/license
39889 */
39890var modelGroupProvider = {
39891 provide: ControlContainer,
39892 useExisting: forwardRef(function () { return NgModelGroup; })
39893};
39894/**
39895 * \@whatItDoes Creates and binds a {\@link FormGroup} instance to a DOM element.
39896 *
39897 * \@howToUse
39898 *
39899 * This directive can only be used as a child of {\@link NgForm} (or in other words,
39900 * within `<form>` tags).
39901 *
39902 * Use this directive if you'd like to create a sub-group within a form. This can
39903 * come in handy if you want to validate a sub-group of your form separately from
39904 * the rest of your form, or if some values in your domain model make more sense to
39905 * consume together in a nested object.
39906 *
39907 * Pass in the name you'd like this sub-group to have and it will become the key
39908 * for the sub-group in the form's full value. You can also export the directive into
39909 * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
39910 *
39911 * {\@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
39912 *
39913 * * **npm package**: `\@angular/forms`
39914 *
39915 * * **NgModule**: `FormsModule`
39916 *
39917 * \@stable
39918 */
39919var NgModelGroup = (function (_super) {
39920 __extends$1(NgModelGroup, _super);
39921 /**
39922 * @param {?} parent
39923 * @param {?} validators
39924 * @param {?} asyncValidators
39925 */
39926 function NgModelGroup(parent, validators, asyncValidators) {
39927 var _this = _super.call(this) || this;
39928 _this._parent = parent;
39929 _this._validators = validators;
39930 _this._asyncValidators = asyncValidators;
39931 return _this;
39932 }
39933 /**
39934 * \@internal
39935 * @return {?}
39936 */
39937 NgModelGroup.prototype._checkParentType = function () {
39938 if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
39939 TemplateDrivenErrors.modelGroupParentException();
39940 }
39941 };
39942 return NgModelGroup;
39943}(AbstractFormGroupDirective));
39944NgModelGroup.decorators = [
39945 { type: Directive, args: [{ selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup' },] },
39946];
39947/**
39948 * @nocollapse
39949 */
39950NgModelGroup.ctorParameters = function () { return [
39951 { type: ControlContainer, decorators: [{ type: Host }, { type: SkipSelf },] },
39952 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
39953 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
39954]; };
39955NgModelGroup.propDecorators = {
39956 'name': [{ type: Input, args: ['ngModelGroup',] },],
39957};
39958/**
39959 * @license
39960 * Copyright Google Inc. All Rights Reserved.
39961 *
39962 * Use of this source code is governed by an MIT-style license that can be
39963 * found in the LICENSE file at https://angular.io/license
39964 */
39965var formControlBinding = {
39966 provide: NgControl,
39967 useExisting: forwardRef(function () { return NgModel; })
39968};
39969/**
39970 * `ngModel` forces an additional change detection run when its inputs change:
39971 * E.g.:
39972 * ```
39973 * <div>{{myModel.valid}}</div>
39974 * <input [(ngModel)]="myValue" #myModel="ngModel">
39975 * ```
39976 * I.e. `ngModel` can export itself on the element and then be used in the template.
39977 * Normally, this would result in expressions before the `input` that use the exported directive
39978 * to have and old value as they have been
39979 * dirty checked before. As this is a very common case for `ngModel`, we added this second change
39980 * detection run.
39981 *
39982 * Notes:
39983 * - this is just one extra run no matter how many `ngModel` have been changed.
39984 * - this is a general problem when using `exportAs` for directives!
39985 */
39986var resolvedPromise$1 = Promise.resolve(null);
39987/**
39988 * \@whatItDoes Creates a {\@link FormControl} instance from a domain model and binds it
39989 * to a form control element.
39990 *
39991 * The {\@link FormControl} instance will track the value, user interaction, and
39992 * validation status of the control and keep the view synced with the model. If used
39993 * within a parent form, the directive will also register itself with the form as a child
39994 * control.
39995 *
39996 * \@howToUse
39997 *
39998 * This directive can be used by itself or as part of a larger form. All you need is the
39999 * `ngModel` selector to activate it.
40000 *
40001 * It accepts a domain model as an optional {\@link Input}. If you have a one-way binding
40002 * to `ngModel` with `[]` syntax, changing the value of the domain model in the component
40003 * class will set the value in the view. If you have a two-way binding with `[()]` syntax
40004 * (also known as 'banana-box syntax'), the value in the UI will always be synced back to
40005 * the domain model in your class as well.
40006 *
40007 * If you wish to inspect the properties of the associated {\@link FormControl} (like
40008 * validity state), you can also export the directive into a local template variable using
40009 * `ngModel` as the key (ex: `#myVar="ngModel"`). You can then access the control using the
40010 * directive's `control` property, but most properties you'll need (like `valid` and `dirty`)
40011 * will fall through to the control anyway, so you can access them directly. You can see a
40012 * full list of properties directly available in {\@link AbstractControlDirective}.
40013 *
40014 * The following is an example of a simple standalone control using `ngModel`:
40015 *
40016 * {\@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
40017 *
40018 * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
40019 * so that the control can be registered with the parent form under that name.
40020 *
40021 * It's worth noting that in the context of a parent form, you often can skip one-way or
40022 * two-way binding because the parent form will sync the value for you. You can access
40023 * its properties by exporting it into a local template variable using `ngForm` (ex:
40024 * `#f="ngForm"`). Then you can pass it where it needs to go on submit.
40025 *
40026 * If you do need to populate initial values into your form, using a one-way binding for
40027 * `ngModel` tends to be sufficient as long as you use the exported form's value rather
40028 * than the domain model's value on submit.
40029 *
40030 * Take a look at an example of using `ngModel` within a form:
40031 *
40032 * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
40033 *
40034 * To see `ngModel` examples with different form control types, see:
40035 *
40036 * * Radio buttons: {\@link RadioControlValueAccessor}
40037 * * Selects: {\@link SelectControlValueAccessor}
40038 *
40039 * **npm package**: `\@angular/forms`
40040 *
40041 * **NgModule**: `FormsModule`
40042 *
40043 * \@stable
40044 */
40045var NgModel = (function (_super) {
40046 __extends$1(NgModel, _super);
40047 /**
40048 * @param {?} parent
40049 * @param {?} validators
40050 * @param {?} asyncValidators
40051 * @param {?} valueAccessors
40052 */
40053 function NgModel(parent, validators, asyncValidators, valueAccessors) {
40054 var _this = _super.call(this) || this;
40055 /**
40056 * \@internal
40057 */
40058 _this._control = new FormControl();
40059 /**
40060 * \@internal
40061 */
40062 _this._registered = false;
40063 _this.update = new EventEmitter();
40064 _this._parent = parent;
40065 _this._rawValidators = validators || [];
40066 _this._rawAsyncValidators = asyncValidators || [];
40067 _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
40068 return _this;
40069 }
40070 /**
40071 * @param {?} changes
40072 * @return {?}
40073 */
40074 NgModel.prototype.ngOnChanges = function (changes) {
40075 this._checkForErrors();
40076 if (!this._registered)
40077 this._setUpControl();
40078 if ('isDisabled' in changes) {
40079 this._updateDisabled(changes);
40080 }
40081 if (isPropertyUpdated(changes, this.viewModel)) {
40082 this._updateValue(this.model);
40083 this.viewModel = this.model;
40084 }
40085 };
40086 /**
40087 * @return {?}
40088 */
40089 NgModel.prototype.ngOnDestroy = function () { this.formDirective && this.formDirective.removeControl(this); };
40090 Object.defineProperty(NgModel.prototype, "control", {
40091 /**
40092 * @return {?}
40093 */
40094 get: function () { return this._control; },
40095 enumerable: true,
40096 configurable: true
40097 });
40098 Object.defineProperty(NgModel.prototype, "path", {
40099 /**
40100 * @return {?}
40101 */
40102 get: function () {
40103 return this._parent ? controlPath(this.name, this._parent) : [this.name];
40104 },
40105 enumerable: true,
40106 configurable: true
40107 });
40108 Object.defineProperty(NgModel.prototype, "formDirective", {
40109 /**
40110 * @return {?}
40111 */
40112 get: function () { return this._parent ? this._parent.formDirective : null; },
40113 enumerable: true,
40114 configurable: true
40115 });
40116 Object.defineProperty(NgModel.prototype, "validator", {
40117 /**
40118 * @return {?}
40119 */
40120 get: function () { return composeValidators(this._rawValidators); },
40121 enumerable: true,
40122 configurable: true
40123 });
40124 Object.defineProperty(NgModel.prototype, "asyncValidator", {
40125 /**
40126 * @return {?}
40127 */
40128 get: function () {
40129 return composeAsyncValidators(this._rawAsyncValidators);
40130 },
40131 enumerable: true,
40132 configurable: true
40133 });
40134 /**
40135 * @param {?} newValue
40136 * @return {?}
40137 */
40138 NgModel.prototype.viewToModelUpdate = function (newValue) {
40139 this.viewModel = newValue;
40140 this.update.emit(newValue);
40141 };
40142 /**
40143 * @return {?}
40144 */
40145 NgModel.prototype._setUpControl = function () {
40146 this._isStandalone() ? this._setUpStandalone() :
40147 this.formDirective.addControl(this);
40148 this._registered = true;
40149 };
40150 /**
40151 * @return {?}
40152 */
40153 NgModel.prototype._isStandalone = function () {
40154 return !this._parent || !!(this.options && this.options.standalone);
40155 };
40156 /**
40157 * @return {?}
40158 */
40159 NgModel.prototype._setUpStandalone = function () {
40160 setUpControl(this._control, this);
40161 this._control.updateValueAndValidity({ emitEvent: false });
40162 };
40163 /**
40164 * @return {?}
40165 */
40166 NgModel.prototype._checkForErrors = function () {
40167 if (!this._isStandalone()) {
40168 this._checkParentType();
40169 }
40170 this._checkName();
40171 };
40172 /**
40173 * @return {?}
40174 */
40175 NgModel.prototype._checkParentType = function () {
40176 if (!(this._parent instanceof NgModelGroup) &&
40177 this._parent instanceof AbstractFormGroupDirective) {
40178 TemplateDrivenErrors.formGroupNameException();
40179 }
40180 else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
40181 TemplateDrivenErrors.modelParentException();
40182 }
40183 };
40184 /**
40185 * @return {?}
40186 */
40187 NgModel.prototype._checkName = function () {
40188 if (this.options && this.options.name)
40189 this.name = this.options.name;
40190 if (!this._isStandalone() && !this.name) {
40191 TemplateDrivenErrors.missingNameException();
40192 }
40193 };
40194 /**
40195 * @param {?} value
40196 * @return {?}
40197 */
40198 NgModel.prototype._updateValue = function (value) {
40199 var _this = this;
40200 resolvedPromise$1.then(function () { _this.control.setValue(value, { emitViewToModelChange: false }); });
40201 };
40202 /**
40203 * @param {?} changes
40204 * @return {?}
40205 */
40206 NgModel.prototype._updateDisabled = function (changes) {
40207 var _this = this;
40208 var /** @type {?} */ disabledValue = changes['isDisabled'].currentValue;
40209 var /** @type {?} */ isDisabled = disabledValue === '' || (disabledValue && disabledValue !== 'false');
40210 resolvedPromise$1.then(function () {
40211 if (isDisabled && !_this.control.disabled) {
40212 _this.control.disable();
40213 }
40214 else if (!isDisabled && _this.control.disabled) {
40215 _this.control.enable();
40216 }
40217 });
40218 };
40219 return NgModel;
40220}(NgControl));
40221NgModel.decorators = [
40222 { type: Directive, args: [{
40223 selector: '[ngModel]:not([formControlName]):not([formControl])',
40224 providers: [formControlBinding],
40225 exportAs: 'ngModel'
40226 },] },
40227];
40228/**
40229 * @nocollapse
40230 */
40231NgModel.ctorParameters = function () { return [
40232 { type: ControlContainer, decorators: [{ type: Optional }, { type: Host },] },
40233 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
40234 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
40235 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
40236]; };
40237NgModel.propDecorators = {
40238 'name': [{ type: Input },],
40239 'isDisabled': [{ type: Input, args: ['disabled',] },],
40240 'model': [{ type: Input, args: ['ngModel',] },],
40241 'options': [{ type: Input, args: ['ngModelOptions',] },],
40242 'update': [{ type: Output, args: ['ngModelChange',] },],
40243};
40244/**
40245 * @license
40246 * Copyright Google Inc. All Rights Reserved.
40247 *
40248 * Use of this source code is governed by an MIT-style license that can be
40249 * found in the LICENSE file at https://angular.io/license
40250 */
40251var ReactiveErrors = (function () {
40252 function ReactiveErrors() {
40253 }
40254 /**
40255 * @return {?}
40256 */
40257 ReactiveErrors.controlParentException = function () {
40258 throw new Error("formControlName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formControlName);
40259 };
40260 /**
40261 * @return {?}
40262 */
40263 ReactiveErrors.ngModelGroupException = function () {
40264 throw new Error("formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents\n that also have a \"form\" prefix: formGroupName, formArrayName, or formGroup.\n\n Option 1: Update the parent to be formGroupName (reactive form strategy)\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Use ngModel instead of formControlName (template-driven strategy)\n\n " + FormErrorExamples.ngModelGroup);
40265 };
40266 /**
40267 * @return {?}
40268 */
40269 ReactiveErrors.missingFormException = function () {
40270 throw new Error("formGroup expects a FormGroup instance. Please pass one in.\n\n Example:\n\n " + FormErrorExamples.formControlName);
40271 };
40272 /**
40273 * @return {?}
40274 */
40275 ReactiveErrors.groupParentException = function () {
40276 throw new Error("formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formGroupName);
40277 };
40278 /**
40279 * @return {?}
40280 */
40281 ReactiveErrors.arrayParentException = function () {
40282 throw new Error("formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formArrayName);
40283 };
40284 /**
40285 * @return {?}
40286 */
40287 ReactiveErrors.disabledAttrWarning = function () {
40288 console.warn("\n It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true\n when you set up this control in your component class, the disabled attribute will actually be set in the DOM for\n you. We recommend using this approach to avoid 'changed after checked' errors.\n \n Example: \n form = new FormGroup({\n first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),\n last: new FormControl('Drew', Validators.required)\n });\n ");
40289 };
40290 return ReactiveErrors;
40291}());
40292/**
40293 * @license
40294 * Copyright Google Inc. All Rights Reserved.
40295 *
40296 * Use of this source code is governed by an MIT-style license that can be
40297 * found in the LICENSE file at https://angular.io/license
40298 */
40299var formControlBinding$1 = {
40300 provide: NgControl,
40301 useExisting: forwardRef(function () { return FormControlDirective; })
40302};
40303/**
40304 * \@whatItDoes Syncs a standalone {\@link FormControl} instance to a form control element.
40305 *
40306 * In other words, this directive ensures that any values written to the {\@link FormControl}
40307 * instance programmatically will be written to the DOM element (model -> view). Conversely,
40308 * any values written to the DOM element through user input will be reflected in the
40309 * {\@link FormControl} instance (view -> model).
40310 *
40311 * \@howToUse
40312 *
40313 * Use this directive if you'd like to create and manage a {\@link FormControl} instance directly.
40314 * Simply create a {\@link FormControl}, save it to your component class, and pass it into the
40315 * {\@link FormControlDirective}.
40316 *
40317 * This directive is designed to be used as a standalone control. Unlike {\@link FormControlName},
40318 * it does not require that your {\@link FormControl} instance be part of any parent
40319 * {\@link FormGroup}, and it won't be registered to any {\@link FormGroupDirective} that
40320 * exists above it.
40321 *
40322 * **Get the value**: the `value` property is always synced and available on the
40323 * {\@link FormControl} instance. See a full list of available properties in
40324 * {\@link AbstractControl}.
40325 *
40326 * **Set the value**: You can pass in an initial value when instantiating the {\@link FormControl},
40327 * or you can set it programmatically later using {\@link AbstractControl#setValue setValue} or
40328 * {\@link AbstractControl#patchValue patchValue}.
40329 *
40330 * **Listen to value**: If you want to listen to changes in the value of the control, you can
40331 * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
40332 * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
40333 * re-calculated.
40334 *
40335 * ### Example
40336 *
40337 * {\@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
40338 *
40339 * * **npm package**: `\@angular/forms`
40340 *
40341 * * **NgModule**: `ReactiveFormsModule`
40342 *
40343 * \@stable
40344 */
40345var FormControlDirective = (function (_super) {
40346 __extends$1(FormControlDirective, _super);
40347 /**
40348 * @param {?} validators
40349 * @param {?} asyncValidators
40350 * @param {?} valueAccessors
40351 */
40352 function FormControlDirective(validators, asyncValidators, valueAccessors) {
40353 var _this = _super.call(this) || this;
40354 _this.update = new EventEmitter();
40355 _this._rawValidators = validators || [];
40356 _this._rawAsyncValidators = asyncValidators || [];
40357 _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
40358 return _this;
40359 }
40360 Object.defineProperty(FormControlDirective.prototype, "isDisabled", {
40361 /**
40362 * @param {?} isDisabled
40363 * @return {?}
40364 */
40365 set: function (isDisabled) { ReactiveErrors.disabledAttrWarning(); },
40366 enumerable: true,
40367 configurable: true
40368 });
40369 /**
40370 * @param {?} changes
40371 * @return {?}
40372 */
40373 FormControlDirective.prototype.ngOnChanges = function (changes) {
40374 if (this._isControlChanged(changes)) {
40375 setUpControl(this.form, this);
40376 if (this.control.disabled && ((this.valueAccessor)).setDisabledState) {
40377 ((((this.valueAccessor)).setDisabledState))(true);
40378 }
40379 this.form.updateValueAndValidity({ emitEvent: false });
40380 }
40381 if (isPropertyUpdated(changes, this.viewModel)) {
40382 this.form.setValue(this.model);
40383 this.viewModel = this.model;
40384 }
40385 };
40386 Object.defineProperty(FormControlDirective.prototype, "path", {
40387 /**
40388 * @return {?}
40389 */
40390 get: function () { return []; },
40391 enumerable: true,
40392 configurable: true
40393 });
40394 Object.defineProperty(FormControlDirective.prototype, "validator", {
40395 /**
40396 * @return {?}
40397 */
40398 get: function () { return composeValidators(this._rawValidators); },
40399 enumerable: true,
40400 configurable: true
40401 });
40402 Object.defineProperty(FormControlDirective.prototype, "asyncValidator", {
40403 /**
40404 * @return {?}
40405 */
40406 get: function () {
40407 return composeAsyncValidators(this._rawAsyncValidators);
40408 },
40409 enumerable: true,
40410 configurable: true
40411 });
40412 Object.defineProperty(FormControlDirective.prototype, "control", {
40413 /**
40414 * @return {?}
40415 */
40416 get: function () { return this.form; },
40417 enumerable: true,
40418 configurable: true
40419 });
40420 /**
40421 * @param {?} newValue
40422 * @return {?}
40423 */
40424 FormControlDirective.prototype.viewToModelUpdate = function (newValue) {
40425 this.viewModel = newValue;
40426 this.update.emit(newValue);
40427 };
40428 /**
40429 * @param {?} changes
40430 * @return {?}
40431 */
40432 FormControlDirective.prototype._isControlChanged = function (changes) {
40433 return changes.hasOwnProperty('form');
40434 };
40435 return FormControlDirective;
40436}(NgControl));
40437FormControlDirective.decorators = [
40438 { type: Directive, args: [{ selector: '[formControl]', providers: [formControlBinding$1], exportAs: 'ngForm' },] },
40439];
40440/**
40441 * @nocollapse
40442 */
40443FormControlDirective.ctorParameters = function () { return [
40444 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
40445 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
40446 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
40447]; };
40448FormControlDirective.propDecorators = {
40449 'form': [{ type: Input, args: ['formControl',] },],
40450 'model': [{ type: Input, args: ['ngModel',] },],
40451 'update': [{ type: Output, args: ['ngModelChange',] },],
40452 'isDisabled': [{ type: Input, args: ['disabled',] },],
40453};
40454/**
40455 * @license
40456 * Copyright Google Inc. All Rights Reserved.
40457 *
40458 * Use of this source code is governed by an MIT-style license that can be
40459 * found in the LICENSE file at https://angular.io/license
40460 */
40461var formDirectiveProvider$1 = {
40462 provide: ControlContainer,
40463 useExisting: forwardRef(function () { return FormGroupDirective; })
40464};
40465/**
40466 * \@whatItDoes Binds an existing {\@link FormGroup} to a DOM element.
40467 *
40468 * \@howToUse
40469 *
40470 * This directive accepts an existing {\@link FormGroup} instance. It will then use this
40471 * {\@link FormGroup} instance to match any child {\@link FormControl}, {\@link FormGroup},
40472 * and {\@link FormArray} instances to child {\@link FormControlName}, {\@link FormGroupName},
40473 * and {\@link FormArrayName} directives.
40474 *
40475 * **Set value**: You can set the form's initial value when instantiating the
40476 * {\@link FormGroup}, or you can set it programmatically later using the {\@link FormGroup}'s
40477 * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}
40478 * methods.
40479 *
40480 * **Listen to value**: If you want to listen to changes in the value of the form, you can subscribe
40481 * to the {\@link FormGroup}'s {\@link AbstractControl#valueChanges valueChanges} event. You can also
40482 * listen to its {\@link AbstractControl#statusChanges statusChanges} event to be notified when the
40483 * validation status is re-calculated.
40484 *
40485 * Furthermore, you can listen to the directive's `ngSubmit` event to be notified when the user has
40486 * triggered a form submission. The `ngSubmit` event will be emitted with the original form
40487 * submission event.
40488 *
40489 * ### Example
40490 *
40491 * In this example, we create form controls for first name and last name.
40492 *
40493 * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
40494 *
40495 * **npm package**: `\@angular/forms`
40496 *
40497 * **NgModule**: {\@link ReactiveFormsModule}
40498 *
40499 * \@stable
40500 */
40501var FormGroupDirective = (function (_super) {
40502 __extends$1(FormGroupDirective, _super);
40503 /**
40504 * @param {?} _validators
40505 * @param {?} _asyncValidators
40506 */
40507 function FormGroupDirective(_validators, _asyncValidators) {
40508 var _this = _super.call(this) || this;
40509 _this._validators = _validators;
40510 _this._asyncValidators = _asyncValidators;
40511 _this._submitted = false;
40512 _this.directives = [];
40513 _this.form = ((null));
40514 _this.ngSubmit = new EventEmitter();
40515 return _this;
40516 }
40517 /**
40518 * @param {?} changes
40519 * @return {?}
40520 */
40521 FormGroupDirective.prototype.ngOnChanges = function (changes) {
40522 this._checkFormPresent();
40523 if (changes.hasOwnProperty('form')) {
40524 this._updateValidators();
40525 this._updateDomValue();
40526 this._updateRegistrations();
40527 }
40528 };
40529 Object.defineProperty(FormGroupDirective.prototype, "submitted", {
40530 /**
40531 * @return {?}
40532 */
40533 get: function () { return this._submitted; },
40534 enumerable: true,
40535 configurable: true
40536 });
40537 Object.defineProperty(FormGroupDirective.prototype, "formDirective", {
40538 /**
40539 * @return {?}
40540 */
40541 get: function () { return this; },
40542 enumerable: true,
40543 configurable: true
40544 });
40545 Object.defineProperty(FormGroupDirective.prototype, "control", {
40546 /**
40547 * @return {?}
40548 */
40549 get: function () { return this.form; },
40550 enumerable: true,
40551 configurable: true
40552 });
40553 Object.defineProperty(FormGroupDirective.prototype, "path", {
40554 /**
40555 * @return {?}
40556 */
40557 get: function () { return []; },
40558 enumerable: true,
40559 configurable: true
40560 });
40561 /**
40562 * @param {?} dir
40563 * @return {?}
40564 */
40565 FormGroupDirective.prototype.addControl = function (dir) {
40566 var /** @type {?} */ ctrl = this.form.get(dir.path);
40567 setUpControl(ctrl, dir);
40568 ctrl.updateValueAndValidity({ emitEvent: false });
40569 this.directives.push(dir);
40570 return ctrl;
40571 };
40572 /**
40573 * @param {?} dir
40574 * @return {?}
40575 */
40576 FormGroupDirective.prototype.getControl = function (dir) { return (this.form.get(dir.path)); };
40577 /**
40578 * @param {?} dir
40579 * @return {?}
40580 */
40581 FormGroupDirective.prototype.removeControl = function (dir) { remove$1(this.directives, dir); };
40582 /**
40583 * @param {?} dir
40584 * @return {?}
40585 */
40586 FormGroupDirective.prototype.addFormGroup = function (dir) {
40587 var /** @type {?} */ ctrl = this.form.get(dir.path);
40588 setUpFormContainer(ctrl, dir);
40589 ctrl.updateValueAndValidity({ emitEvent: false });
40590 };
40591 /**
40592 * @param {?} dir
40593 * @return {?}
40594 */
40595 FormGroupDirective.prototype.removeFormGroup = function (dir) { };
40596 /**
40597 * @param {?} dir
40598 * @return {?}
40599 */
40600 FormGroupDirective.prototype.getFormGroup = function (dir) { return (this.form.get(dir.path)); };
40601 /**
40602 * @param {?} dir
40603 * @return {?}
40604 */
40605 FormGroupDirective.prototype.addFormArray = function (dir) {
40606 var /** @type {?} */ ctrl = this.form.get(dir.path);
40607 setUpFormContainer(ctrl, dir);
40608 ctrl.updateValueAndValidity({ emitEvent: false });
40609 };
40610 /**
40611 * @param {?} dir
40612 * @return {?}
40613 */
40614 FormGroupDirective.prototype.removeFormArray = function (dir) { };
40615 /**
40616 * @param {?} dir
40617 * @return {?}
40618 */
40619 FormGroupDirective.prototype.getFormArray = function (dir) { return (this.form.get(dir.path)); };
40620 /**
40621 * @param {?} dir
40622 * @param {?} value
40623 * @return {?}
40624 */
40625 FormGroupDirective.prototype.updateModel = function (dir, value) {
40626 var /** @type {?} */ ctrl = (this.form.get(dir.path));
40627 ctrl.setValue(value);
40628 };
40629 /**
40630 * @param {?} $event
40631 * @return {?}
40632 */
40633 FormGroupDirective.prototype.onSubmit = function ($event) {
40634 this._submitted = true;
40635 this.ngSubmit.emit($event);
40636 return false;
40637 };
40638 /**
40639 * @return {?}
40640 */
40641 FormGroupDirective.prototype.onReset = function () { this.resetForm(); };
40642 /**
40643 * @param {?=} value
40644 * @return {?}
40645 */
40646 FormGroupDirective.prototype.resetForm = function (value) {
40647 if (value === void 0) { value = undefined; }
40648 this.form.reset(value);
40649 this._submitted = false;
40650 };
40651 /**
40652 * \@internal
40653 * @return {?}
40654 */
40655 FormGroupDirective.prototype._updateDomValue = function () {
40656 var _this = this;
40657 this.directives.forEach(function (dir) {
40658 var /** @type {?} */ newCtrl = _this.form.get(dir.path);
40659 if (dir._control !== newCtrl) {
40660 cleanUpControl(dir._control, dir);
40661 if (newCtrl)
40662 setUpControl(newCtrl, dir);
40663 dir._control = newCtrl;
40664 }
40665 });
40666 this.form._updateTreeValidity({ emitEvent: false });
40667 };
40668 /**
40669 * @return {?}
40670 */
40671 FormGroupDirective.prototype._updateRegistrations = function () {
40672 var _this = this;
40673 this.form._registerOnCollectionChange(function () { return _this._updateDomValue(); });
40674 if (this._oldForm)
40675 this._oldForm._registerOnCollectionChange(function () { });
40676 this._oldForm = this.form;
40677 };
40678 /**
40679 * @return {?}
40680 */
40681 FormGroupDirective.prototype._updateValidators = function () {
40682 var /** @type {?} */ sync = composeValidators(this._validators);
40683 this.form.validator = Validators.compose([/** @type {?} */ ((this.form.validator)), /** @type {?} */ ((sync))]);
40684 var /** @type {?} */ async = composeAsyncValidators(this._asyncValidators);
40685 this.form.asyncValidator = Validators.composeAsync([/** @type {?} */ ((this.form.asyncValidator)), /** @type {?} */ ((async))]);
40686 };
40687 /**
40688 * @return {?}
40689 */
40690 FormGroupDirective.prototype._checkFormPresent = function () {
40691 if (!this.form) {
40692 ReactiveErrors.missingFormException();
40693 }
40694 };
40695 return FormGroupDirective;
40696}(ControlContainer));
40697FormGroupDirective.decorators = [
40698 { type: Directive, args: [{
40699 selector: '[formGroup]',
40700 providers: [formDirectiveProvider$1],
40701 host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
40702 exportAs: 'ngForm'
40703 },] },
40704];
40705/**
40706 * @nocollapse
40707 */
40708FormGroupDirective.ctorParameters = function () { return [
40709 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
40710 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
40711]; };
40712FormGroupDirective.propDecorators = {
40713 'form': [{ type: Input, args: ['formGroup',] },],
40714 'ngSubmit': [{ type: Output },],
40715};
40716/**
40717 * @template T
40718 * @param {?} list
40719 * @param {?} el
40720 * @return {?}
40721 */
40722function remove$1(list, el) {
40723 var /** @type {?} */ index = list.indexOf(el);
40724 if (index > -1) {
40725 list.splice(index, 1);
40726 }
40727}
40728/**
40729 * @license
40730 * Copyright Google Inc. All Rights Reserved.
40731 *
40732 * Use of this source code is governed by an MIT-style license that can be
40733 * found in the LICENSE file at https://angular.io/license
40734 */
40735var formGroupNameProvider = {
40736 provide: ControlContainer,
40737 useExisting: forwardRef(function () { return FormGroupName; })
40738};
40739/**
40740 * \@whatItDoes Syncs a nested {\@link FormGroup} to a DOM element.
40741 *
40742 * \@howToUse
40743 *
40744 * This directive can only be used with a parent {\@link FormGroupDirective} (selector:
40745 * `[formGroup]`).
40746 *
40747 * It accepts the string name of the nested {\@link FormGroup} you want to link, and
40748 * will look for a {\@link FormGroup} registered with that name in the parent
40749 * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
40750 *
40751 * Nested form groups can come in handy when you want to validate a sub-group of a
40752 * form separately from the rest or when you'd like to group the values of certain
40753 * controls into their own nested object.
40754 *
40755 * **Access the group**: You can access the associated {\@link FormGroup} using the
40756 * {\@link AbstractControl#get} method. Ex: `this.form.get('name')`.
40757 *
40758 * You can also access individual controls within the group using dot syntax.
40759 * Ex: `this.form.get('name.first')`
40760 *
40761 * **Get the value**: the `value` property is always synced and available on the
40762 * {\@link FormGroup}. See a full list of available properties in {\@link AbstractControl}.
40763 *
40764 * **Set the value**: You can set an initial value for each child control when instantiating
40765 * the {\@link FormGroup}, or you can set it programmatically later using
40766 * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
40767 *
40768 * **Listen to value**: If you want to listen to changes in the value of the group, you can
40769 * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
40770 * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
40771 * re-calculated.
40772 *
40773 * ### Example
40774 *
40775 * {\@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
40776 *
40777 * * **npm package**: `\@angular/forms`
40778 *
40779 * * **NgModule**: `ReactiveFormsModule`
40780 *
40781 * \@stable
40782 */
40783var FormGroupName = (function (_super) {
40784 __extends$1(FormGroupName, _super);
40785 /**
40786 * @param {?} parent
40787 * @param {?} validators
40788 * @param {?} asyncValidators
40789 */
40790 function FormGroupName(parent, validators, asyncValidators) {
40791 var _this = _super.call(this) || this;
40792 _this._parent = parent;
40793 _this._validators = validators;
40794 _this._asyncValidators = asyncValidators;
40795 return _this;
40796 }
40797 /**
40798 * \@internal
40799 * @return {?}
40800 */
40801 FormGroupName.prototype._checkParentType = function () {
40802 if (_hasInvalidParent(this._parent)) {
40803 ReactiveErrors.groupParentException();
40804 }
40805 };
40806 return FormGroupName;
40807}(AbstractFormGroupDirective));
40808FormGroupName.decorators = [
40809 { type: Directive, args: [{ selector: '[formGroupName]', providers: [formGroupNameProvider] },] },
40810];
40811/**
40812 * @nocollapse
40813 */
40814FormGroupName.ctorParameters = function () { return [
40815 { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
40816 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
40817 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
40818]; };
40819FormGroupName.propDecorators = {
40820 'name': [{ type: Input, args: ['formGroupName',] },],
40821};
40822var formArrayNameProvider = {
40823 provide: ControlContainer,
40824 useExisting: forwardRef(function () { return FormArrayName; })
40825};
40826/**
40827 * \@whatItDoes Syncs a nested {\@link FormArray} to a DOM element.
40828 *
40829 * \@howToUse
40830 *
40831 * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
40832 * `[formGroup]`).
40833 *
40834 * It accepts the string name of the nested {\@link FormArray} you want to link, and
40835 * will look for a {\@link FormArray} registered with that name in the parent
40836 * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
40837 *
40838 * Nested form arrays can come in handy when you have a group of form controls but
40839 * you're not sure how many there will be. Form arrays allow you to create new
40840 * form controls dynamically.
40841 *
40842 * **Access the array**: You can access the associated {\@link FormArray} using the
40843 * {\@link AbstractControl#get} method on the parent {\@link FormGroup}.
40844 * Ex: `this.form.get('cities')`.
40845 *
40846 * **Get the value**: the `value` property is always synced and available on the
40847 * {\@link FormArray}. See a full list of available properties in {\@link AbstractControl}.
40848 *
40849 * **Set the value**: You can set an initial value for each child control when instantiating
40850 * the {\@link FormArray}, or you can set the value programmatically later using the
40851 * {\@link FormArray}'s {\@link AbstractControl#setValue} or {\@link AbstractControl#patchValue}
40852 * methods.
40853 *
40854 * **Listen to value**: If you want to listen to changes in the value of the array, you can
40855 * subscribe to the {\@link FormArray}'s {\@link AbstractControl#valueChanges} event. You can also
40856 * listen to its {\@link AbstractControl#statusChanges} event to be notified when the validation
40857 * status is re-calculated.
40858 *
40859 * **Add new controls**: You can add new controls to the {\@link FormArray} dynamically by
40860 * calling its {\@link FormArray#push} method.
40861 * Ex: `this.form.get('cities').push(new FormControl());`
40862 *
40863 * ### Example
40864 *
40865 * {\@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
40866 *
40867 * * **npm package**: `\@angular/forms`
40868 *
40869 * * **NgModule**: `ReactiveFormsModule`
40870 *
40871 * \@stable
40872 */
40873var FormArrayName = (function (_super) {
40874 __extends$1(FormArrayName, _super);
40875 /**
40876 * @param {?} parent
40877 * @param {?} validators
40878 * @param {?} asyncValidators
40879 */
40880 function FormArrayName(parent, validators, asyncValidators) {
40881 var _this = _super.call(this) || this;
40882 _this._parent = parent;
40883 _this._validators = validators;
40884 _this._asyncValidators = asyncValidators;
40885 return _this;
40886 }
40887 /**
40888 * @return {?}
40889 */
40890 FormArrayName.prototype.ngOnInit = function () {
40891 this._checkParentType(); /** @type {?} */
40892 ((this.formDirective)).addFormArray(this);
40893 };
40894 /**
40895 * @return {?}
40896 */
40897 FormArrayName.prototype.ngOnDestroy = function () {
40898 if (this.formDirective) {
40899 this.formDirective.removeFormArray(this);
40900 }
40901 };
40902 Object.defineProperty(FormArrayName.prototype, "control", {
40903 /**
40904 * @return {?}
40905 */
40906 get: function () { return ((this.formDirective)).getFormArray(this); },
40907 enumerable: true,
40908 configurable: true
40909 });
40910 Object.defineProperty(FormArrayName.prototype, "formDirective", {
40911 /**
40912 * @return {?}
40913 */
40914 get: function () {
40915 return this._parent ? (this._parent.formDirective) : null;
40916 },
40917 enumerable: true,
40918 configurable: true
40919 });
40920 Object.defineProperty(FormArrayName.prototype, "path", {
40921 /**
40922 * @return {?}
40923 */
40924 get: function () { return controlPath(this.name, this._parent); },
40925 enumerable: true,
40926 configurable: true
40927 });
40928 Object.defineProperty(FormArrayName.prototype, "validator", {
40929 /**
40930 * @return {?}
40931 */
40932 get: function () { return composeValidators(this._validators); },
40933 enumerable: true,
40934 configurable: true
40935 });
40936 Object.defineProperty(FormArrayName.prototype, "asyncValidator", {
40937 /**
40938 * @return {?}
40939 */
40940 get: function () {
40941 return composeAsyncValidators(this._asyncValidators);
40942 },
40943 enumerable: true,
40944 configurable: true
40945 });
40946 /**
40947 * @return {?}
40948 */
40949 FormArrayName.prototype._checkParentType = function () {
40950 if (_hasInvalidParent(this._parent)) {
40951 ReactiveErrors.arrayParentException();
40952 }
40953 };
40954 return FormArrayName;
40955}(ControlContainer));
40956FormArrayName.decorators = [
40957 { type: Directive, args: [{ selector: '[formArrayName]', providers: [formArrayNameProvider] },] },
40958];
40959/**
40960 * @nocollapse
40961 */
40962FormArrayName.ctorParameters = function () { return [
40963 { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
40964 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
40965 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
40966]; };
40967FormArrayName.propDecorators = {
40968 'name': [{ type: Input, args: ['formArrayName',] },],
40969};
40970/**
40971 * @param {?} parent
40972 * @return {?}
40973 */
40974function _hasInvalidParent(parent) {
40975 return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) &&
40976 !(parent instanceof FormArrayName);
40977}
40978/**
40979 * @license
40980 * Copyright Google Inc. All Rights Reserved.
40981 *
40982 * Use of this source code is governed by an MIT-style license that can be
40983 * found in the LICENSE file at https://angular.io/license
40984 */
40985var controlNameBinding = {
40986 provide: NgControl,
40987 useExisting: forwardRef(function () { return FormControlName; })
40988};
40989/**
40990 * \@whatItDoes Syncs a {\@link FormControl} in an existing {\@link FormGroup} to a form control
40991 * element by name.
40992 *
40993 * In other words, this directive ensures that any values written to the {\@link FormControl}
40994 * instance programmatically will be written to the DOM element (model -> view). Conversely,
40995 * any values written to the DOM element through user input will be reflected in the
40996 * {\@link FormControl} instance (view -> model).
40997 *
40998 * \@howToUse
40999 *
41000 * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
41001 * `[formGroup]`).
41002 *
41003 * It accepts the string name of the {\@link FormControl} instance you want to
41004 * link, and will look for a {\@link FormControl} registered with that name in the
41005 * closest {\@link FormGroup} or {\@link FormArray} above it.
41006 *
41007 * **Access the control**: You can access the {\@link FormControl} associated with
41008 * this directive by using the {\@link AbstractControl#get get} method.
41009 * Ex: `this.form.get('first');`
41010 *
41011 * **Get value**: the `value` property is always synced and available on the {\@link FormControl}.
41012 * See a full list of available properties in {\@link AbstractControl}.
41013 *
41014 * **Set value**: You can set an initial value for the control when instantiating the
41015 * {\@link FormControl}, or you can set it programmatically later using
41016 * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
41017 *
41018 * **Listen to value**: If you want to listen to changes in the value of the control, you can
41019 * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
41020 * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
41021 * re-calculated.
41022 *
41023 * ### Example
41024 *
41025 * In this example, we create form controls for first name and last name.
41026 *
41027 * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
41028 *
41029 * To see `formControlName` examples with different form control types, see:
41030 *
41031 * * Radio buttons: {\@link RadioControlValueAccessor}
41032 * * Selects: {\@link SelectControlValueAccessor}
41033 *
41034 * **npm package**: `\@angular/forms`
41035 *
41036 * **NgModule**: {\@link ReactiveFormsModule}
41037 *
41038 * \@stable
41039 */
41040var FormControlName = (function (_super) {
41041 __extends$1(FormControlName, _super);
41042 /**
41043 * @param {?} parent
41044 * @param {?} validators
41045 * @param {?} asyncValidators
41046 * @param {?} valueAccessors
41047 */
41048 function FormControlName(parent, validators, asyncValidators, valueAccessors) {
41049 var _this = _super.call(this) || this;
41050 _this._added = false;
41051 _this.update = new EventEmitter();
41052 _this._parent = parent;
41053 _this._rawValidators = validators || [];
41054 _this._rawAsyncValidators = asyncValidators || [];
41055 _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
41056 return _this;
41057 }
41058 Object.defineProperty(FormControlName.prototype, "isDisabled", {
41059 /**
41060 * @param {?} isDisabled
41061 * @return {?}
41062 */
41063 set: function (isDisabled) { ReactiveErrors.disabledAttrWarning(); },
41064 enumerable: true,
41065 configurable: true
41066 });
41067 /**
41068 * @param {?} changes
41069 * @return {?}
41070 */
41071 FormControlName.prototype.ngOnChanges = function (changes) {
41072 if (!this._added)
41073 this._setUpControl();
41074 if (isPropertyUpdated(changes, this.viewModel)) {
41075 this.viewModel = this.model;
41076 this.formDirective.updateModel(this, this.model);
41077 }
41078 };
41079 /**
41080 * @return {?}
41081 */
41082 FormControlName.prototype.ngOnDestroy = function () {
41083 if (this.formDirective) {
41084 this.formDirective.removeControl(this);
41085 }
41086 };
41087 /**
41088 * @param {?} newValue
41089 * @return {?}
41090 */
41091 FormControlName.prototype.viewToModelUpdate = function (newValue) {
41092 this.viewModel = newValue;
41093 this.update.emit(newValue);
41094 };
41095 Object.defineProperty(FormControlName.prototype, "path", {
41096 /**
41097 * @return {?}
41098 */
41099 get: function () { return controlPath(this.name, /** @type {?} */ ((this._parent))); },
41100 enumerable: true,
41101 configurable: true
41102 });
41103 Object.defineProperty(FormControlName.prototype, "formDirective", {
41104 /**
41105 * @return {?}
41106 */
41107 get: function () { return this._parent ? this._parent.formDirective : null; },
41108 enumerable: true,
41109 configurable: true
41110 });
41111 Object.defineProperty(FormControlName.prototype, "validator", {
41112 /**
41113 * @return {?}
41114 */
41115 get: function () { return composeValidators(this._rawValidators); },
41116 enumerable: true,
41117 configurable: true
41118 });
41119 Object.defineProperty(FormControlName.prototype, "asyncValidator", {
41120 /**
41121 * @return {?}
41122 */
41123 get: function () {
41124 return ((composeAsyncValidators(this._rawAsyncValidators)));
41125 },
41126 enumerable: true,
41127 configurable: true
41128 });
41129 Object.defineProperty(FormControlName.prototype, "control", {
41130 /**
41131 * @return {?}
41132 */
41133 get: function () { return this._control; },
41134 enumerable: true,
41135 configurable: true
41136 });
41137 /**
41138 * @return {?}
41139 */
41140 FormControlName.prototype._checkParentType = function () {
41141 if (!(this._parent instanceof FormGroupName) &&
41142 this._parent instanceof AbstractFormGroupDirective) {
41143 ReactiveErrors.ngModelGroupException();
41144 }
41145 else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) &&
41146 !(this._parent instanceof FormArrayName)) {
41147 ReactiveErrors.controlParentException();
41148 }
41149 };
41150 /**
41151 * @return {?}
41152 */
41153 FormControlName.prototype._setUpControl = function () {
41154 this._checkParentType();
41155 this._control = this.formDirective.addControl(this);
41156 if (this.control.disabled && ((this.valueAccessor)).setDisabledState) {
41157 ((((this.valueAccessor)).setDisabledState))(true);
41158 }
41159 this._added = true;
41160 };
41161 return FormControlName;
41162}(NgControl));
41163FormControlName.decorators = [
41164 { type: Directive, args: [{ selector: '[formControlName]', providers: [controlNameBinding] },] },
41165];
41166/**
41167 * @nocollapse
41168 */
41169FormControlName.ctorParameters = function () { return [
41170 { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
41171 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
41172 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
41173 { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
41174]; };
41175FormControlName.propDecorators = {
41176 'name': [{ type: Input, args: ['formControlName',] },],
41177 'model': [{ type: Input, args: ['ngModel',] },],
41178 'update': [{ type: Output, args: ['ngModelChange',] },],
41179 'isDisabled': [{ type: Input, args: ['disabled',] },],
41180};
41181/**
41182 * @license
41183 * Copyright Google Inc. All Rights Reserved.
41184 *
41185 * Use of this source code is governed by an MIT-style license that can be
41186 * found in the LICENSE file at https://angular.io/license
41187 */
41188var REQUIRED_VALIDATOR = {
41189 provide: NG_VALIDATORS,
41190 useExisting: forwardRef(function () { return RequiredValidator; }),
41191 multi: true
41192};
41193var CHECKBOX_REQUIRED_VALIDATOR = {
41194 provide: NG_VALIDATORS,
41195 useExisting: forwardRef(function () { return CheckboxRequiredValidator; }),
41196 multi: true
41197};
41198/**
41199 * A Directive that adds the `required` validator to any controls marked with the
41200 * `required` attribute, via the {\@link NG_VALIDATORS} binding.
41201 *
41202 * ### Example
41203 *
41204 * ```
41205 * <input name="fullName" ngModel required>
41206 * ```
41207 *
41208 * \@stable
41209 */
41210var RequiredValidator = (function () {
41211 function RequiredValidator() {
41212 }
41213 Object.defineProperty(RequiredValidator.prototype, "required", {
41214 /**
41215 * @return {?}
41216 */
41217 get: function () { return this._required; },
41218 /**
41219 * @param {?} value
41220 * @return {?}
41221 */
41222 set: function (value) {
41223 this._required = value != null && value !== false && "" + value !== 'false';
41224 if (this._onChange)
41225 this._onChange();
41226 },
41227 enumerable: true,
41228 configurable: true
41229 });
41230 /**
41231 * @param {?} c
41232 * @return {?}
41233 */
41234 RequiredValidator.prototype.validate = function (c) {
41235 return this.required ? Validators.required(c) : null;
41236 };
41237 /**
41238 * @param {?} fn
41239 * @return {?}
41240 */
41241 RequiredValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
41242 return RequiredValidator;
41243}());
41244RequiredValidator.decorators = [
41245 { type: Directive, args: [{
41246 selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
41247 providers: [REQUIRED_VALIDATOR],
41248 host: { '[attr.required]': 'required ? "" : null' }
41249 },] },
41250];
41251/**
41252 * @nocollapse
41253 */
41254RequiredValidator.ctorParameters = function () { return []; };
41255RequiredValidator.propDecorators = {
41256 'required': [{ type: Input },],
41257};
41258/**
41259 * A Directive that adds the `required` validator to checkbox controls marked with the
41260 * `required` attribute, via the {\@link NG_VALIDATORS} binding.
41261 *
41262 * ### Example
41263 *
41264 * ```
41265 * <input type="checkbox" name="active" ngModel required>
41266 * ```
41267 *
41268 * \@experimental
41269 */
41270var CheckboxRequiredValidator = (function (_super) {
41271 __extends$1(CheckboxRequiredValidator, _super);
41272 function CheckboxRequiredValidator() {
41273 return _super !== null && _super.apply(this, arguments) || this;
41274 }
41275 /**
41276 * @param {?} c
41277 * @return {?}
41278 */
41279 CheckboxRequiredValidator.prototype.validate = function (c) {
41280 return this.required ? Validators.requiredTrue(c) : null;
41281 };
41282 return CheckboxRequiredValidator;
41283}(RequiredValidator));
41284CheckboxRequiredValidator.decorators = [
41285 { type: Directive, args: [{
41286 selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
41287 providers: [CHECKBOX_REQUIRED_VALIDATOR],
41288 host: { '[attr.required]': 'required ? "" : null' }
41289 },] },
41290];
41291/**
41292 * @nocollapse
41293 */
41294CheckboxRequiredValidator.ctorParameters = function () { return []; };
41295/**
41296 * Provider which adds {\@link EmailValidator} to {\@link NG_VALIDATORS}.
41297 */
41298var EMAIL_VALIDATOR = {
41299 provide: NG_VALIDATORS,
41300 useExisting: forwardRef(function () { return EmailValidator; }),
41301 multi: true
41302};
41303/**
41304 * A Directive that adds the `email` validator to controls marked with the
41305 * `email` attribute, via the {\@link NG_VALIDATORS} binding.
41306 *
41307 * ### Example
41308 *
41309 * ```
41310 * <input type="email" name="email" ngModel email>
41311 * <input type="email" name="email" ngModel email="true">
41312 * <input type="email" name="email" ngModel [email]="true">
41313 * ```
41314 *
41315 * \@experimental
41316 */
41317var EmailValidator = (function () {
41318 function EmailValidator() {
41319 }
41320 Object.defineProperty(EmailValidator.prototype, "email", {
41321 /**
41322 * @param {?} value
41323 * @return {?}
41324 */
41325 set: function (value) {
41326 this._enabled = value === '' || value === true || value === 'true';
41327 if (this._onChange)
41328 this._onChange();
41329 },
41330 enumerable: true,
41331 configurable: true
41332 });
41333 /**
41334 * @param {?} c
41335 * @return {?}
41336 */
41337 EmailValidator.prototype.validate = function (c) {
41338 return this._enabled ? Validators.email(c) : null;
41339 };
41340 /**
41341 * @param {?} fn
41342 * @return {?}
41343 */
41344 EmailValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
41345 return EmailValidator;
41346}());
41347EmailValidator.decorators = [
41348 { type: Directive, args: [{
41349 selector: '[email][formControlName],[email][formControl],[email][ngModel]',
41350 providers: [EMAIL_VALIDATOR]
41351 },] },
41352];
41353/**
41354 * @nocollapse
41355 */
41356EmailValidator.ctorParameters = function () { return []; };
41357EmailValidator.propDecorators = {
41358 'email': [{ type: Input },],
41359};
41360/**
41361 * Provider which adds {\@link MinLengthValidator} to {\@link NG_VALIDATORS}.
41362 *
41363 * ## Example:
41364 *
41365 * {\@example common/forms/ts/validators/validators.ts region='min'}
41366 */
41367var MIN_LENGTH_VALIDATOR = {
41368 provide: NG_VALIDATORS,
41369 useExisting: forwardRef(function () { return MinLengthValidator; }),
41370 multi: true
41371};
41372/**
41373 * A directive which installs the {\@link MinLengthValidator} for any `formControlName`,
41374 * `formControl`, or control with `ngModel` that also has a `minlength` attribute.
41375 *
41376 * \@stable
41377 */
41378var MinLengthValidator = (function () {
41379 function MinLengthValidator() {
41380 }
41381 /**
41382 * @param {?} changes
41383 * @return {?}
41384 */
41385 MinLengthValidator.prototype.ngOnChanges = function (changes) {
41386 if ('minlength' in changes) {
41387 this._createValidator();
41388 if (this._onChange)
41389 this._onChange();
41390 }
41391 };
41392 /**
41393 * @param {?} c
41394 * @return {?}
41395 */
41396 MinLengthValidator.prototype.validate = function (c) {
41397 return this.minlength == null ? null : this._validator(c);
41398 };
41399 /**
41400 * @param {?} fn
41401 * @return {?}
41402 */
41403 MinLengthValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
41404 /**
41405 * @return {?}
41406 */
41407 MinLengthValidator.prototype._createValidator = function () {
41408 this._validator = Validators.minLength(parseInt(this.minlength, 10));
41409 };
41410 return MinLengthValidator;
41411}());
41412MinLengthValidator.decorators = [
41413 { type: Directive, args: [{
41414 selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
41415 providers: [MIN_LENGTH_VALIDATOR],
41416 host: { '[attr.minlength]': 'minlength ? minlength : null' }
41417 },] },
41418];
41419/**
41420 * @nocollapse
41421 */
41422MinLengthValidator.ctorParameters = function () { return []; };
41423MinLengthValidator.propDecorators = {
41424 'minlength': [{ type: Input },],
41425};
41426/**
41427 * Provider which adds {\@link MaxLengthValidator} to {\@link NG_VALIDATORS}.
41428 *
41429 * ## Example:
41430 *
41431 * {\@example common/forms/ts/validators/validators.ts region='max'}
41432 */
41433var MAX_LENGTH_VALIDATOR = {
41434 provide: NG_VALIDATORS,
41435 useExisting: forwardRef(function () { return MaxLengthValidator; }),
41436 multi: true
41437};
41438/**
41439 * A directive which installs the {\@link MaxLengthValidator} for any `formControlName,
41440 * `formControl`,
41441 * or control with `ngModel` that also has a `maxlength` attribute.
41442 *
41443 * \@stable
41444 */
41445var MaxLengthValidator = (function () {
41446 function MaxLengthValidator() {
41447 }
41448 /**
41449 * @param {?} changes
41450 * @return {?}
41451 */
41452 MaxLengthValidator.prototype.ngOnChanges = function (changes) {
41453 if ('maxlength' in changes) {
41454 this._createValidator();
41455 if (this._onChange)
41456 this._onChange();
41457 }
41458 };
41459 /**
41460 * @param {?} c
41461 * @return {?}
41462 */
41463 MaxLengthValidator.prototype.validate = function (c) {
41464 return this.maxlength != null ? this._validator(c) : null;
41465 };
41466 /**
41467 * @param {?} fn
41468 * @return {?}
41469 */
41470 MaxLengthValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
41471 /**
41472 * @return {?}
41473 */
41474 MaxLengthValidator.prototype._createValidator = function () {
41475 this._validator = Validators.maxLength(parseInt(this.maxlength, 10));
41476 };
41477 return MaxLengthValidator;
41478}());
41479MaxLengthValidator.decorators = [
41480 { type: Directive, args: [{
41481 selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
41482 providers: [MAX_LENGTH_VALIDATOR],
41483 host: { '[attr.maxlength]': 'maxlength ? maxlength : null' }
41484 },] },
41485];
41486/**
41487 * @nocollapse
41488 */
41489MaxLengthValidator.ctorParameters = function () { return []; };
41490MaxLengthValidator.propDecorators = {
41491 'maxlength': [{ type: Input },],
41492};
41493var PATTERN_VALIDATOR = {
41494 provide: NG_VALIDATORS,
41495 useExisting: forwardRef(function () { return PatternValidator; }),
41496 multi: true
41497};
41498/**
41499 * A Directive that adds the `pattern` validator to any controls marked with the
41500 * `pattern` attribute, via the {\@link NG_VALIDATORS} binding. Uses attribute value
41501 * as the regex to validate Control value against. Follows pattern attribute
41502 * semantics; i.e. regex must match entire Control value.
41503 *
41504 * ### Example
41505 *
41506 * ```
41507 * <input [name]="fullName" pattern="[a-zA-Z ]*" ngModel>
41508 * ```
41509 * \@stable
41510 */
41511var PatternValidator = (function () {
41512 function PatternValidator() {
41513 }
41514 /**
41515 * @param {?} changes
41516 * @return {?}
41517 */
41518 PatternValidator.prototype.ngOnChanges = function (changes) {
41519 if ('pattern' in changes) {
41520 this._createValidator();
41521 if (this._onChange)
41522 this._onChange();
41523 }
41524 };
41525 /**
41526 * @param {?} c
41527 * @return {?}
41528 */
41529 PatternValidator.prototype.validate = function (c) { return this._validator(c); };
41530 /**
41531 * @param {?} fn
41532 * @return {?}
41533 */
41534 PatternValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
41535 /**
41536 * @return {?}
41537 */
41538 PatternValidator.prototype._createValidator = function () { this._validator = Validators.pattern(this.pattern); };
41539 return PatternValidator;
41540}());
41541PatternValidator.decorators = [
41542 { type: Directive, args: [{
41543 selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
41544 providers: [PATTERN_VALIDATOR],
41545 host: { '[attr.pattern]': 'pattern ? pattern : null' }
41546 },] },
41547];
41548/**
41549 * @nocollapse
41550 */
41551PatternValidator.ctorParameters = function () { return []; };
41552PatternValidator.propDecorators = {
41553 'pattern': [{ type: Input },],
41554};
41555/**
41556 * @license
41557 * Copyright Google Inc. All Rights Reserved.
41558 *
41559 * Use of this source code is governed by an MIT-style license that can be
41560 * found in the LICENSE file at https://angular.io/license
41561 */
41562/**
41563 * \@whatItDoes Creates an {\@link AbstractControl} from a user-specified configuration.
41564 *
41565 * It is essentially syntactic sugar that shortens the `new FormGroup()`,
41566 * `new FormControl()`, and `new FormArray()` boilerplate that can build up in larger
41567 * forms.
41568 *
41569 * \@howToUse
41570 *
41571 * To use, inject `FormBuilder` into your component class. You can then call its methods
41572 * directly.
41573 *
41574 * {\@example forms/ts/formBuilder/form_builder_example.ts region='Component'}
41575 *
41576 * * **npm package**: `\@angular/forms`
41577 *
41578 * * **NgModule**: {\@link ReactiveFormsModule}
41579 *
41580 * \@stable
41581 */
41582var FormBuilder = (function () {
41583 function FormBuilder() {
41584 }
41585 /**
41586 * Construct a new {\@link FormGroup} with the given map of configuration.
41587 * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`.
41588 *
41589 * See the {\@link FormGroup} constructor for more details.
41590 * @param {?} controlsConfig
41591 * @param {?=} extra
41592 * @return {?}
41593 */
41594 FormBuilder.prototype.group = function (controlsConfig, extra) {
41595 if (extra === void 0) { extra = null; }
41596 var /** @type {?} */ controls = this._reduceControls(controlsConfig);
41597 var /** @type {?} */ validator = extra != null ? extra['validator'] : null;
41598 var /** @type {?} */ asyncValidator = extra != null ? extra['asyncValidator'] : null;
41599 return new FormGroup(controls, validator, asyncValidator);
41600 };
41601 /**
41602 * Construct a new {\@link FormControl} with the given `formState`,`validator`, and
41603 * `asyncValidator`.
41604 *
41605 * `formState` can either be a standalone value for the form control or an object
41606 * that contains both a value and a disabled status.
41607 *
41608 * @param {?} formState
41609 * @param {?=} validator
41610 * @param {?=} asyncValidator
41611 * @return {?}
41612 */
41613 FormBuilder.prototype.control = function (formState, validator, asyncValidator) {
41614 return new FormControl(formState, validator, asyncValidator);
41615 };
41616 /**
41617 * Construct a {\@link FormArray} from the given `controlsConfig` array of
41618 * configuration, with the given optional `validator` and `asyncValidator`.
41619 * @param {?} controlsConfig
41620 * @param {?=} validator
41621 * @param {?=} asyncValidator
41622 * @return {?}
41623 */
41624 FormBuilder.prototype.array = function (controlsConfig, validator, asyncValidator) {
41625 var _this = this;
41626 var /** @type {?} */ controls = controlsConfig.map(function (c) { return _this._createControl(c); });
41627 return new FormArray(controls, validator, asyncValidator);
41628 };
41629 /**
41630 * \@internal
41631 * @param {?} controlsConfig
41632 * @return {?}
41633 */
41634 FormBuilder.prototype._reduceControls = function (controlsConfig) {
41635 var _this = this;
41636 var /** @type {?} */ controls = {};
41637 Object.keys(controlsConfig).forEach(function (controlName) {
41638 controls[controlName] = _this._createControl(controlsConfig[controlName]);
41639 });
41640 return controls;
41641 };
41642 /**
41643 * \@internal
41644 * @param {?} controlConfig
41645 * @return {?}
41646 */
41647 FormBuilder.prototype._createControl = function (controlConfig) {
41648 if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup ||
41649 controlConfig instanceof FormArray) {
41650 return controlConfig;
41651 }
41652 else if (Array.isArray(controlConfig)) {
41653 var /** @type {?} */ value = controlConfig[0];
41654 var /** @type {?} */ validator = controlConfig.length > 1 ? controlConfig[1] : null;
41655 var /** @type {?} */ asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null;
41656 return this.control(value, validator, asyncValidator);
41657 }
41658 else {
41659 return this.control(controlConfig);
41660 }
41661 };
41662 return FormBuilder;
41663}());
41664FormBuilder.decorators = [
41665 { type: Injectable },
41666];
41667/**
41668 * @nocollapse
41669 */
41670FormBuilder.ctorParameters = function () { return []; };
41671/**
41672 * @license
41673 * Copyright Google Inc. All Rights Reserved.
41674 *
41675 * Use of this source code is governed by an MIT-style license that can be
41676 * found in the LICENSE file at https://angular.io/license
41677 */
41678/**
41679 * @module
41680 * @description
41681 * Entry point for all public APIs of the common package.
41682 */
41683/**
41684 * \@stable
41685 */
41686var VERSION$3 = new Version('4.4.3');
41687/**
41688 * @license
41689 * Copyright Google Inc. All Rights Reserved.
41690 *
41691 * Use of this source code is governed by an MIT-style license that can be
41692 * found in the LICENSE file at https://angular.io/license
41693 */
41694/**
41695 * \@whatItDoes Adds `novalidate` attribute to all forms by default.
41696 *
41697 * `novalidate` is used to disable browser's native form validation.
41698 *
41699 * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
41700 *
41701 * ```
41702 * <form ngNativeValidate></form>
41703 * ```
41704 *
41705 * \@experimental
41706 */
41707var NgNoValidate = (function () {
41708 function NgNoValidate() {
41709 }
41710 return NgNoValidate;
41711}());
41712NgNoValidate.decorators = [
41713 { type: Directive, args: [{
41714 selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
41715 host: { 'novalidate': '' },
41716 },] },
41717];
41718/**
41719 * @nocollapse
41720 */
41721NgNoValidate.ctorParameters = function () { return []; };
41722/**
41723 * @license
41724 * Copyright Google Inc. All Rights Reserved.
41725 *
41726 * Use of this source code is governed by an MIT-style license that can be
41727 * found in the LICENSE file at https://angular.io/license
41728 */
41729var SHARED_FORM_DIRECTIVES = [
41730 NgNoValidate,
41731 NgSelectOption,
41732 NgSelectMultipleOption,
41733 DefaultValueAccessor,
41734 NumberValueAccessor,
41735 RangeValueAccessor,
41736 CheckboxControlValueAccessor,
41737 SelectControlValueAccessor,
41738 SelectMultipleControlValueAccessor,
41739 RadioControlValueAccessor,
41740 NgControlStatus,
41741 NgControlStatusGroup,
41742 RequiredValidator,
41743 MinLengthValidator,
41744 MaxLengthValidator,
41745 PatternValidator,
41746 CheckboxRequiredValidator,
41747 EmailValidator,
41748];
41749var TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm];
41750var REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
41751/**
41752 * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
41753 */
41754var InternalFormsSharedModule = (function () {
41755 function InternalFormsSharedModule() {
41756 }
41757 return InternalFormsSharedModule;
41758}());
41759InternalFormsSharedModule.decorators = [
41760 { type: NgModule, args: [{
41761 declarations: SHARED_FORM_DIRECTIVES,
41762 exports: SHARED_FORM_DIRECTIVES,
41763 },] },
41764];
41765/**
41766 * @nocollapse
41767 */
41768InternalFormsSharedModule.ctorParameters = function () { return []; };
41769/**
41770 * @license
41771 * Copyright Google Inc. All Rights Reserved.
41772 *
41773 * Use of this source code is governed by an MIT-style license that can be
41774 * found in the LICENSE file at https://angular.io/license
41775 */
41776/**
41777 * The ng module for forms.
41778 * \@stable
41779 */
41780var FormsModule = (function () {
41781 function FormsModule() {
41782 }
41783 return FormsModule;
41784}());
41785FormsModule.decorators = [
41786 { type: NgModule, args: [{
41787 declarations: TEMPLATE_DRIVEN_DIRECTIVES,
41788 providers: [RadioControlRegistry],
41789 exports: [InternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
41790 },] },
41791];
41792/**
41793 * @nocollapse
41794 */
41795FormsModule.ctorParameters = function () { return []; };
41796/**
41797 * The ng module for reactive forms.
41798 * \@stable
41799 */
41800var ReactiveFormsModule = (function () {
41801 function ReactiveFormsModule() {
41802 }
41803 return ReactiveFormsModule;
41804}());
41805ReactiveFormsModule.decorators = [
41806 { type: NgModule, args: [{
41807 declarations: [REACTIVE_DRIVEN_DIRECTIVES],
41808 providers: [FormBuilder, RadioControlRegistry],
41809 exports: [InternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
41810 },] },
41811];
41812/**
41813 * @nocollapse
41814 */
41815ReactiveFormsModule.ctorParameters = function () { return []; };
41816
41817/**
41818 * @hidden
41819 */
41820var Form = (function () {
41821 function Form() {
41822 this._focused = null;
41823 this._ids = -1;
41824 this._inputs = [];
41825 }
41826 /**
41827 * @param {?} input
41828 * @return {?}
41829 */
41830 Form.prototype.register = function (input) {
41831 this._inputs.push(input);
41832 };
41833 /**
41834 * @param {?} input
41835 * @return {?}
41836 */
41837 Form.prototype.deregister = function (input) {
41838 removeArrayItem(this._inputs, input);
41839 this.unsetAsFocused(input);
41840 };
41841 /**
41842 * @param {?} input
41843 * @return {?}
41844 */
41845 Form.prototype.setAsFocused = function (input) {
41846 this._focused = input;
41847 };
41848 /**
41849 * @param {?} input
41850 * @return {?}
41851 */
41852 Form.prototype.unsetAsFocused = function (input) {
41853 if (input === this._focused) {
41854 this._focused = null;
41855 }
41856 };
41857 /**
41858 * Focuses the next input element, if it exists.
41859 * @param {?} currentInput
41860 * @return {?}
41861 */
41862 Form.prototype.tabFocus = function (currentInput) {
41863 var /** @type {?} */ inputs = this._inputs;
41864 var /** @type {?} */ index = inputs.indexOf(currentInput) + 1;
41865 if (index > 0 && index < inputs.length) {
41866 var /** @type {?} */ nextInput = inputs[index];
41867 if (nextInput !== this._focused) {
41868 (void 0) /* console.debug */;
41869 return nextInput.initFocus();
41870 }
41871 }
41872 index = inputs.indexOf(this._focused);
41873 if (index > 0) {
41874 var /** @type {?} */ previousInput = inputs[index - 1];
41875 if (previousInput) {
41876 (void 0) /* console.debug */;
41877 previousInput.initFocus();
41878 }
41879 }
41880 };
41881 /**
41882 * @return {?}
41883 */
41884 Form.prototype.nextId = function () {
41885 return ++this._ids;
41886 };
41887 return Form;
41888}());
41889Form.decorators = [
41890 { type: Injectable },
41891];
41892/**
41893 * @nocollapse
41894 */
41895Form.ctorParameters = function () { return []; };
41896/**
41897 * @hidden
41898 * @abstract
41899 */
41900var IonicTapInput = (function () {
41901 function IonicTapInput() {
41902 }
41903 /**
41904 * @abstract
41905 * @return {?}
41906 */
41907 IonicTapInput.prototype.initFocus = function () { };
41908 /**
41909 * @abstract
41910 * @return {?}
41911 */
41912 IonicTapInput.prototype.checked = function () { };
41913 /**
41914 * @abstract
41915 * @param {?} val
41916 * @return {?}
41917 */
41918 IonicTapInput.prototype.checked = function (val) { };
41919 /**
41920 * @abstract
41921 * @return {?}
41922 */
41923 IonicTapInput.prototype.disabled = function () { };
41924 /**
41925 * @abstract
41926 * @param {?} val
41927 * @return {?}
41928 */
41929 IonicTapInput.prototype.disabled = function (val) { };
41930 return IonicTapInput;
41931}());
41932/**
41933 * @hidden
41934 * @abstract
41935 */
41936var IonicFormInput = (function () {
41937 function IonicFormInput() {
41938 }
41939 /**
41940 * @abstract
41941 * @return {?}
41942 */
41943 IonicFormInput.prototype.initFocus = function () { };
41944 return IonicFormInput;
41945}());
41946
41947var TimeoutDebouncer = (function () {
41948 /**
41949 * @param {?} wait
41950 */
41951 function TimeoutDebouncer(wait) {
41952 this.wait = wait;
41953 this.timer = null;
41954 }
41955 /**
41956 * @param {?} callback
41957 * @return {?}
41958 */
41959 TimeoutDebouncer.prototype.debounce = function (callback) {
41960 this.callback = callback;
41961 this.schedule();
41962 };
41963 /**
41964 * @return {?}
41965 */
41966 TimeoutDebouncer.prototype.schedule = function () {
41967 this.cancel();
41968 if (this.wait <= 0) {
41969 this.callback();
41970 }
41971 else {
41972 this.timer = setTimeout(this.callback, this.wait);
41973 }
41974 };
41975 /**
41976 * @return {?}
41977 */
41978 TimeoutDebouncer.prototype.cancel = function () {
41979 if (this.timer) {
41980 clearTimeout(this.timer);
41981 this.timer = null;
41982 }
41983 };
41984 return TimeoutDebouncer;
41985}());
41986
41987var __extends$38 = (undefined && undefined.__extends) || (function () {
41988 var extendStatics = Object.setPrototypeOf ||
41989 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
41990 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
41991 return function (d, b) {
41992 extendStatics(d, b);
41993 function __() { this.constructor = d; }
41994 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
41995 };
41996})();
41997var BaseInput = (function (_super) {
41998 __extends$38(BaseInput, _super);
41999 /**
42000 * @param {?} config
42001 * @param {?} elementRef
42002 * @param {?} renderer
42003 * @param {?} name
42004 * @param {?} _defaultValue
42005 * @param {?} _form
42006 * @param {?} _item
42007 * @param {?} _ngControl
42008 */
42009 function BaseInput(config, elementRef, renderer, name, _defaultValue, _form, _item, _ngControl) {
42010 var _this = _super.call(this, config, elementRef, renderer, name) || this;
42011 _this._defaultValue = _defaultValue;
42012 _this._form = _form;
42013 _this._item = _item;
42014 _this._ngControl = _ngControl;
42015 _this._isFocus = false;
42016 _this._disabled = false;
42017 _this._debouncer = new TimeoutDebouncer(0);
42018 _this._init = false;
42019 _this._initModel = false;
42020 /**
42021 * \@output {Range} Emitted when the range selector drag starts.
42022 */
42023 _this.ionFocus = new EventEmitter();
42024 /**
42025 * \@output {Range} Emitted when the range value changes.
42026 */
42027 _this.ionChange = new EventEmitter();
42028 /**
42029 * \@output {Range} Emitted when the range selector drag ends.
42030 */
42031 _this.ionBlur = new EventEmitter();
42032 _form && _form.register(_this);
42033 _this._value = deepCopy(_this._defaultValue);
42034 if (_item) {
42035 (void 0) /* assert */;
42036 _this.id = name + '-' + _item.registerInput(name);
42037 _this._labelId = _item.labelId;
42038 _this._item.setElementClass('item-' + name, true);
42039 }
42040 // If the user passed a ngControl we need to set the valueAccessor
42041 if (_ngControl) {
42042 _ngControl.valueAccessor = _this;
42043 }
42044 return _this;
42045 }
42046 Object.defineProperty(BaseInput.prototype, "disabled", {
42047 /**
42048 * \@input {boolean} If true, the user cannot interact with this element.
42049 * @return {?}
42050 */
42051 get: function () {
42052 return this._disabled;
42053 },
42054 /**
42055 * @param {?} val
42056 * @return {?}
42057 */
42058 set: function (val) {
42059 this.setDisabledState(val);
42060 },
42061 enumerable: true,
42062 configurable: true
42063 });
42064 Object.defineProperty(BaseInput.prototype, "value", {
42065 /**
42066 * @return {?}
42067 */
42068 get: function () {
42069 return this._value;
42070 },
42071 /**
42072 * @param {?} val
42073 * @return {?}
42074 */
42075 set: function (val) {
42076 if (this._writeValue(val)) {
42077 this.onChange();
42078 this._fireIonChange();
42079 }
42080 },
42081 enumerable: true,
42082 configurable: true
42083 });
42084 /**
42085 * @param {?} val
42086 * @return {?}
42087 */
42088 BaseInput.prototype.setValue = function (val) {
42089 this.value = val;
42090 };
42091 /**
42092 * @hidden
42093 * @param {?} isDisabled
42094 * @return {?}
42095 */
42096 BaseInput.prototype.setDisabledState = function (isDisabled) {
42097 this._disabled = isDisabled = isTrueProperty(isDisabled);
42098 this._item && this._item.setElementClass("item-" + this._componentName + "-disabled", isDisabled);
42099 };
42100 /**
42101 * @hidden
42102 * @param {?} val
42103 * @return {?}
42104 */
42105 BaseInput.prototype.writeValue = function (val) {
42106 if (this._writeValue(val)) {
42107 if (this._initModel) {
42108 this._fireIonChange();
42109 }
42110 else if (this._init) {
42111 // ngModel fires the first time too late, we need to skip the first ngModel update
42112 this._initModel = true;
42113 }
42114 }
42115 };
42116 /**
42117 * @hidden
42118 * @param {?} val
42119 * @return {?}
42120 */
42121 BaseInput.prototype._writeValue = function (val) {
42122 (void 0) /* assert */;
42123 if (isUndefined(val)) {
42124 return false;
42125 }
42126 var /** @type {?} */ normalized = (val === null)
42127 ? deepCopy(this._defaultValue)
42128 : this._inputNormalize(val);
42129 var /** @type {?} */ notUpdate = isUndefined(normalized) || !this._inputShouldChange(normalized);
42130 if (notUpdate) {
42131 return false;
42132 }
42133 (void 0) /* console.debug */;
42134 this._value = normalized;
42135 if (this._init) {
42136 this._inputUpdated();
42137 }
42138 return true;
42139 };
42140 /**
42141 * @hidden
42142 * @return {?}
42143 */
42144 BaseInput.prototype._fireIonChange = function () {
42145 var _this = this;
42146 if (this._init) {
42147 this._debouncer.debounce(function () {
42148 (void 0) /* assert */;
42149 _this.ionChange.emit(_this._inputChangeEvent());
42150 _this._initModel = true;
42151 });
42152 }
42153 };
42154 /**
42155 * @hidden
42156 * @param {?} fn
42157 * @return {?}
42158 */
42159 BaseInput.prototype.registerOnChange = function (fn) {
42160 this._onChanged = fn;
42161 };
42162 /**
42163 * @hidden
42164 * @param {?} fn
42165 * @return {?}
42166 */
42167 BaseInput.prototype.registerOnTouched = function (fn) {
42168 this._onTouched = fn;
42169 };
42170 /**
42171 * @hidden
42172 * @return {?}
42173 */
42174 BaseInput.prototype._initialize = function () {
42175 if (this._init) {
42176 (void 0) /* assert */;
42177 return;
42178 }
42179 this._init = true;
42180 if (isPresent(this._value)) {
42181 this._inputUpdated();
42182 }
42183 };
42184 /**
42185 * @hidden
42186 * @return {?}
42187 */
42188 BaseInput.prototype._fireFocus = function () {
42189 if (this._isFocus) {
42190 return;
42191 }
42192 (void 0) /* console.debug */;
42193 this._form && this._form.setAsFocused(this);
42194 this._setFocus(true);
42195 this.ionFocus.emit(this);
42196 };
42197 /**
42198 * @hidden
42199 * @return {?}
42200 */
42201 BaseInput.prototype._fireBlur = function () {
42202 if (!this._isFocus) {
42203 return;
42204 }
42205 (void 0) /* console.debug */;
42206 this._form && this._form.unsetAsFocused(this);
42207 this._setFocus(false);
42208 this._fireTouched();
42209 this.ionBlur.emit(this);
42210 };
42211 /**
42212 * @hidden
42213 * @return {?}
42214 */
42215 BaseInput.prototype._fireTouched = function () {
42216 this._onTouched && this._onTouched();
42217 };
42218 /**
42219 * @hidden
42220 * @param {?} isFocused
42221 * @return {?}
42222 */
42223 BaseInput.prototype._setFocus = function (isFocused) {
42224 (void 0) /* assert */;
42225 (void 0) /* assert */;
42226 (void 0) /* assert */;
42227 this._isFocus = isFocused;
42228 var /** @type {?} */ item = this._item;
42229 if (item) {
42230 item.setElementClass('input-has-focus', isFocused);
42231 item.setElementClass('item-input-has-focus', isFocused);
42232 }
42233 this._inputUpdated();
42234 };
42235 /**
42236 * @hidden
42237 * @return {?}
42238 */
42239 BaseInput.prototype.onChange = function () {
42240 this._onChanged && this._onChanged(this._inputNgModelEvent());
42241 };
42242 /**
42243 * @hidden
42244 * @return {?}
42245 */
42246 BaseInput.prototype.isFocus = function () {
42247 return this._isFocus;
42248 };
42249 /**
42250 * @hidden
42251 * @return {?}
42252 */
42253 BaseInput.prototype.hasValue = function () {
42254 var /** @type {?} */ val = this._value;
42255 if (!isPresent(val)) {
42256 return false;
42257 }
42258 if (isArray$2(val) || isString(val)) {
42259 return val.length > 0;
42260 }
42261 return true;
42262 };
42263 /**
42264 * @hidden
42265 * @return {?}
42266 */
42267 BaseInput.prototype.focusNext = function () {
42268 this._form && this._form.tabFocus(this);
42269 };
42270 /**
42271 * @hidden
42272 * @return {?}
42273 */
42274 BaseInput.prototype.ngOnDestroy = function () {
42275 (void 0) /* assert */;
42276 var /** @type {?} */ form = this._form;
42277 form && form.deregister(this);
42278 this._init = false;
42279 };
42280 /**
42281 * @hidden
42282 * @return {?}
42283 */
42284 BaseInput.prototype.ngAfterContentInit = function () {
42285 this._initialize();
42286 };
42287 /**
42288 * @hidden
42289 * @return {?}
42290 */
42291 BaseInput.prototype.initFocus = function () {
42292 var /** @type {?} */ ele = this._elementRef.nativeElement.querySelector('button');
42293 ele && ele.focus();
42294 };
42295 /**
42296 * @hidden
42297 * @param {?} val
42298 * @return {?}
42299 */
42300 BaseInput.prototype._inputNormalize = function (val) {
42301 return val;
42302 };
42303 /**
42304 * @hidden
42305 * @param {?} val
42306 * @return {?}
42307 */
42308 BaseInput.prototype._inputShouldChange = function (val) {
42309 return this._value !== val;
42310 };
42311 /**
42312 * @hidden
42313 * @return {?}
42314 */
42315 BaseInput.prototype._inputChangeEvent = function () {
42316 return this;
42317 };
42318 /**
42319 * @hidden
42320 * @return {?}
42321 */
42322 BaseInput.prototype._inputNgModelEvent = function () {
42323 return this._value;
42324 };
42325 /**
42326 * @hidden
42327 * @return {?}
42328 */
42329 BaseInput.prototype._inputUpdated = function () {
42330 (void 0) /* assert */;
42331 var /** @type {?} */ item = this._item;
42332 if (item) {
42333 setControlCss(item, this._ngControl);
42334 // TODO remove all uses of input-has-value in v4
42335 var /** @type {?} */ hasValue = this.hasValue();
42336 item.setElementClass('input-has-value', hasValue);
42337 item.setElementClass('item-input-has-value', hasValue);
42338 }
42339 };
42340 return BaseInput;
42341}(Ion));
42342BaseInput.propDecorators = {
42343 'ionFocus': [{ type: Output },],
42344 'ionChange': [{ type: Output },],
42345 'ionBlur': [{ type: Output },],
42346 'disabled': [{ type: Input },],
42347};
42348/**
42349 * @param {?} element
42350 * @param {?} control
42351 * @return {?}
42352 */
42353function setControlCss(element, control) {
42354 if (!control) {
42355 return;
42356 }
42357 element.setElementClass('ng-untouched', control.untouched);
42358 element.setElementClass('ng-touched', control.touched);
42359 element.setElementClass('ng-pristine', control.pristine);
42360 element.setElementClass('ng-dirty', control.dirty);
42361 element.setElementClass('ng-valid', control.valid);
42362 element.setElementClass('ng-invalid', !control.valid);
42363}
42364
42365var __extends$40 = (undefined && undefined.__extends) || (function () {
42366 var extendStatics = Object.setPrototypeOf ||
42367 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
42368 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
42369 return function (d, b) {
42370 extendStatics(d, b);
42371 function __() { this.constructor = d; }
42372 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
42373 };
42374})();
42375/**
42376 * \@name Icon
42377 * \@description
42378 * Icons can be used on their own, or inside of a number of Ionic components.
42379 * For a full list of available icons, check out the
42380 * [Ionicons docs](../../../../ionicons).
42381 *
42382 * One feature of Ionicons in Ionic is when icon names are set, the actual icon
42383 * which is rendered can change slightly depending on the mode the app is
42384 * running from. For example, by setting the icon name of `alarm`, on iOS the
42385 * icon will automatically apply `ios-alarm`, and on Material Design it will
42386 * automatically apply `md-alarm`. This allows the developer to write the
42387 * markup once while Ionic applies the appropriate icon based on the mode.
42388 *
42389 * \@usage
42390 * ```html
42391 * <!-- automatically uses the correct "star" icon depending on the mode -->
42392 * <ion-icon name="star"></ion-icon>
42393 *
42394 * <!-- explicity set the icon for each mode -->
42395 * <ion-icon ios="ios-home" md="md-home"></ion-icon>
42396 *
42397 * <!-- always use the same icon, no matter what the mode -->
42398 * <ion-icon name="ios-clock"></ion-icon>
42399 * <ion-icon name="logo-twitter"></ion-icon>
42400 * ```
42401 *
42402 * \@demo /docs/demos/src/icon/
42403 * @see {\@link /docs/components#icons Icon Component Docs}
42404 *
42405 */
42406var Icon = (function (_super) {
42407 __extends$40(Icon, _super);
42408 /**
42409 * @param {?} config
42410 * @param {?} elementRef
42411 * @param {?} renderer
42412 */
42413 function Icon(config, elementRef, renderer) {
42414 var _this = _super.call(this, config, elementRef, renderer, 'icon') || this;
42415 /**
42416 * @hidden
42417 */
42418 _this._isActive = true;
42419 /**
42420 * @hidden
42421 */
42422 _this._name = '';
42423 /**
42424 * @hidden
42425 */
42426 _this._ios = '';
42427 /**
42428 * @hidden
42429 */
42430 _this._md = '';
42431 /**
42432 * @hidden
42433 */
42434 _this._css = '';
42435 /**
42436 * @hidden
42437 */
42438 _this._hidden = false;
42439 _this._iconMode = config.get('iconMode');
42440 return _this;
42441 }
42442 /**
42443 * @hidden
42444 * @return {?}
42445 */
42446 Icon.prototype.ngOnDestroy = function () {
42447 if (this._css) {
42448 this.setElementClass(this._css, false);
42449 }
42450 };
42451 Object.defineProperty(Icon.prototype, "name", {
42452 /**
42453 * \@input {string} Specifies which icon to use. The appropriate icon will be used based on the mode.
42454 * For more information, see [Ionicons](/docs/ionicons/).
42455 * @return {?}
42456 */
42457 get: function () {
42458 return this._name;
42459 },
42460 /**
42461 * @param {?} val
42462 * @return {?}
42463 */
42464 set: function (val) {
42465 if (!(/^md-|^ios-|^logo-/.test(val))) {
42466 // this does not have one of the defaults
42467 // so lets auto add in the mode prefix for them
42468 this._name = this._iconMode + '-' + val;
42469 }
42470 else {
42471 this._name = val;
42472 }
42473 this.update();
42474 },
42475 enumerable: true,
42476 configurable: true
42477 });
42478 Object.defineProperty(Icon.prototype, "ios", {
42479 /**
42480 * \@input {string} Specifies which icon to use on `ios` mode.
42481 * @return {?}
42482 */
42483 get: function () {
42484 return this._ios;
42485 },
42486 /**
42487 * @param {?} val
42488 * @return {?}
42489 */
42490 set: function (val) {
42491 this._ios = val;
42492 this.update();
42493 },
42494 enumerable: true,
42495 configurable: true
42496 });
42497 Object.defineProperty(Icon.prototype, "md", {
42498 /**
42499 * \@input {string} Specifies which icon to use on `md` mode.
42500 * @return {?}
42501 */
42502 get: function () {
42503 return this._md;
42504 },
42505 /**
42506 * @param {?} val
42507 * @return {?}
42508 */
42509 set: function (val) {
42510 this._md = val;
42511 this.update();
42512 },
42513 enumerable: true,
42514 configurable: true
42515 });
42516 Object.defineProperty(Icon.prototype, "isActive", {
42517 /**
42518 * \@input {boolean} If true, the icon is styled with an "active" appearance.
42519 * An active icon is filled in, and an inactive icon is the outline of the icon.
42520 * The `isActive` property is largely used by the tabbar. Only affects `ios` icons.
42521 * @return {?}
42522 */
42523 get: function () {
42524 return this._isActive;
42525 },
42526 /**
42527 * @param {?} val
42528 * @return {?}
42529 */
42530 set: function (val) {
42531 this._isActive = isTrueProperty(val);
42532 this.update();
42533 },
42534 enumerable: true,
42535 configurable: true
42536 });
42537 /**
42538 * @hidden
42539 * @return {?}
42540 */
42541 Icon.prototype.update = function () {
42542 var /** @type {?} */ iconName;
42543 if (this._ios && this._iconMode === 'ios') {
42544 iconName = this._ios;
42545 }
42546 else if (this._md && this._iconMode === 'md') {
42547 iconName = this._md;
42548 }
42549 else {
42550 iconName = this._name;
42551 }
42552 var /** @type {?} */ hidden = this._hidden = (iconName === null);
42553 if (hidden) {
42554 return;
42555 }
42556 var /** @type {?} */ iconMode = iconName.split('-', 2)[0];
42557 if (iconMode === 'ios' &&
42558 !this._isActive &&
42559 iconName.indexOf('logo-') < 0 &&
42560 iconName.indexOf('-outline') < 0) {
42561 iconName += '-outline';
42562 }
42563 var /** @type {?} */ css = 'ion-' + iconName;
42564 if (this._css === css) {
42565 return;
42566 }
42567 if (this._css) {
42568 this.setElementClass(this._css, false);
42569 }
42570 this._css = css;
42571 this.setElementClass(css, true);
42572 var /** @type {?} */ label = iconName
42573 .replace('ios-', '')
42574 .replace('md-', '')
42575 .replace('-', ' ');
42576 this.setElementAttribute('aria-label', label);
42577 };
42578 return Icon;
42579}(Ion));
42580Icon.decorators = [
42581 { type: Directive, args: [{
42582 selector: 'ion-icon',
42583 host: {
42584 'role': 'img'
42585 }
42586 },] },
42587];
42588/**
42589 * @nocollapse
42590 */
42591Icon.ctorParameters = function () { return [
42592 { type: Config, },
42593 { type: ElementRef, },
42594 { type: Renderer, },
42595]; };
42596Icon.propDecorators = {
42597 'name': [{ type: Input },],
42598 'ios': [{ type: Input },],
42599 'md': [{ type: Input },],
42600 'isActive': [{ type: Input },],
42601 '_hidden': [{ type: HostBinding, args: ['class.hide',] },],
42602};
42603
42604var __extends$41 = (undefined && undefined.__extends) || (function () {
42605 var extendStatics = Object.setPrototypeOf ||
42606 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
42607 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
42608 return function (d, b) {
42609 extendStatics(d, b);
42610 function __() { this.constructor = d; }
42611 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
42612 };
42613})();
42614/**
42615 * \@name Label
42616 * \@description
42617 * Labels are placed inside of an `ion-item` element and can be used
42618 * to describe an `ion-input`, `ion-toggle`, `ion-checkbox`, and more.
42619 *
42620 * \@property [fixed] - A persistent label that sits next the input.
42621 * \@property [floating] - A label that will float above the input if the input is empty or loses focus.
42622 * \@property [stacked] - A stacked label will always appear on top of the input.
42623 *
42624 * \@usage
42625 * ```html
42626 * <ion-item>
42627 * <ion-label>Username</ion-label>
42628 * <ion-input></ion-input>
42629 * </ion-item>
42630 *
42631 * <ion-item>
42632 * <ion-label fixed>Website</ion-label>
42633 * <ion-input type="url"></ion-input>
42634 * </ion-item>
42635 *
42636 * <ion-item>
42637 * <ion-label floating>Email</ion-label>
42638 * <ion-input type="email"></ion-input>
42639 * </ion-item>
42640 *
42641 * <ion-item>
42642 * <ion-label stacked>Phone</ion-label>
42643 * <ion-input type="tel"></ion-input>
42644 * </ion-item>
42645 *
42646 * <ion-item>
42647 * <ion-label>Toggle</ion-label>
42648 * <ion-toggle></ion-toggle>
42649 * </ion-item>
42650 *
42651 * <ion-item>
42652 * <ion-label>Checkbox</ion-label>
42653 * <ion-checkbox></ion-checkbox>
42654 * </ion-item>
42655 * ```
42656 *
42657 * \@demo /docs/demos/src/label/
42658 * @see {\@link ../../../../components#inputs Input Component Docs}
42659 * @see {\@link ../../input/Input Input API Docs}
42660 *
42661 */
42662var Label = (function (_super) {
42663 __extends$41(Label, _super);
42664 /**
42665 * @param {?} config
42666 * @param {?} elementRef
42667 * @param {?} renderer
42668 * @param {?} isFloating
42669 * @param {?} isStacked
42670 * @param {?} isFixed
42671 * @param {?} isInset
42672 */
42673 function Label(config, elementRef, renderer, isFloating, isStacked, isFixed, isInset) {
42674 var _this = _super.call(this, config, elementRef, renderer, 'label') || this;
42675 _this.type = (isFloating === '' ? 'floating' : (isStacked === '' ? 'stacked' : (isFixed === '' ? 'fixed' : (isInset === '' ? 'inset' : null))));
42676 return _this;
42677 }
42678 Object.defineProperty(Label.prototype, "id", {
42679 /**
42680 * @hidden
42681 * @return {?}
42682 */
42683 get: function () {
42684 return this._id;
42685 },
42686 /**
42687 * @param {?} val
42688 * @return {?}
42689 */
42690 set: function (val) {
42691 this._id = val;
42692 if (val) {
42693 this.setElementAttribute('id', val);
42694 }
42695 },
42696 enumerable: true,
42697 configurable: true
42698 });
42699 Object.defineProperty(Label.prototype, "text", {
42700 /**
42701 * @hidden
42702 * @return {?}
42703 */
42704 get: function () {
42705 return this.getNativeElement().textContent || '';
42706 },
42707 enumerable: true,
42708 configurable: true
42709 });
42710 return Label;
42711}(Ion));
42712Label.decorators = [
42713 { type: Directive, args: [{
42714 selector: 'ion-label'
42715 },] },
42716];
42717/**
42718 * @nocollapse
42719 */
42720Label.ctorParameters = function () { return [
42721 { type: Config, },
42722 { type: ElementRef, },
42723 { type: Renderer, },
42724 { type: undefined, decorators: [{ type: Attribute, args: ['floating',] },] },
42725 { type: undefined, decorators: [{ type: Attribute, args: ['stacked',] },] },
42726 { type: undefined, decorators: [{ type: Attribute, args: ['fixed',] },] },
42727 { type: undefined, decorators: [{ type: Attribute, args: ['inset',] },] },
42728]; };
42729Label.propDecorators = {
42730 'id': [{ type: Input },],
42731};
42732
42733/**
42734 * \@name Keyboard
42735 * \@description
42736 * The `Keyboard` class allows you to work with the keyboard events provided
42737 * by the Ionic keyboard plugin.
42738 *
42739 * \@usage
42740 * ```ts
42741 * export class MyClass {
42742 *
42743 * constructor(public keyboard: Keyboard) { }
42744 *
42745 * }
42746 * ```
42747 */
42748var Keyboard = (function () {
42749 /**
42750 * @param {?} config
42751 * @param {?} _plt
42752 * @param {?} _zone
42753 * @param {?} _dom
42754 */
42755 function Keyboard(config, _plt, _zone, _dom) {
42756 this._plt = _plt;
42757 this._zone = _zone;
42758 this._dom = _dom;
42759 this.willShow = new EventEmitter();
42760 this.willHide = new EventEmitter();
42761 this.didShow = new EventEmitter();
42762 this.didHide = new EventEmitter();
42763 this.eventsAvailable = false;
42764 this.focusOutline(config.get('focusOutline'));
42765 var win = _plt.win();
42766 if (config.getBoolean('keyboardResizes', false)) {
42767 this.listenV2(win);
42768 }
42769 else {
42770 this.listenV1(win);
42771 }
42772 }
42773 /**
42774 * @param {?} win
42775 * @return {?}
42776 */
42777 Keyboard.prototype.listenV2 = function (win) {
42778 var _this = this;
42779 var /** @type {?} */ platform = this._plt;
42780 platform.registerListener(win, 'keyboardWillShow', function () {
42781 _this._zone.run(function () {
42782 _this.willShow.emit();
42783 });
42784 }, { zone: false, passive: true });
42785 platform.registerListener(win, 'keyboardWillHide', function () {
42786 _this._zone.run(function () {
42787 _this.willHide.emit();
42788 });
42789 }, { zone: false, passive: true });
42790 platform.registerListener(win, 'keyboardDidShow', function () {
42791 _this._zone.run(function () {
42792 _this.didShow.emit();
42793 });
42794 }, { zone: false, passive: true });
42795 platform.registerListener(win, 'keyboardDidHide', function () {
42796 _this._zone.run(function () {
42797 _this.didHide.emit();
42798 });
42799 }, { zone: false, passive: true });
42800 this.eventsAvailable = true;
42801 };
42802 /**
42803 * @param {?} win
42804 * @return {?}
42805 */
42806 Keyboard.prototype.listenV1 = function (win) {
42807 var _this = this;
42808 var /** @type {?} */ platform = this._plt;
42809 platform.registerListener(win, 'native.keyboardhide', function () {
42810 _this.blurActiveInput(true);
42811 }, { zone: false, passive: true });
42812 platform.registerListener(win, 'native.keyboardshow', function () {
42813 _this.blurActiveInput(false);
42814 }, { zone: false, passive: true });
42815 };
42816 /**
42817 * @param {?} shouldBlur
42818 * @return {?}
42819 */
42820 Keyboard.prototype.blurActiveInput = function (shouldBlur) {
42821 var _this = this;
42822 var /** @type {?} */ platform = this._plt;
42823 platform.cancelTimeout(this._tmr);
42824 if (shouldBlur) {
42825 this._tmr = platform.timeout(function () {
42826 // this custom cordova plugin event fires when the keyboard will hide
42827 // useful when the virtual keyboard is closed natively
42828 // https://github.com/ionic-team/ionic-plugin-keyboard
42829 if (_this.isOpen()) {
42830 platform.focusOutActiveElement();
42831 }
42832 }, 80);
42833 }
42834 };
42835 /**
42836 * Check to see if the keyboard is open or not.
42837 *
42838 * ```ts
42839 * export class MyClass {
42840 * constructor(public keyboard: Keyboard) {
42841 *
42842 * }
42843 *
42844 * keyboardCheck() {
42845 * console.log('The keyboard is open:', this.keyboard.isOpen());
42846 * }
42847 * }
42848 * ```
42849 *
42850 * @return {?}
42851 */
42852 Keyboard.prototype.isOpen = function () {
42853 return this.hasFocusedTextInput();
42854 };
42855 /**
42856 * When the keyboard is closed, call any methods you want.
42857 *
42858 * ```ts
42859 * export class MyClass {
42860 * constructor(public keyboard: Keyboard) {
42861 * this.keyboard.onClose(this.closeCallback);
42862 * }
42863 * closeCallback() {
42864 * // call what ever functionality you want on keyboard close
42865 * console.log('Closing time');
42866 * }
42867 * }
42868 * ```
42869 *
42870 * @param {?} callback
42871 * @param {?=} pollingInternval
42872 * @param {?=} pollingChecksMax
42873 * @return {?}
42874 */
42875 Keyboard.prototype.onClose = function (callback, pollingInternval, pollingChecksMax) {
42876 if (pollingInternval === void 0) { pollingInternval = KEYBOARD_CLOSE_POLLING; }
42877 if (pollingChecksMax === void 0) { pollingChecksMax = KEYBOARD_POLLING_CHECKS_MAX; }
42878 (void 0) /* console.debug */;
42879 var /** @type {?} */ self = this;
42880 var /** @type {?} */ checks = 0;
42881 var /** @type {?} */ promise = null;
42882 if (!callback) {
42883 // a callback wasn't provided, so let's return a promise instead
42884 promise = new Promise(function (resolve) { callback = resolve; });
42885 }
42886 /**
42887 * @return {?}
42888 */
42889 function checkKeyboard() {
42890 (void 0) /* console.debug */;
42891 if (!self.isOpen() || checks > pollingChecksMax) {
42892 self._plt.timeout(function () {
42893 self._zone.run(function () {
42894 (void 0) /* console.debug */;
42895 callback();
42896 });
42897 }, 400);
42898 }
42899 else {
42900 self._plt.timeout(checkKeyboard, pollingInternval);
42901 }
42902 checks++;
42903 }
42904 self._plt.timeout(checkKeyboard, pollingInternval);
42905 return promise;
42906 };
42907 /**
42908 * Programmatically close the keyboard.
42909 * @return {?}
42910 */
42911 Keyboard.prototype.close = function () {
42912 var _this = this;
42913 this._dom.read(function () {
42914 if (_this.isOpen()) {
42915 // only focus out when a text input has focus
42916 (void 0) /* console.debug */;
42917 _this._dom.write(function () {
42918 _this._plt.focusOutActiveElement();
42919 });
42920 }
42921 });
42922 };
42923 /**
42924 * @hidden
42925 * @param {?} setting
42926 * @return {?}
42927 */
42928 Keyboard.prototype.focusOutline = function (setting) {
42929 /* Focus Outline
42930 * --------------------------------------------------
42931 * By default, when a keydown event happens from a tab key, then
42932 * the 'focus-outline' css class is added to the body element
42933 * so focusable elements have an outline. On a mousedown or
42934 * touchstart event, then the 'focus-outline' css class is removed.
42935 *
42936 * Config default overrides:
42937 * focusOutline: true - Always add the focus-outline
42938 * focusOutline: false - Do not add the focus-outline
42939 */
42940 var /** @type {?} */ self = this;
42941 var /** @type {?} */ platform = self._plt;
42942 var /** @type {?} */ doc = platform.doc();
42943 var /** @type {?} */ isKeyInputEnabled = false;
42944 var /** @type {?} */ unRegMouse;
42945 var /** @type {?} */ unRegTouch;
42946 var /** @type {?} */ evOpts = { passive: true, zone: false };
42947 /**
42948 * @return {?}
42949 */
42950 function cssClass() {
42951 self._dom.write(function () {
42952 ((platform.doc().body.classList))[isKeyInputEnabled ? 'add' : 'remove']('focus-outline');
42953 });
42954 }
42955 if (setting === true) {
42956 isKeyInputEnabled = true;
42957 return cssClass();
42958 }
42959 else if (setting === false) {
42960 return;
42961 }
42962 /**
42963 * @param {?} ev
42964 * @return {?}
42965 */
42966 function keyDown(ev) {
42967 if (!isKeyInputEnabled && ev.keyCode === KEY_TAB) {
42968 isKeyInputEnabled = true;
42969 enableKeyInput();
42970 }
42971 }
42972 /**
42973 * @return {?}
42974 */
42975 function pointerDown() {
42976 isKeyInputEnabled = false;
42977 enableKeyInput();
42978 }
42979 /**
42980 * @return {?}
42981 */
42982 function enableKeyInput() {
42983 cssClass();
42984 unRegMouse && unRegMouse();
42985 unRegTouch && unRegTouch();
42986 if (isKeyInputEnabled) {
42987 // listen for when a mousedown or touchstart event happens
42988 unRegMouse = platform.registerListener(doc, 'mousedown', pointerDown, evOpts);
42989 unRegTouch = platform.registerListener(doc, 'touchstart', pointerDown, evOpts);
42990 }
42991 }
42992 // always listen for tab keydown events
42993 platform.registerListener(platform.doc(), 'keydown', keyDown, evOpts);
42994 };
42995 /**
42996 * @return {?}
42997 */
42998 Keyboard.prototype.hasFocusedTextInput = function () {
42999 var /** @type {?} */ activeEle = this._plt.getActiveElement();
43000 if (isTextInput(activeEle)) {
43001 return (activeEle.parentElement.querySelector(':focus') === activeEle);
43002 }
43003 return false;
43004 };
43005 return Keyboard;
43006}());
43007Keyboard.decorators = [
43008 { type: Injectable },
43009];
43010/**
43011 * @nocollapse
43012 */
43013Keyboard.ctorParameters = function () { return [
43014 { type: Config, },
43015 { type: Platform, },
43016 { type: NgZone, },
43017 { type: DomController, },
43018]; };
43019var KEYBOARD_CLOSE_POLLING = 150;
43020var KEYBOARD_POLLING_CHECKS_MAX = 100;
43021
43022var ScrollView = (function () {
43023 /**
43024 * @param {?} _app
43025 * @param {?} _plt
43026 * @param {?} _dom
43027 */
43028 function ScrollView(_app, _plt, _dom) {
43029 this._app = _app;
43030 this._plt = _plt;
43031 this._dom = _dom;
43032 this.isScrolling = false;
43033 this.initialized = false;
43034 this._eventsEnabled = false;
43035 this._t = 0;
43036 this._l = 0;
43037 this.ev = {
43038 timeStamp: 0,
43039 scrollTop: 0,
43040 scrollLeft: 0,
43041 scrollHeight: 0,
43042 scrollWidth: 0,
43043 contentHeight: 0,
43044 contentWidth: 0,
43045 contentTop: 0,
43046 contentBottom: 0,
43047 startY: 0,
43048 startX: 0,
43049 deltaY: 0,
43050 deltaX: 0,
43051 velocityY: 0,
43052 velocityX: 0,
43053 directionY: 'down',
43054 directionX: null,
43055 domWrite: _dom.write.bind(_dom)
43056 };
43057 }
43058 /**
43059 * @param {?} ele
43060 * @param {?} contentTop
43061 * @param {?} contentBottom
43062 * @return {?}
43063 */
43064 ScrollView.prototype.init = function (ele, contentTop, contentBottom) {
43065 (void 0) /* assert */;
43066 this._el = ele;
43067 if (!this.initialized) {
43068 this.initialized = true;
43069 if (this._js) {
43070 this.enableJsScroll(contentTop, contentBottom);
43071 }
43072 else {
43073 this.enableNativeScrolling();
43074 }
43075 }
43076 };
43077 /**
43078 * @return {?}
43079 */
43080 ScrollView.prototype.enableEvents = function () {
43081 this._eventsEnabled = true;
43082 };
43083 /**
43084 * @param {?} isScrolling
43085 * @param {?} ev
43086 * @return {?}
43087 */
43088 ScrollView.prototype.setScrolling = function (isScrolling, ev) {
43089 if (this.isScrolling) {
43090 if (isScrolling) {
43091 this.onScroll && this.onScroll(ev);
43092 }
43093 else {
43094 this.isScrolling = false;
43095 this.onScrollEnd && this.onScrollEnd(ev);
43096 }
43097 }
43098 else if (isScrolling) {
43099 this.isScrolling = true;
43100 this.onScrollStart && this.onScrollStart(ev);
43101 }
43102 };
43103 /**
43104 * @return {?}
43105 */
43106 ScrollView.prototype.enableNativeScrolling = function () {
43107 (void 0) /* assert */;
43108 (void 0) /* assert */;
43109 (void 0) /* assert */;
43110 this._js = false;
43111 if (!this._el) {
43112 return;
43113 }
43114 (void 0) /* console.debug */;
43115 var /** @type {?} */ self = this;
43116 var /** @type {?} */ ev = self.ev;
43117 var /** @type {?} */ positions = [];
43118 /**
43119 * @param {?} scrollEvent
43120 * @return {?}
43121 */
43122 function scrollCallback(scrollEvent) {
43123 // remind the app that it's currently scrolling
43124 self._app.setScrolling();
43125 // if events are disabled, we do nothing
43126 if (!self._eventsEnabled) {
43127 return;
43128 }
43129 ev.timeStamp = scrollEvent.timeStamp;
43130 // Event.timeStamp is 0 in firefox
43131 if (!ev.timeStamp) {
43132 ev.timeStamp = Date.now();
43133 }
43134 // get the current scrollTop
43135 // ******** DOM READ ****************
43136 ev.scrollTop = self.getTop();
43137 // get the current scrollLeft
43138 // ******** DOM READ ****************
43139 ev.scrollLeft = self.getLeft();
43140 if (!self.isScrolling) {
43141 // remember the start positions
43142 ev.startY = ev.scrollTop;
43143 ev.startX = ev.scrollLeft;
43144 // new scroll, so do some resets
43145 ev.velocityY = ev.velocityX = 0;
43146 ev.deltaY = ev.deltaX = 0;
43147 positions.length = 0;
43148 }
43149 // actively scrolling
43150 positions.push(ev.scrollTop, ev.scrollLeft, ev.timeStamp);
43151 if (positions.length > 3) {
43152 // we've gotten at least 2 scroll events so far
43153 ev.deltaY = (ev.scrollTop - ev.startY);
43154 ev.deltaX = (ev.scrollLeft - ev.startX);
43155 var /** @type {?} */ endPos = (positions.length - 1);
43156 var /** @type {?} */ startPos = endPos;
43157 var /** @type {?} */ timeRange = (ev.timeStamp - 100);
43158 // move pointer to position measured 100ms ago
43159 for (var /** @type {?} */ i = endPos; i > 0 && positions[i] > timeRange; i -= 3) {
43160 startPos = i;
43161 }
43162 if (startPos !== endPos) {
43163 // compute relative movement between these two points
43164 var /** @type {?} */ movedTop = (positions[startPos - 2] - positions[endPos - 2]);
43165 var /** @type {?} */ movedLeft = (positions[startPos - 1] - positions[endPos - 1]);
43166 var /** @type {?} */ factor = FRAME_MS / (positions[endPos] - positions[startPos]);
43167 // based on XXms compute the movement to apply for each render step
43168 ev.velocityY = movedTop * factor;
43169 ev.velocityX = movedLeft * factor;
43170 // figure out which direction we're scrolling
43171 ev.directionY = (movedTop > 0 ? 'up' : 'down');
43172 ev.directionX = (movedLeft > 0 ? 'left' : 'right');
43173 }
43174 }
43175 /**
43176 * @return {?}
43177 */
43178 function scrollEnd() {
43179 // reset velocity, do not reset the directions or deltas
43180 ev.velocityY = ev.velocityX = 0;
43181 // emit that the scroll has ended
43182 self.setScrolling(false, ev);
43183 self._endTmr = null;
43184 }
43185 // emit on each scroll event
43186 self.setScrolling(true, ev);
43187 // debounce for a moment after the last scroll event
43188 self._dom.cancel(self._endTmr);
43189 self._endTmr = self._dom.read(scrollEnd, SCROLL_END_DEBOUNCE_MS);
43190 }
43191 // clear out any existing listeners (just to be safe)
43192 self._lsn && self._lsn();
43193 // assign the raw scroll listener
43194 // note that it does not have a wrapping requestAnimationFrame on purpose
43195 // a scroll event callback will always be right before the raf callback
43196 // so there's little to no value of using raf here since it'll all ways immediately
43197 // call the raf if it was set within the scroll event, so this will save us some time
43198 self._lsn = self._plt.registerListener(self._el, 'scroll', scrollCallback, EVENT_OPTS);
43199 };
43200 /**
43201 * @hidden
43202 * JS Scrolling has been provided only as a temporary solution
43203 * until iOS apps can take advantage of scroll events at all times.
43204 * The goal is to eventually remove JS scrolling entirely. When we
43205 * no longer have to worry about iOS not firing scroll events during
43206 * inertia then this can be burned to the ground. iOS's more modern
43207 * WKWebView does not have this issue, only UIWebView does.
43208 * @param {?} contentTop
43209 * @param {?} contentBottom
43210 * @return {?}
43211 */
43212 ScrollView.prototype.enableJsScroll = function (contentTop, contentBottom) {
43213 var /** @type {?} */ self = this;
43214 self._js = true;
43215 var /** @type {?} */ ele = self._el;
43216 if (!ele) {
43217 return;
43218 }
43219 (void 0) /* console.debug */;
43220 var /** @type {?} */ ev = self.ev;
43221 var /** @type {?} */ positions = [];
43222 var /** @type {?} */ rafCancel;
43223 var /** @type {?} */ max;
43224 /**
43225 * @return {?}
43226 */
43227 function setMax() {
43228 if (!max) {
43229 // ******** DOM READ ****************
43230 max = ele.scrollHeight - ele.parentElement.offsetHeight + contentTop + contentBottom;
43231 }
43232 }
43233 /**
43234 * @param {?} timeStamp
43235 * @return {?}
43236 */
43237 function jsScrollDecelerate(timeStamp) {
43238 ev.timeStamp = timeStamp;
43239 (void 0) /* console.debug */;
43240 if (ev.velocityY) {
43241 ev.velocityY *= DECELERATION_FRICTION;
43242 // update top with updated velocity
43243 // clamp top within scroll limits
43244 // ******** DOM READ ****************
43245 setMax();
43246 self._t = Math.min(Math.max(self._t + ev.velocityY, 0), max);
43247 ev.scrollTop = self._t;
43248 // emit on each scroll event
43249 self.onScroll(ev);
43250 self._dom.write(function () {
43251 // ******** DOM WRITE ****************
43252 self.setTop(self._t);
43253 if (self._t > 0 && self._t < max && Math.abs(ev.velocityY) > MIN_VELOCITY_CONTINUE_DECELERATION) {
43254 rafCancel = self._dom.read(function (rafTimeStamp) {
43255 jsScrollDecelerate(rafTimeStamp);
43256 });
43257 }
43258 else {
43259 // haven't scrolled in a while, so it's a scrollend
43260 self.isScrolling = false;
43261 // reset velocity, do not reset the directions or deltas
43262 ev.velocityY = ev.velocityX = 0;
43263 // emit that the scroll has ended
43264 self.onScrollEnd(ev);
43265 }
43266 });
43267 }
43268 }
43269 /**
43270 * @param {?} touchEvent
43271 * @return {?}
43272 */
43273 function jsScrollTouchStart(touchEvent) {
43274 positions.length = 0;
43275 max = null;
43276 self._dom.cancel(rafCancel);
43277 positions.push(pointerCoord(touchEvent).y, touchEvent.timeStamp);
43278 }
43279 /**
43280 * @param {?} touchEvent
43281 * @return {?}
43282 */
43283 function jsScrollTouchMove(touchEvent) {
43284 if (!positions.length) {
43285 return;
43286 }
43287 ev.timeStamp = touchEvent.timeStamp;
43288 var /** @type {?} */ y = pointerCoord(touchEvent).y;
43289 // ******** DOM READ ****************
43290 setMax();
43291 self._t -= (y - positions[positions.length - 2]);
43292 self._t = Math.min(Math.max(self._t, 0), max);
43293 positions.push(y, ev.timeStamp);
43294 if (!self.isScrolling) {
43295 // remember the start position
43296 ev.startY = self._t;
43297 // new scroll, so do some resets
43298 ev.velocityY = ev.deltaY = 0;
43299 self.isScrolling = true;
43300 // emit only on the first scroll event
43301 self.onScrollStart(ev);
43302 }
43303 self._dom.write(function () {
43304 // ******** DOM WRITE ****************
43305 self.setTop(self._t);
43306 });
43307 }
43308 /**
43309 * @param {?} touchEvent
43310 * @return {?}
43311 */
43312 function jsScrollTouchEnd(touchEvent) {
43313 // figure out what the scroll position was about 100ms ago
43314 self._dom.cancel(rafCancel);
43315 if (!positions.length && self.isScrolling) {
43316 self.isScrolling = false;
43317 ev.velocityY = ev.velocityX = 0;
43318 self.onScrollEnd(ev);
43319 return;
43320 }
43321 var /** @type {?} */ y = pointerCoord(touchEvent).y;
43322 positions.push(y, touchEvent.timeStamp);
43323 var /** @type {?} */ endPos = (positions.length - 1);
43324 var /** @type {?} */ startPos = endPos;
43325 var /** @type {?} */ timeRange = (touchEvent.timeStamp - 100);
43326 // move pointer to position measured 100ms ago
43327 for (var /** @type {?} */ i = endPos; i > 0 && positions[i] > timeRange; i -= 2) {
43328 startPos = i;
43329 }
43330 if (startPos !== endPos) {
43331 // compute relative movement between these two points
43332 var /** @type {?} */ timeOffset = (positions[endPos] - positions[startPos]);
43333 var /** @type {?} */ movedTop = (positions[startPos - 1] - positions[endPos - 1]);
43334 // based on XXms compute the movement to apply for each render step
43335 ev.velocityY = ((movedTop / timeOffset) * FRAME_MS);
43336 // verify that we have enough velocity to start deceleration
43337 if (Math.abs(ev.velocityY) > MIN_VELOCITY_START_DECELERATION) {
43338 // ******** DOM READ ****************
43339 setMax();
43340 rafCancel = self._dom.read(function (rafTimeStamp) {
43341 jsScrollDecelerate(rafTimeStamp);
43342 });
43343 }
43344 }
43345 else {
43346 self.isScrolling = false;
43347 ev.velocityY = 0;
43348 self.onScrollEnd(ev);
43349 }
43350 positions.length = 0;
43351 }
43352 var /** @type {?} */ plt = self._plt;
43353 var /** @type {?} */ unRegStart = plt.registerListener(ele, 'touchstart', jsScrollTouchStart, EVENT_OPTS);
43354 var /** @type {?} */ unRegMove = plt.registerListener(ele, 'touchmove', jsScrollTouchMove, EVENT_OPTS);
43355 var /** @type {?} */ unRegEnd = plt.registerListener(ele, 'touchend', jsScrollTouchEnd, EVENT_OPTS);
43356 ele.parentElement.classList.add('js-scroll');
43357 // stop listening for actual scroll events
43358 self._lsn && self._lsn();
43359 // create an unregister for all of these events
43360 self._lsn = function () {
43361 unRegStart();
43362 unRegMove();
43363 unRegEnd();
43364 ele.parentElement.classList.remove('js-scroll');
43365 };
43366 };
43367 /**
43368 * DOM READ
43369 * @return {?}
43370 */
43371 ScrollView.prototype.getTop = function () {
43372 if (this._js) {
43373 return this._t;
43374 }
43375 return this._t = this._el.scrollTop;
43376 };
43377 /**
43378 * DOM READ
43379 * @return {?}
43380 */
43381 ScrollView.prototype.getLeft = function () {
43382 if (this._js) {
43383 return 0;
43384 }
43385 return this._l = this._el.scrollLeft;
43386 };
43387 /**
43388 * DOM WRITE
43389 * @param {?} top
43390 * @return {?}
43391 */
43392 ScrollView.prototype.setTop = function (top) {
43393 this._t = top;
43394 if (this._js) {
43395 ((this._el.style))[this._plt.Css.transform] = "translate3d(" + this._l * -1 + "px," + top * -1 + "px,0px)";
43396 }
43397 else {
43398 this._el.scrollTop = top;
43399 }
43400 };
43401 /**
43402 * DOM WRITE
43403 * @param {?} left
43404 * @return {?}
43405 */
43406 ScrollView.prototype.setLeft = function (left) {
43407 this._l = left;
43408 if (this._js) {
43409 ((this._el.style))[this._plt.Css.transform] = "translate3d(" + left * -1 + "px," + this._t * -1 + "px,0px)";
43410 }
43411 else {
43412 this._el.scrollLeft = left;
43413 }
43414 };
43415 /**
43416 * @param {?} x
43417 * @param {?} y
43418 * @param {?} duration
43419 * @param {?=} done
43420 * @return {?}
43421 */
43422 ScrollView.prototype.scrollTo = function (x, y, duration, done) {
43423 // scroll animation loop w/ easing
43424 // credit https://gist.github.com/dezinezync/5487119
43425 var /** @type {?} */ promise;
43426 if (done === undefined) {
43427 // only create a promise if a done callback wasn't provided
43428 // done can be a null, which avoids any functions
43429 promise = new Promise(function (resolve) {
43430 done = resolve;
43431 });
43432 }
43433 var /** @type {?} */ self = this;
43434 var /** @type {?} */ el = self._el;
43435 if (!el) {
43436 // invalid element
43437 done();
43438 return promise;
43439 }
43440 if (duration < 32) {
43441 self.setTop(y);
43442 self.setLeft(x);
43443 done();
43444 return promise;
43445 }
43446 var /** @type {?} */ fromY = el.scrollTop;
43447 var /** @type {?} */ fromX = el.scrollLeft;
43448 var /** @type {?} */ maxAttempts = (duration / 16) + 100;
43449 var /** @type {?} */ transform = self._plt.Css.transform;
43450 var /** @type {?} */ startTime;
43451 var /** @type {?} */ attempts = 0;
43452 var /** @type {?} */ stopScroll = false;
43453 /**
43454 * @param {?} timeStamp
43455 * @return {?}
43456 */
43457 function step(timeStamp) {
43458 attempts++;
43459 if (!self._el || stopScroll || attempts > maxAttempts) {
43460 self.setScrolling(false, null);
43461 ((el.style))[transform] = '';
43462 done();
43463 return;
43464 }
43465 var /** @type {?} */ time = Math.min(1, ((timeStamp - startTime) / duration));
43466 // where .5 would be 50% of time on a linear scale easedT gives a
43467 // fraction based on the easing method
43468 var /** @type {?} */ easedT = (--time) * time * time + 1;
43469 if (fromY !== y) {
43470 self.setTop((easedT * (y - fromY)) + fromY);
43471 }
43472 if (fromX !== x) {
43473 self.setLeft(Math.floor((easedT * (x - fromX)) + fromX));
43474 }
43475 if (easedT < 1) {
43476 // do not use DomController here
43477 // must use nativeRaf in order to fire in the next frame
43478 self._plt.raf(step);
43479 }
43480 else {
43481 stopScroll = true;
43482 self.setScrolling(false, null);
43483 ((el.style))[transform] = '';
43484 done();
43485 }
43486 }
43487 // start scroll loop
43488 self.setScrolling(true, null);
43489 self.isScrolling = true;
43490 // chill out for a frame first
43491 self._dom.write(function (timeStamp) {
43492 startTime = timeStamp;
43493 step(timeStamp);
43494 }, 16);
43495 return promise;
43496 };
43497 /**
43498 * @param {?} duration
43499 * @return {?}
43500 */
43501 ScrollView.prototype.scrollToTop = function (duration) {
43502 return this.scrollTo(0, 0, duration);
43503 };
43504 /**
43505 * @param {?} duration
43506 * @return {?}
43507 */
43508 ScrollView.prototype.scrollToBottom = function (duration) {
43509 var /** @type {?} */ y = 0;
43510 if (this._el) {
43511 y = this._el.scrollHeight - this._el.clientHeight;
43512 }
43513 return this.scrollTo(0, y, duration);
43514 };
43515 /**
43516 * @return {?}
43517 */
43518 ScrollView.prototype.stop = function () {
43519 this.setScrolling(false, null);
43520 };
43521 /**
43522 * @hidden
43523 * @return {?}
43524 */
43525 ScrollView.prototype.destroy = function () {
43526 this.stop();
43527 this._endTmr && this._dom.cancel(this._endTmr);
43528 this._lsn && this._lsn();
43529 var /** @type {?} */ ev = this.ev;
43530 ev.domWrite = ev.contentElement = ev.fixedElement = ev.scrollElement = ev.headerElement = null;
43531 this._lsn = this._el = this._dom = this.ev = ev = null;
43532 this.onScrollStart = this.onScroll = this.onScrollEnd = null;
43533 };
43534 return ScrollView;
43535}());
43536var SCROLL_END_DEBOUNCE_MS = 80;
43537var MIN_VELOCITY_START_DECELERATION = 4;
43538var MIN_VELOCITY_CONTINUE_DECELERATION = 0.12;
43539var DECELERATION_FRICTION = 0.97;
43540var FRAME_MS = (1000 / 60);
43541var EVENT_OPTS = {
43542 passive: true,
43543 zone: false
43544};
43545
43546var __extends$42 = (undefined && undefined.__extends) || (function () {
43547 var extendStatics = Object.setPrototypeOf ||
43548 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
43549 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
43550 return function (d, b) {
43551 extendStatics(d, b);
43552 function __() { this.constructor = d; }
43553 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
43554 };
43555})();
43556var EventEmitterProxy = (function (_super) {
43557 __extends$42(EventEmitterProxy, _super);
43558 function EventEmitterProxy() {
43559 return _super !== null && _super.apply(this, arguments) || this;
43560 }
43561 /**
43562 * @param {?=} generatorOrNext
43563 * @param {?=} error
43564 * @param {?=} complete
43565 * @return {?}
43566 */
43567 EventEmitterProxy.prototype.subscribe = function (generatorOrNext, error, complete) {
43568 this.onSubscribe();
43569 return _super.prototype.subscribe.call(this, generatorOrNext, error, complete);
43570 };
43571 return EventEmitterProxy;
43572}(EventEmitter));
43573/**
43574 * \@name Content
43575 * \@description
43576 * The Content component provides an easy to use content area with
43577 * some useful methods to control the scrollable area. There should
43578 * only be one content in a single view component. If additional scrollable
43579 * elements are needed, use [ionScroll](../../scroll/Scroll).
43580 *
43581 *
43582 * The content area can also implement pull-to-refresh with the
43583 * [Refresher](../../refresher/Refresher) component.
43584 *
43585 * \@usage
43586 * ```html
43587 * <ion-content>
43588 * Add your content here!
43589 * </ion-content>
43590 * ```
43591 *
43592 * To get a reference to the content component from a Page's logic,
43593 * you can use Angular's `\@ViewChild` annotation:
43594 *
43595 * ```ts
43596 * import { Component, ViewChild } from '\@angular/core';
43597 * import { Content } from 'ionic-angular';
43598 *
43599 * \@Component({...})
43600 * export class MyPage{
43601 * \@ViewChild(Content) content: Content;
43602 *
43603 * scrollToTop() {
43604 * this.content.scrollToTop();
43605 * }
43606 * }
43607 * ```
43608 *
43609 * \@advanced
43610 *
43611 * ### Scroll Events
43612 *
43613 * Scroll events happen outside of Angular's Zones. This is for performance reasons. So
43614 * if you're trying to bind a value to any scroll event, it will need to be wrapped in
43615 * a `zone.run()`
43616 *
43617 * ```ts
43618 * import { Component, NgZone } from '\@angular/core';
43619 * \@Component({
43620 * template: `
43621 * <ion-header>
43622 * <ion-navbar>
43623 * <ion-title>{{scrollAmount}}</ion-title>
43624 * </ion-navbar>
43625 * </ion-header>
43626 * <ion-content (ionScroll)="scrollHandler($event)">
43627 * <p> Some realllllllly long content </p>
43628 * </ion-content>
43629 * `})
43630 * class E2EPage {
43631 * public scrollAmount = 0;
43632 * constructor( public zone: NgZone){}
43633 * scrollHandler(event) {
43634 * console.log(`ScrollEvent: ${event}`)
43635 * this.zone.run(()=>{
43636 * // since scrollAmount is data-binded,
43637 * // the update needs to happen in zone
43638 * this.scrollAmount++
43639 * })
43640 * }
43641 * }
43642 * ```
43643 *
43644 * This goes for any scroll event, not just `ionScroll`.
43645 *
43646 * ### Resizing the content
43647 *
43648 * If the height of `ion-header`, `ion-footer` or `ion-tabbar`
43649 * changes dynamically, `content.resize()` has to be called in order to update the
43650 * layout of `Content`.
43651 *
43652 *
43653 * ```ts
43654 * \@Component({
43655 * template: `
43656 * <ion-header>
43657 * <ion-navbar>
43658 * <ion-title>Main Navbar</ion-title>
43659 * </ion-navbar>
43660 * <ion-toolbar *ngIf="showToolbar">
43661 * <ion-title>Dynamic Toolbar</ion-title>
43662 * </ion-toolbar>
43663 * </ion-header>
43664 * <ion-content>
43665 * <button ion-button (click)="toggleToolbar()">Toggle Toolbar</button>
43666 * </ion-content>
43667 * `})
43668 *
43669 * class E2EPage {
43670 * \@ViewChild(Content) content: Content;
43671 * showToolbar: boolean = false;
43672 *
43673 * toggleToolbar() {
43674 * this.showToolbar = !this.showToolbar;
43675 * this.content.resize();
43676 * }
43677 * }
43678 * ```
43679 *
43680 *
43681 * Scroll to a specific position
43682 *
43683 * ```ts
43684 * import { Component, ViewChild } from '\@angular/core';
43685 * import { Content } from 'ionic-angular';
43686 *
43687 * \@Component({
43688 * template: `<ion-content>
43689 * <button ion-button (click)="scrollTo()">Down 500px</button>
43690 * </ion-content>`
43691 * )}
43692 * export class MyPage{
43693 * \@ViewChild(Content) content: Content;
43694 *
43695 * scrollTo() {
43696 * // set the scrollLeft to 0px, and scrollTop to 500px
43697 * // the scroll duration should take 200ms
43698 * this.content.scrollTo(0, 500, 200);
43699 * }
43700 * }
43701 * ```
43702 *
43703 */
43704var Content = (function (_super) {
43705 __extends$42(Content, _super);
43706 /**
43707 * @param {?} config
43708 * @param {?} _plt
43709 * @param {?} _dom
43710 * @param {?} elementRef
43711 * @param {?} renderer
43712 * @param {?} _app
43713 * @param {?} _keyboard
43714 * @param {?} _zone
43715 * @param {?} viewCtrl
43716 * @param {?} navCtrl
43717 */
43718 function Content(config, _plt, _dom, elementRef, renderer, _app, _keyboard, _zone, viewCtrl, navCtrl) {
43719 var _this = _super.call(this, config, elementRef, renderer, 'content') || this;
43720 _this._plt = _plt;
43721 _this._dom = _dom;
43722 _this._app = _app;
43723 _this._keyboard = _keyboard;
43724 _this._zone = _zone;
43725 /**
43726 * \@internal
43727 */
43728 _this._scrollPadding = 0;
43729 /**
43730 * \@internal
43731 */
43732 _this._inputPolling = false;
43733 /**
43734 * \@internal
43735 */
43736 _this._hasRefresher = false;
43737 /**
43738 * \@internal
43739 */
43740 _this._imgs = [];
43741 /**
43742 * \@internal
43743 */
43744 _this._scrollDownOnLoad = false;
43745 /**
43746 * \@output {ScrollEvent} Emitted when the scrolling first starts.
43747 */
43748 _this.ionScrollStart = new EventEmitterProxy();
43749 /**
43750 * \@output {ScrollEvent} Emitted on every scroll event.
43751 */
43752 _this.ionScroll = new EventEmitterProxy();
43753 /**
43754 * \@output {ScrollEvent} Emitted when scrolling ends.
43755 */
43756 _this.ionScrollEnd = new EventEmitterProxy();
43757 var enableScrollListener = function () { return _this._scroll.enableEvents(); };
43758 _this.ionScroll.onSubscribe = enableScrollListener;
43759 _this.ionScrollStart.onSubscribe = enableScrollListener;
43760 _this.ionScrollEnd.onSubscribe = enableScrollListener;
43761 _this.statusbarPadding = config.getBoolean('statusbarPadding', false);
43762 _this._imgReqBfr = config.getNumber('imgRequestBuffer', 1400);
43763 _this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
43764 _this._imgVelMax = config.getNumber('imgVelocityMax', 3);
43765 _this._scroll = new ScrollView(_app, _plt, _dom);
43766 while (navCtrl) {
43767 if (isTabs(navCtrl)) {
43768 _this._tabs = navCtrl;
43769 break;
43770 }
43771 navCtrl = navCtrl.parent;
43772 }
43773 if (viewCtrl) {
43774 // content has a view controller
43775 viewCtrl._setIONContent(_this);
43776 viewCtrl._setIONContentRef(elementRef);
43777 _this._viewCtrlReadSub = viewCtrl.readReady.subscribe(function () {
43778 _this._viewCtrlReadSub.unsubscribe();
43779 _this._readDimensions();
43780 });
43781 _this._viewCtrlWriteSub = viewCtrl.writeReady.subscribe(function () {
43782 _this._viewCtrlWriteSub.unsubscribe();
43783 _this._writeDimensions();
43784 });
43785 }
43786 else {
43787 // content does not have a view controller
43788 _dom.read(_this._readDimensions.bind(_this));
43789 _dom.write(_this._writeDimensions.bind(_this));
43790 }
43791 return _this;
43792 }
43793 Object.defineProperty(Content.prototype, "contentHeight", {
43794 /**
43795 * Content height of the viewable area. This does not include content
43796 * which is outside the overflow area, or content area which is under
43797 * headers and footers. Read-only.
43798 *
43799 * @return {?}
43800 */
43801 get: function () {
43802 return this._scroll.ev.contentHeight;
43803 },
43804 enumerable: true,
43805 configurable: true
43806 });
43807 Object.defineProperty(Content.prototype, "contentWidth", {
43808 /**
43809 * Content width including content which is not visible on the screen
43810 * due to overflow. Read-only.
43811 *
43812 * @return {?}
43813 */
43814 get: function () {
43815 return this._scroll.ev.contentWidth;
43816 },
43817 enumerable: true,
43818 configurable: true
43819 });
43820 Object.defineProperty(Content.prototype, "scrollHeight", {
43821 /**
43822 * Content height including content which is not visible on the screen
43823 * due to overflow. Read-only.
43824 *
43825 * @return {?}
43826 */
43827 get: function () {
43828 return this._scroll.ev.scrollHeight;
43829 },
43830 enumerable: true,
43831 configurable: true
43832 });
43833 Object.defineProperty(Content.prototype, "scrollWidth", {
43834 /**
43835 * Content width including content which is not visible due to
43836 * overflow. Read-only.
43837 *
43838 * @return {?}
43839 */
43840 get: function () {
43841 return this._scroll.ev.scrollWidth;
43842 },
43843 enumerable: true,
43844 configurable: true
43845 });
43846 Object.defineProperty(Content.prototype, "scrollTop", {
43847 /**
43848 * The distance of the content's top to its topmost visible content.
43849 *
43850 * @return {?}
43851 */
43852 get: function () {
43853 return this._scroll.ev.scrollTop;
43854 },
43855 /**
43856 * @param {?} top
43857 * @return {?}
43858 */
43859 set: function (top) {
43860 this._scroll.setTop(top);
43861 },
43862 enumerable: true,
43863 configurable: true
43864 });
43865 Object.defineProperty(Content.prototype, "scrollLeft", {
43866 /**
43867 * The distance of the content's left to its leftmost visible content.
43868 *
43869 * @return {?}
43870 */
43871 get: function () {
43872 return this._scroll.ev.scrollLeft;
43873 },
43874 /**
43875 * @param {?} top
43876 * @return {?}
43877 */
43878 set: function (top) {
43879 this._scroll.setLeft(top);
43880 },
43881 enumerable: true,
43882 configurable: true
43883 });
43884 Object.defineProperty(Content.prototype, "isScrolling", {
43885 /**
43886 * If the content is actively scrolling or not.
43887 *
43888 * @return {?}
43889 */
43890 get: function () {
43891 return this._scroll.isScrolling;
43892 },
43893 enumerable: true,
43894 configurable: true
43895 });
43896 Object.defineProperty(Content.prototype, "directionY", {
43897 /**
43898 * The current, or last known, vertical scroll direction. Possible
43899 * string values include `down` and `up`.
43900 *
43901 * @return {?}
43902 */
43903 get: function () {
43904 return this._scroll.ev.directionY;
43905 },
43906 enumerable: true,
43907 configurable: true
43908 });
43909 Object.defineProperty(Content.prototype, "directionX", {
43910 /**
43911 * The current, or last known, horizontal scroll direction. Possible
43912 * string values include `right` and `left`.
43913 *
43914 * @return {?}
43915 */
43916 get: function () {
43917 return this._scroll.ev.directionX;
43918 },
43919 enumerable: true,
43920 configurable: true
43921 });
43922 /**
43923 * @hidden
43924 * @return {?}
43925 */
43926 Content.prototype.ngAfterViewInit = function () {
43927 var _this = this;
43928 (void 0) /* assert */;
43929 (void 0) /* assert */;
43930 var /** @type {?} */ scroll = this._scroll;
43931 scroll.ev.fixedElement = this.getFixedElement();
43932 scroll.ev.scrollElement = this.getScrollElement();
43933 // subscribe to the scroll start
43934 scroll.onScrollStart = function (ev) {
43935 _this.ionScrollStart.emit(ev);
43936 };
43937 // subscribe to every scroll move
43938 scroll.onScroll = function (ev) {
43939 // emit to all of our other friends things be scrolling
43940 _this.ionScroll.emit(ev);
43941 _this.imgsUpdate();
43942 };
43943 // subscribe to the scroll end
43944 scroll.onScrollEnd = function (ev) {
43945 _this.ionScrollEnd.emit(ev);
43946 _this.imgsUpdate();
43947 };
43948 };
43949 /**
43950 * @hidden
43951 * @return {?}
43952 */
43953 Content.prototype.enableJsScroll = function () {
43954 this._scroll.enableJsScroll(this._cTop, this._cBottom);
43955 };
43956 /**
43957 * @hidden
43958 * @return {?}
43959 */
43960 Content.prototype.ngOnDestroy = function () {
43961 this._scLsn && this._scLsn();
43962 this._viewCtrlReadSub && this._viewCtrlReadSub.unsubscribe();
43963 this._viewCtrlWriteSub && this._viewCtrlWriteSub.unsubscribe();
43964 this._viewCtrlReadSub = this._viewCtrlWriteSub = null;
43965 this._scroll && this._scroll.destroy();
43966 this._footerEle = this._scLsn = this._scroll = null;
43967 };
43968 /**
43969 * @hidden
43970 * @return {?}
43971 */
43972 Content.prototype.getScrollElement = function () {
43973 return this._scrollContent.nativeElement;
43974 };
43975 /**
43976 * @return {?}
43977 */
43978 Content.prototype.getFixedElement = function () {
43979 return this._fixedContent.nativeElement;
43980 };
43981 /**
43982 * @hidden
43983 * @param {?} callback
43984 * @return {?}
43985 */
43986 Content.prototype.onScrollElementTransitionEnd = function (callback) {
43987 this._plt.transitionEnd(this.getScrollElement(), callback);
43988 };
43989 /**
43990 * Scroll to the specified position.
43991 *
43992 * @param {?} x
43993 * @param {?} y
43994 * @param {?=} duration
43995 * @param {?=} done
43996 * @return {?}
43997 */
43998 Content.prototype.scrollTo = function (x, y, duration, done) {
43999 if (duration === void 0) { duration = 300; }
44000 (void 0) /* console.debug */;
44001 return this._scroll.scrollTo(x, y, duration, done);
44002 };
44003 /**
44004 * Scroll to the top of the content component.
44005 *
44006 * @param {?=} duration
44007 * @return {?}
44008 */
44009 Content.prototype.scrollToTop = function (duration) {
44010 if (duration === void 0) { duration = 300; }
44011 (void 0) /* console.debug */;
44012 return this._scroll.scrollToTop(duration);
44013 };
44014 /**
44015 * Scroll to the bottom of the content component.
44016 *
44017 * @param {?=} duration
44018 * @return {?}
44019 */
44020 Content.prototype.scrollToBottom = function (duration) {
44021 if (duration === void 0) { duration = 300; }
44022 (void 0) /* console.debug */;
44023 return this._scroll.scrollToBottom(duration);
44024 };
44025 Object.defineProperty(Content.prototype, "fullscreen", {
44026 /**
44027 * \@input {boolean} If true, the content will scroll behind the headers
44028 * and footers. This effect can easily be seen by setting the toolbar
44029 * to transparent.
44030 * @return {?}
44031 */
44032 get: function () {
44033 return this._fullscreen;
44034 },
44035 /**
44036 * @param {?} val
44037 * @return {?}
44038 */
44039 set: function (val) {
44040 this._fullscreen = isTrueProperty(val);
44041 },
44042 enumerable: true,
44043 configurable: true
44044 });
44045 Object.defineProperty(Content.prototype, "scrollDownOnLoad", {
44046 /**
44047 * \@input {boolean} If true, the content will scroll down on load.
44048 * @return {?}
44049 */
44050 get: function () {
44051 return this._scrollDownOnLoad;
44052 },
44053 /**
44054 * @param {?} val
44055 * @return {?}
44056 */
44057 set: function (val) {
44058 this._scrollDownOnLoad = isTrueProperty(val);
44059 },
44060 enumerable: true,
44061 configurable: true
44062 });
44063 /**
44064 * @param {?} img
44065 * @return {?}
44066 */
44067 Content.prototype.addImg = function (img) {
44068 this._imgs.push(img);
44069 };
44070 /**
44071 * @hidden
44072 * @param {?} img
44073 * @return {?}
44074 */
44075 Content.prototype.removeImg = function (img) {
44076 removeArrayItem(this._imgs, img);
44077 };
44078 /**
44079 * @hidden
44080 * DOM WRITE
44081 * @param {?} prop
44082 * @param {?} val
44083 * @return {?}
44084 */
44085 Content.prototype.setScrollElementStyle = function (prop, val) {
44086 var /** @type {?} */ scrollEle = this.getScrollElement();
44087 if (scrollEle) {
44088 this._dom.write(function () {
44089 ((scrollEle.style))[prop] = val;
44090 });
44091 }
44092 };
44093 /**
44094 * Returns the content and scroll elements' dimensions.
44095 * {number} dimensions.contentHeight content offsetHeight
44096 * {number} dimensions.contentTop content offsetTop
44097 * {number} dimensions.contentBottom content offsetTop+offsetHeight
44098 * {number} dimensions.contentWidth content offsetWidth
44099 * {number} dimensions.contentLeft content offsetLeft
44100 * {number} dimensions.contentRight content offsetLeft + offsetWidth
44101 * {number} dimensions.scrollHeight scroll scrollHeight
44102 * {number} dimensions.scrollTop scroll scrollTop
44103 * {number} dimensions.scrollBottom scroll scrollTop + scrollHeight
44104 * {number} dimensions.scrollWidth scroll scrollWidth
44105 * {number} dimensions.scrollLeft scroll scrollLeft
44106 * {number} dimensions.scrollRight scroll scrollLeft + scrollWidth
44107 * @return {?}
44108 */
44109 Content.prototype.getContentDimensions = function () {
44110 var /** @type {?} */ scrollEle = this.getScrollElement();
44111 var /** @type {?} */ parentElement = scrollEle.parentElement;
44112 return {
44113 contentHeight: parentElement.offsetHeight - this._cTop - this._cBottom,
44114 contentTop: this._cTop,
44115 contentBottom: this._cBottom,
44116 contentWidth: parentElement.offsetWidth,
44117 contentLeft: parentElement.offsetLeft,
44118 scrollHeight: scrollEle.scrollHeight,
44119 scrollTop: scrollEle.scrollTop,
44120 scrollWidth: scrollEle.scrollWidth,
44121 scrollLeft: scrollEle.scrollLeft,
44122 };
44123 };
44124 /**
44125 * @hidden
44126 * DOM WRITE
44127 * Adds padding to the bottom of the scroll element when the keyboard is open
44128 * so content below the keyboard can be scrolled into view.
44129 * @param {?} newPadding
44130 * @return {?}
44131 */
44132 Content.prototype.addScrollPadding = function (newPadding) {
44133 (void 0) /* assert */;
44134 if (newPadding > this._scrollPadding) {
44135 (void 0) /* console.debug */;
44136 this._scrollPadding = newPadding;
44137 var /** @type {?} */ scrollEle = this.getScrollElement();
44138 if (scrollEle) {
44139 this._dom.write(function () {
44140 scrollEle.style.paddingBottom = (newPadding > 0) ? newPadding + 'px' : '';
44141 });
44142 }
44143 }
44144 };
44145 /**
44146 * @hidden
44147 * DOM WRITE
44148 * @return {?}
44149 */
44150 Content.prototype.clearScrollPaddingFocusOut = function () {
44151 var _this = this;
44152 if (!this._inputPolling) {
44153 (void 0) /* console.debug */;
44154 this._inputPolling = true;
44155 this._keyboard.onClose(function () {
44156 (void 0) /* console.debug */;
44157 _this._inputPolling = false;
44158 _this._scrollPadding = -1;
44159 _this.addScrollPadding(0);
44160 }, 200, 3000);
44161 }
44162 };
44163 /**
44164 * Tell the content to recalculate its dimensions. This should be called
44165 * after dynamically adding/removing headers, footers, or tabs.
44166 * @return {?}
44167 */
44168 Content.prototype.resize = function () {
44169 this._dom.read(this._readDimensions.bind(this));
44170 this._dom.write(this._writeDimensions.bind(this));
44171 };
44172 /**
44173 * @hidden
44174 * DOM READ
44175 * @return {?}
44176 */
44177 Content.prototype._readDimensions = function () {
44178 var /** @type {?} */ cachePaddingTop = this._pTop;
44179 var /** @type {?} */ cachePaddingRight = this._pRight;
44180 var /** @type {?} */ cachePaddingBottom = this._pBottom;
44181 var /** @type {?} */ cachePaddingLeft = this._pLeft;
44182 var /** @type {?} */ cacheHeaderHeight = this._hdrHeight;
44183 var /** @type {?} */ cacheFooterHeight = this._ftrHeight;
44184 var /** @type {?} */ cacheTabsPlacement = this._tabsPlacement;
44185 var /** @type {?} */ tabsTop = 0;
44186 var /** @type {?} */ scrollEvent;
44187 this._pTop = 0;
44188 this._pRight = 0;
44189 this._pBottom = 0;
44190 this._pLeft = 0;
44191 this._hdrHeight = 0;
44192 this._ftrHeight = 0;
44193 this._tabsPlacement = null;
44194 this._tTop = 0;
44195 this._fTop = 0;
44196 this._fBottom = 0;
44197 // In certain cases this._scroll is undefined
44198 // if that is the case then we should just return
44199 if (!this._scroll) {
44200 return;
44201 }
44202 scrollEvent = this._scroll.ev;
44203 var /** @type {?} */ ele = this.getNativeElement();
44204 if (!ele) {
44205 (void 0) /* assert */;
44206 return;
44207 }
44208 var /** @type {?} */ computedStyle;
44209 var /** @type {?} */ tagName;
44210 var /** @type {?} */ parentEle = ele.parentElement;
44211 var /** @type {?} */ children = parentEle.children;
44212 for (var /** @type {?} */ i = children.length - 1; i >= 0; i--) {
44213 ele = (children[i]);
44214 tagName = ele.tagName;
44215 if (tagName === 'ION-CONTENT') {
44216 scrollEvent.contentElement = ele;
44217 if (this._fullscreen) {
44218 // ******** DOM READ ****************
44219 computedStyle = getComputedStyle(ele);
44220 this._pTop = parsePxUnit(computedStyle.paddingTop);
44221 this._pBottom = parsePxUnit(computedStyle.paddingBottom);
44222 this._pRight = parsePxUnit(computedStyle.paddingRight);
44223 this._pLeft = parsePxUnit(computedStyle.paddingLeft);
44224 }
44225 }
44226 else if (tagName === 'ION-HEADER') {
44227 scrollEvent.headerElement = ele;
44228 // ******** DOM READ ****************
44229 this._hdrHeight = ele.clientHeight;
44230 }
44231 else if (tagName === 'ION-FOOTER') {
44232 scrollEvent.footerElement = ele;
44233 // ******** DOM READ ****************
44234 this._ftrHeight = ele.clientHeight;
44235 this._footerEle = ele;
44236 }
44237 }
44238 ele = parentEle;
44239 var /** @type {?} */ tabbarEle;
44240 while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
44241 if (ele.tagName === 'ION-TABS') {
44242 tabbarEle = (ele.firstElementChild);
44243 // ******** DOM READ ****************
44244 this._tabbarHeight = tabbarEle.clientHeight;
44245 if (this._tabsPlacement === null) {
44246 // this is the first tabbar found, remember it's position
44247 this._tabsPlacement = ele.getAttribute('tabsplacement');
44248 }
44249 }
44250 ele = ele.parentElement;
44251 }
44252 // Tabs top
44253 if (this._tabs && this._tabsPlacement === 'top') {
44254 this._tTop = this._hdrHeight;
44255 tabsTop = this._tabs._top;
44256 }
44257 // Toolbar height
44258 this._cTop = this._hdrHeight;
44259 this._cBottom = this._ftrHeight;
44260 // Tabs height
44261 if (this._tabsPlacement === 'top') {
44262 this._cTop += this._tabbarHeight;
44263 }
44264 else if (this._tabsPlacement === 'bottom') {
44265 this._cBottom += this._tabbarHeight;
44266 }
44267 // Refresher uses a border which should be hidden unless pulled
44268 if (this._hasRefresher) {
44269 this._cTop -= 1;
44270 }
44271 // Fixed content shouldn't include content padding
44272 this._fTop = this._cTop;
44273 this._fBottom = this._cBottom;
44274 // Handle fullscreen viewport (padding vs margin)
44275 if (this._fullscreen) {
44276 this._cTop += this._pTop;
44277 this._cBottom += this._pBottom;
44278 }
44279 // ******** DOM READ ****************
44280 var /** @type {?} */ contentDimensions = this.getContentDimensions();
44281 scrollEvent.scrollHeight = contentDimensions.scrollHeight;
44282 scrollEvent.scrollWidth = contentDimensions.scrollWidth;
44283 scrollEvent.contentHeight = contentDimensions.contentHeight;
44284 scrollEvent.contentWidth = contentDimensions.contentWidth;
44285 scrollEvent.contentTop = contentDimensions.contentTop;
44286 scrollEvent.contentBottom = contentDimensions.contentBottom;
44287 this._dirty = (cachePaddingTop !== this._pTop ||
44288 cachePaddingBottom !== this._pBottom ||
44289 cachePaddingLeft !== this._pLeft ||
44290 cachePaddingRight !== this._pRight ||
44291 cacheHeaderHeight !== this._hdrHeight ||
44292 cacheFooterHeight !== this._ftrHeight ||
44293 cacheTabsPlacement !== this._tabsPlacement ||
44294 tabsTop !== this._tTop ||
44295 this._cTop !== this.contentTop ||
44296 this._cBottom !== this.contentBottom);
44297 this._scroll.init(this.getScrollElement(), this._cTop, this._cBottom);
44298 // initial imgs refresh
44299 this.imgsUpdate();
44300 };
44301 /**
44302 * @hidden
44303 * DOM WRITE
44304 * @return {?}
44305 */
44306 Content.prototype._writeDimensions = function () {
44307 if (!this._dirty) {
44308 (void 0) /* console.debug */;
44309 return;
44310 }
44311 var /** @type {?} */ scrollEle = this.getScrollElement();
44312 if (!scrollEle) {
44313 (void 0) /* assert */;
44314 return;
44315 }
44316 var /** @type {?} */ fixedEle = this.getFixedElement();
44317 if (!fixedEle) {
44318 (void 0) /* assert */;
44319 return;
44320 }
44321 // Tabs height
44322 if (this._tabsPlacement === 'bottom' && this._cBottom > 0 && this._footerEle) {
44323 var /** @type {?} */ footerPos = this._cBottom - this._ftrHeight;
44324 (void 0) /* assert */;
44325 // ******** DOM WRITE ****************
44326 this._footerEle.style.bottom = cssFormat(footerPos);
44327 }
44328 // Handle fullscreen viewport (padding vs margin)
44329 var /** @type {?} */ topProperty = 'marginTop';
44330 var /** @type {?} */ bottomProperty = 'marginBottom';
44331 var /** @type {?} */ fixedTop = this._fTop;
44332 var /** @type {?} */ fixedBottom = this._fBottom;
44333 if (this._fullscreen) {
44334 (void 0) /* assert */;
44335 (void 0) /* assert */;
44336 // adjust the content with padding, allowing content to scroll under headers/footers
44337 // however, on iOS you cannot control the margins of the scrollbar (last tested iOS9.2)
44338 // only add inline padding styles if the computed padding value, which would
44339 // have come from the app's css, is different than the new padding value
44340 topProperty = 'paddingTop';
44341 bottomProperty = 'paddingBottom';
44342 }
44343 // Only update top margin if value changed
44344 if (this._cTop !== this.contentTop) {
44345 (void 0) /* assert */;
44346 (void 0) /* assert */;
44347 // ******** DOM WRITE ****************
44348 ((scrollEle.style))[topProperty] = cssFormat(this._cTop);
44349 // ******** DOM WRITE ****************
44350 fixedEle.style.marginTop = cssFormat(fixedTop);
44351 this.contentTop = this._cTop;
44352 }
44353 // Only update bottom margin if value changed
44354 if (this._cBottom !== this.contentBottom) {
44355 (void 0) /* assert */;
44356 (void 0) /* assert */;
44357 // ******** DOM WRITE ****************
44358 ((scrollEle.style))[bottomProperty] = cssFormat(this._cBottom);
44359 // ******** DOM WRITE ****************
44360 fixedEle.style.marginBottom = cssFormat(fixedBottom);
44361 this.contentBottom = this._cBottom;
44362 }
44363 if (this._tabsPlacement !== null && this._tabs) {
44364 // set the position of the tabbar
44365 if (this._tabsPlacement === 'top') {
44366 // ******** DOM WRITE ****************
44367 this._tabs.setTabbarPosition(this._tTop, -1);
44368 }
44369 else {
44370 (void 0) /* assert */;
44371 // ******** DOM WRITE ****************
44372 this._tabs.setTabbarPosition(-1, 0);
44373 }
44374 }
44375 // Scroll the page all the way down after setting dimensions
44376 if (this._scrollDownOnLoad) {
44377 this.scrollToBottom(0);
44378 this._scrollDownOnLoad = false;
44379 }
44380 };
44381 /**
44382 * @hidden
44383 * @return {?}
44384 */
44385 Content.prototype.imgsUpdate = function () {
44386 if (this._scroll.initialized && this._imgs.length && this.isImgsUpdatable()) {
44387 updateImgs(this._imgs, this.scrollTop, this.contentHeight, this.directionY, this._imgReqBfr, this._imgRndBfr);
44388 }
44389 };
44390 /**
44391 * @hidden
44392 * @return {?}
44393 */
44394 Content.prototype.isImgsUpdatable = function () {
44395 // an image is only "updatable" if the content isn't scrolling too fast
44396 // if scroll speed is above the maximum velocity, then let current
44397 // requests finish, but do not start new requets or render anything
44398 // if scroll speed is below the maximum velocity, then it's ok
44399 // to start new requests and render images
44400 return Math.abs(this._scroll.ev.velocityY) < this._imgVelMax;
44401 };
44402 return Content;
44403}(Ion));
44404Content.decorators = [
44405 { type: Component, args: [{
44406 selector: 'ion-content',
44407 template: '<div class="fixed-content" #fixedContent>' +
44408 '<ng-content select="[ion-fixed],ion-fab"></ng-content>' +
44409 '</div>' +
44410 '<div class="scroll-content" #scrollContent>' +
44411 '<ng-content></ng-content>' +
44412 '</div>' +
44413 '<ng-content select="ion-refresher"></ng-content>',
44414 host: {
44415 '[class.statusbar-padding]': 'statusbarPadding',
44416 '[class.has-refresher]': '_hasRefresher'
44417 },
44418 changeDetection: ChangeDetectionStrategy.OnPush,
44419 encapsulation: ViewEncapsulation.None
44420 },] },
44421];
44422/**
44423 * @nocollapse
44424 */
44425Content.ctorParameters = function () { return [
44426 { type: Config, },
44427 { type: Platform, },
44428 { type: DomController, },
44429 { type: ElementRef, },
44430 { type: Renderer, },
44431 { type: App, },
44432 { type: Keyboard, },
44433 { type: NgZone, },
44434 { type: ViewController, decorators: [{ type: Optional },] },
44435 { type: NavController, decorators: [{ type: Optional },] },
44436]; };
44437Content.propDecorators = {
44438 '_fixedContent': [{ type: ViewChild, args: ['fixedContent', { read: ElementRef },] },],
44439 '_scrollContent': [{ type: ViewChild, args: ['scrollContent', { read: ElementRef },] },],
44440 'ionScrollStart': [{ type: Output },],
44441 'ionScroll': [{ type: Output },],
44442 'ionScrollEnd': [{ type: Output },],
44443 'fullscreen': [{ type: Input },],
44444 'scrollDownOnLoad': [{ type: Input },],
44445 'resize': [{ type: HostListener, args: ['window:resize',] },],
44446};
44447/**
44448 * @param {?} imgs
44449 * @param {?} viewableTop
44450 * @param {?} contentHeight
44451 * @param {?} scrollDirectionY
44452 * @param {?} requestableBuffer
44453 * @param {?} renderableBuffer
44454 * @return {?}
44455 */
44456function updateImgs(imgs, viewableTop, contentHeight, scrollDirectionY, requestableBuffer, renderableBuffer) {
44457 // ok, so it's time to see which images, if any, should be requested and rendered
44458 // ultimately, if we're scrolling fast then don't bother requesting or rendering
44459 // when scrolling is done, then it needs to do a check to see which images are
44460 // important to request and render, and which image requests should be aborted.
44461 // Additionally, images which are not near the viewable area should not be
44462 // rendered at all in order to save browser resources.
44463 var /** @type {?} */ viewableBottom = (viewableTop + contentHeight);
44464 var /** @type {?} */ priority1 = [];
44465 var /** @type {?} */ priority2 = [];
44466 var /** @type {?} */ img;
44467 // all images should be paused
44468 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = imgs.length; i < ilen; i++) {
44469 img = imgs[i];
44470 if (scrollDirectionY === 'up') {
44471 // scrolling up
44472 if (img.top < viewableBottom && img.bottom > viewableTop - renderableBuffer) {
44473 // scrolling up, img is within viewable area
44474 // or about to be viewable area
44475 img.canRequest = img.canRender = true;
44476 priority1.push(img);
44477 continue;
44478 }
44479 if (img.bottom <= viewableTop && img.bottom > viewableTop - requestableBuffer) {
44480 // scrolling up, img is within requestable area
44481 img.canRequest = true;
44482 img.canRender = false;
44483 priority2.push(img);
44484 continue;
44485 }
44486 if (img.top >= viewableBottom && img.top < viewableBottom + renderableBuffer) {
44487 // scrolling up, img below viewable area
44488 // but it's still within renderable area
44489 // don't allow a reset
44490 img.canRequest = img.canRender = false;
44491 continue;
44492 }
44493 }
44494 else {
44495 // scrolling down
44496 if (img.bottom > viewableTop && img.top < viewableBottom + renderableBuffer) {
44497 // scrolling down, img is within viewable area
44498 // or about to be viewable area
44499 img.canRequest = img.canRender = true;
44500 priority1.push(img);
44501 continue;
44502 }
44503 if (img.top >= viewableBottom && img.top < viewableBottom + requestableBuffer) {
44504 // scrolling down, img is within requestable area
44505 img.canRequest = true;
44506 img.canRender = false;
44507 priority2.push(img);
44508 continue;
44509 }
44510 if (img.bottom <= viewableTop && img.bottom > viewableTop - renderableBuffer) {
44511 // scrolling down, img above viewable area
44512 // but it's still within renderable area
44513 // don't allow a reset
44514 img.canRequest = img.canRender = false;
44515 continue;
44516 }
44517 }
44518 img.canRequest = img.canRender = false;
44519 img.reset();
44520 }
44521 // update all imgs which are viewable
44522 priority1.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
44523 if (scrollDirectionY === 'up') {
44524 // scrolling up
44525 priority2.sort(sortTopToBottom).reverse().forEach(function (i) { return i.update(); });
44526 }
44527 else {
44528 // scrolling down
44529 priority2.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
44530 }
44531}
44532/**
44533 * @param {?} a
44534 * @param {?} b
44535 * @return {?}
44536 */
44537function sortTopToBottom(a, b) {
44538 if (a.top < b.top) {
44539 return -1;
44540 }
44541 if (a.top > b.top) {
44542 return 1;
44543 }
44544 return 0;
44545}
44546/**
44547 * @param {?} val
44548 * @return {?}
44549 */
44550function parsePxUnit(val) {
44551 return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
44552}
44553/**
44554 * @param {?} val
44555 * @return {?}
44556 */
44557function cssFormat(val) {
44558 return (val > 0 ? val + 'px' : '');
44559}
44560
44561/**
44562 * @hidden
44563 * @param {?} element
44564 * @return {?}
44565 */
44566function indexForItem(element) {
44567 return element['$ionIndex'];
44568}
44569/**
44570 * @hidden
44571 * @param {?} element
44572 * @return {?}
44573 */
44574
44575/**
44576 * @hidden
44577 * @param {?} node
44578 * @param {?} listNode
44579 * @return {?}
44580 */
44581function findReorderItem(node, listNode) {
44582 var /** @type {?} */ nested = 0;
44583 while (node && nested < 4) {
44584 if (indexForItem(node) !== undefined) {
44585 if (listNode && node.parentNode !== listNode) {
44586 return null;
44587 }
44588 return node;
44589 }
44590 node = node.parentNode;
44591 nested++;
44592 }
44593 return null;
44594}
44595
44596/**
44597 * @hidden
44598 */
44599var ItemReorderGesture = (function () {
44600 /**
44601 * @param {?} plt
44602 * @param {?} reorderList
44603 */
44604 function ItemReorderGesture(plt, reorderList) {
44605 this.plt = plt;
44606 this.reorderList = reorderList;
44607 this.selectedItemEle = null;
44608 this.events = new UIEventManager(plt);
44609 this.events.pointerEvents({
44610 element: this.reorderList.getNativeElement(),
44611 pointerDown: this.onDragStart.bind(this),
44612 pointerMove: this.onDragMove.bind(this),
44613 pointerUp: this.onDragEnd.bind(this),
44614 zone: false
44615 });
44616 }
44617 /**
44618 * @param {?} ev
44619 * @return {?}
44620 */
44621 ItemReorderGesture.prototype.onDragStart = function (ev) {
44622 if (this.selectedItemEle) {
44623 return false;
44624 }
44625 var /** @type {?} */ reorderElement = ev.target;
44626 if (reorderElement.nodeName !== 'ION-REORDER') {
44627 return false;
44628 }
44629 var /** @type {?} */ reorderMark = reorderElement['$ionComponent'];
44630 if (!reorderMark) {
44631 console.error('ion-reorder does not contain $ionComponent');
44632 return false;
44633 }
44634 this.reorderList._reorderPrepare();
44635 var /** @type {?} */ item = reorderMark.getReorderNode();
44636 if (!item) {
44637 console.error('reorder node not found');
44638 return false;
44639 }
44640 ev.preventDefault();
44641 // Preparing state
44642 this.selectedItemEle = item;
44643 this.selectedItemHeight = item.offsetHeight;
44644 this.lastYcoord = -100;
44645 this.lastToIndex = indexForItem(item);
44646 this.windowHeight = this.plt.height() - AUTO_SCROLL_MARGIN;
44647 this.lastScrollPosition = this.reorderList._scrollContent(0);
44648 this.offset = pointerCoord(ev);
44649 this.offset.y += this.lastScrollPosition;
44650 item.classList.add(ITEM_REORDER_ACTIVE);
44651 this.reorderList._reorderStart();
44652 return true;
44653 };
44654 /**
44655 * @param {?} ev
44656 * @return {?}
44657 */
44658 ItemReorderGesture.prototype.onDragMove = function (ev) {
44659 var /** @type {?} */ selectedItem = this.selectedItemEle;
44660 if (!selectedItem) {
44661 return;
44662 }
44663 ev.preventDefault();
44664 // Get coordinate
44665 var /** @type {?} */ coord = pointerCoord(ev);
44666 var /** @type {?} */ posY = coord.y;
44667 // Scroll if we reach the scroll margins
44668 var /** @type {?} */ scrollPosition = this.scroll(posY);
44669 // Only perform hit test if we moved at least 30px from previous position
44670 if (Math.abs(posY - this.lastYcoord) > 30) {
44671 var /** @type {?} */ overItem = this.itemForCoord(coord);
44672 if (overItem) {
44673 var /** @type {?} */ toIndex = indexForItem(overItem);
44674 if (toIndex !== undefined && (toIndex !== this.lastToIndex || this.emptyZone)) {
44675 var /** @type {?} */ fromIndex = indexForItem(selectedItem);
44676 this.lastToIndex = toIndex;
44677 this.lastYcoord = posY;
44678 this.emptyZone = false;
44679 this.reorderList._reorderMove(fromIndex, toIndex, this.selectedItemHeight);
44680 }
44681 }
44682 else {
44683 this.emptyZone = true;
44684 }
44685 }
44686 // Update selected item position
44687 var /** @type {?} */ ydiff = Math.round(posY - this.offset.y + scrollPosition);
44688 ((selectedItem.style))[this.plt.Css.transform] = "translateY(" + ydiff + "px)";
44689 };
44690 /**
44691 * @param {?} ev
44692 * @return {?}
44693 */
44694 ItemReorderGesture.prototype.onDragEnd = function (ev) {
44695 var _this = this;
44696 var /** @type {?} */ selectedItem = this.selectedItemEle;
44697 if (!selectedItem) {
44698 return;
44699 }
44700 if (ev) {
44701 ev.preventDefault();
44702 ev.stopPropagation();
44703 }
44704 var /** @type {?} */ toIndex = this.lastToIndex;
44705 var /** @type {?} */ fromIndex = indexForItem(selectedItem);
44706 var /** @type {?} */ reorderInactive = function () {
44707 _this.selectedItemEle.style.transition = '';
44708 _this.selectedItemEle.classList.remove(ITEM_REORDER_ACTIVE);
44709 _this.selectedItemEle = null;
44710 };
44711 if (toIndex === fromIndex) {
44712 selectedItem.style.transition = 'transform 200ms ease-in-out';
44713 setTimeout(reorderInactive, 200);
44714 }
44715 else {
44716 reorderInactive();
44717 }
44718 this.reorderList._reorderEmit(fromIndex, toIndex);
44719 };
44720 /**
44721 * @param {?} coord
44722 * @return {?}
44723 */
44724 ItemReorderGesture.prototype.itemForCoord = function (coord) {
44725 var /** @type {?} */ sideOffset = this.reorderList._isStart === this.plt.isRTL ? -100 : 100;
44726 var /** @type {?} */ x = this.offset.x + sideOffset;
44727 var /** @type {?} */ y = coord.y;
44728 var /** @type {?} */ element = this.plt.getElementFromPoint(x, y);
44729 return findReorderItem(element, this.reorderList.getNativeElement());
44730 };
44731 /**
44732 * @param {?} posY
44733 * @return {?}
44734 */
44735 ItemReorderGesture.prototype.scroll = function (posY) {
44736 if (posY < AUTO_SCROLL_MARGIN) {
44737 this.lastScrollPosition = this.reorderList._scrollContent(-SCROLL_JUMP);
44738 }
44739 else if (posY > this.windowHeight) {
44740 this.lastScrollPosition = this.reorderList._scrollContent(SCROLL_JUMP);
44741 }
44742 return this.lastScrollPosition;
44743 };
44744 /**
44745 * @hidden
44746 * @return {?}
44747 */
44748 ItemReorderGesture.prototype.destroy = function () {
44749 this.onDragEnd(null);
44750 this.events.destroy();
44751 this.events = null;
44752 this.reorderList = null;
44753 };
44754 return ItemReorderGesture;
44755}());
44756var AUTO_SCROLL_MARGIN = 60;
44757var SCROLL_JUMP = 10;
44758var ITEM_REORDER_ACTIVE = 'reorder-active';
44759
44760var ReorderIndexes = (function () {
44761 /**
44762 * @param {?} from
44763 * @param {?} to
44764 */
44765 function ReorderIndexes(from, to) {
44766 this.from = from;
44767 this.to = to;
44768 }
44769 /**
44770 * @param {?} array
44771 * @return {?}
44772 */
44773 ReorderIndexes.prototype.applyTo = function (array) {
44774 reorderArray(array, this);
44775 };
44776 return ReorderIndexes;
44777}());
44778/**
44779 * \@name ItemReorder
44780 * \@description
44781 * Item reorder adds the ability to change an item's order in a group.
44782 * It can be used within an `ion-list` or `ion-item-group` to provide a
44783 * visual drag and drop interface.
44784 *
44785 * ## Grouping Items
44786 *
44787 * All reorderable items must be grouped in the same element. If an item
44788 * should not be reordered, it shouldn't be included in this group. For
44789 * example, the following code works because the items are grouped in the
44790 * `<ion-list>`:
44791 *
44792 * ```html
44793 * <ion-list reorder="true">
44794 * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
44795 * </ion-list>
44796 * ```
44797 *
44798 * However, the below list includes a header that shouldn't be reordered:
44799 *
44800 * ```html
44801 * <ion-list reorder="true">
44802 * <ion-list-header>Header</ion-list-header>
44803 * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
44804 * </ion-list>
44805 * ```
44806 *
44807 * In order to mix different sets of items, `ion-item-group` should be used to
44808 * group the reorderable items:
44809 *
44810 * ```html
44811 * <ion-list>
44812 * <ion-list-header>Header</ion-list-header>
44813 * <ion-item-group reorder="true">
44814 * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
44815 * </ion-item-group>
44816 * </ion-list>
44817 * ```
44818 *
44819 * It's important to note that in this example, the `[reorder]` directive is applied to
44820 * the `<ion-item-group>` instead of the `<ion-list>`. This way makes it possible to
44821 * mix items that should and shouldn't be reordered.
44822 *
44823 *
44824 * ## Implementing the Reorder Function
44825 *
44826 * When the item is dragged and dropped into the new position, the `(ionItemReorder)` event is
44827 * emitted. This event provides the initial index (from) and the new index (to) of the reordered
44828 * item. For example, if the first item is dragged to the fifth position, the event will emit
44829 * `{from: 0, to: 4}`. Note that the index starts at zero.
44830 *
44831 * A function should be called when the event is emitted that handles the reordering of the items.
44832 * See [usage](#usage) below for some examples.
44833 *
44834 *
44835 * \@usage
44836 *
44837 * ```html
44838 * <ion-list>
44839 * <ion-list-header>Header</ion-list-header>
44840 * <ion-item-group reorder="true" (ionItemReorder)="reorderItems($event)">
44841 * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
44842 * </ion-item-group>
44843 * </ion-list>
44844 * ```
44845 *
44846 * ```ts
44847 * class MyComponent {
44848 * items = [];
44849 *
44850 * constructor() {
44851 * for (let x = 0; x < 5; x++) {
44852 * this.items.push(x);
44853 * }
44854 * }
44855 *
44856 * reorderItems(indexes) {
44857 * let element = this.items[indexes.from];
44858 * this.items.splice(indexes.from, 1);
44859 * this.items.splice(indexes.to, 0, element);
44860 * }
44861 * }
44862 * ```
44863 *
44864 * Ionic also provides a helper function called `reorderArray` to
44865 * reorder the array of items. This can be used instead:
44866 *
44867 * ```ts
44868 * import { reorderArray } from 'ionic-angular';
44869 *
44870 * class MyComponent {
44871 * items = [];
44872 *
44873 * constructor() {
44874 * for (let x = 0; x < 5; x++) {
44875 * this.items.push(x);
44876 * }
44877 * }
44878 *
44879 * reorderItems(indexes) {
44880 * this.items = reorderArray(this.items, indexes);
44881 * }
44882 * }
44883 * ```
44884 * Alternatevely you can execute helper function inside template:
44885 *
44886 * ```html
44887 * <ion-list>
44888 * <ion-list-header>Header</ion-list-header>
44889 * <ion-item-group reorder="true" (ionItemReorder)="$event.applyTo(items)">
44890 * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
44891 * </ion-item-group>
44892 * </ion-list>
44893 * ```
44894 *
44895 * \@demo /docs/demos/src/item-reorder/
44896 * @see {\@link /docs/components#lists List Component Docs}
44897 * @see {\@link ../../list/List List API Docs}
44898 * @see {\@link ../Item Item API Docs}
44899 */
44900var ItemReorder = (function () {
44901 /**
44902 * @param {?} _plt
44903 * @param {?} _dom
44904 * @param {?} elementRef
44905 * @param {?} _rendered
44906 * @param {?} _zone
44907 * @param {?} _content
44908 */
44909 function ItemReorder(_plt, _dom, elementRef, _rendered, _zone, _content) {
44910 this._plt = _plt;
44911 this._dom = _dom;
44912 this._rendered = _rendered;
44913 this._zone = _zone;
44914 this._content = _content;
44915 this._enableReorder = false;
44916 this._visibleReorder = false;
44917 this._isStart = false;
44918 this._lastToIndex = -1;
44919 /**
44920 * \@output {object} Emitted when the item is reordered. Emits an object
44921 * with `from` and `to` properties.
44922 */
44923 this.ionItemReorder = new EventEmitter();
44924 this._element = elementRef.nativeElement;
44925 }
44926 Object.defineProperty(ItemReorder.prototype, "side", {
44927 /**
44928 * \@input {string} Which side of the view the ion-reorder should be placed. Default `"end"`.
44929 * @param {?} side
44930 * @return {?}
44931 */
44932 set: function (side) {
44933 this._isStart = side === 'start';
44934 },
44935 enumerable: true,
44936 configurable: true
44937 });
44938 /**
44939 * @hidden
44940 * @return {?}
44941 */
44942 ItemReorder.prototype.ngOnDestroy = function () {
44943 this._element = null;
44944 this._reorderGesture && this._reorderGesture.destroy();
44945 };
44946 Object.defineProperty(ItemReorder.prototype, "reorder", {
44947 /**
44948 * @hidden
44949 * @return {?}
44950 */
44951 get: function () {
44952 return this._enableReorder;
44953 },
44954 /**
44955 * @param {?} val
44956 * @return {?}
44957 */
44958 set: function (val) {
44959 var _this = this;
44960 var /** @type {?} */ enabled = isTrueProperty(val);
44961 if (!enabled && this._reorderGesture) {
44962 this._reorderGesture.destroy();
44963 this._reorderGesture = null;
44964 this._visibleReorder = false;
44965 setTimeout(function () { return _this._enableReorder = false; }, 400);
44966 }
44967 else if (enabled && !this._reorderGesture) {
44968 (void 0) /* console.debug */;
44969 this._reorderGesture = new ItemReorderGesture(this._plt, this);
44970 this._enableReorder = true;
44971 this._dom.write(function () {
44972 _this._zone.run(function () {
44973 _this._visibleReorder = true;
44974 });
44975 }, 16);
44976 }
44977 },
44978 enumerable: true,
44979 configurable: true
44980 });
44981 /**
44982 * @return {?}
44983 */
44984 ItemReorder.prototype._reorderPrepare = function () {
44985 var /** @type {?} */ ele = this._element;
44986 var /** @type {?} */ children = ele.children;
44987 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = children.length; i < ilen; i++) {
44988 var /** @type {?} */ child = children[i];
44989 child.$ionIndex = i;
44990 child.$ionReorderList = ele;
44991 }
44992 };
44993 /**
44994 * @return {?}
44995 */
44996 ItemReorder.prototype._reorderStart = function () {
44997 this.setElementClass('reorder-list-active', true);
44998 };
44999 /**
45000 * @param {?} fromIndex
45001 * @param {?} toIndex
45002 * @return {?}
45003 */
45004 ItemReorder.prototype._reorderEmit = function (fromIndex, toIndex) {
45005 var _this = this;
45006 this._reorderReset();
45007 if (fromIndex !== toIndex) {
45008 this._zone.run(function () {
45009 var /** @type {?} */ indexes = new ReorderIndexes(fromIndex, toIndex);
45010 _this.ionItemReorder.emit(indexes);
45011 });
45012 }
45013 };
45014 /**
45015 * @param {?} scroll
45016 * @return {?}
45017 */
45018 ItemReorder.prototype._scrollContent = function (scroll) {
45019 var /** @type {?} */ scrollTop = this._content.scrollTop + scroll;
45020 if (scroll !== 0) {
45021 this._content.scrollTo(0, scrollTop, 0);
45022 }
45023 return scrollTop;
45024 };
45025 /**
45026 * @return {?}
45027 */
45028 ItemReorder.prototype._reorderReset = function () {
45029 var /** @type {?} */ children = this._element.children;
45030 var /** @type {?} */ len = children.length;
45031 this.setElementClass('reorder-list-active', false);
45032 var /** @type {?} */ transform = this._plt.Css.transform;
45033 for (var /** @type {?} */ i = 0; i < len; i++) {
45034 ((children[i])).style[transform] = '';
45035 }
45036 this._lastToIndex = -1;
45037 };
45038 /**
45039 * @param {?} fromIndex
45040 * @param {?} toIndex
45041 * @param {?} itemHeight
45042 * @return {?}
45043 */
45044 ItemReorder.prototype._reorderMove = function (fromIndex, toIndex, itemHeight) {
45045 if (this._lastToIndex === -1) {
45046 this._lastToIndex = fromIndex;
45047 }
45048 var /** @type {?} */ lastToIndex = this._lastToIndex;
45049 this._lastToIndex = toIndex;
45050 /**
45051 * ****** DOM READ **********
45052 */
45053 var children = this._element.children;
45054 /**
45055 * ****** DOM WRITE *********
45056 */
45057 var transform = this._plt.Css.transform;
45058 if (toIndex >= lastToIndex) {
45059 for (var /** @type {?} */ i = lastToIndex; i <= toIndex; i++) {
45060 if (i !== fromIndex) {
45061 ((children[i])).style[transform] = (i > fromIndex)
45062 ? "translateY(" + -itemHeight + "px)" : '';
45063 }
45064 }
45065 }
45066 if (toIndex <= lastToIndex) {
45067 for (var /** @type {?} */ i = toIndex; i <= lastToIndex; i++) {
45068 if (i !== fromIndex) {
45069 ((children[i])).style[transform] = (i < fromIndex)
45070 ? "translateY(" + itemHeight + "px)" : '';
45071 }
45072 }
45073 }
45074 };
45075 /**
45076 * @hidden
45077 * @param {?} classname
45078 * @param {?} add
45079 * @return {?}
45080 */
45081 ItemReorder.prototype.setElementClass = function (classname, add) {
45082 this._rendered.setElementClass(this._element, classname, add);
45083 };
45084 /**
45085 * @hidden
45086 * @return {?}
45087 */
45088 ItemReorder.prototype.getNativeElement = function () {
45089 return this._element;
45090 };
45091 return ItemReorder;
45092}());
45093ItemReorder.decorators = [
45094 { type: Directive, args: [{
45095 selector: 'ion-list[reorder],ion-item-group[reorder]',
45096 host: {
45097 '[class.reorder-enabled]': '_enableReorder',
45098 '[class.reorder-visible]': '_visibleReorder',
45099 '[class.reorder-side-start]': '_isStart'
45100 }
45101 },] },
45102];
45103/**
45104 * @nocollapse
45105 */
45106ItemReorder.ctorParameters = function () { return [
45107 { type: Platform, },
45108 { type: DomController, },
45109 { type: ElementRef, },
45110 { type: Renderer, },
45111 { type: NgZone, },
45112 { type: Content, decorators: [{ type: Optional },] },
45113]; };
45114ItemReorder.propDecorators = {
45115 'ionItemReorder': [{ type: Output },],
45116 'side': [{ type: Input, args: ['side',] },],
45117 'reorder': [{ type: Input },],
45118};
45119
45120var __extends$39 = (undefined && undefined.__extends) || (function () {
45121 var extendStatics = Object.setPrototypeOf ||
45122 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
45123 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
45124 return function (d, b) {
45125 extendStatics(d, b);
45126 function __() { this.constructor = d; }
45127 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
45128 };
45129})();
45130/**
45131 * \@name Item
45132 * \@description
45133 * An item can contain text, images, and anything else. Generally it is placed in a list with other
45134 * items. It can easily be swiped, deleted, reordered, edited, and more. An item is only required to
45135 * be in a [List](../../list/List) if manipulating the item via gestures is required. It requires an
45136 * [ItemSliding](../ItemSliding) wrapper element in order to be swiped.
45137 *
45138 *
45139 * ## Common Usage
45140 * There are a few elements that are considered items, but not all of them are styled to look the same.
45141 * The basic item can be written as an `<ion-item>` element or it can be added to any element by adding
45142 * `ion-item` as an attribute. List headers and item dividers, although styled differently, are also items
45143 * and can be written as `<ion-list-header>` and `<ion-item-divider>`, respectively.
45144 *
45145 * ### As an Element
45146 * A basic item should be written as a `<ion-item>` element when it is not clickable.
45147 *
45148 * ```html
45149 * <ion-item>
45150 * Item
45151 * </ion-item>
45152 * ```
45153 *
45154 * A list header should be written as `<ion-list-header>`.
45155 *
45156 * ```html
45157 * <ion-list-header>
45158 * List Header
45159 * </ion-list-header>
45160 * ```
45161 *
45162 * An item divider should be written as `<ion-item-divider>`.
45163 *
45164 * ```html
45165 * <ion-item-divider>
45166 * Item Divider
45167 * </ion-item-divider>
45168 * ```
45169 *
45170 * ### As an Attribute
45171 * The attribute `ion-item` should be added to a `<button>` when the item can be clicked or tapped. It
45172 * should be added to an `<a>` element when the item needs to contain a `href`. It can be added as an
45173 * attribute to any element to take on the item styling.
45174 *
45175 * ```html
45176 * <button ion-item (click)="buttonClick()">
45177 * Button Item
45178 * </button>
45179 *
45180 * <a ion-item href="https://www.ionicframework.com">
45181 * Anchor Item
45182 * </a>
45183 * ```
45184 *
45185 * Note: do not add `ion-item` as an attribute to an `<ion-list-header>` or `<ion-item-divider>` element
45186 * as they are already items and their styling will be changed to look like a basic item.
45187 *
45188 * ## Detail Arrows
45189 * By default, `<button>` and `<a>` elements with the `ion-item` attribute will display a right arrow icon
45190 * on `ios` mode. To hide the right arrow icon on either of these elements, add the `detail-none` attribute
45191 * to the item. To show the right arrow icon on an element that doesn't display it naturally, add the
45192 * `detail-push` attribute to the item.
45193 *
45194 * ```html
45195 * <ion-item detail-push>
45196 * Item with Detail Arrow
45197 * </ion-item>
45198 *
45199 * <button ion-item (click)="buttonClick()">
45200 * Button Item with Detail Arrow
45201 * </button>
45202 *
45203 * <a ion-item detail-none href="https://www.ionicframework.com">
45204 * Anchor Item with no Detail Arrow
45205 * </a>
45206 * ```
45207 *
45208 * This feature is not enabled by default for `md` and `wp` modes, but it can be enabled by setting the
45209 * Sass variables `$item-md-detail-push-show` and `$item-wp-detail-push-show`, respectively, to `true`.
45210 * It can also be disabled for ios by setting `$item-ios-detail-push-show` to `false`. See the
45211 * [theming documentation](http://ionicframework.com/docs/theming/overriding-ionic-variables/) for
45212 * more information on overriding Sass variables.
45213 *
45214 *
45215 * ## Item Placement
45216 * Items rely heavily on content projection to position content. The item grabs content based on the
45217 * element or attribute and positions it that way. This logic makes it possible to write a complex
45218 * item with simple, understandable markup without having to worry about styling and positioning
45219 * the elements.
45220 *
45221 * The below chart details the attributes item looks for and where it will place the element with
45222 * that attribute inside of the item:
45223 *
45224 * | Attribute | Description |
45225 * |----------------|----------------------------------------------------------------------------------------------------- |
45226 * | `item-start` | Placed to the left of all other elements, outside of the inner item. |
45227 * | `item-end` | Placed to the right of all other elements, inside of the inner item, outside of the input wrapper. |
45228 * | `item-content` | Placed to the right of any `ion-label`, inside of the input wrapper. |
45229 *
45230 * ### Checkboxes, Radios and Toggles
45231 * [Checkboxes](../../checkbox/Checkbox) are positioned in the same place as the `item-start` attribute.
45232 * [Radios](../../radio/RadioButton) and [Toggles](../../toggle/Toggle) are positioned in the same place
45233 * as the `item-end` attribute. All of these components can be positioned differently by adding the
45234 * `item-start` or `item-end` attribute.
45235 *
45236 * ### Content and Inputs
45237 * A [Label](../../label/Label) is placed inside of the item to the left of all content and inputs. The
45238 * following components are all placed in the same position as the `item-content` attribute: [Select](../../select/Select),
45239 * [Input](../../input/Input), [TextArea](../../input/TextArea), [DateTime](../../datetime/DateTime), and
45240 * [Range](../../range/Range).
45241 *
45242 * Any element directly placed inside of an `<ion-item>` that does not have one of the previously mentioned
45243 * attributes and isn't one of the above elements will be placed inside of a [Label](../../label/Label).
45244 *
45245 * ### Text Alignment
45246 * By default, Items will align text to the left and add an ellipsis when the text is wider than the item.
45247 * See the [Utility Attributes Documentation](../../../../theming/css-utilities/) for attributes that can
45248 * be added to `ion-item` to transform the text.
45249 *
45250 * \@usage
45251 *
45252 * ```html
45253 * <ion-list>
45254 *
45255 * <ion-list-header>
45256 * Header
45257 * </ion-list-header>
45258 *
45259 * <ion-item>
45260 * Item
45261 * </ion-item>
45262 *
45263 * <ion-item detail-push>
45264 * Item with Detail Arrow
45265 * </ion-item>
45266 *
45267 * <button ion-item (click)="buttonClick()">
45268 * Button Item
45269 * </button>
45270 *
45271 * <ion-item-divider>
45272 * Item Divider
45273 * </ion-item-divider>
45274 *
45275 * <button ion-item detail-none (click)="buttonClick()">
45276 * Button Item with no Detail Arrow
45277 * </button>
45278 *
45279 * <a ion-item href="https://www.ionicframework.com">
45280 * Anchor Item
45281 * </a>
45282 *
45283 * <ion-item no-lines>
45284 * Item with no border
45285 * </ion-item>
45286 *
45287 * <ion-item text-wrap>
45288 * Multiline text that should wrap when it is too long
45289 * to fit on one line in the item.
45290 * </ion-item>
45291 *
45292 * </ion-list>
45293 * ```
45294 *
45295 *
45296 * \@advanced
45297 *
45298 * ```html
45299 * <ion-list>
45300 *
45301 * <!-- List header with buttons on each side -->
45302 * <ion-list-header>
45303 * <button ion-button item-start (click)="buttonClick()">Button</button>
45304 * List Header
45305 * <button ion-button outline item-end (click)="buttonClick()">Outline</button>
45306 * </ion-list-header>
45307 *
45308 * <!-- Loops through and creates multiple items -->
45309 * <ion-item *ngFor="let item of items">
45310 * Item {% raw %}{{item}}{% endraw %}
45311 * </ion-item>
45312 *
45313 * <!-- Button item with an icon on the left -->
45314 * <button ion-item>
45315 * <ion-icon name="star" item-start></ion-icon>
45316 * Button Item
45317 * </button>
45318 *
45319 * <!-- Item with a label and content -->
45320 * <ion-item>
45321 * <ion-label>
45322 * Item Label
45323 * </ion-label>
45324 * <div item-content>
45325 * Item Content next to the label
45326 * </div>
45327 * </ion-item>
45328 *
45329 * <!-- Item with left and right buttons -->
45330 * <ion-item>
45331 * <button ion-button item-start (click)="buttonClick()">Button</button>
45332 * Item
45333 * <button ion-button outline item-end (click)="buttonClick()">Outline</button>
45334 * </ion-item>
45335 *
45336 * <!-- Item divider with a right button -->
45337 * <ion-item-divider>
45338 * Item Divider
45339 * <button ion-button item-end>Button</button>
45340 * </ion-item-divider>
45341 *
45342 * <!-- Disabled button item with left and right buttons -->
45343 * <button ion-item disabled>
45344 * <button ion-button item-start (click)="buttonClick()">
45345 * <ion-icon name="home"></ion-icon>
45346 * Left Icon
45347 * </button>
45348 * Disabled Button Item
45349 * <button ion-button outline item-end (click)="buttonClick()">
45350 * <ion-icon name="star"></ion-icon>
45351 * Left Icon
45352 * </button>
45353 * </button>
45354 *
45355 * <!-- Item with an avatar on the left and button on the right -->
45356 * <ion-item>
45357 * <ion-avatar item-start>
45358 * <img src="img/my-avatar.png">
45359 * </ion-avatar>
45360 * Avatar Item
45361 * <button ion-button outline item-end>View</button>
45362 * </ion-item>
45363 *
45364 * <!-- Item with a thumbnail on the right -->
45365 * <ion-item>
45366 * <h2>Item</h2>
45367 * <p>Item Paragraph</p>
45368 * <ion-thumbnail item-end>
45369 * <img src="img/my-thumbnail.png">
45370 * </ion-thumbnail>
45371 * </ion-item>
45372 *
45373 * <!-- Sliding item -->
45374 * <ion-item-sliding>
45375 * <ion-item>
45376 * Item
45377 * </ion-item>
45378 * <ion-item-options>
45379 * <button ion-button color="primary" (click)="archive()">Archive</button>
45380 * </ion-item-options>
45381 * </ion-item-sliding>
45382 *
45383 * </ion-list>
45384 * ```
45385 *
45386 *
45387 * \@demo /docs/demos/src/item/
45388 * @see {\@link /docs/components#lists List Component Docs}
45389 * @see {\@link ../../list/List List API Docs}
45390 * @see {\@link ../ItemSliding ItemSliding API Docs}
45391 */
45392var Item = (function (_super) {
45393 __extends$39(Item, _super);
45394 /**
45395 * @param {?} form
45396 * @param {?} config
45397 * @param {?} elementRef
45398 * @param {?} renderer
45399 * @param {?} reorder
45400 */
45401 function Item(form, config, elementRef, renderer, reorder) {
45402 var _this = _super.call(this, config, elementRef, renderer, 'item') || this;
45403 _this._ids = -1;
45404 _this._inputs = [];
45405 _this._viewLabel = true;
45406 _this._name = 'item';
45407 /**
45408 * @hidden
45409 */
45410 _this.labelId = null;
45411 _this._setName(elementRef);
45412 _this._hasReorder = !!reorder;
45413 _this.id = form.nextId().toString();
45414 _this.labelId = 'lbl-' + _this.id;
45415 // auto add "tappable" attribute to ion-item components that have a click listener
45416 if (!renderer.orgListen) {
45417 renderer.orgListen = renderer.listen;
45418 renderer.listen = function (renderElement, name, callback) {
45419 if (name === 'click' && renderElement.setAttribute) {
45420 renderElement.setAttribute('tappable', '');
45421 }
45422 return renderer.orgListen(renderElement, name, callback);
45423 };
45424 }
45425 return _this;
45426 }
45427 /**
45428 * @hidden
45429 * @param {?} type
45430 * @return {?}
45431 */
45432 Item.prototype.registerInput = function (type) {
45433 this._inputs.push(type);
45434 return this.id + '-' + (++this._ids);
45435 };
45436 /**
45437 * @hidden
45438 * @return {?}
45439 */
45440 Item.prototype.ngAfterContentInit = function () {
45441 if (this._viewLabel && this._inputs.length) {
45442 var /** @type {?} */ labelText = this.getLabelText().trim();
45443 this._viewLabel = (labelText.length > 0);
45444 }
45445 if (this._inputs.length > 1) {
45446 this.setElementClass('item-multiple-inputs', true);
45447 }
45448 };
45449 /**
45450 * @hidden
45451 * @param {?} newColor
45452 * @param {?=} componentName
45453 * @return {?}
45454 */
45455 Item.prototype._updateColor = function (newColor, componentName) {
45456 componentName = componentName || 'item'; // item-radio
45457 this._setColor(newColor, componentName);
45458 };
45459 /**
45460 * @hidden
45461 * @param {?} elementRef
45462 * @return {?}
45463 */
45464 Item.prototype._setName = function (elementRef) {
45465 var /** @type {?} */ nodeName = elementRef.nativeElement.nodeName.replace('ION-', '');
45466 if (nodeName === 'LIST-HEADER' || nodeName === 'ITEM-DIVIDER') {
45467 this._name = nodeName;
45468 }
45469 };
45470 /**
45471 * @hidden
45472 * @return {?}
45473 */
45474 Item.prototype.getLabelText = function () {
45475 return this._label ? this._label.text : '';
45476 };
45477 Object.defineProperty(Item.prototype, "contentLabel", {
45478 /**
45479 * @hidden
45480 * @param {?} label
45481 * @return {?}
45482 */
45483 set: function (label) {
45484 if (label) {
45485 this._label = label;
45486 label.id = this.labelId;
45487 if (label.type) {
45488 this.setElementClass('item-label-' + label.type, true);
45489 }
45490 this._viewLabel = false;
45491 }
45492 },
45493 enumerable: true,
45494 configurable: true
45495 });
45496 Object.defineProperty(Item.prototype, "viewLabel", {
45497 /**
45498 * @hidden
45499 * @param {?} label
45500 * @return {?}
45501 */
45502 set: function (label) {
45503 if (!this._label) {
45504 this._label = label;
45505 }
45506 },
45507 enumerable: true,
45508 configurable: true
45509 });
45510 Object.defineProperty(Item.prototype, "_buttons", {
45511 /**
45512 * @hidden
45513 * @param {?} buttons
45514 * @return {?}
45515 */
45516 set: function (buttons) {
45517 buttons.forEach(function (button) {
45518 if (!button._size) {
45519 button.setElementClass('item-button', true);
45520 }
45521 });
45522 },
45523 enumerable: true,
45524 configurable: true
45525 });
45526 Object.defineProperty(Item.prototype, "_icons", {
45527 /**
45528 * @hidden
45529 * @param {?} icons
45530 * @return {?}
45531 */
45532 set: function (icons) {
45533 icons.forEach(function (icon) {
45534 icon.setElementClass('item-icon', true);
45535 });
45536 },
45537 enumerable: true,
45538 configurable: true
45539 });
45540 return Item;
45541}(Ion));
45542Item.decorators = [
45543 { type: Component, args: [{
45544 selector: 'ion-list-header,ion-item,[ion-item],ion-item-divider',
45545 template: '<ng-content select="[item-start],[item-left],ion-checkbox:not([item-end]):not([item-right])"></ng-content>' +
45546 '<div class="item-inner">' +
45547 '<div class="input-wrapper">' +
45548 '<ng-content select="ion-label"></ng-content>' +
45549 '<ion-label *ngIf="_viewLabel">' +
45550 '<ng-content></ng-content>' +
45551 '</ion-label>' +
45552 '<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
45553 '</div>' +
45554 '<ng-content select="[item-end],[item-right],ion-radio,ion-toggle"></ng-content>' +
45555 '<ion-reorder *ngIf="_hasReorder"></ion-reorder>' +
45556 '</div>' +
45557 '<div class="button-effect"></div>',
45558 host: {
45559 'class': 'item'
45560 },
45561 changeDetection: ChangeDetectionStrategy.OnPush,
45562 encapsulation: ViewEncapsulation.None,
45563 },] },
45564];
45565/**
45566 * @nocollapse
45567 */
45568Item.ctorParameters = function () { return [
45569 { type: Form, },
45570 { type: Config, },
45571 { type: ElementRef, },
45572 { type: Renderer, },
45573 { type: ItemReorder, decorators: [{ type: Optional },] },
45574]; };
45575Item.propDecorators = {
45576 'contentLabel': [{ type: ContentChild, args: [Label,] },],
45577 'viewLabel': [{ type: ViewChild, args: [Label,] },],
45578 '_buttons': [{ type: ContentChildren, args: [Button,] },],
45579 '_icons': [{ type: ContentChildren, args: [Icon,] },],
45580};
45581
45582var __extends$34 = (undefined && undefined.__extends) || (function () {
45583 var extendStatics = Object.setPrototypeOf ||
45584 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
45585 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
45586 return function (d, b) {
45587 extendStatics(d, b);
45588 function __() { this.constructor = d; }
45589 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
45590 };
45591})();
45592/**
45593 * \@name Checkbox
45594 * \@module ionic
45595 *
45596 * \@description
45597 * The Checkbox is a simple component styled based on the mode. It can be
45598 * placed in an `ion-item` or used as a stand-alone checkbox.
45599 *
45600 * See the [Angular Docs](https://angular.io/docs/ts/latest/guide/forms.html)
45601 * for more info on forms and inputs.
45602 *
45603 *
45604 * \@usage
45605 * ```html
45606 *
45607 * <ion-list>
45608 *
45609 * <ion-item>
45610 * <ion-label>Pepperoni</ion-label>
45611 * <ion-checkbox [(ngModel)]="pepperoni"></ion-checkbox>
45612 * </ion-item>
45613 *
45614 * <ion-item>
45615 * <ion-label>Sausage</ion-label>
45616 * <ion-checkbox [(ngModel)]="sausage" disabled="true"></ion-checkbox>
45617 * </ion-item>
45618 *
45619 * <ion-item>
45620 * <ion-label>Mushrooms</ion-label>
45621 * <ion-checkbox [(ngModel)]="mushrooms"></ion-checkbox>
45622 * </ion-item>
45623 *
45624 * </ion-list>
45625 * ```
45626 *
45627 * \@advanced
45628 *
45629 * ```html
45630 *
45631 * <!-- Call function when state changes -->
45632 * <ion-list>
45633 *
45634 * <ion-item>
45635 * <ion-label>Cucumber</ion-label>
45636 * <ion-checkbox [(ngModel)]="cucumber" (ionChange)="updateCucumber()"></ion-checkbox>
45637 * </ion-item>
45638 *
45639 * </ion-list>
45640 * ```
45641 *
45642 * ```ts
45643 * \@Component({
45644 * templateUrl: 'main.html'
45645 * })
45646 * class SaladPage {
45647 * cucumber: boolean;
45648 *
45649 * updateCucumber() {
45650 * console.log('Cucumbers new state:' + this.cucumber);
45651 * }
45652 * }
45653 * ```
45654 *
45655 * \@demo /docs/demos/src/checkbox/
45656 * @see {\@link /docs/components#checkbox Checkbox Component Docs}
45657 */
45658var Checkbox = (function (_super) {
45659 __extends$34(Checkbox, _super);
45660 /**
45661 * @param {?} config
45662 * @param {?} form
45663 * @param {?} item
45664 * @param {?} elementRef
45665 * @param {?} renderer
45666 */
45667 function Checkbox(config, form, item, elementRef, renderer) {
45668 return _super.call(this, config, elementRef, renderer, 'checkbox', false, form, item, null) || this;
45669 }
45670 Object.defineProperty(Checkbox.prototype, "checked", {
45671 /**
45672 * \@input {boolean} If true, the element is selected.
45673 * @return {?}
45674 */
45675 get: function () {
45676 return this.value;
45677 },
45678 /**
45679 * @param {?} val
45680 * @return {?}
45681 */
45682 set: function (val) {
45683 this.value = val;
45684 },
45685 enumerable: true,
45686 configurable: true
45687 });
45688 /**
45689 * @hidden
45690 * @param {?} ev
45691 * @return {?}
45692 */
45693 Checkbox.prototype._click = function (ev) {
45694 ev.preventDefault();
45695 ev.stopPropagation();
45696 this.value = !this.value;
45697 this._fireTouched();
45698 };
45699 /**
45700 * @hidden
45701 * @param {?} val
45702 * @return {?}
45703 */
45704 Checkbox.prototype._inputNormalize = function (val) {
45705 return isTrueProperty(val);
45706 };
45707 /**
45708 * @hidden
45709 * @return {?}
45710 */
45711 Checkbox.prototype._inputUpdated = function () {
45712 this._item && this._item.setElementClass('item-checkbox-checked', this._value);
45713 };
45714 return Checkbox;
45715}(BaseInput));
45716Checkbox.decorators = [
45717 { type: Component, args: [{
45718 selector: 'ion-checkbox',
45719 template: '<div class="checkbox-icon" [class.checkbox-checked]="_value">' +
45720 '<div class="checkbox-inner"></div>' +
45721 '</div>' +
45722 '<button role="checkbox" ' +
45723 'type="button" ' +
45724 'ion-button="item-cover" ' +
45725 '[id]="id" ' +
45726 '[attr.aria-checked]="_value" ' +
45727 '[attr.aria-labelledby]="_labelId" ' +
45728 '[attr.aria-disabled]="_disabled" ' +
45729 'class="item-cover"> ' +
45730 '</button>',
45731 host: {
45732 '[class.checkbox-disabled]': '_disabled'
45733 },
45734 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Checkbox, multi: true }],
45735 encapsulation: ViewEncapsulation.None,
45736 },] },
45737];
45738/**
45739 * @nocollapse
45740 */
45741Checkbox.ctorParameters = function () { return [
45742 { type: Config, },
45743 { type: Form, },
45744 { type: Item, decorators: [{ type: Optional },] },
45745 { type: ElementRef, },
45746 { type: Renderer, },
45747]; };
45748Checkbox.propDecorators = {
45749 'checked': [{ type: Input },],
45750 '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
45751};
45752
45753var __extends$43 = (undefined && undefined.__extends) || (function () {
45754 var extendStatics = Object.setPrototypeOf ||
45755 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
45756 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
45757 return function (d, b) {
45758 extendStatics(d, b);
45759 function __() { this.constructor = d; }
45760 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
45761 };
45762})();
45763/**
45764 * \@name Chip
45765 * \@module ionic
45766 * \@description
45767 * Chips represent complex entities in small blocks, such as a contact.
45768 *
45769 *
45770 * \@usage
45771 *
45772 * ```html
45773 * <ion-chip>
45774 * <ion-label>Default</ion-label>
45775 * </ion-chip>
45776 *
45777 * <ion-chip>
45778 * <ion-label color="secondary">Secondary Label</ion-label>
45779 * </ion-chip>
45780 *
45781 * <ion-chip color="secondary">
45782 * <ion-label color="dark">Secondary w/ Dark label</ion-label>
45783 * </ion-chip>
45784 *
45785 * <ion-chip color="danger">
45786 * <ion-label>Danger</ion-label>
45787 * </ion-chip>
45788 *
45789 * <ion-chip>
45790 * <ion-icon name="pin"></ion-icon>
45791 * <ion-label>Default</ion-label>
45792 * </ion-chip>
45793 *
45794 * <ion-chip>
45795 * <ion-icon name="heart" color="dark"></ion-icon>
45796 * <ion-label>Default</ion-label>
45797 * </ion-chip>
45798 *
45799 * <ion-chip>
45800 * <ion-avatar>
45801 * <img src="assets/img/my-img.png">
45802 * </ion-avatar>
45803 * <ion-label>Default</ion-label>
45804 * </ion-chip>
45805 * ```
45806 *
45807 *
45808 * \@advanced
45809 *
45810 * ```html
45811 * <ion-chip #chip1>
45812 * <ion-label>Default</ion-label>
45813 * <button ion-button clear color="light" (click)="delete(chip1)">
45814 * <ion-icon name="close-circle"></ion-icon>
45815 * </button>
45816 * </ion-chip>
45817 *
45818 * <ion-chip #chip2>
45819 * <ion-icon name="pin" color="primary"></ion-icon>
45820 * <ion-label>With Icon</ion-label>
45821 * <button ion-button (click)="delete(chip2)">
45822 * <ion-icon name="close"></ion-icon>
45823 * </button>
45824 * </ion-chip>
45825 *
45826 * <ion-chip #chip3>
45827 * <ion-avatar>
45828 * <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==">
45829 * </ion-avatar>
45830 * <ion-label>With Avatar</ion-label>
45831 * <button ion-button clear color="dark" (click)="delete(chip3)">
45832 * <ion-icon name="close-circle"></ion-icon>
45833 * </button>
45834 * </ion-chip>
45835 * ```
45836 *
45837 * ```ts
45838 * \@Component({
45839 * templateUrl: 'main.html'
45840 * })
45841 * class E2EPage {
45842 * delete(chip: Element) {
45843 * chip.remove();
45844 * }
45845 * }
45846 * ```
45847 *
45848 * \@demo /docs/demos/src/chip/
45849 *
45850 */
45851var Chip = (function (_super) {
45852 __extends$43(Chip, _super);
45853 /**
45854 * @param {?} config
45855 * @param {?} elementRef
45856 * @param {?} renderer
45857 */
45858 function Chip(config, elementRef, renderer) {
45859 return _super.call(this, config, elementRef, renderer, 'chip') || this;
45860 }
45861 return Chip;
45862}(Ion));
45863Chip.decorators = [
45864 { type: Directive, args: [{
45865 selector: 'ion-chip'
45866 },] },
45867];
45868/**
45869 * @nocollapse
45870 */
45871Chip.ctorParameters = function () { return [
45872 { type: Config, },
45873 { type: ElementRef, },
45874 { type: Renderer, },
45875]; };
45876
45877/**
45878 * \@name Haptic
45879 * \@description
45880 * The `Haptic` class interacts with a haptic engine on the device, if
45881 * available. Generally, Ionic components use this under the hood, but you're
45882 * welcome to get a bit crazy with it if you fancy.
45883 *
45884 * Currently, this uses the Taptic engine on iOS.
45885 *
45886 * \@usage
45887 * ```ts
45888 * export class MyClass {
45889 *
45890 * constructor(haptic: Haptic) {
45891 * haptic.selection();
45892 * }
45893 * }
45894 *
45895 * ```
45896 */
45897var Haptic = (function () {
45898 /**
45899 * @param {?} plt
45900 */
45901 function Haptic(plt) {
45902 var _this = this;
45903 if (plt) {
45904 plt.ready().then(function () {
45905 _this._p = plt.win().TapticEngine;
45906 });
45907 }
45908 }
45909 /**
45910 * Check to see if the Haptic Plugin is available
45911 *
45912 * @return {?}
45913 */
45914 Haptic.prototype.available = function () {
45915 return !!this._p;
45916 };
45917 /**
45918 * Trigger a selection changed haptic event. Good for one-time events
45919 * (not for gestures)
45920 * @return {?}
45921 */
45922 Haptic.prototype.selection = function () {
45923 this._p && this._p.selection();
45924 };
45925 /**
45926 * Tell the haptic engine that a gesture for a selection change is starting.
45927 * @return {?}
45928 */
45929 Haptic.prototype.gestureSelectionStart = function () {
45930 this._p && this._p.gestureSelectionStart();
45931 };
45932 /**
45933 * Tell the haptic engine that a selection changed during a gesture.
45934 * @return {?}
45935 */
45936 Haptic.prototype.gestureSelectionChanged = function () {
45937 this._p && this._p.gestureSelectionChanged();
45938 };
45939 /**
45940 * Tell the haptic engine we are done with a gesture. This needs to be
45941 * called lest resources are not properly recycled.
45942 * @return {?}
45943 */
45944 Haptic.prototype.gestureSelectionEnd = function () {
45945 this._p && this._p.gestureSelectionEnd();
45946 };
45947 /**
45948 * Use this to indicate success/failure/warning to the user.
45949 * options should be of the type `{ type: 'success' }` (or `warning`/`error`)
45950 * @param {?} options
45951 * @return {?}
45952 */
45953 Haptic.prototype.notification = function (options) {
45954 this._p && this._p.notification(options);
45955 };
45956 /**
45957 * Use this to indicate success/failure/warning to the user.
45958 * options should be of the type `{ style: 'light' }` (or `medium`/`heavy`)
45959 * @param {?} options
45960 * @return {?}
45961 */
45962 Haptic.prototype.impact = function (options) {
45963 this._p && this._p.impact(options);
45964 };
45965 return Haptic;
45966}());
45967Haptic.decorators = [
45968 { type: Injectable },
45969];
45970/**
45971 * @nocollapse
45972 */
45973Haptic.ctorParameters = function () { return [
45974 { type: Platform, },
45975]; };
45976
45977var PICKER_OPT_SELECTED = 'picker-opt-selected';
45978var DECELERATION_FRICTION$1 = 0.97;
45979var FRAME_MS$1 = (1000 / 60);
45980var MAX_PICKER_SPEED = 60;
45981
45982/**
45983 * @hidden
45984 */
45985var PickerColumnCmp = (function () {
45986 /**
45987 * @param {?} config
45988 * @param {?} _plt
45989 * @param {?} elementRef
45990 * @param {?} _zone
45991 * @param {?} _haptic
45992 * @param {?} plt
45993 * @param {?} domCtrl
45994 */
45995 function PickerColumnCmp(config, _plt, elementRef, _zone, _haptic, plt, domCtrl) {
45996 this._plt = _plt;
45997 this.elementRef = elementRef;
45998 this._zone = _zone;
45999 this._haptic = _haptic;
46000 this.y = 0;
46001 this.pos = [];
46002 this.startY = null;
46003 this.ionChange = new EventEmitter();
46004 this.events = new UIEventManager(plt);
46005 this.rotateFactor = config.getNumber('pickerRotateFactor', 0);
46006 this.scaleFactor = config.getNumber('pickerScaleFactor', 1);
46007 this.decelerateFunc = this.decelerate.bind(this);
46008 this.debouncer = domCtrl.debouncer();
46009 }
46010 /**
46011 * @return {?}
46012 */
46013 PickerColumnCmp.prototype.ngAfterViewInit = function () {
46014 // get the scrollable element within the column
46015 var /** @type {?} */ colEle = this.colEle.nativeElement;
46016 this.colHeight = colEle.clientHeight;
46017 // get the height of one option
46018 this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
46019 // Listening for pointer events
46020 this.events.pointerEvents({
46021 element: this.elementRef.nativeElement,
46022 pointerDown: this.pointerStart.bind(this),
46023 pointerMove: this.pointerMove.bind(this),
46024 pointerUp: this.pointerEnd.bind(this),
46025 capture: true,
46026 zone: false
46027 });
46028 };
46029 /**
46030 * @return {?}
46031 */
46032 PickerColumnCmp.prototype.ngOnDestroy = function () {
46033 this._plt.cancelRaf(this.rafId);
46034 this.events.destroy();
46035 };
46036 /**
46037 * @param {?} ev
46038 * @return {?}
46039 */
46040 PickerColumnCmp.prototype.pointerStart = function (ev) {
46041 (void 0) /* console.debug */;
46042 this._haptic.gestureSelectionStart();
46043 // We have to prevent default in order to block scrolling under the picker
46044 // but we DO NOT have to stop propagation, since we still want
46045 // some "click" events to capture
46046 ev.preventDefault();
46047 // cancel any previous raf's that haven't fired yet
46048 this._plt.cancelRaf(this.rafId);
46049 // remember where the pointer started from`
46050 this.startY = pointerCoord(ev).y;
46051 // reset everything
46052 this.velocity = 0;
46053 this.pos.length = 0;
46054 this.pos.push(this.startY, Date.now());
46055 var /** @type {?} */ options = this.col.options;
46056 var /** @type {?} */ minY = (options.length - 1);
46057 var /** @type {?} */ maxY = 0;
46058 for (var /** @type {?} */ i = 0; i < options.length; i++) {
46059 if (!options[i].disabled) {
46060 minY = Math.min(minY, i);
46061 maxY = Math.max(maxY, i);
46062 }
46063 }
46064 this.minY = (minY * this.optHeight * -1);
46065 this.maxY = (maxY * this.optHeight * -1);
46066 return true;
46067 };
46068 /**
46069 * @param {?} ev
46070 * @return {?}
46071 */
46072 PickerColumnCmp.prototype.pointerMove = function (ev) {
46073 var _this = this;
46074 ev.preventDefault();
46075 ev.stopPropagation();
46076 var /** @type {?} */ currentY = pointerCoord(ev).y;
46077 this.pos.push(currentY, Date.now());
46078 this.debouncer.write(function () {
46079 if (_this.startY === null) {
46080 return;
46081 }
46082 // update the scroll position relative to pointer start position
46083 var /** @type {?} */ y = _this.y + (currentY - _this.startY);
46084 if (y > _this.minY) {
46085 // scrolling up higher than scroll area
46086 y = Math.pow(y, 0.8);
46087 _this.bounceFrom = y;
46088 }
46089 else if (y < _this.maxY) {
46090 // scrolling down below scroll area
46091 y += Math.pow(_this.maxY - y, 0.9);
46092 _this.bounceFrom = y;
46093 }
46094 else {
46095 _this.bounceFrom = 0;
46096 }
46097 _this.update(y, 0, false, false);
46098 var /** @type {?} */ currentIndex = Math.max(Math.abs(Math.round(y / _this.optHeight)), 0);
46099 if (currentIndex !== _this.lastTempIndex) {
46100 // Trigger a haptic event for physical feedback that the index has changed
46101 _this._haptic.gestureSelectionChanged();
46102 _this.lastTempIndex = currentIndex;
46103 }
46104 });
46105 };
46106 /**
46107 * @param {?} ev
46108 * @return {?}
46109 */
46110 PickerColumnCmp.prototype.pointerEnd = function (ev) {
46111 ev.preventDefault();
46112 this.debouncer.cancel();
46113 if (this.startY === null) {
46114 return;
46115 }
46116 (void 0) /* console.debug */;
46117 this.velocity = 0;
46118 if (this.bounceFrom > 0) {
46119 // bounce back up
46120 this.update(this.minY, 100, true, true);
46121 return;
46122 }
46123 else if (this.bounceFrom < 0) {
46124 // bounce back down
46125 this.update(this.maxY, 100, true, true);
46126 return;
46127 }
46128 var /** @type {?} */ endY = pointerCoord(ev).y;
46129 this.pos.push(endY, Date.now());
46130 var /** @type {?} */ endPos = (this.pos.length - 1);
46131 var /** @type {?} */ startPos = endPos;
46132 var /** @type {?} */ timeRange = (Date.now() - 100);
46133 // move pointer to position measured 100ms ago
46134 for (var /** @type {?} */ i = endPos; i > 0 && this.pos[i] > timeRange; i -= 2) {
46135 startPos = i;
46136 }
46137 if (startPos !== endPos) {
46138 // compute relative movement between these two points
46139 var /** @type {?} */ timeOffset = (this.pos[endPos] - this.pos[startPos]);
46140 var /** @type {?} */ movedTop = (this.pos[startPos - 1] - this.pos[endPos - 1]);
46141 // based on XXms compute the movement to apply for each render step
46142 var /** @type {?} */ velocity = ((movedTop / timeOffset) * FRAME_MS$1);
46143 this.velocity = clamp(-MAX_PICKER_SPEED, velocity, MAX_PICKER_SPEED);
46144 }
46145 if (Math.abs(endY - this.startY) > 3) {
46146 var /** @type {?} */ y = this.y + (endY - this.startY);
46147 this.update(y, 0, true, true);
46148 }
46149 this.startY = null;
46150 this.decelerate();
46151 };
46152 /**
46153 * @return {?}
46154 */
46155 PickerColumnCmp.prototype.decelerate = function () {
46156 var /** @type {?} */ y = 0;
46157 if (isNaN(this.y) || !this.optHeight) {
46158 // fallback in case numbers get outta wack
46159 this.update(y, 0, true, true);
46160 this._haptic.gestureSelectionEnd();
46161 }
46162 else if (Math.abs(this.velocity) > 0) {
46163 // still decelerating
46164 this.velocity *= DECELERATION_FRICTION$1;
46165 // do not let it go slower than a velocity of 1
46166 this.velocity = (this.velocity > 0)
46167 ? Math.max(this.velocity, 1)
46168 : Math.min(this.velocity, -1);
46169 y = Math.round(this.y - this.velocity);
46170 if (y > this.minY) {
46171 // whoops, it's trying to scroll up farther than the options we have!
46172 y = this.minY;
46173 this.velocity = 0;
46174 }
46175 else if (y < this.maxY) {
46176 // gahh, it's trying to scroll down farther than we can!
46177 y = this.maxY;
46178 this.velocity = 0;
46179 }
46180 var /** @type {?} */ notLockedIn = (y % this.optHeight !== 0 || Math.abs(this.velocity) > 1);
46181 this.update(y, 0, true, !notLockedIn);
46182 if (notLockedIn) {
46183 // isn't locked in yet, keep decelerating until it is
46184 this.rafId = this._plt.raf(this.decelerateFunc);
46185 }
46186 }
46187 else if (this.y % this.optHeight !== 0) {
46188 // needs to still get locked into a position so options line up
46189 var /** @type {?} */ currentPos = Math.abs(this.y % this.optHeight);
46190 // create a velocity in the direction it needs to scroll
46191 this.velocity = (currentPos > (this.optHeight / 2) ? 1 : -1);
46192 this._haptic.gestureSelectionEnd();
46193 this.decelerate();
46194 }
46195 var /** @type {?} */ currentIndex = Math.max(Math.abs(Math.round(y / this.optHeight)), 0);
46196 if (currentIndex !== this.lastTempIndex) {
46197 // Trigger a haptic event for physical feedback that the index has changed
46198 this._haptic.gestureSelectionChanged();
46199 }
46200 this.lastTempIndex = currentIndex;
46201 };
46202 /**
46203 * @param {?} ev
46204 * @param {?} index
46205 * @return {?}
46206 */
46207 PickerColumnCmp.prototype.optClick = function (ev, index) {
46208 if (!this.velocity) {
46209 ev.preventDefault();
46210 ev.stopPropagation();
46211 this.setSelected(index, 150);
46212 }
46213 };
46214 /**
46215 * @param {?} selectedIndex
46216 * @param {?} duration
46217 * @return {?}
46218 */
46219 PickerColumnCmp.prototype.setSelected = function (selectedIndex, duration) {
46220 // if there is a selected index, then figure out it's y position
46221 // if there isn't a selected index, then just use the top y position
46222 var /** @type {?} */ y = (selectedIndex > -1) ? ((selectedIndex * this.optHeight) * -1) : 0;
46223 this._plt.cancelRaf(this.rafId);
46224 this.velocity = 0;
46225 // so what y position we're at
46226 this.update(y, duration, true, true);
46227 };
46228 /**
46229 * @param {?} y
46230 * @param {?} duration
46231 * @param {?} saveY
46232 * @param {?} emitChange
46233 * @return {?}
46234 */
46235 PickerColumnCmp.prototype.update = function (y, duration, saveY, emitChange) {
46236 // ensure we've got a good round number :)
46237 y = Math.round(y);
46238 var /** @type {?} */ i;
46239 var /** @type {?} */ button;
46240 var /** @type {?} */ opt;
46241 var /** @type {?} */ optOffset;
46242 var /** @type {?} */ visible;
46243 var /** @type {?} */ translateX;
46244 var /** @type {?} */ translateY;
46245 var /** @type {?} */ translateZ;
46246 var /** @type {?} */ rotateX;
46247 var /** @type {?} */ transform;
46248 var /** @type {?} */ selected;
46249 var /** @type {?} */ parent = this.colEle.nativeElement;
46250 var /** @type {?} */ children = parent.children;
46251 var /** @type {?} */ length = children.length;
46252 var /** @type {?} */ selectedIndex = this.col.selectedIndex = Math.min(Math.max(Math.round(-y / this.optHeight), 0), length - 1);
46253 var /** @type {?} */ durationStr = (duration === 0) ? null : duration + 'ms';
46254 var /** @type {?} */ scaleStr = "scale(" + this.scaleFactor + ")";
46255 for (i = 0; i < length; i++) {
46256 button = children[i];
46257 opt = (this.col.options[i]);
46258 optOffset = (i * this.optHeight) + y;
46259 visible = true;
46260 transform = '';
46261 if (this.rotateFactor !== 0) {
46262 rotateX = optOffset * this.rotateFactor;
46263 if (Math.abs(rotateX) > 90) {
46264 visible = false;
46265 }
46266 else {
46267 translateX = 0;
46268 translateY = 0;
46269 translateZ = 90;
46270 transform = "rotateX(" + rotateX + "deg) ";
46271 }
46272 }
46273 else {
46274 translateX = 0;
46275 translateZ = 0;
46276 translateY = optOffset;
46277 if (Math.abs(translateY) > 170) {
46278 visible = false;
46279 }
46280 }
46281 selected = selectedIndex === i;
46282 if (visible) {
46283 transform += "translate3d(0px," + translateY + "px," + translateZ + "px) ";
46284 if (this.scaleFactor !== 1 && !selected) {
46285 transform += scaleStr;
46286 }
46287 }
46288 else {
46289 transform = 'translate3d(-9999px,0px,0px)';
46290 }
46291 // Update transition duration
46292 if (duration !== opt._dur) {
46293 opt._dur = duration;
46294 button.style[this._plt.Css.transitionDuration] = durationStr;
46295 }
46296 // Update transform
46297 if (transform !== opt._trans) {
46298 opt._trans = transform;
46299 button.style[this._plt.Css.transform] = transform;
46300 }
46301 // Update selected item
46302 if (selected !== opt._selected) {
46303 opt._selected = selected;
46304 if (selected) {
46305 button.classList.add(PICKER_OPT_SELECTED);
46306 }
46307 else {
46308 button.classList.remove(PICKER_OPT_SELECTED);
46309 }
46310 }
46311 }
46312 this.col.prevSelected = selectedIndex;
46313 if (saveY) {
46314 this.y = y;
46315 }
46316 if (emitChange) {
46317 if (this.lastIndex === undefined) {
46318 // have not set a last index yet
46319 this.lastIndex = this.col.selectedIndex;
46320 }
46321 else if (this.lastIndex !== this.col.selectedIndex) {
46322 // new selected index has changed from the last index
46323 // update the lastIndex and emit that it has changed
46324 this.lastIndex = this.col.selectedIndex;
46325 var /** @type {?} */ ionChange = this.ionChange;
46326 if (ionChange.observers.length > 0) {
46327 this._zone.run(ionChange.emit.bind(ionChange, this.col.options[this.col.selectedIndex]));
46328 }
46329 }
46330 }
46331 };
46332 /**
46333 * @return {?}
46334 */
46335 PickerColumnCmp.prototype.refresh = function () {
46336 var /** @type {?} */ min = this.col.options.length - 1;
46337 var /** @type {?} */ max = 0;
46338 var /** @type {?} */ options = this.col.options;
46339 for (var /** @type {?} */ i = 0; i < options.length; i++) {
46340 if (!options[i].disabled) {
46341 min = Math.min(min, i);
46342 max = Math.max(max, i);
46343 }
46344 }
46345 var /** @type {?} */ selectedIndex = clamp(min, this.col.selectedIndex, max);
46346 if (this.col.prevSelected !== selectedIndex) {
46347 var /** @type {?} */ y = (selectedIndex * this.optHeight) * -1;
46348 this._plt.cancelRaf(this.rafId);
46349 this.velocity = 0;
46350 this.update(y, 150, true, false);
46351 }
46352 };
46353 return PickerColumnCmp;
46354}());
46355PickerColumnCmp.decorators = [
46356 { type: Component, args: [{
46357 selector: '.picker-col',
46358 template: '<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>' +
46359 '<div class="picker-opts" #colEle [style.max-width]="col.optionsWidth">' +
46360 '<button *ngFor="let o of col.options; let i=index"' +
46361 '[class.picker-opt-disabled]="o.disabled" ' +
46362 'class="picker-opt" disable-activated (click)="optClick($event, i)">' +
46363 '{{o.text}}' +
46364 '</button>' +
46365 '</div>' +
46366 '<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>',
46367 host: {
46368 '[style.max-width]': 'col.columnWidth',
46369 '[class.picker-opts-left]': 'col.align=="left"',
46370 '[class.picker-opts-right]': 'col.align=="right"',
46371 }
46372 },] },
46373];
46374/**
46375 * @nocollapse
46376 */
46377PickerColumnCmp.ctorParameters = function () { return [
46378 { type: Config, },
46379 { type: Platform, },
46380 { type: ElementRef, },
46381 { type: NgZone, },
46382 { type: Haptic, },
46383 { type: Platform, },
46384 { type: DomController, },
46385]; };
46386PickerColumnCmp.propDecorators = {
46387 'colEle': [{ type: ViewChild, args: ['colEle',] },],
46388 'col': [{ type: Input },],
46389 'ionChange': [{ type: Output },],
46390};
46391
46392/**
46393 * @hidden
46394 */
46395var PickerCmp = (function () {
46396 /**
46397 * @param {?} _viewCtrl
46398 * @param {?} _elementRef
46399 * @param {?} config
46400 * @param {?} gestureCtrl
46401 * @param {?} params
46402 * @param {?} renderer
46403 */
46404 function PickerCmp(_viewCtrl, _elementRef, config, gestureCtrl, params, renderer) {
46405 this._viewCtrl = _viewCtrl;
46406 this._elementRef = _elementRef;
46407 this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
46408 this.d = params.data;
46409 this.mode = config.get('mode');
46410 renderer.setElementClass(_elementRef.nativeElement, "picker-" + this.mode, true);
46411 if (this.d.cssClass) {
46412 this.d.cssClass.split(' ').forEach(function (cssClass) {
46413 renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
46414 });
46415 }
46416 this.id = (++pickerIds);
46417 this.lastClick = 0;
46418 }
46419 /**
46420 * @return {?}
46421 */
46422 PickerCmp.prototype.ionViewWillLoad = function () {
46423 // normalize the data
46424 var /** @type {?} */ data = this.d;
46425 data.buttons = data.buttons.map(function (button) {
46426 if (isString(button)) {
46427 return { text: button };
46428 }
46429 if (button.role) {
46430 button.cssRole = "picker-toolbar-" + button.role;
46431 }
46432 return button;
46433 });
46434 // clean up dat data
46435 data.columns = data.columns.map(function (column) {
46436 if (!isPresent(column.options)) {
46437 column.options = [];
46438 }
46439 column.selectedIndex = column.selectedIndex || 0;
46440 column.options = column.options.map(function (inputOpt) {
46441 var /** @type {?} */ opt = {
46442 text: '',
46443 value: '',
46444 disabled: inputOpt.disabled,
46445 };
46446 if (isPresent(inputOpt)) {
46447 if (isString(inputOpt) || isNumber(inputOpt)) {
46448 opt.text = inputOpt.toString();
46449 opt.value = inputOpt;
46450 }
46451 else {
46452 opt.text = isPresent(inputOpt.text) ? inputOpt.text : inputOpt.value;
46453 opt.value = isPresent(inputOpt.value) ? inputOpt.value : inputOpt.text;
46454 }
46455 }
46456 return opt;
46457 });
46458 return column;
46459 });
46460 };
46461 /**
46462 * @return {?}
46463 */
46464 PickerCmp.prototype.ionViewDidLoad = function () {
46465 this.refresh();
46466 };
46467 /**
46468 * @return {?}
46469 */
46470 PickerCmp.prototype.ionViewWillEnter = function () {
46471 this._gestureBlocker.block();
46472 };
46473 /**
46474 * @return {?}
46475 */
46476 PickerCmp.prototype.ionViewDidLeave = function () {
46477 this._gestureBlocker.unblock();
46478 };
46479 /**
46480 * @return {?}
46481 */
46482 PickerCmp.prototype.refresh = function () {
46483 this._cols.forEach(function (column) { return column.refresh(); });
46484 };
46485 /**
46486 * @return {?}
46487 */
46488 PickerCmp.prototype._colChange = function () {
46489 // one of the columns has changed its selected index
46490 var /** @type {?} */ picker = (this._viewCtrl);
46491 picker.ionChange.emit(this.getSelected());
46492 };
46493 /**
46494 * @param {?} ev
46495 * @return {?}
46496 */
46497 PickerCmp.prototype._keyUp = function (ev) {
46498 if (this.enabled && this._viewCtrl.isLast()) {
46499 if (ev.keyCode === KEY_ENTER) {
46500 if (this.lastClick + 1000 < Date.now()) {
46501 // do not fire this click if there recently was already a click
46502 // this can happen when the button has focus and used the enter
46503 // key to click the button. However, both the click handler and
46504 // this keyup event will fire, so only allow one of them to go.
46505 (void 0) /* console.debug */;
46506 var /** @type {?} */ button = this.d.buttons[this.d.buttons.length - 1];
46507 this.btnClick(button);
46508 }
46509 }
46510 else if (ev.keyCode === KEY_ESCAPE) {
46511 (void 0) /* console.debug */;
46512 this.bdClick();
46513 }
46514 }
46515 };
46516 /**
46517 * @return {?}
46518 */
46519 PickerCmp.prototype.ionViewDidEnter = function () {
46520 var /** @type {?} */ focusableEle = this._elementRef.nativeElement.querySelector('button');
46521 if (focusableEle) {
46522 focusableEle.focus();
46523 }
46524 this.enabled = true;
46525 };
46526 /**
46527 * @param {?} button
46528 * @return {?}
46529 */
46530 PickerCmp.prototype.btnClick = function (button) {
46531 if (!this.enabled) {
46532 return;
46533 }
46534 // keep the time of the most recent button click
46535 this.lastClick = Date.now();
46536 var /** @type {?} */ shouldDismiss = true;
46537 if (button.handler) {
46538 // a handler has been provided, execute it
46539 // pass the handler the values from the inputs
46540 if (button.handler(this.getSelected()) === false) {
46541 // if the return value of the handler is false then do not dismiss
46542 shouldDismiss = false;
46543 }
46544 }
46545 if (shouldDismiss) {
46546 this.dismiss(button.role);
46547 }
46548 };
46549 /**
46550 * @return {?}
46551 */
46552 PickerCmp.prototype.bdClick = function () {
46553 if (this.enabled && this.d.enableBackdropDismiss) {
46554 var /** @type {?} */ cancelBtn = this.d.buttons.find(function (b) { return b.role === 'cancel'; });
46555 if (cancelBtn) {
46556 this.btnClick(cancelBtn);
46557 }
46558 else {
46559 this.dismiss('backdrop');
46560 }
46561 }
46562 };
46563 /**
46564 * @param {?} role
46565 * @return {?}
46566 */
46567 PickerCmp.prototype.dismiss = function (role) {
46568 return this._viewCtrl.dismiss(this.getSelected(), role);
46569 };
46570 /**
46571 * @return {?}
46572 */
46573 PickerCmp.prototype.getSelected = function () {
46574 var /** @type {?} */ selected = {};
46575 this.d.columns.forEach(function (col, index) {
46576 var /** @type {?} */ selectedColumn = col.options[col.selectedIndex];
46577 selected[col.name] = {
46578 text: selectedColumn ? selectedColumn.text : null,
46579 value: selectedColumn ? selectedColumn.value : null,
46580 columnIndex: index,
46581 };
46582 });
46583 return selected;
46584 };
46585 /**
46586 * @return {?}
46587 */
46588 PickerCmp.prototype.ngOnDestroy = function () {
46589 (void 0) /* assert */;
46590 this._gestureBlocker.destroy();
46591 };
46592 return PickerCmp;
46593}());
46594PickerCmp.decorators = [
46595 { type: Component, args: [{
46596 selector: 'ion-picker-cmp',
46597 template: "\n <ion-backdrop (click)=\"bdClick()\"></ion-backdrop>\n <div class=\"picker-wrapper\">\n <div class=\"picker-toolbar\">\n <div *ngFor=\"let b of d.buttons\" class=\"picker-toolbar-button\" [ngClass]=\"b.cssRole\">\n <button ion-button (click)=\"btnClick(b)\" [ngClass]=\"b.cssClass\" class=\"picker-button\" clear>\n {{b.text}}\n </button>\n </div>\n </div>\n <div class=\"picker-columns\">\n <div class=\"picker-above-highlight\"></div>\n <div *ngFor=\"let c of d.columns\" [col]=\"c\" class=\"picker-col\" (ionChange)=\"_colChange($event)\"></div>\n <div class=\"picker-below-highlight\"></div>\n </div>\n </div>\n ",
46598 host: {
46599 'role': 'dialog'
46600 },
46601 encapsulation: ViewEncapsulation.None,
46602 },] },
46603];
46604/**
46605 * @nocollapse
46606 */
46607PickerCmp.ctorParameters = function () { return [
46608 { type: ViewController, },
46609 { type: ElementRef, },
46610 { type: Config, },
46611 { type: GestureController, },
46612 { type: NavParams, },
46613 { type: Renderer, },
46614]; };
46615PickerCmp.propDecorators = {
46616 '_cols': [{ type: ViewChildren, args: [PickerColumnCmp,] },],
46617 '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
46618};
46619var pickerIds = -1;
46620
46621var __extends$46 = (undefined && undefined.__extends) || (function () {
46622 var extendStatics = Object.setPrototypeOf ||
46623 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
46624 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
46625 return function (d, b) {
46626 extendStatics(d, b);
46627 function __() { this.constructor = d; }
46628 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
46629 };
46630})();
46631/**
46632 * Animations for pickers
46633 */
46634var PickerSlideIn = (function (_super) {
46635 __extends$46(PickerSlideIn, _super);
46636 function PickerSlideIn() {
46637 return _super !== null && _super.apply(this, arguments) || this;
46638 }
46639 /**
46640 * @return {?}
46641 */
46642 PickerSlideIn.prototype.init = function () {
46643 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
46644 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
46645 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.picker-wrapper'));
46646 backdrop.fromTo('opacity', 0.01, 0.26);
46647 wrapper.fromTo('translateY', '100%', '0%');
46648 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
46649 };
46650 return PickerSlideIn;
46651}(Transition));
46652var PickerSlideOut = (function (_super) {
46653 __extends$46(PickerSlideOut, _super);
46654 function PickerSlideOut() {
46655 return _super !== null && _super.apply(this, arguments) || this;
46656 }
46657 /**
46658 * @return {?}
46659 */
46660 PickerSlideOut.prototype.init = function () {
46661 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
46662 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
46663 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.picker-wrapper'));
46664 backdrop.fromTo('opacity', 0.26, 0);
46665 wrapper.fromTo('translateY', '0%', '100%');
46666 this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
46667 };
46668 return PickerSlideOut;
46669}(Transition));
46670
46671var __extends$45 = (undefined && undefined.__extends) || (function () {
46672 var extendStatics = Object.setPrototypeOf ||
46673 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
46674 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
46675 return function (d, b) {
46676 extendStatics(d, b);
46677 function __() { this.constructor = d; }
46678 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
46679 };
46680})();
46681/**
46682 * @hidden
46683 */
46684var Picker = (function (_super) {
46685 __extends$45(Picker, _super);
46686 /**
46687 * @param {?} app
46688 * @param {?=} opts
46689 * @param {?=} config
46690 */
46691 function Picker(app, opts, config) {
46692 if (opts === void 0) { opts = {}; }
46693 var _this = this;
46694 if (!opts) {
46695 opts = {};
46696 }
46697 opts.columns = opts.columns || [];
46698 opts.buttons = opts.buttons || [];
46699 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? Boolean(opts.enableBackdropDismiss) : true;
46700 _this = _super.call(this, PickerCmp, opts, null) || this;
46701 _this._app = app;
46702 _this.isOverlay = true;
46703 _this.ionChange = new EventEmitter();
46704 config.setTransition('picker-slide-in', PickerSlideIn);
46705 config.setTransition('picker-slide-out', PickerSlideOut);
46706 return _this;
46707 }
46708 /**
46709 * @hidden
46710 * @param {?} direction
46711 * @return {?}
46712 */
46713 Picker.prototype.getTransitionName = function (direction) {
46714 var /** @type {?} */ key = (direction === 'back' ? 'pickerLeave' : 'pickerEnter');
46715 return this._nav && this._nav.config.get(key);
46716 };
46717 /**
46718 * @param {?} button
46719 * @return {?}
46720 */
46721 Picker.prototype.addButton = function (button) {
46722 this.data.buttons.push(button);
46723 };
46724 /**
46725 * @param {?} column
46726 * @return {?}
46727 */
46728 Picker.prototype.addColumn = function (column) {
46729 this.data.columns.push(column);
46730 };
46731 /**
46732 * @return {?}
46733 */
46734 Picker.prototype.getColumns = function () {
46735 return this.data.columns;
46736 };
46737 /**
46738 * @param {?} name
46739 * @return {?}
46740 */
46741 Picker.prototype.getColumn = function (name) {
46742 return this.getColumns().find(function (column) { return column.name === name; });
46743 };
46744 /**
46745 * @return {?}
46746 */
46747 Picker.prototype.refresh = function () {
46748 (void 0) /* assert */;
46749 (void 0) /* assert */;
46750 this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
46751 };
46752 /**
46753 * @param {?} cssClass
46754 * @return {?}
46755 */
46756 Picker.prototype.setCssClass = function (cssClass) {
46757 this.data.cssClass = cssClass;
46758 };
46759 /**
46760 * Present the picker instance.
46761 *
46762 * @param {?=} navOptions
46763 * @return {?}
46764 */
46765 Picker.prototype.present = function (navOptions) {
46766 if (navOptions === void 0) { navOptions = {}; }
46767 return this._app.present(this, navOptions);
46768 };
46769 return Picker;
46770}(ViewController));
46771Picker.propDecorators = {
46772 'ionChange': [{ type: Output },],
46773};
46774
46775/**
46776 * @hidden
46777 * \@name PickerController
46778 * \@description
46779 *
46780 */
46781var PickerController = (function () {
46782 /**
46783 * @param {?} _app
46784 * @param {?} config
46785 */
46786 function PickerController(_app, config) {
46787 this._app = _app;
46788 this.config = config;
46789 }
46790 /**
46791 * Open a picker.
46792 * @param {?=} opts
46793 * @return {?}
46794 */
46795 PickerController.prototype.create = function (opts) {
46796 if (opts === void 0) { opts = {}; }
46797 return new Picker(this._app, opts, this.config);
46798 };
46799 return PickerController;
46800}());
46801PickerController.decorators = [
46802 { type: Injectable },
46803];
46804/**
46805 * @nocollapse
46806 */
46807PickerController.ctorParameters = function () { return [
46808 { type: App, },
46809 { type: Config, },
46810]; };
46811
46812/**
46813 * @param {?} template
46814 * @param {?} value
46815 * @param {?} locale
46816 * @return {?}
46817 */
46818function renderDateTime(template, value, locale) {
46819 if (isBlank$1(value)) {
46820 return '';
46821 }
46822 var /** @type {?} */ tokens = [];
46823 var /** @type {?} */ hasText = false;
46824 FORMAT_KEYS.forEach(function (format, index) {
46825 if (template.indexOf(format.f) > -1) {
46826 var /** @type {?} */ token = '{' + index + '}';
46827 var /** @type {?} */ text = renderTextFormat(format.f, ((value))[format.k], value, locale);
46828 if (!hasText && text && isPresent(((value))[format.k])) {
46829 hasText = true;
46830 }
46831 tokens.push(token, text);
46832 template = template.replace(format.f, token);
46833 }
46834 });
46835 if (!hasText) {
46836 return '';
46837 }
46838 for (var /** @type {?} */ i = 0; i < tokens.length; i += 2) {
46839 template = template.replace(tokens[i], tokens[i + 1]);
46840 }
46841 return template;
46842}
46843/**
46844 * @param {?} format
46845 * @param {?} value
46846 * @param {?} date
46847 * @param {?} locale
46848 * @return {?}
46849 */
46850function renderTextFormat(format, value, date, locale) {
46851 if (format === FORMAT_DDDD || format === FORMAT_DDD) {
46852 try {
46853 value = (new Date(date.year, date.month - 1, date.day)).getDay();
46854 if (format === FORMAT_DDDD) {
46855 return (isPresent(locale.dayNames) ? locale.dayNames : DAY_NAMES)[value];
46856 }
46857 return (isPresent(locale.dayShortNames) ? locale.dayShortNames : DAY_SHORT_NAMES)[value];
46858 }
46859 catch (e) { }
46860 return '';
46861 }
46862 if (format === FORMAT_A) {
46863 return date ? date.hour < 12 ? 'AM' : 'PM' : isPresent(value) ? value.toUpperCase() : '';
46864 }
46865 if (format === FORMAT_a) {
46866 return date ? date.hour < 12 ? 'am' : 'pm' : isPresent(value) ? value : '';
46867 }
46868 if (isBlank$1(value)) {
46869 return '';
46870 }
46871 if (format === FORMAT_YY || format === FORMAT_MM ||
46872 format === FORMAT_DD || format === FORMAT_HH ||
46873 format === FORMAT_mm || format === FORMAT_ss) {
46874 return twoDigit(value);
46875 }
46876 if (format === FORMAT_YYYY) {
46877 return fourDigit(value);
46878 }
46879 if (format === FORMAT_MMMM) {
46880 return (isPresent(locale.monthNames) ? locale.monthNames : MONTH_NAMES)[value - 1];
46881 }
46882 if (format === FORMAT_MMM) {
46883 return (isPresent(locale.monthShortNames) ? locale.monthShortNames : MONTH_SHORT_NAMES)[value - 1];
46884 }
46885 if (format === FORMAT_hh || format === FORMAT_h) {
46886 if (value === 0) {
46887 return '12';
46888 }
46889 if (value > 12) {
46890 value -= 12;
46891 }
46892 if (format === FORMAT_hh && value < 10) {
46893 return ('0' + value);
46894 }
46895 }
46896 return value.toString();
46897}
46898/**
46899 * @param {?} format
46900 * @param {?} min
46901 * @param {?} max
46902 * @return {?}
46903 */
46904function dateValueRange(format, min, max) {
46905 var /** @type {?} */ opts = [];
46906 var /** @type {?} */ i;
46907 if (format === FORMAT_YYYY || format === FORMAT_YY) {
46908 // year
46909 i = max.year;
46910 while (i >= min.year) {
46911 opts.push(i--);
46912 }
46913 }
46914 else if (format === FORMAT_MMMM || format === FORMAT_MMM ||
46915 format === FORMAT_MM || format === FORMAT_M ||
46916 format === FORMAT_hh || format === FORMAT_h) {
46917 // month or 12-hour
46918 for (i = 1; i < 13; i++) {
46919 opts.push(i);
46920 }
46921 }
46922 else if (format === FORMAT_DDDD || format === FORMAT_DDD ||
46923 format === FORMAT_DD || format === FORMAT_D) {
46924 // day
46925 for (i = 1; i < 32; i++) {
46926 opts.push(i);
46927 }
46928 }
46929 else if (format === FORMAT_HH || format === FORMAT_H) {
46930 // 24-hour
46931 for (i = 0; i < 24; i++) {
46932 opts.push(i);
46933 }
46934 }
46935 else if (format === FORMAT_mm || format === FORMAT_m) {
46936 // minutes
46937 for (i = 0; i < 60; i++) {
46938 opts.push(i);
46939 }
46940 }
46941 else if (format === FORMAT_ss || format === FORMAT_s) {
46942 // seconds
46943 for (i = 0; i < 60; i++) {
46944 opts.push(i);
46945 }
46946 }
46947 else if (format === FORMAT_A || format === FORMAT_a) {
46948 // AM/PM
46949 opts.push('am', 'pm');
46950 }
46951 return opts;
46952}
46953/**
46954 * @param {?} year
46955 * @param {?} month
46956 * @param {?} day
46957 * @param {?=} hour
46958 * @param {?=} minute
46959 * @return {?}
46960 */
46961function dateSortValue(year, month, day, hour, minute) {
46962 if (hour === void 0) { hour = 0; }
46963 if (minute === void 0) { minute = 0; }
46964 return parseInt("1" + fourDigit(year) + twoDigit(month) + twoDigit(day) + twoDigit(hour) + twoDigit(minute), 10);
46965}
46966/**
46967 * @param {?} data
46968 * @return {?}
46969 */
46970function dateDataSortValue(data) {
46971 if (data) {
46972 return dateSortValue(data.year, data.month, data.day, data.hour, data.minute);
46973 }
46974 return -1;
46975}
46976/**
46977 * @param {?} month
46978 * @param {?} year
46979 * @return {?}
46980 */
46981function daysInMonth(month, year) {
46982 return (month === 4 || month === 6 || month === 9 || month === 11) ? 30 : (month === 2) ? isLeapYear(year) ? 29 : 28 : 31;
46983}
46984/**
46985 * @param {?} year
46986 * @return {?}
46987 */
46988function isLeapYear(year) {
46989 return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
46990}
46991var ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
46992var TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
46993/**
46994 * @param {?} val
46995 * @return {?}
46996 */
46997function parseDate(val) {
46998 // manually parse IS0 cuz Date.parse cannot be trusted
46999 // ISO 8601 format: 1994-12-15T13:47:20Z
47000 var /** @type {?} */ parse;
47001 if (isPresent(val) && val !== '') {
47002 // try parsing for just time first, HH:MM
47003 parse = TIME_REGEXP.exec(val);
47004 if (isPresent(parse)) {
47005 // adjust the array so it fits nicely with the datetime parse
47006 parse.unshift(undefined, undefined);
47007 parse[2] = parse[3] = undefined;
47008 }
47009 else {
47010 // try parsing for full ISO datetime
47011 parse = ISO_8601_REGEXP.exec(val);
47012 }
47013 }
47014 if (isBlank$1(parse)) {
47015 // wasn't able to parse the ISO datetime
47016 return null;
47017 }
47018 // ensure all the parse values exist with at least 0
47019 for (var /** @type {?} */ i = 1; i < 8; i++) {
47020 parse[i] = (parse[i] !== undefined ? parseInt(parse[i], 10) : null);
47021 }
47022 var /** @type {?} */ tzOffset = 0;
47023 if (isPresent(parse[9]) && isPresent(parse[10])) {
47024 // hours
47025 tzOffset = parseInt(parse[10], 10) * 60;
47026 if (isPresent(parse[11])) {
47027 // minutes
47028 tzOffset += parseInt(parse[11], 10);
47029 }
47030 if (parse[9] === '-') {
47031 // + or -
47032 tzOffset *= -1;
47033 }
47034 }
47035 return {
47036 year: parse[1],
47037 month: parse[2],
47038 day: parse[3],
47039 hour: parse[4],
47040 minute: parse[5],
47041 second: parse[6],
47042 millisecond: parse[7],
47043 tzOffset: tzOffset,
47044 };
47045}
47046/**
47047 * @param {?} existingData
47048 * @param {?} newData
47049 * @return {?}
47050 */
47051function updateDate(existingData, newData) {
47052 if (isPresent(newData) && newData !== '') {
47053 if (isString(newData)) {
47054 // new date is a string, and hopefully in the ISO format
47055 // convert it to our DateTimeData if a valid ISO
47056 newData = parseDate(newData);
47057 if (newData) {
47058 // successfully parsed the ISO string to our DateTimeData
47059 Object.assign(existingData, newData);
47060 return true;
47061 }
47062 }
47063 else if ((isPresent(newData.year) || isPresent(newData.hour) || isPresent(newData.month) || isPresent(newData.day) || isPresent(newData.minute) || isPresent(newData.second))) {
47064 // newData is from of a datetime picker's selected values
47065 // update the existing DateTimeData data with the new values
47066 // do some magic for 12-hour values
47067 if (isPresent(newData.ampm) && isPresent(newData.hour)) {
47068 if (newData.ampm.value === 'pm') {
47069 newData.hour.value = (newData.hour.value === 12 ? 12 : newData.hour.value + 12);
47070 }
47071 else {
47072 newData.hour.value = (newData.hour.value === 12 ? 0 : newData.hour.value);
47073 }
47074 }
47075 // merge new values from the picker's selection
47076 // to the existing DateTimeData values
47077 for (var /** @type {?} */ k in newData) {
47078 ((existingData))[k] = newData[k].value;
47079 }
47080 return true;
47081 }
47082 // eww, invalid data
47083 console.warn("Error parsing date: \"" + newData + "\". Please provide a valid ISO 8601 datetime format: https://www.w3.org/TR/NOTE-datetime");
47084 }
47085 else {
47086 // blank data, clear everything out
47087 for (var /** @type {?} */ k in existingData) {
47088 delete ((existingData))[k];
47089 }
47090 }
47091 return false;
47092}
47093/**
47094 * @param {?} template
47095 * @return {?}
47096 */
47097function parseTemplate(template) {
47098 var /** @type {?} */ formats = [];
47099 template = template.replace(/[^\w\s]/gi, ' ');
47100 FORMAT_KEYS.forEach(function (format) {
47101 if (format.f.length > 1 && template.indexOf(format.f) > -1 && template.indexOf(format.f + format.f.charAt(0)) < 0) {
47102 template = template.replace(format.f, ' ' + format.f + ' ');
47103 }
47104 });
47105 var /** @type {?} */ words = template.split(' ').filter(function (w) { return w.length > 0; });
47106 words.forEach(function (word, i) {
47107 FORMAT_KEYS.forEach(function (format) {
47108 if (word === format.f) {
47109 if (word === FORMAT_A || word === FORMAT_a) {
47110 // this format is an am/pm format, so it's an "a" or "A"
47111 if ((formats.indexOf(FORMAT_h) < 0 && formats.indexOf(FORMAT_hh) < 0) ||
47112 VALID_AMPM_PREFIX.indexOf(words[i - 1]) === -1) {
47113 // template does not already have a 12-hour format
47114 // or this am/pm format doesn't have a hour, minute, or second format immediately before it
47115 // so do not treat this word "a" or "A" as the am/pm format
47116 return;
47117 }
47118 }
47119 formats.push(word);
47120 }
47121 });
47122 });
47123 return formats;
47124}
47125/**
47126 * @param {?} date
47127 * @param {?} format
47128 * @return {?}
47129 */
47130function getValueFromFormat(date, format) {
47131 if (format === FORMAT_A || format === FORMAT_a) {
47132 return (date.hour < 12 ? 'am' : 'pm');
47133 }
47134 if (format === FORMAT_hh || format === FORMAT_h) {
47135 return (date.hour > 12 ? date.hour - 12 : date.hour);
47136 }
47137 return ((date))[convertFormatToKey(format)];
47138}
47139/**
47140 * @param {?} format
47141 * @return {?}
47142 */
47143function convertFormatToKey(format) {
47144 for (var /** @type {?} */ k in FORMAT_KEYS) {
47145 if (FORMAT_KEYS[k].f === format) {
47146 return FORMAT_KEYS[k].k;
47147 }
47148 }
47149 return null;
47150}
47151/**
47152 * @param {?} data
47153 * @return {?}
47154 */
47155function convertDataToISO(data) {
47156 // https://www.w3.org/TR/NOTE-datetime
47157 var /** @type {?} */ rtn = '';
47158 if (isPresent(data)) {
47159 if (isPresent(data.year)) {
47160 // YYYY
47161 rtn = fourDigit(data.year);
47162 if (isPresent(data.month)) {
47163 // YYYY-MM
47164 rtn += '-' + twoDigit(data.month);
47165 if (isPresent(data.day)) {
47166 // YYYY-MM-DD
47167 rtn += '-' + twoDigit(data.day);
47168 if (isPresent(data.hour)) {
47169 // YYYY-MM-DDTHH:mm:SS
47170 rtn += "T" + twoDigit(data.hour) + ":" + twoDigit(data.minute) + ":" + twoDigit(data.second);
47171 if (data.millisecond > 0) {
47172 // YYYY-MM-DDTHH:mm:SS.SSS
47173 rtn += '.' + threeDigit(data.millisecond);
47174 }
47175 if (isBlank$1(data.tzOffset) || data.tzOffset === 0) {
47176 // YYYY-MM-DDTHH:mm:SSZ
47177 rtn += 'Z';
47178 }
47179 else {
47180 // YYYY-MM-DDTHH:mm:SS+/-HH:mm
47181 rtn += (data.tzOffset > 0 ? '+' : '-') + twoDigit(Math.floor(data.tzOffset / 60)) + ':' + twoDigit(data.tzOffset % 60);
47182 }
47183 }
47184 }
47185 }
47186 }
47187 else if (isPresent(data.hour)) {
47188 // HH:mm
47189 rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
47190 if (isPresent(data.second)) {
47191 // HH:mm:SS
47192 rtn += ':' + twoDigit(data.second);
47193 if (isPresent(data.millisecond)) {
47194 // HH:mm:SS.SSS
47195 rtn += '.' + threeDigit(data.millisecond);
47196 }
47197 }
47198 }
47199 }
47200 return rtn;
47201}
47202/**
47203 * @param {?} val
47204 * @return {?}
47205 */
47206function twoDigit(val) {
47207 return ('0' + (isPresent(val) ? Math.abs(val) : '0')).slice(-2);
47208}
47209/**
47210 * @param {?} val
47211 * @return {?}
47212 */
47213function threeDigit(val) {
47214 return ('00' + (isPresent(val) ? Math.abs(val) : '0')).slice(-3);
47215}
47216/**
47217 * @param {?} val
47218 * @return {?}
47219 */
47220function fourDigit(val) {
47221 return ('000' + (isPresent(val) ? Math.abs(val) : '0')).slice(-4);
47222}
47223var FORMAT_YYYY = 'YYYY';
47224var FORMAT_YY = 'YY';
47225var FORMAT_MMMM = 'MMMM';
47226var FORMAT_MMM = 'MMM';
47227var FORMAT_MM = 'MM';
47228var FORMAT_M = 'M';
47229var FORMAT_DDDD = 'DDDD';
47230var FORMAT_DDD = 'DDD';
47231var FORMAT_DD = 'DD';
47232var FORMAT_D = 'D';
47233var FORMAT_HH = 'HH';
47234var FORMAT_H = 'H';
47235var FORMAT_hh = 'hh';
47236var FORMAT_h = 'h';
47237var FORMAT_mm = 'mm';
47238var FORMAT_m = 'm';
47239var FORMAT_ss = 'ss';
47240var FORMAT_s = 's';
47241var FORMAT_A = 'A';
47242var FORMAT_a = 'a';
47243var FORMAT_KEYS = [
47244 { f: FORMAT_YYYY, k: 'year' },
47245 { f: FORMAT_MMMM, k: 'month' },
47246 { f: FORMAT_DDDD, k: 'day' },
47247 { f: FORMAT_MMM, k: 'month' },
47248 { f: FORMAT_DDD, k: 'day' },
47249 { f: FORMAT_YY, k: 'year' },
47250 { f: FORMAT_MM, k: 'month' },
47251 { f: FORMAT_DD, k: 'day' },
47252 { f: FORMAT_HH, k: 'hour' },
47253 { f: FORMAT_hh, k: 'hour' },
47254 { f: FORMAT_mm, k: 'minute' },
47255 { f: FORMAT_ss, k: 'second' },
47256 { f: FORMAT_M, k: 'month' },
47257 { f: FORMAT_D, k: 'day' },
47258 { f: FORMAT_H, k: 'hour' },
47259 { f: FORMAT_h, k: 'hour' },
47260 { f: FORMAT_m, k: 'minute' },
47261 { f: FORMAT_s, k: 'second' },
47262 { f: FORMAT_A, k: 'ampm' },
47263 { f: FORMAT_a, k: 'ampm' },
47264];
47265var DAY_NAMES = [
47266 'Sunday',
47267 'Monday',
47268 'Tuesday',
47269 'Wednesday',
47270 'Thursday',
47271 'Friday',
47272 'Saturday',
47273];
47274var DAY_SHORT_NAMES = [
47275 'Sun',
47276 'Mon',
47277 'Tue',
47278 'Wed',
47279 'Thu',
47280 'Fri',
47281 'Sat',
47282];
47283var MONTH_NAMES = [
47284 'January',
47285 'February',
47286 'March',
47287 'April',
47288 'May',
47289 'June',
47290 'July',
47291 'August',
47292 'September',
47293 'October',
47294 'November',
47295 'December',
47296];
47297var MONTH_SHORT_NAMES = [
47298 'Jan',
47299 'Feb',
47300 'Mar',
47301 'Apr',
47302 'May',
47303 'Jun',
47304 'Jul',
47305 'Aug',
47306 'Sep',
47307 'Oct',
47308 'Nov',
47309 'Dec',
47310];
47311var VALID_AMPM_PREFIX = [
47312 FORMAT_hh, FORMAT_h, FORMAT_mm, FORMAT_m, FORMAT_ss, FORMAT_s
47313];
47314
47315var __extends$44 = (undefined && undefined.__extends) || (function () {
47316 var extendStatics = Object.setPrototypeOf ||
47317 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
47318 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
47319 return function (d, b) {
47320 extendStatics(d, b);
47321 function __() { this.constructor = d; }
47322 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
47323 };
47324})();
47325/**
47326 * \@name DateTime
47327 * \@description
47328 * The DateTime component is used to present an interface which makes it easy for
47329 * users to select dates and times. Tapping on `<ion-datetime>` will display a picker
47330 * interface that slides up from the bottom of the page. The picker then displays
47331 * scrollable columns that can be used to individually select years, months, days,
47332 * hours and minute values. The DateTime component is similar to the native
47333 * `<input type="datetime-local">` element, however, Ionic's DateTime component makes
47334 * it easy to display the date and time in a preferred format, and manage the datetime
47335 * values.
47336 *
47337 * ```html
47338 * <ion-item>
47339 * <ion-label>Date</ion-label>
47340 * <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="myDate"></ion-datetime>
47341 * </ion-item>
47342 * ```
47343 *
47344 *
47345 * ## Display and Picker Formats
47346 *
47347 * The DateTime component displays the values in two places: in the `<ion-datetime>`
47348 * component, and in the interface that is presented from the bottom of the screen.
47349 * The following chart lists all of the formats that can be used.
47350 *
47351 * | Format | Description | Example |
47352 * |---------|--------------------------------|-------------------------|
47353 * | `YYYY` | Year, 4 digits | `2018` |
47354 * | `YY` | Year, 2 digits | `18` |
47355 * | `M` | Month | `1` ... `12` |
47356 * | `MM` | Month, leading zero | `01` ... `12` |
47357 * | `MMM` | Month, short name | `Jan` |
47358 * | `MMMM` | Month, full name | `January` |
47359 * | `D` | Day | `1` ... `31` |
47360 * | `DD` | Day, leading zero | `01` ... `31` |
47361 * | `DDD` | Day, short name | `Fri` |
47362 * | `DDDD` | Day, full name | `Friday` |
47363 * | `H` | Hour, 24-hour | `0` ... `23` |
47364 * | `HH` | Hour, 24-hour, leading zero | `00` ... `23` |
47365 * | `h` | Hour, 12-hour | `1` ... `12` |
47366 * | `hh` | Hour, 12-hour, leading zero | `01` ... `12` |
47367 * | `a` | 12-hour time period, lowercase | `am` `pm` |
47368 * | `A` | 12-hour time period, uppercase | `AM` `PM` |
47369 * | `m` | Minute | `1` ... `59` |
47370 * | `mm` | Minute, leading zero | `01` ... `59` |
47371 * | `s` | Second | `1` ... `59` |
47372 * | `ss` | Second, leading zero | `01` ... `59` |
47373 * | `Z` | UTC Timezone Offset | `Z or +HH:mm or -HH:mm` |
47374 *
47375 * **Important**: See the [Month Names and Day of the Week Names](#month-names-and-day-of-the-week-names)
47376 * section below on how to use different names for the month and day.
47377 *
47378 * ### Display Format
47379 *
47380 * The `displayFormat` input property specifies how a datetime's value should be
47381 * printed, as formatted text, within the `ion-datetime` component.
47382 *
47383 * In the following example, the display in the `<ion-datetime>` will use the
47384 * month's short name, the numerical day with a leading zero, a comma and the
47385 * four-digit year. In addition to the date, it will display the time with the hours
47386 * in the 24-hour format and the minutes. Any character can be used as a separator.
47387 * An example display using this format is: `Jun 17, 2005 11:06`.
47388 *
47389 * ```html
47390 * <ion-item>
47391 * <ion-label>Date</ion-label>
47392 * <ion-datetime displayFormat="MMM DD, YYYY HH:mm" [(ngModel)]="myDate"></ion-datetime>
47393 * </ion-item>
47394 * ```
47395 *
47396 * ### Picker Format
47397 *
47398 * The `pickerFormat` input property determines which columns should be shown in the
47399 * interface, the order of the columns, and which format to use within each column.
47400 * If the `pickerFormat` input is not provided then it will default to the `displayFormat`.
47401 *
47402 * In the following example, the display in the `<ion-datetime>` will use the
47403 * `MM/YYYY` format, such as `06/2020`. However, the picker interface
47404 * will display two columns with the month's long name, and the four-digit year.
47405 *
47406 * ```html
47407 * <ion-item>
47408 * <ion-label>Date</ion-label>
47409 * <ion-datetime displayFormat="MM/YYYY" pickerFormat="MMMM YYYY" [(ngModel)]="myDate"></ion-datetime>
47410 * </ion-item>
47411 * ```
47412 *
47413 * ### Datetime Data
47414 *
47415 * Historically, handling datetime values within JavaScript, or even within HTML
47416 * inputs, has always been a challenge. Specifically, JavaScript's `Date` object is
47417 * notoriously difficult to correctly parse apart datetime strings or to format
47418 * datetime values. Even worse is how different browsers and JavaScript versions
47419 * parse various datetime strings differently, especially per locale.
47420 *
47421 * But no worries, all is not lost! Ionic's datetime input has been designed so
47422 * developers can avoid the common pitfalls, allowing developers to easily format
47423 * datetime values within the input, and give the user a simple datetime picker for a
47424 * great user experience.
47425 *
47426 * ##### ISO 8601 Datetime Format: YYYY-MM-DDTHH:mmZ
47427 *
47428 * Ionic uses the [ISO 8601 datetime format](https://www.w3.org/TR/NOTE-datetime)
47429 * for its value. The value is simply a string, rather than using JavaScript's `Date`
47430 * object. Additionally, when using the ISO datetime format, it makes it easier
47431 * to serialize and pass within JSON objects, and sending databases a standardized
47432 * format which it can be easily parsed if need be.
47433 *
47434 * To create an ISO datetime string for the current date and time, e.g. use `const currentDate = (new Date()).toISOString();`.
47435 *
47436 * An ISO format can be used as a simple year, or just the hour and minute, or get more
47437 * detailed down to the millisecond and timezone. Any of the ISO formats below can be used,
47438 * and after a user selects a new value, Ionic will continue to use the same ISO format
47439 * which datetime value was originally given as.
47440 *
47441 * | Description | Format | Datetime Value Example |
47442 * |----------------------|------------------------|------------------------------|
47443 * | Year | YYYY | 1994 |
47444 * | Year and Month | YYYY-MM | 1994-12 |
47445 * | Complete Date | YYYY-MM-DD | 1994-12-15 |
47446 * | Date and Time | YYYY-MM-DDTHH:mm | 1994-12-15T13:47 |
47447 * | UTC Timezone | YYYY-MM-DDTHH:mm:ssTZD | 1994-12-15T13:47:20.789Z |
47448 * | Timezone Offset | YYYY-MM-DDTHH:mm:ssTZD | 1994-12-15T13:47:20.789+5:00 |
47449 * | Hour and Minute | HH:mm | 13:47 |
47450 * | Hour, Minute, Second | HH:mm:ss | 13:47:20 |
47451 *
47452 * Note that the year is always four-digits, milliseconds (if it's added) is always
47453 * three-digits, and all others are always two-digits. So the number representing
47454 * January always has a leading zero, such as `01`. Additionally, the hour is always
47455 * in the 24-hour format, so `00` is `12am` on a 12-hour clock, `13` means `1pm`,
47456 * and `23` means `11pm`.
47457 *
47458 * It's also important to note that neither the `displayFormat` or `pickerFormat` can
47459 * set the datetime value's output, which is the value that is set by the component's
47460 * `ngModel`. The format's are merely for displaying the value as text and the picker's
47461 * interface, but the datetime's value is always persisted as a valid ISO 8601 datetime
47462 * string.
47463 *
47464 *
47465 * ## Min and Max Datetimes
47466 *
47467 * Dates are infinite in either direction, so for a user's selection there should be at
47468 * least some form of restricting the dates that can be selected. By default, the maximum
47469 * date is to the end of the current year, and the minimum date is from the beginning
47470 * of the year that was 100 years ago.
47471 *
47472 * To customize the minimum and maximum datetime values, the `min` and `max` component
47473 * inputs can be provided which may make more sense for the app's use-case, rather
47474 * than the default of the last 100 years. Following the same IS0 8601 format listed
47475 * in the table above, each component can restrict which dates can be selected by the
47476 * user. Below is an example of restricting the date selection between the beginning
47477 * of 2016, and October 31st of 2020:
47478 *
47479 * ```html
47480 * <ion-item>
47481 * <ion-label>Date</ion-label>
47482 * <ion-datetime displayFormat="MMMM YYYY" min="2016" max="2020-10-31" [(ngModel)]="myDate">
47483 * </ion-datetime>
47484 * </ion-item>
47485 * ```
47486 *
47487 *
47488 * ## Month Names and Day of the Week Names
47489 *
47490 * At this time, there is no one-size-fits-all standard to automatically choose the correct
47491 * language/spelling for a month name, or day of the week name, depending on the language
47492 * or locale. Good news is that there is an
47493 * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat)
47494 * standard which *most* browsers have adopted. However, at this time the standard has not
47495 * been fully implemented by all popular browsers so Ionic is unavailable to take advantage
47496 * of it *yet*. Additionally, Angular also provides an internationalization service, but it
47497 * is still under heavy development so Ionic does not depend on it at this time.
47498 *
47499 * All things considered, the by far easiest solution is to just provide an array of names
47500 * if the app needs to use names other than the default English version of month and day
47501 * names. The month names and day names can be either configured at the app level, or
47502 * individual `ion-datetime` level.
47503 *
47504 * ### App Config Level
47505 *
47506 * ```ts
47507 * //app.module.ts
47508 * \@NgModule({
47509 * ...,
47510 * imports: [
47511 * IonicModule.forRoot(MyApp, {
47512 * monthNames: ['janeiro', 'fevereiro', 'mar\u00e7o', ... ],
47513 * monthShortNames: ['jan', 'fev', 'mar', ... ],
47514 * dayNames: ['domingo', 'segunda-feira', 'ter\u00e7a-feira', ... ],
47515 * dayShortNames: ['dom', 'seg', 'ter', ... ],
47516 * })
47517 * ],
47518 * ...
47519 * })
47520 * ```
47521 *
47522 * ### Component Input Level
47523 *
47524 * ```html
47525 * <ion-item>
47526 * <ion-label>Período</ion-label>
47527 * <ion-datetime displayFormat="DDDD MMM D, YYYY" [(ngModel)]="myDate"
47528 * monthNames="janeiro, fevereiro, mar\u00e7o, ..."
47529 * monthShortNames="jan, fev, mar, ..."
47530 * dayNames="domingo, segunda-feira, ter\u00e7a-feira, ..."
47531 * dayShortNames="dom, seg, ter, ..."></ion-datetime>
47532 * </ion-item>
47533 * ```
47534 *
47535 *
47536 * ### Advanced Datetime Validation and Manipulation
47537 *
47538 * The datetime picker provides the simplicity of selecting an exact format, and persists
47539 * the datetime values as a string using the standardized
47540 * [ISO 8601 datetime format](https://www.w3.org/TR/NOTE-datetime).
47541 * However, it's important to note that `ion-datetime` does not attempt to solve all
47542 * situtations when validating and manipulating datetime values. If datetime values need
47543 * to be parsed from a certain format, or manipulated (such as adding 5 days to a date,
47544 * subtracting 30 minutes, etc.), or even formatting data to a specific locale, then we highly
47545 * recommend using [moment.js](http://momentjs.com/) to "Parse, validate, manipulate, and
47546 * display dates in JavaScript". [Moment.js](http://momentjs.com/) has quickly become
47547 * our goto standard when dealing with datetimes within JavaScript, but Ionic does not
47548 * prepackage this dependency since most apps will not require it, and its locale
47549 * configuration should be decided by the end-developer.
47550 *
47551 *
47552 * \@usage
47553 * ```html
47554 * <ion-item>
47555 * <ion-label>Date</ion-label>
47556 * <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="myDate">
47557 * </ion-datetime>
47558 * </ion-item>
47559 * ```
47560 *
47561 *
47562 * \@demo /docs/demos/src/datetime/
47563 */
47564var DateTime = (function (_super) {
47565 __extends$44(DateTime, _super);
47566 /**
47567 * @param {?} form
47568 * @param {?} config
47569 * @param {?} elementRef
47570 * @param {?} renderer
47571 * @param {?} item
47572 * @param {?} _pickerCtrl
47573 */
47574 function DateTime(form, config, elementRef, renderer, item, _pickerCtrl) {
47575 var _this = _super.call(this, config, elementRef, renderer, 'datetime', {}, form, item, null) || this;
47576 _this._pickerCtrl = _pickerCtrl;
47577 _this._text = '';
47578 _this._locale = {};
47579 /**
47580 * \@input {string} The text to display on the picker's cancel button. Default: `Cancel`.
47581 */
47582 _this.cancelText = 'Cancel';
47583 /**
47584 * \@input {string} The text to display on the picker's "Done" button. Default: `Done`.
47585 */
47586 _this.doneText = 'Done';
47587 /**
47588 * \@input {any} Any additional options that the picker interface can accept.
47589 * See the [Picker API docs](../../picker/Picker) for the picker options.
47590 */
47591 _this.pickerOptions = {};
47592 /**
47593 * \@input {string} The text to display when there's no date selected yet.
47594 * Using lowercase to match the input attribute
47595 */
47596 _this.placeholder = '';
47597 /**
47598 * \@output {any} Emitted when the datetime selection was cancelled.
47599 */
47600 _this.ionCancel = new EventEmitter();
47601 return _this;
47602 }
47603 /**
47604 * @hidden
47605 * @return {?}
47606 */
47607 DateTime.prototype.ngAfterContentInit = function () {
47608 var _this = this;
47609 // first see if locale names were provided in the inputs
47610 // then check to see if they're in the config
47611 // if neither were provided then it will use default English names
47612 ['monthNames', 'monthShortNames', 'dayNames', 'dayShortNames'].forEach(function (type) {
47613 ((_this))._locale[type] = convertToArrayOfStrings(isPresent(((_this))[type]) ? ((_this))[type] : _this._config.get(type), type);
47614 });
47615 this._initialize();
47616 };
47617 /**
47618 * @hidden
47619 * @param {?} val
47620 * @return {?}
47621 */
47622 DateTime.prototype._inputNormalize = function (val) {
47623 updateDate(this._value, val);
47624 return this._value;
47625 };
47626 /**
47627 * @hidden
47628 * @return {?}
47629 */
47630 DateTime.prototype._inputUpdated = function () {
47631 _super.prototype._inputUpdated.call(this);
47632 this.updateText();
47633 };
47634 /**
47635 * @hidden
47636 * @return {?}
47637 */
47638 DateTime.prototype._inputShouldChange = function () {
47639 return true;
47640 };
47641 /**
47642 * TODO: REMOVE THIS
47643 * @hidden
47644 * @return {?}
47645 */
47646 DateTime.prototype._inputChangeEvent = function () {
47647 return this.value;
47648 };
47649 /**
47650 * @hidden
47651 * @return {?}
47652 */
47653 DateTime.prototype._inputNgModelEvent = function () {
47654 return convertDataToISO(this.value);
47655 };
47656 /**
47657 * @param {?} ev
47658 * @return {?}
47659 */
47660 DateTime.prototype._click = function (ev) {
47661 ev.preventDefault();
47662 ev.stopPropagation();
47663 this.open();
47664 };
47665 /**
47666 * @return {?}
47667 */
47668 DateTime.prototype._keyup = function () {
47669 this.open();
47670 };
47671 /**
47672 * @hidden
47673 * @return {?}
47674 */
47675 DateTime.prototype.open = function () {
47676 var _this = this;
47677 if (this.isFocus() || this._disabled) {
47678 return;
47679 }
47680 (void 0) /* console.debug */;
47681 // the user may have assigned some options specifically for the alert
47682 var /** @type {?} */ pickerOptions = deepCopy(this.pickerOptions);
47683 // Configure picker under the hood
47684 var /** @type {?} */ picker = this._picker = this._pickerCtrl.create(pickerOptions);
47685 picker.addButton({
47686 text: this.cancelText,
47687 role: 'cancel',
47688 handler: function () { return _this.ionCancel.emit(_this); }
47689 });
47690 picker.addButton({
47691 text: this.doneText,
47692 handler: function (data) { return _this.value = data; },
47693 });
47694 picker.ionChange.subscribe(function () {
47695 _this.validate();
47696 picker.refresh();
47697 });
47698 // Update picker status before presenting
47699 this.generate();
47700 this.validate();
47701 // Present picker
47702 this._fireFocus();
47703 picker.present(pickerOptions);
47704 picker.onDidDismiss(function () {
47705 _this._fireBlur();
47706 });
47707 };
47708 /**
47709 * @hidden
47710 * @return {?}
47711 */
47712 DateTime.prototype.generate = function () {
47713 var _this = this;
47714 var /** @type {?} */ picker = this._picker;
47715 // if a picker format wasn't provided, then fallback
47716 // to use the display format
47717 var /** @type {?} */ template = this.pickerFormat || this.displayFormat || DEFAULT_FORMAT;
47718 if (isPresent(template)) {
47719 // make sure we've got up to date sizing information
47720 this.calcMinMax();
47721 // does not support selecting by day name
47722 // automaticallly remove any day name formats
47723 template = template.replace('DDDD', '{~}').replace('DDD', '{~}');
47724 if (template.indexOf('D') === -1) {
47725 // there is not a day in the template
47726 // replace the day name with a numeric one if it exists
47727 template = template.replace('{~}', 'D');
47728 }
47729 // make sure no day name replacer is left in the string
47730 template = template.replace(/{~}/g, '');
47731 // parse apart the given template into an array of "formats"
47732 parseTemplate(template).forEach(function (format) {
47733 // loop through each format in the template
47734 // create a new picker column to build up with data
47735 var /** @type {?} */ key = convertFormatToKey(format);
47736 var /** @type {?} */ values;
47737 // first see if they have exact values to use for this input
47738 if (isPresent(((_this))[key + 'Values'])) {
47739 // user provide exact values for this date part
47740 values = convertToArrayOfNumbers(((_this))[key + 'Values'], key);
47741 }
47742 else {
47743 // use the default date part values
47744 values = dateValueRange(format, _this._min, _this._max);
47745 }
47746 var /** @type {?} */ column = {
47747 name: key,
47748 selectedIndex: 0,
47749 options: values.map(function (val) {
47750 return {
47751 value: val,
47752 text: renderTextFormat(format, val, null, _this._locale),
47753 };
47754 })
47755 };
47756 // cool, we've loaded up the columns with options
47757 // preselect the option for this column
47758 var /** @type {?} */ optValue = getValueFromFormat(_this.getValue(), format);
47759 var /** @type {?} */ selectedIndex = column.options.findIndex(function (opt) { return opt.value === optValue; });
47760 if (selectedIndex >= 0) {
47761 // set the select index for this column's options
47762 column.selectedIndex = selectedIndex;
47763 }
47764 // add our newly created column to the picker
47765 picker.addColumn(column);
47766 });
47767 // Normalize min/max
47768 var /** @type {?} */ min_1 = (this._min);
47769 var /** @type {?} */ max_1 = (this._max);
47770 var /** @type {?} */ columns_1 = this._picker.getColumns();
47771 ['month', 'day', 'hour', 'minute']
47772 .filter(function (name) { return !columns_1.find(function (column) { return column.name === name; }); })
47773 .forEach(function (name) {
47774 min_1[name] = 0;
47775 max_1[name] = 0;
47776 });
47777 this.divyColumns();
47778 }
47779 };
47780 /**
47781 * @hidden
47782 * @param {?} name
47783 * @param {?} index
47784 * @param {?} min
47785 * @param {?} max
47786 * @param {?} lowerBounds
47787 * @param {?} upperBounds
47788 * @return {?}
47789 */
47790 DateTime.prototype.validateColumn = function (name, index, min, max, lowerBounds, upperBounds) {
47791 (void 0) /* assert */;
47792 (void 0) /* assert */;
47793 var /** @type {?} */ column = this._picker.getColumn(name);
47794 if (!column) {
47795 return 0;
47796 }
47797 var /** @type {?} */ lb = lowerBounds.slice();
47798 var /** @type {?} */ ub = upperBounds.slice();
47799 var /** @type {?} */ options = column.options;
47800 var /** @type {?} */ indexMin = options.length - 1;
47801 var /** @type {?} */ indexMax = 0;
47802 for (var /** @type {?} */ i = 0; i < options.length; i++) {
47803 var /** @type {?} */ opt = options[i];
47804 var /** @type {?} */ value = opt.value;
47805 lb[index] = opt.value;
47806 ub[index] = opt.value;
47807 var /** @type {?} */ disabled = opt.disabled = (value < lowerBounds[index] ||
47808 value > upperBounds[index] ||
47809 dateSortValue(ub[0], ub[1], ub[2], ub[3], ub[4]) < min ||
47810 dateSortValue(lb[0], lb[1], lb[2], lb[3], lb[4]) > max);
47811 if (!disabled) {
47812 indexMin = Math.min(indexMin, i);
47813 indexMax = Math.max(indexMax, i);
47814 }
47815 }
47816 var /** @type {?} */ selectedIndex = column.selectedIndex = clamp(indexMin, column.selectedIndex, indexMax);
47817 opt = column.options[selectedIndex];
47818 if (opt) {
47819 return opt.value;
47820 }
47821 return 0;
47822 };
47823 /**
47824 * @return {?}
47825 */
47826 DateTime.prototype.validate = function () {
47827 var /** @type {?} */ today = new Date();
47828 var /** @type {?} */ minCompareVal = dateDataSortValue(this._min);
47829 var /** @type {?} */ maxCompareVal = dateDataSortValue(this._max);
47830 var /** @type {?} */ yearCol = this._picker.getColumn('year');
47831 (void 0) /* assert */;
47832 var /** @type {?} */ selectedYear = today.getFullYear();
47833 if (yearCol) {
47834 // default to the first value if the current year doesn't exist in the options
47835 if (!yearCol.options.find(function (col) { return col.value === today.getFullYear(); })) {
47836 selectedYear = yearCol.options[0].value;
47837 }
47838 var /** @type {?} */ yearOpt = yearCol.options[yearCol.selectedIndex];
47839 if (yearOpt) {
47840 // they have a selected year value
47841 selectedYear = yearOpt.value;
47842 }
47843 }
47844 var /** @type {?} */ selectedMonth = this.validateColumn('month', 1, minCompareVal, maxCompareVal, [selectedYear, 0, 0, 0, 0], [selectedYear, 12, 31, 23, 59]);
47845 var /** @type {?} */ numDaysInMonth = daysInMonth(selectedMonth, selectedYear);
47846 var /** @type {?} */ selectedDay = this.validateColumn('day', 2, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, 0, 0, 0], [selectedYear, selectedMonth, numDaysInMonth, 23, 59]);
47847 var /** @type {?} */ selectedHour = this.validateColumn('hour', 3, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, selectedDay, 0, 0], [selectedYear, selectedMonth, selectedDay, 23, 59]);
47848 this.validateColumn('minute', 4, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, selectedDay, selectedHour, 0], [selectedYear, selectedMonth, selectedDay, selectedHour, 59]);
47849 };
47850 /**
47851 * @hidden
47852 * @return {?}
47853 */
47854 DateTime.prototype.divyColumns = function () {
47855 var /** @type {?} */ pickerColumns = this._picker.getColumns();
47856 var /** @type {?} */ columnsWidth = [];
47857 var /** @type {?} */ col;
47858 var /** @type {?} */ width;
47859 for (var /** @type {?} */ i = 0; i < pickerColumns.length; i++) {
47860 col = pickerColumns[i];
47861 columnsWidth.push(0);
47862 for (var /** @type {?} */ j = 0; j < col.options.length; j++) {
47863 width = col.options[j].text.length;
47864 if (width > columnsWidth[i]) {
47865 columnsWidth[i] = width;
47866 }
47867 }
47868 }
47869 if (columnsWidth.length === 2) {
47870 width = Math.max(columnsWidth[0], columnsWidth[1]);
47871 pickerColumns[0].align = 'right';
47872 pickerColumns[1].align = 'left';
47873 pickerColumns[0].optionsWidth = pickerColumns[1].optionsWidth = width * 17 + "px";
47874 }
47875 else if (columnsWidth.length === 3) {
47876 width = Math.max(columnsWidth[0], columnsWidth[2]);
47877 pickerColumns[0].align = 'right';
47878 pickerColumns[1].columnWidth = columnsWidth[1] * 17 + "px";
47879 pickerColumns[0].optionsWidth = pickerColumns[2].optionsWidth = width * 17 + "px";
47880 pickerColumns[2].align = 'left';
47881 }
47882 };
47883 /**
47884 * @hidden
47885 * @return {?}
47886 */
47887 DateTime.prototype.updateText = function () {
47888 // create the text of the formatted data
47889 var /** @type {?} */ template = this.displayFormat || this.pickerFormat || DEFAULT_FORMAT;
47890 this._text = renderDateTime(template, this.getValue(), this._locale);
47891 };
47892 /**
47893 * @hidden
47894 * @return {?}
47895 */
47896 DateTime.prototype.getValue = function () {
47897 return this._value;
47898 };
47899 /**
47900 * @hidden
47901 * @return {?}
47902 */
47903 DateTime.prototype.hasValue = function () {
47904 var /** @type {?} */ val = this._value;
47905 return isPresent(val)
47906 && isObject$1(val)
47907 && Object.keys(val).length > 0;
47908 };
47909 /**
47910 * @hidden
47911 * @param {?=} now
47912 * @return {?}
47913 */
47914 DateTime.prototype.calcMinMax = function (now) {
47915 var /** @type {?} */ todaysYear = (now || new Date()).getFullYear();
47916 if (isPresent(this.yearValues)) {
47917 var /** @type {?} */ years = convertToArrayOfNumbers(this.yearValues, 'year');
47918 if (isBlank$1(this.min)) {
47919 this.min = Math.min.apply(Math, years);
47920 }
47921 if (isBlank$1(this.max)) {
47922 this.max = Math.max.apply(Math, years);
47923 }
47924 }
47925 else {
47926 if (isBlank$1(this.min)) {
47927 this.min = (todaysYear - 100).toString();
47928 }
47929 if (isBlank$1(this.max)) {
47930 this.max = todaysYear.toString();
47931 }
47932 }
47933 var /** @type {?} */ min = this._min = parseDate(this.min);
47934 var /** @type {?} */ max = this._max = parseDate(this.max);
47935 min.year = min.year || todaysYear;
47936 max.year = max.year || todaysYear;
47937 min.month = min.month || 1;
47938 max.month = max.month || 12;
47939 min.day = min.day || 1;
47940 max.day = max.day || 31;
47941 min.hour = min.hour || 0;
47942 max.hour = max.hour || 23;
47943 min.minute = min.minute || 0;
47944 max.minute = max.minute || 59;
47945 min.second = min.second || 0;
47946 max.second = max.second || 59;
47947 // Ensure min/max constraits
47948 if (min.year > max.year) {
47949 console.error('min.year > max.year');
47950 min.year = max.year - 100;
47951 }
47952 if (min.year === max.year) {
47953 if (min.month > max.month) {
47954 console.error('min.month > max.month');
47955 min.month = 1;
47956 }
47957 else if (min.month === max.month && min.day > max.day) {
47958 console.error('min.day > max.day');
47959 min.day = 1;
47960 }
47961 }
47962 };
47963 return DateTime;
47964}(BaseInput));
47965DateTime.decorators = [
47966 { type: Component, args: [{
47967 selector: 'ion-datetime',
47968 template: '<div *ngIf="!_text" class="datetime-text datetime-placeholder">{{placeholder}}</div>' +
47969 '<div *ngIf="_text" class="datetime-text">{{_text}}</div>' +
47970 '<button aria-haspopup="true" ' +
47971 'type="button" ' +
47972 '[id]="id" ' +
47973 'ion-button="item-cover" ' +
47974 '[attr.aria-labelledby]="_labelId" ' +
47975 '[attr.aria-disabled]="_disabled" ' +
47976 'class="item-cover">' +
47977 '</button>',
47978 host: {
47979 '[class.datetime-disabled]': '_disabled'
47980 },
47981 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DateTime, multi: true }],
47982 encapsulation: ViewEncapsulation.None,
47983 },] },
47984];
47985/**
47986 * @nocollapse
47987 */
47988DateTime.ctorParameters = function () { return [
47989 { type: Form, },
47990 { type: Config, },
47991 { type: ElementRef, },
47992 { type: Renderer, },
47993 { type: Item, decorators: [{ type: Optional },] },
47994 { type: PickerController, decorators: [{ type: Optional },] },
47995]; };
47996DateTime.propDecorators = {
47997 'min': [{ type: Input },],
47998 'max': [{ type: Input },],
47999 'displayFormat': [{ type: Input },],
48000 'pickerFormat': [{ type: Input },],
48001 'cancelText': [{ type: Input },],
48002 'doneText': [{ type: Input },],
48003 'yearValues': [{ type: Input },],
48004 'monthValues': [{ type: Input },],
48005 'dayValues': [{ type: Input },],
48006 'hourValues': [{ type: Input },],
48007 'minuteValues': [{ type: Input },],
48008 'monthNames': [{ type: Input },],
48009 'monthShortNames': [{ type: Input },],
48010 'dayNames': [{ type: Input },],
48011 'dayShortNames': [{ type: Input },],
48012 'pickerOptions': [{ type: Input },],
48013 'placeholder': [{ type: Input },],
48014 'ionCancel': [{ type: Output },],
48015 '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
48016 '_keyup': [{ type: HostListener, args: ['keyup.space',] },],
48017};
48018/**
48019 * @hidden
48020 * Use to convert a string of comma separated numbers or
48021 * an array of numbers, and clean up any user input
48022 * @param {?} input
48023 * @param {?} type
48024 * @return {?}
48025 */
48026function convertToArrayOfNumbers(input, type) {
48027 if (isString(input)) {
48028 // convert the string to an array of strings
48029 // auto remove any whitespace and [] characters
48030 input = input.replace(/\[|\]|\s/g, '').split(',');
48031 }
48032 var /** @type {?} */ values;
48033 if (isArray$2(input)) {
48034 // ensure each value is an actual number in the returned array
48035 values = input
48036 .map(function (num) { return parseInt(num, 10); })
48037 .filter(isFinite);
48038 }
48039 if (!values || !values.length) {
48040 console.warn("Invalid \"" + type + "Values\". Must be an array of numbers, or a comma separated string of numbers.");
48041 }
48042 return values;
48043}
48044/**
48045 * @hidden
48046 * Use to convert a string of comma separated strings or
48047 * an array of strings, and clean up any user input
48048 * @param {?} input
48049 * @param {?} type
48050 * @return {?}
48051 */
48052function convertToArrayOfStrings(input, type) {
48053 if (isPresent(input)) {
48054 if (isString(input)) {
48055 // convert the string to an array of strings
48056 // auto remove any [] characters
48057 input = input.replace(/\[|\]/g, '').split(',');
48058 }
48059 var /** @type {?} */ values;
48060 if (isArray$2(input)) {
48061 // trim up each string value
48062 values = input.map(function (val) { return val.trim(); });
48063 }
48064 if (!values || !values.length) {
48065 console.warn("Invalid \"" + type + "Names\". Must be an array of strings, or a comma separated string.");
48066 }
48067 return values;
48068 }
48069}
48070var DEFAULT_FORMAT = 'MMM D, YYYY';
48071
48072var __extends$47 = (undefined && undefined.__extends) || (function () {
48073 var extendStatics = Object.setPrototypeOf ||
48074 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
48075 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
48076 return function (d, b) {
48077 extendStatics(d, b);
48078 function __() { this.constructor = d; }
48079 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
48080 };
48081})();
48082/**
48083 * \@name FabButton
48084 * \@module ionic
48085 *
48086 * \@description
48087 * FABs (Floating Action Buttons) are standard material design components. They are shaped as a circle that represents a promoted action. When pressed, it may contain more related actions.
48088 * FABs as its name suggests are floating over the content in a fixed position. This is not achieved exclusively with `<button ion-fab>Button</button>` but it has to wrapped with the `<ion-fab>` component, like this:
48089 *
48090 * ```html
48091 * <ion-content>
48092 * <!-- Real floating action button, fixed. It will not scroll with the content -->
48093 * <ion-fab>
48094 * <button ion-fab>Button</button>
48095 * </ion-fab>
48096 *
48097 * <!-- Button shaped as a circle that just like a normal button scrolls with the content -->
48098 * <button ion-fab>Button</button>
48099 * </ion-content>
48100 *
48101 * ```
48102 *
48103 * In case the button is not wrapped with `<ion-fab>`, the fab button will behave like a normal button, scrolling with the content.
48104 *
48105 * See [ion-fab] to learn more information about how to position the fab button.
48106 *
48107 * \@property [mini] - Makes a fab button with a reduced size.
48108 *
48109 * \@usage
48110 *
48111 * ```html
48112 *
48113 * <!-- Colors -->
48114 * <ion-fab>
48115 * <button ion-fab color="primary">Button</button>
48116 * </ion-fab>
48117 *
48118 * <!-- Mini -->
48119 * <ion-fab>
48120 * <button ion-fab mini>Small</button>
48121 * </ion-fab>
48122 * ```
48123 *
48124 * \@demo /docs/demos/src/fab/
48125 * @see {\@link /docs/components#fabs FAB Component Docs}
48126 */
48127var FabButton = (function (_super) {
48128 __extends$47(FabButton, _super);
48129 /**
48130 * @param {?} config
48131 * @param {?} elementRef
48132 * @param {?} renderer
48133 */
48134 function FabButton(config, elementRef, renderer) {
48135 return _super.call(this, config, elementRef, renderer, 'fab') || this;
48136 }
48137 /**
48138 * @hidden
48139 * @param {?} closeVisible
48140 * @return {?}
48141 */
48142 FabButton.prototype.setActiveClose = function (closeVisible) {
48143 this.setElementClass('fab-close-active', closeVisible);
48144 };
48145 return FabButton;
48146}(Ion));
48147FabButton.decorators = [
48148 { type: Component, args: [{
48149 selector: '[ion-fab]',
48150 template: '<ion-icon name="close" class="fab-close-icon"></ion-icon>' +
48151 '<span class="button-inner">' +
48152 '<ng-content></ng-content>' +
48153 '</span>' +
48154 '<div class="button-effect"></div>',
48155 changeDetection: ChangeDetectionStrategy.OnPush,
48156 encapsulation: ViewEncapsulation.None,
48157 },] },
48158];
48159/**
48160 * @nocollapse
48161 */
48162FabButton.ctorParameters = function () { return [
48163 { type: Config, },
48164 { type: ElementRef, },
48165 { type: Renderer, },
48166]; };
48167
48168/**
48169 * \@name FabList
48170 * \@description
48171 * `ion-fab-list` is a container for multiple FAB buttons. They are components of `ion-fab` and allow you to specificy the buttons position, left, right, top, bottom.
48172 * \@usage
48173 *
48174 * ```html
48175 * <ion-fab bottom right >
48176 * <button ion-fab>Share</button>
48177 * <ion-fab-list side="top">
48178 * <button ion-fab>Facebook</button>
48179 * <button ion-fab>Twitter</button>
48180 * <button ion-fab>Youtube</button>
48181 * </ion-fab-list>
48182 * <ion-fab-list side="left">
48183 * <button ion-fab>Vimeo</button>
48184 * </ion-fab-list>
48185 * </ion-fab>
48186 * ```
48187 * \@module ionic
48188 *
48189 * \@demo /docs/demos/src/fab/
48190 * @see {\@link /docs/components#fab Fab Component Docs}
48191 */
48192var FabList = (function () {
48193 /**
48194 * @param {?} _elementRef
48195 * @param {?} _renderer
48196 * @param {?} config
48197 * @param {?} _plt
48198 */
48199 function FabList(_elementRef, _renderer, config, _plt) {
48200 this._elementRef = _elementRef;
48201 this._renderer = _renderer;
48202 this._plt = _plt;
48203 this._visible = false;
48204 this._fabs = [];
48205 this._mode = config.get('mode');
48206 }
48207 Object.defineProperty(FabList.prototype, "_setbuttons", {
48208 /**
48209 * @param {?} query
48210 * @return {?}
48211 */
48212 set: function (query) {
48213 var /** @type {?} */ fabs = this._fabs = query.toArray();
48214 var /** @type {?} */ className = "fab-" + this._mode + "-in-list";
48215 for (var _i = 0, fabs_1 = fabs; _i < fabs_1.length; _i++) {
48216 var fab = fabs_1[_i];
48217 fab.setElementClass('fab-in-list', true);
48218 fab.setElementClass(className, true);
48219 }
48220 },
48221 enumerable: true,
48222 configurable: true
48223 });
48224 /**
48225 * @hidden
48226 * @param {?} val
48227 * @return {?}
48228 */
48229 FabList.prototype.setVisible = function (val) {
48230 var _this = this;
48231 var /** @type {?} */ visible = isTrueProperty(val);
48232 if (visible === this._visible) {
48233 return;
48234 }
48235 this._visible = visible;
48236 var /** @type {?} */ fabs = this._fabs;
48237 var /** @type {?} */ i = 1;
48238 if (visible) {
48239 fabs.forEach(function (fab) {
48240 _this._plt.timeout(function () { return fab.setElementClass('show', true); }, i * 30);
48241 i++;
48242 });
48243 }
48244 else {
48245 fabs.forEach(function (fab) { return fab.setElementClass('show', false); });
48246 }
48247 this.setElementClass('fab-list-active', visible);
48248 };
48249 /**
48250 * \@internal
48251 * @param {?} className
48252 * @param {?} add
48253 * @return {?}
48254 */
48255 FabList.prototype.setElementClass = function (className, add) {
48256 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
48257 };
48258 return FabList;
48259}());
48260FabList.decorators = [
48261 { type: Directive, args: [{
48262 selector: 'ion-fab-list',
48263 },] },
48264];
48265/**
48266 * @nocollapse
48267 */
48268FabList.ctorParameters = function () { return [
48269 { type: ElementRef, },
48270 { type: Renderer, },
48271 { type: Config, },
48272 { type: Platform, },
48273]; };
48274FabList.propDecorators = {
48275 '_setbuttons': [{ type: ContentChildren, args: [FabButton,] },],
48276};
48277
48278/**
48279 * \@name FabContainer
48280 * \@module ionic
48281 *
48282 * \@description
48283 * `<ion-fab>` is not a FAB button by itself but a container that assist the fab button (`<button ion-fab>`) allowing it
48284 * to be placed in fixed position that does not scroll with the content. It is also used to implement "material design speed dial",
48285 * ie. a FAB buttons displays a small lists of related actions when clicked.
48286 *
48287 * \@property [top] - Places the container on the top of the content
48288 * \@property [bottom] - Places the container on the bottom of the content
48289 * \@property [left] - Places the container on the left
48290 * \@property [right] - Places the container on the right
48291 * \@property [middle] - Places the container on the middle vertically
48292 * \@property [center] - Places the container on the center horizontally
48293 * \@property [edge] - Used to place the container between the content and the header/footer
48294 *
48295 * \@usage
48296 *
48297 * ```html
48298 * <!-- this fab is placed at top right -->
48299 * <ion-content>
48300 * <ion-fab top right>
48301 * <button ion-fab>Button</button>
48302 * </ion-fab>
48303 *
48304 * <!-- this fab is placed at the center of the content viewport -->
48305 * <ion-fab center middle>
48306 * <button ion-fab>Button</button>
48307 * </ion-fab>
48308 * </ion-content>
48309 * ```
48310 *
48311 * Ionic's FAB also supports "material design's fab speed dial". It is a normal fab button
48312 * that shows a list of related actions when clicked.
48313 *
48314 * The same `ion-fab` container can contain several `ion-fab-list` with different side values:
48315 * `top`, `bottom`, `left` and `right`. For example, if you want to have a list of button that are
48316 * on the top of the main button, you should use `side="top"` and so on. By default, if side is ommited, `side="bottom"`.
48317 *
48318 * ```html
48319 * <ion-content>
48320 * <!-- this fab is placed at bottom right -->
48321 * <ion-fab bottom right >
48322 * <button ion-fab>Share</button>
48323 * <ion-fab-list side="top">
48324 * <button ion-fab>Facebook</button>
48325 * <button ion-fab>Twitter</button>
48326 * <button ion-fab>Youtube</button>
48327 * </ion-fab-list>
48328 * <ion-fab-list side="left">
48329 * <button ion-fab>Vimeo</button>
48330 * </ion-fab-list>
48331 * </ion-fab>
48332 * </ion-content>
48333 * ```
48334 *
48335 * A FAB speed dial can also be closed programatically.
48336 *
48337 * ```html
48338 * <ion-content>
48339 * <ion-fab bottom right #fab>
48340 * <button ion-fab>Share</button>
48341 * <ion-fab-list side="top">
48342 * <button ion-fab (click)="share('facebook', fab)">Facebook</button>
48343 * <button ion-fab (click)="share('twitter', fab)">Twitter</button>
48344 * </ion-fab-list>
48345 * </ion-fab>
48346 * </ion-content>
48347 * ```
48348 *
48349 * ```ts
48350 * share(socialNet: string, fab: FabContainer) {
48351 * fab.close();
48352 * console.log("Sharing in", socialNet);
48353 * }
48354 * ```
48355 *
48356 * \@demo /docs/demos/src/fab/
48357 * @see {\@link /docs/components#fabs FAB Component Docs}
48358 */
48359var FabContainer = (function () {
48360 /**
48361 * @param {?} plt
48362 */
48363 function FabContainer(plt) {
48364 /**
48365 * @hidden
48366 */
48367 this._listsActive = false;
48368 this._events = new UIEventManager(plt);
48369 }
48370 /**
48371 * @hidden
48372 * @return {?}
48373 */
48374 FabContainer.prototype.ngAfterContentInit = function () {
48375 var /** @type {?} */ mainButton = this._mainButton;
48376 if (!mainButton || !mainButton.getNativeElement()) {
48377 console.error('FAB container needs a main <button ion-fab>');
48378 return;
48379 }
48380 this._events.listen(mainButton.getNativeElement(), 'click', this.clickHandler.bind(this), { zone: true });
48381 };
48382 /**
48383 * @hidden
48384 * @param {?} ev
48385 * @return {?}
48386 */
48387 FabContainer.prototype.clickHandler = function (ev) {
48388 if (this.canActivateList(ev)) {
48389 this.toggleList();
48390 }
48391 };
48392 /**
48393 * @hidden
48394 * @param {?} ev
48395 * @return {?}
48396 */
48397 FabContainer.prototype.canActivateList = function (ev) {
48398 if (this._fabLists.length > 0 && this._mainButton && ev.target) {
48399 var /** @type {?} */ ele = ev.target.closest('ion-fab>[ion-fab]');
48400 return (ele && ele === this._mainButton.getNativeElement());
48401 }
48402 return false;
48403 };
48404 /**
48405 * @hidden
48406 * @return {?}
48407 */
48408 FabContainer.prototype.toggleList = function () {
48409 this.setActiveLists(!this._listsActive);
48410 };
48411 /**
48412 * @hidden
48413 * @param {?} isActive
48414 * @return {?}
48415 */
48416 FabContainer.prototype.setActiveLists = function (isActive) {
48417 if (isActive === this._listsActive) {
48418 return;
48419 }
48420 var /** @type {?} */ lists = this._fabLists.toArray();
48421 for (var _i = 0, lists_1 = lists; _i < lists_1.length; _i++) {
48422 var list = lists_1[_i];
48423 list.setVisible(isActive);
48424 }
48425 this._mainButton.setActiveClose(isActive);
48426 this._listsActive = isActive;
48427 };
48428 /**
48429 * Close an active FAB list container
48430 * @return {?}
48431 */
48432 FabContainer.prototype.close = function () {
48433 this.setActiveLists(false);
48434 };
48435 /**
48436 * @hidden
48437 * @return {?}
48438 */
48439 FabContainer.prototype.ngOnDestroy = function () {
48440 this._events.destroy();
48441 };
48442 return FabContainer;
48443}());
48444FabContainer.decorators = [
48445 { type: Component, args: [{
48446 selector: 'ion-fab',
48447 template: '<ng-content></ng-content>'
48448 },] },
48449];
48450/**
48451 * @nocollapse
48452 */
48453FabContainer.ctorParameters = function () { return [
48454 { type: Platform, },
48455]; };
48456FabContainer.propDecorators = {
48457 '_mainButton': [{ type: ContentChild, args: [FabButton,] },],
48458 '_fabLists': [{ type: ContentChildren, args: [FabList,] },],
48459};
48460
48461/**
48462 * \@name Col
48463 * \@module ionic
48464 * \@description
48465 *
48466 * Columns are cellular components of the [grid](../Grid) system and go inside of a [row](../Row).
48467 * They will expand to fill their row. All content within a grid should go inside of a column.
48468 *
48469 * ## Column attributes
48470 *
48471 * By default, columns will stretch to fill the entire height of the row.
48472 * There are several attributes that can be added to a column to customize this behavior.
48473 *
48474 * | Property | Description |
48475 * |-----------------------|-------------------------------------------------------------------------------------------------------------|
48476 * | align-self-start | Adds `align-self: flex-start`. The column will be vertically aligned at the top. |
48477 * | align-self-center | Adds `align-self: center`. The column will be vertically aligned in the center. |
48478 * | align-self-end | Adds `align-self: flex-end`. The column will be vertically aligned at the bottom. |
48479 * | align-self-stretch | Adds `align-self: stretch`. The column will be stretched to take up the entire height of the row. |
48480 * | align-self-baseline | Adds `align-self: baseline`. The column will be vertically aligned at its baseline. |
48481 *
48482 *
48483 */
48484var Col = (function () {
48485 function Col() {
48486 }
48487 return Col;
48488}());
48489Col.decorators = [
48490 { type: Directive, args: [{
48491 selector: 'ion-col, [ion-col]',
48492 host: {
48493 'class': 'col'
48494 }
48495 },] },
48496];
48497/**
48498 * @nocollapse
48499 */
48500Col.ctorParameters = function () { return []; };
48501
48502/**
48503 * \@name Grid
48504 * \@module ionic
48505 * \@description
48506 *
48507 * The grid is a powerful mobile-first flexbox system for building custom layouts.
48508 * It is heavily influenced by [Bootstrap's grid system](http://v4-alpha.getbootstrap.com/layout/grid/).
48509 *
48510 * The grid is composed of three units — a grid, row(s) and column(s). Columns will expand to fill their
48511 * row, and will resize to fit additional columns. It is based on a 12 column layout with different
48512 * breakpoints based on the screen size. The number of columns and breakpoints can be fully customized
48513 * using Sass.
48514 *
48515 * - [How it works](#how-it-works)
48516 * - [Grid size](#grid-size)
48517 * - [Grid attributes](#grid-attributes)
48518 * - [Default breakpoints](#default-breakpoints)
48519 * - [Auto-layout columns](#auto-layout-columns)
48520 * - [Equal-width](#equal-width)
48521 * - [Setting one column width](#setting-one-column-width)
48522 * - [Variable-width](#variable-width)
48523 * - [Responsive attributes](#responsive-attributes)
48524 * - [All breakpoints](#all-breakpoints)
48525 * - [Stacked to horizontal](#stacked-to-horizontal)
48526 * - [Reordering](#reordering)
48527 * - [Offsetting columns](#offsetting-columns)
48528 * - [Push and pull](#push-and-pull)
48529 * - [Alignment](#alignment)
48530 * - [Vertical Alignment](#vertical-alignment)
48531 * - [Horizontal Alignment](#horizontal-alignment)
48532 * - [Customizing the grid](#customizing-the-grid)
48533 * - [Number of columns and padding](#number-of-columns-and-padding)
48534 * - [Grid tiers](#grid-tiers)
48535 *
48536 *
48537 * ## How it works
48538 *
48539 * The grid is a mobile-first system made up of any number of rows and columns.
48540 * It is built with flexbox making it extremely responsive. The components that
48541 * make up the grid can be written as an element (e.g., `<ion-grid>`) or added as
48542 * an attribute to any element (e.g., `<div ion-row>`).
48543 *
48544 * Here's how it works:
48545 *
48546 * - Grids act as a container for all rows and columns. Grids take up the full width of their container,
48547 * but adding the `fixed` attribute will specify the width per screen size, see [grid size](#grid-size) below.
48548 * - Rows are horizontal groups of columns that line the columns up properly.
48549 * - Content should be placed within columns, and only columns may be immediate children of rows.
48550 * - Grid columns without a specified width will automatically have equal widths.
48551 * For example, four instances of `col-sm` will each automatically be 25% wide for small breakpoints.
48552 * - Column attributes indicate the number of columns to use out of the default 12 per row.
48553 * So, `col-4` can be added in order to have three equal-width columns.
48554 * - Column widths are set as a percentage, so they’re always fluid and sized relative to their parent element.
48555 * - Columns have padding between individual columns, however, the padding can be removed from the grid and
48556 * columns by adding `no-padding` on the grid.
48557 * - There are five grid tiers by default, one for each responsive breakpoint: all breakpoints (extra small),
48558 * small, medium, large, and extra large.
48559 * - Grid tiers are based on minimum widths, meaning they apply to their tier and all those larger than it
48560 * (e.g., `col-sm-4` applies to small, medium, large, and extra large devices).
48561 * - Grids can easily be customized via Sass variables. See [customizing the grid](#customizing-the-grid).
48562 *
48563 * There are some [known bugs with flexbox](https://github.com/philipwalton/flexbugs) that
48564 * should be checked prior to creating issues with Ionic.
48565 *
48566 * ## Grid size
48567 *
48568 * By default, the grid will take up 100% width. To set a maximum width based on the screen
48569 * size add the `fixed` attribute. The maximum width of the grid for each breakpoint is defined
48570 * in the `$grid-max-widths` Sass variable. For more information, see
48571 * [customizing the grid](#customizing-the-grid).
48572 *
48573 * | Name | Value | Description |
48574 * |----------|----------|-----------------------------------------------------|
48575 * | xs | auto | Don't set the grid width for xs screens |
48576 * | sm | 540px | Set grid width to 540px when (min-width: 576px) |
48577 * | md | 720px | Set grid width to 720px when (min-width: 768px) |
48578 * | lg | 960px | Set grid width to 960px when (min-width: 992px) |
48579 * | xl | 1140px | Set grid width to 1140px when (min-width: 1200px) |
48580 *
48581 *
48582 * ## Grid attributes
48583 *
48584 * The grid takes up full width and has padding added to it based on the screen size. There are two
48585 * attributes that can be used to adjust this behavior.
48586 *
48587 * | Property | Description |
48588 * |-----------------|-------------------------------------------------------------------------------------------------------------------|
48589 * | no-padding | Removes padding from the grid and immediate children columns. |
48590 * | fixed | Set a max width based on the screen size. |
48591 *
48592 *
48593 * ## Default breakpoints
48594 *
48595 * The default breakpoints are defined by the `$grid-breakpoints` Sass variable. It can be
48596 * customized to use different values for the breakpoint, rename and add/remove breakpoints.
48597 * For more information, see [customizing the grid](#customizing-the-grid).
48598 *
48599 * | Name | Value | Width Prefix | Offset Prefix | Push Prefix | Pull Prefix | Description |
48600 * |----------|----------|--------------|---------------|--------------|-------------|---------------------------------------------------|
48601 * | xs | 0 | `col-` | `offset-` | `push-` | `pull-` | Set columns when (min-width: 0) |
48602 * | sm | 576px | `col-sm-` | `offset-sm-` | `push-sm-` | `pull-sm-` | Set columns when (min-width: 576px) |
48603 * | md | 768px | `col-md-` | `offset-md-` | `push-md-` | `pull-md-` | Set columns when (min-width: 768px) |
48604 * | lg | 992px | `col-lg-` | `offset-lg-` | `push-lg-` | `pull-lg-` | Set columns when (min-width: 992px) |
48605 * | xl | 1200px | `col-xl-` | `offset-xl-` | `push-xl-` | `pull-xl-` | Set columns when (min-width: 1200px) |
48606 *
48607 * _Note: the first breakpoint must have the value set to 0 and all breakpoint values must be in
48608 * ascending order._
48609 *
48610 * ## Auto-layout columns
48611 *
48612 * ### Equal-width
48613 *
48614 * By default, columns will take up equal width inside of a row for all devices and screen sizes.
48615 *
48616 * ```
48617 * <ion-grid>
48618 * <ion-row>
48619 * <ion-col>
48620 * 1 of 2
48621 * </ion-col>
48622 * <ion-col>
48623 * 2 of 2
48624 * </ion-col>
48625 * </ion-row>
48626 * <ion-row>
48627 * <ion-col>
48628 * 1 of 3
48629 * </ion-col>
48630 * <ion-col>
48631 * 2 of 3
48632 * </ion-col>
48633 * <ion-col>
48634 * 3 of 3
48635 * </ion-col>
48636 * </ion-row>
48637 * </ion-grid>
48638 * ```
48639 *
48640 * ### Setting one column width
48641 *
48642 * Set the width of one column and the others will automatically resize around it.
48643 * This can be done using our predefined grid attributes. In the example below,
48644 * the other columns will resize no matter the width of the center column.
48645 *
48646 * ```
48647 * <ion-grid>
48648 * <ion-row>
48649 * <ion-col>
48650 * 1 of 3
48651 * </ion-col>
48652 * <ion-col col-8>
48653 * 2 of 3 (wider)
48654 * </ion-col>
48655 * <ion-col>
48656 * 3 of 3
48657 * </ion-col>
48658 * </ion-row>
48659 * <ion-row>
48660 * <ion-col>
48661 * 1 of 3
48662 * </ion-col>
48663 * <ion-col col-6>
48664 * 2 of 3 (wider)
48665 * </ion-col>
48666 * <ion-col>
48667 * 3 of 3
48668 * </ion-col>
48669 * </ion-row>
48670 * </ion-grid>
48671 * ```
48672 *
48673 * ### Variable-width
48674 *
48675 * Using the `col-{breakpoint}-auto` attributes, the column can size itself based on the
48676 * natural width of its content. This is extremely useful for setting a column width
48677 * using pixels. The columns next to the variable-width column will resize to fill the row.
48678 *
48679 * ```
48680 * <ion-grid>
48681 * <ion-row>
48682 * <ion-col>
48683 * 1 of 3
48684 * </ion-col>
48685 * <ion-col col-auto>
48686 * Variable width content
48687 * </ion-col>
48688 * <ion-col>
48689 * 3 of 3
48690 * </ion-col>
48691 * </ion-row>
48692 * <ion-row>
48693 * <ion-col>
48694 * 1 of 4
48695 * </ion-col>
48696 * <ion-col>
48697 * 2 of 4
48698 * </ion-col>
48699 * <ion-col col-auto>
48700 * <ion-input placeholder="Variable width input"></ion-input>
48701 * </ion-col>
48702 * <ion-col>
48703 * 4 of 4
48704 * </ion-col>
48705 * </ion-row>
48706 * </ion-grid>
48707 * ```
48708 *
48709 *
48710 * ## Responsive attributes
48711 *
48712 * ### All breakpoints
48713 *
48714 * To customize a column's width for all devices and screens, add the `col-*`
48715 * attribute. These attributes tell the column to take up `*` columns out
48716 * of the available columns.
48717 *
48718 * ```
48719 * <ion-grid>
48720 * <ion-row>
48721 * <ion-col col-4>
48722 * 1 of 4
48723 * </ion-col>
48724 * <ion-col col-2>
48725 * 2 of 4
48726 * </ion-col>
48727 * <ion-col col-2>
48728 * 3 of 4
48729 * </ion-col>
48730 * <ion-col col-4>
48731 * 4 of 4
48732 * </ion-col>
48733 * </ion-row>
48734 * </ion-grid>
48735 * ```
48736 *
48737 * ### Stacked to horizontal
48738 *
48739 * Use a combination of width and breakpoint attributes to create a grid that starts out stacked
48740 * on extra small screens before becoming horizontal on small screens.
48741 *
48742 * ```
48743 * <ion-grid>
48744 * <ion-row>
48745 * <ion-col col-12 col-sm>
48746 * 1 of 4
48747 * </ion-col>
48748 * <ion-col col-12 col-sm>
48749 * 2 of 4
48750 * </ion-col>
48751 * <ion-col col-12 col-sm>
48752 * 3 of 4
48753 * </ion-col>
48754 * <ion-col col-12 col-sm>
48755 * 4 of 4
48756 * </ion-col>
48757 * </ion-row>
48758 * </ion-grid>
48759 * ```
48760 *
48761 *
48762 * ## Reordering
48763 *
48764 * ### Offsetting columns
48765 *
48766 * Move columns to the right by adding the `offset-*` attributes. These attributes
48767 * increase the margin start of the column by `*` columns. For example, in the following
48768 * grid the last column will be offset by 3 columns and take up 3 columns:
48769 *
48770 * ```
48771 * <ion-grid>
48772 * <ion-row>
48773 * <ion-col col-3>
48774 * 1 of 2
48775 * </ion-col>
48776 * <ion-col col-3 offset-3>
48777 * 2 of 2
48778 * </ion-col>
48779 * </ion-row>
48780 * </ion-grid>
48781 * ```
48782 *
48783 * Offsets can also be added based on screen breakpoints. Here's an example of a
48784 * grid where the last column will be offset by 3 columns for `md` screens and up:
48785 *
48786 * ```
48787 * <ion-grid>
48788 * <ion-row>
48789 * <ion-col col-md-3>
48790 * 1 of 3
48791 * </ion-col>
48792 * <ion-col col-md-3>
48793 * 2 of 3
48794 * </ion-col>
48795 * <ion-col col-md-3 offset-md-3>
48796 * 3 of 3
48797 * </ion-col>
48798 * </ion-row>
48799 * </ion-grid>
48800 * ```
48801 *
48802 * ### Push and pull
48803 *
48804 * Reorder the columns by adding the `push-*` and `pull-*` attributes. These attributes
48805 * adjust the `left` and `right` of the columns by `*` columns making it easy to reorder
48806 * columns. For example, in the following grid the column with the `1st col` description
48807 * will actually be the last column and the `2nd col` will be the first column.
48808 *
48809 * ```
48810 * <ion-grid>
48811 * <ion-row>
48812 * <ion-col col-9 push-3>
48813 * 1 of 2
48814 * </ion-col>
48815 * <ion-col col-3 pull-9>
48816 * 2 of 2
48817 * </ion-col>
48818 * </ion-row>
48819 * </ion-grid>
48820 * ```
48821 *
48822 * Push and pull can also be added based on screen breakpoints. In the following example,
48823 * the column with the `3rd` column description will actually be the first column for
48824 * `md` screens and up:
48825 *
48826 * ```
48827 * <ion-grid>
48828 * <ion-row>
48829 * <ion-col col-md-6 push-md-3>
48830 * 1 of 3
48831 * </ion-col>
48832 * <ion-col col-md-3 push-md-3>
48833 * 2 of 3
48834 * </ion-col>
48835 * <ion-col col-md-3 pull-md-9>
48836 * 3 of 3
48837 * </ion-col>
48838 * </ion-row>
48839 * </ion-grid>
48840 * ```
48841 *
48842 *
48843 * ## Alignment
48844 *
48845 * ### Vertical alignment
48846 *
48847 * All columns can be vertically aligned inside of a row by adding different
48848 * attributes to the row. For a list of available attributes, see
48849 * [row attributes](../Row#row-attributes).
48850 *
48851 * ```
48852 * <ion-grid>
48853 * <ion-row align-items-start>
48854 * <ion-col>
48855 * 1 of 4
48856 * </ion-col>
48857 * <ion-col>
48858 * 2 of 4
48859 * </ion-col>
48860 * <ion-col>
48861 * 3 of 4
48862 * </ion-col>
48863 * <ion-col>
48864 * 4 of 4 <br>#<br>#<br>#
48865 * </ion-col>
48866 * </ion-row>
48867 *
48868 * <ion-row align-items-center>
48869 * <ion-col>
48870 * 1 of 4
48871 * </ion-col>
48872 * <ion-col>
48873 * 2 of 4
48874 * </ion-col>
48875 * <ion-col>
48876 * 3 of 4
48877 * </ion-col>
48878 * <ion-col>
48879 * 4 of 4 <br>#<br>#<br>#
48880 * </ion-col>
48881 * </ion-row>
48882 *
48883 * <ion-row align-items-end>
48884 * <ion-col>
48885 * 1 of 4
48886 * </ion-col>
48887 * <ion-col>
48888 * 2 of 4
48889 * </ion-col>
48890 * <ion-col>
48891 * 3 of 4
48892 * </ion-col>
48893 * <ion-col>
48894 * 4 of 4 <br>#<br>#<br>#
48895 * </ion-col>
48896 * </ion-row>
48897 * </ion-grid>
48898 * ```
48899 *
48900 * Columns can also align themselves differently than other columns by
48901 * adding the alignment attribute directly to the column. For a list of available
48902 * attributes, see [column attributes](../Col#column-attributes).
48903 *
48904 * ```
48905 * <ion-grid>
48906 * <ion-row>
48907 * <ion-col align-self-start>
48908 * <div>
48909 * 1 of 4
48910 * </div>
48911 * </ion-col>
48912 * <ion-col align-self-center>
48913 * <div>
48914 * 2 of 4
48915 * </div>
48916 * </ion-col>
48917 * <ion-col align-self-end>
48918 * <div>
48919 * 3 of 4
48920 * </div>
48921 * </ion-col>
48922 * <ion-col>
48923 * <div>
48924 * 4 of 4 <br>#<br>#<br>#
48925 * </div>
48926 * </ion-col>
48927 * </ion-row>
48928 * </ion-grid>
48929 * ```
48930 *
48931 * ### Horizontal alignment
48932 *
48933 * All columns can be horizontally aligned inside of a row by adding different
48934 * attributes to the row. For a list of available attributes, see
48935 * [row attributes](../Row#row-attributes).
48936 *
48937 * ```
48938 * <ion-grid>
48939 * <ion-row justify-content-start>
48940 * <ion-col col-3>
48941 * 1 of 2
48942 * </ion-col>
48943 * <ion-col col-3>
48944 * 2 of 2
48945 * </ion-col>
48946 * </ion-row>
48947 *
48948 * <ion-row justify-content-center>
48949 * <ion-col col-3>
48950 * 1 of 2
48951 * </ion-col>
48952 * <ion-col col-3>
48953 * 2 of 2
48954 * </ion-col>
48955 * </ion-row>
48956 *
48957 * <ion-row justify-content-end>
48958 * <ion-col col-3>
48959 * 1 of 2
48960 * </ion-col>
48961 * <ion-col col-3>
48962 * 2 of 2
48963 * </ion-col>
48964 * </ion-row>
48965 *
48966 * <ion-row justify-content-around>
48967 * <ion-col col-3>
48968 * 1 of 2
48969 * </ion-col>
48970 * <ion-col col-3>
48971 * 2 of 2
48972 * </ion-col>
48973 * </ion-row>
48974 *
48975 * <ion-row justify-content-between>
48976 * <ion-col col-3>
48977 * 1 of 2
48978 * </ion-col>
48979 * <ion-col col-3>
48980 * 2 of 2
48981 * </ion-col>
48982 * </ion-row>
48983 * </ion-grid>
48984 * ```
48985 *
48986 *
48987 * ## Customizing the grid
48988 *
48989 * Using our built-in grid Sass variables and maps, it’s possible to completely customize
48990 * the predefined grid attributes. Change the number of breakpoints, the media query values,
48991 * the number of columns, and more.
48992 *
48993 * ### Number of columns and padding
48994 *
48995 * The number of grid columns and their padding can be modified via Sass variables.
48996 * `$grid-columns` is used to generate the widths (in percent) of each individual column.
48997 * `$grid-padding-width` is used for the padding on the grid, while `$grid-padding-widths`
48998 * allows breakpoint-specific widths that are divided evenly across `padding-left` and
48999 * `padding-right` as well as `padding-top` and `padding-bottom` of the grid and columns.
49000 *
49001 * ```
49002 * $grid-columns: 12 !default;
49003 *
49004 * $grid-padding-width: 10px !default;
49005 *
49006 * $grid-padding-widths: (
49007 * xs: $grid-padding-width,
49008 * sm: $grid-padding-width,
49009 * md: $grid-padding-width,
49010 * lg: $grid-padding-width,
49011 * xl: $grid-padding-width
49012 * ) !default;
49013 * ```
49014 *
49015 * ### Grid tiers
49016 *
49017 * To customize the breakpoints and their values, override the values of
49018 * `$grid-breakpoints` and `$grid-max-widths`. For example, to only use
49019 * 3 breakpoints, the following could be written:
49020 *
49021 * ```
49022 * $grid-breakpoints: (
49023 * sm: 0,
49024 * md: 768px,
49025 * lg: 1024px
49026 * );
49027 *
49028 * $grid-max-widths: (
49029 * sm: 420px,
49030 * md: 720px,
49031 * lg: 960px
49032 * );
49033 * ```
49034 *
49035 */
49036var Grid = (function () {
49037 function Grid() {
49038 }
49039 return Grid;
49040}());
49041Grid.decorators = [
49042 { type: Directive, args: [{
49043 selector: 'ion-grid, [ion-grid]',
49044 host: {
49045 'class': 'grid'
49046 }
49047 },] },
49048];
49049/**
49050 * @nocollapse
49051 */
49052Grid.ctorParameters = function () { return []; };
49053
49054/**
49055 * \@name Row
49056 * \@module ionic
49057 * \@description
49058 *
49059 * Rows are horizontal components of the [grid](../Grid) system and contain varying numbers of
49060 * [columns](../Col). They ensure the columns are positioned properly.
49061 *
49062 * ## Row attributes
49063 *
49064 * By default, columns will stretch to fill the entire height of the row and wrap when necessary.
49065 * There are several attributes that can be added to a row to customize this behavior.
49066 *
49067 * | Property | Description |
49068 * |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
49069 * | nowrap | Adds `flex-wrap: nowrap`. Forces the columns to a single row. |
49070 * | wrap-reverse | Adds `flex-wrap: wrap-reverse`. The columns will wrap in reverse. |
49071 * | align-items-start | Adds `align-items: flex-start`. All columns will be vertically aligned at the top, unless they specify their own alignment. |
49072 * | align-items-center | Adds `align-items: center`. All columns will be vertically aligned in the center, unless they specify their own alignment. |
49073 * | align-items-end | Adds `align-items: flex-end`. All columns will be vertically aligned at the bottom, unless they specify their own alignment. |
49074 * | align-items-stretch | Adds `align-items: stretch`. All columns will be stretched to take up the entire height of the row, unless they specify their own alignment. |
49075 * | align-items-baseline | Adds `align-items: baseline`. All columns will be vertically aligned at their baselines, unless they specify their own alignment. |
49076 * | justify-content-start | Adds `justify-content: start`. All columns will be horizontally aligned at the start. |
49077 * | justify-content-center | Adds `justify-content: center`. All columns will be horizontally aligned at the center. |
49078 * | justify-content-end | Adds `justify-content: end`. All columns will be horizontally aligned at the end. |
49079 * | justify-content-around | Adds `justify-content: space-around`. All columns will be horizontally aligned with equal space around them. |
49080 * | justify-content-between | Adds `justify-content: space-between`. All columns will be horizontally aligned with a half-size space on either end. |
49081 *
49082 *
49083 */
49084var Row = (function () {
49085 function Row() {
49086 }
49087 return Row;
49088}());
49089Row.decorators = [
49090 { type: Directive, args: [{
49091 selector: 'ion-row, [ion-row]',
49092 host: {
49093 'class': 'row'
49094 }
49095 },] },
49096];
49097/**
49098 * @nocollapse
49099 */
49100Row.ctorParameters = function () { return []; };
49101
49102/**
49103 * \@name Img
49104 * \@description
49105 * Two of the biggest cuprits of scroll jank is starting up a new HTTP
49106 * request, and rendering images. These two reasons is largely why
49107 * `ion-img` was created. The standard HTML `img` element is often a large
49108 * source of these problems, and what makes matters worse is that the app
49109 * does not have fine-grained control of requests and rendering for each
49110 * `img` element.
49111 *
49112 * The `ion-img` component is similar to the standard `img` element,
49113 * but it also adds features in order to provide improved performance.
49114 * Features include only loading images which are visible, using web workers
49115 * for HTTP requests, preventing jank while scrolling and in-memory caching.
49116 *
49117 * Note that `ion-img` also comes with a few more restrictions in comparison
49118 * to the standard `img` element. A good rule is, if there are only a few
49119 * images to be rendered on a page, then the standard `img` is probably
49120 * best. However, if a page has the potential for hundreds or even thousands
49121 * of images within a scrollable area, then `ion-img` would be better suited
49122 * for the job.
49123 *
49124 * > Note: `ion-img` is only meant to be used inside of [virtual-scroll](/docs/api/components/virtual-scroll/VirtualScroll/)
49125 *
49126 *
49127 * ### Lazy Loading
49128 *
49129 * Lazy loading images refers to only loading images which are actually
49130 * visible within the user's viewport. This also means that images which are
49131 * not viewable on the initial load would not be downloaded or rendered. Next,
49132 * as the user scrolls, each image which becomes visible is then requested
49133 * then rendered on-demand.
49134 *
49135 * The benefits of this approach is that unnecessary and resource intensive
49136 * HTTP requests are not started, valuable bandwidth isn't wasted, and this
49137 * allows the browser to free up resources which would be wasted on images
49138 * which are not even viewable. For example, animated GIFs are enourmous
49139 * performance drains, however, with `ion-img` the app is able to dedicate
49140 * resources to just the viewable images. But again, if the problems listed
49141 * above are not problems within your app, then the standard `img` element
49142 * may be best.
49143 *
49144 *
49145 * ### Image Dimensions
49146 *
49147 * By providing image dimensions up front, Ionic is able to accurately size
49148 * up the image's location within the viewport, which helps lazy load only
49149 * images which are viewable. Image dimensions can either by set as
49150 * properties, inline styles, or external stylesheets. It doesn't matter
49151 * which method of setting dimensions is used, but it's important that somehow
49152 * each `ion-img` has been given an exact size.
49153 *
49154 * For example, by default `<ion-avatar>` and `<ion-thumbnail>` already come
49155 * with exact sizes when placed within an `<ion-item>`. By giving each image
49156 * an exact size, this then further locks in the size of each `ion-item`,
49157 * which again helps improve scroll performance.
49158 *
49159 * ```html
49160 * <!-- dimensions set using attributes -->
49161 * <ion-img width="80" height="80" src="..."></ion-img>
49162 *
49163 * <!-- dimensions set using input properties -->
49164 * <ion-img [width]="imgWidth" [height]="imgHeight" src="..."></ion-img>
49165 *
49166 * <!-- dimensions set using inline styles -->
49167 * <ion-img style="width: 80px; height: 80px;" src="..."></ion-img>
49168 * ```
49169 *
49170 * Additionally, each `ion-img` uses the `object-fit: cover` CSS property.
49171 * What this means is that the actual rendered image will center itself within
49172 * it's container. Or to really get detailed: The image is sized to maintain
49173 * its aspect ratio while filling the containing element’s entire content box.
49174 * Its concrete object size is resolved as a cover constraint against the
49175 * element’s used width and height.
49176 *
49177 * ### Future Optimizations
49178 *
49179 * Future goals are to place image requests within web workers, and cache
49180 * images in-memory as datauris. This method has proven to be effective,
49181 * however there are some current limitations with Cordova which we are
49182 * currently working on.
49183 *
49184 */
49185var Img = (function () {
49186 /**
49187 * @param {?} _elementRef
49188 * @param {?} _renderer
49189 * @param {?} _plt
49190 * @param {?} _content
49191 * @param {?} _dom
49192 */
49193 function Img(_elementRef, _renderer, _plt, _content, _dom) {
49194 this._elementRef = _elementRef;
49195 this._renderer = _renderer;
49196 this._plt = _plt;
49197 this._content = _content;
49198 this._dom = _dom;
49199 /**
49200 * \@internal
49201 */
49202 this._cache = true;
49203 /**
49204 * \@internal
49205 */
49206 this._w = '';
49207 /**
49208 * \@internal
49209 */
49210 this._h = '';
49211 /**
49212 * \@internal
49213 */
49214 this._wQ = '';
49215 /**
49216 * \@internal
49217 */
49218 this._hQ = '';
49219 /**
49220 * \@input {string} Set the `alt` attribute which gets assigned to
49221 * the inner `img` element.
49222 */
49223 this.alt = '';
49224 if (!this._content) {
49225 console.warn("ion-img can only be used within an ion-content");
49226 }
49227 else {
49228 this._content.addImg(this);
49229 }
49230 this._isLoaded(false);
49231 }
49232 Object.defineProperty(Img.prototype, "src", {
49233 /**
49234 * \@input {string} The source of the image.
49235 * @return {?}
49236 */
49237 get: function () {
49238 return this._src;
49239 },
49240 /**
49241 * @param {?} newSrc
49242 * @return {?}
49243 */
49244 set: function (newSrc) {
49245 // if the source hasn't changed, then um, let's not change it
49246 if (newSrc !== this._src) {
49247 // we're changing the source
49248 // so abort any active http requests
49249 // and render the image empty
49250 this.reset();
49251 // update to the new src
49252 this._src = newSrc;
49253 // Are they using an actual datauri already,
49254 // or reset any existing datauri we might be holding onto
49255 this._hasLoaded = newSrc.indexOf('data:') === 0;
49256 // run update to kick off requests or render if everything is good
49257 this.update();
49258 }
49259 },
49260 enumerable: true,
49261 configurable: true
49262 });
49263 /**
49264 * @hidden
49265 * @return {?}
49266 */
49267 Img.prototype.reset = function () {
49268 if (this._requestingSrc) {
49269 // abort any active requests
49270 (void 0) /* console.debug */;
49271 this._srcAttr('');
49272 this._requestingSrc = null;
49273 }
49274 if (this._renderedSrc) {
49275 // clear out the currently rendered img
49276 (void 0) /* console.debug */;
49277 this._renderedSrc = null;
49278 this._isLoaded(false);
49279 }
49280 };
49281 /**
49282 * @hidden
49283 * @return {?}
49284 */
49285 Img.prototype.update = function () {
49286 var _this = this;
49287 // only attempt an update if there is an active src
49288 // and the content containing the image considers it updatable
49289 if (this._src && this._content.isImgsUpdatable()) {
49290 if (this.canRequest && (this._src !== this._renderedSrc && this._src !== this._requestingSrc) && !this._hasLoaded) {
49291 // only begin the request if we "can" request
49292 // begin the image request if the src is different from the rendered src
49293 // and if we don't already has a tmpDataUri
49294 (void 0) /* console.debug */;
49295 this._requestingSrc = this._src;
49296 this._isLoaded(false);
49297 this._srcAttr(this._src);
49298 // set the dimensions of the image if we do have different data
49299 this._setDims();
49300 }
49301 if (this.canRender && this._hasLoaded && this._src !== this._renderedSrc) {
49302 // we can render and we have a datauri to render
49303 this._renderedSrc = this._src;
49304 this._setDims();
49305 this._dom.write(function () {
49306 if (_this._hasLoaded) {
49307 (void 0) /* console.debug */;
49308 _this._isLoaded(true);
49309 _this._srcAttr(_this._src);
49310 }
49311 });
49312 }
49313 }
49314 };
49315 /**
49316 * \@internal
49317 * @param {?} isLoaded
49318 * @return {?}
49319 */
49320 Img.prototype._isLoaded = function (isLoaded) {
49321 var /** @type {?} */ renderer = this._renderer;
49322 var /** @type {?} */ ele = this._elementRef.nativeElement;
49323 renderer.setElementClass(ele, 'img-loaded', isLoaded);
49324 renderer.setElementClass(ele, 'img-unloaded', !isLoaded);
49325 };
49326 /**
49327 * \@internal
49328 * @param {?} srcAttr
49329 * @return {?}
49330 */
49331 Img.prototype._srcAttr = function (srcAttr) {
49332 var /** @type {?} */ imgEle = this._img;
49333 var /** @type {?} */ renderer = this._renderer;
49334 if (imgEle && imgEle.src !== srcAttr) {
49335 renderer.setElementAttribute(this._img, 'src', srcAttr);
49336 renderer.setElementAttribute(this._img, 'alt', this.alt);
49337 }
49338 };
49339 Object.defineProperty(Img.prototype, "top", {
49340 /**
49341 * @hidden
49342 * @return {?}
49343 */
49344 get: function () {
49345 var /** @type {?} */ bounds = this._getBounds();
49346 return bounds && bounds.top || 0;
49347 },
49348 enumerable: true,
49349 configurable: true
49350 });
49351 Object.defineProperty(Img.prototype, "bottom", {
49352 /**
49353 * @hidden
49354 * @return {?}
49355 */
49356 get: function () {
49357 var /** @type {?} */ bounds = this._getBounds();
49358 return bounds && bounds.bottom || 0;
49359 },
49360 enumerable: true,
49361 configurable: true
49362 });
49363 /**
49364 * @return {?}
49365 */
49366 Img.prototype._getBounds = function () {
49367 if (this._bounds) {
49368 // we've been manually passed bounds data
49369 // this is probably from Virtual Scroll items
49370 return this._bounds;
49371 }
49372 if (!this._rect) {
49373 // we don't have bounds from virtual scroll
49374 // so let's do the raw DOM lookup w/ getBoundingClientRect
49375 this._rect = ((this._elementRef.nativeElement)).getBoundingClientRect();
49376 (void 0) /* console.debug */;
49377 }
49378 return this._rect;
49379 };
49380 Object.defineProperty(Img.prototype, "bounds", {
49381 /**
49382 * \@input {any} Sets the bounding rectangle of the element relative to the viewport.
49383 * When using `VirtualScroll`, each virtual item should pass its bounds to each
49384 * `ion-img`. The passed in data object should include `top` and `bottom` properties.
49385 * @param {?} b
49386 * @return {?}
49387 */
49388 set: function (b) {
49389 if (isPresent(b)) {
49390 this._bounds = b;
49391 }
49392 },
49393 enumerable: true,
49394 configurable: true
49395 });
49396 Object.defineProperty(Img.prototype, "cache", {
49397 /**
49398 * \@input {boolean} After an image has been successfully downloaded, it can be cached
49399 * in-memory. This is useful for `VirtualScroll` by allowing image responses to be
49400 * cached, and not rendered, until after scrolling has completed, which allows for
49401 * smoother scrolling.
49402 * @return {?}
49403 */
49404 get: function () {
49405 return this._cache;
49406 },
49407 /**
49408 * @param {?} val
49409 * @return {?}
49410 */
49411 set: function (val) {
49412 this._cache = isTrueProperty(val);
49413 },
49414 enumerable: true,
49415 configurable: true
49416 });
49417 Object.defineProperty(Img.prototype, "width", {
49418 /**
49419 * \@input {string} Image width. If this property is not set it's important that
49420 * the dimensions are still set using CSS. If the dimension is just a number it
49421 * will assume the `px` unit.
49422 * @param {?} val
49423 * @return {?}
49424 */
49425 set: function (val) {
49426 this._wQ = getUnitValue(val);
49427 this._setDims();
49428 },
49429 enumerable: true,
49430 configurable: true
49431 });
49432 Object.defineProperty(Img.prototype, "height", {
49433 /**
49434 * \@input {string} Image height. If this property is not set it's important that
49435 * the dimensions are still set using CSS. If the dimension is just a number it
49436 * will assume the `px` unit.
49437 * @param {?} val
49438 * @return {?}
49439 */
49440 set: function (val) {
49441 this._hQ = getUnitValue(val);
49442 this._setDims();
49443 },
49444 enumerable: true,
49445 configurable: true
49446 });
49447 /**
49448 * @return {?}
49449 */
49450 Img.prototype._setDims = function () {
49451 var _this = this;
49452 // only set the dimensions if we can render
49453 // and only if the dimensions have changed from when we last set it
49454 if (this.canRender && (this._w !== this._wQ || this._h !== this._hQ)) {
49455 var /** @type {?} */ wrapperEle = this._elementRef.nativeElement;
49456 var /** @type {?} */ renderer = this._renderer;
49457 this._dom.write(function () {
49458 if (_this._w !== _this._wQ) {
49459 _this._w = _this._wQ;
49460 renderer.setElementStyle(wrapperEle, 'width', _this._w);
49461 }
49462 if (_this._h !== _this._hQ) {
49463 _this._h = _this._hQ;
49464 renderer.setElementStyle(wrapperEle, 'height', _this._h);
49465 }
49466 });
49467 }
49468 };
49469 /**
49470 * @hidden
49471 * @return {?}
49472 */
49473 Img.prototype.ngAfterContentInit = function () {
49474 var _this = this;
49475 this._img = this._elementRef.nativeElement.firstChild;
49476 this._unreg = this._plt.registerListener(this._img, 'load', function () {
49477 _this._hasLoaded = true;
49478 _this.update();
49479 }, { passive: true });
49480 };
49481 /**
49482 * @hidden
49483 * @return {?}
49484 */
49485 Img.prototype.ngOnDestroy = function () {
49486 this._unreg && this._unreg();
49487 this._content && this._content.removeImg(this);
49488 };
49489 return Img;
49490}());
49491Img.decorators = [
49492 { type: Component, args: [{
49493 selector: 'ion-img',
49494 template: '<img>',
49495 changeDetection: ChangeDetectionStrategy.OnPush,
49496 encapsulation: ViewEncapsulation.None,
49497 },] },
49498];
49499/**
49500 * @nocollapse
49501 */
49502Img.ctorParameters = function () { return [
49503 { type: ElementRef, },
49504 { type: Renderer, },
49505 { type: Platform, },
49506 { type: Content, decorators: [{ type: Optional },] },
49507 { type: DomController, },
49508]; };
49509Img.propDecorators = {
49510 'src': [{ type: Input },],
49511 'bounds': [{ type: Input },],
49512 'cache': [{ type: Input },],
49513 'width': [{ type: Input },],
49514 'height': [{ type: Input },],
49515 'alt': [{ type: Input },],
49516};
49517/**
49518 * @param {?} val
49519 * @return {?}
49520 */
49521function getUnitValue(val) {
49522 if (isPresent(val)) {
49523 if (typeof val === 'string') {
49524 if (val.indexOf('%') > -1 || val.indexOf('px') > -1) {
49525 return val;
49526 }
49527 if (val.length) {
49528 return val + 'px';
49529 }
49530 }
49531 else if (typeof val === 'number') {
49532 return val + 'px';
49533 }
49534 }
49535 return '';
49536}
49537
49538/**
49539 * \@name InfiniteScroll
49540 * \@description
49541 * The Infinite Scroll allows you to perform an action when the user
49542 * scrolls a specified distance from the bottom or top of the page.
49543 *
49544 * The expression assigned to the `infinite` event is called when
49545 * the user scrolls to the specified distance. When this expression
49546 * has finished its tasks, it should call the `complete()` method
49547 * on the infinite scroll instance.
49548 *
49549 * \@usage
49550 * ```html
49551 * <ion-content>
49552 *
49553 * <ion-list>
49554 * <ion-item *ngFor="let i of items">{% raw %}{{i}}{% endraw %}</ion-item>
49555 * </ion-list>
49556 *
49557 * <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
49558 * <ion-infinite-scroll-content></ion-infinite-scroll-content>
49559 * </ion-infinite-scroll>
49560 *
49561 * </ion-content>
49562 * ```
49563 *
49564 * ```ts
49565 * \@Component({...})
49566 * export class NewsFeedPage {
49567 * items = [];
49568 *
49569 * constructor() {
49570 * for (let i = 0; i < 30; i++) {
49571 * this.items.push( this.items.length );
49572 * }
49573 * }
49574 *
49575 * doInfinite(infiniteScroll) {
49576 * console.log('Begin async operation');
49577 *
49578 * setTimeout(() => {
49579 * for (let i = 0; i < 30; i++) {
49580 * this.items.push( this.items.length );
49581 * }
49582 *
49583 * console.log('Async operation has ended');
49584 * infiniteScroll.complete();
49585 * }, 500);
49586 * }
49587 *
49588 * }
49589 * ```
49590 *
49591 * ## `waitFor` method of InfiniteScroll
49592 *
49593 * In case if your async operation returns promise you can utilize
49594 * `waitFor` method inside your template.
49595 *
49596 * ```html
49597 * <ion-content>
49598 *
49599 * <ion-list>
49600 * <ion-item *ngFor="let item of items">{{item}}</ion-item>
49601 * </ion-list>
49602 *
49603 * <ion-infinite-scroll (ionInfinite)="$event.waitFor(doInfinite())">
49604 * <ion-infinite-scroll-content></ion-infinite-scroll-content>
49605 * </ion-infinite-scroll>
49606 *
49607 * </ion-content>
49608 * ```
49609 *
49610 * ```ts
49611 * \@Component({...})
49612 * export class NewsFeedPage {
49613 * items = [];
49614 *
49615 * constructor() {
49616 * for (var i = 0; i < 30; i++) {
49617 * this.items.push( this.items.length );
49618 * }
49619 * }
49620 *
49621 * doInfinite(): Promise<any> {
49622 * console.log('Begin async operation');
49623 *
49624 * return new Promise((resolve) => {
49625 * setTimeout(() => {
49626 * for (var i = 0; i < 30; i++) {
49627 * this.items.push( this.items.length );
49628 * }
49629 *
49630 * console.log('Async operation has ended');
49631 * resolve();
49632 * }, 500);
49633 * })
49634 * }
49635 * }
49636 * ```
49637 *
49638 * ## Infinite Scroll Content
49639 *
49640 * By default, Ionic uses the infinite scroll spinner that looks
49641 * best for the platform the user is on. However, you can change the
49642 * default spinner or add text by adding properties to the
49643 * `ion-infinite-scroll-content` component.
49644 *
49645 * ```html
49646 * <ion-content>
49647 *
49648 * <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
49649 * <ion-infinite-scroll-content
49650 * loadingSpinner="bubbles"
49651 * loadingText="Loading more data...">
49652 * </ion-infinite-scroll-content>
49653 * </ion-infinite-scroll>
49654 *
49655 * </ion-content>
49656 * ```
49657 *
49658 *
49659 * ## Further Customizing Infinite Scroll Content
49660 *
49661 * The `ion-infinite-scroll` component holds the infinite scroll logic.
49662 * It requires a child component in order to display the content.
49663 * Ionic uses `ion-infinite-scroll-content` by default. This component
49664 * displays the infinite scroll and changes the look depending
49665 * on the infinite scroll's state. Separating these components allows
49666 * developers to create their own infinite scroll content components.
49667 * You could replace our default content with custom SVG or CSS animations.
49668 *
49669 * \@demo /docs/demos/src/infinite-scroll/
49670 *
49671 */
49672var InfiniteScroll = (function () {
49673 /**
49674 * @param {?} _content
49675 * @param {?} _zone
49676 * @param {?} _elementRef
49677 * @param {?} _dom
49678 */
49679 function InfiniteScroll(_content, _zone, _elementRef, _dom) {
49680 this._content = _content;
49681 this._zone = _zone;
49682 this._elementRef = _elementRef;
49683 this._dom = _dom;
49684 this._lastCheck = 0;
49685 this._highestY = 0;
49686 this._thr = '15%';
49687 this._thrPx = 0;
49688 this._thrPc = 0.15;
49689 this._position = POSITION_BOTTOM;
49690 this._init = false;
49691 /**
49692 * \@internal
49693 */
49694 this.state = STATE_ENABLED;
49695 /**
49696 * \@output {event} Emitted when the scroll reaches
49697 * the threshold distance. From within your infinite handler,
49698 * you must call the infinite scroll's `complete()` method when
49699 * your async operation has completed.
49700 */
49701 this.ionInfinite = new EventEmitter();
49702 _content.setElementClass('has-infinite-scroll', true);
49703 }
49704 Object.defineProperty(InfiniteScroll.prototype, "threshold", {
49705 /**
49706 * \@input {string} The threshold distance from the bottom
49707 * of the content to call the `infinite` output event when scrolled.
49708 * The threshold value can be either a percent, or
49709 * in pixels. For example, use the value of `10%` for the `infinite`
49710 * output event to get called when the user has scrolled 10%
49711 * from the bottom of the page. Use the value `100px` when the
49712 * scroll is within 100 pixels from the bottom of the page.
49713 * Default is `15%`.
49714 * @return {?}
49715 */
49716 get: function () {
49717 return this._thr;
49718 },
49719 /**
49720 * @param {?} val
49721 * @return {?}
49722 */
49723 set: function (val) {
49724 this._thr = val;
49725 if (val.indexOf('%') > -1) {
49726 this._thrPx = 0;
49727 this._thrPc = (parseFloat(val) / 100);
49728 }
49729 else {
49730 this._thrPx = parseFloat(val);
49731 this._thrPc = 0;
49732 }
49733 },
49734 enumerable: true,
49735 configurable: true
49736 });
49737 Object.defineProperty(InfiniteScroll.prototype, "enabled", {
49738 /**
49739 * \@input {boolean} If true, Whether or not the infinite scroll should be
49740 * enabled or not. Setting to `false` will remove scroll event listeners
49741 * and hide the display.
49742 * @param {?} shouldEnable
49743 * @return {?}
49744 */
49745 set: function (shouldEnable) {
49746 this.enable(shouldEnable);
49747 },
49748 enumerable: true,
49749 configurable: true
49750 });
49751 Object.defineProperty(InfiniteScroll.prototype, "position", {
49752 /**
49753 * \@input {string} The position of the infinite scroll element.
49754 * The value can be either `top` or `bottom`.
49755 * Default is `bottom`.
49756 * @return {?}
49757 */
49758 get: function () {
49759 return this._position;
49760 },
49761 /**
49762 * @param {?} val
49763 * @return {?}
49764 */
49765 set: function (val) {
49766 if (val === POSITION_TOP || val === POSITION_BOTTOM) {
49767 this._position = val;
49768 }
49769 else {
49770 console.error("Invalid value for ion-infinite-scroll's position input. Its value should be '" + POSITION_BOTTOM + "' or '" + POSITION_TOP + "'.");
49771 }
49772 },
49773 enumerable: true,
49774 configurable: true
49775 });
49776 /**
49777 * @param {?} ev
49778 * @return {?}
49779 */
49780 InfiniteScroll.prototype._onScroll = function (ev) {
49781 var _this = this;
49782 if (this.state === STATE_LOADING || this.state === STATE_DISABLED) {
49783 return 1;
49784 }
49785 if (this._lastCheck + 32 > ev.timeStamp) {
49786 // no need to check less than every XXms
49787 return 2;
49788 }
49789 this._lastCheck = ev.timeStamp;
49790 // ******** DOM READ ****************
49791 var /** @type {?} */ infiniteHeight = this._elementRef.nativeElement.scrollHeight;
49792 if (!infiniteHeight) {
49793 // if there is no height of this element then do nothing
49794 return 3;
49795 }
49796 // ******** DOM READ ****************
49797 var /** @type {?} */ d = this._content.getContentDimensions();
49798 var /** @type {?} */ height = d.contentHeight;
49799 var /** @type {?} */ threshold = this._thrPc ? (height * this._thrPc) : this._thrPx;
49800 // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
49801 var /** @type {?} */ distanceFromInfinite;
49802 if (this._position === POSITION_BOTTOM) {
49803 distanceFromInfinite = d.scrollHeight - infiniteHeight - d.scrollTop - height - threshold;
49804 }
49805 else {
49806 (void 0) /* assert */;
49807 distanceFromInfinite = d.scrollTop - infiniteHeight - threshold;
49808 }
49809 if (distanceFromInfinite < 0) {
49810 // ******** DOM WRITE ****************
49811 this._dom.write(function () {
49812 _this._zone.run(function () {
49813 if (_this.state !== STATE_LOADING && _this.state !== STATE_DISABLED) {
49814 _this.state = STATE_LOADING;
49815 _this.ionInfinite.emit(_this);
49816 }
49817 });
49818 });
49819 return 5;
49820 }
49821 return 6;
49822 };
49823 /**
49824 * Call `complete()` within the `infinite` output event handler when
49825 * your async operation has completed. For example, the `loading`
49826 * state is while the app is performing an asynchronous operation,
49827 * such as receiving more data from an AJAX request to add more items
49828 * to a data list. Once the data has been received and UI updated, you
49829 * then call this method to signify that the loading has completed.
49830 * This method will change the infinite scroll's state from `loading`
49831 * to `enabled`.
49832 * @return {?}
49833 */
49834 InfiniteScroll.prototype.complete = function () {
49835 var _this = this;
49836 if (this.state !== STATE_LOADING) {
49837 return;
49838 }
49839 if (this._position === POSITION_BOTTOM) {
49840 this.state = STATE_ENABLED;
49841 return;
49842 }
49843 (void 0) /* assert */;
49844 /* New content is being added at the top, but the scrollTop position stays the same,
49845 which causes a scroll jump visually. This algorithm makes sure to prevent this.
49846
49847 (Frame 1)
49848 complete() is called, but the UI hasn't had time to update yet.
49849 Save the current content dimensions.
49850 Wait for the next frame using _dom.read, so the UI will be updated.
49851
49852 (Frame 2)
49853 Read the new content dimensions.
49854 Calculate the height difference and the new scroll position.
49855 Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
49856
49857 (Still frame 2, if I'm correct)
49858 Change the scroll position (= visually maintain the scroll position).
49859 Change the state to re-enable the InfiniteScroll. This should be after changing the scroll position, or it could cause the InfiniteScroll to be triggered again immediately.
49860
49861 (Frame 3)
49862 Done.
49863 */
49864 // ******** DOM READ ****************
49865 // Save the current content dimensions before the UI updates
49866 var /** @type {?} */ prevDim = this._content.getContentDimensions();
49867 // ******** DOM READ ****************
49868 this._dom.read(function () {
49869 // UI has updated, save the new content dimensions
49870 var /** @type {?} */ newDim = _this._content.getContentDimensions();
49871 // New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
49872 var /** @type {?} */ newScrollTop = newDim.scrollHeight - (prevDim.scrollHeight - prevDim.scrollTop);
49873 // ******** DOM WRITE ****************
49874 _this._dom.write(function () {
49875 _this._content.scrollTop = newScrollTop;
49876 _this.state = STATE_ENABLED;
49877 });
49878 });
49879 };
49880 /**
49881 * Pass a promise inside `waitFor()` within the `infinite` output event handler in order to
49882 * change state of infiniteScroll to "complete"
49883 * @param {?} action
49884 * @return {?}
49885 */
49886 InfiniteScroll.prototype.waitFor = function (action) {
49887 var /** @type {?} */ enable = this.complete.bind(this);
49888 action.then(enable, enable);
49889 };
49890 /**
49891 * Call `enable(false)` to disable the infinite scroll from actively
49892 * trying to receive new data while scrolling. This method is useful
49893 * when it is known that there is no more data that can be added, and
49894 * the infinite scroll is no longer needed.
49895 * enabled or not. Setting to `false` will remove scroll event listeners
49896 * and hide the display.
49897 * @param {?} shouldEnable
49898 * @return {?}
49899 */
49900 InfiniteScroll.prototype.enable = function (shouldEnable) {
49901 this.state = (shouldEnable ? STATE_ENABLED : STATE_DISABLED);
49902 this._setListeners(shouldEnable);
49903 };
49904 /**
49905 * @hidden
49906 * @param {?} shouldListen
49907 * @return {?}
49908 */
49909 InfiniteScroll.prototype._setListeners = function (shouldListen) {
49910 if (this._init) {
49911 if (shouldListen) {
49912 if (!this._scLsn) {
49913 this._scLsn = this._content.ionScroll.subscribe(this._onScroll.bind(this));
49914 }
49915 }
49916 else {
49917 this._scLsn && this._scLsn.unsubscribe();
49918 this._scLsn = null;
49919 }
49920 }
49921 };
49922 /**
49923 * @hidden
49924 * @return {?}
49925 */
49926 InfiniteScroll.prototype.ngAfterContentInit = function () {
49927 this._init = true;
49928 this._setListeners(this.state !== STATE_DISABLED);
49929 if (this._position === POSITION_TOP) {
49930 this._content.scrollDownOnLoad = true;
49931 }
49932 };
49933 /**
49934 * @hidden
49935 * @return {?}
49936 */
49937 InfiniteScroll.prototype.ngOnDestroy = function () {
49938 this._setListeners(false);
49939 };
49940 return InfiniteScroll;
49941}());
49942InfiniteScroll.decorators = [
49943 { type: Directive, args: [{
49944 selector: 'ion-infinite-scroll'
49945 },] },
49946];
49947/**
49948 * @nocollapse
49949 */
49950InfiniteScroll.ctorParameters = function () { return [
49951 { type: Content, },
49952 { type: NgZone, },
49953 { type: ElementRef, },
49954 { type: DomController, },
49955]; };
49956InfiniteScroll.propDecorators = {
49957 'threshold': [{ type: Input },],
49958 'enabled': [{ type: Input },],
49959 'position': [{ type: Input },],
49960 'ionInfinite': [{ type: Output },],
49961};
49962var STATE_ENABLED = 'enabled';
49963var STATE_DISABLED = 'disabled';
49964var STATE_LOADING = 'loading';
49965var POSITION_TOP = 'top';
49966var POSITION_BOTTOM = 'bottom';
49967
49968/**
49969 * @hidden
49970 */
49971var InfiniteScrollContent = (function () {
49972 /**
49973 * @param {?} inf
49974 * @param {?} _config
49975 */
49976 function InfiniteScrollContent(inf, _config) {
49977 this.inf = inf;
49978 this._config = _config;
49979 }
49980 /**
49981 * @hidden
49982 * @return {?}
49983 */
49984 InfiniteScrollContent.prototype.ngOnInit = function () {
49985 if (!this.loadingSpinner) {
49986 this.loadingSpinner = this._config.get('infiniteLoadingSpinner', this._config.get('spinner', 'ios'));
49987 }
49988 };
49989 return InfiniteScrollContent;
49990}());
49991InfiniteScrollContent.decorators = [
49992 { type: Component, args: [{
49993 selector: 'ion-infinite-scroll-content',
49994 template: '<div class="infinite-loading">' +
49995 '<div class="infinite-loading-spinner" *ngIf="loadingSpinner">' +
49996 '<ion-spinner [name]="loadingSpinner"></ion-spinner>' +
49997 '</div>' +
49998 '<div class="infinite-loading-text" [innerHTML]="loadingText" *ngIf="loadingText"></div>' +
49999 '</div>',
50000 host: {
50001 '[attr.state]': 'inf.state'
50002 },
50003 encapsulation: ViewEncapsulation.None,
50004 },] },
50005];
50006/**
50007 * @nocollapse
50008 */
50009InfiniteScrollContent.ctorParameters = function () { return [
50010 { type: InfiniteScroll, },
50011 { type: Config, },
50012]; };
50013InfiniteScrollContent.propDecorators = {
50014 'loadingSpinner': [{ type: Input },],
50015 'loadingText': [{ type: Input },],
50016};
50017
50018var __extends$49 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
50019 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
50020 function __() { this.constructor = d; }
50021 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
50022};
50023
50024
50025/**
50026 * Emits the values emitted by the source Observable until a `notifier`
50027 * Observable emits a value.
50028 *
50029 * <span class="informal">Lets values pass until a second Observable,
50030 * `notifier`, emits something. Then, it completes.</span>
50031 *
50032 * <img src="./img/takeUntil.png" width="100%">
50033 *
50034 * `takeUntil` subscribes and begins mirroring the source Observable. It also
50035 * monitors a second Observable, `notifier` that you provide. If the `notifier`
50036 * emits a value or a complete notification, the output Observable stops
50037 * mirroring the source Observable and completes.
50038 *
50039 * @example <caption>Tick every second until the first click happens</caption>
50040 * var interval = Rx.Observable.interval(1000);
50041 * var clicks = Rx.Observable.fromEvent(document, 'click');
50042 * var result = interval.takeUntil(clicks);
50043 * result.subscribe(x => console.log(x));
50044 *
50045 * @see {@link take}
50046 * @see {@link takeLast}
50047 * @see {@link takeWhile}
50048 * @see {@link skip}
50049 *
50050 * @param {Observable} notifier The Observable whose first emitted value will
50051 * cause the output Observable of `takeUntil` to stop emitting values from the
50052 * source Observable.
50053 * @return {Observable<T>} An Observable that emits the values from the source
50054 * Observable until such time as `notifier` emits its first value.
50055 * @method takeUntil
50056 * @owner Observable
50057 */
50058function takeUntil$2(notifier) {
50059 return this.lift(new TakeUntilOperator(notifier));
50060}
50061var takeUntil_2 = takeUntil$2;
50062var TakeUntilOperator = (function () {
50063 function TakeUntilOperator(notifier) {
50064 this.notifier = notifier;
50065 }
50066 TakeUntilOperator.prototype.call = function (subscriber, source) {
50067 return source.subscribe(new TakeUntilSubscriber(subscriber, this.notifier));
50068 };
50069 return TakeUntilOperator;
50070}());
50071/**
50072 * We need this JSDoc comment for affecting ESDoc.
50073 * @ignore
50074 * @extends {Ignored}
50075 */
50076var TakeUntilSubscriber = (function (_super) {
50077 __extends$49(TakeUntilSubscriber, _super);
50078 function TakeUntilSubscriber(destination, notifier) {
50079 _super.call(this, destination);
50080 this.notifier = notifier;
50081 this.add(subscribeToResult_1.subscribeToResult(this, notifier));
50082 }
50083 TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
50084 this.complete();
50085 };
50086 TakeUntilSubscriber.prototype.notifyComplete = function () {
50087 // noop
50088 };
50089 return TakeUntilSubscriber;
50090}(OuterSubscriber_1.OuterSubscriber));
50091
50092var takeUntil_1 = {
50093 takeUntil: takeUntil_2
50094};
50095
50096Observable_1.Observable.prototype.takeUntil = takeUntil_1.takeUntil;
50097
50098var __extends$48 = (undefined && undefined.__extends) || (function () {
50099 var extendStatics = Object.setPrototypeOf ||
50100 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
50101 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
50102 return function (d, b) {
50103 extendStatics(d, b);
50104 function __() { this.constructor = d; }
50105 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
50106 };
50107})();
50108/**
50109 * \@name Input
50110 * \@description
50111 *
50112 * `ion-input` is meant for text type inputs only, such as `text`,
50113 * `password`, `email`, `number`, `search`, `tel`, and `url`. Ionic
50114 * still uses an actual `<input type="text">` HTML element within the
50115 * component, however, with Ionic wrapping the native HTML input
50116 * element it's better able to handle the user experience and
50117 * interactivity.
50118 *
50119 * Similarly, `<ion-textarea>` should be used in place of `<textarea>`.
50120 *
50121 * An `ion-input` is **not** used for non-text type inputs, such as a
50122 * `checkbox`, `radio`, `toggle`, `range`, `select`, etc.
50123 *
50124 * Along with the blur/focus events, `input` support all standard text input
50125 * events like `keyup`, `keydown`, `keypress`, `input`,etc. Any standard event
50126 * can be attached and will function as expected.
50127 *
50128 * \@usage
50129 * ```html
50130 * <ion-list>
50131 * <ion-item>
50132 * <ion-label color="primary">Inline Label</ion-label>
50133 * <ion-input placeholder="Text Input"></ion-input>
50134 * </ion-item>
50135 *
50136 * <ion-item>
50137 * <ion-label color="primary" fixed>Fixed Label</ion-label>
50138 * <ion-input type="tel" placeholder="Tel Input"></ion-input>
50139 * </ion-item>
50140 *
50141 * <ion-item>
50142 * <ion-input type="number" placeholder="Number Input with no label"></ion-input>
50143 * </ion-item>
50144 *
50145 * <ion-item>
50146 * <ion-label color="primary" stacked>Stacked Label</ion-label>
50147 * <ion-input type="email" placeholder="Email Input"></ion-input>
50148 * </ion-item>
50149 *
50150 * <ion-item>
50151 * <ion-label color="primary" stacked>Stacked Label</ion-label>
50152 * <ion-input type="password" placeholder="Password Input"></ion-input>
50153 * </ion-item>
50154 *
50155 * <ion-item>
50156 * <ion-label color="primary" floating>Floating Label</ion-label>
50157 * <ion-input></ion-input>
50158 * </ion-item>
50159 *
50160 * <ion-item>
50161 * <ion-input placeholder="Clear Input" clearInput></ion-input>
50162 * </ion-item>
50163 *
50164 * <ion-item>
50165 * <ion-textarea placeholder="Enter a description"></ion-textarea>
50166 * </ion-item>
50167 * </ion-list>
50168 * ```
50169 *
50170 * \@demo /docs/demos/src/input/
50171 */
50172var TextInput = (function (_super) {
50173 __extends$48(TextInput, _super);
50174 /**
50175 * @param {?} config
50176 * @param {?} _plt
50177 * @param {?} _form
50178 * @param {?} _app
50179 * @param {?} elementRef
50180 * @param {?} renderer
50181 * @param {?} _content
50182 * @param {?} _item
50183 * @param {?} ngControl
50184 * @param {?} _dom
50185 */
50186 function TextInput(config, _plt, _form, _app, elementRef, renderer, _content, _item, ngControl, _dom) {
50187 var _this = _super.call(this, config, elementRef, renderer, 'input', '', _form, _item, ngControl) || this;
50188 _this._plt = _plt;
50189 _this._app = _app;
50190 _this._content = _content;
50191 _this.ngControl = ngControl;
50192 _this._dom = _dom;
50193 _this._clearInput = false;
50194 _this._readonly = false;
50195 _this._type = 'text';
50196 _this._isTextarea = false;
50197 _this._onDestroy = new Subject_2();
50198 _this._useAssist = false;
50199 _this._relocated = false;
50200 /**
50201 * \@input {string} Set the input's autocomplete property. Values: `"on"`, `"off"`. Default `"off"`.
50202 */
50203 _this.autocomplete = '';
50204 /**
50205 * \@input {string} Set the input's autocorrect property. Values: `"on"`, `"off"`. Default `"off"`.
50206 */
50207 _this.autocorrect = '';
50208 /**
50209 * \@input {string} Instructional text that shows before the input has a value.
50210 */
50211 _this.placeholder = '';
50212 /**
50213 * \@input {any} The minimum value, which must not be greater than its maximum (max attribute) value.
50214 */
50215 _this.min = null;
50216 /**
50217 * \@input {any} The maximum value, which must not be less than its minimum (min attribute) value.
50218 */
50219 _this.max = null;
50220 /**
50221 * \@input {any} Works with the min and max attributes to limit the increments at which a value can be set.
50222 */
50223 _this.step = null;
50224 /**
50225 * @hidden
50226 */
50227 _this.input = new EventEmitter();
50228 /**
50229 * @hidden
50230 */
50231 _this.blur = new EventEmitter();
50232 /**
50233 * @hidden
50234 */
50235 _this.focus = new EventEmitter();
50236 _this.autocomplete = config.get('autocomplete', 'off');
50237 _this.autocorrect = config.get('autocorrect', 'off');
50238 _this._autoFocusAssist = config.get('autoFocusAssist', 'delay');
50239 _this._keyboardHeight = config.getNumber('keyboardHeight');
50240 _this._isTextarea = !!(elementRef.nativeElement.tagName === 'ION-TEXTAREA');
50241 if (_this._isTextarea && _item) {
50242 _item.setElementClass('item-textarea', true);
50243 }
50244 // If not inside content, let's disable all the hacks
50245 if (!_content) {
50246 return _this;
50247 }
50248 var blurOnScroll = config.getBoolean('hideCaretOnScroll', false);
50249 if (blurOnScroll) {
50250 _this._enableHideCaretOnScroll();
50251 }
50252 var resizeAssist = config.getBoolean('resizeAssist', false);
50253 if (resizeAssist) {
50254 _this._keyboardHeight = 60;
50255 _this._enableResizeAssist();
50256 }
50257 else {
50258 _this._useAssist = config.getBoolean('scrollAssist', false);
50259 var usePadding = config.getBoolean('scrollPadding', _this._useAssist);
50260 if (usePadding) {
50261 _this._enableScrollPadding();
50262 }
50263 }
50264 return _this;
50265 }
50266 Object.defineProperty(TextInput.prototype, "clearInput", {
50267 /**
50268 * \@input {boolean} If true, a clear icon will appear in the input when there is a value. Clicking it clears the input.
50269 * @return {?}
50270 */
50271 get: function () {
50272 return this._clearInput;
50273 },
50274 /**
50275 * @param {?} val
50276 * @return {?}
50277 */
50278 set: function (val) {
50279 this._clearInput = (!this._isTextarea && isTrueProperty(val));
50280 },
50281 enumerable: true,
50282 configurable: true
50283 });
50284 Object.defineProperty(TextInput.prototype, "type", {
50285 /**
50286 * \@input {string} The type of control to display. The default type is text.
50287 * Possible values are: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, or `"url"`.
50288 * @return {?}
50289 */
50290 get: function () {
50291 return (this._isTextarea)
50292 ? 'text'
50293 : this._type;
50294 },
50295 /**
50296 * @param {?} val
50297 * @return {?}
50298 */
50299 set: function (val) {
50300 this._type = val;
50301 },
50302 enumerable: true,
50303 configurable: true
50304 });
50305 Object.defineProperty(TextInput.prototype, "readonly", {
50306 /**
50307 * \@input {boolean} If true, the user cannot modify the value.
50308 * @return {?}
50309 */
50310 get: function () {
50311 return this._readonly;
50312 },
50313 /**
50314 * @param {?} val
50315 * @return {?}
50316 */
50317 set: function (val) {
50318 this._readonly = isTrueProperty(val);
50319 },
50320 enumerable: true,
50321 configurable: true
50322 });
50323 Object.defineProperty(TextInput.prototype, "clearOnEdit", {
50324 /**
50325 * \@input {boolean} If true, the value will be cleared after focus upon edit.
50326 * Defaults to `true` when `type` is `"password"`, `false` for all other types.
50327 * @return {?}
50328 */
50329 get: function () {
50330 return this._clearOnEdit;
50331 },
50332 /**
50333 * @param {?} val
50334 * @return {?}
50335 */
50336 set: function (val) {
50337 this._clearOnEdit = isTrueProperty(val);
50338 },
50339 enumerable: true,
50340 configurable: true
50341 });
50342 /**
50343 * @return {?}
50344 */
50345 TextInput.prototype.ngAfterContentInit = function () { };
50346 /**
50347 * @hidden
50348 * @return {?}
50349 */
50350 TextInput.prototype.ngAfterViewInit = function () {
50351 (void 0) /* assert */;
50352 // By default, password inputs clear after focus when they have content
50353 if (this.clearOnEdit !== false && this.type === 'password') {
50354 this.clearOnEdit = true;
50355 }
50356 var /** @type {?} */ ionInputEle = this._elementRef.nativeElement;
50357 var /** @type {?} */ nativeInputEle = this._native.nativeElement;
50358 // Copy remaining attributes, not handled by ionic/angular
50359 copyInputAttributes(ionInputEle, nativeInputEle);
50360 // prevent having tabIndex duplicated
50361 if (ionInputEle.hasAttribute('tabIndex')) {
50362 ionInputEle.removeAttribute('tabIndex');
50363 }
50364 // handle the autofocus attribute
50365 if (ionInputEle.hasAttribute('autofocus')) {
50366 ionInputEle.removeAttribute('autofocus');
50367 switch (this._autoFocusAssist) {
50368 case 'immediate':
50369 // config says to immediate focus on the input
50370 // works best on android devices
50371 nativeInputEle.focus();
50372 break;
50373 case 'delay':
50374 // config says to chill out a bit and focus on the input after transitions
50375 // works best on desktop
50376 this._plt.timeout(function () { return nativeInputEle.focus(); }, 800);
50377 break;
50378 }
50379 // traditionally iOS has big issues with autofocus on actual devices
50380 // autoFocus is disabled by default with the iOS mode config
50381 }
50382 // Initialize the input (can start emitting events)
50383 this._initialize();
50384 if (this.focus.observers.length > 0) {
50385 console.warn('(focus) is deprecated in ion-input, use (ionFocus) instead');
50386 }
50387 if (this.blur.observers.length > 0) {
50388 console.warn('(blur) is deprecated in ion-input, use (ionBlur) instead');
50389 }
50390 };
50391 /**
50392 * @hidden
50393 * @return {?}
50394 */
50395 TextInput.prototype.ngOnDestroy = function () {
50396 _super.prototype.ngOnDestroy.call(this);
50397 this._onDestroy.next();
50398 this._onDestroy = null;
50399 };
50400 /**
50401 * @hidden
50402 * @return {?}
50403 */
50404 TextInput.prototype.initFocus = function () {
50405 this.setFocus();
50406 };
50407 /**
50408 * @hidden
50409 * @return {?}
50410 */
50411 TextInput.prototype.setFocus = function () {
50412 // let's set focus to the element
50413 // but only if it does not already have focus
50414 if (!this.isFocus()) {
50415 this._native.nativeElement.focus();
50416 }
50417 };
50418 /**
50419 * @hidden
50420 * @return {?}
50421 */
50422 TextInput.prototype.setBlur = function () {
50423 if (this.isFocus()) {
50424 this._native.nativeElement.blur();
50425 }
50426 };
50427 /**
50428 * @hidden
50429 * @param {?} ev
50430 * @return {?}
50431 */
50432 TextInput.prototype.onInput = function (ev) {
50433 this.value = ev.target.value;
50434 // TODO: deprecate this
50435 this.input.emit(ev);
50436 };
50437 /**
50438 * @hidden
50439 * @param {?} ev
50440 * @return {?}
50441 */
50442 TextInput.prototype.onBlur = function (ev) {
50443 this._fireBlur();
50444 // TODO: deprecate this (06/07/2017)
50445 this.blur.emit(ev);
50446 this._scrollData = null;
50447 if (this._clearOnEdit && this.hasValue()) {
50448 this._didBlurAfterEdit = true;
50449 }
50450 };
50451 /**
50452 * @hidden
50453 * @param {?} ev
50454 * @return {?}
50455 */
50456 TextInput.prototype.onFocus = function (ev) {
50457 this._fireFocus();
50458 // TODO: deprecate this (06/07/2017)
50459 this.focus.emit(ev);
50460 };
50461 /**
50462 * @hidden
50463 * @param {?} ev
50464 * @return {?}
50465 */
50466 TextInput.prototype.onKeydown = function (ev) {
50467 if (ev && this._clearOnEdit) {
50468 this.checkClearOnEdit(ev.target.value);
50469 }
50470 };
50471 /**
50472 * @hidden
50473 * @return {?}
50474 */
50475 TextInput.prototype._inputUpdated = function () {
50476 _super.prototype._inputUpdated.call(this);
50477 var /** @type {?} */ inputEle = this._native.nativeElement;
50478 var /** @type {?} */ value = this._value;
50479 if (inputEle.value !== value) {
50480 inputEle.value = value;
50481 }
50482 };
50483 /**
50484 * @hidden
50485 * @return {?}
50486 */
50487 TextInput.prototype.clearTextInput = function () {
50488 this.value = '';
50489 };
50490 /**
50491 * Check if we need to clear the text input if clearOnEdit is enabled
50492 * @hidden
50493 * @param {?} _
50494 * @return {?}
50495 */
50496 TextInput.prototype.checkClearOnEdit = function (_) {
50497 if (!this._clearOnEdit) {
50498 return;
50499 }
50500 // Did the input value change after it was blurred and edited?
50501 if (this._didBlurAfterEdit && this.hasValue()) {
50502 // Clear the input
50503 this.clearTextInput();
50504 }
50505 // Reset the flag
50506 this._didBlurAfterEdit = false;
50507 };
50508 /**
50509 * @return {?}
50510 */
50511 TextInput.prototype._getScrollData = function () {
50512 if (!this._content) {
50513 return newScrollData();
50514 }
50515 // get container of this input, probably an ion-item a few nodes up
50516 if (this._scrollData) {
50517 return this._scrollData;
50518 }
50519 var /** @type {?} */ ele = this._elementRef.nativeElement;
50520 ele = (ele.closest('ion-item,[ion-item]')) || ele;
50521 return this._scrollData = getScrollData(ele.offsetTop, ele.offsetHeight, this._content.getContentDimensions(), this._keyboardHeight, this._plt.height());
50522 };
50523 /**
50524 * @param {?} shouldRelocate
50525 * @return {?}
50526 */
50527 TextInput.prototype._relocateInput = function (shouldRelocate) {
50528 if (this._relocated === shouldRelocate) {
50529 return;
50530 }
50531 var /** @type {?} */ platform = this._plt;
50532 var /** @type {?} */ componentEle = this.getNativeElement();
50533 var /** @type {?} */ focusedInputEle = this._native.nativeElement;
50534 (void 0) /* console.debug */;
50535 if (shouldRelocate) {
50536 // this allows for the actual input to receive the focus from
50537 // the user's touch event, but before it receives focus, it
50538 // moves the actual input to a location that will not screw
50539 // up the app's layout, and does not allow the native browser
50540 // to attempt to scroll the input into place (messing up headers/footers)
50541 // the cloned input fills the area of where native input should be
50542 // while the native input fakes out the browser by relocating itself
50543 // before it receives the actual focus event
50544 // We hide the focused input (with the visible caret) invisiable by making it scale(0),
50545 cloneInputComponent(platform, componentEle, focusedInputEle);
50546 var /** @type {?} */ inputRelativeY = this._getScrollData().inputSafeY;
50547 // fix for #11817
50548 var /** @type {?} */ tx = this._plt.isRTL ? 9999 : -9999;
50549 focusedInputEle.style[platform.Css.transform] = "translate3d(" + tx + "px," + inputRelativeY + "px,0)";
50550 focusedInputEle.style.opacity = '0';
50551 }
50552 else {
50553 removeClone(platform, componentEle, focusedInputEle);
50554 }
50555 this._relocated = shouldRelocate;
50556 };
50557 /**
50558 * @return {?}
50559 */
50560 TextInput.prototype._enableScrollPadding = function () {
50561 var _this = this;
50562 (void 0) /* assert */;
50563 (void 0) /* console.debug */;
50564 this.ionFocus.subscribe(function () {
50565 var /** @type {?} */ content = _this._content;
50566 // add padding to the bottom of the scroll view (if needed)
50567 content.addScrollPadding(_this._getScrollData().scrollPadding);
50568 content.clearScrollPaddingFocusOut();
50569 });
50570 };
50571 /**
50572 * @return {?}
50573 */
50574 TextInput.prototype._enableHideCaretOnScroll = function () {
50575 var _this = this;
50576 (void 0) /* assert */;
50577 var /** @type {?} */ content = this._content;
50578 (void 0) /* console.debug */;
50579 content.ionScrollStart
50580 .takeUntil(this._onDestroy)
50581 .subscribe(function () { return scrollHideCaret(true); });
50582 content.ionScrollEnd
50583 .takeUntil(this._onDestroy)
50584 .subscribe(function () { return scrollHideCaret(false); });
50585 this.ionBlur.subscribe(function () { return _this._relocateInput(false); });
50586 var /** @type {?} */ self = this;
50587 /**
50588 * @param {?} shouldHideCaret
50589 * @return {?}
50590 */
50591 function scrollHideCaret(shouldHideCaret) {
50592 // if it does have focus, then do the dom write
50593 if (self.isFocus()) {
50594 self._dom.write(function () { return self._relocateInput(shouldHideCaret); });
50595 }
50596 }
50597 };
50598 /**
50599 * @return {?}
50600 */
50601 TextInput.prototype._enableResizeAssist = function () {
50602 var _this = this;
50603 (void 0) /* assert */;
50604 (void 0) /* console.debug */;
50605 this.ionFocus.subscribe(function () {
50606 var /** @type {?} */ scrollData = _this._getScrollData();
50607 if (Math.abs(scrollData.scrollAmount) > 100) {
50608 _this._content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration);
50609 }
50610 });
50611 };
50612 /**
50613 * @param {?} ev
50614 * @return {?}
50615 */
50616 TextInput.prototype._pointerStart = function (ev) {
50617 (void 0) /* assert */;
50618 // input cover touchstart
50619 if (ev.type === 'touchstart') {
50620 this._isTouch = true;
50621 }
50622 if ((this._isTouch || (!this._isTouch && ev.type === 'mousedown')) && this._app.isEnabled()) {
50623 // remember where the touchstart/mousedown started
50624 this._coord = pointerCoord(ev);
50625 }
50626 (void 0) /* console.debug */;
50627 };
50628 /**
50629 * @param {?} ev
50630 * @return {?}
50631 */
50632 TextInput.prototype._pointerEnd = function (ev) {
50633 (void 0) /* assert */;
50634 // input cover touchend/mouseup
50635 (void 0) /* console.debug */;
50636 if ((this._isTouch && ev.type === 'mouseup') || !this._app.isEnabled()) {
50637 // the app is actively doing something right now
50638 // don't try to scroll in the input
50639 ev.preventDefault();
50640 ev.stopPropagation();
50641 }
50642 else if (this._coord) {
50643 // get where the touchend/mouseup ended
50644 var /** @type {?} */ endCoord = pointerCoord(ev);
50645 // focus this input if the pointer hasn't moved XX pixels
50646 // and the input doesn't already have focus
50647 if (!hasPointerMoved(8, this._coord, endCoord) && !this.isFocus()) {
50648 ev.preventDefault();
50649 ev.stopPropagation();
50650 // begin the input focus process
50651 this._jsSetFocus();
50652 }
50653 }
50654 this._coord = null;
50655 };
50656 /**
50657 * @return {?}
50658 */
50659 TextInput.prototype._jsSetFocus = function () {
50660 var _this = this;
50661 (void 0) /* assert */;
50662 // begin the process of setting focus to the inner input element
50663 var /** @type {?} */ content = this._content;
50664 (void 0) /* console.debug */;
50665 if (!content) {
50666 // not inside of a scroll view, just focus it
50667 this.setFocus();
50668 }
50669 var /** @type {?} */ scrollData = this._getScrollData();
50670 if (Math.abs(scrollData.scrollAmount) < 4) {
50671 // the text input is in a safe position that doesn't
50672 // require it to be scrolled into view, just set focus now
50673 this.setFocus();
50674 return;
50675 }
50676 // temporarily move the focus to the focus holder so the browser
50677 // doesn't freak out while it's trying to get the input in place
50678 // at this point the native text input still does not have focus
50679 this._relocateInput(true);
50680 this.setFocus();
50681 // scroll the input into place
50682 content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration, function () {
50683 // the scroll view is in the correct position now
50684 // give the native text input focus
50685 _this._relocateInput(false);
50686 // ensure this is the focused input
50687 _this.setFocus();
50688 });
50689 };
50690 return TextInput;
50691}(BaseInput));
50692TextInput.decorators = [
50693 { type: Component, args: [{
50694 selector: 'ion-input,ion-textarea',
50695 template: '<input #textInput *ngIf="!_isTextarea" class="text-input" ' +
50696 '[ngClass]="\'text-input-\' + _mode"' +
50697 '(input)="onInput($event)" ' +
50698 '(blur)="onBlur($event)" ' +
50699 '(focus)="onFocus($event)" ' +
50700 '(keydown)="onKeydown($event)" ' +
50701 '[type]="_type" ' +
50702 '[attr.aria-labelledby]="_labelId" ' +
50703 '[attr.min]="min" ' +
50704 '[attr.max]="max" ' +
50705 '[attr.step]="step" ' +
50706 '[attr.autocomplete]="autocomplete" ' +
50707 '[attr.autocorrect]="autocorrect" ' +
50708 '[placeholder]="placeholder" ' +
50709 '[disabled]="_disabled" ' +
50710 '[readonly]="_readonly">' +
50711 '<textarea #textInput *ngIf="_isTextarea" class="text-input" ' +
50712 '[ngClass]="\'text-input-\' + _mode"' +
50713 '(input)="onInput($event)" ' +
50714 '(blur)="onBlur($event)" ' +
50715 '(focus)="onFocus($event)" ' +
50716 '(keydown)="onKeydown($event)" ' +
50717 '[attr.aria-labelledby]="_labelId" ' +
50718 '[attr.autocomplete]="autocomplete" ' +
50719 '[attr.autocorrect]="autocorrect" ' +
50720 '[placeholder]="placeholder" ' +
50721 '[disabled]="_disabled" ' +
50722 '[readonly]="_readonly"></textarea>' +
50723 '<button ion-button *ngIf="_clearInput" clear class="text-input-clear-icon" ' +
50724 'type="button" ' +
50725 '(click)="clearTextInput($event)" ' +
50726 '(mousedown)="clearTextInput($event)" ' +
50727 'tabindex="-1"></button>' +
50728 '<div class="input-cover" *ngIf="_useAssist" ' +
50729 '(touchstart)="_pointerStart($event)" ' +
50730 '(touchend)="_pointerEnd($event)" ' +
50731 '(mousedown)="_pointerStart($event)" ' +
50732 '(mouseup)="_pointerEnd($event)"></div>',
50733 encapsulation: ViewEncapsulation.None,
50734 changeDetection: ChangeDetectionStrategy.OnPush,
50735 inputs: ['value']
50736 },] },
50737];
50738/**
50739 * @nocollapse
50740 */
50741TextInput.ctorParameters = function () { return [
50742 { type: Config, },
50743 { type: Platform, },
50744 { type: Form, },
50745 { type: App, },
50746 { type: ElementRef, },
50747 { type: Renderer, },
50748 { type: Content, decorators: [{ type: Optional },] },
50749 { type: Item, decorators: [{ type: Optional },] },
50750 { type: NgControl, decorators: [{ type: Optional },] },
50751 { type: DomController, },
50752]; };
50753TextInput.propDecorators = {
50754 'clearInput': [{ type: Input },],
50755 'type': [{ type: Input },],
50756 'readonly': [{ type: Input },],
50757 'clearOnEdit': [{ type: Input },],
50758 '_native': [{ type: ViewChild, args: ['textInput', { read: ElementRef },] },],
50759 'autocomplete': [{ type: Input },],
50760 'autocorrect': [{ type: Input },],
50761 'placeholder': [{ type: Input },],
50762 'min': [{ type: Input },],
50763 'max': [{ type: Input },],
50764 'step': [{ type: Input },],
50765 'input': [{ type: Output },],
50766 'blur': [{ type: Output },],
50767 'focus': [{ type: Output },],
50768};
50769/**
50770 * \@name TextArea
50771 * \@description
50772 *
50773 * `ion-textarea` is used for multi-line text inputs. Ionic still
50774 * uses an actual `<textarea>` HTML element within the component;
50775 * however, with Ionic wrapping the native HTML text area element, Ionic
50776 * is able to better handle the user experience and interactivity.
50777 *
50778 * Note that `<ion-textarea>` must load its value from the `value` or
50779 * `[(ngModel)]` attribute. Unlike the native `<textarea>` element,
50780 * `<ion-textarea>` does not support loading its value from the
50781 * textarea's inner content.
50782 *
50783 * When requiring only a single-line text input, we recommend using
50784 * `<ion-input>` instead.
50785 *
50786 * \@usage
50787 * ```html
50788 * <ion-item>
50789 * <ion-label>Comments</ion-label>
50790 * <ion-textarea></ion-textarea>
50791 * </ion-item>
50792 *
50793 * <ion-item>
50794 * <ion-label stacked>Message</ion-label>
50795 * <ion-textarea [(ngModel)]="msg"></ion-textarea>
50796 * </ion-item>
50797 *
50798 * <ion-item>
50799 * <ion-label floating>Description</ion-label>
50800 * <ion-textarea></ion-textarea>
50801 * </ion-item>
50802 *
50803 * <ion-item>
50804 * <ion-label>Long Description</ion-label>
50805 * <ion-textarea rows="6" placeholder="enter long description here..."></ion-textarea>
50806 * </ion-item>
50807 * ```
50808 *
50809 * \@demo /docs/demos/src/textarea/
50810 */
50811var SCROLL_ASSIST_SPEED = 0.3;
50812/**
50813 * @return {?}
50814 */
50815function newScrollData() {
50816 return {
50817 scrollAmount: 0,
50818 scrollTo: 0,
50819 scrollPadding: 0,
50820 scrollDuration: 0,
50821 inputSafeY: 0
50822 };
50823}
50824/**
50825 * @hidden
50826 * @param {?} inputOffsetTop
50827 * @param {?} inputOffsetHeight
50828 * @param {?} scrollViewDimensions
50829 * @param {?} keyboardHeight
50830 * @param {?} plaformHeight
50831 * @return {?}
50832 */
50833function getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, plaformHeight) {
50834 // compute input's Y values relative to the body
50835 var /** @type {?} */ inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop);
50836 var /** @type {?} */ inputBottom = (inputTop + inputOffsetHeight);
50837 // compute the safe area which is the viewable content area when the soft keyboard is up
50838 var /** @type {?} */ safeAreaTop = scrollViewDimensions.contentTop;
50839 var /** @type {?} */ safeAreaHeight = (plaformHeight - keyboardHeight - safeAreaTop) / 2;
50840 var /** @type {?} */ safeAreaBottom = safeAreaTop + safeAreaHeight;
50841 // figure out if each edge of teh input is within the safe area
50842 var /** @type {?} */ inputTopWithinSafeArea = (inputTop >= safeAreaTop && inputTop <= safeAreaBottom);
50843 var /** @type {?} */ inputTopAboveSafeArea = (inputTop < safeAreaTop);
50844 var /** @type {?} */ inputTopBelowSafeArea = (inputTop > safeAreaBottom);
50845 var /** @type {?} */ inputBottomWithinSafeArea = (inputBottom >= safeAreaTop && inputBottom <= safeAreaBottom);
50846 var /** @type {?} */ inputBottomBelowSafeArea = (inputBottom > safeAreaBottom);
50847 /*
50848 Text Input Scroll To Scenarios
50849 ---------------------------------------
50850 1) Input top within safe area, bottom within safe area
50851 2) Input top within safe area, bottom below safe area, room to scroll
50852 3) Input top above safe area, bottom within safe area, room to scroll
50853 4) Input top below safe area, no room to scroll, input smaller than safe area
50854 5) Input top within safe area, bottom below safe area, no room to scroll, input smaller than safe area
50855 6) Input top within safe area, bottom below safe area, no room to scroll, input larger than safe area
50856 7) Input top below safe area, no room to scroll, input larger than safe area
50857 */
50858 var /** @type {?} */ scrollData = newScrollData();
50859 if (inputTopWithinSafeArea && inputBottomWithinSafeArea) {
50860 // Input top within safe area, bottom within safe area
50861 // no need to scroll to a position, it's good as-is
50862 return scrollData;
50863 }
50864 // looks like we'll have to do some auto-scrolling
50865 if (inputTopBelowSafeArea || inputBottomBelowSafeArea || inputTopAboveSafeArea) {
50866 // Input top or bottom below safe area
50867 // auto scroll the input up so at least the top of it shows
50868 if (safeAreaHeight > inputOffsetHeight) {
50869 // safe area height is taller than the input height, so we
50870 // can bring up the input just enough to show the input bottom
50871 scrollData.scrollAmount = Math.round(safeAreaBottom - inputBottom);
50872 }
50873 else {
50874 // safe area height is smaller than the input height, so we can
50875 // only scroll it up so the input top is at the top of the safe area
50876 // however the input bottom will be below the safe area
50877 scrollData.scrollAmount = Math.round(safeAreaTop - inputTop);
50878 }
50879 scrollData.inputSafeY = -(inputTop - safeAreaTop) + 4;
50880 if (inputTopAboveSafeArea && scrollData.scrollAmount > inputOffsetHeight) {
50881 // the input top is above the safe area and we're already scrolling it into place
50882 // don't let it scroll more than the height of the input
50883 scrollData.scrollAmount = inputOffsetHeight;
50884 }
50885 }
50886 // figure out where it should scroll to for the best position to the input
50887 scrollData.scrollTo = (scrollViewDimensions.scrollTop - scrollData.scrollAmount);
50888 // when auto-scrolling, there also needs to be enough
50889 // content padding at the bottom of the scroll view
50890 // always add scroll padding when a text input has focus
50891 // this allows for the content to scroll above of the keyboard
50892 // content behind the keyboard would be blank
50893 // some cases may not need it, but when jumping around it's best
50894 // to have the padding already rendered so there's no jank
50895 scrollData.scrollPadding = keyboardHeight;
50896 // calculate animation duration
50897 var /** @type {?} */ distance = Math.abs(scrollData.scrollAmount);
50898 var /** @type {?} */ duration = distance / SCROLL_ASSIST_SPEED;
50899 scrollData.scrollDuration = Math.min(400, Math.max(150, duration));
50900 return scrollData;
50901}
50902/**
50903 * @param {?} plt
50904 * @param {?} srcComponentEle
50905 * @param {?} srcNativeInputEle
50906 * @return {?}
50907 */
50908function cloneInputComponent(plt, srcComponentEle, srcNativeInputEle) {
50909 // Make sure we kill all the clones before creating new ones
50910 // It is a defensive, removeClone() should do nothing
50911 // removeClone(plt, srcComponentEle, srcNativeInputEle);
50912 (void 0) /* assert */;
50913 // given a native <input> or <textarea> element
50914 // find its parent wrapping component like <ion-input> or <ion-textarea>
50915 // then clone the entire component
50916 if (srcComponentEle) {
50917 // DOM READ
50918 var /** @type {?} */ srcTop = srcComponentEle.offsetTop;
50919 var /** @type {?} */ srcLeft = srcComponentEle.offsetLeft;
50920 var /** @type {?} */ srcWidth = srcComponentEle.offsetWidth;
50921 var /** @type {?} */ srcHeight = srcComponentEle.offsetHeight;
50922 // DOM WRITE
50923 // not using deep clone so we don't pull in unnecessary nodes
50924 var /** @type {?} */ clonedComponentEle = (srcComponentEle.cloneNode(false));
50925 var /** @type {?} */ clonedStyle = clonedComponentEle.style;
50926 clonedComponentEle.classList.add('cloned-input');
50927 clonedComponentEle.setAttribute('aria-hidden', 'true');
50928 clonedStyle.pointerEvents = 'none';
50929 clonedStyle.position = 'absolute';
50930 clonedStyle.top = srcTop + 'px';
50931 clonedStyle.left = srcLeft + 'px';
50932 clonedStyle.width = srcWidth + 'px';
50933 clonedStyle.height = srcHeight + 'px';
50934 var /** @type {?} */ clonedNativeInputEle = (srcNativeInputEle.cloneNode(false));
50935 clonedNativeInputEle.value = srcNativeInputEle.value;
50936 clonedNativeInputEle.tabIndex = -1;
50937 clonedComponentEle.appendChild(clonedNativeInputEle);
50938 srcComponentEle.parentNode.appendChild(clonedComponentEle);
50939 srcComponentEle.style.pointerEvents = 'none';
50940 }
50941 ((srcNativeInputEle.style))[plt.Css.transform] = 'scale(0)';
50942}
50943/**
50944 * @param {?} plt
50945 * @param {?} srcComponentEle
50946 * @param {?} srcNativeInputEle
50947 * @return {?}
50948 */
50949function removeClone(plt, srcComponentEle, srcNativeInputEle) {
50950 if (srcComponentEle && srcComponentEle.parentElement) {
50951 var /** @type {?} */ clonedInputEles = srcComponentEle.parentElement.querySelectorAll('.cloned-input');
50952 for (var /** @type {?} */ i = 0; i < clonedInputEles.length; i++) {
50953 clonedInputEles[i].parentNode.removeChild(clonedInputEles[i]);
50954 }
50955 srcComponentEle.style.pointerEvents = '';
50956 }
50957 ((srcNativeInputEle.style))[plt.Css.transform] = '';
50958 srcNativeInputEle.style.opacity = '';
50959}
50960
50961/**
50962 * @hidden
50963 */
50964var ItemContent = (function () {
50965 function ItemContent() {
50966 }
50967 return ItemContent;
50968}());
50969ItemContent.decorators = [
50970 { type: Directive, args: [{
50971 selector: 'ion-item,[ion-item]',
50972 host: {
50973 'class': 'item-block'
50974 }
50975 },] },
50976];
50977/**
50978 * @nocollapse
50979 */
50980ItemContent.ctorParameters = function () { return []; };
50981
50982var __extends$50 = (undefined && undefined.__extends) || (function () {
50983 var extendStatics = Object.setPrototypeOf ||
50984 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
50985 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
50986 return function (d, b) {
50987 extendStatics(d, b);
50988 function __() { this.constructor = d; }
50989 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
50990 };
50991})();
50992/**
50993 * @hidden
50994 */
50995var ItemDivider = (function (_super) {
50996 __extends$50(ItemDivider, _super);
50997 /**
50998 * @param {?} config
50999 * @param {?} elementRef
51000 * @param {?} renderer
51001 */
51002 function ItemDivider(config, elementRef, renderer) {
51003 return _super.call(this, config, elementRef, renderer, 'item-divider') || this;
51004 }
51005 return ItemDivider;
51006}(Ion));
51007ItemDivider.decorators = [
51008 { type: Directive, args: [{
51009 selector: 'ion-item-divider',
51010 host: {
51011 'class': 'item-divider'
51012 }
51013 },] },
51014];
51015/**
51016 * @nocollapse
51017 */
51018ItemDivider.ctorParameters = function () { return [
51019 { type: Config, },
51020 { type: ElementRef, },
51021 { type: Renderer, },
51022]; };
51023
51024/**
51025 * @hidden
51026 */
51027var ItemGroup = (function () {
51028 function ItemGroup() {
51029 }
51030 return ItemGroup;
51031}());
51032ItemGroup.decorators = [
51033 { type: Directive, args: [{
51034 selector: 'ion-item-group'
51035 },] },
51036];
51037/**
51038 * @nocollapse
51039 */
51040ItemGroup.ctorParameters = function () { return []; };
51041
51042/**
51043 * \@name ItemOptions
51044 * \@description
51045 * The option buttons for an `ion-item-sliding`. These buttons can be placed either on the left or right side.
51046 * You can combine the `(ionSwipe)` event plus the `expandable` directive to create a full swipe action for the item.
51047 *
51048 * \@usage
51049 *
51050 * ```html
51051 * <ion-item-sliding>
51052 * <ion-item>
51053 * Item 1
51054 * </ion-item>
51055 * <ion-item-options side="right" (ionSwipe)="saveItem(item)">
51056 * <button ion-button expandable (click)="saveItem(item)">
51057 * <ion-icon name="star"></ion-icon>
51058 * </button>
51059 * </ion-item-options>
51060 * </ion-item-sliding>
51061 * ```
51062 */
51063var ItemOptions = (function () {
51064 /**
51065 * @param {?} _elementRef
51066 * @param {?} _plt
51067 */
51068 function ItemOptions(_elementRef, _plt) {
51069 this._elementRef = _elementRef;
51070 this._plt = _plt;
51071 /**
51072 * \@output {event} Emitted when the item has been fully swiped.
51073 */
51074 this.ionSwipe = new EventEmitter();
51075 }
51076 /**
51077 * @hidden
51078 * @return {?}
51079 */
51080 ItemOptions.prototype.isRightSide = function () {
51081 return isRightSide(this.side, this._plt.isRTL, true);
51082 };
51083 /**
51084 * @hidden
51085 * @return {?}
51086 */
51087 ItemOptions.prototype.width = function () {
51088 return this._elementRef.nativeElement.offsetWidth;
51089 };
51090 return ItemOptions;
51091}());
51092ItemOptions.decorators = [
51093 { type: Directive, args: [{
51094 selector: 'ion-item-options',
51095 },] },
51096];
51097/**
51098 * @nocollapse
51099 */
51100ItemOptions.ctorParameters = function () { return [
51101 { type: ElementRef, },
51102 { type: Platform, },
51103]; };
51104ItemOptions.propDecorators = {
51105 'side': [{ type: Input },],
51106 'ionSwipe': [{ type: Output },],
51107};
51108
51109var __extends$52 = (undefined && undefined.__extends) || (function () {
51110 var extendStatics = Object.setPrototypeOf ||
51111 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
51112 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
51113 return function (d, b) {
51114 extendStatics(d, b);
51115 function __() { this.constructor = d; }
51116 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
51117 };
51118})();
51119/**
51120 * @hidden
51121 */
51122var ItemSlidingGesture = (function (_super) {
51123 __extends$52(ItemSlidingGesture, _super);
51124 /**
51125 * @param {?} plt
51126 * @param {?} list
51127 * @param {?} gestureCtrl
51128 * @param {?} domCtrl
51129 */
51130 function ItemSlidingGesture(plt, list, gestureCtrl, domCtrl) {
51131 var _this = _super.call(this, plt, list.getNativeElement(), {
51132 maxAngle: 20,
51133 threshold: 5,
51134 zone: false,
51135 domController: domCtrl,
51136 gesture: gestureCtrl.createGesture({
51137 name: GESTURE_ITEM_SWIPE,
51138 priority: GESTURE_PRIORITY_SLIDING_ITEM,
51139 disableScroll: true
51140 })
51141 }) || this;
51142 _this.list = list;
51143 _this.preSelectedContainer = null;
51144 _this.selectedContainer = null;
51145 _this.openContainer = null;
51146 return _this;
51147 }
51148 /**
51149 * @param {?} ev
51150 * @return {?}
51151 */
51152 ItemSlidingGesture.prototype.canStart = function (ev) {
51153 if (this.selectedContainer) {
51154 return false;
51155 }
51156 // Get swiped sliding container
51157 var /** @type {?} */ container = getContainer(ev);
51158 if (!container) {
51159 this.closeOpened();
51160 return false;
51161 }
51162 // Close open container if it is not the selected one.
51163 if (container !== this.openContainer) {
51164 this.closeOpened();
51165 }
51166 var /** @type {?} */ coord = pointerCoord(ev);
51167 this.preSelectedContainer = container;
51168 this.firstCoordX = coord.x;
51169 this.firstTimestamp = Date.now();
51170 return true;
51171 };
51172 /**
51173 * @param {?} ev
51174 * @return {?}
51175 */
51176 ItemSlidingGesture.prototype.onDragStart = function (ev) {
51177 ev.preventDefault();
51178 var /** @type {?} */ coord = pointerCoord(ev);
51179 this.selectedContainer = this.openContainer = this.preSelectedContainer;
51180 this.selectedContainer.startSliding(coord.x);
51181 };
51182 /**
51183 * @param {?} ev
51184 * @return {?}
51185 */
51186 ItemSlidingGesture.prototype.onDragMove = function (ev) {
51187 ev.preventDefault();
51188 this.selectedContainer.moveSliding(pointerCoord(ev).x);
51189 };
51190 /**
51191 * @param {?} ev
51192 * @return {?}
51193 */
51194 ItemSlidingGesture.prototype.onDragEnd = function (ev) {
51195 ev.preventDefault();
51196 var /** @type {?} */ coordX = pointerCoord(ev).x;
51197 var /** @type {?} */ deltaX = (coordX - this.firstCoordX);
51198 var /** @type {?} */ deltaT = (Date.now() - this.firstTimestamp);
51199 this.selectedContainer.endSliding(deltaX / deltaT);
51200 this.selectedContainer = null;
51201 this.preSelectedContainer = null;
51202 };
51203 /**
51204 * @param {?} ev
51205 * @return {?}
51206 */
51207 ItemSlidingGesture.prototype.notCaptured = function (ev) {
51208 if (!clickedOptionButton(ev)) {
51209 this.closeOpened();
51210 }
51211 };
51212 /**
51213 * @return {?}
51214 */
51215 ItemSlidingGesture.prototype.closeOpened = function () {
51216 this.selectedContainer = null;
51217 if (this.openContainer) {
51218 this.openContainer.close();
51219 this.openContainer = null;
51220 return true;
51221 }
51222 return false;
51223 };
51224 /**
51225 * @return {?}
51226 */
51227 ItemSlidingGesture.prototype.destroy = function () {
51228 _super.prototype.destroy.call(this);
51229 this.closeOpened();
51230 this.list = null;
51231 this.preSelectedContainer = null;
51232 this.selectedContainer = null;
51233 this.openContainer = null;
51234 };
51235 return ItemSlidingGesture;
51236}(PanGesture));
51237/**
51238 * @param {?} ev
51239 * @return {?}
51240 */
51241function getContainer(ev) {
51242 var /** @type {?} */ ele = ev.target.closest('ion-item-sliding');
51243 if (ele) {
51244 return ((ele))['$ionComponent'];
51245 }
51246 return null;
51247}
51248/**
51249 * @param {?} ev
51250 * @return {?}
51251 */
51252function clickedOptionButton(ev) {
51253 var /** @type {?} */ ele = ev.target.closest('ion-item-options>button');
51254 return !!ele;
51255}
51256
51257var __extends$51 = (undefined && undefined.__extends) || (function () {
51258 var extendStatics = Object.setPrototypeOf ||
51259 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
51260 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
51261 return function (d, b) {
51262 extendStatics(d, b);
51263 function __() { this.constructor = d; }
51264 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
51265 };
51266})();
51267/**
51268 * The List is a widely used interface element in almost any mobile app,
51269 * and can include content ranging from basic text all the way to
51270 * buttons, toggles, icons, and thumbnails.
51271 *
51272 * Both the list, which contains items, and the list items themselves
51273 * can be any HTML element.
51274 *
51275 * Using the List and Item components make it easy to support various
51276 * interaction modes such as swipe to edit, drag to reorder, and
51277 * removing items.
51278 *
51279 * \@demo /docs/demos/src/list/
51280 * @see {\@link /docs/components#lists List Component Docs}
51281 * \@advanced
51282 *
51283 * Enable the sliding items.
51284 *
51285 * ```ts
51286 * import { Component, ViewChild } from '\@angular/core';
51287 * import { List } from 'ionic-angular';
51288 *
51289 * \@Component({...})
51290 * export class MyClass {
51291 * \@ViewChild(List) list: List;
51292 *
51293 * constructor() { }
51294 *
51295 * stopSliding() {
51296 * this.list.enableSlidingItems(false);
51297 * }
51298 * }
51299 * ```
51300 *
51301 */
51302var List = (function (_super) {
51303 __extends$51(List, _super);
51304 /**
51305 * @param {?} config
51306 * @param {?} elementRef
51307 * @param {?} renderer
51308 * @param {?} _plt
51309 * @param {?} _gestureCtrl
51310 * @param {?} _domCtrl
51311 */
51312 function List(config, elementRef, renderer, _plt, _gestureCtrl, _domCtrl) {
51313 var _this = _super.call(this, config, elementRef, renderer, 'list') || this;
51314 _this._plt = _plt;
51315 _this._gestureCtrl = _gestureCtrl;
51316 _this._domCtrl = _domCtrl;
51317 _this._enableSliding = true;
51318 _this._containsSlidingItems = false;
51319 return _this;
51320 }
51321 Object.defineProperty(List.prototype, "sliding", {
51322 /**
51323 * \@input {boolean} If true, the sliding items will be enabled.
51324 * @return {?}
51325 */
51326 get: function () {
51327 return this._enableSliding;
51328 },
51329 /**
51330 * @param {?} val
51331 * @return {?}
51332 */
51333 set: function (val) {
51334 this._enableSliding = isTrueProperty(val);
51335 this._updateSlidingState();
51336 },
51337 enumerable: true,
51338 configurable: true
51339 });
51340 /**
51341 * @hidden
51342 * @param {?} contains
51343 * @return {?}
51344 */
51345 List.prototype.containsSlidingItem = function (contains) {
51346 this._containsSlidingItems = contains;
51347 this._updateSlidingState();
51348 };
51349 /**
51350 * @return {?}
51351 */
51352 List.prototype._updateSlidingState = function () {
51353 var /** @type {?} */ shouldSlide = this._enableSliding && this._containsSlidingItems;
51354 if (!shouldSlide) {
51355 this._slidingGesture && this._slidingGesture.destroy();
51356 this._slidingGesture = null;
51357 }
51358 else if (!this._slidingGesture) {
51359 (void 0) /* console.debug */;
51360 this._slidingGesture = new ItemSlidingGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
51361 this._slidingGesture.listen();
51362 }
51363 };
51364 /**
51365 * Close any sliding items that are open.
51366 * @return {?}
51367 */
51368 List.prototype.closeSlidingItems = function () {
51369 this._slidingGesture && this._slidingGesture.closeOpened();
51370 };
51371 /**
51372 * @hidden
51373 * @return {?}
51374 */
51375 List.prototype.destroy = function () {
51376 this._slidingGesture && this._slidingGesture.destroy();
51377 };
51378 return List;
51379}(Ion));
51380List.decorators = [
51381 { type: Directive, args: [{
51382 selector: 'ion-list',
51383 },] },
51384];
51385/**
51386 * @nocollapse
51387 */
51388List.ctorParameters = function () { return [
51389 { type: Config, },
51390 { type: ElementRef, },
51391 { type: Renderer, },
51392 { type: Platform, },
51393 { type: GestureController, },
51394 { type: DomController, },
51395]; };
51396List.propDecorators = {
51397 'sliding': [{ type: Input },],
51398};
51399
51400var SWIPE_MARGIN = 30;
51401var ELASTIC_FACTOR = 0.55;
51402var ITEM_SIDE_FLAG_NONE = 0;
51403var ITEM_SIDE_FLAG_LEFT = 1 << 0;
51404var ITEM_SIDE_FLAG_RIGHT = 1 << 1;
51405var ITEM_SIDE_FLAG_BOTH = ITEM_SIDE_FLAG_LEFT | ITEM_SIDE_FLAG_RIGHT;
51406/**
51407 * \@name ItemSliding
51408 * \@description
51409 * A sliding item is a list item that can be swiped to reveal buttons. It requires
51410 * an [Item](../Item) component as a child and a [List](../../list/List) component as
51411 * a parent. All buttons to reveal can be placed in the `<ion-item-options>` element.
51412 *
51413 * \@usage
51414 * ```html
51415 * <ion-list>
51416 * <ion-item-sliding #item>
51417 * <ion-item>
51418 * Item
51419 * </ion-item>
51420 * <ion-item-options side="left">
51421 * <button ion-button (click)="favorite(item)">Favorite</button>
51422 * <button ion-button color="danger" (click)="share(item)">Share</button>
51423 * </ion-item-options>
51424 *
51425 * <ion-item-options side="right">
51426 * <button ion-button (click)="unread(item)">Unread</button>
51427 * </ion-item-options>
51428 * </ion-item-sliding>
51429 * </ion-list>
51430 * ```
51431 *
51432 * ### Swipe Direction
51433 * By default, the buttons are revealed when the sliding item is swiped from right to left,
51434 * so the buttons are placed in the right side. But it's also possible to reveal them
51435 * in the right side (sliding from left to right) by setting the `side` attribute
51436 * on the `ion-item-options` element. Up to 2 `ion-item-options` can used at the same time
51437 * in order to reveal two different sets of buttons depending the swipping direction.
51438 *
51439 * ```html
51440 * <ion-item-options side="right">
51441 * <button ion-button (click)="archive(item)">
51442 * <ion-icon name="archive"></ion-icon>
51443 * Archive
51444 * </button>
51445 * </ion-item-options>
51446 *
51447 * <ion-item-options side="left">
51448 * <button ion-button (click)="archive(item)">
51449 * <ion-icon name="archive"></ion-icon>
51450 * Archive
51451 * </button>
51452 * </ion-item-options>
51453 * ```
51454 *
51455 * ### Listening for events (ionDrag) and (ionSwipe)
51456 * It's possible to know the current relative position of the sliding item by subscribing
51457 * to the (ionDrag)` event.
51458 *
51459 * ```html
51460 * <ion-item-sliding (ionDrag)="logDrag($event)">
51461 * <ion-item>Item</ion-item>
51462 * <ion-item-options>
51463 * <button ion-button>Favorite</button>
51464 * </ion-item-options>
51465 * </ion-item-sliding>
51466 * ```
51467 *
51468 * ### Button Layout
51469 * If an icon is placed with text in the option button, by default it will
51470 * display the icon on top of the text. This can be changed to display the icon
51471 * to the left of the text by setting `icon-start` as an attribute on the
51472 * `<ion-item-options>` element.
51473 *
51474 * ```html
51475 * <ion-item-options icon-start>
51476 * <button ion-button (click)="archive(item)">
51477 * <ion-icon name="archive"></ion-icon>
51478 * Archive
51479 * </button>
51480 * </ion-item-options>
51481 *
51482 * ```
51483 *
51484 * ### Expandable Options
51485 *
51486 * Options can be expanded to take up the full width of the item if you swipe past
51487 * a certain point. This can be combined with the `ionSwipe` event to call methods
51488 * on the class.
51489 *
51490 * ```html
51491 *
51492 * <ion-item-sliding (ionSwipe)="delete(item)">
51493 * <ion-item>Item</ion-item>
51494 * <ion-item-options>
51495 * <button ion-button expandable (click)="delete(item)">Delete</button>
51496 * </ion-item-options>
51497 * </ion-item-sliding>
51498 * ```
51499 *
51500 * We can call `delete` by either clicking the button, or by doing a full swipe on the item.
51501 *
51502 * \@demo /docs/demos/src/item-sliding/
51503 * @see {\@link /docs/components#lists List Component Docs}
51504 * @see {\@link ../Item Item API Docs}
51505 * @see {\@link ../../list/List List API Docs}
51506 */
51507var ItemSliding = (function () {
51508 /**
51509 * @param {?} list
51510 * @param {?} _plt
51511 * @param {?} _renderer
51512 * @param {?} _elementRef
51513 * @param {?} _zone
51514 */
51515 function ItemSliding(list, _plt, _renderer, _elementRef, _zone) {
51516 this._plt = _plt;
51517 this._renderer = _renderer;
51518 this._elementRef = _elementRef;
51519 this._zone = _zone;
51520 this._openAmount = 0;
51521 this._startX = 0;
51522 this._optsWidthRightSide = 0;
51523 this._optsWidthLeftSide = 0;
51524 this._tmr = null;
51525 this._optsDirty = true;
51526 this._state = 2 /* Disabled */;
51527 /**
51528 * \@output {event} Emitted when the sliding position changes.
51529 * It reports the relative position.
51530 *
51531 * ```ts
51532 * ondrag(item) {
51533 * let percent = item.getSlidingPercent();
51534 * if (percent > 0) {
51535 * // positive
51536 * console.log('right side');
51537 * } else {
51538 * // negative
51539 * console.log('left side');
51540 * }
51541 * if (Math.abs(percent) > 1) {
51542 * console.log('overscroll');
51543 * }
51544 * }
51545 * ```
51546 *
51547 */
51548 this.ionDrag = new EventEmitter();
51549 list && list.containsSlidingItem(true);
51550 _elementRef.nativeElement.$ionComponent = this;
51551 this.setElementClass('item-wrapper', true);
51552 }
51553 Object.defineProperty(ItemSliding.prototype, "_itemOptions", {
51554 /**
51555 * @param {?} itemOptions
51556 * @return {?}
51557 */
51558 set: function (itemOptions) {
51559 var /** @type {?} */ sides = 0;
51560 // Reset left and right options in case they were removed
51561 this._leftOptions = this._rightOptions = null;
51562 for (var _i = 0, _a = itemOptions.toArray(); _i < _a.length; _i++) {
51563 var item = _a[_i];
51564 if (item.isRightSide()) {
51565 this._rightOptions = item;
51566 sides |= ITEM_SIDE_FLAG_RIGHT;
51567 }
51568 else {
51569 this._leftOptions = item;
51570 sides |= ITEM_SIDE_FLAG_LEFT;
51571 }
51572 }
51573 this._optsDirty = true;
51574 this._sides = sides;
51575 },
51576 enumerable: true,
51577 configurable: true
51578 });
51579 /**
51580 * @hidden
51581 * @return {?}
51582 */
51583 ItemSliding.prototype.getOpenAmount = function () {
51584 return this._openAmount;
51585 };
51586 /**
51587 * @hidden
51588 * @return {?}
51589 */
51590 ItemSliding.prototype.getSlidingPercent = function () {
51591 var /** @type {?} */ openAmount = this._openAmount;
51592 if (openAmount > 0) {
51593 return openAmount / this._optsWidthRightSide;
51594 }
51595 else if (openAmount < 0) {
51596 return openAmount / this._optsWidthLeftSide;
51597 }
51598 else {
51599 return 0;
51600 }
51601 };
51602 /**
51603 * @hidden
51604 * @param {?} startX
51605 * @return {?}
51606 */
51607 ItemSliding.prototype.startSliding = function (startX) {
51608 if (this._tmr) {
51609 this._plt.cancelTimeout(this._tmr);
51610 this._tmr = null;
51611 }
51612 if (this._openAmount === 0) {
51613 this._optsDirty = true;
51614 this._setState(4 /* Enabled */);
51615 }
51616 this._startX = startX + this._openAmount;
51617 this.item.setElementStyle(this._plt.Css.transition, 'none');
51618 };
51619 /**
51620 * @hidden
51621 * @param {?} x
51622 * @return {?}
51623 */
51624 ItemSliding.prototype.moveSliding = function (x) {
51625 if (this._optsDirty) {
51626 this.calculateOptsWidth();
51627 return;
51628 }
51629 var /** @type {?} */ openAmount = (this._startX - x);
51630 switch (this._sides) {
51631 case ITEM_SIDE_FLAG_RIGHT:
51632 openAmount = Math.max(0, openAmount);
51633 break;
51634 case ITEM_SIDE_FLAG_LEFT:
51635 openAmount = Math.min(0, openAmount);
51636 break;
51637 case ITEM_SIDE_FLAG_BOTH: break;
51638 case ITEM_SIDE_FLAG_NONE: return;
51639 default:
51640 (void 0) /* assert */;
51641 break;
51642 }
51643 if (openAmount > this._optsWidthRightSide) {
51644 var /** @type {?} */ optsWidth = this._optsWidthRightSide;
51645 openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
51646 }
51647 else if (openAmount < -this._optsWidthLeftSide) {
51648 var /** @type {?} */ optsWidth = -this._optsWidthLeftSide;
51649 openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
51650 }
51651 this._setOpenAmount(openAmount, false);
51652 return openAmount;
51653 };
51654 /**
51655 * @hidden
51656 * @param {?} velocity
51657 * @return {?}
51658 */
51659 ItemSliding.prototype.endSliding = function (velocity) {
51660 var /** @type {?} */ restingPoint = (this._openAmount > 0)
51661 ? this._optsWidthRightSide
51662 : -this._optsWidthLeftSide;
51663 // Check if the drag didn't clear the buttons mid-point
51664 // and we aren't moving fast enough to swipe open
51665 var /** @type {?} */ isResetDirection = (this._openAmount > 0) === !(velocity < 0);
51666 var /** @type {?} */ isMovingFast = Math.abs(velocity) > 0.3;
51667 var /** @type {?} */ isOnCloseZone = Math.abs(this._openAmount) < Math.abs(restingPoint / 2);
51668 if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) {
51669 restingPoint = 0;
51670 }
51671 this.fireSwipeEvent();
51672 this._setOpenAmount(restingPoint, true);
51673 return restingPoint;
51674 };
51675 /**
51676 * @hidden
51677 * @return {?}
51678 */
51679 ItemSliding.prototype.fireSwipeEvent = function () {
51680 var _this = this;
51681 if (this._state & 32 /* SwipeRight */) {
51682 this._zone.run(function () { return _this._rightOptions.ionSwipe.emit(_this); });
51683 }
51684 else if (this._state & 64 /* SwipeLeft */) {
51685 this._zone.run(function () { return _this._leftOptions.ionSwipe.emit(_this); });
51686 }
51687 };
51688 /**
51689 * @hidden
51690 * @return {?}
51691 */
51692 ItemSliding.prototype.calculateOptsWidth = function () {
51693 if (!this._optsDirty) {
51694 return;
51695 }
51696 this._optsWidthRightSide = 0;
51697 if (this._rightOptions) {
51698 this._optsWidthRightSide = this._rightOptions.width();
51699 (void 0) /* assert */;
51700 }
51701 this._optsWidthLeftSide = 0;
51702 if (this._leftOptions) {
51703 this._optsWidthLeftSide = this._leftOptions.width();
51704 (void 0) /* assert */;
51705 }
51706 this._optsDirty = false;
51707 };
51708 /**
51709 * @param {?} openAmount
51710 * @param {?} isFinal
51711 * @return {?}
51712 */
51713 ItemSliding.prototype._setOpenAmount = function (openAmount, isFinal) {
51714 var _this = this;
51715 var /** @type {?} */ platform = this._plt;
51716 if (this._tmr) {
51717 platform.cancelTimeout(this._tmr);
51718 this._tmr = null;
51719 }
51720 this._openAmount = openAmount;
51721 if (isFinal) {
51722 this.item.setElementStyle(platform.Css.transition, '');
51723 }
51724 if (openAmount > 0) {
51725 var /** @type {?} */ state$$1 = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN))
51726 ? 8 /* Right */ | 32 /* SwipeRight */
51727 : 8;
51728 this._setState(state$$1);
51729 }
51730 else if (openAmount < 0) {
51731 var /** @type {?} */ state_1 = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN))
51732 ? 16 /* Left */ | 64 /* SwipeLeft */
51733 : 16;
51734 this._setState(state_1);
51735 }
51736 else {
51737 (void 0) /* assert */;
51738 this._tmr = platform.timeout(function () {
51739 _this._setState(2 /* Disabled */);
51740 _this._tmr = null;
51741 }, 600);
51742 this.item.setElementStyle(platform.Css.transform, '');
51743 return;
51744 }
51745 this.item.setElementStyle(platform.Css.transform, "translate3d(" + -openAmount + "px,0,0)");
51746 var /** @type {?} */ ionDrag = this.ionDrag;
51747 if (ionDrag.observers.length > 0) {
51748 ionDrag.emit(this);
51749 }
51750 };
51751 /**
51752 * @param {?} state
51753 * @return {?}
51754 */
51755 ItemSliding.prototype._setState = function (state$$1) {
51756 if (state$$1 === this._state) {
51757 return;
51758 }
51759 this.setElementClass('active-slide', (state$$1 !== 2 /* Disabled */));
51760 this.setElementClass('active-options-right', !!(state$$1 & 8 /* Right */));
51761 this.setElementClass('active-options-left', !!(state$$1 & 16 /* Left */));
51762 this.setElementClass('active-swipe-right', !!(state$$1 & 32 /* SwipeRight */));
51763 this.setElementClass('active-swipe-left', !!(state$$1 & 64 /* SwipeLeft */));
51764 this._state = state$$1;
51765 };
51766 /**
51767 * Close the sliding item. Items can also be closed from the [List](../../list/List).
51768 *
51769 * The sliding item can be closed by grabbing a reference to `ItemSliding`. In the
51770 * below example, the template reference variable `slidingItem` is placed on the element
51771 * and passed to the `share` method.
51772 *
51773 * ```html
51774 * <ion-list>
51775 * <ion-item-sliding #slidingItem>
51776 * <ion-item>
51777 * Item
51778 * </ion-item>
51779 * <ion-item-options>
51780 * <button ion-button (click)="share(slidingItem)">Share</button>
51781 * </ion-item-options>
51782 * </ion-item-sliding>
51783 * </ion-list>
51784 * ```
51785 *
51786 * ```ts
51787 * import { Component } from '\@angular/core';
51788 * import { ItemSliding } from 'ionic-angular';
51789 *
51790 * \@Component({...})
51791 * export class MyClass {
51792 * constructor() { }
51793 *
51794 * share(slidingItem: ItemSliding) {
51795 * slidingItem.close();
51796 * }
51797 * }
51798 * ```
51799 * @return {?}
51800 */
51801 ItemSliding.prototype.close = function () {
51802 this._setOpenAmount(0, true);
51803 };
51804 /**
51805 * @hidden
51806 * @param {?} cssClass
51807 * @param {?} shouldAdd
51808 * @return {?}
51809 */
51810 ItemSliding.prototype.setElementClass = function (cssClass, shouldAdd) {
51811 this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd);
51812 };
51813 return ItemSliding;
51814}());
51815ItemSliding.decorators = [
51816 { type: Component, args: [{
51817 selector: 'ion-item-sliding',
51818 template: "\n <ng-content select=\"ion-item,[ion-item]\"></ng-content>\n <ng-content select=\"ion-item-options\"></ng-content>\n ",
51819 changeDetection: ChangeDetectionStrategy.OnPush,
51820 encapsulation: ViewEncapsulation.None
51821 },] },
51822];
51823/**
51824 * @nocollapse
51825 */
51826ItemSliding.ctorParameters = function () { return [
51827 { type: List, decorators: [{ type: Optional },] },
51828 { type: Platform, },
51829 { type: Renderer, },
51830 { type: ElementRef, },
51831 { type: NgZone, },
51832]; };
51833ItemSliding.propDecorators = {
51834 'item': [{ type: ContentChild, args: [Item,] },],
51835 'ionDrag': [{ type: Output },],
51836 '_itemOptions': [{ type: ContentChildren, args: [forwardRef(function () { return ItemOptions; }),] },],
51837};
51838
51839/**
51840 * @hidden
51841 */
51842var Reorder = (function () {
51843 /**
51844 * @param {?} elementRef
51845 */
51846 function Reorder(elementRef) {
51847 this.elementRef = elementRef;
51848 elementRef.nativeElement['$ionComponent'] = this;
51849 }
51850 /**
51851 * @return {?}
51852 */
51853 Reorder.prototype.getReorderNode = function () {
51854 return findReorderItem(this.elementRef.nativeElement, null);
51855 };
51856 /**
51857 * @param {?} ev
51858 * @return {?}
51859 */
51860 Reorder.prototype.onClick = function (ev) {
51861 // Stop propagation if click event reaches ion-reorder
51862 ev.preventDefault();
51863 ev.stopPropagation();
51864 };
51865 return Reorder;
51866}());
51867Reorder.decorators = [
51868 { type: Component, args: [{
51869 selector: 'ion-reorder',
51870 template: "<ion-icon name=\"reorder\"></ion-icon>"
51871 },] },
51872];
51873/**
51874 * @nocollapse
51875 */
51876Reorder.ctorParameters = function () { return [
51877 { type: ElementRef, },
51878]; };
51879Reorder.propDecorators = {
51880 'onClick': [{ type: HostListener, args: ['click', ['$event'],] },],
51881};
51882
51883var __extends$53 = (undefined && undefined.__extends) || (function () {
51884 var extendStatics = Object.setPrototypeOf ||
51885 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
51886 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
51887 return function (d, b) {
51888 extendStatics(d, b);
51889 function __() { this.constructor = d; }
51890 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
51891 };
51892})();
51893/**
51894 * @hidden
51895 */
51896var ListHeader = (function (_super) {
51897 __extends$53(ListHeader, _super);
51898 /**
51899 * @param {?} config
51900 * @param {?} renderer
51901 * @param {?} elementRef
51902 * @param {?} _id
51903 */
51904 function ListHeader(config, renderer, elementRef, _id) {
51905 var _this = _super.call(this, config, elementRef, renderer, 'list-header') || this;
51906 _this._id = _id;
51907 return _this;
51908 }
51909 Object.defineProperty(ListHeader.prototype, "id", {
51910 /**
51911 * @return {?}
51912 */
51913 get: function () {
51914 return this._id;
51915 },
51916 /**
51917 * @param {?} val
51918 * @return {?}
51919 */
51920 set: function (val) {
51921 this._id = val;
51922 this.setElementAttribute('id', val);
51923 },
51924 enumerable: true,
51925 configurable: true
51926 });
51927 return ListHeader;
51928}(Ion));
51929ListHeader.decorators = [
51930 { type: Directive, args: [{
51931 selector: 'ion-list-header'
51932 },] },
51933];
51934/**
51935 * @nocollapse
51936 */
51937ListHeader.ctorParameters = function () { return [
51938 { type: Config, },
51939 { type: Renderer, },
51940 { type: ElementRef, },
51941 { type: undefined, decorators: [{ type: Attribute, args: ['id',] },] },
51942]; };
51943
51944/**
51945 * @hidden
51946 */
51947var LoadingCmp = (function () {
51948 /**
51949 * @param {?} _viewCtrl
51950 * @param {?} _config
51951 * @param {?} _elementRef
51952 * @param {?} gestureCtrl
51953 * @param {?} params
51954 * @param {?} renderer
51955 */
51956 function LoadingCmp(_viewCtrl, _config, _elementRef, gestureCtrl, params, renderer) {
51957 this._viewCtrl = _viewCtrl;
51958 this._config = _config;
51959 (void 0) /* assert */;
51960 this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
51961 this.d = params.data;
51962 renderer.setElementClass(_elementRef.nativeElement, "loading-" + _config.get('mode'), true);
51963 if (this.d.cssClass) {
51964 this.d.cssClass.split(' ').forEach(function (cssClass) {
51965 // Make sure the class isn't whitespace, otherwise it throws exceptions
51966 if (cssClass.trim() !== '')
51967 renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
51968 });
51969 }
51970 this.id = (++loadingIds);
51971 }
51972 /**
51973 * @return {?}
51974 */
51975 LoadingCmp.prototype.ngOnInit = function () {
51976 // If no spinner was passed in loading options we need to fall back
51977 // to the loadingSpinner in the app's config, then the mode spinner
51978 if (isUndefined(this.d.spinner)) {
51979 this.d.spinner = this._config.get('loadingSpinner', this._config.get('spinner', 'ios'));
51980 }
51981 // If the user passed hide to the spinner we don't want to show it
51982 this.showSpinner = isDefined(this.d.spinner) && this.d.spinner !== 'hide';
51983 };
51984 /**
51985 * @return {?}
51986 */
51987 LoadingCmp.prototype.ionViewWillEnter = function () {
51988 this.gestureBlocker.block();
51989 };
51990 /**
51991 * @return {?}
51992 */
51993 LoadingCmp.prototype.ionViewDidLeave = function () {
51994 this.gestureBlocker.unblock();
51995 };
51996 /**
51997 * @return {?}
51998 */
51999 LoadingCmp.prototype.ionViewDidEnter = function () {
52000 var _this = this;
52001 // If there is a duration, dismiss after that amount of time
52002 if (this.d && this.d.duration) {
52003 this.durationTimeout = setTimeout(function () { return _this.dismiss('backdrop'); }, this.d.duration);
52004 }
52005 };
52006 /**
52007 * @param {?} ev
52008 * @return {?}
52009 */
52010 LoadingCmp.prototype.keyUp = function (ev) {
52011 if (this._viewCtrl.isLast() && ev.keyCode === KEY_ESCAPE) {
52012 this.bdClick();
52013 }
52014 };
52015 /**
52016 * @return {?}
52017 */
52018 LoadingCmp.prototype.bdClick = function () {
52019 if (this.d.enableBackdropDismiss) {
52020 this.dismiss('backdrop');
52021 }
52022 };
52023 /**
52024 * @param {?} role
52025 * @return {?}
52026 */
52027 LoadingCmp.prototype.dismiss = function (role) {
52028 if (this.durationTimeout) {
52029 clearTimeout(this.durationTimeout);
52030 }
52031 return this._viewCtrl.dismiss(null, role);
52032 };
52033 /**
52034 * @return {?}
52035 */
52036 LoadingCmp.prototype.ngOnDestroy = function () {
52037 (void 0) /* assert */;
52038 this.gestureBlocker.destroy();
52039 };
52040 return LoadingCmp;
52041}());
52042LoadingCmp.decorators = [
52043 { type: Component, args: [{
52044 selector: 'ion-loading',
52045 template: '<ion-backdrop [hidden]="!d.showBackdrop" (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
52046 '<div class="loading-wrapper">' +
52047 '<div *ngIf="showSpinner" class="loading-spinner">' +
52048 '<ion-spinner [name]="d.spinner"></ion-spinner>' +
52049 '</div>' +
52050 '<div *ngIf="d.content" [innerHTML]="d.content" class="loading-content"></div>' +
52051 '</div>',
52052 host: {
52053 'role': 'dialog'
52054 },
52055 encapsulation: ViewEncapsulation.None,
52056 },] },
52057];
52058/**
52059 * @nocollapse
52060 */
52061LoadingCmp.ctorParameters = function () { return [
52062 { type: ViewController, },
52063 { type: Config, },
52064 { type: ElementRef, },
52065 { type: GestureController, },
52066 { type: NavParams, },
52067 { type: Renderer, },
52068]; };
52069LoadingCmp.propDecorators = {
52070 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
52071};
52072var loadingIds = -1;
52073
52074var __extends$55 = (undefined && undefined.__extends) || (function () {
52075 var extendStatics = Object.setPrototypeOf ||
52076 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
52077 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
52078 return function (d, b) {
52079 extendStatics(d, b);
52080 function __() { this.constructor = d; }
52081 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52082 };
52083})();
52084/**
52085 * Animations for loading
52086 */
52087var LoadingPopIn = (function (_super) {
52088 __extends$55(LoadingPopIn, _super);
52089 function LoadingPopIn() {
52090 return _super !== null && _super.apply(this, arguments) || this;
52091 }
52092 /**
52093 * @return {?}
52094 */
52095 LoadingPopIn.prototype.init = function () {
52096 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
52097 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52098 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52099 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
52100 backdrop.fromTo('opacity', 0.01, 0.3);
52101 this
52102 .easing('ease-in-out')
52103 .duration(200)
52104 .add(backdrop)
52105 .add(wrapper);
52106 };
52107 return LoadingPopIn;
52108}(Transition));
52109var LoadingPopOut = (function (_super) {
52110 __extends$55(LoadingPopOut, _super);
52111 function LoadingPopOut() {
52112 return _super !== null && _super.apply(this, arguments) || this;
52113 }
52114 /**
52115 * @return {?}
52116 */
52117 LoadingPopOut.prototype.init = function () {
52118 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
52119 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52120 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52121 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
52122 backdrop.fromTo('opacity', 0.3, 0);
52123 this
52124 .easing('ease-in-out')
52125 .duration(200)
52126 .add(backdrop)
52127 .add(wrapper);
52128 };
52129 return LoadingPopOut;
52130}(Transition));
52131var LoadingMdPopIn = (function (_super) {
52132 __extends$55(LoadingMdPopIn, _super);
52133 function LoadingMdPopIn() {
52134 return _super !== null && _super.apply(this, arguments) || this;
52135 }
52136 /**
52137 * @return {?}
52138 */
52139 LoadingMdPopIn.prototype.init = function () {
52140 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
52141 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52142 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52143 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
52144 backdrop.fromTo('opacity', 0.01, 0.5);
52145 this
52146 .easing('ease-in-out')
52147 .duration(200)
52148 .add(backdrop)
52149 .add(wrapper);
52150 };
52151 return LoadingMdPopIn;
52152}(Transition));
52153var LoadingMdPopOut = (function (_super) {
52154 __extends$55(LoadingMdPopOut, _super);
52155 function LoadingMdPopOut() {
52156 return _super !== null && _super.apply(this, arguments) || this;
52157 }
52158 /**
52159 * @return {?}
52160 */
52161 LoadingMdPopOut.prototype.init = function () {
52162 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
52163 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52164 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52165 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
52166 backdrop.fromTo('opacity', 0.5, 0);
52167 this
52168 .easing('ease-in-out')
52169 .duration(200)
52170 .add(backdrop)
52171 .add(wrapper);
52172 };
52173 return LoadingMdPopOut;
52174}(Transition));
52175var LoadingWpPopIn = (function (_super) {
52176 __extends$55(LoadingWpPopIn, _super);
52177 function LoadingWpPopIn() {
52178 return _super !== null && _super.apply(this, arguments) || this;
52179 }
52180 /**
52181 * @return {?}
52182 */
52183 LoadingWpPopIn.prototype.init = function () {
52184 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
52185 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52186 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52187 wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
52188 backdrop.fromTo('opacity', 0.01, 0.16);
52189 this
52190 .easing('cubic-bezier(0,0,0.05,1)')
52191 .duration(200)
52192 .add(backdrop)
52193 .add(wrapper);
52194 };
52195 return LoadingWpPopIn;
52196}(Transition));
52197var LoadingWpPopOut = (function (_super) {
52198 __extends$55(LoadingWpPopOut, _super);
52199 function LoadingWpPopOut() {
52200 return _super !== null && _super.apply(this, arguments) || this;
52201 }
52202 /**
52203 * @return {?}
52204 */
52205 LoadingWpPopOut.prototype.init = function () {
52206 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
52207 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
52208 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
52209 wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
52210 backdrop.fromTo('opacity', 0.16, 0);
52211 this
52212 .easing('ease-out')
52213 .duration(150)
52214 .add(backdrop)
52215 .add(wrapper);
52216 };
52217 return LoadingWpPopOut;
52218}(Transition));
52219
52220var __extends$54 = (undefined && undefined.__extends) || (function () {
52221 var extendStatics = Object.setPrototypeOf ||
52222 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
52223 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
52224 return function (d, b) {
52225 extendStatics(d, b);
52226 function __() { this.constructor = d; }
52227 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52228 };
52229})();
52230/**
52231 * @hidden
52232 */
52233var Loading = (function (_super) {
52234 __extends$54(Loading, _super);
52235 /**
52236 * @param {?} app
52237 * @param {?=} opts
52238 * @param {?=} config
52239 */
52240 function Loading(app, opts, config) {
52241 if (opts === void 0) { opts = {}; }
52242 var _this = this;
52243 opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
52244 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : false;
52245 opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
52246 _this = _super.call(this, LoadingCmp, opts, null) || this;
52247 _this._app = app;
52248 _this.isOverlay = true;
52249 config.setTransition('loading-pop-in', LoadingPopIn);
52250 config.setTransition('loading-pop-out', LoadingPopOut);
52251 config.setTransition('loading-md-pop-in', LoadingMdPopIn);
52252 config.setTransition('loading-md-pop-out', LoadingMdPopOut);
52253 config.setTransition('loading-wp-pop-in', LoadingWpPopIn);
52254 config.setTransition('loading-wp-pop-out', LoadingWpPopOut);
52255 return _this;
52256 }
52257 /**
52258 * @hidden
52259 * @param {?} direction
52260 * @return {?}
52261 */
52262 Loading.prototype.getTransitionName = function (direction) {
52263 var /** @type {?} */ key = (direction === 'back' ? 'loadingLeave' : 'loadingEnter');
52264 return this._nav && this._nav.config.get(key);
52265 };
52266 /**
52267 * @param {?} content
52268 * @return {?}
52269 */
52270 Loading.prototype.setContent = function (content) {
52271 this.data.content = content;
52272 return this;
52273 };
52274 /**
52275 * @param {?} spinner
52276 * @return {?}
52277 */
52278 Loading.prototype.setSpinner = function (spinner) {
52279 this.data.spinner = spinner;
52280 return this;
52281 };
52282 /**
52283 * @param {?} cssClass
52284 * @return {?}
52285 */
52286 Loading.prototype.setCssClass = function (cssClass) {
52287 this.data.cssClass = cssClass;
52288 return this;
52289 };
52290 /**
52291 * @param {?} showBackdrop
52292 * @return {?}
52293 */
52294 Loading.prototype.setShowBackdrop = function (showBackdrop) {
52295 this.data.showBackdrop = showBackdrop;
52296 return this;
52297 };
52298 /**
52299 * @param {?} dur
52300 * @return {?}
52301 */
52302 Loading.prototype.setDuration = function (dur) {
52303 this.data.duration = dur;
52304 return this;
52305 };
52306 /**
52307 * Present the loading instance.
52308 *
52309 * @param {?=} navOptions
52310 * @return {?}
52311 */
52312 Loading.prototype.present = function (navOptions) {
52313 if (navOptions === void 0) { navOptions = {}; }
52314 return this._app.present(this, navOptions, PORTAL_LOADING);
52315 };
52316 /**
52317 * Dismiss all loading components which have been presented.
52318 * @return {?}
52319 */
52320 Loading.prototype.dismissAll = function () {
52321 this._nav && this._nav.popAll();
52322 };
52323 return Loading;
52324}(ViewController));
52325
52326/**
52327 * \@name LoadingController
52328 * \@description
52329 * An overlay that can be used to indicate activity while blocking user
52330 * interaction. The loading indicator appears on top of the app's content,
52331 * and can be dismissed by the app to resume user interaction with
52332 * the app. It includes an optional backdrop, which can be disabled
52333 * by setting `showBackdrop: false` upon creation.
52334 *
52335 * ### Creating
52336 * You can pass all of the loading options in the first argument of
52337 * the create method: `create(opts)`. The spinner name should be
52338 * passed in the `spinner` property, and any optional HTML can be passed
52339 * in the `content` property. If you do not pass a value to `spinner`
52340 * the loading indicator will use the spinner specified by the mode. To
52341 * set the spinner name across the app, set the value of `loadingSpinner`
52342 * in your app's config. To hide the spinner, set `loadingSpinner: 'hide'`
52343 * in the app's config or pass `spinner: 'hide'` in the loading
52344 * options. See the [create](#create) method below for all available options.
52345 *
52346 * ### Dismissing
52347 * The loading indicator can be dismissed automatically after a specific
52348 * amount of time by passing the number of milliseconds to display it in
52349 * the `duration` of the loading options. By default the loading indicator
52350 * will show even during page changes, but this can be disabled by setting
52351 * `dismissOnPageChange` to `true`. To dismiss the loading indicator after
52352 * creation, call the `dismiss()` method on the Loading instance. The
52353 * `onDidDismiss` function can be called to perform an action after the loading
52354 * indicator is dismissed.
52355 *
52356 * >Note that after the component is dismissed, it will not be usable anymore
52357 * and another one must be created. This can be avoided by wrapping the
52358 * creation and presentation of the component in a reusable function as shown
52359 * in the `usage` section below.
52360 *
52361 * ### Limitations
52362 * The element is styled to appear on top of other content by setting its
52363 * `z-index` property. You must ensure no element has a stacking context with
52364 * a higher `z-index` than this element.
52365 *
52366 * \@usage
52367 * ```ts
52368 * import { LoadingController } from 'ionic-angular';
52369 *
52370 * constructor(public loadingCtrl: LoadingController) { }
52371 *
52372 * presentLoadingDefault() {
52373 * const loading = this.loadingCtrl.create({
52374 * content: 'Please wait...'
52375 * });
52376 *
52377 * loading.present();
52378 *
52379 * setTimeout(() => {
52380 * loading.dismiss();
52381 * }, 5000);
52382 * }
52383 *
52384 * presentLoadingCustom() {
52385 * const loading = this.loadingCtrl.create({
52386 * spinner: 'hide',
52387 * content: `
52388 * <div class="custom-spinner-container">
52389 * <div class="custom-spinner-box"></div>
52390 * </div>`,
52391 * duration: 5000
52392 * });
52393 *
52394 * loading.onDidDismiss(() => {
52395 * console.log('Dismissed loading');
52396 * });
52397 *
52398 * loading.present();
52399 * }
52400 *
52401 * presentLoadingText() {
52402 * const loading = this.loadingCtrl.create({
52403 * spinner: 'hide',
52404 * content: 'Loading Please Wait...'
52405 * });
52406 *
52407 * loading.present();
52408 *
52409 * setTimeout(() => {
52410 * this.nav.push(Page2);
52411 * }, 1000);
52412 *
52413 * setTimeout(() => {
52414 * loading.dismiss();
52415 * }, 5000);
52416 * }
52417 * ```
52418 * \@advanced
52419 *
52420 * Loading options
52421 *
52422 * | Option | Type | Description |
52423 * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
52424 * | spinner |`string` | The name of the SVG spinner for the loading indicator. |
52425 * | content |`string` | The html content for the loading indicator. |
52426 * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
52427 * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
52428 * | enableBackdropDismiss | `boolean` | Whether the loading indicator should be dismissed by tapping the backdrop. Default false. |
52429 * | dismissOnPageChange |`boolean` | Whether to dismiss the indicator when navigating to a new page. Default false. |
52430 * | duration |`number` | How many milliseconds to wait before hiding the indicator. By default, it will show until `dismiss()` is called. |
52431 *
52432 * \@demo /docs/demos/src/loading/
52433 * @see {\@link /docs/api/components/spinner/Spinner Spinner API Docs}
52434 */
52435var LoadingController = (function () {
52436 /**
52437 * @param {?} _app
52438 * @param {?} config
52439 */
52440 function LoadingController(_app, config) {
52441 this._app = _app;
52442 this.config = config;
52443 }
52444 /**
52445 * Create a loading indicator. See below for options.
52446 * @param {?=} opts
52447 * @return {?}
52448 */
52449 LoadingController.prototype.create = function (opts) {
52450 if (opts === void 0) { opts = {}; }
52451 return new Loading(this._app, opts, this.config);
52452 };
52453 return LoadingController;
52454}());
52455LoadingController.decorators = [
52456 { type: Injectable },
52457];
52458/**
52459 * @nocollapse
52460 */
52461LoadingController.ctorParameters = function () { return [
52462 { type: App, },
52463 { type: Config, },
52464]; };
52465
52466var __extends$56 = (undefined && undefined.__extends) || (function () {
52467 var extendStatics = Object.setPrototypeOf ||
52468 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
52469 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
52470 return function (d, b) {
52471 extendStatics(d, b);
52472 function __() { this.constructor = d; }
52473 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52474 };
52475})();
52476/**
52477 * Gesture attached to the content which the menu is assigned to
52478 */
52479var MenuContentGesture = (function (_super) {
52480 __extends$56(MenuContentGesture, _super);
52481 /**
52482 * @param {?} plt
52483 * @param {?} menu
52484 * @param {?} gestureCtrl
52485 * @param {?} domCtrl
52486 */
52487 function MenuContentGesture(plt, menu, gestureCtrl, domCtrl) {
52488 var _this = _super.call(this, plt, plt.doc().body, {
52489 direction: 'x',
52490 edge: menu.side,
52491 threshold: 5,
52492 maxEdgeStart: menu.maxEdgeStart || 50,
52493 zone: false,
52494 passive: true,
52495 domController: domCtrl,
52496 gesture: gestureCtrl.createGesture({
52497 name: GESTURE_MENU_SWIPE,
52498 priority: GESTURE_PRIORITY_MENU_SWIPE,
52499 disableScroll: true
52500 })
52501 }) || this;
52502 _this.menu = menu;
52503 return _this;
52504 }
52505 /**
52506 * @param {?} ev
52507 * @return {?}
52508 */
52509 MenuContentGesture.prototype.canStart = function (ev) {
52510 var /** @type {?} */ menu = this.menu;
52511 if (!menu.canSwipe()) {
52512 return false;
52513 }
52514 if (menu.isOpen) {
52515 return true;
52516 }
52517 else if (menu.getMenuController().getOpen()) {
52518 return false;
52519 }
52520 return _super.prototype.canStart.call(this, ev);
52521 };
52522 /**
52523 * @return {?}
52524 */
52525 MenuContentGesture.prototype.onSlideBeforeStart = function () {
52526 (void 0) /* console.debug */;
52527 this.menu._swipeBeforeStart();
52528 };
52529 /**
52530 * @return {?}
52531 */
52532 MenuContentGesture.prototype.onSlideStart = function () {
52533 (void 0) /* console.debug */;
52534 this.menu._swipeStart();
52535 };
52536 /**
52537 * @param {?} slide
52538 * @return {?}
52539 */
52540 MenuContentGesture.prototype.onSlide = function (slide) {
52541 var /** @type {?} */ z = (this.menu.isRightSide !== this.plt.isRTL ? slide.min : slide.max);
52542 var /** @type {?} */ stepValue = (slide.distance / z);
52543 this.menu._swipeProgress(stepValue);
52544 };
52545 /**
52546 * @param {?} slide
52547 * @return {?}
52548 */
52549 MenuContentGesture.prototype.onSlideEnd = function (slide) {
52550 var /** @type {?} */ z = (this.menu.isRightSide !== this.plt.isRTL ? slide.min : slide.max);
52551 var /** @type {?} */ currentStepValue = (slide.distance / z);
52552 var /** @type {?} */ velocity = slide.velocity;
52553 z = Math.abs(z * 0.5);
52554 var /** @type {?} */ shouldCompleteRight = (velocity >= 0)
52555 && (velocity > 0.2 || slide.delta > z);
52556 var /** @type {?} */ shouldCompleteLeft = (velocity <= 0)
52557 && (velocity < -0.2 || slide.delta < -z);
52558 (void 0) /* console.debug */;
52559 this.menu._swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue, velocity);
52560 };
52561 /**
52562 * @param {?} slide
52563 * @return {?}
52564 */
52565 MenuContentGesture.prototype.getElementStartPos = function (slide) {
52566 var /** @type {?} */ menu = this.menu;
52567 if (menu.isRightSide !== this.plt.isRTL) {
52568 return menu.isOpen ? slide.min : slide.max;
52569 }
52570 // left menu
52571 return menu.isOpen ? slide.max : slide.min;
52572 };
52573 /**
52574 * @return {?}
52575 */
52576 MenuContentGesture.prototype.getSlideBoundaries = function () {
52577 var /** @type {?} */ menu = this.menu;
52578 if (menu.isRightSide !== this.plt.isRTL) {
52579 return {
52580 min: -menu.width(),
52581 max: 0
52582 };
52583 }
52584 // left menu
52585 return {
52586 min: 0,
52587 max: menu.width()
52588 };
52589 };
52590 return MenuContentGesture;
52591}(SlideEdgeGesture));
52592
52593var __extends$58 = (undefined && undefined.__extends) || (function () {
52594 var extendStatics = Object.setPrototypeOf ||
52595 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
52596 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
52597 return function (d, b) {
52598 extendStatics(d, b);
52599 function __() { this.constructor = d; }
52600 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52601 };
52602})();
52603var QUERY = {
52604 xs: '(min-width: 0px)',
52605 sm: '(min-width: 576px)',
52606 md: '(min-width: 768px)',
52607 lg: '(min-width: 992px)',
52608 xl: '(min-width: 1200px)',
52609 never: ''
52610};
52611/**
52612 * @hidden
52613 * @abstract
52614 */
52615var RootNode = (function () {
52616 function RootNode() {
52617 }
52618 /**
52619 * @abstract
52620 * @return {?}
52621 */
52622 RootNode.prototype.getElementRef = function () { };
52623 /**
52624 * @abstract
52625 * @return {?}
52626 */
52627 RootNode.prototype.initPane = function () { };
52628 /**
52629 * @abstract
52630 * @param {?} visible
52631 * @return {?}
52632 */
52633 RootNode.prototype.paneChanged = function (visible) { };
52634 return RootNode;
52635}());
52636/**
52637 * \@name SplitPane
52638 *
52639 * \@description
52640 * SplitPane is a component that makes it possible to create multi-view layout.
52641 * Similar to iPad apps, SplitPane allows UI elements, like Menus, to be
52642 * displayed as the viewport increases.
52643 *
52644 * If the devices screen size is below a certain size, the SplitPane will
52645 * collapse and the menu will become hidden again. This is especially useful when
52646 * creating an app that will be served over a browser or deployed through the app
52647 * store to phones and tablets.
52648 *
52649 * \@usage
52650 * To use SplitPane, simply add the component around your root component.
52651 * In this example, we'll be using a sidemenu layout, similar to what is
52652 * provided from the sidemenu starter template.
52653 *
52654 * ```html
52655 * <ion-split-pane>
52656 * <!-- our side menu -->
52657 * <ion-menu [content]="content">
52658 * <ion-header>
52659 * <ion-toolbar>
52660 * <ion-title>Menu</ion-title>
52661 * </ion-toolbar>
52662 * </ion-header>
52663 * </ion-menu>
52664 *
52665 * <!-- the main content -->
52666 * <ion-nav [root]="root" main #content></ion-nav>
52667 * </ion-split-pane>
52668 * ```
52669 *
52670 * Here, SplitPane will look for the element with the `main` attribute and make
52671 * that the central component on larger screens. The `main` component can be any
52672 * Ionic component (`ion-nav` or `ion-tabs`) except `ion-menu`.
52673 *
52674 * ### Setting breakpoints
52675 *
52676 * By default, SplitPane will expand when the screen is larger than 768px.
52677 * If you want to customize this, use the `when` input. The `when` input can
52678 * accept any valid media query, as it uses `matchMedia()` underneath.
52679 *
52680 * ```
52681 * <ion-split-pane when="(min-width: 475px)">
52682 *
52683 * <!-- our side menu -->
52684 * <ion-menu [content]="content">
52685 * ....
52686 * </ion-menu>
52687 *
52688 * <!-- the main content -->
52689 * <ion-nav [root]="root" main #content></ion-nav>
52690 * </ion-split-pane>
52691 * ```
52692 *
52693 * SplitPane also provides some predefined media queries that can be used.
52694 *
52695 * ```html
52696 * <!-- could be "xs", "sm", "md", "lg", or "xl" -->
52697 * <ion-split-pane when="lg">
52698 * ...
52699 * </ion-split-pane>
52700 * ```
52701 *
52702 *
52703 * | Size | Value | Description |
52704 * |------|-----------------------|-----------------------------------------------------------------------|
52705 * | `xs` | `(min-width: 0px)` | Show the split-pane when the min-width is 0px (meaning, always) |
52706 * | `sm` | `(min-width: 576px)` | Show the split-pane when the min-width is 576px |
52707 * | `md` | `(min-width: 768px)` | Show the split-pane when the min-width is 768px (default break point) |
52708 * | `lg` | `(min-width: 992px)` | Show the split-pane when the min-width is 992px |
52709 * | `xl` | `(min-width: 1200px)` | Show the split-pane when the min-width is 1200px |
52710 *
52711 * You can also pass in boolean values that will trigger SplitPane when the value
52712 * or expression evaluates to true.
52713 *
52714 *
52715 * ```html
52716 * <ion-split-pane [when]="isLarge">
52717 * ...
52718 * </ion-split-pane>
52719 * ```
52720 *
52721 * ```ts
52722 * class MyClass {
52723 * public isLarge = false;
52724 * constructor(){}
52725 * }
52726 * ```
52727 *
52728 * Or
52729 *
52730 * ```html
52731 * <ion-split-pane [when]="shouldShow()">
52732 * ...
52733 * </ion-split-pane>
52734 * ```
52735 *
52736 * ```ts
52737 * class MyClass {
52738 * constructor(){}
52739 * shouldShow(){
52740 * if(conditionA){
52741 * return true
52742 * } else {
52743 * return false
52744 * }
52745 * }
52746 * }
52747 * ```
52748 *
52749 */
52750var SplitPane = (function (_super) {
52751 __extends$58(SplitPane, _super);
52752 /**
52753 * @param {?} _zone
52754 * @param {?} _plt
52755 * @param {?} config
52756 * @param {?} elementRef
52757 * @param {?} renderer
52758 */
52759 function SplitPane(_zone, _plt, config, elementRef, renderer) {
52760 var _this = _super.call(this, config, elementRef, renderer, 'split-pane') || this;
52761 _this._zone = _zone;
52762 _this._plt = _plt;
52763 _this._init = false;
52764 _this._visible = false;
52765 _this._isEnabled = true;
52766 _this._mediaQuery = QUERY['md'];
52767 /**
52768 * @hidden
52769 */
52770 _this.sideContent = null;
52771 /**
52772 * @hidden
52773 */
52774 _this.mainContent = null;
52775 /**
52776 * \@output {any} Expression to be called when the split-pane visibility has changed
52777 */
52778 _this.ionChange = new EventEmitter();
52779 return _this;
52780 }
52781 Object.defineProperty(SplitPane.prototype, "_setchildren", {
52782 /**
52783 * @hidden
52784 * @param {?} query
52785 * @return {?}
52786 */
52787 set: function (query) {
52788 var _this = this;
52789 var /** @type {?} */ children = this._children = query.filter((function (child) { return child !== _this; }));
52790 children.forEach(function (child) {
52791 var /** @type {?} */ isMain = child.initPane();
52792 _this._setPaneCSSClass(child.getElementRef(), isMain);
52793 });
52794 },
52795 enumerable: true,
52796 configurable: true
52797 });
52798 Object.defineProperty(SplitPane.prototype, "when", {
52799 /**
52800 * @return {?}
52801 */
52802 get: function () {
52803 return this._mediaQuery;
52804 },
52805 /**
52806 * \@input {string | boolean} When the split-pane should be shown.
52807 * Can be a CSS media query expression, or a shortcut expression.
52808 * Can also be a boolean expression.
52809 * @param {?} query
52810 * @return {?}
52811 */
52812 set: function (query) {
52813 if (typeof query === 'boolean') {
52814 this._mediaQuery = query;
52815 }
52816 else {
52817 var /** @type {?} */ defaultQuery = QUERY[query];
52818 this._mediaQuery = (defaultQuery)
52819 ? defaultQuery
52820 : query;
52821 }
52822 this._update();
52823 },
52824 enumerable: true,
52825 configurable: true
52826 });
52827 Object.defineProperty(SplitPane.prototype, "enabled", {
52828 /**
52829 * @return {?}
52830 */
52831 get: function () {
52832 return this._isEnabled;
52833 },
52834 /**
52835 * \@input {boolean} If `false`, the split-pane is disabled, ie. the side pane will
52836 * never be displayed. Default `true`.
52837 * @param {?} val
52838 * @return {?}
52839 */
52840 set: function (val) {
52841 this._isEnabled = isTrueProperty(val);
52842 this._update();
52843 },
52844 enumerable: true,
52845 configurable: true
52846 });
52847 /**
52848 * @hidden
52849 * @param {?} node
52850 * @param {?} isMain
52851 * @param {?} callback
52852 * @return {?}
52853 */
52854 SplitPane.prototype._register = function (node, isMain, callback) {
52855 if (this.getElementRef().nativeElement !== node.getElementRef().nativeElement.parentNode) {
52856 return false;
52857 }
52858 this._setPaneCSSClass(node.getElementRef(), isMain);
52859 if (callback) {
52860 this.ionChange.subscribe(callback);
52861 }
52862 if (isMain) {
52863 if (this.mainContent) {
52864 console.error('split pane: main content was already set');
52865 }
52866 this.mainContent = node;
52867 }
52868 return true;
52869 };
52870 /**
52871 * @hidden
52872 * @return {?}
52873 */
52874 SplitPane.prototype.ngAfterViewInit = function () {
52875 this._init = true;
52876 this._update();
52877 };
52878 /**
52879 * @hidden
52880 * @return {?}
52881 */
52882 SplitPane.prototype._update = function () {
52883 var _this = this;
52884 if (!this._init) {
52885 return;
52886 }
52887 // Unlisten
52888 this._rmListener && this._rmListener();
52889 this._rmListener = null;
52890 // Check if the split-pane is disabled
52891 if (!this._isEnabled) {
52892 this._setVisible(false);
52893 return;
52894 }
52895 var /** @type {?} */ query = this._mediaQuery;
52896 if (typeof query === 'boolean') {
52897 this._setVisible(query);
52898 return;
52899 }
52900 if (query && query.length > 0) {
52901 // Listen
52902 var /** @type {?} */ callback_1 = function (query) { return _this._setVisible(query.matches); };
52903 var /** @type {?} */ mediaList_1 = this._plt.win().matchMedia(query);
52904 mediaList_1.addListener(callback_1);
52905 this._setVisible(mediaList_1.matches);
52906 this._rmListener = function () {
52907 mediaList_1.removeListener(callback_1);
52908 };
52909 }
52910 else {
52911 this._setVisible(false);
52912 }
52913 };
52914 /**
52915 * @hidden
52916 * @return {?}
52917 */
52918 SplitPane.prototype._updateChildren = function () {
52919 this.mainContent = null;
52920 this.sideContent = null;
52921 var /** @type {?} */ visible = this._visible;
52922 this._children.forEach(function (child) { return child.paneChanged && child.paneChanged(visible); });
52923 };
52924 /**
52925 * @hidden
52926 * @param {?} visible
52927 * @return {?}
52928 */
52929 SplitPane.prototype._setVisible = function (visible) {
52930 var _this = this;
52931 if (this._visible === visible) {
52932 return;
52933 }
52934 this._visible = visible;
52935 this.setElementClass('split-pane-visible', visible);
52936 this._updateChildren();
52937 this._zone.run(function () {
52938 _this.ionChange.emit(_this);
52939 });
52940 };
52941 /**
52942 * @hidden
52943 * @return {?}
52944 */
52945 SplitPane.prototype.isVisible = function () {
52946 return this._visible;
52947 };
52948 /**
52949 * @hidden
52950 * @param {?} className
52951 * @param {?} add
52952 * @return {?}
52953 */
52954 SplitPane.prototype.setElementClass = function (className, add) {
52955 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
52956 };
52957 /**
52958 * @hidden
52959 * @param {?} elementRef
52960 * @param {?} isMain
52961 * @return {?}
52962 */
52963 SplitPane.prototype._setPaneCSSClass = function (elementRef, isMain) {
52964 var /** @type {?} */ ele = elementRef.nativeElement;
52965 this._renderer.setElementClass(ele, 'split-pane-main', isMain);
52966 this._renderer.setElementClass(ele, 'split-pane-side', !isMain);
52967 };
52968 /**
52969 * @hidden
52970 * @return {?}
52971 */
52972 SplitPane.prototype.ngOnDestroy = function () {
52973 (void 0) /* assert */;
52974 this._rmListener && this._rmListener();
52975 this._rmListener = null;
52976 };
52977 /**
52978 * @hidden
52979 * @return {?}
52980 */
52981 SplitPane.prototype.initPane = function () {
52982 return true;
52983 };
52984 return SplitPane;
52985}(Ion));
52986SplitPane.decorators = [
52987 { type: Directive, args: [{
52988 selector: 'ion-split-pane',
52989 providers: [{ provide: RootNode, useExisting: forwardRef(function () { return SplitPane; }) }]
52990 },] },
52991];
52992/**
52993 * @nocollapse
52994 */
52995SplitPane.ctorParameters = function () { return [
52996 { type: NgZone, },
52997 { type: Platform, },
52998 { type: Config, },
52999 { type: ElementRef, },
53000 { type: Renderer, },
53001]; };
53002SplitPane.propDecorators = {
53003 '_setchildren': [{ type: ContentChildren, args: [RootNode, { descendants: false },] },],
53004 'when': [{ type: Input },],
53005 'enabled': [{ type: Input },],
53006 'ionChange': [{ type: Output },],
53007};
53008
53009var __extends$57 = (undefined && undefined.__extends) || (function () {
53010 var extendStatics = Object.setPrototypeOf ||
53011 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
53012 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
53013 return function (d, b) {
53014 extendStatics(d, b);
53015 function __() { this.constructor = d; }
53016 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
53017 };
53018})();
53019/**
53020 * \@name Nav
53021 * \@description
53022 *
53023 * `ion-nav` is the declarative component for a [NavController](../../../navigation/NavController/).
53024 *
53025 * For more information on using nav controllers like Nav or [Tab](../../Tabs/Tab/),
53026 * take a look at the [NavController API Docs](../../../navigation/NavController/).
53027 *
53028 *
53029 * \@usage
53030 * You must set a root page to be loaded initially by any Nav you create, using
53031 * the 'root' property:
53032 *
53033 * ```ts
53034 * import { Component } from '\@angular/core';
53035 * import { GettingStartedPage } from './getting-started';
53036 *
53037 * \@Component({
53038 * template: `<ion-nav [root]="root"></ion-nav>`
53039 * })
53040 * class MyApp {
53041 * root = GettingStartedPage;
53042 *
53043 * constructor(){
53044 * }
53045 * }
53046 * ```
53047 *
53048 * \@demo /docs/demos/src/navigation/
53049 * @see {\@link /docs/components#navigation Navigation Component Docs}
53050 */
53051var Nav = (function (_super) {
53052 __extends$57(Nav, _super);
53053 /**
53054 * @param {?} viewCtrl
53055 * @param {?} parent
53056 * @param {?} app
53057 * @param {?} config
53058 * @param {?} plt
53059 * @param {?} elementRef
53060 * @param {?} zone
53061 * @param {?} renderer
53062 * @param {?} cfr
53063 * @param {?} gestureCtrl
53064 * @param {?} transCtrl
53065 * @param {?} linker
53066 * @param {?} domCtrl
53067 * @param {?} errHandler
53068 */
53069 function Nav(viewCtrl, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) {
53070 var _this = _super.call(this, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) || this;
53071 _this._hasInit = false;
53072 if (viewCtrl) {
53073 // an ion-nav can also act as an ion-page within a parent ion-nav
53074 // this would happen when an ion-nav nests a child ion-nav.
53075 viewCtrl._setContent(_this);
53076 }
53077 if (parent) {
53078 // this Nav has a parent Nav
53079 parent.registerChildNav(_this);
53080 }
53081 else if (viewCtrl && viewCtrl.getNav()) {
53082 // this Nav was opened from a modal
53083 _this.parent = viewCtrl.getNav();
53084 _this.parent.registerChildNav(_this);
53085 }
53086 else if (app && !app.getRootNavById(_this.id)) {
53087 // a root nav has not been registered yet with the app
53088 // this is the root navcontroller for the entire app
53089 app.registerRootNav(_this);
53090 }
53091 return _this;
53092 }
53093 Object.defineProperty(Nav.prototype, "_vp", {
53094 /**
53095 * @hidden
53096 * @param {?} val
53097 * @return {?}
53098 */
53099 set: function (val) {
53100 this.setViewport(val);
53101 },
53102 enumerable: true,
53103 configurable: true
53104 });
53105 /**
53106 * @return {?}
53107 */
53108 Nav.prototype.ngAfterViewInit = function () {
53109 var _this = this;
53110 this._hasInit = true;
53111 var /** @type {?} */ segment = this._linker.getSegmentByNavIdOrName(this.id, this.name);
53112 if (segment && (segment.component || segment.loadChildren)) {
53113 return this._linker.initViews(segment).then(function (views) {
53114 return _this.setPages(views, null, null);
53115 });
53116 }
53117 else if (this._root) {
53118 // no segment match, so use the root property but don't set the url I guess
53119 var /** @type {?} */ setUrl = segment ? false : true;
53120 return this.push(this._root, this.rootParams, {
53121 isNavRoot: ((this._app.getRootNavById(this.id)) === this),
53122 updateUrl: setUrl
53123 }, null);
53124 }
53125 };
53126 Object.defineProperty(Nav.prototype, "root", {
53127 /**
53128 * \@input {Page} The Page component to load as the root page within this nav.
53129 * @return {?}
53130 */
53131 get: function () {
53132 return this._root;
53133 },
53134 /**
53135 * @param {?} page
53136 * @return {?}
53137 */
53138 set: function (page) {
53139 this._root = page;
53140 if (this._hasInit) {
53141 this.setRoot(page);
53142 }
53143 },
53144 enumerable: true,
53145 configurable: true
53146 });
53147 /**
53148 * @hidden
53149 * @return {?}
53150 */
53151 Nav.prototype.ngOnDestroy = function () {
53152 this.destroy();
53153 };
53154 /**
53155 * @return {?}
53156 */
53157 Nav.prototype.initPane = function () {
53158 var /** @type {?} */ isMain = this._elementRef.nativeElement.hasAttribute('main');
53159 return isMain;
53160 };
53161 /**
53162 * @param {?} isPane
53163 * @return {?}
53164 */
53165 Nav.prototype.paneChanged = function (isPane) {
53166 if (isPane) {
53167 this.resize();
53168 }
53169 };
53170 /**
53171 * @param {?} opts
53172 * @return {?}
53173 */
53174 Nav.prototype.goToRoot = function (opts) {
53175 return this.setRoot(this._root, this.rootParams, opts, null);
53176 };
53177 /**
53178 * @return {?}
53179 */
53180 Nav.prototype.getType = function () {
53181 return 'nav';
53182 };
53183 /**
53184 * @return {?}
53185 */
53186 Nav.prototype.getSecondaryIdentifier = function () {
53187 return null;
53188 };
53189 return Nav;
53190}(NavControllerBase));
53191Nav.decorators = [
53192 { type: Component, args: [{
53193 selector: 'ion-nav',
53194 template: '<div #viewport nav-viewport></div>' +
53195 '<div class="nav-decor"></div>',
53196 encapsulation: ViewEncapsulation.None,
53197 providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Nav; }) }]
53198 },] },
53199];
53200/**
53201 * @nocollapse
53202 */
53203Nav.ctorParameters = function () { return [
53204 { type: ViewController, decorators: [{ type: Optional },] },
53205 { type: NavController, decorators: [{ type: Optional },] },
53206 { type: App, },
53207 { type: Config, },
53208 { type: Platform, },
53209 { type: ElementRef, },
53210 { type: NgZone, },
53211 { type: Renderer, },
53212 { type: ComponentFactoryResolver, },
53213 { type: GestureController, },
53214 { type: TransitionController, },
53215 { type: DeepLinker, decorators: [{ type: Optional },] },
53216 { type: DomController, },
53217 { type: ErrorHandler, },
53218]; };
53219Nav.propDecorators = {
53220 '_vp': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
53221 'root': [{ type: Input },],
53222 'rootParams': [{ type: Input },],
53223 'name': [{ type: Input },],
53224};
53225
53226/**
53227 * \@name Menu
53228 * \@description
53229 * The Menu component is a navigation drawer that slides in from the side of the current
53230 * view. By default, it slides in from the left, but the side can be overridden. The menu
53231 * will be displayed differently based on the mode, however the display type can be changed
53232 * to any of the available [menu types](#menu-types). The menu element should be a sibling
53233 * to the app's content element. There can be any number of menus attached to the content.
53234 * These can be controlled from the templates, or programmatically using the [MenuController](../../app/MenuController).
53235 *
53236 * \@usage
53237 *
53238 * ```html
53239 * <ion-menu [content]="mycontent">
53240 * <ion-content>
53241 * <ion-list>
53242 * <p>some menu content, could be list items</p>
53243 * </ion-list>
53244 * </ion-content>
53245 * </ion-menu>
53246 *
53247 * <ion-nav #mycontent [root]="rootPage"></ion-nav>
53248 * ```
53249 *
53250 * To add a menu to an app, the `<ion-menu>` element should be added as a sibling to the `ion-nav` it will belongs
53251 * to. A [local variable](https://angular.io/docs/ts/latest/guide/user-input.html#local-variables)
53252 * should be added to the `ion-nav` and passed to the `ion-menu`s `content` property.
53253 *
53254 * This tells the menu what it is bound to and what element to watch for gestures.
53255 * In the below example, `content` is using [property binding](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding)
53256 * because `mycontent` is a reference to the `<ion-nav>` element, and not a string.
53257 *
53258 *
53259 * ### Opening/Closing Menus
53260 *
53261 * There are several ways to open or close a menu. The menu can be **toggled** open or closed
53262 * from the template using the [MenuToggle](../MenuToggle) directive. It can also be
53263 * **closed** from the template using the [MenuClose](../MenuClose) directive. To display a menu
53264 * programmatically, inject the [MenuController](../MenuController) provider and call any of the
53265 * `MenuController` methods.
53266 *
53267 *
53268 * ### Menu Types
53269 *
53270 * The menu supports several display types: `overlay`, `reveal` and `push`. By default,
53271 * it will use the correct type based on the mode, but this can be changed. The default
53272 * type for both Material Design and Windows mode is `overlay`, and `reveal` is the default
53273 * type for iOS mode. The menu type can be changed in the app's [config](../../config/Config)
53274 * via the `menuType` property, or passed in the `type` property on the `<ion-menu>` element.
53275 * See [usage](#usage) below for examples of changing the menu type.
53276 *
53277 *
53278 * ### Navigation Bar Behavior
53279 *
53280 * If a [MenuToggle](../MenuToggle) button is added to the [Navbar](../../navbar/Navbar) of
53281 * a page, the button will only appear when the page it's in is currently a root page. The
53282 * root page is the initial page loaded in the app, or a page that has been set as the root
53283 * using the [setRoot](../../nav/NavController/#setRoot) method on the [NavController](../../nav/NavController).
53284 *
53285 * For example, say the application has two pages, `Page1` and `Page2`, and both have a
53286 * `MenuToggle` button in their navigation bars. Assume the initial page loaded into the app
53287 * is `Page1`, making it the root page. `Page1` will display the `MenuToggle` button, but once
53288 * `Page2` is pushed onto the navigation stack, the `MenuToggle` will not be displayed.
53289 *
53290 *
53291 * ### Persistent Menus
53292 *
53293 * Persistent menus display the [MenuToggle](../MenuToggle) button in the [Navbar](../../navbar/Navbar)
53294 * on all pages in the navigation stack. To make a menu persistent set `persistent` to `true` on the
53295 * `<ion-menu>` element. Note that this will only affect the `MenuToggle` button in the `Navbar` attached
53296 * to the `Menu` with `persistent` set to true, any other `MenuToggle` buttons will not be affected.
53297 * ### Menu Side
53298 *
53299 * By default, menus slide in from the left, but this can be overridden by passing `right`
53300 * to the `side` property:
53301 *
53302 * ```html
53303 * <ion-menu side="right" [content]="mycontent">...</ion-menu>
53304 * ```
53305 *
53306 *
53307 * ### Menu Type
53308 *
53309 * The menu type can be changed by passing the value to `type` on the `<ion-menu>`:
53310 *
53311 * ```html
53312 * <ion-menu type="overlay" [content]="mycontent">...</ion-menu>
53313 * ```
53314 *
53315 * It can also be set in the app's config. The below will set the menu type to
53316 * `push` for all modes, and then set the type to `overlay` for the `ios` mode.
53317 *
53318 * ```ts
53319 * // in NgModules
53320 *
53321 * imports: [
53322 * IonicModule.forRoot(MyApp,{
53323 * menuType: 'push',
53324 * platforms: {
53325 * ios: {
53326 * menuType: 'overlay',
53327 * }
53328 * }
53329 * })
53330 * ],
53331 * ```
53332 *
53333 *
53334 * ### Displaying the Menu
53335 *
53336 * To toggle a menu from the template, add a button with the `menuToggle`
53337 * directive anywhere in the page's template:
53338 *
53339 * ```html
53340 * <button ion-button menuToggle>Toggle Menu</button>
53341 * ```
53342 *
53343 * To close a menu, add the `menuClose` button. It can be added anywhere
53344 * in the content, or even the menu itself. Below it is added to the menu's
53345 * content:
53346 *
53347 * ```html
53348 * <ion-menu [content]="mycontent">
53349 * <ion-content>
53350 * <ion-list>
53351 * <ion-item menuClose detail-none>Close Menu</ion-item>
53352 * </ion-list>
53353 * </ion-content>
53354 * </ion-menu>
53355 * ```
53356 *
53357 * See the [MenuToggle](../MenuToggle) and [MenuClose](../MenuClose) docs
53358 * for more information on these directives.
53359 *
53360 * The menu can also be controlled from the Page by using the `MenuController`.
53361 * Inject the `MenuController` provider into the page and then call any of its
53362 * methods. In the below example, the `openMenu` method will open the menu
53363 * when it is called.
53364 *
53365 * ```ts
53366 * import { Component } from '\@angular/core';
53367 * import { MenuController } from 'ionic-angular';
53368 *
53369 * \@Component({...})
53370 * export class MyPage {
53371 * constructor(public menuCtrl: MenuController) {}
53372 *
53373 * openMenu() {
53374 * this.menuCtrl.open();
53375 * }
53376 * }
53377 * ```
53378 *
53379 * See the [MenuController](../../app/MenuController) API docs for all of the methods
53380 * and usage information.
53381 *
53382 *
53383 * \@demo /docs/demos/src/menu/
53384 *
53385 * @see {\@link /docs/components#menus Menu Component Docs}
53386 * @see {\@link ../../app/MenuController MenuController API Docs}
53387 * @see {\@link ../../nav/Nav Nav API Docs}
53388 * @see {\@link ../../nav/NavController NavController API Docs}
53389 */
53390var Menu = (function () {
53391 /**
53392 * @param {?} _menuCtrl
53393 * @param {?} _elementRef
53394 * @param {?} _config
53395 * @param {?} _plt
53396 * @param {?} _renderer
53397 * @param {?} _keyboard
53398 * @param {?} _gestureCtrl
53399 * @param {?} _domCtrl
53400 * @param {?} _app
53401 */
53402 function Menu(_menuCtrl, _elementRef, _config, _plt, _renderer, _keyboard, _gestureCtrl, _domCtrl, _app) {
53403 this._menuCtrl = _menuCtrl;
53404 this._elementRef = _elementRef;
53405 this._config = _config;
53406 this._plt = _plt;
53407 this._renderer = _renderer;
53408 this._keyboard = _keyboard;
53409 this._gestureCtrl = _gestureCtrl;
53410 this._domCtrl = _domCtrl;
53411 this._app = _app;
53412 this._isSwipeEnabled = true;
53413 this._isAnimating = false;
53414 this._isPersistent = false;
53415 this._init = false;
53416 this._isPane = false;
53417 /**
53418 * @hidden
53419 */
53420 this.isOpen = false;
53421 /**
53422 * @hidden
53423 */
53424 this.isRightSide = false;
53425 /**
53426 * \@output {event} Emitted when the menu is being dragged open.
53427 */
53428 this.ionDrag = new EventEmitter();
53429 /**
53430 * \@output {event} Emitted when the menu has been opened.
53431 */
53432 this.ionOpen = new EventEmitter();
53433 /**
53434 * \@output {event} Emitted when the menu has been closed.
53435 */
53436 this.ionClose = new EventEmitter();
53437 this._events = new UIEventManager(_plt);
53438 this._gestureBlocker = _gestureCtrl.createBlocker({
53439 disable: [GESTURE_GO_BACK_SWIPE]
53440 });
53441 this.side = 'start';
53442 }
53443 Object.defineProperty(Menu.prototype, "enabled", {
53444 /**
53445 * \@input {boolean} If true, the menu is enabled. Default `true`.
53446 * @return {?}
53447 */
53448 get: function () {
53449 return this._isEnabled;
53450 },
53451 /**
53452 * @param {?} val
53453 * @return {?}
53454 */
53455 set: function (val) {
53456 var /** @type {?} */ isEnabled = isTrueProperty(val);
53457 this.enable(isEnabled);
53458 },
53459 enumerable: true,
53460 configurable: true
53461 });
53462 Object.defineProperty(Menu.prototype, "side", {
53463 /**
53464 * \@input {string} Which side of the view the menu should be placed. Default `"left"`.
53465 * @return {?}
53466 */
53467 get: function () {
53468 return this._side;
53469 },
53470 /**
53471 * @param {?} val
53472 * @return {?}
53473 */
53474 set: function (val) {
53475 this.isRightSide = isRightSide(val, this._plt.isRTL);
53476 if (this.isRightSide) {
53477 this._side = 'right';
53478 }
53479 else {
53480 this._side = 'left';
53481 }
53482 },
53483 enumerable: true,
53484 configurable: true
53485 });
53486 Object.defineProperty(Menu.prototype, "swipeEnabled", {
53487 /**
53488 * \@input {boolean} If true, swiping the menu is enabled. Default `true`.
53489 * @return {?}
53490 */
53491 get: function () {
53492 return this._isSwipeEnabled;
53493 },
53494 /**
53495 * @param {?} val
53496 * @return {?}
53497 */
53498 set: function (val) {
53499 var /** @type {?} */ isEnabled = isTrueProperty(val);
53500 this.swipeEnable(isEnabled);
53501 },
53502 enumerable: true,
53503 configurable: true
53504 });
53505 Object.defineProperty(Menu.prototype, "persistent", {
53506 /**
53507 * \@input {boolean} If true, the menu will persist on child pages.
53508 * @return {?}
53509 */
53510 get: function () {
53511 return this._isPersistent;
53512 },
53513 /**
53514 * @param {?} val
53515 * @return {?}
53516 */
53517 set: function (val) {
53518 this._isPersistent = isTrueProperty(val);
53519 },
53520 enumerable: true,
53521 configurable: true
53522 });
53523 /**
53524 * @hidden
53525 * @return {?}
53526 */
53527 Menu.prototype.ngOnInit = function () {
53528 var _this = this;
53529 this._init = true;
53530 var /** @type {?} */ content = this.content;
53531 this._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement();
53532 // requires content element
53533 if (!this._cntEle) {
53534 return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-nav #content></ion-nav>');
53535 }
53536 this.setElementAttribute('side', this._side);
53537 // normalize the "type"
53538 if (!this.type) {
53539 this.type = this._config.get('menuType');
53540 }
53541 this.setElementAttribute('type', this.type);
53542 // add the gestures
53543 this._gesture = new MenuContentGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
53544 // add menu's content classes
53545 this._cntEle.classList.add('menu-content');
53546 this._cntEle.classList.add('menu-content-' + this.type);
53547 var /** @type {?} */ isEnabled = this._isEnabled;
53548 if (isEnabled === true || typeof isEnabled === 'undefined') {
53549 // check if more than one menu is on the same side
53550 isEnabled = !this._menuCtrl.getMenus().some(function (m) {
53551 return m.side === _this.side && m.enabled;
53552 });
53553 }
53554 // register this menu with the app's menu controller
53555 this._menuCtrl._register(this);
53556 // mask it as enabled / disabled
53557 this.enable(isEnabled);
53558 };
53559 /**
53560 * @hidden
53561 * @param {?} ev
53562 * @return {?}
53563 */
53564 Menu.prototype.onBackdropClick = function (ev) {
53565 ev.preventDefault();
53566 ev.stopPropagation();
53567 this._menuCtrl.close();
53568 };
53569 /**
53570 * @hidden
53571 * @return {?}
53572 */
53573 Menu.prototype._getType = function () {
53574 if (!this._type) {
53575 this._type = MenuController.create(this.type, this, this._plt);
53576 if (this._config.get('animate') === false) {
53577 this._type.ani.duration(0);
53578 }
53579 }
53580 return this._type;
53581 };
53582 /**
53583 * @hidden
53584 * @param {?} shouldOpen
53585 * @param {?=} animated
53586 * @return {?}
53587 */
53588 Menu.prototype.setOpen = function (shouldOpen, animated) {
53589 var _this = this;
53590 if (animated === void 0) { animated = true; }
53591 // If the menu is disabled or it is currenly being animated, let's do nothing
53592 if ((shouldOpen === this.isOpen) || !this._canOpen() || this._isAnimating) {
53593 return Promise.resolve(this.isOpen);
53594 }
53595 return new Promise(function (resolve) {
53596 _this._before();
53597 _this._getType().setOpen(shouldOpen, animated, function () {
53598 _this._after(shouldOpen);
53599 resolve(_this.isOpen);
53600 });
53601 });
53602 };
53603 /**
53604 * @return {?}
53605 */
53606 Menu.prototype._forceClosing = function () {
53607 var _this = this;
53608 (void 0) /* assert */;
53609 this._isAnimating = true;
53610 this._getType().setOpen(false, false, function () {
53611 _this._after(false);
53612 });
53613 };
53614 /**
53615 * @hidden
53616 * @return {?}
53617 */
53618 Menu.prototype.canSwipe = function () {
53619 return this._isSwipeEnabled &&
53620 !this._isAnimating &&
53621 this._canOpen() &&
53622 this._app.isEnabled();
53623 };
53624 /**
53625 * @hidden
53626 * @return {?}
53627 */
53628 Menu.prototype.isAnimating = function () {
53629 return this._isAnimating;
53630 };
53631 /**
53632 * @return {?}
53633 */
53634 Menu.prototype._swipeBeforeStart = function () {
53635 if (!this.canSwipe()) {
53636 (void 0) /* assert */;
53637 return;
53638 }
53639 this._before();
53640 };
53641 /**
53642 * @return {?}
53643 */
53644 Menu.prototype._swipeStart = function () {
53645 if (!this._isAnimating) {
53646 (void 0) /* assert */;
53647 return;
53648 }
53649 this._getType().setProgressStart(this.isOpen);
53650 };
53651 /**
53652 * @param {?} stepValue
53653 * @return {?}
53654 */
53655 Menu.prototype._swipeProgress = function (stepValue) {
53656 if (!this._isAnimating) {
53657 (void 0) /* assert */;
53658 return;
53659 }
53660 this._getType().setProgessStep(stepValue);
53661 var /** @type {?} */ ionDrag = this.ionDrag;
53662 if (ionDrag.observers.length > 0) {
53663 ionDrag.emit(stepValue);
53664 }
53665 };
53666 /**
53667 * @param {?} shouldCompleteLeft
53668 * @param {?} shouldCompleteRight
53669 * @param {?} stepValue
53670 * @param {?} velocity
53671 * @return {?}
53672 */
53673 Menu.prototype._swipeEnd = function (shouldCompleteLeft, shouldCompleteRight, stepValue, velocity) {
53674 var _this = this;
53675 if (!this._isAnimating) {
53676 (void 0) /* assert */;
53677 return;
53678 }
53679 // user has finished dragging the menu
53680 var /** @type {?} */ isRightSide$$1 = this.isRightSide;
53681 var /** @type {?} */ isRTL = this._plt.isRTL;
53682 var /** @type {?} */ opening = !this.isOpen;
53683 var /** @type {?} */ shouldComplete = (opening)
53684 ? (isRightSide$$1 !== isRTL) ? shouldCompleteLeft : shouldCompleteRight
53685 : (isRightSide$$1 !== isRTL) ? shouldCompleteRight : shouldCompleteLeft;
53686 this._getType().setProgressEnd(shouldComplete, stepValue, velocity, function (isOpen) {
53687 (void 0) /* console.debug */;
53688 _this._after(isOpen);
53689 });
53690 };
53691 /**
53692 * @return {?}
53693 */
53694 Menu.prototype._before = function () {
53695 (void 0) /* assert */;
53696 // this places the menu into the correct location before it animates in
53697 // this css class doesn't actually kick off any animations
53698 this.setElementClass('show-menu', true);
53699 this.backdrop.setElementClass('show-backdrop', true);
53700 this.resize();
53701 this._keyboard.close();
53702 this._isAnimating = true;
53703 };
53704 /**
53705 * @param {?} isOpen
53706 * @return {?}
53707 */
53708 Menu.prototype._after = function (isOpen) {
53709 (void 0) /* assert */;
53710 this._app.setEnabled(false, 100);
53711 // keep opening/closing the menu disabled for a touch more yet
53712 // only add listeners/css if it's enabled and isOpen
53713 // and only remove listeners/css if it's not open
53714 // emit opened/closed events
53715 this.isOpen = isOpen;
53716 this._isAnimating = false;
53717 this._events.unlistenAll();
53718 if (isOpen) {
53719 // Disable swipe to go back gesture
53720 this._gestureBlocker.block();
53721 this._cntEle.classList.add('menu-content-open');
53722 var /** @type {?} */ callback = this.onBackdropClick.bind(this);
53723 this._events.listen(this._cntEle, 'click', callback, { capture: true });
53724 this._events.listen(this.backdrop.getNativeElement(), 'click', callback, { capture: true });
53725 this.ionOpen.emit(true);
53726 }
53727 else {
53728 // Enable swipe to go back gesture
53729 this._gestureBlocker.unblock();
53730 this._cntEle.classList.remove('menu-content-open');
53731 this.setElementClass('show-menu', false);
53732 this.backdrop.setElementClass('show-menu', false);
53733 this.ionClose.emit(true);
53734 }
53735 };
53736 /**
53737 * @hidden
53738 * @return {?}
53739 */
53740 Menu.prototype.open = function () {
53741 return this.setOpen(true);
53742 };
53743 /**
53744 * @hidden
53745 * @return {?}
53746 */
53747 Menu.prototype.close = function () {
53748 return this.setOpen(false);
53749 };
53750 /**
53751 * @hidden
53752 * @return {?}
53753 */
53754 Menu.prototype.resize = function () {
53755 var /** @type {?} */ content = this.menuContent
53756 ? this.menuContent
53757 : this.menuNav;
53758 content && content.resize();
53759 };
53760 /**
53761 * @hidden
53762 * @return {?}
53763 */
53764 Menu.prototype.toggle = function () {
53765 return this.setOpen(!this.isOpen);
53766 };
53767 /**
53768 * @return {?}
53769 */
53770 Menu.prototype._canOpen = function () {
53771 return this._isEnabled && !this._isPane;
53772 };
53773 /**
53774 * @hidden
53775 * @return {?}
53776 */
53777 Menu.prototype._updateState = function () {
53778 var /** @type {?} */ canOpen = this._canOpen();
53779 // Close menu inmediately
53780 if (!canOpen && this.isOpen) {
53781 (void 0) /* assert */;
53782 // close if this menu is open, and should not be enabled
53783 this._forceClosing();
53784 }
53785 if (this._isEnabled && this._menuCtrl) {
53786 this._menuCtrl._setActiveMenu(this);
53787 }
53788 if (!this._init) {
53789 return;
53790 }
53791 var /** @type {?} */ gesture = this._gesture;
53792 // only listen/unlisten if the menu has initialized
53793 if (canOpen && this._isSwipeEnabled && !gesture.isListening) {
53794 // should listen, but is not currently listening
53795 (void 0) /* console.debug */;
53796 gesture.listen();
53797 }
53798 else if (gesture.isListening && (!canOpen || !this._isSwipeEnabled)) {
53799 // should not listen, but is currently listening
53800 (void 0) /* console.debug */;
53801 gesture.unlisten();
53802 }
53803 if (this.isOpen || (this._isPane && this._isEnabled)) {
53804 this.resize();
53805 }
53806 (void 0) /* assert */;
53807 };
53808 /**
53809 * @hidden
53810 * @param {?} shouldEnable
53811 * @return {?}
53812 */
53813 Menu.prototype.enable = function (shouldEnable) {
53814 this._isEnabled = shouldEnable;
53815 this.setElementClass('menu-enabled', shouldEnable);
53816 this._updateState();
53817 return this;
53818 };
53819 /**
53820 * \@internal
53821 * @return {?}
53822 */
53823 Menu.prototype.initPane = function () {
53824 return false;
53825 };
53826 /**
53827 * \@internal
53828 * @param {?} isPane
53829 * @return {?}
53830 */
53831 Menu.prototype.paneChanged = function (isPane) {
53832 this._isPane = isPane;
53833 this._updateState();
53834 };
53835 /**
53836 * @hidden
53837 * @param {?} shouldEnable
53838 * @return {?}
53839 */
53840 Menu.prototype.swipeEnable = function (shouldEnable) {
53841 this._isSwipeEnabled = shouldEnable;
53842 this._updateState();
53843 return this;
53844 };
53845 /**
53846 * @hidden
53847 * @return {?}
53848 */
53849 Menu.prototype.getNativeElement = function () {
53850 return this._elementRef.nativeElement;
53851 };
53852 /**
53853 * @hidden
53854 * @return {?}
53855 */
53856 Menu.prototype.getMenuElement = function () {
53857 return (this.getNativeElement().querySelector('.menu-inner'));
53858 };
53859 /**
53860 * @hidden
53861 * @return {?}
53862 */
53863 Menu.prototype.getContentElement = function () {
53864 return this._cntEle;
53865 };
53866 /**
53867 * @hidden
53868 * @return {?}
53869 */
53870 Menu.prototype.getBackdropElement = function () {
53871 return this.backdrop.getNativeElement();
53872 };
53873 /**
53874 * @hidden
53875 * @return {?}
53876 */
53877 Menu.prototype.width = function () {
53878 return this.getMenuElement().offsetWidth;
53879 };
53880 /**
53881 * @hidden
53882 * @return {?}
53883 */
53884 Menu.prototype.getMenuController = function () {
53885 return this._menuCtrl;
53886 };
53887 /**
53888 * @hidden
53889 * @param {?} className
53890 * @param {?} add
53891 * @return {?}
53892 */
53893 Menu.prototype.setElementClass = function (className, add) {
53894 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
53895 };
53896 /**
53897 * @hidden
53898 * @param {?} attributeName
53899 * @param {?} value
53900 * @return {?}
53901 */
53902 Menu.prototype.setElementAttribute = function (attributeName, value) {
53903 this._renderer.setElementAttribute(this._elementRef.nativeElement, attributeName, value);
53904 };
53905 /**
53906 * @hidden
53907 * @return {?}
53908 */
53909 Menu.prototype.getElementRef = function () {
53910 return this._elementRef;
53911 };
53912 /**
53913 * @hidden
53914 * @return {?}
53915 */
53916 Menu.prototype.ngOnDestroy = function () {
53917 this._menuCtrl._unregister(this);
53918 this._events.destroy();
53919 this._gesture && this._gesture.destroy();
53920 this._type && this._type.destroy();
53921 this._gesture = null;
53922 this._type = null;
53923 this._cntEle = null;
53924 };
53925 return Menu;
53926}());
53927Menu.decorators = [
53928 { type: Component, args: [{
53929 selector: 'ion-menu',
53930 template: '<div class="menu-inner"><ng-content></ng-content></div>' +
53931 '<ion-backdrop></ion-backdrop>',
53932 host: {
53933 'role': 'navigation'
53934 },
53935 changeDetection: ChangeDetectionStrategy.OnPush,
53936 encapsulation: ViewEncapsulation.None,
53937 providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Menu; }) }]
53938 },] },
53939];
53940/**
53941 * @nocollapse
53942 */
53943Menu.ctorParameters = function () { return [
53944 { type: MenuController, },
53945 { type: ElementRef, },
53946 { type: Config, },
53947 { type: Platform, },
53948 { type: Renderer, },
53949 { type: Keyboard, },
53950 { type: GestureController, },
53951 { type: DomController, },
53952 { type: App, },
53953]; };
53954Menu.propDecorators = {
53955 'backdrop': [{ type: ViewChild, args: [Backdrop,] },],
53956 'menuContent': [{ type: ContentChild, args: [Content,] },],
53957 'menuNav': [{ type: ContentChild, args: [Nav,] },],
53958 'content': [{ type: Input },],
53959 'id': [{ type: Input },],
53960 'type': [{ type: Input },],
53961 'enabled': [{ type: Input },],
53962 'side': [{ type: Input },],
53963 'swipeEnabled': [{ type: Input },],
53964 'persistent': [{ type: Input },],
53965 'maxEdgeStart': [{ type: Input },],
53966 'ionDrag': [{ type: Output },],
53967 'ionOpen': [{ type: Output },],
53968 'ionClose': [{ type: Output },],
53969};
53970
53971/**
53972 * \@name MenuClose
53973 * \@description
53974 * The `menuClose` directive can be placed on any button to close an open menu.
53975 *
53976 * \@usage
53977 *
53978 * A simple `menuClose` button can be added using the following markup:
53979 *
53980 * ```html
53981 * <button ion-button menuClose>Close Menu</button>
53982 * ```
53983 *
53984 * To close a certain menu by its id or side, give the `menuClose`
53985 * directive a value.
53986 *
53987 * ```html
53988 * <button ion-button menuClose="left">Close Left Menu</button>
53989 * ```
53990 *
53991 * \@demo /docs/demos/src/menu/
53992 * @see {\@link /docs/components#menus Menu Component Docs}
53993 * @see {\@link ../../menu/Menu Menu API Docs}
53994 */
53995var MenuClose = (function () {
53996 /**
53997 * @param {?} _menu
53998 */
53999 function MenuClose(_menu) {
54000 this._menu = _menu;
54001 }
54002 /**
54003 * @hidden
54004 * @return {?}
54005 */
54006 MenuClose.prototype.close = function () {
54007 var /** @type {?} */ menu = this._menu.get(this.menuClose);
54008 menu && menu.close();
54009 };
54010 return MenuClose;
54011}());
54012MenuClose.decorators = [
54013 { type: Directive, args: [{
54014 selector: '[menuClose]'
54015 },] },
54016];
54017/**
54018 * @nocollapse
54019 */
54020MenuClose.ctorParameters = function () { return [
54021 { type: MenuController, },
54022]; };
54023MenuClose.propDecorators = {
54024 'menuClose': [{ type: Input },],
54025 'close': [{ type: HostListener, args: ['click',] },],
54026};
54027
54028var __extends$60 = (undefined && undefined.__extends) || (function () {
54029 var extendStatics = Object.setPrototypeOf ||
54030 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
54031 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
54032 return function (d, b) {
54033 extendStatics(d, b);
54034 function __() { this.constructor = d; }
54035 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
54036 };
54037})();
54038/**
54039 * @hidden
54040 */
54041var ToolbarBase = (function (_super) {
54042 __extends$60(ToolbarBase, _super);
54043 /**
54044 * @param {?} config
54045 * @param {?} elementRef
54046 * @param {?} renderer
54047 */
54048 function ToolbarBase(config, elementRef, renderer) {
54049 return _super.call(this, config, elementRef, renderer, 'toolbar') || this;
54050 }
54051 /**
54052 * @hidden
54053 * @param {?} titleCmp
54054 * @return {?}
54055 */
54056 ToolbarBase.prototype._setTitle = function (titleCmp) {
54057 this._title = titleCmp;
54058 };
54059 /**
54060 * @hidden
54061 * Returns the toolbar title text if it exists or an empty string
54062 * @return {?}
54063 */
54064 ToolbarBase.prototype.getTitleText = function () {
54065 return (this._title && this._title.getTitleText()) || '';
54066 };
54067 return ToolbarBase;
54068}(Ion));
54069
54070var __extends$59 = (undefined && undefined.__extends) || (function () {
54071 var extendStatics = Object.setPrototypeOf ||
54072 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
54073 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
54074 return function (d, b) {
54075 extendStatics(d, b);
54076 function __() { this.constructor = d; }
54077 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
54078 };
54079})();
54080/**
54081 * \@name Navbar
54082 * \@description
54083 * Navbar acts as the navigational toolbar, which also comes with a back
54084 * button. A navbar can contain a `ion-title`, any number of buttons,
54085 * a segment, or a searchbar. Navbars must be placed within an
54086 * `<ion-header>` in order for them to be placed above the content.
54087 * It's important to note that navbar's are part of the dynamic navigation
54088 * stack. If you need a static toolbar, use ion-toolbar.
54089 *
54090 * \@usage
54091 * ```html
54092 * <ion-header>
54093 *
54094 * <ion-navbar>
54095 * <button ion-button icon-only menuToggle>
54096 * <ion-icon name="menu"></ion-icon>
54097 * </button>
54098 *
54099 * <ion-title>
54100 * Page Title
54101 * </ion-title>
54102 *
54103 * <ion-buttons end>
54104 * <button ion-button icon-only (click)="openModal()">
54105 * <ion-icon name="options"></ion-icon>
54106 * </button>
54107 * </ion-buttons>
54108 * </ion-navbar>
54109 *
54110 * </ion-header>
54111 * ```
54112 *
54113 * \@demo /docs/demos/src/navbar/
54114 * @see {\@link ../../toolbar/Toolbar/ Toolbar API Docs}
54115 */
54116var Navbar = (function (_super) {
54117 __extends$59(Navbar, _super);
54118 /**
54119 * @param {?} _app
54120 * @param {?} viewCtrl
54121 * @param {?} navCtrl
54122 * @param {?} config
54123 * @param {?} elementRef
54124 * @param {?} renderer
54125 */
54126 function Navbar(_app, viewCtrl, navCtrl, config, elementRef, renderer) {
54127 var _this = _super.call(this, config, elementRef, renderer) || this;
54128 _this._app = _app;
54129 _this.navCtrl = navCtrl;
54130 /**
54131 * @hidden
54132 */
54133 _this._hidden = false;
54134 /**
54135 * @hidden
54136 */
54137 _this._hideBb = false;
54138 viewCtrl && viewCtrl._setNavbar(_this);
54139 _this._bbIcon = config.get('backButtonIcon');
54140 _this._sbPadding = config.getBoolean('statusbarPadding');
54141 _this._backText = config.get('backButtonText', 'Back');
54142 return _this;
54143 }
54144 Object.defineProperty(Navbar.prototype, "hideBackButton", {
54145 /**
54146 * \@input {boolean} If true, the back button will be hidden.
54147 * @return {?}
54148 */
54149 get: function () {
54150 return this._hideBb;
54151 },
54152 /**
54153 * @param {?} val
54154 * @return {?}
54155 */
54156 set: function (val) {
54157 this._hideBb = isTrueProperty(val);
54158 },
54159 enumerable: true,
54160 configurable: true
54161 });
54162 /**
54163 * @param {?} ev
54164 * @return {?}
54165 */
54166 Navbar.prototype.backButtonClick = function (ev) {
54167 ev.preventDefault();
54168 ev.stopPropagation();
54169 this.navCtrl && this.navCtrl.pop(null, null);
54170 };
54171 /**
54172 * Set the text of the Back Button in the Nav Bar. Defaults to "Back".
54173 * @param {?} text
54174 * @return {?}
54175 */
54176 Navbar.prototype.setBackButtonText = function (text) {
54177 this._backText = text;
54178 };
54179 /**
54180 * @hidden
54181 * @return {?}
54182 */
54183 Navbar.prototype.didEnter = function () {
54184 try {
54185 this._app.setTitle(this.getTitleText());
54186 }
54187 catch (e) {
54188 console.error(e);
54189 }
54190 };
54191 /**
54192 * @hidden
54193 * @param {?} isHidden
54194 * @return {?}
54195 */
54196 Navbar.prototype.setHidden = function (isHidden) {
54197 // used to display none/block the navbar
54198 this._hidden = isHidden;
54199 };
54200 return Navbar;
54201}(ToolbarBase));
54202Navbar.decorators = [
54203 { type: Component, args: [{
54204 selector: 'ion-navbar',
54205 template: '<div class="toolbar-background" [ngClass]="\'toolbar-background-\' + _mode"></div>' +
54206 '<button (click)="backButtonClick($event)" ion-button="bar-button" class="back-button" [ngClass]="\'back-button-\' + _mode" [hidden]="_hideBb">' +
54207 '<ion-icon class="back-button-icon" [ngClass]="\'back-button-icon-\' + _mode" [name]="_bbIcon"></ion-icon>' +
54208 '<span class="back-button-text" [ngClass]="\'back-button-text-\' + _mode">{{_backText}}</span>' +
54209 '</button>' +
54210 '<ng-content select="[menuToggle],ion-buttons[left]"></ng-content>' +
54211 '<ng-content select="ion-buttons[start]"></ng-content>' +
54212 '<ng-content select="ion-buttons[end],ion-buttons[right]"></ng-content>' +
54213 '<div class="toolbar-content" [ngClass]="\'toolbar-content-\' + _mode">' +
54214 '<ng-content></ng-content>' +
54215 '</div>',
54216 host: {
54217 '[hidden]': '_hidden',
54218 'class': 'toolbar',
54219 '[class.statusbar-padding]': '_sbPadding'
54220 }
54221 },] },
54222];
54223/**
54224 * @nocollapse
54225 */
54226Navbar.ctorParameters = function () { return [
54227 { type: App, },
54228 { type: ViewController, decorators: [{ type: Optional },] },
54229 { type: NavController, decorators: [{ type: Optional },] },
54230 { type: Config, },
54231 { type: ElementRef, },
54232 { type: Renderer, },
54233]; };
54234Navbar.propDecorators = {
54235 'hideBackButton': [{ type: Input },],
54236};
54237
54238/**
54239 * \@name MenuToggle
54240 * \@description
54241 * The `menuToggle` directive can be placed on any button to toggle a menu open or closed.
54242 * If it is added to the [NavBar](../../toolbar/Navbar) of a page, the button will only appear
54243 * when the page it's in is currently a root page. See the [Menu Navigation Bar Behavior](../Menu#navigation-bar-behavior)
54244 * docs for more information.
54245 *
54246 *
54247 * \@usage
54248 *
54249 * A simple `menuToggle` button can be added using the following markup:
54250 *
54251 * ```html
54252 * <button ion-button menuToggle>Toggle Menu</button>
54253 * ```
54254 *
54255 * To toggle a specific menu by its id or side, give the `menuToggle`
54256 * directive a value.
54257 *
54258 * ```html
54259 * <button ion-button menuToggle="right">Toggle Right Menu</button>
54260 * ```
54261 *
54262 * If placing the `menuToggle` in a navbar or toolbar, it should be
54263 * placed as a child of the `<ion-navbar>` or `<ion-toolbar>`, and not in
54264 * the `<ion-buttons>` element:
54265 *
54266 * ```html
54267 * <ion-header>
54268 *
54269 * <ion-navbar>
54270 * <ion-buttons start>
54271 * <button ion-button>
54272 * <ion-icon name="contact"></ion-icon>
54273 * </button>
54274 * </ion-buttons>
54275 * <button ion-button menuToggle>
54276 * <ion-icon name="menu"></ion-icon>
54277 * </button>
54278 * <ion-title>
54279 * Title
54280 * </ion-title>
54281 * <ion-buttons end>
54282 * <button ion-button (click)="doClick()">
54283 * <ion-icon name="more"></ion-icon>
54284 * </button>
54285 * </ion-buttons>
54286 * </ion-navbar>
54287 *
54288 * </ion-header>
54289 * ```
54290 *
54291 * Similar to `<ion-buttons>`, the `menuToggle` can be positioned using
54292 * `start`, `end`, `left`, or `right`:
54293 *
54294 * ```html
54295 * <ion-toolbar>
54296 * <button ion-button menuToggle right>
54297 * <ion-icon name="menu"></ion-icon>
54298 * </button>
54299 * <ion-title>
54300 * Title
54301 * </ion-title>
54302 * <ion-buttons end>
54303 * <button ion-button (click)="doClick()">
54304 * <ion-icon name="more"></ion-icon>
54305 * </button>
54306 * </ion-buttons>
54307 * </ion-toolbar>
54308 * ```
54309 *
54310 * See the [Toolbar API docs](../../toolbar/Toolbar) for more information
54311 * on the different positions.
54312 *
54313 * \@demo /docs/demos/src/menu/
54314 * @see {\@link /docs/components#menus Menu Component Docs}
54315 * @see {\@link ../../menu/Menu Menu API Docs}
54316 */
54317var MenuToggle = (function () {
54318 /**
54319 * @param {?} _menu
54320 * @param {?} _viewCtrl
54321 * @param {?} _button
54322 * @param {?} _navbar
54323 */
54324 function MenuToggle(_menu, _viewCtrl, _button, _navbar) {
54325 this._menu = _menu;
54326 this._viewCtrl = _viewCtrl;
54327 this._button = _button;
54328 this._isButton = !!_button;
54329 this._inNavbar = !!_navbar;
54330 }
54331 /**
54332 * @return {?}
54333 */
54334 MenuToggle.prototype.ngAfterContentInit = function () {
54335 // Add the bar-button-menutoggle / button-menutoggle class
54336 if (this._isButton) {
54337 this._button._setClass('menutoggle', true);
54338 }
54339 };
54340 /**
54341 * @hidden
54342 * @return {?}
54343 */
54344 MenuToggle.prototype.toggle = function () {
54345 var /** @type {?} */ menu = this._menu.get(this.menuToggle);
54346 menu && menu.toggle();
54347 };
54348 Object.defineProperty(MenuToggle.prototype, "isHidden", {
54349 /**
54350 * @hidden
54351 * @return {?}
54352 */
54353 get: function () {
54354 var /** @type {?} */ menu = this._menu.get(this.menuToggle);
54355 if (this._inNavbar && this._viewCtrl) {
54356 if (!menu || !menu._canOpen()) {
54357 return true;
54358 }
54359 if (this._viewCtrl.isFirst()) {
54360 // this is the first view, so it should always show
54361 return false;
54362 }
54363 if (menu) {
54364 // this is not the root view, so see if this menu
54365 // is configured to still be enabled if it's not the root view
54366 return !menu.persistent;
54367 }
54368 }
54369 return false;
54370 },
54371 enumerable: true,
54372 configurable: true
54373 });
54374 return MenuToggle;
54375}());
54376MenuToggle.decorators = [
54377 { type: Directive, args: [{
54378 selector: '[menuToggle]',
54379 host: {
54380 '[hidden]': 'isHidden'
54381 }
54382 },] },
54383];
54384/**
54385 * @nocollapse
54386 */
54387MenuToggle.ctorParameters = function () { return [
54388 { type: MenuController, },
54389 { type: ViewController, decorators: [{ type: Optional },] },
54390 { type: Button, decorators: [{ type: Optional },] },
54391 { type: Navbar, decorators: [{ type: Optional },] },
54392]; };
54393MenuToggle.propDecorators = {
54394 'menuToggle': [{ type: Input },],
54395 'toggle': [{ type: HostListener, args: ['click',] },],
54396};
54397
54398var __extends$61 = (undefined && undefined.__extends) || (function () {
54399 var extendStatics = Object.setPrototypeOf ||
54400 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
54401 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
54402 return function (d, b) {
54403 extendStatics(d, b);
54404 function __() { this.constructor = d; }
54405 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
54406 };
54407})();
54408/**
54409 * @hidden
54410 * Menu Type
54411 * Base class which is extended by the various types. Each
54412 * type will provide their own animations for open and close
54413 * and registers itself with Menu.
54414 */
54415var MenuType = (function () {
54416 /**
54417 * @param {?} plt
54418 */
54419 function MenuType(plt) {
54420 this.ani = new Animation(plt);
54421 this.ani
54422 .easing('cubic-bezier(0.0, 0.0, 0.2, 1)')
54423 .easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)')
54424 .duration(280);
54425 }
54426 /**
54427 * @param {?} shouldOpen
54428 * @param {?} animated
54429 * @param {?} done
54430 * @return {?}
54431 */
54432 MenuType.prototype.setOpen = function (shouldOpen, animated, done) {
54433 var /** @type {?} */ ani = this.ani
54434 .onFinish(done, true, true)
54435 .reverse(!shouldOpen);
54436 if (animated) {
54437 ani.play();
54438 }
54439 else {
54440 ani.syncPlay();
54441 }
54442 };
54443 /**
54444 * @param {?} isOpen
54445 * @return {?}
54446 */
54447 MenuType.prototype.setProgressStart = function (isOpen) {
54448 this.isOpening = !isOpen;
54449 // the cloned animation should not use an easing curve during seek
54450 this.ani
54451 .reverse(isOpen)
54452 .progressStart();
54453 };
54454 /**
54455 * @param {?} stepValue
54456 * @return {?}
54457 */
54458 MenuType.prototype.setProgessStep = function (stepValue) {
54459 // adjust progress value depending if it opening or closing
54460 this.ani.progressStep(stepValue);
54461 };
54462 /**
54463 * @param {?} shouldComplete
54464 * @param {?} currentStepValue
54465 * @param {?} velocity
54466 * @param {?} done
54467 * @return {?}
54468 */
54469 MenuType.prototype.setProgressEnd = function (shouldComplete, currentStepValue, velocity, done) {
54470 var _this = this;
54471 var /** @type {?} */ isOpen = (this.isOpening && shouldComplete);
54472 if (!this.isOpening && !shouldComplete) {
54473 isOpen = true;
54474 }
54475 var /** @type {?} */ ani = this.ani;
54476 ani.onFinish(function () {
54477 _this.isOpening = false;
54478 done(isOpen);
54479 }, true);
54480 var /** @type {?} */ factor = 1 - Math.min(Math.abs(velocity) / 4, 0.7);
54481 var /** @type {?} */ dur = ani.getDuration() * factor;
54482 ani.progressEnd(shouldComplete, currentStepValue, dur);
54483 };
54484 /**
54485 * @return {?}
54486 */
54487 MenuType.prototype.destroy = function () {
54488 this.ani.destroy();
54489 this.ani = null;
54490 };
54491 return MenuType;
54492}());
54493/**
54494 * @hidden
54495 * Menu Reveal Type
54496 * The content slides over to reveal the menu underneath.
54497 * The menu itself, which is under the content, does not move.
54498 */
54499var MenuRevealType = (function (_super) {
54500 __extends$61(MenuRevealType, _super);
54501 /**
54502 * @param {?} menu
54503 * @param {?} plt
54504 */
54505 function MenuRevealType(menu, plt) {
54506 var _this = _super.call(this, plt) || this;
54507 var openedX = (menu.width() * (menu.isRightSide ? -1 : 1)) + 'px';
54508 var contentOpen = new Animation(plt, menu.getContentElement());
54509 contentOpen.fromTo('translateX', '0px', openedX);
54510 _this.ani.add(contentOpen);
54511 return _this;
54512 }
54513 return MenuRevealType;
54514}(MenuType));
54515MenuController.registerType('reveal', MenuRevealType);
54516/**
54517 * @hidden
54518 * Menu Push Type
54519 * The content slides over to reveal the menu underneath.
54520 * The menu itself also slides over to reveal its bad self.
54521 */
54522var MenuPushType = (function (_super) {
54523 __extends$61(MenuPushType, _super);
54524 /**
54525 * @param {?} menu
54526 * @param {?} plt
54527 */
54528 function MenuPushType(menu, plt) {
54529 var _this = _super.call(this, plt) || this;
54530 var contentOpenedX, menuClosedX, menuOpenedX;
54531 var width = menu.width();
54532 if (menu.isRightSide) {
54533 // right side
54534 contentOpenedX = -width + 'px';
54535 menuClosedX = width + 'px';
54536 menuOpenedX = '0px';
54537 }
54538 else {
54539 contentOpenedX = width + 'px';
54540 menuOpenedX = '0px';
54541 menuClosedX = -width + 'px';
54542 }
54543 var menuAni = new Animation(plt, menu.getMenuElement());
54544 menuAni.fromTo('translateX', menuClosedX, menuOpenedX);
54545 _this.ani.add(menuAni);
54546 var contentApi = new Animation(plt, menu.getContentElement());
54547 contentApi.fromTo('translateX', '0px', contentOpenedX);
54548 _this.ani.add(contentApi);
54549 return _this;
54550 }
54551 return MenuPushType;
54552}(MenuType));
54553MenuController.registerType('push', MenuPushType);
54554/**
54555 * @hidden
54556 * Menu Overlay Type
54557 * The menu slides over the content. The content
54558 * itself, which is under the menu, does not move.
54559 */
54560var MenuOverlayType = (function (_super) {
54561 __extends$61(MenuOverlayType, _super);
54562 /**
54563 * @param {?} menu
54564 * @param {?} plt
54565 */
54566 function MenuOverlayType(menu, plt) {
54567 var _this = _super.call(this, plt) || this;
54568 var closedX, openedX;
54569 var width = menu.width();
54570 if (menu.isRightSide) {
54571 // right side
54572 closedX = 8 + width + 'px';
54573 openedX = '0px';
54574 }
54575 else {
54576 // left side
54577 closedX = -(8 + width) + 'px';
54578 openedX = '0px';
54579 }
54580 var menuAni = new Animation(plt, menu.getMenuElement());
54581 menuAni.fromTo('translateX', closedX, openedX);
54582 _this.ani.add(menuAni);
54583 var backdropApi = new Animation(plt, menu.getBackdropElement());
54584 backdropApi.fromTo('opacity', 0.01, 0.35);
54585 _this.ani.add(backdropApi);
54586 return _this;
54587 }
54588 return MenuOverlayType;
54589}(MenuType));
54590MenuController.registerType('overlay', MenuOverlayType);
54591
54592var OverlayProxy = (function () {
54593 /**
54594 * @param {?} _app
54595 * @param {?} _component
54596 * @param {?} _config
54597 * @param {?} _deepLinker
54598 */
54599 function OverlayProxy(_app, _component, _config, _deepLinker) {
54600 this._app = _app;
54601 this._component = _component;
54602 this._config = _config;
54603 this._deepLinker = _deepLinker;
54604 }
54605 /**
54606 * @return {?}
54607 */
54608 OverlayProxy.prototype.getImplementation = function () {
54609 throw new Error('Child class must implement "getImplementation" method');
54610 };
54611 /**
54612 * Present the modal instance.
54613 *
54614 * @param {?=} navOptions
54615 * @return {?}
54616 */
54617 OverlayProxy.prototype.present = function (navOptions) {
54618 var _this = this;
54619 if (navOptions === void 0) { navOptions = {}; }
54620 // check if it's a lazy loaded component, or not
54621 var /** @type {?} */ isLazyLoaded = isString(this._component);
54622 if (isLazyLoaded) {
54623 return this._deepLinker.getComponentFromName(this._component).then(function (loadedComponent) {
54624 _this._component = loadedComponent;
54625 return _this.createAndPresentOverlay(navOptions);
54626 });
54627 }
54628 else {
54629 return this.createAndPresentOverlay(navOptions);
54630 }
54631 };
54632 /**
54633 * @param {?=} data
54634 * @param {?=} role
54635 * @param {?=} navOptions
54636 * @return {?}
54637 */
54638 OverlayProxy.prototype.dismiss = function (data, role, navOptions) {
54639 if (this.overlay) {
54640 return this.overlay.dismiss(data, role, navOptions);
54641 }
54642 };
54643 /**
54644 * Called when the current viewController has be successfully dismissed
54645 * @param {?} callback
54646 * @return {?}
54647 */
54648 OverlayProxy.prototype.onDidDismiss = function (callback) {
54649 this._onDidDismiss = callback;
54650 if (this.overlay) {
54651 this.overlay.onDidDismiss(this._onDidDismiss);
54652 }
54653 };
54654 /**
54655 * @param {?} navOptions
54656 * @return {?}
54657 */
54658 OverlayProxy.prototype.createAndPresentOverlay = function (navOptions) {
54659 this.overlay = this.getImplementation();
54660 this.overlay.onWillDismiss(this._onWillDismiss);
54661 this.overlay.onDidDismiss(this._onDidDismiss);
54662 return this.overlay.present(navOptions);
54663 };
54664 /**
54665 * Called when the current viewController will be dismissed
54666 * @param {?} callback
54667 * @return {?}
54668 */
54669 OverlayProxy.prototype.onWillDismiss = function (callback) {
54670 this._onWillDismiss = callback;
54671 if (this.overlay) {
54672 this.overlay.onWillDismiss(this._onWillDismiss);
54673 }
54674 };
54675 return OverlayProxy;
54676}());
54677
54678/**
54679 * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
54680 */
54681var NgModuleLoader = (function () {
54682 /**
54683 * @param {?} _compiler
54684 */
54685 function NgModuleLoader(_compiler) {
54686 this._compiler = _compiler;
54687 }
54688 /**
54689 * @param {?} modulePath
54690 * @param {?} ngModuleExport
54691 * @return {?}
54692 */
54693 NgModuleLoader.prototype.load = function (modulePath, ngModuleExport) {
54694 var /** @type {?} */ offlineMode = this._compiler instanceof Compiler;
54695 return offlineMode ? loadPrecompiledFactory(modulePath, ngModuleExport) : loadAndCompile(this._compiler, modulePath, ngModuleExport);
54696 };
54697 return NgModuleLoader;
54698}());
54699NgModuleLoader.decorators = [
54700 { type: Injectable },
54701];
54702/**
54703 * @nocollapse
54704 */
54705NgModuleLoader.ctorParameters = function () { return [
54706 { type: Compiler, },
54707]; };
54708/**
54709 * @param {?} compiler
54710 * @param {?} modulePath
54711 * @param {?} ngModuleExport
54712 * @return {?}
54713 */
54714function loadAndCompile(compiler, modulePath, ngModuleExport) {
54715 if (!ngModuleExport) {
54716 ngModuleExport = 'default';
54717 }
54718 return System.import(modulePath)
54719 .then(function (rawModule) {
54720 var /** @type {?} */ module = rawModule[ngModuleExport];
54721 if (!module) {
54722 throw new Error("Module " + modulePath + " does not export " + ngModuleExport);
54723 }
54724 return compiler.compileModuleAsync(module);
54725 });
54726}
54727/**
54728 * @param {?} modulePath
54729 * @param {?} ngModuleExport
54730 * @return {?}
54731 */
54732function loadPrecompiledFactory(modulePath, ngModuleExport) {
54733 return System.import(modulePath)
54734 .then(function (rawModule) {
54735 var /** @type {?} */ ngModuleFactory = rawModule[ngModuleExport];
54736 if (!ngModuleFactory) {
54737 throw new Error("Module " + modulePath + " does not export " + ngModuleExport);
54738 }
54739 return ngModuleFactory;
54740 });
54741}
54742
54743var LAZY_LOADED_TOKEN = new OpaqueToken('LZYCMP');
54744/**
54745 * @hidden
54746 */
54747var ModuleLoader = (function () {
54748 /**
54749 * @param {?} _ngModuleLoader
54750 * @param {?} _injector
54751 */
54752 function ModuleLoader(_ngModuleLoader, _injector) {
54753 this._ngModuleLoader = _ngModuleLoader;
54754 this._injector = _injector;
54755 /**
54756 * \@internal
54757 */
54758 this._cfrMap = new Map();
54759 this._promiseMap = new Map();
54760 }
54761 /**
54762 * @param {?} modulePath
54763 * @return {?}
54764 */
54765 ModuleLoader.prototype.load = function (modulePath) {
54766 var _this = this;
54767 (void 0) /* console.time */;
54768 var /** @type {?} */ splitString = modulePath.split(SPLITTER);
54769 var /** @type {?} */ promise = this._promiseMap.get(modulePath);
54770 if (!promise) {
54771 promise = this._ngModuleLoader.load(splitString[0], splitString[1]);
54772 this._promiseMap.set(modulePath, promise);
54773 }
54774 return promise.then(function (loadedModule) {
54775 (void 0) /* console.timeEnd */;
54776 var /** @type {?} */ ref = loadedModule.create(_this._injector);
54777 var /** @type {?} */ component = ref.injector.get(LAZY_LOADED_TOKEN);
54778 _this._cfrMap.set(component, ref.componentFactoryResolver);
54779 return {
54780 componentFactoryResolver: ref.componentFactoryResolver,
54781 component: component
54782 };
54783 });
54784 };
54785 /**
54786 * @param {?} component
54787 * @return {?}
54788 */
54789 ModuleLoader.prototype.getComponentFactoryResolver = function (component) {
54790 return this._cfrMap.get(component);
54791 };
54792 return ModuleLoader;
54793}());
54794ModuleLoader.decorators = [
54795 { type: Injectable },
54796];
54797/**
54798 * @nocollapse
54799 */
54800ModuleLoader.ctorParameters = function () { return [
54801 { type: NgModuleLoader, },
54802 { type: Injector, },
54803]; };
54804var SPLITTER = '#';
54805/**
54806 * @hidden
54807 * @param {?} ngModuleLoader
54808 * @param {?} injector
54809 * @return {?}
54810 */
54811function provideModuleLoader(ngModuleLoader, injector) {
54812 return new ModuleLoader(ngModuleLoader, injector);
54813}
54814/**
54815 * @hidden
54816 * @param {?} config
54817 * @param {?} deepLinkConfig
54818 * @param {?} moduleLoader
54819 * @return {?}
54820 */
54821function setupPreloadingImplementation(config, deepLinkConfig, moduleLoader) {
54822 if (!deepLinkConfig || !deepLinkConfig.links || !config.getBoolean('preloadModules')) {
54823 return Promise.resolve();
54824 }
54825 var /** @type {?} */ linksToLoad = deepLinkConfig.links.filter(function (link) { return !!link.loadChildren && link.priority !== 'off'; });
54826 // Load the high priority modules first
54827 var /** @type {?} */ highPriorityPromises = linksToLoad
54828 .filter(function (link) { return link.priority === 'high'; })
54829 .map(function (link) { return moduleLoader.load(link.loadChildren); });
54830 return Promise.all(highPriorityPromises).then(function () {
54831 // Load the low priority modules after the high priority are done
54832 var /** @type {?} */ lowPriorityPromises = linksToLoad
54833 .filter(function (link) { return link.priority === 'low'; })
54834 .map(function (link) { return moduleLoader.load(link.loadChildren); });
54835 return Promise.all(lowPriorityPromises);
54836 }).catch(function (err) {
54837 console.error(err.message);
54838 });
54839}
54840/**
54841 * @hidden
54842 * @param {?} config
54843 * @param {?} deepLinkConfig
54844 * @param {?} moduleLoader
54845 * @param {?} ngZone
54846 * @return {?}
54847 */
54848function setupPreloading(config, deepLinkConfig, moduleLoader, ngZone) {
54849 return function () {
54850 requestIonicCallback(function () {
54851 ngZone.runOutsideAngular(function () {
54852 setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
54853 });
54854 });
54855 };
54856}
54857
54858/**
54859 * @hidden
54860 */
54861var ModalCmp = (function () {
54862 /**
54863 * @param {?} _cfr
54864 * @param {?} _renderer
54865 * @param {?} _elementRef
54866 * @param {?} _navParams
54867 * @param {?} _viewCtrl
54868 * @param {?} gestureCtrl
54869 * @param {?} moduleLoader
54870 */
54871 function ModalCmp(_cfr, _renderer, _elementRef, _navParams, _viewCtrl, gestureCtrl, moduleLoader) {
54872 this._cfr = _cfr;
54873 this._renderer = _renderer;
54874 this._elementRef = _elementRef;
54875 this._navParams = _navParams;
54876 this._viewCtrl = _viewCtrl;
54877 this.moduleLoader = moduleLoader;
54878 var opts = _navParams.get('opts');
54879 (void 0) /* assert */;
54880 this._gestureBlocker = gestureCtrl.createBlocker({
54881 disable: [GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE]
54882 });
54883 this._bdDismiss = opts.enableBackdropDismiss;
54884 if (opts.cssClass) {
54885 opts.cssClass.split(' ').forEach(function (cssClass) {
54886 // Make sure the class isn't whitespace, otherwise it throws exceptions
54887 if (cssClass.trim() !== '')
54888 _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
54889 });
54890 }
54891 }
54892 /**
54893 * @return {?}
54894 */
54895 ModalCmp.prototype.ionViewPreLoad = function () {
54896 var /** @type {?} */ component = this._navParams.data.component;
54897 if (!component) {
54898 console.warn('modal\'s page was not defined');
54899 return;
54900 }
54901 var /** @type {?} */ cfr = this.moduleLoader.getComponentFactoryResolver(component);
54902 if (!cfr) {
54903 cfr = this._cfr;
54904 }
54905 var /** @type {?} */ componentFactory = cfr.resolveComponentFactory(component);
54906 // ******** DOM WRITE ****************
54907 var /** @type {?} */ componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []);
54908 this._setCssClass(componentRef, 'ion-page');
54909 this._setCssClass(componentRef, 'show-page');
54910 // Change the viewcontroller's instance to point the user provided page
54911 // Lifecycle events will be sent to the new instance, instead of the modal's component
54912 // we need to manually subscribe to them
54913 this._viewCtrl._setInstance(componentRef.instance);
54914 this._viewCtrl.willEnter.subscribe(this._viewWillEnter.bind(this));
54915 this._viewCtrl.didLeave.subscribe(this._viewDidLeave.bind(this));
54916 this._enabled = true;
54917 };
54918 /**
54919 * @return {?}
54920 */
54921 ModalCmp.prototype._viewWillEnter = function () {
54922 this._gestureBlocker.block();
54923 };
54924 /**
54925 * @return {?}
54926 */
54927 ModalCmp.prototype._viewDidLeave = function () {
54928 this._gestureBlocker.unblock();
54929 };
54930 /**
54931 * @param {?} componentRef
54932 * @param {?} className
54933 * @return {?}
54934 */
54935 ModalCmp.prototype._setCssClass = function (componentRef, className) {
54936 this._renderer.setElementClass(componentRef.location.nativeElement, className, true);
54937 };
54938 /**
54939 * @return {?}
54940 */
54941 ModalCmp.prototype._bdClick = function () {
54942 if (this._enabled && this._bdDismiss) {
54943 var /** @type {?} */ opts = {
54944 minClickBlockDuration: 400
54945 };
54946 return this._viewCtrl.dismiss(null, 'backdrop', opts);
54947 }
54948 };
54949 /**
54950 * @param {?} ev
54951 * @return {?}
54952 */
54953 ModalCmp.prototype._keyUp = function (ev) {
54954 if (this._enabled && this._viewCtrl.isLast() && ev.keyCode === KEY_ESCAPE) {
54955 this._bdClick();
54956 }
54957 };
54958 /**
54959 * @return {?}
54960 */
54961 ModalCmp.prototype.ngOnDestroy = function () {
54962 (void 0) /* assert */;
54963 this._gestureBlocker.destroy();
54964 };
54965 return ModalCmp;
54966}());
54967ModalCmp.decorators = [
54968 { type: Component, args: [{
54969 selector: 'ion-modal',
54970 template: '<ion-backdrop (click)="_bdClick()" [class.backdrop-no-tappable]="!_bdDismiss"></ion-backdrop>' +
54971 '<div class="modal-wrapper">' +
54972 '<div #viewport nav-viewport></div>' +
54973 '</div>'
54974 },] },
54975];
54976/**
54977 * @nocollapse
54978 */
54979ModalCmp.ctorParameters = function () { return [
54980 { type: ComponentFactoryResolver, },
54981 { type: Renderer, },
54982 { type: ElementRef, },
54983 { type: NavParams, },
54984 { type: ViewController, },
54985 { type: GestureController, },
54986 { type: ModuleLoader, },
54987]; };
54988ModalCmp.propDecorators = {
54989 '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
54990 '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
54991};
54992
54993var __extends$64 = (undefined && undefined.__extends) || (function () {
54994 var extendStatics = Object.setPrototypeOf ||
54995 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
54996 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
54997 return function (d, b) {
54998 extendStatics(d, b);
54999 function __() { this.constructor = d; }
55000 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
55001 };
55002})();
55003/**
55004 * Animations for modals
55005 */
55006var ModalSlideIn = (function (_super) {
55007 __extends$64(ModalSlideIn, _super);
55008 function ModalSlideIn() {
55009 return _super !== null && _super.apply(this, arguments) || this;
55010 }
55011 /**
55012 * @return {?}
55013 */
55014 ModalSlideIn.prototype.init = function () {
55015 _super.prototype.init.call(this);
55016 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
55017 var /** @type {?} */ backdropEle = ele.querySelector('ion-backdrop');
55018 var /** @type {?} */ backdrop = new Animation(this.plt, backdropEle);
55019 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
55020 wrapper.beforeStyles({ 'opacity': 1 });
55021 wrapper.fromTo('translateY', '100%', '0%');
55022 backdrop.fromTo('opacity', 0.01, 0.4);
55023 this
55024 .element(this.enteringView.pageRef())
55025 .easing('cubic-bezier(0.36,0.66,0.04,1)')
55026 .duration(400)
55027 .add(backdrop)
55028 .add(wrapper);
55029 };
55030 return ModalSlideIn;
55031}(PageTransition));
55032var ModalSlideOut = (function (_super) {
55033 __extends$64(ModalSlideOut, _super);
55034 function ModalSlideOut() {
55035 return _super !== null && _super.apply(this, arguments) || this;
55036 }
55037 /**
55038 * @return {?}
55039 */
55040 ModalSlideOut.prototype.init = function () {
55041 _super.prototype.init.call(this);
55042 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
55043 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
55044 var /** @type {?} */ wrapperEle = (ele.querySelector('.modal-wrapper'));
55045 var /** @type {?} */ wrapperEleRect = wrapperEle.getBoundingClientRect();
55046 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
55047 // height of the screen - top of the container tells us how much to scoot it down
55048 // so it's off-screen
55049 wrapper.fromTo('translateY', '0px', this.plt.height() - wrapperEleRect.top + "px");
55050 backdrop.fromTo('opacity', 0.4, 0.0);
55051 this
55052 .element(this.leavingView.pageRef())
55053 .easing('ease-out')
55054 .duration(250)
55055 .add(backdrop)
55056 .add(wrapper);
55057 };
55058 return ModalSlideOut;
55059}(PageTransition));
55060var ModalMDSlideIn = (function (_super) {
55061 __extends$64(ModalMDSlideIn, _super);
55062 function ModalMDSlideIn() {
55063 return _super !== null && _super.apply(this, arguments) || this;
55064 }
55065 /**
55066 * @return {?}
55067 */
55068 ModalMDSlideIn.prototype.init = function () {
55069 _super.prototype.init.call(this);
55070 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
55071 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
55072 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
55073 backdrop.fromTo('opacity', 0.01, 0.4);
55074 wrapper.fromTo('translateY', '40px', '0px');
55075 wrapper.fromTo('opacity', 0.01, 1);
55076 var /** @type {?} */ DURATION = 280;
55077 var /** @type {?} */ EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
55078 this.element(this.enteringView.pageRef()).easing(EASING).duration(DURATION)
55079 .add(backdrop)
55080 .add(wrapper);
55081 };
55082 return ModalMDSlideIn;
55083}(PageTransition));
55084var ModalMDSlideOut = (function (_super) {
55085 __extends$64(ModalMDSlideOut, _super);
55086 function ModalMDSlideOut() {
55087 return _super !== null && _super.apply(this, arguments) || this;
55088 }
55089 /**
55090 * @return {?}
55091 */
55092 ModalMDSlideOut.prototype.init = function () {
55093 _super.prototype.init.call(this);
55094 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
55095 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
55096 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
55097 backdrop.fromTo('opacity', 0.4, 0.0);
55098 wrapper.fromTo('translateY', '0px', '40px');
55099 wrapper.fromTo('opacity', 0.99, 0);
55100 this
55101 .element(this.leavingView.pageRef())
55102 .duration(200)
55103 .easing('cubic-bezier(0.47,0,0.745,0.715)')
55104 .add(wrapper)
55105 .add(backdrop);
55106 };
55107 return ModalMDSlideOut;
55108}(PageTransition));
55109
55110var __extends$63 = (undefined && undefined.__extends) || (function () {
55111 var extendStatics = Object.setPrototypeOf ||
55112 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
55113 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
55114 return function (d, b) {
55115 extendStatics(d, b);
55116 function __() { this.constructor = d; }
55117 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
55118 };
55119})();
55120/**
55121 * @hidden
55122 */
55123var ModalImpl = (function (_super) {
55124 __extends$63(ModalImpl, _super);
55125 /**
55126 * @param {?} app
55127 * @param {?} component
55128 * @param {?} data
55129 * @param {?=} opts
55130 * @param {?=} config
55131 */
55132 function ModalImpl(app, component, data, opts, config) {
55133 if (opts === void 0) { opts = {}; }
55134 var _this = this;
55135 data = data || {};
55136 data.component = component;
55137 opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
55138 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
55139 data.opts = opts;
55140 _this = _super.call(this, ModalCmp, data, null) || this;
55141 _this._app = app;
55142 _this._enterAnimation = opts.enterAnimation;
55143 _this._leaveAnimation = opts.leaveAnimation;
55144 _this.isOverlay = true;
55145 config.setTransition('modal-slide-in', ModalSlideIn);
55146 config.setTransition('modal-slide-out', ModalSlideOut);
55147 config.setTransition('modal-md-slide-in', ModalMDSlideIn);
55148 config.setTransition('modal-md-slide-out', ModalMDSlideOut);
55149 return _this;
55150 }
55151 /**
55152 * @hidden
55153 * @param {?} direction
55154 * @return {?}
55155 */
55156 ModalImpl.prototype.getTransitionName = function (direction) {
55157 var /** @type {?} */ key;
55158 if (direction === 'back') {
55159 if (this._leaveAnimation) {
55160 return this._leaveAnimation;
55161 }
55162 key = 'modalLeave';
55163 }
55164 else {
55165 if (this._enterAnimation) {
55166 return this._enterAnimation;
55167 }
55168 key = 'modalEnter';
55169 }
55170 return this._nav && this._nav.config.get(key);
55171 };
55172 /**
55173 * Present the action sheet instance.
55174 *
55175 * @param {?=} navOptions
55176 * @return {?}
55177 */
55178 ModalImpl.prototype.present = function (navOptions) {
55179 if (navOptions === void 0) { navOptions = {}; }
55180 navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
55181 return this._app.present(this, navOptions, PORTAL_MODAL);
55182 };
55183 return ModalImpl;
55184}(ViewController));
55185
55186var __extends$62 = (undefined && undefined.__extends) || (function () {
55187 var extendStatics = Object.setPrototypeOf ||
55188 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
55189 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
55190 return function (d, b) {
55191 extendStatics(d, b);
55192 function __() { this.constructor = d; }
55193 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
55194 };
55195})();
55196/**
55197 * @hidden
55198 */
55199var Modal = (function (_super) {
55200 __extends$62(Modal, _super);
55201 /**
55202 * @param {?} app
55203 * @param {?} component
55204 * @param {?} data
55205 * @param {?=} opts
55206 * @param {?=} config
55207 * @param {?=} deepLinker
55208 */
55209 function Modal(app, component, data, opts, config, deepLinker) {
55210 if (opts === void 0) { opts = {}; }
55211 var _this = _super.call(this, app, component, config, deepLinker) || this;
55212 _this.data = data;
55213 _this.opts = opts;
55214 _this.isOverlay = true;
55215 return _this;
55216 }
55217 /**
55218 * @return {?}
55219 */
55220 Modal.prototype.getImplementation = function () {
55221 return new ModalImpl(this._app, this._component, this.data, this.opts, this._config);
55222 };
55223 return Modal;
55224}(OverlayProxy));
55225
55226/**
55227 * \@name ModalController
55228 * \@description
55229 * A Modal is a content pane that goes over the user's current page.
55230 * Usually it is used for making a choice or editing an item. A modal uses the
55231 * `NavController` to
55232 * {\@link /docs/api/components/nav/NavController/#present present}
55233 * itself in the root nav stack. It is added to the stack similar to how
55234 * {\@link /docs/api/components/nav/NavController/#push NavController.push}
55235 * works.
55236 *
55237 * When a modal (or any other overlay such as an alert or actionsheet) is
55238 * "presented" to a nav controller, the overlay is added to the app's root nav.
55239 * After the modal has been presented, from within the component instance, the
55240 * modal can later be closed or "dismissed" by using the ViewController's
55241 * `dismiss` method. Additionally, you can dismiss any overlay by using `pop`
55242 * on the root nav controller. Modals are not reusable. When a modal is dismissed
55243 * it is destroyed.
55244 *
55245 * Data can be passed to a new modal through `Modal.create()` as the second
55246 * argument. The data can then be accessed from the opened page by injecting
55247 * `NavParams`. Note that the page, which opened as a modal, has no special
55248 * "modal" logic within it, but uses `NavParams` no differently than a
55249 * standard page.
55250 *
55251 * \@usage
55252 * ```ts
55253 * import { ModalController, NavParams } from 'ionic-angular';
55254 *
55255 * \@Component(...)
55256 * class HomePage {
55257 *
55258 * constructor(public modalCtrl: ModalController) { }
55259 *
55260 * presentProfileModal() {
55261 * const profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
55262 * profileModal.present();
55263 * }
55264 *
55265 * }
55266 *
55267 * \@Component(...)
55268 * class Profile {
55269 *
55270 * constructor(params: NavParams) {
55271 * console.log('UserId', params.get('userId'));
55272 * }
55273 *
55274 * }
55275 * ```
55276 *
55277 * \@advanced
55278 *
55279 * | Option | Type | Description |
55280 * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
55281 * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
55282 * | enableBackdropDismiss |`boolean` | Whether the popover should be dismissed by tapping the backdrop. Default true. |
55283 * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
55284 *
55285 * A modal can also emit data, which is useful when it is used to add or edit
55286 * data. For example, a profile page could slide up in a modal, and on submit,
55287 * the submit button could pass the updated profile data, then dismiss the
55288 * modal.
55289 *
55290 * ```ts
55291 * import { Component } from '\@angular/core';
55292 * import { ModalController, ViewController } from 'ionic-angular';
55293 *
55294 * \@Component(...)
55295 * class HomePage {
55296 *
55297 * constructor(public modalCtrl: ModalController) {
55298 *
55299 * }
55300 *
55301 * presentContactModal() {
55302 * let contactModal = this.modalCtrl.create(ContactUs);
55303 * contactModal.present();
55304 * }
55305 *
55306 * presentProfileModal() {
55307 * let profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
55308 * profileModal.onDidDismiss(data => {
55309 * console.log(data);
55310 * });
55311 * profileModal.present();
55312 * }
55313 *
55314 * }
55315 *
55316 * \@Component(...)
55317 * class Profile {
55318 *
55319 * constructor(public viewCtrl: ViewController) {
55320 *
55321 * }
55322 *
55323 * dismiss() {
55324 * let data = { 'foo': 'bar' };
55325 * this.viewCtrl.dismiss(data);
55326 * }
55327 *
55328 * }
55329 * ```
55330 *
55331 * A common issue is that a developer may try to implement navigation in a modal, but when you try NavController.push(),
55332 * you will notice that the status bar on iOS gets cut off. The proper way to implement navigation in a modal is to
55333 * make the modal component a navigation container, and set the root page to the page you want to show in your modal.
55334 *
55335 * ```ts
55336 * \@Component({
55337 * template: '<ion-nav [root]="rootPage" [rootParams]="rootParams"></ion-nav>'
55338 * })
55339 * export class MyModalWrapper {
55340 * rootPage = 'MyModalContentPage'; // This is the page you want your modal to display
55341 * rootParams;
55342 *
55343 * constructor(navParams: NavParams, private viewCtrl: ViewController) {
55344 * this.rootParams = Object.assign({}, navParams.data, {viewCtrl: viewCtrl});
55345 * // This line will send the view controller into your child views, so you can dismiss the modals from there.
55346 * }
55347 * }
55348 * ```
55349 * \@demo /docs/demos/src/modal/
55350 * @see {\@link /docs/components#modals Modal Component Docs}
55351 */
55352var ModalController = (function () {
55353 /**
55354 * @param {?} _app
55355 * @param {?} config
55356 * @param {?} deepLinker
55357 */
55358 function ModalController(_app, config, deepLinker) {
55359 this._app = _app;
55360 this.config = config;
55361 this.deepLinker = deepLinker;
55362 }
55363 /**
55364 * Create a modal to display. See below for options.
55365 *
55366 * @param {?} component
55367 * @param {?=} data
55368 * @param {?=} opts
55369 * @return {?}
55370 */
55371 ModalController.prototype.create = function (component, data, opts) {
55372 if (data === void 0) { data = {}; }
55373 if (opts === void 0) { opts = {}; }
55374 return new Modal(this._app, component, data, opts, this.config, this.deepLinker);
55375 };
55376 return ModalController;
55377}());
55378ModalController.decorators = [
55379 { type: Injectable },
55380];
55381/**
55382 * @nocollapse
55383 */
55384ModalController.ctorParameters = function () { return [
55385 { type: App, },
55386 { type: Config, },
55387 { type: DeepLinker, },
55388]; };
55389
55390/**
55391 * \@name NavPop
55392 * \@description
55393 * Directive to declaratively pop the current page off from the
55394 * navigation stack.
55395 *
55396 * \@usage
55397 * ```html
55398 * <ion-content>
55399 *
55400 * <button ion-button navPop>Go Back</button>
55401 *
55402 * </ion-content>
55403 * ```
55404 *
55405 * Similar to {\@link /docs/api/components/nav/NavPush/ `NavPush` }
55406 * \@demo /docs/demos/src/navigation/
55407 * @see {\@link /docs/components#navigation Navigation Component Docs}
55408 * @see {\@link ../NavPush NavPush API Docs}
55409 */
55410var NavPop = (function () {
55411 /**
55412 * @param {?} _nav
55413 */
55414 function NavPop(_nav) {
55415 this._nav = _nav;
55416 if (!_nav) {
55417 console.error('navPop must be within a NavController');
55418 }
55419 }
55420 /**
55421 * @hidden
55422 * @return {?}
55423 */
55424 NavPop.prototype.onClick = function () {
55425 // If no target, or if target is _self, prevent default browser behavior
55426 if (this._nav) {
55427 this._nav.pop().catch(function () {
55428 (void 0) /* console.debug */;
55429 });
55430 return false;
55431 }
55432 return true;
55433 };
55434 return NavPop;
55435}());
55436NavPop.decorators = [
55437 { type: Directive, args: [{
55438 selector: '[navPop]'
55439 },] },
55440];
55441/**
55442 * @nocollapse
55443 */
55444NavPop.ctorParameters = function () { return [
55445 { type: NavController, decorators: [{ type: Optional },] },
55446]; };
55447NavPop.propDecorators = {
55448 'onClick': [{ type: HostListener, args: ['click',] },],
55449};
55450
55451/**
55452 * @hidden
55453 */
55454var NavPopAnchor = (function () {
55455 /**
55456 * @param {?} host
55457 * @param {?} linker
55458 * @param {?} viewCtrl
55459 */
55460 function NavPopAnchor(host, linker, viewCtrl) {
55461 this.host = host;
55462 this.linker = linker;
55463 this.viewCtrl = viewCtrl;
55464 }
55465 /**
55466 * @return {?}
55467 */
55468 NavPopAnchor.prototype.updateHref = function () {
55469 if (this.host && this.viewCtrl) {
55470 var /** @type {?} */ previousView = this.host._nav.getPrevious(this.viewCtrl);
55471 this._href = (previousView && this.linker.createUrl(this.host._nav, this.viewCtrl.component, this.viewCtrl.data)) || '#';
55472 }
55473 else {
55474 this._href = '#';
55475 }
55476 };
55477 /**
55478 * @return {?}
55479 */
55480 NavPopAnchor.prototype.ngAfterContentInit = function () {
55481 this.updateHref();
55482 };
55483 return NavPopAnchor;
55484}());
55485NavPopAnchor.decorators = [
55486 { type: Directive, args: [{
55487 selector: 'a[navPop]',
55488 host: {
55489 '[attr.href]': '_href'
55490 }
55491 },] },
55492];
55493/**
55494 * @nocollapse
55495 */
55496NavPopAnchor.ctorParameters = function () { return [
55497 { type: NavPop, decorators: [{ type: Optional },] },
55498 { type: DeepLinker, },
55499 { type: ViewController, decorators: [{ type: Optional },] },
55500]; };
55501
55502/**
55503 * \@name NavPush
55504 * \@description
55505 * Directive to declaratively push a new page to the current nav
55506 * stack.
55507 *
55508 * \@usage
55509 * ```html
55510 * <button ion-button [navPush]="pushPage"></button>
55511 * ```
55512 *
55513 * To specify parameters you can use array syntax or the `navParams`
55514 * property:
55515 *
55516 * ```html
55517 * <button ion-button [navPush]="pushPage" [navParams]="params">Go</button>
55518 * ```
55519 *
55520 * Where `pushPage` and `params` are specified in your component,
55521 * and `pushPage` contains a reference to a
55522 * component you would like to push:
55523 *
55524 * ```ts
55525 * import { LoginPage } from './login';
55526 *
55527 * \@Component({
55528 * template: `<button ion-button [navPush]="pushPage" [navParams]="params">Go</button>`
55529 * })
55530 * class MyPage {
55531 * pushPage: any;
55532 * params: Object;
55533 * constructor(){
55534 * this.pushPage = LoginPage;
55535 * this.params = { id: 42 };
55536 * }
55537 * }
55538 * ```
55539 *
55540 * \@demo /docs/demos/src/navigation/
55541 * @see {\@link /docs/components#navigation Navigation Component Docs}
55542 * @see {\@link ../NavPop NavPop API Docs}
55543 *
55544 */
55545var NavPush = (function () {
55546 /**
55547 * @param {?} _nav
55548 */
55549 function NavPush(_nav) {
55550 this._nav = _nav;
55551 if (!_nav) {
55552 console.error('navPush must be within a NavController');
55553 }
55554 }
55555 /**
55556 * @hidden
55557 * @return {?}
55558 */
55559 NavPush.prototype.onClick = function () {
55560 if (this._nav && this.navPush) {
55561 this._nav.push(this.navPush, this.navParams);
55562 return false;
55563 }
55564 return true;
55565 };
55566 return NavPush;
55567}());
55568NavPush.decorators = [
55569 { type: Directive, args: [{
55570 selector: '[navPush]'
55571 },] },
55572];
55573/**
55574 * @nocollapse
55575 */
55576NavPush.ctorParameters = function () { return [
55577 { type: NavController, decorators: [{ type: Optional },] },
55578]; };
55579NavPush.propDecorators = {
55580 'navPush': [{ type: Input },],
55581 'navParams': [{ type: Input },],
55582 'onClick': [{ type: HostListener, args: ['click',] },],
55583};
55584
55585/**
55586 * @hidden
55587 */
55588var NavPushAnchor = (function () {
55589 /**
55590 * @param {?} host
55591 * @param {?} linker
55592 */
55593 function NavPushAnchor(host, linker) {
55594 this.host = host;
55595 this.linker = linker;
55596 }
55597 /**
55598 * @return {?}
55599 */
55600 NavPushAnchor.prototype.updateHref = function () {
55601 if (this.host && this.linker) {
55602 this._href = this.linker.createUrl(this.host._nav, this.host.navPush, this.host.navParams) || '#';
55603 }
55604 else {
55605 this._href = '#';
55606 }
55607 };
55608 /**
55609 * @return {?}
55610 */
55611 NavPushAnchor.prototype.ngAfterContentInit = function () {
55612 this.updateHref();
55613 };
55614 return NavPushAnchor;
55615}());
55616NavPushAnchor.decorators = [
55617 { type: Directive, args: [{
55618 selector: 'a[navPush]',
55619 host: {
55620 '[attr.href]': '_href'
55621 }
55622 },] },
55623];
55624/**
55625 * @nocollapse
55626 */
55627NavPushAnchor.ctorParameters = function () { return [
55628 { type: NavPush, decorators: [{ type: Host },] },
55629 { type: DeepLinker, decorators: [{ type: Optional },] },
55630]; };
55631
55632var __extends$65 = (undefined && undefined.__extends) || (function () {
55633 var extendStatics = Object.setPrototypeOf ||
55634 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
55635 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
55636 return function (d, b) {
55637 extendStatics(d, b);
55638 function __() { this.constructor = d; }
55639 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
55640 };
55641})();
55642/**
55643 * \@name Note
55644 * \@module ionic
55645 * \@description
55646 * A note is detailed item in an ion-item. It creates greyed out element that can be on the left or right side of an item.
55647 * \@usage
55648 *
55649 * ```html
55650 * <ion-content>
55651 * <ion-list>
55652 * <ion-item>
55653 * <ion-note item-start>
55654 * Left Note
55655 * </ion-note>
55656 * My Item
55657 * <ion-note item-end>
55658 * Right Note
55659 * </ion-note>
55660 * </ion-item>
55661 * </ion-list>
55662 * </ion-content>
55663 * ```
55664 * {\@link /docs/api/components/api/components/item/item ion-item}
55665 */
55666var Note = (function (_super) {
55667 __extends$65(Note, _super);
55668 /**
55669 * @param {?} config
55670 * @param {?} elementRef
55671 * @param {?} renderer
55672 */
55673 function Note(config, elementRef, renderer) {
55674 return _super.call(this, config, elementRef, renderer, 'note') || this;
55675 }
55676 return Note;
55677}(Ion));
55678Note.decorators = [
55679 { type: Directive, args: [{
55680 selector: 'ion-note'
55681 },] },
55682];
55683/**
55684 * @nocollapse
55685 */
55686Note.ctorParameters = function () { return [
55687 { type: Config, },
55688 { type: ElementRef, },
55689 { type: Renderer, },
55690]; };
55691
55692/**
55693 * \@name Option
55694 * \@description
55695 * `ion-option` is a child component of `ion-select`. Similar to the native option element, `ion-option` can take a value and a selected property.
55696 *
55697 * \@demo /docs/demos/src/select/
55698 */
55699var Option = (function () {
55700 /**
55701 * @param {?} _elementRef
55702 */
55703 function Option(_elementRef) {
55704 this._elementRef = _elementRef;
55705 this._selected = false;
55706 this._disabled = false;
55707 /**
55708 * \@output {any} Event to evaluate when option is selected.
55709 */
55710 this.ionSelect = new EventEmitter();
55711 }
55712 Object.defineProperty(Option.prototype, "disabled", {
55713 /**
55714 * \@input {boolean} If true, the user cannot interact with this element.
55715 * @return {?}
55716 */
55717 get: function () {
55718 return this._disabled;
55719 },
55720 /**
55721 * @param {?} val
55722 * @return {?}
55723 */
55724 set: function (val) {
55725 this._disabled = isTrueProperty(val);
55726 },
55727 enumerable: true,
55728 configurable: true
55729 });
55730 Object.defineProperty(Option.prototype, "selected", {
55731 /**
55732 * \@input {boolean} If true, the element is selected.
55733 * @return {?}
55734 */
55735 get: function () {
55736 return this._selected;
55737 },
55738 /**
55739 * @param {?} val
55740 * @return {?}
55741 */
55742 set: function (val) {
55743 this._selected = isTrueProperty(val);
55744 },
55745 enumerable: true,
55746 configurable: true
55747 });
55748 Object.defineProperty(Option.prototype, "value", {
55749 /**
55750 * \@input {any} The value of the option.
55751 * @return {?}
55752 */
55753 get: function () {
55754 if (isPresent(this._value)) {
55755 return this._value;
55756 }
55757 return this.text;
55758 },
55759 /**
55760 * @param {?} val
55761 * @return {?}
55762 */
55763 set: function (val) {
55764 this._value = val;
55765 },
55766 enumerable: true,
55767 configurable: true
55768 });
55769 Object.defineProperty(Option.prototype, "text", {
55770 /**
55771 * @hidden
55772 * @return {?}
55773 */
55774 get: function () {
55775 return this._elementRef.nativeElement.textContent;
55776 },
55777 enumerable: true,
55778 configurable: true
55779 });
55780 return Option;
55781}());
55782Option.decorators = [
55783 { type: Directive, args: [{
55784 selector: 'ion-option'
55785 },] },
55786];
55787/**
55788 * @nocollapse
55789 */
55790Option.ctorParameters = function () { return [
55791 { type: ElementRef, },
55792]; };
55793Option.propDecorators = {
55794 'disabled': [{ type: Input },],
55795 'selected': [{ type: Input },],
55796 'value': [{ type: Input },],
55797 'ionSelect': [{ type: Output },],
55798};
55799
55800/**
55801 * @hidden
55802 */
55803var PopoverCmp = (function () {
55804 /**
55805 * @param {?} _cfr
55806 * @param {?} _elementRef
55807 * @param {?} _renderer
55808 * @param {?} _config
55809 * @param {?} _navParams
55810 * @param {?} _viewCtrl
55811 * @param {?} gestureCtrl
55812 * @param {?} moduleLoader
55813 */
55814 function PopoverCmp(_cfr, _elementRef, _renderer, _config, _navParams, _viewCtrl, gestureCtrl, moduleLoader) {
55815 this._cfr = _cfr;
55816 this._elementRef = _elementRef;
55817 this._renderer = _renderer;
55818 this._config = _config;
55819 this._navParams = _navParams;
55820 this._viewCtrl = _viewCtrl;
55821 this.moduleLoader = moduleLoader;
55822 this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
55823 this.d = _navParams.data.opts;
55824 _renderer.setElementClass(_elementRef.nativeElement, "popover-" + _config.get('mode'), true);
55825 if (this.d.cssClass) {
55826 this.d.cssClass.split(' ').forEach(function (cssClass) {
55827 // Make sure the class isn't whitespace, otherwise it throws exceptions
55828 if (cssClass.trim() !== '')
55829 _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
55830 });
55831 }
55832 this.id = (++popoverIds);
55833 }
55834 /**
55835 * @return {?}
55836 */
55837 PopoverCmp.prototype.ionViewPreLoad = function () {
55838 this._load(this._navParams.data.component);
55839 };
55840 /**
55841 * @param {?} component
55842 * @return {?}
55843 */
55844 PopoverCmp.prototype._load = function (component) {
55845 if (component) {
55846 var /** @type {?} */ cfr = this.moduleLoader.getComponentFactoryResolver(component);
55847 if (!cfr) {
55848 cfr = this._cfr;
55849 }
55850 var /** @type {?} */ componentFactory = cfr.resolveComponentFactory(component);
55851 // ******** DOM WRITE ****************
55852 var /** @type {?} */ componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []);
55853 this._viewCtrl._setInstance(componentRef.instance);
55854 this._enabled = true;
55855 // Subscribe to events in order to block gestures
55856 // TODO, should we unsubscribe? memory leak?
55857 this._viewCtrl.willEnter.subscribe(this._viewWillEnter.bind(this));
55858 this._viewCtrl.didLeave.subscribe(this._viewDidLeave.bind(this));
55859 }
55860 };
55861 /**
55862 * @return {?}
55863 */
55864 PopoverCmp.prototype._viewWillEnter = function () {
55865 this._gestureBlocker.block();
55866 };
55867 /**
55868 * @return {?}
55869 */
55870 PopoverCmp.prototype._viewDidLeave = function () {
55871 this._gestureBlocker.unblock();
55872 };
55873 /**
55874 * @param {?} componentRef
55875 * @param {?} className
55876 * @return {?}
55877 */
55878 PopoverCmp.prototype._setCssClass = function (componentRef, className) {
55879 this._renderer.setElementClass(componentRef.location.nativeElement, className, true);
55880 };
55881 /**
55882 * @return {?}
55883 */
55884 PopoverCmp.prototype._bdClick = function () {
55885 if (this._enabled && this.d.enableBackdropDismiss) {
55886 return this._viewCtrl.dismiss(null, 'backdrop');
55887 }
55888 };
55889 /**
55890 * @param {?} ev
55891 * @return {?}
55892 */
55893 PopoverCmp.prototype._keyUp = function (ev) {
55894 if (this._enabled && ev.keyCode === KEY_ESCAPE && this._viewCtrl.isLast()) {
55895 this._bdClick();
55896 }
55897 };
55898 /**
55899 * @return {?}
55900 */
55901 PopoverCmp.prototype.ngOnDestroy = function () {
55902 (void 0) /* assert */;
55903 this._gestureBlocker.destroy();
55904 };
55905 return PopoverCmp;
55906}());
55907PopoverCmp.decorators = [
55908 { type: Component, args: [{
55909 selector: 'ion-popover',
55910 template: '<ion-backdrop (click)="_bdClick()" [hidden]="!d.showBackdrop"></ion-backdrop>' +
55911 '<div class="popover-wrapper">' +
55912 '<div class="popover-arrow"></div>' +
55913 '<div class="popover-content">' +
55914 '<div class="popover-viewport">' +
55915 '<div #viewport nav-viewport></div>' +
55916 '</div>' +
55917 '</div>' +
55918 '</div>'
55919 },] },
55920];
55921/**
55922 * @nocollapse
55923 */
55924PopoverCmp.ctorParameters = function () { return [
55925 { type: ComponentFactoryResolver, },
55926 { type: ElementRef, },
55927 { type: Renderer, },
55928 { type: Config, },
55929 { type: NavParams, },
55930 { type: ViewController, },
55931 { type: GestureController, },
55932 { type: ModuleLoader, },
55933]; };
55934PopoverCmp.propDecorators = {
55935 '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
55936 '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
55937};
55938var popoverIds = -1;
55939
55940var __extends$68 = (undefined && undefined.__extends) || (function () {
55941 var extendStatics = Object.setPrototypeOf ||
55942 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
55943 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
55944 return function (d, b) {
55945 extendStatics(d, b);
55946 function __() { this.constructor = d; }
55947 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
55948 };
55949})();
55950/**
55951 * Animations for popover
55952 */
55953var PopoverTransition = (function (_super) {
55954 __extends$68(PopoverTransition, _super);
55955 function PopoverTransition() {
55956 return _super !== null && _super.apply(this, arguments) || this;
55957 }
55958 /**
55959 * @param {?} nativeEle
55960 * @param {?} ev
55961 * @return {?}
55962 */
55963 PopoverTransition.prototype.mdPositionView = function (nativeEle, ev) {
55964 var /** @type {?} */ originY = 'top';
55965 var /** @type {?} */ originX = 'left';
55966 var /** @type {?} */ popoverWrapperEle = (nativeEle.querySelector('.popover-wrapper'));
55967 // Popover content width and height
55968 var /** @type {?} */ popoverEle = (nativeEle.querySelector('.popover-content'));
55969 var /** @type {?} */ popoverDim = popoverEle.getBoundingClientRect();
55970 var /** @type {?} */ popoverWidth = popoverDim.width;
55971 var /** @type {?} */ popoverHeight = popoverDim.height;
55972 // Window body width and height
55973 var /** @type {?} */ bodyWidth = this.plt.width();
55974 var /** @type {?} */ bodyHeight = this.plt.height();
55975 // If ev was passed, use that for target element
55976 var /** @type {?} */ targetDim = ev && ev.target && ev.target.getBoundingClientRect();
55977 var /** @type {?} */ targetTop = (targetDim && 'top' in targetDim) ? targetDim.top : (bodyHeight / 2) - (popoverHeight / 2);
55978 var /** @type {?} */ targetLeft = (targetDim && 'left' in targetDim) ? targetDim.left : (bodyWidth / 2) - (popoverWidth / 2);
55979 var /** @type {?} */ targetHeight = targetDim && targetDim.height || 0;
55980 var /** @type {?} */ popoverCSS = {
55981 top: targetTop,
55982 left: targetLeft
55983 };
55984 // If the popover left is less than the padding it is off screen
55985 // to the left so adjust it, else if the width of the popover
55986 // exceeds the body width it is off screen to the right so adjust
55987 if (popoverCSS.left < POPOVER_MD_BODY_PADDING) {
55988 popoverCSS.left = POPOVER_MD_BODY_PADDING;
55989 }
55990 else if (popoverWidth + POPOVER_MD_BODY_PADDING + popoverCSS.left > bodyWidth) {
55991 popoverCSS.left = bodyWidth - popoverWidth - POPOVER_MD_BODY_PADDING;
55992 originX = 'right';
55993 }
55994 // If the popover when popped down stretches past bottom of screen,
55995 // make it pop up if there's room above
55996 if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) {
55997 popoverCSS.top = targetTop - popoverHeight;
55998 nativeEle.className = nativeEle.className + ' popover-bottom';
55999 originY = 'bottom';
56000 // If there isn't room for it to pop up above the target cut it off
56001 }
56002 else if (targetTop + targetHeight + popoverHeight > bodyHeight) {
56003 popoverEle.style.bottom = POPOVER_MD_BODY_PADDING + 'px';
56004 }
56005 popoverEle.style.top = popoverCSS.top + 'px';
56006 popoverEle.style.left = popoverCSS.left + 'px';
56007 ((popoverEle.style))[this.plt.Css.transformOrigin] = originY + ' ' + originX;
56008 // Since the transition starts before styling is done we
56009 // want to wait for the styles to apply before showing the wrapper
56010 popoverWrapperEle.style.opacity = '1';
56011 };
56012 /**
56013 * @param {?} nativeEle
56014 * @param {?} ev
56015 * @return {?}
56016 */
56017 PopoverTransition.prototype.iosPositionView = function (nativeEle, ev) {
56018 var /** @type {?} */ originY = 'top';
56019 var /** @type {?} */ originX = 'left';
56020 var /** @type {?} */ popoverWrapperEle = (nativeEle.querySelector('.popover-wrapper'));
56021 // Popover content width and height
56022 var /** @type {?} */ popoverEle = (nativeEle.querySelector('.popover-content'));
56023 var /** @type {?} */ popoverDim = popoverEle.getBoundingClientRect();
56024 var /** @type {?} */ popoverWidth = popoverDim.width;
56025 var /** @type {?} */ popoverHeight = popoverDim.height;
56026 // Window body width and height
56027 var /** @type {?} */ bodyWidth = this.plt.width();
56028 var /** @type {?} */ bodyHeight = this.plt.height();
56029 // If ev was passed, use that for target element
56030 var /** @type {?} */ targetDim = ev && ev.target && ev.target.getBoundingClientRect();
56031 var /** @type {?} */ targetTop = (targetDim && 'top' in targetDim) ? targetDim.top : (bodyHeight / 2) - (popoverHeight / 2);
56032 var /** @type {?} */ targetLeft = (targetDim && 'left' in targetDim) ? targetDim.left : (bodyWidth / 2);
56033 var /** @type {?} */ targetWidth = targetDim && targetDim.width || 0;
56034 var /** @type {?} */ targetHeight = targetDim && targetDim.height || 0;
56035 // The arrow that shows above the popover on iOS
56036 var /** @type {?} */ arrowEle = (nativeEle.querySelector('.popover-arrow'));
56037 var /** @type {?} */ arrowDim = arrowEle.getBoundingClientRect();
56038 var /** @type {?} */ arrowWidth = arrowDim.width;
56039 var /** @type {?} */ arrowHeight = arrowDim.height;
56040 // If no ev was passed, hide the arrow
56041 if (!targetDim) {
56042 arrowEle.style.display = 'none';
56043 }
56044 var /** @type {?} */ arrowCSS = {
56045 top: targetTop + targetHeight,
56046 left: targetLeft + (targetWidth / 2) - (arrowWidth / 2)
56047 };
56048 var /** @type {?} */ popoverCSS = {
56049 top: targetTop + targetHeight + (arrowHeight - 1),
56050 left: targetLeft + (targetWidth / 2) - (popoverWidth / 2)
56051 };
56052 // If the popover left is less than the padding it is off screen
56053 // to the left so adjust it, else if the width of the popover
56054 // exceeds the body width it is off screen to the right so adjust
56055 if (popoverCSS.left < POPOVER_IOS_BODY_PADDING) {
56056 popoverCSS.left = POPOVER_IOS_BODY_PADDING;
56057 }
56058 else if (popoverWidth + POPOVER_IOS_BODY_PADDING + popoverCSS.left > bodyWidth) {
56059 popoverCSS.left = bodyWidth - popoverWidth - POPOVER_IOS_BODY_PADDING;
56060 originX = 'right';
56061 }
56062 // If the popover when popped down stretches past bottom of screen,
56063 // make it pop up if there's room above
56064 if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) {
56065 arrowCSS.top = targetTop - (arrowHeight + 1);
56066 popoverCSS.top = targetTop - popoverHeight - (arrowHeight - 1);
56067 nativeEle.className = nativeEle.className + ' popover-bottom';
56068 originY = 'bottom';
56069 // If there isn't room for it to pop up above the target cut it off
56070 }
56071 else if (targetTop + targetHeight + popoverHeight > bodyHeight) {
56072 popoverEle.style.bottom = POPOVER_IOS_BODY_PADDING + '%';
56073 }
56074 arrowEle.style.top = arrowCSS.top + 'px';
56075 arrowEle.style.left = arrowCSS.left + 'px';
56076 popoverEle.style.top = popoverCSS.top + 'px';
56077 popoverEle.style.left = popoverCSS.left + 'px';
56078 ((popoverEle.style))[this.plt.Css.transformOrigin] = originY + ' ' + originX;
56079 // Since the transition starts before styling is done we
56080 // want to wait for the styles to apply before showing the wrapper
56081 popoverWrapperEle.style.opacity = '1';
56082 };
56083 return PopoverTransition;
56084}(PageTransition));
56085var PopoverPopIn = (function (_super) {
56086 __extends$68(PopoverPopIn, _super);
56087 function PopoverPopIn() {
56088 return _super !== null && _super.apply(this, arguments) || this;
56089 }
56090 /**
56091 * @return {?}
56092 */
56093 PopoverPopIn.prototype.init = function () {
56094 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
56095 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
56096 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
56097 wrapper.fromTo('opacity', 0.01, 1);
56098 backdrop.fromTo('opacity', 0.01, 0.08);
56099 this
56100 .easing('ease')
56101 .duration(100)
56102 .add(backdrop)
56103 .add(wrapper);
56104 };
56105 /**
56106 * @return {?}
56107 */
56108 PopoverPopIn.prototype.play = function () {
56109 var _this = this;
56110 this.plt.raf(function () {
56111 _this.iosPositionView(_this.enteringView.pageRef().nativeElement, _this.opts.ev);
56112 _super.prototype.play.call(_this);
56113 });
56114 };
56115 return PopoverPopIn;
56116}(PopoverTransition));
56117var PopoverPopOut = (function (_super) {
56118 __extends$68(PopoverPopOut, _super);
56119 function PopoverPopOut() {
56120 return _super !== null && _super.apply(this, arguments) || this;
56121 }
56122 /**
56123 * @return {?}
56124 */
56125 PopoverPopOut.prototype.init = function () {
56126 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
56127 var /** @type {?} */ backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
56128 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
56129 wrapper.fromTo('opacity', 0.99, 0);
56130 backdrop.fromTo('opacity', 0.08, 0);
56131 this
56132 .easing('ease')
56133 .duration(500)
56134 .add(backdrop)
56135 .add(wrapper);
56136 };
56137 return PopoverPopOut;
56138}(PopoverTransition));
56139var PopoverMdPopIn = (function (_super) {
56140 __extends$68(PopoverMdPopIn, _super);
56141 function PopoverMdPopIn() {
56142 return _super !== null && _super.apply(this, arguments) || this;
56143 }
56144 /**
56145 * @return {?}
56146 */
56147 PopoverMdPopIn.prototype.init = function () {
56148 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
56149 var /** @type {?} */ content = new Animation(this.plt, ele.querySelector('.popover-content'));
56150 var /** @type {?} */ viewport = new Animation(this.plt, ele.querySelector('.popover-viewport'));
56151 content.fromTo('scale', 0.001, 1);
56152 viewport.fromTo('opacity', 0.01, 1);
56153 this
56154 .easing('cubic-bezier(0.36,0.66,0.04,1)')
56155 .duration(300)
56156 .add(content)
56157 .add(viewport);
56158 };
56159 /**
56160 * @return {?}
56161 */
56162 PopoverMdPopIn.prototype.play = function () {
56163 var _this = this;
56164 this.plt.raf(function () {
56165 _this.mdPositionView(_this.enteringView.pageRef().nativeElement, _this.opts.ev);
56166 _super.prototype.play.call(_this);
56167 });
56168 };
56169 return PopoverMdPopIn;
56170}(PopoverTransition));
56171var PopoverMdPopOut = (function (_super) {
56172 __extends$68(PopoverMdPopOut, _super);
56173 function PopoverMdPopOut() {
56174 return _super !== null && _super.apply(this, arguments) || this;
56175 }
56176 /**
56177 * @return {?}
56178 */
56179 PopoverMdPopOut.prototype.init = function () {
56180 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
56181 var /** @type {?} */ wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
56182 wrapper.fromTo('opacity', 0.99, 0);
56183 this
56184 .easing('ease')
56185 .duration(500)
56186 .fromTo('opacity', 0.01, 1)
56187 .add(wrapper);
56188 };
56189 return PopoverMdPopOut;
56190}(PopoverTransition));
56191var POPOVER_IOS_BODY_PADDING = 2;
56192var POPOVER_MD_BODY_PADDING = 12;
56193
56194var __extends$67 = (undefined && undefined.__extends) || (function () {
56195 var extendStatics = Object.setPrototypeOf ||
56196 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
56197 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
56198 return function (d, b) {
56199 extendStatics(d, b);
56200 function __() { this.constructor = d; }
56201 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
56202 };
56203})();
56204/**
56205 * @hidden
56206 */
56207var PopoverImpl = (function (_super) {
56208 __extends$67(PopoverImpl, _super);
56209 /**
56210 * @param {?} app
56211 * @param {?} component
56212 * @param {?=} data
56213 * @param {?=} opts
56214 * @param {?=} config
56215 */
56216 function PopoverImpl(app, component, data, opts, config) {
56217 if (data === void 0) { data = {}; }
56218 if (opts === void 0) { opts = {}; }
56219 var _this = this;
56220 opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
56221 opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
56222 data.component = component;
56223 data.opts = opts;
56224 _this = _super.call(this, PopoverCmp, data, null) || this;
56225 _this._app = app;
56226 _this.isOverlay = true;
56227 config.setTransition('popover-pop-in', PopoverPopIn);
56228 config.setTransition('popover-pop-out', PopoverPopOut);
56229 config.setTransition('popover-md-pop-in', PopoverMdPopIn);
56230 config.setTransition('popover-md-pop-out', PopoverMdPopOut);
56231 return _this;
56232 }
56233 /**
56234 * @hidden
56235 * @param {?} direction
56236 * @return {?}
56237 */
56238 PopoverImpl.prototype.getTransitionName = function (direction) {
56239 var /** @type {?} */ key = (direction === 'back' ? 'popoverLeave' : 'popoverEnter');
56240 return this._nav && this._nav.config.get(key);
56241 };
56242 /**
56243 * Present the popover instance.
56244 *
56245 * @param {?=} navOptions
56246 * @return {?}
56247 */
56248 PopoverImpl.prototype.present = function (navOptions) {
56249 if (navOptions === void 0) { navOptions = {}; }
56250 return this._app.present(this, navOptions);
56251 };
56252 return PopoverImpl;
56253}(ViewController));
56254
56255var __extends$66 = (undefined && undefined.__extends) || (function () {
56256 var extendStatics = Object.setPrototypeOf ||
56257 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
56258 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
56259 return function (d, b) {
56260 extendStatics(d, b);
56261 function __() { this.constructor = d; }
56262 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
56263 };
56264})();
56265/**
56266 * @hidden
56267 */
56268var Popover = (function (_super) {
56269 __extends$66(Popover, _super);
56270 /**
56271 * @param {?} app
56272 * @param {?} component
56273 * @param {?} data
56274 * @param {?=} opts
56275 * @param {?=} config
56276 * @param {?=} deepLinker
56277 */
56278 function Popover(app, component, data, opts, config, deepLinker) {
56279 if (opts === void 0) { opts = {}; }
56280 var _this = _super.call(this, app, component, config, deepLinker) || this;
56281 _this.data = data;
56282 _this.opts = opts;
56283 _this.isOverlay = true;
56284 return _this;
56285 }
56286 /**
56287 * @return {?}
56288 */
56289 Popover.prototype.getImplementation = function () {
56290 return new PopoverImpl(this._app, this._component, this.data, this.opts, this._config);
56291 };
56292 return Popover;
56293}(OverlayProxy));
56294
56295/**
56296 * \@name PopoverController
56297 * \@description
56298 * A Popover is a dialog that appears on top of the current page.
56299 * It can be used for anything, but generally it is used for overflow
56300 * actions that don't fit in the navigation bar.
56301 *
56302 * ### Creating
56303 * A popover can be created by calling the `create` method. The view
56304 * to display in the popover should be passed as the first argument.
56305 * Any data to pass to the popover view can optionally be passed in
56306 * the second argument. Options for the popover can optionally be
56307 * passed in the third argument. See the [create](#create) method
56308 * below for all available options.
56309 *
56310 * ### Presenting
56311 * To present a popover, call the `present` method on a PopoverController instance.
56312 * In order to position the popover relative to the element clicked, a click event
56313 * needs to be passed into the options of the the `present method. If the event
56314 * is not passed, the popover will be positioned in the center of the current
56315 * view. See the [usage](#usage) section for an example of passing this event.
56316 *
56317 * ### Dismissing
56318 * To dismiss the popover after creation, call the `dismiss()` method on the
56319 * `Popover` instance. The popover can also be dismissed from within the popover's
56320 * view by calling the `dismiss()` method on the [ViewController](../../navigation/ViewController).
56321 * The `dismiss()` call accepts an optional parameter that will be passed to the callback described
56322 * as follows. The `onDidDismiss(<func>)` function can be called to set up a callback action that will
56323 * be performed after the popover is dismissed, receiving the parameter passed to `dismiss()`.
56324 * The popover will dismiss when the backdrop is clicked by implicitly performing `dismiss(null)`,
56325 * but this can be disabled by setting `enableBackdropDismiss` to `false` in the popover options.
56326 *
56327 * > Note that after the component is dismissed, it will not be usable anymore and
56328 * another one must be created. This can be avoided by wrapping the creation and
56329 * presentation of the component in a reusable function as shown in the [usage](#usage)
56330 * section below.
56331 *
56332 * \@usage
56333 *
56334 * To open a popover on the click of a button, pass `$event` to the method
56335 * which creates and presents the popover:
56336 *
56337 * ```html
56338 * <button ion-button icon-only (click)="presentPopover($event)">
56339 * <ion-icon name="more"></ion-icon>
56340 * </button>
56341 * ```
56342 *
56343 * ```ts
56344 * import { PopoverController } from 'ionic-angular';
56345 *
56346 * \@Component({})
56347 * class MyPage {
56348 * constructor(public popoverCtrl: PopoverController) {}
56349 *
56350 * presentPopover(myEvent) {
56351 * let popover = this.popoverCtrl.create(PopoverPage);
56352 * popover.present({
56353 * ev: myEvent
56354 * });
56355 * }
56356 * }
56357 * ```
56358 *
56359 * The `PopoverPage` will display inside of the popover, and
56360 * can be anything. Below is an example of a page with items
56361 * that close the popover on click.
56362 *
56363 * ```ts
56364 * \@Component({
56365 * template: `
56366 * <ion-list>
56367 * <ion-list-header>Ionic</ion-list-header>
56368 * <button ion-item (click)="close()">Learn Ionic</button>
56369 * <button ion-item (click)="close()">Documentation</button>
56370 * <button ion-item (click)="close()">Showcase</button>
56371 * <button ion-item (click)="close()">GitHub Repo</button>
56372 * </ion-list>
56373 * `
56374 * })
56375 * class PopoverPage {
56376 * constructor(public viewCtrl: ViewController) {}
56377 *
56378 * close() {
56379 * this.viewCtrl.dismiss();
56380 * }
56381 * }
56382 * ```
56383 * \@advanced
56384 * Popover Options
56385 *
56386 * | Option | Type | Description |
56387 * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
56388 * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
56389 * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
56390 * | enableBackdropDismiss |`boolean` | Whether the popover should be dismissed by tapping the backdrop. Default true. |
56391 *
56392 *
56393 *
56394 * \@demo /docs/demos/src/popover/
56395 */
56396var PopoverController = (function () {
56397 /**
56398 * @param {?} _app
56399 * @param {?} config
56400 * @param {?} _deepLinker
56401 */
56402 function PopoverController(_app, config, _deepLinker) {
56403 this._app = _app;
56404 this.config = config;
56405 this._deepLinker = _deepLinker;
56406 }
56407 /**
56408 * Present a popover. See below for options
56409 * @param {?} component
56410 * @param {?=} data
56411 * @param {?=} opts
56412 * @return {?}
56413 */
56414 PopoverController.prototype.create = function (component, data, opts) {
56415 if (data === void 0) { data = {}; }
56416 if (opts === void 0) { opts = {}; }
56417 return new Popover(this._app, component, data, opts, this.config, this._deepLinker);
56418 };
56419 return PopoverController;
56420}());
56421PopoverController.decorators = [
56422 { type: Injectable },
56423];
56424/**
56425 * @nocollapse
56426 */
56427PopoverController.ctorParameters = function () { return [
56428 { type: App, },
56429 { type: Config, },
56430 { type: DeepLinker, },
56431]; };
56432
56433/**
56434 * \@name RadioGroup
56435 * \@description
56436 * A radio group is a group of [radio buttons](../RadioButton). It allows
56437 * a user to select at most one radio button from a set. Checking one radio
56438 * button that belongs to a radio group unchecks any previous checked
56439 * radio button within the same group.
56440 *
56441 * See the [Angular Forms Docs](https://angular.io/docs/ts/latest/guide/forms.html)
56442 * for more information on forms and inputs.
56443 *
56444 * \@usage
56445 * ```html
56446 * <ion-list radio-group [(ngModel)]="autoManufacturers">
56447 *
56448 * <ion-list-header>
56449 * Auto Manufacturers
56450 * </ion-list-header>
56451 *
56452 * <ion-item>
56453 * <ion-label>Cord</ion-label>
56454 * <ion-radio value="cord"></ion-radio>
56455 * </ion-item>
56456 *
56457 * <ion-item>
56458 * <ion-label>Duesenberg</ion-label>
56459 * <ion-radio value="duesenberg"></ion-radio>
56460 * </ion-item>
56461 *
56462 * <ion-item>
56463 * <ion-label>Hudson</ion-label>
56464 * <ion-radio value="hudson"></ion-radio>
56465 * </ion-item>
56466 *
56467 * <ion-item>
56468 * <ion-label>Packard</ion-label>
56469 * <ion-radio value="packard"></ion-radio>
56470 * </ion-item>
56471 *
56472 * <ion-item>
56473 * <ion-label>Studebaker</ion-label>
56474 * <ion-radio value="studebaker"></ion-radio>
56475 * </ion-item>
56476 *
56477 * </ion-list>
56478 * ```
56479 *
56480 * \@demo /docs/demos/src/radio/
56481 * @see {\@link /docs/components#radio Radio Component Docs}
56482 * @see {\@link ../RadioButton RadioButton API Docs}
56483 */
56484var RadioGroup = (function () {
56485 /**
56486 * @param {?} _renderer
56487 * @param {?} _elementRef
56488 * @param {?} _cd
56489 */
56490 function RadioGroup(_renderer, _elementRef, _cd) {
56491 this._renderer = _renderer;
56492 this._elementRef = _elementRef;
56493 this._cd = _cd;
56494 /**
56495 * \@internal
56496 */
56497 this._disabled = false;
56498 /**
56499 * @hidden
56500 */
56501 this._btns = [];
56502 /**
56503 * @hidden
56504 */
56505 this._ids = -1;
56506 /**
56507 * @hidden
56508 */
56509 this._init = false;
56510 /**
56511 * \@output {any} Emitted when the selected button has changed.
56512 */
56513 this.ionChange = new EventEmitter();
56514 this.id = ++radioGroupIds;
56515 }
56516 Object.defineProperty(RadioGroup.prototype, "disabled", {
56517 /**
56518 * \@input {boolean} If true, the user cannot interact with any of the buttons in the group.
56519 * @return {?}
56520 */
56521 get: function () {
56522 return this._disabled;
56523 },
56524 /**
56525 * @param {?} val
56526 * @return {?}
56527 */
56528 set: function (val) {
56529 this._disabled = isTrueProperty(val);
56530 },
56531 enumerable: true,
56532 configurable: true
56533 });
56534 /**
56535 * @hidden
56536 * @return {?}
56537 */
56538 RadioGroup.prototype.ngAfterContentInit = function () {
56539 var /** @type {?} */ activeButton = this._btns.find(function (b) { return b.checked; });
56540 if (activeButton) {
56541 this._setActive(activeButton);
56542 }
56543 };
56544 /**
56545 * @hidden
56546 * @param {?} val
56547 * @return {?}
56548 */
56549 RadioGroup.prototype.writeValue = function (val) {
56550 (void 0) /* console.debug */;
56551 this.value = val;
56552 if (this._init) {
56553 this._update();
56554 this.onTouched();
56555 this.ionChange.emit(val);
56556 }
56557 this._init = true;
56558 };
56559 /**
56560 * @hidden
56561 * @param {?} fn
56562 * @return {?}
56563 */
56564 RadioGroup.prototype.registerOnChange = function (fn) {
56565 var _this = this;
56566 this._fn = fn;
56567 this.onChange = function (val) {
56568 // onChange used when there's an formControlName
56569 (void 0) /* console.debug */;
56570 fn(val);
56571 _this.value = val;
56572 _this._update();
56573 _this.onTouched();
56574 _this.ionChange.emit(val);
56575 };
56576 };
56577 /**
56578 * @hidden
56579 * @param {?} fn
56580 * @return {?}
56581 */
56582 RadioGroup.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
56583 /**
56584 * @hidden
56585 * @return {?}
56586 */
56587 RadioGroup.prototype._update = function () {
56588 var _this = this;
56589 // loop through each of the radiobuttons
56590 var /** @type {?} */ hasChecked = false;
56591 this._btns.forEach(function (radioButton) {
56592 // check this radiobutton if its value is
56593 // the same as the radiogroups value
56594 radioButton.checked = isCheckedProperty(_this.value, radioButton.value) && !hasChecked;
56595 if (radioButton.checked) {
56596 // if this button is checked, then set it as
56597 // the radiogroup's active descendant
56598 _this._setActive(radioButton);
56599 hasChecked = true;
56600 }
56601 });
56602 };
56603 /**
56604 * @hidden
56605 * @param {?} radioButton
56606 * @return {?}
56607 */
56608 RadioGroup.prototype._setActive = function (radioButton) {
56609 this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-activedescendant', radioButton.id);
56610 };
56611 /**
56612 * @hidden
56613 * @param {?} button
56614 * @return {?}
56615 */
56616 RadioGroup.prototype.add = function (button) {
56617 var _this = this;
56618 this._btns.push(button);
56619 // listen for radiobutton select events
56620 button.ionSelect.subscribe(function (val) {
56621 // this radiobutton has been selected
56622 _this.onChange(val);
56623 });
56624 return this.id + '-' + (++this._ids);
56625 };
56626 /**
56627 * @hidden
56628 * @param {?} button
56629 * @return {?}
56630 */
56631 RadioGroup.prototype.remove = function (button) {
56632 var /** @type {?} */ index = this._btns.indexOf(button);
56633 if (index > -1) {
56634 if (button.value === this.value) {
56635 this.value = null;
56636 }
56637 this._btns.splice(index, 1);
56638 }
56639 };
56640 Object.defineProperty(RadioGroup.prototype, "_header", {
56641 /**
56642 * @hidden
56643 * @param {?} header
56644 * @return {?}
56645 */
56646 set: function (header) {
56647 if (header) {
56648 if (!header.id) {
56649 header.id = 'rg-hdr-' + this.id;
56650 }
56651 this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-describedby', header.id);
56652 }
56653 },
56654 enumerable: true,
56655 configurable: true
56656 });
56657 /**
56658 * @hidden
56659 * @param {?} val
56660 * @return {?}
56661 */
56662 RadioGroup.prototype.onChange = function (val) {
56663 // onChange used when there is not an formControlName
56664 (void 0) /* console.debug */;
56665 this.value = val;
56666 this._update();
56667 this.onTouched();
56668 this.ionChange.emit(val);
56669 this._cd.detectChanges();
56670 };
56671 /**
56672 * @hidden
56673 * @return {?}
56674 */
56675 RadioGroup.prototype.onTouched = function () { };
56676 /**
56677 * @hidden
56678 * @param {?} isDisabled
56679 * @return {?}
56680 */
56681 RadioGroup.prototype.setDisabledState = function (isDisabled) {
56682 this.disabled = isDisabled;
56683 };
56684 return RadioGroup;
56685}());
56686RadioGroup.decorators = [
56687 { type: Directive, args: [{
56688 selector: '[radio-group]',
56689 host: {
56690 'role': 'radiogroup'
56691 },
56692 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: RadioGroup, multi: true }],
56693 },] },
56694];
56695/**
56696 * @nocollapse
56697 */
56698RadioGroup.ctorParameters = function () { return [
56699 { type: Renderer, },
56700 { type: ElementRef, },
56701 { type: ChangeDetectorRef, },
56702]; };
56703RadioGroup.propDecorators = {
56704 'disabled': [{ type: Input },],
56705 'ionChange': [{ type: Output },],
56706 '_header': [{ type: ContentChild, args: [ListHeader,] },],
56707};
56708var radioGroupIds = -1;
56709
56710var __extends$69 = (undefined && undefined.__extends) || (function () {
56711 var extendStatics = Object.setPrototypeOf ||
56712 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
56713 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
56714 return function (d, b) {
56715 extendStatics(d, b);
56716 function __() { this.constructor = d; }
56717 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
56718 };
56719})();
56720/**
56721 * \@description
56722 * A radio button is a button that can be either checked or unchecked. A user can tap
56723 * the button to check or uncheck it. It can also be checked from the template using
56724 * the `checked` property.
56725 *
56726 * Use an element with a `radio-group` attribute to group a set of radio buttons. When
56727 * radio buttons are inside a [radio group](../RadioGroup), exactly one radio button
56728 * in the group can be checked at any time. If a radio button is not placed in a group,
56729 * they will all have the ability to be checked at the same time.
56730 *
56731 * See the [Angular Forms Docs](https://angular.io/docs/ts/latest/guide/forms.html) for
56732 * more information on forms and input.
56733 *
56734 * \@usage
56735 * ```html
56736 * <ion-list radio-group [(ngModel)]="relationship">
56737 * <ion-item>
56738 * <ion-label>Friends</ion-label>
56739 * <ion-radio value="friends" checked></ion-radio>
56740 * </ion-item>
56741 * <ion-item>
56742 * <ion-label>Family</ion-label>
56743 * <ion-radio value="family"></ion-radio>
56744 * </ion-item>
56745 * <ion-item>
56746 * <ion-label>Enemies</ion-label>
56747 * <ion-radio value="enemies" [disabled]="isDisabled"></ion-radio>
56748 * </ion-item>
56749 * </ion-list>
56750 * ```
56751 * \@demo /docs/demos/src/radio/
56752 * @see {\@link /docs/components#radio Radio Component Docs}
56753 * @see {\@link ../RadioGroup RadioGroup API Docs}
56754 */
56755var RadioButton = (function (_super) {
56756 __extends$69(RadioButton, _super);
56757 /**
56758 * @param {?} _form
56759 * @param {?} config
56760 * @param {?} elementRef
56761 * @param {?} renderer
56762 * @param {?} _item
56763 * @param {?} _group
56764 */
56765 function RadioButton(_form, config, elementRef, renderer, _item, _group) {
56766 var _this = _super.call(this, config, elementRef, renderer, 'radio') || this;
56767 _this._form = _form;
56768 _this._item = _item;
56769 _this._group = _group;
56770 /**
56771 * \@internal
56772 */
56773 _this._checked = false;
56774 /**
56775 * \@internal
56776 */
56777 _this._disabled = false;
56778 /**
56779 * \@internal
56780 */
56781 _this._value = null;
56782 /**
56783 * \@output {any} Emitted when the radio button is selected.
56784 */
56785 _this.ionSelect = new EventEmitter();
56786 _form.register(_this);
56787 if (_group) {
56788 // register with the radiogroup
56789 _this.id = 'rb-' + _group.add(_this);
56790 }
56791 if (_item) {
56792 // register the input inside of the item
56793 // reset to the item's id instead of the radiogroup id
56794 _this.id = 'rb-' + _item.registerInput('radio');
56795 _this._labelId = 'lbl-' + _item.id;
56796 _this._item.setElementClass('item-radio', true);
56797 }
56798 return _this;
56799 }
56800 Object.defineProperty(RadioButton.prototype, "color", {
56801 /**
56802 * \@input {string} The color to use from your Sass `$colors` map.
56803 * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
56804 * For more information, see [Theming your App](/docs/theming/theming-your-app).
56805 * @param {?} val
56806 * @return {?}
56807 */
56808 set: function (val) {
56809 this._setColor(val);
56810 if (this._item) {
56811 this._item._updateColor(val, 'item-radio');
56812 }
56813 },
56814 enumerable: true,
56815 configurable: true
56816 });
56817 Object.defineProperty(RadioButton.prototype, "value", {
56818 /**
56819 * \@input {any} The value of the radio button. Defaults to the generated id.
56820 * @return {?}
56821 */
56822 get: function () {
56823 // if the value is not defined then use it's unique id
56824 return isBlank$1(this._value) ? this.id : this._value;
56825 },
56826 /**
56827 * @param {?} val
56828 * @return {?}
56829 */
56830 set: function (val) {
56831 this._value = val;
56832 },
56833 enumerable: true,
56834 configurable: true
56835 });
56836 Object.defineProperty(RadioButton.prototype, "checked", {
56837 /**
56838 * \@input {boolean} If true, the element is selected, and other buttons in the group are unselected.
56839 * @return {?}
56840 */
56841 get: function () {
56842 return this._checked;
56843 },
56844 /**
56845 * @param {?} val
56846 * @return {?}
56847 */
56848 set: function (val) {
56849 this._checked = isTrueProperty(val);
56850 if (this._item) {
56851 this._item.setElementClass('item-radio-checked', this._checked);
56852 }
56853 },
56854 enumerable: true,
56855 configurable: true
56856 });
56857 Object.defineProperty(RadioButton.prototype, "disabled", {
56858 /**
56859 * \@input {boolean} If true, the user cannot interact with this element.
56860 * @return {?}
56861 */
56862 get: function () {
56863 return this._disabled || (this._group != null && this._group.disabled);
56864 },
56865 /**
56866 * @param {?} val
56867 * @return {?}
56868 */
56869 set: function (val) {
56870 this._disabled = isTrueProperty(val);
56871 this._item && this._item.setElementClass('item-radio-disabled', this._disabled);
56872 },
56873 enumerable: true,
56874 configurable: true
56875 });
56876 /**
56877 * @hidden
56878 * @return {?}
56879 */
56880 RadioButton.prototype.initFocus = function () {
56881 this._elementRef.nativeElement.querySelector('button').focus();
56882 };
56883 /**
56884 * \@internal
56885 * @param {?} ev
56886 * @return {?}
56887 */
56888 RadioButton.prototype._click = function (ev) {
56889 (void 0) /* console.debug */;
56890 ev.preventDefault();
56891 ev.stopPropagation();
56892 this.checked = true;
56893 this.ionSelect.emit(this.value);
56894 };
56895 /**
56896 * \@internal
56897 * @return {?}
56898 */
56899 RadioButton.prototype.ngOnInit = function () {
56900 if (this._group && isPresent(this._group.value)) {
56901 this.checked = isCheckedProperty(this._group.value, this.value);
56902 }
56903 if (this._group && this._group.disabled) {
56904 this.disabled = this._group.disabled;
56905 }
56906 };
56907 /**
56908 * \@internal
56909 * @return {?}
56910 */
56911 RadioButton.prototype.ngOnDestroy = function () {
56912 this._form.deregister(this);
56913 this._group && this._group.remove(this);
56914 };
56915 return RadioButton;
56916}(Ion));
56917RadioButton.decorators = [
56918 { type: Component, args: [{
56919 selector: 'ion-radio',
56920 template: '<div class="radio-icon" [class.radio-checked]="_checked"> ' +
56921 '<div class="radio-inner"></div> ' +
56922 '</div> ' +
56923 '<button role="radio" ' +
56924 'type="button" ' +
56925 'ion-button="item-cover" ' +
56926 '[id]="id" ' +
56927 '[attr.aria-checked]="_checked" ' +
56928 '[attr.aria-labelledby]="_labelId" ' +
56929 '[attr.aria-disabled]="_disabled" ' +
56930 'class="item-cover"> ' +
56931 '</button>',
56932 host: {
56933 '[class.radio-disabled]': '_disabled'
56934 },
56935 encapsulation: ViewEncapsulation.None,
56936 },] },
56937];
56938/**
56939 * @nocollapse
56940 */
56941RadioButton.ctorParameters = function () { return [
56942 { type: Form, },
56943 { type: Config, },
56944 { type: ElementRef, },
56945 { type: Renderer, },
56946 { type: Item, decorators: [{ type: Optional },] },
56947 { type: RadioGroup, decorators: [{ type: Optional },] },
56948]; };
56949RadioButton.propDecorators = {
56950 'color': [{ type: Input },],
56951 'ionSelect': [{ type: Output },],
56952 'value': [{ type: Input },],
56953 'checked': [{ type: Input },],
56954 'disabled': [{ type: Input },],
56955 '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
56956};
56957
56958var __extends$70 = (undefined && undefined.__extends) || (function () {
56959 var extendStatics = Object.setPrototypeOf ||
56960 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
56961 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
56962 return function (d, b) {
56963 extendStatics(d, b);
56964 function __() { this.constructor = d; }
56965 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
56966 };
56967})();
56968/**
56969 * \@name Range
56970 * \@description
56971 * The Range slider lets users select from a range of values by moving
56972 * the slider knob. It can accept dual knobs, but by default one knob
56973 * controls the value of the range.
56974 *
56975 * ### Range Labels
56976 * Labels can be placed on either side of the range by adding the
56977 * `range-left` or `range-right` property to the element. The element
56978 * doesn't have to be an `ion-label`, it can be added to any element
56979 * to place it to the left or right of the range. See [usage](#usage)
56980 * below for examples.
56981 *
56982 *
56983 * ### Minimum and Maximum Values
56984 * Minimum and maximum values can be passed to the range through the `min`
56985 * and `max` properties, respectively. By default, the range sets the `min`
56986 * to `0` and the `max` to `100`.
56987 *
56988 *
56989 * ### Steps and Snaps
56990 * The `step` property specifies the value granularity of the range's value.
56991 * It can be useful to set the `step` when the value isn't in increments of `1`.
56992 * Setting the `step` property will show tick marks on the range for each step.
56993 * The `snaps` property can be set to automatically move the knob to the nearest
56994 * tick mark based on the step property value.
56995 *
56996 *
56997 * ### Dual Knobs
56998 * Setting the `dualKnobs` property to `true` on the range component will
56999 * enable two knobs on the range. If the range has two knobs, the value will
57000 * be an object containing two properties: `lower` and `upper`.
57001 *
57002 *
57003 * \@usage
57004 * ```html
57005 * <ion-list>
57006 * <ion-item>
57007 * <ion-range [(ngModel)]="singleValue" color="danger" pin="true"></ion-range>
57008 * </ion-item>
57009 *
57010 * <ion-item>
57011 * <ion-range min="-200" max="200" [(ngModel)]="saturation" color="secondary">
57012 * <ion-label range-left>-200</ion-label>
57013 * <ion-label range-right>200</ion-label>
57014 * </ion-range>
57015 * </ion-item>
57016 *
57017 * <ion-item>
57018 * <ion-range min="20" max="80" step="2" [(ngModel)]="brightness">
57019 * <ion-icon small range-left name="sunny"></ion-icon>
57020 * <ion-icon range-right name="sunny"></ion-icon>
57021 * </ion-range>
57022 * </ion-item>
57023 *
57024 * <ion-item>
57025 * <ion-label>step=100, snaps, {{singleValue4}}</ion-label>
57026 * <ion-range min="1000" max="2000" step="100" snaps="true" color="secondary" [(ngModel)]="singleValue4"></ion-range>
57027 * </ion-item>
57028 *
57029 * <ion-item>
57030 * <ion-label>dual, step=3, snaps, {{dualValue2 | json}}</ion-label>
57031 * <ion-range dualKnobs="true" [(ngModel)]="dualValue2" min="21" max="72" step="3" snaps="true"></ion-range>
57032 * </ion-item>
57033 * </ion-list>
57034 * ```
57035 *
57036 *
57037 * \@demo /docs/demos/src/range/
57038 */
57039var Range = (function (_super) {
57040 __extends$70(Range, _super);
57041 /**
57042 * @param {?} form
57043 * @param {?} _haptic
57044 * @param {?} item
57045 * @param {?} config
57046 * @param {?} _plt
57047 * @param {?} elementRef
57048 * @param {?} renderer
57049 * @param {?} _dom
57050 * @param {?} _cd
57051 */
57052 function Range(form, _haptic, item, config, _plt, elementRef, renderer, _dom, _cd) {
57053 var _this = _super.call(this, config, elementRef, renderer, 'range', 0, form, item, null) || this;
57054 _this._haptic = _haptic;
57055 _this._plt = _plt;
57056 _this._dom = _dom;
57057 _this._cd = _cd;
57058 _this._min = 0;
57059 _this._max = 100;
57060 _this._step = 1;
57061 _this._valA = 0;
57062 _this._valB = 0;
57063 _this._ratioA = 0;
57064 _this._ratioB = 0;
57065 _this._events = new UIEventManager(_plt);
57066 return _this;
57067 }
57068 Object.defineProperty(Range.prototype, "min", {
57069 /**
57070 * \@input {number} Minimum integer value of the range. Defaults to `0`.
57071 * @return {?}
57072 */
57073 get: function () {
57074 return this._min;
57075 },
57076 /**
57077 * @param {?} val
57078 * @return {?}
57079 */
57080 set: function (val) {
57081 val = Math.round(val);
57082 if (!isNaN(val)) {
57083 this._min = val;
57084 this._inputUpdated();
57085 }
57086 },
57087 enumerable: true,
57088 configurable: true
57089 });
57090 Object.defineProperty(Range.prototype, "max", {
57091 /**
57092 * \@input {number} Maximum integer value of the range. Defaults to `100`.
57093 * @return {?}
57094 */
57095 get: function () {
57096 return this._max;
57097 },
57098 /**
57099 * @param {?} val
57100 * @return {?}
57101 */
57102 set: function (val) {
57103 val = Math.round(val);
57104 if (!isNaN(val)) {
57105 this._max = val;
57106 this._inputUpdated();
57107 }
57108 },
57109 enumerable: true,
57110 configurable: true
57111 });
57112 Object.defineProperty(Range.prototype, "step", {
57113 /**
57114 * \@input {number} Specifies the value granularity. Defaults to `1`.
57115 * @return {?}
57116 */
57117 get: function () {
57118 return this._step;
57119 },
57120 /**
57121 * @param {?} val
57122 * @return {?}
57123 */
57124 set: function (val) {
57125 val = Math.round(val);
57126 if (!isNaN(val) && val > 0) {
57127 this._step = val;
57128 }
57129 },
57130 enumerable: true,
57131 configurable: true
57132 });
57133 Object.defineProperty(Range.prototype, "snaps", {
57134 /**
57135 * \@input {boolean} If true, the knob snaps to tick marks evenly spaced based
57136 * on the step property value. Defaults to `false`.
57137 * @return {?}
57138 */
57139 get: function () {
57140 return this._snaps;
57141 },
57142 /**
57143 * @param {?} val
57144 * @return {?}
57145 */
57146 set: function (val) {
57147 this._snaps = isTrueProperty(val);
57148 },
57149 enumerable: true,
57150 configurable: true
57151 });
57152 Object.defineProperty(Range.prototype, "pin", {
57153 /**
57154 * \@input {boolean} If true, a pin with integer value is shown when the knob
57155 * is pressed. Defaults to `false`.
57156 * @return {?}
57157 */
57158 get: function () {
57159 return this._pin;
57160 },
57161 /**
57162 * @param {?} val
57163 * @return {?}
57164 */
57165 set: function (val) {
57166 this._pin = isTrueProperty(val);
57167 },
57168 enumerable: true,
57169 configurable: true
57170 });
57171 Object.defineProperty(Range.prototype, "debounce", {
57172 /**
57173 * \@input {number} How long, in milliseconds, to wait to trigger the
57174 * `ionChange` event after each change in the range value. Default `0`.
57175 * @return {?}
57176 */
57177 get: function () {
57178 return this._debouncer.wait;
57179 },
57180 /**
57181 * @param {?} val
57182 * @return {?}
57183 */
57184 set: function (val) {
57185 this._debouncer.wait = val;
57186 },
57187 enumerable: true,
57188 configurable: true
57189 });
57190 Object.defineProperty(Range.prototype, "dualKnobs", {
57191 /**
57192 * \@input {boolean} Show two knobs. Defaults to `false`.
57193 * @return {?}
57194 */
57195 get: function () {
57196 return this._dual;
57197 },
57198 /**
57199 * @param {?} val
57200 * @return {?}
57201 */
57202 set: function (val) {
57203 this._dual = isTrueProperty(val);
57204 },
57205 enumerable: true,
57206 configurable: true
57207 });
57208 Object.defineProperty(Range.prototype, "ratio", {
57209 /**
57210 * Returns the ratio of the knob's is current location, which is a number
57211 * between `0` and `1`. If two knobs are used, this property represents
57212 * the lower value.
57213 * @return {?}
57214 */
57215 get: function () {
57216 if (this._dual) {
57217 return Math.min(this._ratioA, this._ratioB);
57218 }
57219 return this._ratioA;
57220 },
57221 enumerable: true,
57222 configurable: true
57223 });
57224 Object.defineProperty(Range.prototype, "ratioUpper", {
57225 /**
57226 * Returns the ratio of the upper value's is current location, which is
57227 * a number between `0` and `1`. If there is only one knob, then this
57228 * will return `null`.
57229 * @return {?}
57230 */
57231 get: function () {
57232 if (this._dual) {
57233 return Math.max(this._ratioA, this._ratioB);
57234 }
57235 return null;
57236 },
57237 enumerable: true,
57238 configurable: true
57239 });
57240 /**
57241 * @hidden
57242 * @return {?}
57243 */
57244 Range.prototype.ngAfterContentInit = function () {
57245 this._initialize();
57246 // add touchstart/mousedown listeners
57247 this._events.pointerEvents({
57248 element: this._slider.nativeElement,
57249 pointerDown: this._pointerDown.bind(this),
57250 pointerMove: this._pointerMove.bind(this),
57251 pointerUp: this._pointerUp.bind(this),
57252 zone: true
57253 });
57254 // build all the ticks if there are any to show
57255 this._createTicks();
57256 };
57257 /**
57258 * \@internal
57259 * @param {?} ev
57260 * @return {?}
57261 */
57262 Range.prototype._pointerDown = function (ev) {
57263 // TODO: we could stop listening for events instead of checking this._disabled.
57264 // since there are a lot of events involved, this solution is
57265 // enough for the moment
57266 if (this._disabled) {
57267 return false;
57268 }
57269 // trigger ionFocus event
57270 this._fireFocus();
57271 // prevent default so scrolling does not happen
57272 ev.preventDefault();
57273 ev.stopPropagation();
57274 // get the start coordinates
57275 var /** @type {?} */ current = pointerCoord(ev);
57276 // get the full dimensions of the slider element
57277 var /** @type {?} */ rect = this._rect = this._plt.getElementBoundingClientRect(this._slider.nativeElement);
57278 // figure out which knob they started closer to
57279 var /** @type {?} */ ratio = clamp(0, (current.x - rect.left) / (rect.width), 1);
57280 this._activeB = this._dual && (Math.abs(ratio - this._ratioA) > Math.abs(ratio - this._ratioB));
57281 // update the active knob's position
57282 this._update(current, rect, true);
57283 // trigger a haptic start
57284 this._haptic.gestureSelectionStart();
57285 // return true so the pointer events
57286 // know everything's still valid
57287 return true;
57288 };
57289 /**
57290 * \@internal
57291 * @param {?} ev
57292 * @return {?}
57293 */
57294 Range.prototype._pointerMove = function (ev) {
57295 if (this._disabled) {
57296 return;
57297 }
57298 // prevent default so scrolling does not happen
57299 ev.preventDefault();
57300 ev.stopPropagation();
57301 // update the active knob's position
57302 var /** @type {?} */ hasChanged = this._update(pointerCoord(ev), this._rect, true);
57303 if (hasChanged && this._snaps) {
57304 // trigger a haptic selection changed event
57305 // if this is a snap range
57306 this._haptic.gestureSelectionChanged();
57307 }
57308 };
57309 /**
57310 * \@internal
57311 * @param {?} ev
57312 * @return {?}
57313 */
57314 Range.prototype._pointerUp = function (ev) {
57315 if (this._disabled) {
57316 return;
57317 }
57318 // prevent default so scrolling does not happen
57319 ev.preventDefault();
57320 ev.stopPropagation();
57321 // update the active knob's position
57322 this._update(pointerCoord(ev), this._rect, false);
57323 // trigger a haptic end
57324 this._haptic.gestureSelectionEnd();
57325 // trigger ionBlur event
57326 this._fireBlur();
57327 };
57328 /**
57329 * \@internal
57330 * @param {?} current
57331 * @param {?} rect
57332 * @param {?} isPressed
57333 * @return {?}
57334 */
57335 Range.prototype._update = function (current, rect, isPressed) {
57336 // figure out where the pointer is currently at
57337 // update the knob being interacted with
57338 var /** @type {?} */ ratio = clamp(0, (current.x - rect.left) / (rect.width), 1);
57339 var /** @type {?} */ val = this._ratioToValue(ratio);
57340 if (this._snaps) {
57341 // snaps the ratio to the current value
57342 ratio = this._valueToRatio(val);
57343 }
57344 // update which knob is pressed
57345 this._pressed = isPressed;
57346 var /** @type {?} */ valChanged = false;
57347 if (this._activeB) {
57348 // when the pointer down started it was determined
57349 // that knob B was the one they were interacting with
57350 this._pressedB = isPressed;
57351 this._pressedA = false;
57352 this._ratioB = ratio;
57353 valChanged = val === this._valB;
57354 this._valB = val;
57355 }
57356 else {
57357 // interacting with knob A
57358 this._pressedA = isPressed;
57359 this._pressedB = false;
57360 this._ratioA = ratio;
57361 valChanged = val === this._valA;
57362 this._valA = val;
57363 }
57364 this._updateBar();
57365 if (valChanged) {
57366 return false;
57367 }
57368 // value has been updated
57369 var /** @type {?} */ value;
57370 if (this._dual) {
57371 // dual knobs have an lower and upper value
57372 value = {
57373 lower: Math.min(this._valA, this._valB),
57374 upper: Math.max(this._valA, this._valB)
57375 };
57376 (void 0) /* console.debug */;
57377 }
57378 else {
57379 // single knob only has one value
57380 value = this._valA;
57381 (void 0) /* console.debug */;
57382 }
57383 // Update input value
57384 this.value = value;
57385 return true;
57386 };
57387 /**
57388 * \@internal
57389 * @return {?}
57390 */
57391 Range.prototype._updateBar = function () {
57392 var /** @type {?} */ ratioA = this._ratioA;
57393 var /** @type {?} */ ratioB = this._ratioB;
57394 if (this._dual) {
57395 this._barL = (Math.min(ratioA, ratioB) * 100) + "%";
57396 this._barR = 100 - (Math.max(ratioA, ratioB) * 100) + "%";
57397 }
57398 else {
57399 this._barL = '';
57400 this._barR = 100 - (ratioA * 100) + "%";
57401 }
57402 this._updateTicks();
57403 };
57404 /**
57405 * \@internal
57406 * @return {?}
57407 */
57408 Range.prototype._createTicks = function () {
57409 var _this = this;
57410 if (this._snaps) {
57411 this._dom.write(function () {
57412 // TODO: Fix to not use RAF
57413 _this._ticks = [];
57414 for (var /** @type {?} */ value = _this._min; value <= _this._max; value += _this._step) {
57415 var /** @type {?} */ ratio = _this._valueToRatio(value);
57416 _this._ticks.push({
57417 ratio: ratio,
57418 left: ratio * 100 + "%",
57419 });
57420 }
57421 _this._updateTicks();
57422 });
57423 }
57424 };
57425 /**
57426 * \@internal
57427 * @return {?}
57428 */
57429 Range.prototype._updateTicks = function () {
57430 var /** @type {?} */ ticks = this._ticks;
57431 var /** @type {?} */ ratio = this.ratio;
57432 if (this._snaps && ticks) {
57433 if (this._dual) {
57434 var /** @type {?} */ upperRatio = this.ratioUpper;
57435 ticks.forEach(function (t) {
57436 t.active = (t.ratio >= ratio && t.ratio <= upperRatio);
57437 });
57438 }
57439 else {
57440 ticks.forEach(function (t) {
57441 t.active = (t.ratio <= ratio);
57442 });
57443 }
57444 }
57445 };
57446 /**
57447 * @hidden
57448 * @param {?} isIncrease
57449 * @param {?} isKnobB
57450 * @return {?}
57451 */
57452 Range.prototype._keyChg = function (isIncrease, isKnobB) {
57453 var /** @type {?} */ step = this._step;
57454 if (isKnobB) {
57455 if (isIncrease) {
57456 this._valB += step;
57457 }
57458 else {
57459 this._valB -= step;
57460 }
57461 this._valB = clamp(this._min, this._valB, this._max);
57462 this._ratioB = this._valueToRatio(this._valB);
57463 }
57464 else {
57465 if (isIncrease) {
57466 this._valA += step;
57467 }
57468 else {
57469 this._valA -= step;
57470 }
57471 this._valA = clamp(this._min, this._valA, this._max);
57472 this._ratioA = this._valueToRatio(this._valA);
57473 }
57474 this._updateBar();
57475 };
57476 /**
57477 * \@internal
57478 * @param {?} ratio
57479 * @return {?}
57480 */
57481 Range.prototype._ratioToValue = function (ratio) {
57482 ratio = Math.round(((this._max - this._min) * ratio));
57483 ratio = Math.round(ratio / this._step) * this._step + this._min;
57484 return clamp(this._min, ratio, this._max);
57485 };
57486 /**
57487 * \@internal
57488 * @param {?} value
57489 * @return {?}
57490 */
57491 Range.prototype._valueToRatio = function (value) {
57492 value = Math.round((value - this._min) / this._step) * this._step;
57493 value = value / (this._max - this._min);
57494 return clamp(0, value, 1);
57495 };
57496 /**
57497 * @param {?} val
57498 * @return {?}
57499 */
57500 Range.prototype._inputNormalize = function (val) {
57501 if (this._dual) {
57502 return val;
57503 }
57504 else {
57505 val = parseFloat(val);
57506 return isNaN(val) ? undefined : val;
57507 }
57508 };
57509 /**
57510 * @hidden
57511 * @return {?}
57512 */
57513 Range.prototype._inputUpdated = function () {
57514 var /** @type {?} */ val = this.value;
57515 if (this._dual) {
57516 this._valA = val.lower;
57517 this._valB = val.upper;
57518 this._ratioA = this._valueToRatio(val.lower);
57519 this._ratioB = this._valueToRatio(val.upper);
57520 }
57521 else {
57522 this._valA = val;
57523 this._ratioA = this._valueToRatio(val);
57524 }
57525 this._updateBar();
57526 this._cd.detectChanges();
57527 };
57528 /**
57529 * @hidden
57530 * @return {?}
57531 */
57532 Range.prototype.ngOnDestroy = function () {
57533 _super.prototype.ngOnDestroy.call(this);
57534 this._events.destroy();
57535 };
57536 return Range;
57537}(BaseInput));
57538Range.decorators = [
57539 { type: Component, args: [{
57540 selector: 'ion-range',
57541 template: '<ng-content select="[range-left]"></ng-content>' +
57542 '<div class="range-slider" #slider>' +
57543 '<div class="range-tick" *ngFor="let t of _ticks" [style.left]="t.left" [class.range-tick-active]="t.active" role="presentation"></div>' +
57544 '<div class="range-bar" role="presentation"></div>' +
57545 '<div class="range-bar range-bar-active" [style.left]="_barL" [style.right]="_barR" #bar role="presentation"></div>' +
57546 '<div class="range-knob-handle" (ionIncrease)="_keyChg(true, false)" (ionDecrease)="_keyChg(false, false)" [ratio]="_ratioA" [val]="_valA" [pin]="_pin" [pressed]="_pressedA" [min]="_min" [max]="_max" [disabled]="_disabled" [labelId]="_labelId"></div>' +
57547 '<div class="range-knob-handle" (ionIncrease)="_keyChg(true, true)" (ionDecrease)="_keyChg(false, true)" [ratio]="_ratioB" [val]="_valB" [pin]="_pin" [pressed]="_pressedB" [min]="_min" [max]="_max" [disabled]="_disabled" [labelId]="_labelId" *ngIf="_dual"></div>' +
57548 '</div>' +
57549 '<ng-content select="[range-right]"></ng-content>',
57550 host: {
57551 '[class.range-disabled]': '_disabled',
57552 '[class.range-pressed]': '_pressed',
57553 '[class.range-has-pin]': '_pin'
57554 },
57555 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Range, multi: true }],
57556 encapsulation: ViewEncapsulation.None,
57557 },] },
57558];
57559/**
57560 * @nocollapse
57561 */
57562Range.ctorParameters = function () { return [
57563 { type: Form, },
57564 { type: Haptic, },
57565 { type: Item, decorators: [{ type: Optional },] },
57566 { type: Config, },
57567 { type: Platform, },
57568 { type: ElementRef, },
57569 { type: Renderer, },
57570 { type: DomController, },
57571 { type: ChangeDetectorRef, },
57572]; };
57573Range.propDecorators = {
57574 '_slider': [{ type: ViewChild, args: ['slider',] },],
57575 'min': [{ type: Input },],
57576 'max': [{ type: Input },],
57577 'step': [{ type: Input },],
57578 'snaps': [{ type: Input },],
57579 'pin': [{ type: Input },],
57580 'debounce': [{ type: Input },],
57581 'dualKnobs': [{ type: Input },],
57582};
57583
57584/**
57585 * @hidden
57586 */
57587var RangeKnob = (function () {
57588 function RangeKnob() {
57589 this.ionIncrease = new EventEmitter();
57590 this.ionDecrease = new EventEmitter();
57591 }
57592 Object.defineProperty(RangeKnob.prototype, "ratio", {
57593 /**
57594 * @param {?} r
57595 * @return {?}
57596 */
57597 set: function (r) {
57598 this._x = r * 100 + "%";
57599 },
57600 enumerable: true,
57601 configurable: true
57602 });
57603 /**
57604 * @param {?} ev
57605 * @return {?}
57606 */
57607 RangeKnob.prototype._keyup = function (ev) {
57608 var /** @type {?} */ keyCode = ev.keyCode;
57609 if (keyCode === KEY_LEFT || keyCode === KEY_DOWN) {
57610 (void 0) /* console.debug */;
57611 this.ionDecrease.emit();
57612 ev.preventDefault();
57613 ev.stopPropagation();
57614 }
57615 else if (keyCode === KEY_RIGHT || keyCode === KEY_UP) {
57616 (void 0) /* console.debug */;
57617 this.ionIncrease.emit();
57618 ev.preventDefault();
57619 ev.stopPropagation();
57620 }
57621 };
57622 return RangeKnob;
57623}());
57624RangeKnob.decorators = [
57625 { type: Component, args: [{
57626 selector: '.range-knob-handle',
57627 template: '<div class="range-pin" *ngIf="pin" role="presentation">{{val}}</div>' +
57628 '<div class="range-knob" role="presentation"></div>',
57629 host: {
57630 '[class.range-knob-pressed]': 'pressed',
57631 '[class.range-knob-min]': 'val===min||val===undefined',
57632 '[class.range-knob-max]': 'val===max',
57633 '[style.left]': '_x',
57634 '[attr.aria-valuenow]': 'val',
57635 '[attr.aria-valuemin]': 'min',
57636 '[attr.aria-valuemax]': 'max',
57637 '[attr.aria-disabled]': 'disabled',
57638 '[attr.aria-labelledby]': 'labelId',
57639 '[tabindex]': 'disabled?-1:0',
57640 'role': 'slider'
57641 }
57642 },] },
57643];
57644/**
57645 * @nocollapse
57646 */
57647RangeKnob.ctorParameters = function () { return []; };
57648RangeKnob.propDecorators = {
57649 'ratio': [{ type: Input },],
57650 'pressed': [{ type: Input },],
57651 'pin': [{ type: Input },],
57652 'min': [{ type: Input },],
57653 'max': [{ type: Input },],
57654 'val': [{ type: Input },],
57655 'disabled': [{ type: Input },],
57656 'labelId': [{ type: Input },],
57657 'ionIncrease': [{ type: Output },],
57658 'ionDecrease': [{ type: Output },],
57659 '_keyup': [{ type: HostListener, args: ['keydown', ['$event'],] },],
57660};
57661
57662/**
57663 * \@name Refresher
57664 * \@description
57665 * The Refresher provides pull-to-refresh functionality on a content component.
57666 * Place the `ion-refresher` as the first child of your `ion-content` element.
57667 *
57668 * Pages can then listen to the refresher's various output events. The
57669 * `refresh` output event is fired when the user has pulled down far
57670 * enough to kick off the refreshing process. Once the async operation
57671 * has completed and the refreshing should end, call `complete()`.
57672 *
57673 * Note: Do not wrap the `ion-refresher` in a `*ngIf`. It will not render
57674 * properly this way. Please use the `enabled` property instead to
57675 * display or hide the refresher.
57676 *
57677 * \@usage
57678 * ```html
57679 * <ion-content>
57680 *
57681 * <ion-refresher (ionRefresh)="doRefresh($event)">
57682 * <ion-refresher-content></ion-refresher-content>
57683 * </ion-refresher>
57684 *
57685 * </ion-content>
57686 * ```
57687 *
57688 * ```ts
57689 * \@Component({...})
57690 * export class NewsFeedPage {
57691 *
57692 * doRefresh(refresher) {
57693 * console.log('Begin async operation', refresher);
57694 *
57695 * setTimeout(() => {
57696 * console.log('Async operation has ended');
57697 * refresher.complete();
57698 * }, 2000);
57699 * }
57700 *
57701 * }
57702 * ```
57703 *
57704 *
57705 * ## Refresher Content
57706 *
57707 * By default, Ionic provides the pulling icon and refreshing spinner that
57708 * looks best for the platform the user is on. However, you can change the
57709 * default icon and spinner, along with adding text for each state by
57710 * adding properties to the child `ion-refresher-content` component.
57711 *
57712 * ```html
57713 * <ion-content>
57714 *
57715 * <ion-refresher (ionRefresh)="doRefresh($event)">
57716 * <ion-refresher-content
57717 * pullingIcon="arrow-dropdown"
57718 * pullingText="Pull to refresh"
57719 * refreshingSpinner="circles"
57720 * refreshingText="Refreshing...">
57721 * </ion-refresher-content>
57722 * </ion-refresher>
57723 *
57724 * </ion-content>
57725 * ```
57726 *
57727 *
57728 * ## Further Customizing Refresher Content
57729 *
57730 * The `ion-refresher` component holds the refresh logic.
57731 * It requires a child component in order to display the content.
57732 * Ionic uses `ion-refresher-content` by default. This component
57733 * displays the refresher and changes the look depending
57734 * on the refresher's state. Separating these components
57735 * allows developers to create their own refresher content
57736 * components. You could replace our default content with
57737 * custom SVG or CSS animations.
57738 *
57739 * \@demo /docs/demos/src/refresher/
57740 *
57741 */
57742var Refresher = (function () {
57743 /**
57744 * @param {?} _plt
57745 * @param {?} _content
57746 * @param {?} _zone
57747 * @param {?} gestureCtrl
57748 */
57749 function Refresher(_plt, _content, _zone, gestureCtrl) {
57750 this._plt = _plt;
57751 this._content = _content;
57752 this._zone = _zone;
57753 this._appliedStyles = false;
57754 this._lastCheck = 0;
57755 this._isEnabled = true;
57756 this._top = '';
57757 /**
57758 * The current state which the refresher is in. The refresher's states include:
57759 *
57760 * - `inactive` - The refresher is not being pulled down or refreshing and is currently hidden.
57761 * - `pulling` - The user is actively pulling down the refresher, but has not reached the point yet that if the user lets go, it'll refresh.
57762 * - `cancelling` - The user pulled down the refresher and let go, but did not pull down far enough to kick off the `refreshing` state. After letting go, the refresher is in the `cancelling` state while it is closing, and will go back to the `inactive` state once closed.
57763 * - `ready` - The user has pulled down the refresher far enough that if they let go, it'll begin the `refreshing` state.
57764 * - `refreshing` - The refresher is actively waiting on the async operation to end. Once the refresh handler calls `complete()` it will begin the `completing` state.
57765 * - `completing` - The `refreshing` state has finished and the refresher is in the process of closing itself. Once closed, the refresher will go back to the `inactive` state.
57766 */
57767 this.state = STATE_INACTIVE;
57768 /**
57769 * The Y coordinate of where the user started to the pull down the content.
57770 */
57771 this.startY = null;
57772 /**
57773 * The current touch or mouse event's Y coordinate.
57774 */
57775 this.currentY = null;
57776 /**
57777 * The distance between the start of the pull and the current touch or
57778 * mouse event's Y coordinate.
57779 */
57780 this.deltaY = null;
57781 /**
57782 * A number representing how far down the user has pulled.
57783 * The number `0` represents the user hasn't pulled down at all. The
57784 * number `1`, and anything greater than `1`, represents that the user
57785 * has pulled far enough down that when they let go then the refresh will
57786 * happen. If they let go and the number is less than `1`, then the
57787 * refresh will not happen, and the content will return to it's original
57788 * position.
57789 */
57790 this.progress = 0;
57791 /**
57792 * \@input {number} The min distance the user must pull down until the
57793 * refresher can go into the `refreshing` state. Default is `60`.
57794 */
57795 this.pullMin = 60;
57796 /**
57797 * \@input {number} The maximum distance of the pull until the refresher
57798 * will automatically go into the `refreshing` state. By default, the pull
57799 * maximum will be the result of `pullMin + 60`.
57800 */
57801 this.pullMax = this.pullMin + 60;
57802 /**
57803 * \@input {number} How many milliseconds it takes to close the refresher. Default is `280`.
57804 */
57805 this.closeDuration = 280;
57806 /**
57807 * \@input {number} How many milliseconds it takes the refresher to to snap back to the `refreshing` state. Default is `280`.
57808 */
57809 this.snapbackDuration = 280;
57810 /**
57811 * \@output {event} Emitted when the user lets go and has pulled down
57812 * far enough, which would be farther than the `pullMin`, then your refresh hander if
57813 * fired and the state is updated to `refreshing`. From within your refresh handler,
57814 * you must call the `complete()` method when your async operation has completed.
57815 */
57816 this.ionRefresh = new EventEmitter();
57817 /**
57818 * \@output {event} Emitted while the user is pulling down the content and exposing the refresher.
57819 */
57820 this.ionPull = new EventEmitter();
57821 /**
57822 * \@output {event} Emitted when the user begins to start pulling down.
57823 */
57824 this.ionStart = new EventEmitter();
57825 this._events = new UIEventManager(_plt);
57826 _content._hasRefresher = true;
57827 this._gesture = gestureCtrl.createGesture({
57828 name: GESTURE_REFRESHER,
57829 priority: GESTURE_PRIORITY_REFRESHER
57830 });
57831 }
57832 Object.defineProperty(Refresher.prototype, "enabled", {
57833 /**
57834 * \@input {boolean} If the refresher is enabled or not. This should be used in place of an `ngIf`. Default is `true`.
57835 * @return {?}
57836 */
57837 get: function () {
57838 return this._isEnabled;
57839 },
57840 /**
57841 * @param {?} val
57842 * @return {?}
57843 */
57844 set: function (val) {
57845 this._isEnabled = isTrueProperty(val);
57846 this._setListeners(this._isEnabled);
57847 },
57848 enumerable: true,
57849 configurable: true
57850 });
57851 /**
57852 * @param {?} ev
57853 * @return {?}
57854 */
57855 Refresher.prototype._onStart = function (ev) {
57856 // if multitouch then get out immediately
57857 if (ev.touches && ev.touches.length > 1) {
57858 return false;
57859 }
57860 if (this.state !== STATE_INACTIVE) {
57861 return false;
57862 }
57863 var /** @type {?} */ scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
57864 // if the scrollTop is greater than zero then it's
57865 // not possible to pull the content down yet
57866 if (scrollHostScrollTop > 0) {
57867 return false;
57868 }
57869 if (!this._gesture.canStart()) {
57870 return false;
57871 }
57872 var /** @type {?} */ coord = pointerCoord(ev);
57873 (void 0) /* console.debug */;
57874 if (this._content.contentTop > 0) {
57875 var /** @type {?} */ newTop = this._content.contentTop + 'px';
57876 if (this._top !== newTop) {
57877 this._top = newTop;
57878 }
57879 }
57880 this.startY = this.currentY = coord.y;
57881 this.progress = 0;
57882 this.state = STATE_INACTIVE;
57883 return true;
57884 };
57885 /**
57886 * @param {?} ev
57887 * @return {?}
57888 */
57889 Refresher.prototype._onMove = function (ev) {
57890 // this method can get called like a bazillion times per second,
57891 // so it's built to be as efficient as possible, and does its
57892 // best to do any DOM read/writes only when absolutely necessary
57893 var _this = this;
57894 // if multitouch then get out immediately
57895 if (ev.touches && ev.touches.length > 1) {
57896 return 1;
57897 }
57898 if (!this._gesture.canStart()) {
57899 return 0;
57900 }
57901 // do nothing if it's actively refreshing
57902 // or it's in the process of closing
57903 // or this was never a startY
57904 if (this.startY === null || this.state === STATE_REFRESHING || this.state === STATE_CANCELLING || this.state === STATE_COMPLETING) {
57905 return 2;
57906 }
57907 // if we just updated stuff less than 16ms ago
57908 // then don't check again, just chillout plz
57909 var /** @type {?} */ now = Date.now();
57910 if (this._lastCheck + 16 > now) {
57911 return 3;
57912 }
57913 // remember the last time we checked all this
57914 this._lastCheck = now;
57915 // get the current pointer coordinates
57916 var /** @type {?} */ coord = pointerCoord(ev);
57917 this.currentY = coord.y;
57918 // it's now possible they could be pulling down the content
57919 // how far have they pulled so far?
57920 this.deltaY = (coord.y - this.startY);
57921 // don't bother if they're scrolling up
57922 // and have not already started dragging
57923 if (this.deltaY <= 0) {
57924 // the current Y is higher than the starting Y
57925 // so they scrolled up enough to be ignored
57926 this.progress = 0;
57927 if (this.state !== STATE_INACTIVE) {
57928 this._zone.run(function () {
57929 _this.state = STATE_INACTIVE;
57930 });
57931 }
57932 if (this._appliedStyles) {
57933 // reset the styles only if they were applied
57934 this._setCss(0, '', false, '');
57935 return 5;
57936 }
57937 return 6;
57938 }
57939 if (this.state === STATE_INACTIVE) {
57940 // this refresh is not already actively pulling down
57941 // get the content's scrollTop
57942 var /** @type {?} */ scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
57943 // if the scrollTop is greater than zero then it's
57944 // not possible to pull the content down yet
57945 if (scrollHostScrollTop > 0) {
57946 this.progress = 0;
57947 this.startY = null;
57948 return 7;
57949 }
57950 // content scrolled all the way to the top, and dragging down
57951 this.state = STATE_PULLING;
57952 }
57953 // prevent native scroll events
57954 ev.preventDefault();
57955 // the refresher is actively pulling at this point
57956 // move the scroll element within the content element
57957 this._setCss(this.deltaY, '0ms', true, '');
57958 if (!this.deltaY) {
57959 // don't continue if there's no delta yet
57960 this.progress = 0;
57961 return 8;
57962 }
57963 // so far so good, let's run this all back within zone now
57964 this._zone.run(function () {
57965 _this._onMoveInZone();
57966 });
57967 };
57968 /**
57969 * @return {?}
57970 */
57971 Refresher.prototype._onMoveInZone = function () {
57972 // set pull progress
57973 this.progress = (this.deltaY / this.pullMin);
57974 // emit "start" if it hasn't started yet
57975 if (!this._didStart) {
57976 this._didStart = true;
57977 this.ionStart.emit(this);
57978 }
57979 // emit "pulling" on every move
57980 this.ionPull.emit(this);
57981 // do nothing if the delta is less than the pull threshold
57982 if (this.deltaY < this.pullMin) {
57983 // ensure it stays in the pulling state, cuz its not ready yet
57984 this.state = STATE_PULLING;
57985 return 2;
57986 }
57987 if (this.deltaY > this.pullMax) {
57988 // they pulled farther than the max, so kick off the refresh
57989 this._beginRefresh();
57990 return 3;
57991 }
57992 // pulled farther than the pull min!!
57993 // it is now in the `ready` state!!
57994 // if they let go then it'll refresh, kerpow!!
57995 this.state = STATE_READY;
57996 return 4;
57997 };
57998 /**
57999 * @return {?}
58000 */
58001 Refresher.prototype._onEnd = function () {
58002 // only run in a zone when absolutely necessary
58003 var _this = this;
58004 if (this.state === STATE_READY) {
58005 this._zone.run(function () {
58006 // they pulled down far enough, so it's ready to refresh
58007 _this._beginRefresh();
58008 });
58009 }
58010 else if (this.state === STATE_PULLING) {
58011 this._zone.run(function () {
58012 // they were pulling down, but didn't pull down far enough
58013 // set the content back to it's original location
58014 // and close the refresher
58015 // set that the refresh is actively cancelling
58016 _this.cancel();
58017 });
58018 }
58019 // reset on any touchend/mouseup
58020 this.startY = null;
58021 };
58022 /**
58023 * @return {?}
58024 */
58025 Refresher.prototype._beginRefresh = function () {
58026 // assumes we're already back in a zone
58027 // they pulled down far enough, so it's ready to refresh
58028 this.state = STATE_REFRESHING;
58029 // place the content in a hangout position while it thinks
58030 this._setCss(this.pullMin, (this.snapbackDuration + 'ms'), true, '');
58031 // emit "refresh" because it was pulled down far enough
58032 // and they let go to begin refreshing
58033 this.ionRefresh.emit(this);
58034 };
58035 /**
58036 * Call `complete()` when your async operation has completed.
58037 * For example, the `refreshing` state is while the app is performing
58038 * an asynchronous operation, such as receiving more data from an
58039 * AJAX request. Once the data has been received, you then call this
58040 * method to signify that the refreshing has completed and to close
58041 * the refresher. This method also changes the refresher's state from
58042 * `refreshing` to `completing`.
58043 * @return {?}
58044 */
58045 Refresher.prototype.complete = function () {
58046 this._close(STATE_COMPLETING, '120ms');
58047 };
58048 /**
58049 * Changes the refresher's state from `refreshing` to `cancelling`.
58050 * @return {?}
58051 */
58052 Refresher.prototype.cancel = function () {
58053 this._close(STATE_CANCELLING, '');
58054 };
58055 /**
58056 * @param {?} state
58057 * @param {?} delay
58058 * @return {?}
58059 */
58060 Refresher.prototype._close = function (state$$1, delay) {
58061 var /** @type {?} */ timer;
58062 /**
58063 * @param {?} ev
58064 * @return {?}
58065 */
58066 function close(ev) {
58067 // closing is done, return to inactive state
58068 if (ev) {
58069 clearTimeout(timer);
58070 }
58071 this.state = STATE_INACTIVE;
58072 this.progress = 0;
58073 this._didStart = this.startY = this.currentY = this.deltaY = null;
58074 this._setCss(0, '0ms', false, '');
58075 }
58076 // create fallback timer incase something goes wrong with transitionEnd event
58077 timer = setTimeout(close.bind(this), 600);
58078 // create transition end event on the content's scroll element
58079 this._content.onScrollElementTransitionEnd(close.bind(this));
58080 // reset set the styles on the scroll element
58081 // set that the refresh is actively cancelling/completing
58082 this.state = state$$1;
58083 this._setCss(0, '', true, delay);
58084 if (this._pointerEvents) {
58085 this._pointerEvents.stop();
58086 }
58087 };
58088 /**
58089 * @param {?} y
58090 * @param {?} duration
58091 * @param {?} overflowVisible
58092 * @param {?} delay
58093 * @return {?}
58094 */
58095 Refresher.prototype._setCss = function (y, duration, overflowVisible, delay) {
58096 this._appliedStyles = (y > 0);
58097 var /** @type {?} */ content = this._content;
58098 var /** @type {?} */ Css = this._plt.Css;
58099 content.setScrollElementStyle(Css.transform, ((y > 0) ? 'translateY(' + y + 'px) translateZ(0px)' : 'translateZ(0px)'));
58100 content.setScrollElementStyle(Css.transitionDuration, duration);
58101 content.setScrollElementStyle(Css.transitionDelay, delay);
58102 content.setScrollElementStyle('overflow', (overflowVisible ? 'hidden' : ''));
58103 };
58104 /**
58105 * @param {?} shouldListen
58106 * @return {?}
58107 */
58108 Refresher.prototype._setListeners = function (shouldListen) {
58109 this._events.unlistenAll();
58110 this._pointerEvents = null;
58111 if (shouldListen) {
58112 this._pointerEvents = this._events.pointerEvents({
58113 element: this._content.getScrollElement(),
58114 pointerDown: this._onStart.bind(this),
58115 pointerMove: this._onMove.bind(this),
58116 pointerUp: this._onEnd.bind(this),
58117 zone: false
58118 });
58119 }
58120 };
58121 /**
58122 * @hidden
58123 * @return {?}
58124 */
58125 Refresher.prototype.ngOnInit = function () {
58126 // bind event listeners
58127 // save the unregister listener functions to use onDestroy
58128 this._setListeners(this._isEnabled);
58129 };
58130 /**
58131 * @hidden
58132 * @return {?}
58133 */
58134 Refresher.prototype.ngOnDestroy = function () {
58135 this._setListeners(false);
58136 this._events.destroy();
58137 this._gesture.destroy();
58138 };
58139 return Refresher;
58140}());
58141Refresher.decorators = [
58142 { type: Directive, args: [{
58143 selector: 'ion-refresher',
58144 host: {
58145 '[class.refresher-active]': 'state !== "inactive"',
58146 '[style.top]': '_top'
58147 }
58148 },] },
58149];
58150/**
58151 * @nocollapse
58152 */
58153Refresher.ctorParameters = function () { return [
58154 { type: Platform, },
58155 { type: Content, decorators: [{ type: Host },] },
58156 { type: NgZone, },
58157 { type: GestureController, },
58158]; };
58159Refresher.propDecorators = {
58160 'pullMin': [{ type: Input },],
58161 'pullMax': [{ type: Input },],
58162 'closeDuration': [{ type: Input },],
58163 'snapbackDuration': [{ type: Input },],
58164 'enabled': [{ type: Input },],
58165 'ionRefresh': [{ type: Output },],
58166 'ionPull': [{ type: Output },],
58167 'ionStart': [{ type: Output },],
58168};
58169var STATE_INACTIVE = 'inactive';
58170var STATE_PULLING = 'pulling';
58171var STATE_READY = 'ready';
58172var STATE_REFRESHING = 'refreshing';
58173var STATE_CANCELLING = 'cancelling';
58174var STATE_COMPLETING = 'completing';
58175
58176/**
58177 * @hidden
58178 */
58179var RefresherContent = (function () {
58180 /**
58181 * @param {?} r
58182 * @param {?} _config
58183 */
58184 function RefresherContent(r, _config) {
58185 this.r = r;
58186 this._config = _config;
58187 }
58188 /**
58189 * @hidden
58190 * @return {?}
58191 */
58192 RefresherContent.prototype.ngOnInit = function () {
58193 if (!this.pullingIcon) {
58194 this.pullingIcon = this._config.get('ionPullIcon', 'arrow-down');
58195 }
58196 if (!this.refreshingSpinner) {
58197 this.refreshingSpinner = this._config.get('ionRefreshingSpinner', this._config.get('spinner', 'ios'));
58198 }
58199 };
58200 return RefresherContent;
58201}());
58202RefresherContent.decorators = [
58203 { type: Component, args: [{
58204 selector: 'ion-refresher-content',
58205 template: '<div class="refresher-pulling">' +
58206 '<div class="refresher-pulling-icon" *ngIf="pullingIcon">' +
58207 '<ion-icon [name]="pullingIcon"></ion-icon>' +
58208 '</div>' +
58209 '<div class="refresher-pulling-text" [innerHTML]="pullingText" *ngIf="pullingText"></div>' +
58210 '</div>' +
58211 '<div class="refresher-refreshing">' +
58212 '<div class="refresher-refreshing-icon">' +
58213 '<ion-spinner [name]="refreshingSpinner"></ion-spinner>' +
58214 '</div>' +
58215 '<div class="refresher-refreshing-text" [innerHTML]="refreshingText" *ngIf="refreshingText"></div>' +
58216 '</div>',
58217 host: {
58218 '[attr.state]': 'r.state'
58219 },
58220 encapsulation: ViewEncapsulation.None,
58221 },] },
58222];
58223/**
58224 * @nocollapse
58225 */
58226RefresherContent.ctorParameters = function () { return [
58227 { type: Refresher, },
58228 { type: Config, },
58229]; };
58230RefresherContent.propDecorators = {
58231 'pullingIcon': [{ type: Input },],
58232 'pullingText': [{ type: Input },],
58233 'refreshingSpinner': [{ type: Input },],
58234 'refreshingText': [{ type: Input },],
58235};
58236
58237/**
58238 * \@name Scroll
58239 * \@description
58240 * Scroll is a non-flexboxed scroll area that can scroll horizontally or vertically. `ion-Scroll` Can be used in places where you may not need a full page scroller, but a highly customized one, such as image scubber or comment scroller.
58241 * \@usage
58242 * ```html
58243 * <ion-scroll scrollX="true">
58244 * </ion-scroll>
58245 *
58246 * <ion-scroll scrollY="true">
58247 * </ion-scroll>
58248 *
58249 * <ion-scroll scrollX="true" scrollY="true">
58250 * </ion-scroll>
58251 * ```
58252 * \@demo /docs/demos/src/scroll/
58253 */
58254var Scroll = (function () {
58255 function Scroll() {
58256 this._scrollX = false;
58257 this._scrollY = false;
58258 this._zoom = false;
58259 this._maxZoom = 1;
58260 /**
58261 * @hidden
58262 */
58263 this.maxScale = 3;
58264 /**
58265 * @hidden
58266 */
58267 this.zoomDuration = 250;
58268 }
58269 Object.defineProperty(Scroll.prototype, "scrollX", {
58270 /**
58271 * \@input {boolean} If true, scrolling along the X axis is enabled.
58272 * @return {?}
58273 */
58274 get: function () {
58275 return this._scrollX;
58276 },
58277 /**
58278 * @param {?} val
58279 * @return {?}
58280 */
58281 set: function (val) {
58282 this._scrollX = isTrueProperty(val);
58283 },
58284 enumerable: true,
58285 configurable: true
58286 });
58287 Object.defineProperty(Scroll.prototype, "scrollY", {
58288 /**
58289 * \@input {boolean} If true, scrolling along the Y axis is enabled; requires the following CSS declaration: ion-scroll { white-space: nowrap; }
58290 * @return {?}
58291 */
58292 get: function () {
58293 return this._scrollY;
58294 },
58295 /**
58296 * @param {?} val
58297 * @return {?}
58298 */
58299 set: function (val) {
58300 this._scrollY = isTrueProperty(val);
58301 },
58302 enumerable: true,
58303 configurable: true
58304 });
58305 Object.defineProperty(Scroll.prototype, "zoom", {
58306 /**
58307 * \@input {boolean} If true, zooming is enabled.
58308 * @return {?}
58309 */
58310 get: function () {
58311 return this._zoom;
58312 },
58313 /**
58314 * @param {?} val
58315 * @return {?}
58316 */
58317 set: function (val) {
58318 this._zoom = isTrueProperty(val);
58319 },
58320 enumerable: true,
58321 configurable: true
58322 });
58323 Object.defineProperty(Scroll.prototype, "maxZoom", {
58324 /**
58325 * \@input {number} Set the max zoom amount.
58326 * @return {?}
58327 */
58328 get: function () {
58329 return this._maxZoom;
58330 },
58331 /**
58332 * @param {?} val
58333 * @return {?}
58334 */
58335 set: function (val) {
58336 this._maxZoom = val;
58337 },
58338 enumerable: true,
58339 configurable: true
58340 });
58341 /**
58342 * @hidden
58343 * Add a scroll event handler to the scroll element if it exists.
58344 * undefined if the scroll element doesn't exist.
58345 * @param {?} handler
58346 * @return {?}
58347 */
58348 Scroll.prototype.addScrollEventListener = function (handler) {
58349 (void 0) /* assert */;
58350 var /** @type {?} */ ele = this._scrollContent.nativeElement;
58351 ele.addEventListener('scroll', handler);
58352 return function () {
58353 ele.removeEventListener('scroll', handler);
58354 };
58355 };
58356 return Scroll;
58357}());
58358Scroll.decorators = [
58359 { type: Component, args: [{
58360 selector: 'ion-scroll',
58361 template: '<div class="scroll-content" #scrollContent>' +
58362 '<div class="scroll-zoom-wrapper">' +
58363 '<ng-content></ng-content>' +
58364 '</div>' +
58365 '</div>',
58366 host: {
58367 '[class.scroll-x]': 'scrollX',
58368 '[class.scroll-y]': 'scrollY'
58369 },
58370 changeDetection: ChangeDetectionStrategy.OnPush,
58371 encapsulation: ViewEncapsulation.None,
58372 },] },
58373];
58374/**
58375 * @nocollapse
58376 */
58377Scroll.ctorParameters = function () { return []; };
58378Scroll.propDecorators = {
58379 'scrollX': [{ type: Input },],
58380 'scrollY': [{ type: Input },],
58381 'zoom': [{ type: Input },],
58382 'maxZoom': [{ type: Input },],
58383 '_scrollContent': [{ type: ViewChild, args: ['scrollContent', { read: ElementRef },] },],
58384};
58385
58386var __extends$71 = (undefined && undefined.__extends) || (function () {
58387 var extendStatics = Object.setPrototypeOf ||
58388 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
58389 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
58390 return function (d, b) {
58391 extendStatics(d, b);
58392 function __() { this.constructor = d; }
58393 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
58394 };
58395})();
58396/**
58397 * \@name Searchbar
58398 * \@module ionic
58399 * \@description
58400 * Manages the display of a Searchbar which can be used to search or filter items.
58401 *
58402 * \@usage
58403 * ```html
58404 * <ion-searchbar
58405 * [(ngModel)]="myInput"
58406 * [showCancelButton]="shouldShowCancel"
58407 * (ionInput)="onInput($event)"
58408 * (ionCancel)="onCancel($event)">
58409 * </ion-searchbar>
58410 * ```
58411 *
58412 * \@demo /docs/demos/src/searchbar/
58413 * @see {\@link /docs/components#searchbar Searchbar Component Docs}
58414 */
58415var Searchbar = (function (_super) {
58416 __extends$71(Searchbar, _super);
58417 /**
58418 * @param {?} config
58419 * @param {?} _plt
58420 * @param {?} elementRef
58421 * @param {?} renderer
58422 * @param {?} ngControl
58423 */
58424 function Searchbar(config, _plt, elementRef, renderer, ngControl) {
58425 var _this = _super.call(this, config, elementRef, renderer, 'searchbar', '', null, null, ngControl) || this;
58426 _this._plt = _plt;
58427 _this._shouldBlur = true;
58428 _this._shouldAlignLeft = true;
58429 _this._isCancelVisible = false;
58430 _this._spellcheck = false;
58431 _this._autocomplete = 'off';
58432 _this._autocorrect = 'off';
58433 _this._isActive = false;
58434 _this._showCancelButton = false;
58435 _this._animated = false;
58436 _this._inputDebouncer = new TimeoutDebouncer(0);
58437 /**
58438 * \@input {string} Set the the cancel button text. Default: `"Cancel"`.
58439 */
58440 _this.cancelButtonText = 'Cancel';
58441 /**
58442 * \@input {string} Set the input's placeholder. Default `"Search"`.
58443 */
58444 _this.placeholder = 'Search';
58445 /**
58446 * \@input {string} Set the type of the input. Values: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, `"url"`. Default `"search"`.
58447 */
58448 _this.type = 'search';
58449 /**
58450 * \@output {event} Emitted when the Searchbar input has changed, including when it's cleared.
58451 */
58452 _this.ionInput = new EventEmitter();
58453 /**
58454 * \@output {event} Emitted when the cancel button is clicked.
58455 */
58456 _this.ionCancel = new EventEmitter();
58457 /**
58458 * \@output {event} Emitted when the clear input button is clicked.
58459 */
58460 _this.ionClear = new EventEmitter();
58461 _this.debounce = 250;
58462 return _this;
58463 }
58464 Object.defineProperty(Searchbar.prototype, "showCancelButton", {
58465 /**
58466 * \@input {boolean} If true, show the cancel button. Default `false`.
58467 * @return {?}
58468 */
58469 get: function () {
58470 return this._showCancelButton;
58471 },
58472 /**
58473 * @param {?} val
58474 * @return {?}
58475 */
58476 set: function (val) {
58477 this._showCancelButton = isTrueProperty(val);
58478 },
58479 enumerable: true,
58480 configurable: true
58481 });
58482 Object.defineProperty(Searchbar.prototype, "debounce", {
58483 /**
58484 * \@input {number} How long, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. Default `250`.
58485 * @return {?}
58486 */
58487 get: function () {
58488 return this._debouncer.wait;
58489 },
58490 /**
58491 * @param {?} val
58492 * @return {?}
58493 */
58494 set: function (val) {
58495 this._debouncer.wait = val;
58496 this._inputDebouncer.wait = val;
58497 },
58498 enumerable: true,
58499 configurable: true
58500 });
58501 Object.defineProperty(Searchbar.prototype, "autocomplete", {
58502 /**
58503 * \@input {string} Set the input's autocomplete property. Values: `"on"`, `"off"`. Default `"off"`.
58504 * @param {?} val
58505 * @return {?}
58506 */
58507 set: function (val) {
58508 this._autocomplete = (val === '' || val === 'on') ? 'on' : this._config.get('autocomplete', 'off');
58509 },
58510 enumerable: true,
58511 configurable: true
58512 });
58513 Object.defineProperty(Searchbar.prototype, "autocorrect", {
58514 /**
58515 * \@input {string} Set the input's autocorrect property. Values: `"on"`, `"off"`. Default `"off"`.
58516 * @param {?} val
58517 * @return {?}
58518 */
58519 set: function (val) {
58520 this._autocorrect = (val === '' || val === 'on') ? 'on' : this._config.get('autocorrect', 'off');
58521 },
58522 enumerable: true,
58523 configurable: true
58524 });
58525 Object.defineProperty(Searchbar.prototype, "spellcheck", {
58526 /**
58527 * \@input {string|boolean} Set the input's spellcheck property. Values: `true`, `false`. Default `false`.
58528 * @param {?} val
58529 * @return {?}
58530 */
58531 set: function (val) {
58532 this._spellcheck = (val === '' || val === 'true' || val === true) ? true : this._config.getBoolean('spellcheck', false);
58533 },
58534 enumerable: true,
58535 configurable: true
58536 });
58537 Object.defineProperty(Searchbar.prototype, "animated", {
58538 /**
58539 * \@input {boolean} If true, enable searchbar animation. Default `false`.
58540 * @return {?}
58541 */
58542 get: function () {
58543 return this._animated;
58544 },
58545 /**
58546 * @param {?} val
58547 * @return {?}
58548 */
58549 set: function (val) {
58550 this._animated = isTrueProperty(val);
58551 },
58552 enumerable: true,
58553 configurable: true
58554 });
58555 /**
58556 * @hidden
58557 * On Initialization check for attributes
58558 * @return {?}
58559 */
58560 Searchbar.prototype.ngOnInit = function () {
58561 var /** @type {?} */ showCancelButton = this.showCancelButton;
58562 if (typeof showCancelButton === 'string') {
58563 this.showCancelButton = (showCancelButton === '' || showCancelButton === 'true');
58564 }
58565 };
58566 /**
58567 * @hidden
58568 * @return {?}
58569 */
58570 Searchbar.prototype._inputUpdated = function () {
58571 var /** @type {?} */ ele = this._searchbarInput.nativeElement;
58572 var /** @type {?} */ value = this._value;
58573 // It is important not to re-assign the value if it is the same, because,
58574 // otherwise, the caret is moved to the end of the input
58575 if (ele.value !== value) {
58576 ele.value = value;
58577 }
58578 this.positionElements();
58579 };
58580 /**
58581 * @hidden
58582 * Positions the input search icon, placeholder, and the cancel button
58583 * based on the input value and if it is focused. (ios only)
58584 * @return {?}
58585 */
58586 Searchbar.prototype.positionElements = function () {
58587 var /** @type {?} */ isAnimated = this._animated;
58588 var /** @type {?} */ prevAlignLeft = this._shouldAlignLeft;
58589 var /** @type {?} */ shouldAlignLeft = (!isAnimated || (this._value && this._value.toString().trim() !== '') || this._isFocus === true);
58590 this._shouldAlignLeft = shouldAlignLeft;
58591 if (this._mode !== 'ios') {
58592 return;
58593 }
58594 if (prevAlignLeft !== shouldAlignLeft) {
58595 this.positionPlaceholder();
58596 }
58597 if (isAnimated) {
58598 this.positionCancelButton();
58599 }
58600 };
58601 /**
58602 * @return {?}
58603 */
58604 Searchbar.prototype.positionPlaceholder = function () {
58605 var /** @type {?} */ inputEle = this._searchbarInput.nativeElement;
58606 var /** @type {?} */ iconEle = this._searchbarIcon.nativeElement;
58607 if (this._shouldAlignLeft) {
58608 inputEle.removeAttribute('style');
58609 iconEle.removeAttribute('style');
58610 }
58611 else {
58612 // Create a dummy span to get the placeholder width
58613 var /** @type {?} */ doc = this._plt.doc();
58614 var /** @type {?} */ tempSpan = doc.createElement('span');
58615 tempSpan.innerHTML = this.placeholder;
58616 doc.body.appendChild(tempSpan);
58617 // Get the width of the span then remove it
58618 var /** @type {?} */ textWidth = tempSpan.offsetWidth;
58619 doc.body.removeChild(tempSpan);
58620 // Set the input padding start
58621 var /** @type {?} */ inputLeft = 'calc(50% - ' + (textWidth / 2) + 'px)';
58622 if (this._plt.isRTL) {
58623 inputEle.style.paddingRight = inputLeft;
58624 }
58625 else {
58626 inputEle.style.paddingLeft = inputLeft;
58627 }
58628 // Set the icon margin start
58629 var /** @type {?} */ iconLeft = 'calc(50% - ' + ((textWidth / 2) + 30) + 'px)';
58630 if (this._plt.isRTL) {
58631 iconEle.style.marginRight = iconLeft;
58632 }
58633 else {
58634 iconEle.style.marginLeft = iconLeft;
58635 }
58636 }
58637 };
58638 /**
58639 * @hidden
58640 * Show the iOS Cancel button on focus, hide it offscreen otherwise
58641 * @return {?}
58642 */
58643 Searchbar.prototype.positionCancelButton = function () {
58644 var /** @type {?} */ showShowCancel = this._isFocus;
58645 if (showShowCancel !== this._isCancelVisible) {
58646 var /** @type {?} */ cancelStyleEle = this._cancelButton.nativeElement;
58647 var /** @type {?} */ cancelStyle = cancelStyleEle.style;
58648 this._isCancelVisible = showShowCancel;
58649 if (showShowCancel) {
58650 if (this._plt.isRTL) {
58651 cancelStyle.marginLeft = '0';
58652 }
58653 else {
58654 cancelStyle.marginRight = '0';
58655 }
58656 }
58657 else {
58658 var /** @type {?} */ offset = cancelStyleEle.offsetWidth;
58659 if (offset > 0) {
58660 if (this._plt.isRTL) {
58661 cancelStyle.marginLeft = -offset + 'px';
58662 }
58663 else {
58664 cancelStyle.marginRight = -offset + 'px';
58665 }
58666 }
58667 }
58668 }
58669 };
58670 /**
58671 * @hidden
58672 * Update the Searchbar input value when the input changes
58673 * @param {?} ev
58674 * @return {?}
58675 */
58676 Searchbar.prototype.inputChanged = function (ev) {
58677 var _this = this;
58678 this.value = ev.target.value;
58679 this._inputDebouncer.debounce(function () {
58680 _this.ionInput.emit(ev);
58681 });
58682 };
58683 /**
58684 * @hidden
58685 * Sets the Searchbar to focused and active on input focus.
58686 * @return {?}
58687 */
58688 Searchbar.prototype.inputFocused = function () {
58689 this._isActive = true;
58690 this._fireFocus();
58691 this.positionElements();
58692 };
58693 /**
58694 * @hidden
58695 * Sets the Searchbar to not focused and checks if it should align left
58696 * based on whether there is a value in the searchbar or not.
58697 * @return {?}
58698 */
58699 Searchbar.prototype.inputBlurred = function () {
58700 // _shouldBlur determines if it should blur
58701 // if we are clearing the input we still want to stay focused in the input
58702 if (this._shouldBlur === false) {
58703 this._searchbarInput.nativeElement.focus();
58704 this._shouldBlur = true;
58705 return;
58706 }
58707 this._fireBlur();
58708 this.positionElements();
58709 };
58710 /**
58711 * @hidden
58712 * Clears the input field and triggers the control change.
58713 * @param {?} ev
58714 * @return {?}
58715 */
58716 Searchbar.prototype.clearInput = function (ev) {
58717 var _this = this;
58718 this.ionClear.emit(ev);
58719 // setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
58720 // wait for 4 frames
58721 setTimeout(function () {
58722 var /** @type {?} */ value = _this._value;
58723 if (isPresent(value) && value !== '') {
58724 _this.value = ''; // DOM WRITE
58725 _this.ionInput.emit(ev);
58726 }
58727 }, 16 * 4);
58728 this._shouldBlur = false;
58729 };
58730 /**
58731 * @hidden
58732 * Clears the input field and tells the input to blur since
58733 * the clearInput function doesn't want the input to blur
58734 * then calls the custom cancel function if the user passed one in.
58735 * @param {?} ev
58736 * @return {?}
58737 */
58738 Searchbar.prototype.cancelSearchbar = function (ev) {
58739 this.ionCancel.emit(ev);
58740 this.clearInput(ev);
58741 this._shouldBlur = true;
58742 this._isActive = false;
58743 };
58744 /**
58745 * @return {?}
58746 */
58747 Searchbar.prototype.setFocus = function () {
58748 this._renderer.invokeElementMethod(this._searchbarInput.nativeElement, 'focus');
58749 };
58750 return Searchbar;
58751}(BaseInput));
58752Searchbar.decorators = [
58753 { type: Component, args: [{
58754 selector: 'ion-searchbar',
58755 template: '<div class="searchbar-input-container">' +
58756 '<button ion-button mode="md" (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" clear color="dark" class="searchbar-md-cancel" type="button">' +
58757 '<ion-icon name="md-arrow-back"></ion-icon>' +
58758 '</button>' +
58759 '<div #searchbarIcon class="searchbar-search-icon"></div>' +
58760 '<input #searchbarInput class="searchbar-input" (input)="inputChanged($event)" (blur)="inputBlurred()" (focus)="inputFocused()" ' +
58761 '[attr.placeholder]="placeholder" ' +
58762 '[attr.type]="type" ' +
58763 '[attr.autocomplete]="_autocomplete" ' +
58764 '[attr.autocorrect]="_autocorrect" ' +
58765 '[attr.spellcheck]="_spellcheck">' +
58766 '<button ion-button clear class="searchbar-clear-icon" [mode]="_mode" (click)="clearInput($event)" (mousedown)="clearInput($event)" type="button"></button>' +
58767 '</div>' +
58768 '<button ion-button #cancelButton mode="ios" [tabindex]="_isActive ? 1 : -1" clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" class="searchbar-ios-cancel" type="button">{{cancelButtonText}}</button>',
58769 host: {
58770 '[class.searchbar-animated]': '_animated',
58771 '[class.searchbar-has-value]': '_value',
58772 '[class.searchbar-active]': '_isActive',
58773 '[class.searchbar-show-cancel]': '_showCancelButton',
58774 '[class.searchbar-left-aligned]': '_shouldAlignLeft',
58775 '[class.searchbar-has-focus]': '_isFocus'
58776 },
58777 encapsulation: ViewEncapsulation.None
58778 },] },
58779];
58780/**
58781 * @nocollapse
58782 */
58783Searchbar.ctorParameters = function () { return [
58784 { type: Config, },
58785 { type: Platform, },
58786 { type: ElementRef, },
58787 { type: Renderer, },
58788 { type: NgControl, decorators: [{ type: Optional },] },
58789]; };
58790Searchbar.propDecorators = {
58791 'cancelButtonText': [{ type: Input },],
58792 'showCancelButton': [{ type: Input },],
58793 'debounce': [{ type: Input },],
58794 'placeholder': [{ type: Input },],
58795 'autocomplete': [{ type: Input },],
58796 'autocorrect': [{ type: Input },],
58797 'spellcheck': [{ type: Input },],
58798 'type': [{ type: Input },],
58799 'animated': [{ type: Input },],
58800 'ionInput': [{ type: Output },],
58801 'ionCancel': [{ type: Output },],
58802 'ionClear': [{ type: Output },],
58803 '_searchbarInput': [{ type: ViewChild, args: ['searchbarInput',] },],
58804 '_searchbarIcon': [{ type: ViewChild, args: ['searchbarIcon',] },],
58805 '_cancelButton': [{ type: ViewChild, args: ['cancelButton', { read: ElementRef },] },],
58806};
58807
58808/**
58809 * \@name SegmentButton
58810 * \@description
58811 * The child buttons of the `ion-segment` component. Each `ion-segment-button` must have a value.
58812 *
58813 * \@usage
58814 *
58815 * ```html
58816 * <ion-content>
58817 * <!-- Segment buttons with icons -->
58818 * <ion-segment [(ngModel)]="icons" color="secondary">
58819 * <ion-segment-button value="camera">
58820 * <ion-icon name="camera"></ion-icon>
58821 * </ion-segment-button>
58822 * <ion-segment-button value="bookmark">
58823 * <ion-icon name="bookmark"></ion-icon>
58824 * </ion-segment-button>
58825 * </ion-segment>
58826 *
58827 * <!-- Segment buttons with text -->
58828 * <ion-segment [(ngModel)]="relationship" color="primary">
58829 * <ion-segment-button value="friends" (ionSelect)="selectedFriends()">
58830 * Friends
58831 * </ion-segment-button>
58832 * <ion-segment-button value="enemies" (ionSelect)="selectedEnemies()">
58833 * Enemies
58834 * </ion-segment-button>
58835 * </ion-segment>
58836 * </ion-content>
58837 * ```
58838 *
58839 *
58840 * \@demo /docs/demos/src/segment/
58841 * @see {\@link /docs/components#segment Segment Component Docs}
58842 * @see {\@link /docs/api/components/segment/Segment/ Segment API Docs}
58843 */
58844var SegmentButton = (function () {
58845 function SegmentButton() {
58846 this.isActive = false;
58847 this._disabled = false;
58848 /**
58849 * \@output {SegmentButton} Emitted when a segment button has been clicked.
58850 */
58851 this.ionSelect = new EventEmitter();
58852 }
58853 Object.defineProperty(SegmentButton.prototype, "disabled", {
58854 /**
58855 * \@input {boolean} If true, the user cannot interact with this element.
58856 * @return {?}
58857 */
58858 get: function () {
58859 return this._disabled;
58860 },
58861 /**
58862 * @param {?} val
58863 * @return {?}
58864 */
58865 set: function (val) {
58866 this._disabled = isTrueProperty(val);
58867 },
58868 enumerable: true,
58869 configurable: true
58870 });
58871 /**
58872 * @hidden
58873 * On click of a SegmentButton
58874 * @return {?}
58875 */
58876 SegmentButton.prototype.onClick = function () {
58877 (void 0) /* console.debug */;
58878 this.ionSelect.emit(this);
58879 };
58880 /**
58881 * @hidden
58882 * @return {?}
58883 */
58884 SegmentButton.prototype.ngOnInit = function () {
58885 if (!isPresent(this.value)) {
58886 console.warn('<ion-segment-button> requires a "value" attribute');
58887 }
58888 };
58889 return SegmentButton;
58890}());
58891SegmentButton.decorators = [
58892 { type: Component, args: [{
58893 selector: 'ion-segment-button',
58894 template: '<ng-content></ng-content>' +
58895 '<div class="button-effect"></div>',
58896 host: {
58897 'tappable': '',
58898 'class': 'segment-button',
58899 'role': 'button',
58900 '[class.segment-button-disabled]': '_disabled',
58901 '[class.segment-activated]': 'isActive',
58902 '[attr.aria-pressed]': 'isActive'
58903 },
58904 encapsulation: ViewEncapsulation.None,
58905 },] },
58906];
58907/**
58908 * @nocollapse
58909 */
58910SegmentButton.ctorParameters = function () { return []; };
58911SegmentButton.propDecorators = {
58912 'value': [{ type: Input },],
58913 'ionSelect': [{ type: Output },],
58914 'disabled': [{ type: Input },],
58915 'onClick': [{ type: HostListener, args: ['click',] },],
58916};
58917
58918var __extends$72 = (undefined && undefined.__extends) || (function () {
58919 var extendStatics = Object.setPrototypeOf ||
58920 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
58921 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
58922 return function (d, b) {
58923 extendStatics(d, b);
58924 function __() { this.constructor = d; }
58925 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
58926 };
58927})();
58928/**
58929 * \@name Segment
58930 * \@description
58931 * A Segment is a group of buttons, sometimes known as Segmented Controls, that allow the user to interact with a compact group of a number of controls.
58932 * Segments provide functionality similar to tabs, selecting one will unselect all others. You should use a tab bar instead of a segmented control when you want to let the user move back and forth between distinct pages in your app.
58933 * You could use Angular's `ngModel` or `FormBuilder` API. For an overview on how `FormBuilder` works, checkout [Angular Forms](http://learnangular2.com/forms/), or [Angular FormBuilder](https://angular.io/docs/ts/latest/api/forms/index/FormBuilder-class.html)
58934 *
58935 *
58936 * ```html
58937 * <!-- Segment in a header -->
58938 * <ion-header>
58939 * <ion-toolbar>
58940 * <ion-segment [(ngModel)]="icons" color="secondary">
58941 * <ion-segment-button value="camera">
58942 * <ion-icon name="camera"></ion-icon>
58943 * </ion-segment-button>
58944 * <ion-segment-button value="bookmark">
58945 * <ion-icon name="bookmark"></ion-icon>
58946 * </ion-segment-button>
58947 * </ion-segment>
58948 * </ion-toolbar>
58949 * </ion-header>
58950 *
58951 * <ion-content>
58952 * <!-- Segment in content -->
58953 * <ion-segment [(ngModel)]="relationship" color="primary" (ionChange)="segmentChanged($event)">
58954 * <ion-segment-button value="friends">
58955 * Friends
58956 * </ion-segment-button>
58957 * <ion-segment-button value="enemies">
58958 * Enemies
58959 * </ion-segment-button>
58960 * </ion-segment>
58961 *
58962 * <!-- Segment in a form -->
58963 * <form [formGroup]="myForm">
58964 * <ion-segment formControlName="mapStyle" color="danger">
58965 * <ion-segment-button value="standard">
58966 * Standard
58967 * </ion-segment-button>
58968 * <ion-segment-button value="hybrid">
58969 * Hybrid
58970 * </ion-segment-button>
58971 * <ion-segment-button value="sat">
58972 * Satellite
58973 * </ion-segment-button>
58974 * </ion-segment>
58975 * </form>
58976 * </ion-content>
58977 * ```
58978 *
58979 *
58980 * \@demo /docs/demos/src/segment/
58981 * @see {\@link /docs/components#segment Segment Component Docs}
58982 * @see [Angular Forms](http://learnangular2.com/forms/)
58983 */
58984var Segment = (function (_super) {
58985 __extends$72(Segment, _super);
58986 /**
58987 * @param {?} config
58988 * @param {?} elementRef
58989 * @param {?} renderer
58990 * @param {?} ngControl
58991 */
58992 function Segment(config, elementRef, renderer, ngControl) {
58993 return _super.call(this, config, elementRef, renderer, 'segment', null, null, null, ngControl) || this;
58994 }
58995 /**
58996 * @hidden
58997 * @return {?}
58998 */
58999 Segment.prototype.ngAfterContentInit = function () {
59000 var _this = this;
59001 this._initialize();
59002 this._buttons.forEach(function (button) {
59003 button.ionSelect.subscribe(function (selectedButton) {
59004 _this.value = selectedButton.value;
59005 _this._fireTouched();
59006 });
59007 });
59008 };
59009 /**
59010 * @hidden
59011 * Write a new value to the element.
59012 * @return {?}
59013 */
59014 Segment.prototype._inputUpdated = function () {
59015 if (!this._buttons) {
59016 (void 0) /* assert */;
59017 return;
59018 }
59019 var /** @type {?} */ buttons = this._buttons.toArray();
59020 var /** @type {?} */ value = this.value;
59021 for (var _i = 0, buttons_1 = buttons; _i < buttons_1.length; _i++) {
59022 var button = buttons_1[_i];
59023 button.isActive = (button.value === value);
59024 }
59025 };
59026 return Segment;
59027}(BaseInput));
59028Segment.decorators = [
59029 { type: Directive, args: [{
59030 selector: 'ion-segment',
59031 host: {
59032 '[class.segment-disabled]': '_disabled'
59033 }
59034 },] },
59035];
59036/**
59037 * @nocollapse
59038 */
59039Segment.ctorParameters = function () { return [
59040 { type: Config, },
59041 { type: ElementRef, },
59042 { type: Renderer, },
59043 { type: NgControl, decorators: [{ type: Optional },] },
59044]; };
59045Segment.propDecorators = {
59046 '_buttons': [{ type: ContentChildren, args: [SegmentButton,] },],
59047};
59048
59049/**
59050 * @hidden
59051 */
59052var SelectPopover = (function () {
59053 /**
59054 * @param {?} navParams
59055 * @param {?} viewController
59056 */
59057 function SelectPopover(navParams, viewController) {
59058 this.navParams = navParams;
59059 this.viewController = viewController;
59060 }
59061 Object.defineProperty(SelectPopover.prototype, "value", {
59062 /**
59063 * @return {?}
59064 */
59065 get: function () {
59066 var /** @type {?} */ checkedOption = this.options.find(function (option) { return option.checked; });
59067 return checkedOption ? checkedOption.value : undefined;
59068 },
59069 /**
59070 * @param {?} value
59071 * @return {?}
59072 */
59073 set: function (value) {
59074 var /** @type {?} */ checkedOption = this.options.find(function (option) { return option.value === value; });
59075 if (checkedOption && checkedOption.handler) {
59076 checkedOption.handler();
59077 }
59078 this.viewController.dismiss(value);
59079 },
59080 enumerable: true,
59081 configurable: true
59082 });
59083 /**
59084 * @return {?}
59085 */
59086 SelectPopover.prototype.ngOnInit = function () {
59087 this.options = this.navParams.data.options;
59088 };
59089 return SelectPopover;
59090}());
59091SelectPopover.decorators = [
59092 { type: Component, args: [{
59093 template: "\n <ion-list radio-group [(ngModel)]=\"value\">\n <ion-item *ngFor=\"let option of options\">\n <ion-label>{{option.text}}</ion-label>\n <ion-radio [checked]=\"option.checked\" [value]=\"option.value\" [disabled]=\"option.disabled\"></ion-radio>\n </ion-item>\n </ion-list>\n "
59094 },] },
59095];
59096/**
59097 * @nocollapse
59098 */
59099SelectPopover.ctorParameters = function () { return [
59100 { type: NavParams, },
59101 { type: ViewController, },
59102]; };
59103
59104var __extends$73 = (undefined && undefined.__extends) || (function () {
59105 var extendStatics = Object.setPrototypeOf ||
59106 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
59107 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
59108 return function (d, b) {
59109 extendStatics(d, b);
59110 function __() { this.constructor = d; }
59111 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
59112 };
59113})();
59114/**
59115 * \@name Select
59116 * \@description
59117 * The `ion-select` component is similar to an HTML `<select>` element, however,
59118 * Ionic's select component makes it easier for users to sort through and select
59119 * the preferred option or options. When users tap the select component, a
59120 * dialog will appear with all of the options in a large, easy to select list
59121 * for users.
59122 *
59123 * The select component takes child `ion-option` components. If `ion-option` is not
59124 * given a `value` attribute then it will use its text as the value.
59125 *
59126 * If `ngModel` is bound to `ion-select`, the selected value will be based on the
59127 * bound value of the model. Otherwise, the `selected` attribute can be used on
59128 * `ion-option` components.
59129 *
59130 * ### Interfaces
59131 *
59132 * By default, the `ion-select` uses the {\@link ../../alert/AlertController AlertController API}
59133 * to open up the overlay of options in an alert. The interface can be changed to use the
59134 * {\@link ../../action-sheet/ActionSheetController ActionSheetController API} or
59135 * {\@link ../../popover/PopoverController PopoverController API} by passing `action-sheet` or `popover`,
59136 * respectively, to the `interface` property. Read on to the other sections for the limitations
59137 * of the different interfaces.
59138 *
59139 * ### Single Value: Radio Buttons
59140 *
59141 * The standard `ion-select` component allows the user to select only one
59142 * option. When selecting only one option the alert interface presents users with
59143 * a radio button styled list of options. The action sheet interface can only be
59144 * used with a single value select. If the number of options exceed 6, it will
59145 * use the `alert` interface even if `action-sheet` is passed. The `ion-select`
59146 * component's value receives the value of the selected option's value.
59147 *
59148 * ```html
59149 * <ion-item>
59150 * <ion-label>Gender</ion-label>
59151 * <ion-select [(ngModel)]="gender">
59152 * <ion-option value="f">Female</ion-option>
59153 * <ion-option value="m">Male</ion-option>
59154 * </ion-select>
59155 * </ion-item>
59156 * ```
59157 *
59158 * ### Multiple Value: Checkboxes
59159 *
59160 * By adding the `multiple="true"` attribute to `ion-select`, users are able
59161 * to select multiple options. When multiple options can be selected, the alert
59162 * overlay presents users with a checkbox styled list of options. The
59163 * `ion-select multiple="true"` component's value receives an array of all the
59164 * selected option values. In the example below, because each option is not given
59165 * a `value`, then it'll use its text as the value instead.
59166 *
59167 * Note: the `action-sheet` and `popover` interfaces will not work with a multi-value select.
59168 *
59169 * ```html
59170 * <ion-item>
59171 * <ion-label>Toppings</ion-label>
59172 * <ion-select [(ngModel)]="toppings" multiple="true">
59173 * <ion-option>Bacon</ion-option>
59174 * <ion-option>Black Olives</ion-option>
59175 * <ion-option>Extra Cheese</ion-option>
59176 * <ion-option>Mushrooms</ion-option>
59177 * <ion-option>Pepperoni</ion-option>
59178 * <ion-option>Sausage</ion-option>
59179 * </ion-select>
59180 * </ion-item>
59181 * ```
59182 *
59183 * ### Select Buttons
59184 * By default, the two buttons read `Cancel` and `OK`. Each button's text
59185 * can be customized using the `cancelText` and `okText` attributes:
59186 *
59187 * ```html
59188 * <ion-select okText="Okay" cancelText="Dismiss">
59189 * ...
59190 * </ion-select>
59191 * ```
59192 *
59193 * The `action-sheet` and `popover` interfaces do not have an `OK` button, clicking
59194 * on any of the options will automatically close the overlay and select
59195 * that value.
59196 *
59197 * ### Select Options
59198 *
59199 * Since `ion-select` uses the `Alert`, `Action Sheet` and `Popover` interfaces, options can be
59200 * passed to these components through the `selectOptions` property. This can be used
59201 * to pass a custom title, subtitle, css class, and more. See the
59202 * {\@link ../../alert/AlertController/#create AlertController API docs},
59203 * {\@link ../../action-sheet/ActionSheetController/#create ActionSheetController API docs}, and
59204 * {\@link ../../popover/PopoverController/#create PopoverController API docs}
59205 * for the properties that each interface accepts.
59206 *
59207 * For example, to change the `mode` of the overlay, pass it into `selectOptions`.
59208 *
59209 * ```html
59210 * <ion-select [selectOptions]="selectOptions">
59211 * ...
59212 * </ion-select>
59213 * ```
59214 *
59215 * ```ts
59216 * this.selectOptions = {
59217 * title: 'Pizza Toppings',
59218 * subTitle: 'Select your toppings',
59219 * mode: 'md'
59220 * };
59221 * ```
59222 *
59223 * ### Object Value References
59224 *
59225 * When using objects for select values, it is possible for the identities of these objects to
59226 * change if they are coming from a server or database, while the selected value's identity
59227 * remains the same. For example, this can occur when an existing record with the desired object value
59228 * is loaded into the select, but the newly retrieved select options now have different identities. This will
59229 * result in the select appearing to have no value at all, even though the original selection in still intact.
59230 *
59231 * Using the `compareWith` `Input` is the solution to this problem
59232 *
59233 * ```html
59234 * <ion-item>
59235 * <ion-label>Employee</ion-label>
59236 * <ion-select [(ngModel)]="employee" [compareWith]="compareFn">
59237 * <ion-option *ngFor="let employee of employees" [value]="employee">{{employee.name}}</ion-option>
59238 * </ion-select>
59239 * </ion-item>
59240 * ```
59241 *
59242 * ```ts
59243 * compareFn(e1: Employee, e2: Employee): boolean {
59244 * return e1 && e2 ? e1.id === e2.id : e1 === e2;
59245 * }
59246 * ```
59247 *
59248 * \@demo /docs/demos/src/select/
59249 */
59250var Select = (function (_super) {
59251 __extends$73(Select, _super);
59252 /**
59253 * @param {?} _app
59254 * @param {?} form
59255 * @param {?} config
59256 * @param {?} elementRef
59257 * @param {?} renderer
59258 * @param {?} item
59259 * @param {?} deepLinker
59260 */
59261 function Select(_app, form, config, elementRef, renderer, item, deepLinker) {
59262 var _this = _super.call(this, config, elementRef, renderer, 'select', [], form, item, null) || this;
59263 _this._app = _app;
59264 _this.config = config;
59265 _this.deepLinker = deepLinker;
59266 _this._multi = false;
59267 _this._texts = [];
59268 _this._text = '';
59269 _this._compareWith = isCheckedProperty;
59270 /**
59271 * \@input {string} The text to display on the cancel button. Default: `Cancel`.
59272 */
59273 _this.cancelText = 'Cancel';
59274 /**
59275 * \@input {string} The text to display on the ok button. Default: `OK`.
59276 */
59277 _this.okText = 'OK';
59278 /**
59279 * \@input {any} Any additional options that the `alert` or `action-sheet` interface can take.
59280 * See the [AlertController API docs](../../alert/AlertController/#create) and the
59281 * [ActionSheetController API docs](../../action-sheet/ActionSheetController/#create) for the
59282 * create options for each interface.
59283 */
59284 _this.selectOptions = {};
59285 /**
59286 * \@input {string} The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`.
59287 */
59288 _this.interface = '';
59289 /**
59290 * \@input {string} The text to display instead of the selected option's value.
59291 */
59292 _this.selectedText = '';
59293 /**
59294 * \@output {any} Emitted when the selection was cancelled.
59295 */
59296 _this.ionCancel = new EventEmitter();
59297 return _this;
59298 }
59299 Object.defineProperty(Select.prototype, "compareWith", {
59300 /**
59301 * \@input {Function} The function that will be called to compare object values
59302 * @param {?} fn
59303 * @return {?}
59304 */
59305 set: function (fn) {
59306 if (typeof fn !== 'function') {
59307 throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
59308 }
59309 this._compareWith = fn;
59310 },
59311 enumerable: true,
59312 configurable: true
59313 });
59314 /**
59315 * @param {?} ev
59316 * @return {?}
59317 */
59318 Select.prototype._click = function (ev) {
59319 ev.preventDefault();
59320 ev.stopPropagation();
59321 this.open(ev);
59322 };
59323 /**
59324 * @return {?}
59325 */
59326 Select.prototype._keyup = function () {
59327 this.open();
59328 };
59329 /**
59330 * @hidden
59331 * @return {?}
59332 */
59333 Select.prototype.getValues = function () {
59334 var /** @type {?} */ values = Array.isArray(this._value) ? this._value : [this._value];
59335 (void 0) /* assert */;
59336 return values;
59337 };
59338 /**
59339 * Open the select interface.
59340 * @param {?=} ev
59341 * @return {?}
59342 */
59343 Select.prototype.open = function (ev) {
59344 var _this = this;
59345 if (this.isFocus() || this._disabled) {
59346 return;
59347 }
59348 (void 0) /* console.debug */;
59349 // the user may have assigned some options specifically for the alert
59350 var /** @type {?} */ selectOptions = deepCopy(this.selectOptions);
59351 // make sure their buttons array is removed from the options
59352 // and we create a new array for the alert's two buttons
59353 selectOptions.buttons = [{
59354 text: this.cancelText,
59355 role: 'cancel',
59356 handler: function () {
59357 _this.ionCancel.emit(_this);
59358 }
59359 }];
59360 // if the selectOptions didn't provide a title then use the label's text
59361 if (!selectOptions.title && this._item) {
59362 selectOptions.title = this._item.getLabelText();
59363 }
59364 var /** @type {?} */ options = this._options.toArray();
59365 if (this.interface === 'action-sheet' && options.length > 6) {
59366 console.warn('Interface cannot be "action-sheet" with more than 6 options. Using the "alert" interface.');
59367 this.interface = 'alert';
59368 }
59369 if ((this.interface === 'action-sheet' || this.interface === 'popover') && this._multi) {
59370 console.warn('Interface cannot be "' + this.interface + '" with a multi-value select. Using the "alert" interface.');
59371 this.interface = 'alert';
59372 }
59373 if (this.interface === 'popover' && !ev) {
59374 console.warn('Interface cannot be "popover" without UIEvent.');
59375 this.interface = 'alert';
59376 }
59377 var /** @type {?} */ overlay;
59378 if (this.interface === 'action-sheet') {
59379 selectOptions.buttons = selectOptions.buttons.concat(options.map(function (input) {
59380 return {
59381 role: (input.selected ? 'selected' : ''),
59382 text: input.text,
59383 handler: function () {
59384 _this.value = input.value;
59385 input.ionSelect.emit(input.value);
59386 }
59387 };
59388 }));
59389 var /** @type {?} */ selectCssClass = 'select-action-sheet';
59390 // If the user passed a cssClass for the select, add it
59391 selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
59392 selectOptions.cssClass = selectCssClass;
59393 overlay = new ActionSheet(this._app, selectOptions, this.config);
59394 }
59395 else if (this.interface === 'popover') {
59396 var /** @type {?} */ popoverOptions = options.map(function (input) { return ({
59397 text: input.text,
59398 checked: input.selected,
59399 disabled: input.disabled,
59400 value: input.value,
59401 handler: function () {
59402 _this.value = input.value;
59403 input.ionSelect.emit(input.value);
59404 }
59405 }); });
59406 var /** @type {?} */ popoverCssClass = 'select-popover';
59407 // If the user passed a cssClass for the select, add it
59408 popoverCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
59409 overlay = new Popover(this._app, SelectPopover, {
59410 options: popoverOptions
59411 }, {
59412 cssClass: popoverCssClass
59413 }, this.config, this.deepLinker);
59414 // ev.target is readonly.
59415 // place popover regarding to ion-select instead of .button-inner
59416 Object.defineProperty(ev, 'target', { value: ev.currentTarget });
59417 selectOptions.ev = ev;
59418 }
59419 else {
59420 // default to use the alert interface
59421 this.interface = 'alert';
59422 // user cannot provide inputs from selectOptions
59423 // alert inputs must be created by ionic from ion-options
59424 selectOptions.inputs = this._options.map(function (input) {
59425 return {
59426 type: (_this._multi ? 'checkbox' : 'radio'),
59427 label: input.text,
59428 value: input.value,
59429 checked: input.selected,
59430 disabled: input.disabled,
59431 handler: function (selectedOption) {
59432 // Only emit the select event if it is being checked
59433 // For multi selects this won't emit when unchecking
59434 if (selectedOption.checked) {
59435 input.ionSelect.emit(input.value);
59436 }
59437 }
59438 };
59439 });
59440 var /** @type {?} */ selectCssClass_1 = 'select-alert';
59441 // create the alert instance from our built up selectOptions
59442 overlay = new Alert(this._app, selectOptions, this.config);
59443 if (this._multi) {
59444 // use checkboxes
59445 selectCssClass_1 += ' multiple-select-alert';
59446 }
59447 else {
59448 // use radio buttons
59449 selectCssClass_1 += ' single-select-alert';
59450 }
59451 // If the user passed a cssClass for the select, add it
59452 selectCssClass_1 += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
59453 overlay.setCssClass(selectCssClass_1);
59454 overlay.addButton({
59455 text: this.okText,
59456 handler: function (selectedValues) { return _this.value = selectedValues; }
59457 });
59458 }
59459 overlay.present(selectOptions);
59460 this._fireFocus();
59461 overlay.onDidDismiss(function () {
59462 _this._fireBlur();
59463 _this._overlay = undefined;
59464 });
59465 this._overlay = overlay;
59466 };
59467 /**
59468 * Close the select interface.
59469 * @return {?}
59470 */
59471 Select.prototype.close = function () {
59472 if (!this._overlay || !this.isFocus()) {
59473 return;
59474 }
59475 return this._overlay.dismiss();
59476 };
59477 Object.defineProperty(Select.prototype, "multiple", {
59478 /**
59479 * \@input {boolean} If true, the element can accept multiple values.
59480 * @return {?}
59481 */
59482 get: function () {
59483 return this._multi;
59484 },
59485 /**
59486 * @param {?} val
59487 * @return {?}
59488 */
59489 set: function (val) {
59490 this._multi = isTrueProperty(val);
59491 },
59492 enumerable: true,
59493 configurable: true
59494 });
59495 Object.defineProperty(Select.prototype, "text", {
59496 /**
59497 * @hidden
59498 * @return {?}
59499 */
59500 get: function () {
59501 return (this._multi ? this._texts : this._texts.join());
59502 },
59503 enumerable: true,
59504 configurable: true
59505 });
59506 Object.defineProperty(Select.prototype, "options", {
59507 /**
59508 * @param {?} val
59509 * @return {?}
59510 */
59511 set: function (val) {
59512 this._options = val;
59513 var /** @type {?} */ values = this.getValues();
59514 if (values.length === 0) {
59515 // there are no values set at this point
59516 // so check to see who should be selected
59517 // we use writeValue() because we don't want to update ngModel
59518 this.writeValue(val.filter(function (o) { return o.selected; }).map(function (o) { return o.value; }));
59519 }
59520 else {
59521 this._updateText();
59522 }
59523 },
59524 enumerable: true,
59525 configurable: true
59526 });
59527 /**
59528 * @param {?} val
59529 * @return {?}
59530 */
59531 Select.prototype._inputShouldChange = function (val) {
59532 return !deepEqual(this._value, val);
59533 };
59534 /**
59535 * TODO: REMOVE THIS
59536 * @hidden
59537 * @return {?}
59538 */
59539 Select.prototype._inputChangeEvent = function () {
59540 return this.value;
59541 };
59542 /**
59543 * @hidden
59544 * @return {?}
59545 */
59546 Select.prototype._updateText = function () {
59547 var _this = this;
59548 this._texts.length = 0;
59549 if (this._options) {
59550 this._options.forEach(function (option) {
59551 // check this option if the option's value is in the values array
59552 option.selected = _this.getValues().some(function (selectValue) {
59553 return _this._compareWith(selectValue, option.value);
59554 });
59555 if (option.selected) {
59556 _this._texts.push(option.text);
59557 }
59558 });
59559 }
59560 this._text = this._texts.join(', ');
59561 };
59562 /**
59563 * @hidden
59564 * @return {?}
59565 */
59566 Select.prototype._inputUpdated = function () {
59567 this._updateText();
59568 _super.prototype._inputUpdated.call(this);
59569 };
59570 return Select;
59571}(BaseInput));
59572Select.decorators = [
59573 { type: Component, args: [{
59574 selector: 'ion-select',
59575 template: '<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>' +
59576 '<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>' +
59577 '<div class="select-icon">' +
59578 '<div class="select-icon-inner"></div>' +
59579 '</div>' +
59580 '<button aria-haspopup="true" ' +
59581 'type="button" ' +
59582 '[id]="id" ' +
59583 'ion-button="item-cover" ' +
59584 '[attr.aria-labelledby]="_labelId" ' +
59585 '[attr.aria-disabled]="_disabled" ' +
59586 'class="item-cover">' +
59587 '</button>',
59588 host: {
59589 '[class.select-disabled]': '_disabled'
59590 },
59591 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true }],
59592 encapsulation: ViewEncapsulation.None,
59593 },] },
59594];
59595/**
59596 * @nocollapse
59597 */
59598Select.ctorParameters = function () { return [
59599 { type: App, },
59600 { type: Form, },
59601 { type: Config, },
59602 { type: ElementRef, },
59603 { type: Renderer, },
59604 { type: Item, decorators: [{ type: Optional },] },
59605 { type: DeepLinker, },
59606]; };
59607Select.propDecorators = {
59608 'cancelText': [{ type: Input },],
59609 'okText': [{ type: Input },],
59610 'placeholder': [{ type: Input },],
59611 'selectOptions': [{ type: Input },],
59612 'interface': [{ type: Input },],
59613 'selectedText': [{ type: Input },],
59614 'compareWith': [{ type: Input },],
59615 'ionCancel': [{ type: Output },],
59616 '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
59617 '_keyup': [{ type: HostListener, args: ['keyup.space',] },],
59618 'multiple': [{ type: Input },],
59619 'options': [{ type: ContentChildren, args: [Option,] },],
59620};
59621
59622/**
59623 * @hidden
59624 */
59625var DisplayWhen = (function () {
59626 /**
59627 * @param {?} conditions
59628 * @param {?} _plt
59629 * @param {?} zone
59630 */
59631 function DisplayWhen(conditions, _plt, zone) {
59632 this._plt = _plt;
59633 this.zone = zone;
59634 this.isMatch = false;
59635 if (!conditions)
59636 return;
59637 this.conditions = conditions.replace(/\s/g, '').split(',');
59638 // check if its one of the matching platforms first
59639 // a platform does not change during the life of an app
59640 for (var i = 0; i < this.conditions.length; i++) {
59641 if (this.conditions[i] && _plt.is(this.conditions[i])) {
59642 this.isMatch = true;
59643 return;
59644 }
59645 }
59646 if (this.orientation()) {
59647 // add window resize listener
59648 this.resizeObs = _plt.resize.subscribe(this.orientation.bind(this));
59649 }
59650 }
59651 /**
59652 * @return {?}
59653 */
59654 DisplayWhen.prototype.orientation = function () {
59655 for (var /** @type {?} */ i = 0; i < this.conditions.length; i++) {
59656 if (this.conditions[i] === 'portrait') {
59657 this.isMatch = this._plt.isPortrait();
59658 return true;
59659 }
59660 if (this.conditions[i] === 'landscape') {
59661 this.isMatch = this._plt.isLandscape();
59662 return true;
59663 }
59664 }
59665 return false;
59666 };
59667 /**
59668 * @return {?}
59669 */
59670 DisplayWhen.prototype.ngOnDestroy = function () {
59671 this.resizeObs && this.resizeObs.unsubscribe();
59672 this.resizeObs = null;
59673 };
59674 return DisplayWhen;
59675}());
59676
59677var __extends$74 = (undefined && undefined.__extends) || (function () {
59678 var extendStatics = Object.setPrototypeOf ||
59679 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
59680 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
59681 return function (d, b) {
59682 extendStatics(d, b);
59683 function __() { this.constructor = d; }
59684 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
59685 };
59686})();
59687/**
59688 *
59689 * \@name ShowWhen
59690 * \@description
59691 * The `showWhen` attribute takes a string that represents a platform or screen orientation.
59692 * The element the attribute is added to will only be shown when that platform or screen orientation is active.
59693 *
59694 * Complements the [hideWhen attribute](../HideWhen). If the `showWhen` attribute is used on an
59695 * element that also has the `hideWhen` attribute, the element will not show if `hideWhen` evaluates
59696 * to `true` or `showWhen` evaluates to `false`. If the `hidden` attribute is also added, the element
59697 * will not show if `hidden` evaluates to `true`.
59698 *
59699 * View the [Platform API docs](../../../platform/Platform) for more information on the different
59700 * platforms you can use.
59701 *
59702 * \@usage
59703 * ```html
59704 * <div showWhen="android">
59705 * I am visible on Android!
59706 * </div>
59707 *
59708 * <div showWhen="ios">
59709 * I am visible on iOS!
59710 * </div>
59711 *
59712 * <div showWhen="android,ios">
59713 * I am visible on Android and iOS!
59714 * </div>
59715 *
59716 * <div showWhen="portrait">
59717 * I am visible on Portrait!
59718 * </div>
59719 *
59720 * <div showWhen="landscape">
59721 * I am visible on Landscape!
59722 * </div>
59723 * ```
59724 * \@demo /docs/demos/src/show-when/
59725 * @see {\@link ../HideWhen HideWhen API Docs}
59726 * @see {\@link ../../../platform/Platform Platform API Docs}
59727 */
59728var ShowWhen = (function (_super) {
59729 __extends$74(ShowWhen, _super);
59730 /**
59731 * @param {?} showWhen
59732 * @param {?} plt
59733 * @param {?} zone
59734 */
59735 function ShowWhen(showWhen, plt, zone) {
59736 return _super.call(this, showWhen, plt, zone) || this;
59737 }
59738 return ShowWhen;
59739}(DisplayWhen));
59740// ngOnDestroy is implemented in DisplayWhen
59741ShowWhen.decorators = [
59742 { type: Directive, args: [{
59743 selector: '[showWhen]',
59744 host: {
59745 '[class.hidden-show-when]': '!isMatch'
59746 }
59747 },] },
59748];
59749/**
59750 * @nocollapse
59751 */
59752ShowWhen.ctorParameters = function () { return [
59753 { type: undefined, decorators: [{ type: Attribute, args: ['showWhen',] },] },
59754 { type: Platform, },
59755 { type: NgZone, },
59756]; };
59757
59758var __extends$75 = (undefined && undefined.__extends) || (function () {
59759 var extendStatics = Object.setPrototypeOf ||
59760 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
59761 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
59762 return function (d, b) {
59763 extendStatics(d, b);
59764 function __() { this.constructor = d; }
59765 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
59766 };
59767})();
59768/**
59769 * \@name HideWhen
59770 * \@description
59771 * The `hideWhen` attribute takes a string that represents a plaform or screen orientation.
59772 * The element the attribute is added to will only be hidden when that platform or screen orientation is active.
59773 *
59774 * Complements the [showWhen attribute](../ShowWhen). If the `hideWhen` attribute is used on an
59775 * element that also has the `showWhen` attribute, the element will not show if `hideWhen` evaluates
59776 * to `true` or `showWhen` evaluates to `false`. If the `hidden` attribute is also added, the element
59777 * will not show if `hidden` evaluates to `true`.
59778 *
59779 * View the [Platform API docs](../../../platform/Platform) for more information on the different
59780 * platforms you can use.
59781 *
59782 * \@usage
59783 * ```html
59784 * <div hideWhen="android">
59785 * I am hidden on Android!
59786 * </div>
59787 *
59788 * <div hideWhen="ios">
59789 * I am hidden on iOS!
59790 * </div>
59791 *
59792 * <div hideWhen="android,ios">
59793 * I am hidden on Android and iOS!
59794 * </div>
59795 *
59796 * <div hideWhen="portrait">
59797 * I am hidden on Portrait!
59798 * </div>
59799 *
59800 * <div hideWhen="landscape">
59801 * I am hidden on Landscape!
59802 * </div>
59803 * ```
59804 *
59805 * \@demo /docs/demos/src/hide-when/
59806 * @see {\@link ../ShowWhen ShowWhen API Docs}
59807 * @see {\@link ../../../platform/Platform Platform API Docs}
59808 */
59809var HideWhen = (function (_super) {
59810 __extends$75(HideWhen, _super);
59811 /**
59812 * @param {?} hideWhen
59813 * @param {?} plt
59814 * @param {?} zone
59815 */
59816 function HideWhen(hideWhen, plt, zone) {
59817 return _super.call(this, hideWhen, plt, zone) || this;
59818 }
59819 return HideWhen;
59820}(DisplayWhen));
59821HideWhen.decorators = [
59822 { type: Directive, args: [{
59823 selector: '[hideWhen]',
59824 host: {
59825 '[class.hidden-hide-when]': 'isMatch'
59826 }
59827 },] },
59828];
59829/**
59830 * @nocollapse
59831 */
59832HideWhen.ctorParameters = function () { return [
59833 { type: undefined, decorators: [{ type: Attribute, args: ['hideWhen',] },] },
59834 { type: Platform, },
59835 { type: NgZone, },
59836]; };
59837
59838/**
59839 * @param {?} a
59840 * @return {?}
59841 */
59842function round(a) {
59843 return Math.floor(a);
59844}
59845/**
59846 * @param {?} ele
59847 * @param {?} styles
59848 * @return {?}
59849 */
59850function inlineStyle(ele, styles) {
59851 if (ele) {
59852 if (ele.length) {
59853 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
59854 inlineStyle(ele[i], styles);
59855 }
59856 }
59857 else if (ele.nodeType) {
59858 var /** @type {?} */ cssProps = Object.keys(styles);
59859 for (var /** @type {?} */ i_1 = 0; i_1 < cssProps.length; i_1++) {
59860 ele.style[cssProps[i_1]] = styles[cssProps[i_1]];
59861 }
59862 }
59863 }
59864}
59865/**
59866 * @param {?} ele
59867 * @param {?} className
59868 * @return {?}
59869 */
59870function addClass(ele, className) {
59871 if (ele) {
59872 if (ele.length) {
59873 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
59874 addClass(ele[i], className);
59875 }
59876 }
59877 else if (ele.nodeType) {
59878 if (Array.isArray(className)) {
59879 className.forEach(function (cls) {
59880 ele.classList.add(cls);
59881 });
59882 }
59883 else {
59884 ele.classList.add(className);
59885 }
59886 }
59887 }
59888}
59889/**
59890 * @param {?} ele
59891 * @param {?} className
59892 * @return {?}
59893 */
59894function removeClass(ele, className) {
59895 if (ele) {
59896 if (ele.length) {
59897 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
59898 removeClass(ele[i], className);
59899 }
59900 }
59901 else if (ele.nodeType) {
59902 if (Array.isArray(className)) {
59903 className.forEach(function (cls) {
59904 ele.classList.remove(cls);
59905 });
59906 }
59907 else {
59908 ele.classList.remove(className);
59909 }
59910 }
59911 }
59912}
59913/**
59914 * @param {?} ele
59915 * @return {?}
59916 */
59917function getElementIndex(ele) {
59918 var /** @type {?} */ i = 0;
59919 if (ele) {
59920 while ((ele = ele.previousSibling) !== null) {
59921 if (ele.nodeType === 1)
59922 i++;
59923 }
59924 }
59925 return i;
59926}
59927/**
59928 * @param {?} parentEle
59929 * @param {?} query
59930 * @return {?}
59931 */
59932function queryChildren(parentEle, query) {
59933 if (parentEle) {
59934 return (parentEle.querySelectorAll(query));
59935 }
59936 return [];
59937}
59938/**
59939 * @param {?} parentEle
59940 * @param {?} query
59941 * @param {?} callback
59942 * @return {?}
59943 */
59944function eachChild(parentEle, query, callback) {
59945 if (parentEle) {
59946 var /** @type {?} */ nodes = parentEle.querySelectorAll(query);
59947 for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
59948 callback(/** @type {?} */ (nodes[i]));
59949 }
59950 }
59951}
59952/**
59953 * @param {?} ele
59954 * @param {?} val
59955 * @return {?}
59956 */
59957function transform(ele, val) {
59958 if (ele) {
59959 var /** @type {?} */ elStyle = (ele.style);
59960 elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.transform = val;
59961 }
59962}
59963/**
59964 * @param {?} ele
59965 * @param {?} duration
59966 * @return {?}
59967 */
59968function transition(ele, duration) {
59969 if (ele) {
59970 if (typeof duration !== 'string') {
59971 duration = duration + 'ms';
59972 }
59973 var /** @type {?} */ elStyle = (ele.style);
59974 elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.transitionDuration = duration;
59975 }
59976}
59977/**
59978 * @param {?} plt
59979 * @param {?} ele
59980 * @return {?}
59981 */
59982function triggerTransitionEnd(plt, ele) {
59983 try {
59984 var /** @type {?} */ win = plt.win();
59985 var /** @type {?} */ evt = new win.CustomEvent('transitionend', { bubbles: true, cancelable: true });
59986 ele.dispatchEvent(evt);
59987 }
59988 catch (e) { }
59989}
59990/**
59991 * @param {?} ele
59992 * @param {?} plt
59993 * @return {?}
59994 */
59995function offset(ele, plt) {
59996 if (ele) {
59997 var /** @type {?} */ box = plt.getElementBoundingClientRect(ele);
59998 var /** @type {?} */ body = plt.doc().body;
59999 var /** @type {?} */ win = plt.win();
60000 var /** @type {?} */ clientTop = ele.clientTop || body.clientTop || 0;
60001 var /** @type {?} */ clientLeft = ele.clientLeft || body.clientLeft || 0;
60002 var /** @type {?} */ scrollTop = win.pageYOffset || ele.scrollTop;
60003 var /** @type {?} */ scrollLeft = win.pageXOffset || ele.scrollLeft;
60004 return {
60005 top: box.top + scrollTop - clientTop,
60006 left: box.left + scrollLeft - clientLeft
60007 };
60008 }
60009 return null;
60010}
60011/**
60012 * @param {?} s
60013 * @return {?}
60014 */
60015function updateSlidesOffset(s) {
60016 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60017 s._slides[i].swiperSlideOffset = isHorizontal(s) ? s._slides[i].offsetLeft : s._slides[i].offsetTop;
60018 }
60019}
60020/**
60021 * @param {?} s
60022 * @return {?}
60023 */
60024function isHorizontal(s) {
60025 return s.direction === 'horizontal';
60026}
60027var formElements = ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON', 'VIDEO'];
60028/**
60029 * @param {?} el
60030 * @return {?}
60031 */
60032function isFormElement(el) {
60033 return !!el && formElements.indexOf(el.tagName) > -1;
60034}
60035/**
60036 * @param {?} s
60037 * @return {?}
60038 */
60039function minTranslate(s) {
60040 return (-s._snapGrid[0]);
60041}
60042/**
60043 * @param {?} s
60044 * @return {?}
60045 */
60046function maxTranslate(s) {
60047 return (-s._snapGrid[s._snapGrid.length - 1]);
60048}
60049var CLS = {
60050 // Classnames
60051 noSwiping: 'swiper-no-swiping',
60052 containerModifier: 'swiper-container-',
60053 slide: 'swiper-slide',
60054 slideActive: 'swiper-slide-active',
60055 slideDuplicateActive: 'swiper-slide-duplicate-active',
60056 slideVisible: 'swiper-slide-visible',
60057 slideDuplicate: 'swiper-slide-duplicate',
60058 slideNext: 'swiper-slide-next',
60059 slideDuplicateNext: 'swiper-slide-duplicate-next',
60060 slidePrev: 'swiper-slide-prev',
60061 slideDuplicatePrev: 'swiper-slide-duplicate-prev',
60062 wrapper: 'swiper-wrapper',
60063 bullet: 'swiper-pagination-bullet',
60064 bulletActive: 'swiper-pagination-bullet-active',
60065 buttonDisabled: 'swiper-button-disabled',
60066 paginationCurrent: 'swiper-pagination-current',
60067 paginationTotal: 'swiper-pagination-total',
60068 paginationHidden: 'swiper-pagination-hidden',
60069 paginationProgressbar: 'swiper-pagination-progressbar',
60070 paginationClickable: 'swiper-pagination-clickable',
60071 paginationModifier: 'swiper-pagination-',
60072 lazyLoading: 'swiper-lazy',
60073 lazyStatusLoading: 'swiper-lazy-loading',
60074 lazyStatusLoaded: 'swiper-lazy-loaded',
60075 lazyPreloader: 'swiper-lazy-preloader',
60076 notification: 'swiper-notification',
60077 preloader: 'preloader',
60078 zoomContainer: 'swiper-zoom-container',
60079};
60080
60081/**
60082 * @param {?} s
60083 * @param {?} el
60084 * @param {?} progress
60085 * @return {?}
60086 */
60087function setParallaxTransform(s, el, progress) {
60088 var /** @type {?} */ p;
60089 var /** @type {?} */ pX;
60090 var /** @type {?} */ pY;
60091 var /** @type {?} */ rtlFactor = s._rtl ? -1 : 1;
60092 p = el.getAttribute('data-swiper-parallax') || '0';
60093 pX = el.getAttribute('data-swiper-parallax-x');
60094 pY = el.getAttribute('data-swiper-parallax-y');
60095 if (pX || pY) {
60096 pX = pX || '0';
60097 pY = pY || '0';
60098 }
60099 else {
60100 if (isHorizontal(s)) {
60101 pX = p;
60102 pY = '0';
60103 }
60104 else {
60105 pY = p;
60106 pX = '0';
60107 }
60108 }
60109 if ((pX).indexOf('%') >= 0) {
60110 pX = parseInt(pX, 10) * progress * rtlFactor + '%';
60111 }
60112 else {
60113 pX = (pX) * progress * rtlFactor + 'px';
60114 }
60115 if ((pY).indexOf('%') >= 0) {
60116 pY = parseInt(pY, 10) * progress + '%';
60117 }
60118 else {
60119 pY = (pY) * progress + 'px';
60120 }
60121 transform(el, 'translate3d(' + pX + ', ' + pY + ',0px)');
60122}
60123/**
60124 * @param {?} s
60125 * @return {?}
60126 */
60127function parallaxSetTranslate(s) {
60128 eachChild(s.container, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function (el) {
60129 setParallaxTransform(s, el, s.progress);
60130 });
60131 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60132 var /** @type {?} */ slide = s._slides[i];
60133 eachChild(slide, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function () {
60134 var /** @type {?} */ progress = Math.min(Math.max(slide.progress, -1), 1);
60135 setParallaxTransform(s, slide, progress);
60136 });
60137 }
60138}
60139/**
60140 * @param {?} s
60141 * @param {?} duration
60142 * @return {?}
60143 */
60144function parallaxSetTransition(s, duration) {
60145 if (typeof duration === 'undefined')
60146 duration = s.speed;
60147 eachChild(s.container, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function (el) {
60148 var /** @type {?} */ parallaxDuration = parseInt(el.getAttribute('data-swiper-parallax-duration'), 10) || duration;
60149 if (duration === 0)
60150 parallaxDuration = 0;
60151 transition(el, parallaxDuration);
60152 });
60153}
60154
60155/**
60156 * @param {?} s
60157 * @param {?=} translate
60158 * @return {?}
60159 */
60160function updateProgress(s, translate) {
60161 if (typeof translate === 'undefined') {
60162 translate = s._translate || 0;
60163 }
60164 var /** @type {?} */ translatesDiff = maxTranslate(s) - minTranslate(s);
60165 var /** @type {?} */ wasBeginning = s._isBeginning;
60166 var /** @type {?} */ wasEnd = s._isEnd;
60167 if (translatesDiff === 0) {
60168 s.progress = 0;
60169 s._isBeginning = s._isEnd = true;
60170 }
60171 else {
60172 s.progress = (translate - minTranslate(s)) / (translatesDiff);
60173 s._isBeginning = s.progress <= 0;
60174 s._isEnd = s.progress >= 1;
60175 }
60176 s._zone.run(function () {
60177 if (s._isBeginning && !wasBeginning) {
60178 s.ionSlideReachStart.emit();
60179 }
60180 if (s._isEnd && !wasEnd) {
60181 s.ionSlideReachEnd.emit();
60182 }
60183 if (s.watchSlidesProgress) {
60184 updateSlidesProgress(s, translate);
60185 }
60186 s.ionSlideProgress.emit(s.progress);
60187 });
60188}
60189/**
60190 * @param {?} s
60191 * @param {?} translate
60192 * @return {?}
60193 */
60194function updateSlidesProgress(s, translate) {
60195 if (typeof translate === 'undefined') {
60196 translate = s._translate || 0;
60197 }
60198 if (s._slides.length === 0)
60199 return;
60200 if (typeof s._slides[0].swiperSlideOffset === 'undefined') {
60201 updateSlidesOffset(s);
60202 }
60203 var /** @type {?} */ offsetCenter = -translate;
60204 if (s._rtl)
60205 offsetCenter = translate;
60206 // Visible Slides
60207 removeClass(s._slides, CLS.slideVisible);
60208 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60209 var /** @type {?} */ slide = s._slides[i];
60210 var /** @type {?} */ slideProgress = (offsetCenter + (s.centeredSlides ? minTranslate(s) : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.spaceBetween);
60211 if (s.watchSlidesVisibility) {
60212 var /** @type {?} */ slideBefore = -(offsetCenter - slide.swiperSlideOffset);
60213 var /** @type {?} */ slideAfter = slideBefore + s._slidesSizesGrid[i];
60214 var /** @type {?} */ isVisible = (slideBefore >= 0 && slideBefore < s._renderedSize) ||
60215 (slideAfter > 0 && slideAfter <= s._renderedSize) ||
60216 (slideBefore <= 0 && slideAfter >= s._renderedSize);
60217 if (isVisible) {
60218 s._slides[i].classList.add(CLS.slideVisible);
60219 }
60220 }
60221 slide.progress = s._rtl ? -slideProgress : slideProgress;
60222 }
60223}
60224
60225/**
60226 * @param {?} s
60227 * @param {?} plt
60228 * @return {?}
60229 */
60230
60231/**
60232 * @param {?} ele
60233 * @return {?}
60234 */
60235function makeFocusable(ele) {
60236 ele.setAttribute('tabIndex', '0');
60237}
60238/**
60239 * @param {?} ele
60240 * @param {?} role
60241 * @return {?}
60242 */
60243function addRole(ele, role) {
60244 ele.setAttribute('role', role);
60245}
60246/**
60247 * @param {?} ele
60248 * @param {?} label
60249 * @return {?}
60250 */
60251function addLabel(ele, label) {
60252 ele.setAttribute('aria-label', label);
60253}
60254/**
60255 * @param {?} ele
60256 * @param {?} isDisabled
60257 * @return {?}
60258 */
60259function ariaDisable(ele, isDisabled) {
60260 if (isDisabled) {
60261 ele.setAttribute('aria-disabled', 'true');
60262 }
60263 else if (ele.hasAttribute('aria-disabled')) {
60264 ele.removeAttribute('aria-disabled');
60265 }
60266}
60267/**
60268 * @param {?} ele
60269 * @param {?} isHidden
60270 * @return {?}
60271 */
60272function ariaHidden(ele, isHidden) {
60273 if (isHidden) {
60274 ele.setAttribute('aria-hidden', 'true');
60275 }
60276 else if (ele.hasAttribute('aria-hidden')) {
60277 ele.removeAttribute('aria-hidden');
60278 }
60279}
60280/**
60281 * @param {?} _
60282 * @param {?} __
60283 * @return {?}
60284 */
60285function onEnterKey(_, __) {
60286 // if (event.keyCode !== 13) return;
60287 // const target: HTMLElement = <any>event.target;
60288 // if (target.classList.contains(PARAMS.nextButtonClass)) {
60289 // if (s.isEnd) {
60290 // notify(s, PARAMS.lastSlideMessage);
60291 // } else {
60292 // notify(s, PARAMS.nextSlideMessage);
60293 // }
60294 // } else if (target.classList.contains(PARAMS.prevButtonClass)) {
60295 // if (s.isBeginning) {
60296 // notify(s, PARAMS.firstSlideMessage);
60297 // } else {
60298 // notify(s, PARAMS.prevSlideMessage);
60299 // }
60300 // }
60301}
60302// function notify(s: Slides, message: string) {
60303// var notification = s._liveRegion;
60304// if (notification) {
60305// notification.innerHTML = message || '';
60306// }
60307// }
60308
60309/**
60310 * @param {?} s
60311 * @return {?}
60312 */
60313function updatePagination(s) {
60314 if (!s.paginationType || !s._paginationContainer)
60315 return;
60316 var /** @type {?} */ paginationHTML = '';
60317 if (s.paginationType === 'bullets') {
60318 var /** @type {?} */ numberOfBullets = s.loop ? Math.ceil((s._slides.length - s.loopedSlides * 2) / s.slidesPerGroup) : s._snapGrid.length;
60319 for (var /** @type {?} */ i = 0; i < numberOfBullets; i++) {
60320 if (s.paginationBulletRender) {
60321 paginationHTML += s.paginationBulletRender(i, CLS.bullet);
60322 }
60323 else {
60324 paginationHTML += "<button class=\"" + CLS.bullet + "\" aria-label=\"Go to slide " + (i + 1) + "\" data-slide-index=\"" + i + "\"></button>";
60325 }
60326 }
60327 }
60328 else if (s.paginationType === 'fraction') {
60329 paginationHTML =
60330 '<span class="' + CLS.paginationCurrent + '"></span>' +
60331 ' / ' +
60332 '<span class="' + CLS.paginationTotal + '"></span>';
60333 }
60334 else if (s.paginationType === 'progress') {
60335 paginationHTML = '<span class="' + CLS.paginationProgressbar + '"></span>';
60336 }
60337 s._paginationContainer.innerHTML = paginationHTML;
60338 s._bullets = (s._paginationContainer.querySelectorAll('.' + CLS.bullet));
60339}
60340/**
60341 * @param {?} s
60342 * @return {?}
60343 */
60344function updatePaginationClasses(s) {
60345 // Current/Total
60346 var /** @type {?} */ current;
60347 var /** @type {?} */ total = s.loop ? Math.ceil((s._slides.length - s.loopedSlides * 2) / s.slidesPerGroup) : s._snapGrid.length;
60348 if (s.loop) {
60349 current = Math.ceil((s._activeIndex - s.loopedSlides) / s.slidesPerGroup);
60350 if (current > s._slides.length - 1 - s.loopedSlides * 2) {
60351 current = current - (s._slides.length - s.loopedSlides * 2);
60352 }
60353 if (current > total - 1) {
60354 current = current - total;
60355 }
60356 if (current < 0 && s.paginationType !== 'bullets') {
60357 current = total + current;
60358 }
60359 }
60360 else {
60361 if (typeof s._snapIndex !== 'undefined') {
60362 current = s._snapIndex;
60363 }
60364 else {
60365 current = s._activeIndex || 0;
60366 }
60367 }
60368 // Types
60369 if (s.paginationType === 'bullets' && s._bullets) {
60370 var /** @type {?} */ selector = current + (current < 0 ? s._bullets.length : 0);
60371 for (var /** @type {?} */ i = 0; i < s._bullets.length; i++) {
60372 if (i === selector) {
60373 addClass(s._bullets[i], CLS.bulletActive);
60374 }
60375 else {
60376 removeClass(s._bullets[i], CLS.bulletActive);
60377 }
60378 }
60379 }
60380 if (s.paginationType === 'fraction') {
60381 eachChild(s._paginationContainer, '.' + CLS.paginationCurrent, function (ele) {
60382 ele.textContent = ((current + 1));
60383 });
60384 eachChild(s._paginationContainer, '.' + CLS.paginationTotal, function (ele) {
60385 ele.textContent = total;
60386 });
60387 }
60388 if (s.paginationType === 'progress') {
60389 var /** @type {?} */ scale = (current + 1) / total, /** @type {?} */ scaleX = scale, /** @type {?} */ scaleY = 1;
60390 if (!isHorizontal(s)) {
60391 scaleY = scale;
60392 scaleX = 1;
60393 }
60394 eachChild(s._paginationContainer, '.' + CLS.paginationProgressbar, function (ele) {
60395 transform(ele, 'translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')');
60396 transition(ele, s.speed);
60397 });
60398 }
60399}
60400
60401/**
60402 * @param {?} s
60403 * @return {?}
60404 */
60405function updateClasses(s) {
60406 var /** @type {?} */ childElements;
60407 removeClass(s._slides, [CLS.slideActive, CLS.slideNext, CLS.slidePrev, CLS.slideDuplicateActive, CLS.slideDuplicateNext, CLS.slideDuplicatePrev]);
60408 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60409 ariaHidden(s._slides[i], true);
60410 }
60411 var /** @type {?} */ activeSlide = s._slides[s._activeIndex];
60412 if (!activeSlide) {
60413 return;
60414 }
60415 // Active classes
60416 addClass(activeSlide, CLS.slideActive);
60417 ariaHidden(activeSlide, false);
60418 if (s.loop) {
60419 // Duplicate to all looped slides
60420 if (activeSlide.classList.contains(CLS.slideDuplicate)) {
60421 childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + s.realIndex + '"]');
60422 }
60423 else {
60424 childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + s.realIndex + '"]');
60425 }
60426 addClass(childElements, CLS.slideDuplicateActive);
60427 }
60428 // Next Slide
60429 var /** @type {?} */ nextSlide = activeSlide.nextElementSibling;
60430 if (s.loop && !nextSlide) {
60431 nextSlide = s._slides[0];
60432 }
60433 nextSlide && nextSlide.classList.add(CLS.slideNext);
60434 // Prev Slide
60435 var /** @type {?} */ prevSlide = activeSlide.previousElementSibling;
60436 if (s.loop && !prevSlide) {
60437 prevSlide = s._slides[s._slides.length - 1];
60438 }
60439 prevSlide && prevSlide.classList.add(CLS.slidePrev);
60440 if (s.loop) {
60441 // Duplicate to all looped slides
60442 if (nextSlide.classList.contains(CLS.slideDuplicate)) {
60443 childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + nextSlide.getAttribute('data-swiper-slide-index') + '"]');
60444 }
60445 else {
60446 childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + nextSlide.getAttribute('data-swiper-slide-index') + '"]');
60447 }
60448 addClass(childElements, CLS.slideDuplicateNext);
60449 if (prevSlide.classList.contains(CLS.slideDuplicate)) {
60450 childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + prevSlide.getAttribute('data-swiper-slide-index') + '"]');
60451 }
60452 else {
60453 childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + prevSlide.getAttribute('data-swiper-slide-index') + '"]');
60454 }
60455 addClass(childElements, CLS.slideDuplicatePrev);
60456 }
60457 // Pagination
60458 if (s._paginationContainer) {
60459 updatePaginationClasses(s);
60460 }
60461 // Next/active buttons
60462 if (!s.loop) {
60463 if (s.prevButton) {
60464 if (s._isBeginning) {
60465 s.prevButton.classList.add(CLS.buttonDisabled);
60466 ariaDisable(s.prevButton, true);
60467 }
60468 else {
60469 s.prevButton.classList.remove(CLS.buttonDisabled);
60470 ariaDisable(s.prevButton, false);
60471 }
60472 }
60473 if (s.nextButton) {
60474 if (s._isEnd) {
60475 s.nextButton.classList.add(CLS.buttonDisabled);
60476 ariaDisable(s.nextButton, true);
60477 }
60478 else {
60479 s.nextButton.classList.remove(CLS.buttonDisabled);
60480 ariaDisable(s.nextButton, false);
60481 }
60482 }
60483 }
60484}
60485
60486/**
60487 * @param {?} s
60488 * @return {?}
60489 */
60490function updateActiveIndex(s) {
60491 var /** @type {?} */ translate = s._rtl ? s._translate : -s._translate;
60492 var /** @type {?} */ newActiveIndex;
60493 var /** @type {?} */ i;
60494 var /** @type {?} */ snapIndex;
60495 for (i = 0; i < s._slidesGrid.length; i++) {
60496 if (typeof s._slidesGrid[i + 1] !== 'undefined') {
60497 if (translate >= s._slidesGrid[i] && translate < s._slidesGrid[i + 1] - (s._slidesGrid[i + 1] - s._slidesGrid[i]) / 2) {
60498 newActiveIndex = i;
60499 }
60500 else if (translate >= s._slidesGrid[i] && translate < s._slidesGrid[i + 1]) {
60501 newActiveIndex = i + 1;
60502 }
60503 }
60504 else {
60505 if (translate >= s._slidesGrid[i]) {
60506 newActiveIndex = i;
60507 }
60508 }
60509 }
60510 snapIndex = Math.floor(newActiveIndex / s.slidesPerGroup);
60511 if (snapIndex >= s._snapGrid.length)
60512 snapIndex = s._snapGrid.length - 1;
60513 if (newActiveIndex === s._activeIndex) {
60514 return;
60515 }
60516 s._snapIndex = snapIndex;
60517 s._previousIndex = s._activeIndex;
60518 s._activeIndex = newActiveIndex;
60519 updateClasses(s);
60520 updateRealIndex(s);
60521}
60522/**
60523 * @param {?} s
60524 * @return {?}
60525 */
60526function updateRealIndex(s) {
60527 var /** @type {?} */ activeSlide = (s._slides[s._activeIndex]);
60528 if (activeSlide) {
60529 s.realIndex = parseInt(activeSlide.getAttribute('data-swiper-slide-index') || s._activeIndex, 10);
60530 }
60531}
60532
60533/*=========================
60534 Controller
60535 ===========================*/
60536var SWIPER_CONTROLLER = {
60537 LinearSpline: function (_s, _platform, x, y) {
60538 this.x = x;
60539 this.y = y;
60540 this.lastIndex = x.length - 1;
60541 // Given an x value (x2), return the expected y2 value:
60542 // (x1,y1) is the known point before given value,
60543 // (x3,y3) is the known point after given value.
60544 var /** @type {?} */ i1, /** @type {?} */ i3;
60545 this.interpolate = function (x2) {
60546 if (!x2)
60547 return 0;
60548 // Get the indexes of x1 and x3 (the array indexes before and after given x2):
60549 i3 = binarySearch(this.x, x2);
60550 i1 = i3 - 1;
60551 // We have our indexes i1 & i3, so we can calculate already:
60552 // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
60553 return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
60554 };
60555 var /** @type {?} */ binarySearch = (function () {
60556 var /** @type {?} */ maxIndex, /** @type {?} */ minIndex, /** @type {?} */ guess;
60557 return function (array, val) {
60558 minIndex = -1;
60559 maxIndex = array.length;
60560 while (maxIndex - minIndex > 1)
60561 if (array[guess = maxIndex + minIndex >> 1] <= val) {
60562 minIndex = guess;
60563 }
60564 else {
60565 maxIndex = guess;
60566 }
60567 return maxIndex;
60568 };
60569 })();
60570 },
60571 // xxx: for now i will just save one spline function to to
60572 getInterpolateFunction: function (s, plt, c) {
60573 if (!s._spline)
60574 s._spline = s.loop ?
60575 new ((SWIPER_CONTROLLER)).LinearSpline(s, plt, s._slidesGrid, c._slidesGrid) :
60576 new ((SWIPER_CONTROLLER)).LinearSpline(s, plt, s._snapGrid, c._snapGrid);
60577 },
60578 setTranslate: function (s, plt, translate, byController, setWrapperTranslate) {
60579 var /** @type {?} */ controlled = s.control;
60580 var /** @type {?} */ multiplier, /** @type {?} */ controlledTranslate;
60581 /**
60582 * @param {?} c
60583 * @return {?}
60584 */
60585 function setControlledTranslate(c) {
60586 // this will create an Interpolate function based on the snapGrids
60587 // x is the Grid of the scrolled scroller and y will be the controlled scroller
60588 // it makes sense to create this only once and recall it for the interpolation
60589 // the function does a lot of value caching for performance
60590 translate = c._rtl && isHorizontal(c) ? -s._translate : s._translate;
60591 if (s.controlBy === 'slide') {
60592 SWIPER_CONTROLLER.getInterpolateFunction(s, plt, c);
60593 // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
60594 // but it did not work out
60595 controlledTranslate = -s._spline.interpolate(-translate);
60596 }
60597 if (!controlledTranslate || s.controlBy === 'container') {
60598 multiplier = (maxTranslate(c) - minTranslate(c)) / (maxTranslate(s) - minTranslate(s));
60599 controlledTranslate = (translate - minTranslate(s)) * multiplier + minTranslate(c);
60600 }
60601 if (s.controlInverse) {
60602 controlledTranslate = maxTranslate(c) - controlledTranslate;
60603 }
60604 updateProgress(c, controlledTranslate);
60605 setWrapperTranslate(c, plt, controlledTranslate, false, s);
60606 updateActiveIndex(c);
60607 }
60608 if (Array.isArray(controlled)) {
60609 for (var /** @type {?} */ i = 0; i < controlled.length; i++) {
60610 if (controlled[i] !== byController) {
60611 setControlledTranslate(controlled[i]);
60612 }
60613 }
60614 }
60615 else if (byController !== controlled) {
60616 setControlledTranslate(controlled);
60617 }
60618 },
60619 setTransition: function (s, plt, duration, byController, setWrapperTransition) {
60620 var /** @type {?} */ controlled = s.control;
60621 var /** @type {?} */ i;
60622 /**
60623 * @param {?} c
60624 * @return {?}
60625 */
60626 function setControlledTransition(c) {
60627 setWrapperTransition(c, plt, duration, s);
60628 if (duration !== 0) {
60629 onTransitionStart(c);
60630 plt.transitionEnd(c._wrapper, function () {
60631 if (!controlled)
60632 return;
60633 if (c.loop && s.controlBy === 'slide') {
60634 fixLoop(c, plt);
60635 }
60636 onTransitionEnd(c, plt);
60637 });
60638 }
60639 }
60640 if (Array.isArray(controlled)) {
60641 for (i = 0; i < controlled.length; i++) {
60642 if (controlled[i] !== byController) {
60643 setControlledTransition(controlled[i]);
60644 }
60645 }
60646 }
60647 else if (byController !== controlled) {
60648 setControlledTransition(controlled);
60649 }
60650 }
60651};
60652
60653/**
60654 * @param {?} plt
60655 * @return {?}
60656 */
60657function isCordova(plt) {
60658 var /** @type {?} */ win = plt.win();
60659 return !!(win['cordova'] || win['PhoneGap'] || win['phonegap']);
60660}
60661/**
60662 * @param {?} plt
60663 * @return {?}
60664 */
60665function isElectron(plt) {
60666 return plt.testUserAgent('Electron');
60667}
60668/**
60669 * @param {?} plt
60670 * @return {?}
60671 */
60672function isIos(plt) {
60673 // shortcut function to be reused internally
60674 // checks navigator.platform to see if it's an actual iOS device
60675 // this does not use the user-agent string because it is often spoofed
60676 // an actual iPad will return true, a chrome dev tools iPad will return false
60677 return plt.testNavigatorPlatform('iphone|ipad|ipod');
60678}
60679/**
60680 * @param {?} plt
60681 * @return {?}
60682 */
60683function isSafari(plt) {
60684 return plt.testUserAgent('Safari');
60685}
60686/**
60687 * @param {?} plt
60688 * @return {?}
60689 */
60690function isWKWebView(plt) {
60691 return isIos(plt) && !!((plt.win()))['webkit'];
60692}
60693/**
60694 * @param {?} plt
60695 * @return {?}
60696 */
60697function isIosUIWebView(plt) {
60698 return isIos(plt) && !isWKWebView(plt) && !isSafari(plt);
60699}
60700
60701/*=========================
60702 Effects
60703 ===========================*/
60704var SWIPER_EFFECTS = {
60705 'fade': {
60706 setTranslate: function (s) {
60707 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60708 var /** @type {?} */ slide = s._slides[i];
60709 var /** @type {?} */ offset$$1 = slide.swiperSlideOffset;
60710 var /** @type {?} */ tx = -offset$$1;
60711 if (!s.virtualTranslate) {
60712 tx = tx - s._translate;
60713 }
60714 var /** @type {?} */ ty = 0;
60715 if (!isHorizontal(s)) {
60716 ty = tx;
60717 tx = 0;
60718 }
60719 var /** @type {?} */ slideOpacity = s.fade.crossFade ?
60720 Math.max(1 - Math.abs(slide.progress), 0) :
60721 1 + Math.min(Math.max(slide.progress, -1), 0);
60722 slide.style.opacity = (slideOpacity);
60723 transform(slide, 'translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
60724 }
60725 },
60726 setTransition: function (s, plt, duration) {
60727 var /** @type {?} */ slides = s._slides;
60728 for (var /** @type {?} */ i = 0; i < slides.length; i++) {
60729 transition(slides[i], duration);
60730 }
60731 if (s.virtualTranslate && duration !== 0) {
60732 var /** @type {?} */ eventTriggered = false;
60733 for (var /** @type {?} */ i_1 = 0; i_1 < slides.length; i_1++) {
60734 plt.transitionEnd(slides[i_1], function () {
60735 if (eventTriggered || !s)
60736 return;
60737 eventTriggered = true;
60738 s._animating = false;
60739 triggerTransitionEnd(plt, s._wrapper);
60740 });
60741 }
60742 }
60743 }
60744 },
60745 'flip': {
60746 setTranslate: function (s, plt) {
60747 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60748 var /** @type {?} */ slide = s._slides[i];
60749 var /** @type {?} */ progress = slide.progress;
60750 if (s.flip.limitRotation) {
60751 progress = Math.max(Math.min(slide.progress, 1), -1);
60752 }
60753 var /** @type {?} */ offset$$1 = slide.swiperSlideOffset;
60754 var /** @type {?} */ rotate = -180 * progress, /** @type {?} */ rotateY = rotate, /** @type {?} */ rotateX = 0, /** @type {?} */ tx = -offset$$1, /** @type {?} */ ty = 0;
60755 if (!isHorizontal(s)) {
60756 ty = tx;
60757 tx = 0;
60758 rotateX = -rotateY;
60759 rotateY = 0;
60760 }
60761 else if (s._rtl) {
60762 rotateY = -rotateY;
60763 }
60764 slide.style.zIndex = (-Math.abs(Math.round(progress))) + s._slides.length;
60765 if (s.flip.slideShadows) {
60766 // Set shadows
60767 var /** @type {?} */ shadowBefore = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top')));
60768 var /** @type {?} */ shadowAfter = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom')));
60769 if (!shadowBefore) {
60770 shadowBefore = plt.doc().createElement('div');
60771 shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
60772 slide.appendChild(shadowBefore);
60773 }
60774 if (!shadowAfter) {
60775 shadowAfter = plt.doc().createElement('div');
60776 shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
60777 slide.appendChild(shadowAfter);
60778 }
60779 if (shadowBefore) {
60780 shadowBefore.style.opacity = (Math.max(-progress, 0));
60781 }
60782 if (shadowAfter) {
60783 shadowAfter.style.opacity = (Math.max(progress, 0));
60784 }
60785 }
60786 transform(slide, 'translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');
60787 }
60788 },
60789 setTransition: function (s, plt, duration) {
60790 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60791 var /** @type {?} */ slide = s._slides[i];
60792 transition(slide, duration);
60793 eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
60794 transition(el, duration);
60795 });
60796 }
60797 if (s.virtualTranslate && duration !== 0) {
60798 var /** @type {?} */ eventTriggered = false;
60799 plt.transitionEnd(s._slides[s._activeIndex], function (ev) {
60800 if (eventTriggered || !s)
60801 return;
60802 if (!((ev.target)).classList.contains(CLS.slideActive)) {
60803 return;
60804 }
60805 eventTriggered = true;
60806 s._animating = false;
60807 triggerTransitionEnd(plt, s._wrapper);
60808 });
60809 }
60810 }
60811 },
60812 'cube': {
60813 setTranslate: function (s, plt) {
60814 var /** @type {?} */ wrapperRotate = 0;
60815 var /** @type {?} */ cubeShadow;
60816 if (s.cube.shadow) {
60817 if (isHorizontal(s)) {
60818 cubeShadow = (s._wrapper.querySelector('.swiper-cube-shadow'));
60819 if (!cubeShadow) {
60820 cubeShadow = plt.doc().createElement('div');
60821 cubeShadow.className = 'swiper-cube-shadow';
60822 s._wrapper.appendChild(cubeShadow);
60823 }
60824 cubeShadow.style.height = s.renderedWidth + 'px';
60825 }
60826 else {
60827 cubeShadow = (s.container.querySelector('.swiper-cube-shadow'));
60828 if (!cubeShadow) {
60829 cubeShadow = plt.doc().createElement('div');
60830 cubeShadow.className = 'swiper-cube-shadow';
60831 s._wrapper.appendChild(cubeShadow);
60832 }
60833 }
60834 }
60835 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60836 var /** @type {?} */ slide = s._slides[i];
60837 var /** @type {?} */ slideAngle = i * 90;
60838 var /** @type {?} */ round$$1 = Math.floor(slideAngle / 360);
60839 if (s._rtl) {
60840 slideAngle = -slideAngle;
60841 round$$1 = Math.floor(-slideAngle / 360);
60842 }
60843 var /** @type {?} */ progress = Math.max(Math.min(slide.progress, 1), -1);
60844 var /** @type {?} */ tx = 0, /** @type {?} */ ty = 0, /** @type {?} */ tz = 0;
60845 if (i % 4 === 0) {
60846 tx = -round$$1 * 4 * s._renderedSize;
60847 tz = 0;
60848 }
60849 else if ((i - 1) % 4 === 0) {
60850 tx = 0;
60851 tz = -round$$1 * 4 * s._renderedSize;
60852 }
60853 else if ((i - 2) % 4 === 0) {
60854 tx = s._renderedSize + round$$1 * 4 * s._renderedSize;
60855 tz = s._renderedSize;
60856 }
60857 else if ((i - 3) % 4 === 0) {
60858 tx = -s._renderedSize;
60859 tz = 3 * s._renderedSize + s._renderedSize * 4 * round$$1;
60860 }
60861 if (s._rtl) {
60862 tx = -tx;
60863 }
60864 if (!isHorizontal(s)) {
60865 ty = tx;
60866 tx = 0;
60867 }
60868 var /** @type {?} */ transformStr = 'rotateX(' + (isHorizontal(s) ? 0 : -slideAngle) + 'deg) rotateY(' + (isHorizontal(s) ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
60869 if (progress <= 1 && progress > -1) {
60870 wrapperRotate = i * 90 + progress * 90;
60871 if (s._rtl)
60872 wrapperRotate = -i * 90 - progress * 90;
60873 }
60874 transform(slide, transformStr);
60875 if (s.cube.slideShadows) {
60876 // Set shadows
60877 var /** @type {?} */ shadowBefore = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top')));
60878 var /** @type {?} */ shadowAfter = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom')));
60879 if (!shadowBefore) {
60880 shadowBefore = plt.doc().createElement('div');
60881 shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
60882 slide.appendChild(shadowBefore);
60883 }
60884 if (!shadowAfter) {
60885 shadowAfter = plt.doc().createElement('div');
60886 shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
60887 slide.appendChild(shadowAfter);
60888 }
60889 if (shadowBefore)
60890 shadowBefore.style.opacity = (Math.max(-progress, 0));
60891 if (shadowAfter)
60892 shadowAfter.style.opacity = (Math.max(progress, 0));
60893 }
60894 }
60895 s._wrapper.style.transformOrigin = s._wrapper.style.webkitTransformOrigin = '50% 50% -' + (s._renderedSize / 2) + 'px';
60896 if (s.cube.shadow) {
60897 if (isHorizontal(s)) {
60898 transform(cubeShadow, 'translate3d(0px, ' + (s.renderedWidth / 2 + s.cube.shadowOffset) + 'px, ' + (-s.renderedWidth / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.cube.shadowScale) + ')');
60899 }
60900 else {
60901 var /** @type {?} */ shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
60902 var /** @type {?} */ multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
60903 var /** @type {?} */ scale1 = s.cube.shadowScale;
60904 var /** @type {?} */ scale2 = s.cube.shadowScale / multiplier;
60905 var /** @type {?} */ offset$$1 = s.cube.shadowOffset;
60906 transform(cubeShadow, 'scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.renderedHeight / 2 + offset$$1) + 'px, ' + (-s.renderedHeight / 2 / scale2) + 'px) rotateX(-90deg)');
60907 }
60908 }
60909 var /** @type {?} */ zFactor = (isSafari(plt) || isIosUIWebView(plt)) ? (-s._renderedSize / 2) : 0;
60910 transform(s._wrapper, 'translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isHorizontal(s) ? 0 : wrapperRotate) + 'deg) rotateY(' + (isHorizontal(s) ? -wrapperRotate : 0) + 'deg)');
60911 },
60912 setTransition: function (s, _plt, duration) {
60913 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60914 var /** @type {?} */ slide = s._slides[i];
60915 transition(slide, duration);
60916 eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
60917 transition(el, duration);
60918 });
60919 }
60920 if (s.cube.shadow && !isHorizontal(s)) {
60921 eachChild(s.container, '.swiper-cube-shadow', function (el) {
60922 transition(el, duration);
60923 });
60924 }
60925 }
60926 },
60927 'coverflow': {
60928 setTranslate: function (s, plt) {
60929 var /** @type {?} */ transformStr = s._translate;
60930 var /** @type {?} */ center = isHorizontal(s) ? -transformStr + s.renderedWidth / 2 : -transformStr + s.renderedHeight / 2;
60931 var /** @type {?} */ rotate = isHorizontal(s) ? s.coverflow.rotate : -s.coverflow.rotate;
60932 var /** @type {?} */ translate = s.coverflow.depth;
60933 // Each slide offset from center
60934 for (var /** @type {?} */ i = 0, /** @type {?} */ length = s._slides.length; i < length; i++) {
60935 var /** @type {?} */ slide = s._slides[i];
60936 var /** @type {?} */ slideSize = s._slidesSizesGrid[i];
60937 var /** @type {?} */ slideOffset = slide.swiperSlideOffset;
60938 var /** @type {?} */ offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.coverflow.modifier;
60939 var /** @type {?} */ rotateY = isHorizontal(s) ? rotate * offsetMultiplier : 0;
60940 var /** @type {?} */ rotateX = isHorizontal(s) ? 0 : rotate * offsetMultiplier;
60941 // var rotateZ = 0
60942 var /** @type {?} */ translateZ = -translate * Math.abs(offsetMultiplier);
60943 var /** @type {?} */ translateY = isHorizontal(s) ? 0 : s.coverflow.stretch * (offsetMultiplier);
60944 var /** @type {?} */ translateX = isHorizontal(s) ? s.coverflow.stretch * (offsetMultiplier) : 0;
60945 // Fix for ultra small values
60946 if (Math.abs(translateX) < 0.001)
60947 translateX = 0;
60948 if (Math.abs(translateY) < 0.001)
60949 translateY = 0;
60950 if (Math.abs(translateZ) < 0.001)
60951 translateZ = 0;
60952 if (Math.abs(rotateY) < 0.001)
60953 rotateY = 0;
60954 if (Math.abs(rotateX) < 0.001)
60955 rotateX = 0;
60956 var /** @type {?} */ slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
60957 transform(slide, slideTransform);
60958 slide.style.zIndex = (-Math.abs(Math.round(offsetMultiplier))) + 1;
60959 if (s.coverflow.slideShadows) {
60960 // Set shadows
60961 var /** @type {?} */ shadowBefore = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top')));
60962 var /** @type {?} */ shadowAfter = ((isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom')));
60963 if (!shadowBefore) {
60964 shadowBefore = plt.doc().createElement('div');
60965 shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
60966 slide.appendChild(shadowBefore);
60967 }
60968 if (!shadowAfter) {
60969 shadowAfter = plt.doc().createElement('div');
60970 shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
60971 slide.appendChild(shadowAfter);
60972 }
60973 if (shadowBefore) {
60974 shadowBefore.style.opacity = ((offsetMultiplier > 0 ? offsetMultiplier : 0));
60975 }
60976 if (shadowAfter) {
60977 shadowAfter.style.opacity = (((-offsetMultiplier) > 0 ? -offsetMultiplier : 0));
60978 }
60979 }
60980 }
60981 },
60982 setTransition: function (s, _plt, duration) {
60983 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
60984 var /** @type {?} */ slide = s._slides[i];
60985 transition(slide, duration);
60986 eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
60987 transition(el, duration);
60988 });
60989 }
60990 }
60991 }
60992};
60993
60994/**
60995 * @param {?} s
60996 * @param {?} plt
60997 * @param {?} translate
60998 * @param {?=} shouldUpdateActiveIndex
60999 * @param {?=} byController
61000 * @return {?}
61001 */
61002function setWrapperTranslate(s, plt, translate, shouldUpdateActiveIndex, byController) {
61003 var /** @type {?} */ x = 0, /** @type {?} */ y = 0, /** @type {?} */ z = 0;
61004 if (isHorizontal(s)) {
61005 x = s._rtl ? -translate : translate;
61006 }
61007 else {
61008 y = translate;
61009 }
61010 if (s.roundLengths) {
61011 x = round(x);
61012 y = round(y);
61013 }
61014 if (!s.virtualTranslate) {
61015 transform(s._wrapper, 'translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
61016 }
61017 s._translate = isHorizontal(s) ? x : y;
61018 // Check if we need to update progress
61019 var /** @type {?} */ progress;
61020 var /** @type {?} */ translatesDiff = maxTranslate(s) - minTranslate(s);
61021 if (translatesDiff === 0) {
61022 progress = 0;
61023 }
61024 else {
61025 progress = (translate - minTranslate(s)) / (translatesDiff);
61026 }
61027 if (progress !== s.progress) {
61028 updateProgress(s, translate);
61029 }
61030 if (shouldUpdateActiveIndex) {
61031 updateActiveIndex(s);
61032 }
61033 if (s.effect !== 'slide' && SWIPER_EFFECTS[s.effect]) {
61034 SWIPER_EFFECTS[s.effect].setTranslate(s, plt);
61035 }
61036 if (s.parallax) {
61037 parallaxSetTranslate(s);
61038 }
61039 if (s.control) {
61040 SWIPER_CONTROLLER.setTranslate(s, plt, s._translate, byController, setWrapperTranslate);
61041 }
61042}
61043/**
61044 * @param {?} s
61045 * @param {?} plt
61046 * @param {?} el
61047 * @param {?} axis
61048 * @return {?}
61049 */
61050function getTranslate(s, plt, el, axis) {
61051 var /** @type {?} */ win = plt.win();
61052 var /** @type {?} */ matrix;
61053 var /** @type {?} */ curTransform;
61054 var /** @type {?} */ curStyle;
61055 var /** @type {?} */ transformMatrix;
61056 // automatic axis detection
61057 if (typeof axis === 'undefined') {
61058 axis = 'x';
61059 }
61060 if (s.virtualTranslate) {
61061 return s._rtl ? -s._translate : s._translate;
61062 }
61063 curStyle = plt.getElementComputedStyle(el);
61064 if (win.WebKitCSSMatrix) {
61065 curTransform = curStyle.transform || curStyle.webkitTransform;
61066 if (curTransform.split(',').length > 6) {
61067 curTransform = curTransform.split(', ').map(function (a) {
61068 return a.replace(',', '.');
61069 }).join(', ');
61070 }
61071 // Some old versions of Webkit choke when 'none' is passed; pass
61072 // empty string instead in this case
61073 transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
61074 }
61075 else {
61076 transformMatrix = ((curStyle)).MozTransform || ((curStyle)).OTransform || ((curStyle)).MsTransform || ((curStyle)).msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
61077 matrix = transformMatrix.toString().split(',');
61078 }
61079 if (axis === 'x') {
61080 if (win.WebKitCSSMatrix) {
61081 // Latest Chrome and webkits Fix
61082 curTransform = (transformMatrix.m41);
61083 }
61084 else if (matrix.length === 16) {
61085 // Crazy IE10 Matrix
61086 curTransform = parseFloat(matrix[12]);
61087 }
61088 else {
61089 // Normal Browsers
61090 curTransform = parseFloat(matrix[4]);
61091 }
61092 }
61093 if (axis === 'y') {
61094 if (win.WebKitCSSMatrix) {
61095 // Latest Chrome and webkits Fix
61096 curTransform = transformMatrix.m42;
61097 }
61098 else if (matrix.length === 16) {
61099 // Crazy IE10 Matrix
61100 curTransform = parseFloat(matrix[13]);
61101 }
61102 else {
61103 // Normal Browsers
61104 curTransform = parseFloat(matrix[5]);
61105 }
61106 }
61107 if (s._rtl && curTransform) {
61108 curTransform = -curTransform;
61109 }
61110 return curTransform || 0;
61111}
61112/**
61113 * @param {?} s
61114 * @param {?} plt
61115 * @param {?=} axis
61116 * @return {?}
61117 */
61118function getWrapperTranslate(s, plt, axis) {
61119 if (typeof axis === 'undefined') {
61120 axis = isHorizontal(s) ? 'x' : 'y';
61121 }
61122 return getTranslate(s, plt, s._wrapper, axis);
61123}
61124/**
61125 * @param {?} s
61126 * @param {?} plt
61127 * @param {?} duration
61128 * @param {?=} byController
61129 * @return {?}
61130 */
61131function setWrapperTransition(s, plt, duration, byController) {
61132 transition(s._wrapper, duration);
61133 if (s.effect !== 'slide' && SWIPER_EFFECTS[s.effect]) {
61134 SWIPER_EFFECTS[s.effect].setTransition(s, plt, duration);
61135 }
61136 if (s.parallax) {
61137 parallaxSetTransition(s, duration);
61138 }
61139 if (s.control) {
61140 SWIPER_CONTROLLER.setTransition(s, plt, duration, byController, setWrapperTransition);
61141 }
61142}
61143
61144/**
61145 * @param {?} s
61146 * @param {?} plt
61147 * @return {?}
61148 */
61149function initZoom(s, plt) {
61150 s._supportGestures = ('ongesturestart' in plt.win());
61151 s._zoom = {
61152 // "Global" Props
61153 scale: 1,
61154 currentScale: 1,
61155 isScaling: false,
61156 gesture: {
61157 slide: undefined,
61158 slideWidth: undefined,
61159 slideHeight: undefined,
61160 image: undefined,
61161 imageWrap: undefined,
61162 zoomMax: s.zoomMax
61163 },
61164 image: {
61165 isTouched: undefined,
61166 isMoved: undefined,
61167 currentX: undefined,
61168 currentY: undefined,
61169 minX: undefined,
61170 minY: undefined,
61171 maxX: undefined,
61172 maxY: undefined,
61173 width: undefined,
61174 height: undefined,
61175 startX: undefined,
61176 startY: undefined,
61177 touchesStart: {},
61178 touchesCurrent: {}
61179 },
61180 velocity: {
61181 x: undefined,
61182 y: undefined,
61183 prevPositionX: undefined,
61184 prevPositionY: undefined,
61185 prevTime: undefined
61186 },
61187 unRegs: []
61188 };
61189 resetZoomEvents(s, plt);
61190 return function () {
61191 detachZoomEvents(s);
61192 };
61193}
61194/**
61195 * @param {?} ev
61196 * @return {?}
61197 */
61198function getDistanceBetweenTouches(ev) {
61199 if (ev.targetTouches.length < 2)
61200 return 1;
61201 var /** @type {?} */ x1 = ev.targetTouches[0].pageX, /** @type {?} */ y1 = ev.targetTouches[0].pageY, /** @type {?} */ x2 = ev.targetTouches[1].pageX, /** @type {?} */ y2 = ev.targetTouches[1].pageY;
61202 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
61203}
61204/**
61205 * @param {?} s
61206 * @param {?} _plt
61207 * @param {?} ev
61208 * @return {?}
61209 */
61210function onGestureStart(s, _plt, ev) {
61211 var /** @type {?} */ z = s._zoom;
61212 s.originalEvent = ev;
61213 if (!s._supportGestures) {
61214 if (ev.type !== 'touchstart' || ev.type === 'touchstart' && ev.targetTouches.length < 2) {
61215 return;
61216 }
61217 z.gesture.scaleStart = getDistanceBetweenTouches(ev);
61218 }
61219 if (!z.gesture.slide) {
61220 if (ev.currentTarget && ((ev.currentTarget)).classList.contains(CLS.slide)) {
61221 z.gesture.slide = (ev.currentTarget);
61222 }
61223 if (!z.gesture.slide) {
61224 z.gesture.slide = s._slides[s._activeIndex];
61225 }
61226 z.gesture.image = (z.gesture.slide.querySelector('img, svg, canvas, ion-img'));
61227 z.gesture.imageWrap = (z.gesture.image.closest('.' + CLS.zoomContainer));
61228 if (!z.gesture.imageWrap) {
61229 z.gesture.image = undefined;
61230 return;
61231 }
61232 z.gesture.zoomMax = parseInt(z.gesture.imageWrap.getAttribute('data-swiper-zoom') || (s.zoomMax), 10);
61233 }
61234 transition(z.gesture.image, 0);
61235 z.isScaling = true;
61236}
61237/**
61238 * @param {?} s
61239 * @param {?} _plt
61240 * @param {?} ev
61241 * @return {?}
61242 */
61243function onGestureChange(s, _plt, ev) {
61244 var /** @type {?} */ z = s._zoom;
61245 s.originalEvent = ev;
61246 if (!s._supportGestures) {
61247 if (ev.type !== 'touchmove' || ev.type === 'touchmove' && ev.targetTouches.length < 2) {
61248 return;
61249 }
61250 z.gesture.scaleMove = getDistanceBetweenTouches(ev);
61251 }
61252 if (!z.gesture.image)
61253 return;
61254 if (s._supportGestures) {
61255 z.scale = ((ev)).scale * z.currentScale;
61256 }
61257 else {
61258 z.scale = (z.gesture.scaleMove / z.gesture.scaleStart) * z.currentScale;
61259 }
61260 if (z.scale > z.gesture.zoomMax) {
61261 z.scale = z.gesture.zoomMax - 1 + Math.pow((z.scale - z.gesture.zoomMax + 1), 0.5);
61262 }
61263 if (z.scale < s.zoomMin) {
61264 z.scale = s.zoomMin + 1 - Math.pow((s.zoomMin - z.scale + 1), 0.5);
61265 }
61266 transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
61267}
61268/**
61269 * @param {?} s
61270 * @param {?} _plt
61271 * @param {?} ev
61272 * @return {?}
61273 */
61274function onGestureEnd(s, _plt, ev) {
61275 var /** @type {?} */ z = s._zoom;
61276 s.originalEvent = ev;
61277 if (!s._supportGestures) {
61278 if (ev.type !== 'touchend' || ev.type === 'touchend' && ev.changedTouches.length < 2) {
61279 return;
61280 }
61281 }
61282 if (!z.gesture.image)
61283 return;
61284 z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.zoomMin);
61285 transition(z.gesture.image, s.speed);
61286 transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
61287 z.currentScale = z.scale;
61288 z.isScaling = false;
61289 if (z.scale === 1) {
61290 z.gesture.slide = undefined;
61291 }
61292}
61293/**
61294 * @param {?} s
61295 * @param {?} plt
61296 * @param {?} ev
61297 * @return {?}
61298 */
61299function onTouchStart(s, plt, ev) {
61300 var /** @type {?} */ z = s._zoom;
61301 s.originalEvent = ev;
61302 if (!z.gesture.image || z.image.isTouched)
61303 return;
61304 if (plt.is('android')) {
61305 ev.preventDefault();
61306 }
61307 z.image.isTouched = true;
61308 z.image.touchesStart.x = ev.type === 'touchstart' ? ev.targetTouches[0].pageX : ((ev)).pageX;
61309 z.image.touchesStart.y = ev.type === 'touchstart' ? ev.targetTouches[0].pageY : ((ev)).pageY;
61310}
61311/**
61312 * @param {?} s
61313 * @param {?} plt
61314 * @param {?} ev
61315 * @return {?}
61316 */
61317function onTouchMove(s, plt, ev) {
61318 var /** @type {?} */ z = s._zoom;
61319 s.originalEvent = ev;
61320 if (!z.gesture.image)
61321 return;
61322 s._allowClick = false;
61323 if (!z.image.isTouched || !z.gesture.slide)
61324 return;
61325 if (!z.image.isMoved) {
61326 z.image.width = z.gesture.image.offsetWidth;
61327 z.image.height = z.gesture.image.offsetHeight;
61328 z.image.startX = getTranslate(s, plt, z.gesture.imageWrap, 'x') || 0;
61329 z.image.startY = getTranslate(s, plt, z.gesture.imageWrap, 'y') || 0;
61330 z.gesture.slideWidth = z.gesture.slide.offsetWidth;
61331 z.gesture.slideHeight = z.gesture.slide.offsetHeight;
61332 transition(z.gesture.imageWrap, 0);
61333 if (s._rtl) {
61334 z.image.startX = -z.image.startX;
61335 z.image.startY = -z.image.startY;
61336 }
61337 }
61338 // Define if we need image drag
61339 var /** @type {?} */ scaledWidth = z.image.width * z.scale;
61340 var /** @type {?} */ scaledHeight = z.image.height * z.scale;
61341 if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) {
61342 return;
61343 }
61344 z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
61345 z.image.maxX = -z.image.minX;
61346 z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
61347 z.image.maxY = -z.image.minY;
61348 z.image.touchesCurrent.x = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ((ev)).pageX;
61349 z.image.touchesCurrent.y = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ((ev)).pageY;
61350 if (!z.image.isMoved && !z.isScaling) {
61351 if (isHorizontal(s) &&
61352 (Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x) ||
61353 (Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x)) {
61354 z.image.isTouched = false;
61355 return;
61356 }
61357 else if (!isHorizontal(s) &&
61358 (Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y) ||
61359 (Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y)) {
61360 z.image.isTouched = false;
61361 return;
61362 }
61363 }
61364 ev.preventDefault();
61365 ev.stopPropagation();
61366 z.image.isMoved = true;
61367 z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;
61368 z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;
61369 if (z.image.currentX < z.image.minX) {
61370 z.image.currentX = z.image.minX + 1 - Math.pow((z.image.minX - z.image.currentX + 1), 0.8);
61371 }
61372 if (z.image.currentX > z.image.maxX) {
61373 z.image.currentX = z.image.maxX - 1 + Math.pow((z.image.currentX - z.image.maxX + 1), 0.8);
61374 }
61375 if (z.image.currentY < z.image.minY) {
61376 z.image.currentY = z.image.minY + 1 - Math.pow((z.image.minY - z.image.currentY + 1), 0.8);
61377 }
61378 if (z.image.currentY > z.image.maxY) {
61379 z.image.currentY = z.image.maxY - 1 + Math.pow((z.image.currentY - z.image.maxY + 1), 0.8);
61380 }
61381 // Velocity
61382 if (!z.velocity.prevPositionX)
61383 z.velocity.prevPositionX = z.image.touchesCurrent.x;
61384 if (!z.velocity.prevPositionY)
61385 z.velocity.prevPositionY = z.image.touchesCurrent.y;
61386 if (!z.velocity.prevTime)
61387 z.velocity.prevTime = Date.now();
61388 z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;
61389 z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;
61390 if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2)
61391 z.velocity.x = 0;
61392 if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2)
61393 z.velocity.y = 0;
61394 z.velocity.prevPositionX = z.image.touchesCurrent.x;
61395 z.velocity.prevPositionY = z.image.touchesCurrent.y;
61396 z.velocity.prevTime = Date.now();
61397 transform(z.gesture.imageWrap, 'translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
61398}
61399/**
61400 * @param {?} s
61401 * @return {?}
61402 */
61403function onTouchEnd(s) {
61404 var /** @type {?} */ z = s._zoom;
61405 if (!z.gesture.image)
61406 return;
61407 if (!z.image.isTouched || !z.image.isMoved) {
61408 z.image.isTouched = false;
61409 z.image.isMoved = false;
61410 return;
61411 }
61412 z.image.isTouched = false;
61413 z.image.isMoved = false;
61414 var /** @type {?} */ momentumDurationX = 300;
61415 var /** @type {?} */ momentumDurationY = 300;
61416 var /** @type {?} */ momentumDistanceX = z.velocity.x * momentumDurationX;
61417 var /** @type {?} */ newPositionX = z.image.currentX + momentumDistanceX;
61418 var /** @type {?} */ momentumDistanceY = z.velocity.y * momentumDurationY;
61419 var /** @type {?} */ newPositionY = z.image.currentY + momentumDistanceY;
61420 // Fix duration
61421 if (z.velocity.x !== 0)
61422 momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);
61423 if (z.velocity.y !== 0)
61424 momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);
61425 var /** @type {?} */ momentumDuration = Math.max(momentumDurationX, momentumDurationY);
61426 z.image.currentX = newPositionX;
61427 z.image.currentY = newPositionY;
61428 // Define if we need image drag
61429 var /** @type {?} */ scaledWidth = z.image.width * z.scale;
61430 var /** @type {?} */ scaledHeight = z.image.height * z.scale;
61431 z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
61432 z.image.maxX = -z.image.minX;
61433 z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
61434 z.image.maxY = -z.image.minY;
61435 z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);
61436 z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);
61437 transition(z.gesture.imageWrap, momentumDuration);
61438 transform(z.gesture.imageWrap, 'translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
61439}
61440/**
61441 * @param {?} s
61442 * @return {?}
61443 */
61444function onTransitionEnd$1(s) {
61445 var /** @type {?} */ z = s._zoom;
61446 if (z.gesture.slide && s._previousIndex !== s._activeIndex) {
61447 transform(z.gesture.image, 'translate3d(0,0,0) scale(1)');
61448 transform(z.gesture.imageWrap, 'translate3d(0,0,0)');
61449 z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;
61450 z.scale = z.currentScale = 1;
61451 }
61452}
61453/**
61454 * @param {?} s
61455 * @param {?} plt
61456 * @return {?}
61457 */
61458function toggleZoom(s, plt) {
61459 var /** @type {?} */ z = s._zoom;
61460 var /** @type {?} */ ev = s.originalEvent;
61461 if (!z.gesture.slide) {
61462 z.gesture.slide = s.clickedSlide ? s.clickedSlide : s._slides[s._activeIndex];
61463 z.gesture.image = (z.gesture.slide.querySelector('img, svg, canvas, ion-img'));
61464 z.gesture.imageWrap = (z.gesture.image.closest('.' + CLS.zoomContainer));
61465 }
61466 if (!z.gesture.image)
61467 return;
61468 var /** @type {?} */ touchX;
61469 var /** @type {?} */ touchY;
61470 var /** @type {?} */ offsetX;
61471 var /** @type {?} */ offsetY;
61472 var /** @type {?} */ diffX;
61473 var /** @type {?} */ diffY;
61474 var /** @type {?} */ translateX;
61475 var /** @type {?} */ translateY;
61476 var /** @type {?} */ imageWidth;
61477 var /** @type {?} */ imageHeight;
61478 var /** @type {?} */ scaledWidth;
61479 var /** @type {?} */ scaledHeight;
61480 var /** @type {?} */ translateMinX;
61481 var /** @type {?} */ translateMinY;
61482 var /** @type {?} */ translateMaxX;
61483 var /** @type {?} */ translateMaxY;
61484 var /** @type {?} */ slideWidth;
61485 var /** @type {?} */ slideHeight;
61486 if (typeof z.image.touchesStart.x === 'undefined' && ev) {
61487 touchX = ev.type === 'touchend' ? ev.changedTouches[0].pageX : ((ev)).pageX;
61488 touchY = ev.type === 'touchend' ? ev.changedTouches[0].pageY : ((ev)).pageY;
61489 }
61490 else {
61491 touchX = z.image.touchesStart.x;
61492 touchY = z.image.touchesStart.y;
61493 }
61494 if (z.scale && z.scale !== 1) {
61495 // Zoom Out
61496 z.scale = z.currentScale = 1;
61497 transition(z.gesture.imageWrap, 300);
61498 transform(z.gesture.imageWrap, 'translate3d(0,0,0)');
61499 transition(z.gesture.image, 300);
61500 transform(z.gesture.image, 'translate3d(0,0,0) scale(1)');
61501 z.gesture.slide = undefined;
61502 }
61503 else {
61504 // Zoom In
61505 z.scale = z.currentScale = parseInt(z.gesture.imageWrap.getAttribute('data-swiper-zoom') || (s.zoomMax), 10);
61506 if (ev) {
61507 slideWidth = z.gesture.slide.offsetWidth;
61508 slideHeight = z.gesture.slide.offsetHeight;
61509 var /** @type {?} */ slideOffsets = offset(z.gesture.slide, plt);
61510 offsetX = slideOffsets.left;
61511 offsetY = slideOffsets.top;
61512 diffX = offsetX + slideWidth / 2 - touchX;
61513 diffY = offsetY + slideHeight / 2 - touchY;
61514 imageWidth = z.gesture.image.offsetWidth;
61515 imageHeight = z.gesture.image.offsetHeight;
61516 scaledWidth = imageWidth * z.scale;
61517 scaledHeight = imageHeight * z.scale;
61518 translateMinX = Math.min((slideWidth / 2 - scaledWidth / 2), 0);
61519 translateMinY = Math.min((slideHeight / 2 - scaledHeight / 2), 0);
61520 translateMaxX = -translateMinX;
61521 translateMaxY = -translateMinY;
61522 translateX = diffX * z.scale;
61523 translateY = diffY * z.scale;
61524 if (translateX < translateMinX) {
61525 translateX = translateMinX;
61526 }
61527 if (translateX > translateMaxX) {
61528 translateX = translateMaxX;
61529 }
61530 if (translateY < translateMinY) {
61531 translateY = translateMinY;
61532 }
61533 if (translateY > translateMaxY) {
61534 translateY = translateMaxY;
61535 }
61536 }
61537 else {
61538 translateX = 0;
61539 translateY = 0;
61540 }
61541 transition(z.gesture.imageWrap, 300);
61542 transform(z.gesture.imageWrap, 'translate3d(' + translateX + 'px, ' + translateY + 'px,0)');
61543 transition(z.gesture.image, 300);
61544 transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
61545 }
61546}
61547/**
61548 * @param {?} s
61549 * @param {?} plt
61550 * @return {?}
61551 */
61552function resetZoomEvents(s, plt) {
61553 detachZoomEvents(s);
61554 var /** @type {?} */ unRegs = s._zoom.unRegs;
61555 var /** @type {?} */ evtOpts = { passive: s._touchEvents.start === 'touchstart', zone: false };
61556 var /** @type {?} */ slides = s._slides;
61557 var /** @type {?} */ slide;
61558 // Scale image
61559 if (s._supportGestures) {
61560 for (var /** @type {?} */ i = 0; i < slides.length; i++) {
61561 slide = slides[i];
61562 // gesturestart
61563 plt.registerListener(slide, 'gesturestart', function (ev) {
61564 onGestureStart(s, plt, ev);
61565 }, evtOpts, unRegs);
61566 // gesturechange
61567 plt.registerListener(slide, 'gesturechange', function (ev) {
61568 onGestureChange(s, plt, ev);
61569 }, evtOpts, unRegs);
61570 // gestureend
61571 plt.registerListener(slide, 'gestureend', function (ev) {
61572 onGestureEnd(s, plt, ev);
61573 }, evtOpts, unRegs);
61574 }
61575 }
61576 else if (s._touchEvents.start === 'touchstart') {
61577 for (var /** @type {?} */ i = 0; i < slides.length; i++) {
61578 slide = slides[i];
61579 // touchstart
61580 plt.registerListener(slide, s._touchEvents.start, function (ev) {
61581 onGestureStart(s, plt, ev);
61582 }, evtOpts, unRegs);
61583 // touchmove
61584 plt.registerListener(slide, s._touchEvents.move, function (ev) {
61585 onGestureChange(s, plt, ev);
61586 }, evtOpts, unRegs);
61587 // touchend
61588 plt.registerListener(slide, s._touchEvents.end, function (ev) {
61589 onGestureEnd(s, plt, ev);
61590 }, evtOpts, unRegs);
61591 }
61592 }
61593 // Move image
61594 var /** @type {?} */ touchStartSub = s.ionSlideTouchStart.subscribe(function (ev) {
61595 onTouchStart(s, plt, ev);
61596 });
61597 unRegs.push(function () { touchStartSub.unsubscribe(); });
61598 for (var /** @type {?} */ i = 0; i < slides.length; i++) {
61599 slide = slides[i];
61600 if (slide.querySelector('.' + CLS.zoomContainer)) {
61601 plt.registerListener(slide, 's.touchEvents.move', function (ev) {
61602 onTouchMove(s, plt, ev);
61603 }, evtOpts, unRegs);
61604 }
61605 }
61606 var /** @type {?} */ touchEndSub = s.ionSlideTouchEnd.subscribe(function () {
61607 onTouchEnd(s);
61608 });
61609 unRegs.push(function () { touchEndSub.unsubscribe(); });
61610 // Scale Out
61611 var /** @type {?} */ transEndSub = s.ionSlideTouchEnd.subscribe(function () {
61612 onTransitionEnd$1(s);
61613 });
61614 unRegs.push(function () { transEndSub.unsubscribe(); });
61615 if (s.zoomToggle) {
61616 var /** @type {?} */ doubleTapSub = s.ionSlideDoubleTap.subscribe(function () {
61617 toggleZoom(s, plt);
61618 });
61619 unRegs.push(function () { doubleTapSub.unsubscribe(); });
61620 }
61621}
61622/**
61623 * @param {?} s
61624 * @return {?}
61625 */
61626function detachZoomEvents(s) {
61627 s._zoom.unRegs.forEach(function (unReg) {
61628 unReg();
61629 });
61630 s._zoom.unRegs.length = 0;
61631}
61632
61633/**
61634 * Adopted from Swiper
61635 * Most modern mobile touch slider and framework with hardware
61636 * accelerated transitions.
61637 *
61638 * http://www.idangero.us/swiper/
61639 *
61640 * Copyright 2016, Vladimir Kharlampidi
61641 * The iDangero.us
61642 * http://www.idangero.us/
61643 *
61644 * Licensed under MIT
61645 */
61646/**
61647 * @param {?} s
61648 * @param {?} plt
61649 * @return {?}
61650 */
61651function initSwiper(s, plt) {
61652 // Classname
61653 s._classNames = [];
61654 /*=========================
61655 Preparation - Define Container, Wrapper and Pagination
61656 ===========================*/
61657 if (!s.container) {
61658 return;
61659 }
61660 // Save instance in container HTML Element and in data
61661 s.container.swiper = s;
61662 var /** @type {?} */ containerModifierClass = CLS.containerModifier;
61663 s._classNames.push(containerModifierClass + s.direction);
61664 if (s.freeMode) {
61665 s._classNames.push(containerModifierClass + 'free-mode');
61666 }
61667 if (s.autoHeight) {
61668 s._classNames.push(containerModifierClass + 'autoheight');
61669 }
61670 // Enable slides progress when required
61671 if (s.parallax || s.watchSlidesVisibility) {
61672 s.watchSlidesProgress = true;
61673 }
61674 // Max resistance when touchReleaseOnEdges
61675 if (s.touchReleaseOnEdges) {
61676 s.resistanceRatio = 0;
61677 }
61678 var /** @type {?} */ effect = s.effect;
61679 // Coverflow / 3D
61680 if (['cube', 'coverflow', 'flip'].indexOf(effect) >= 0) {
61681 s.watchSlidesProgress = true;
61682 s._classNames.push(containerModifierClass + '3d');
61683 }
61684 if (effect !== 'slide') {
61685 s._classNames.push(containerModifierClass + effect);
61686 }
61687 if (effect === 'cube') {
61688 s.resistanceRatio = 0;
61689 s.slidesPerView = 1;
61690 s.slidesPerColumn = 1;
61691 s.slidesPerGroup = 1;
61692 s.centeredSlides = false;
61693 s.spaceBetween = 0;
61694 s.virtualTranslate = true;
61695 s.setWrapperSize = false;
61696 }
61697 if (effect === 'fade' || effect === 'flip') {
61698 s.slidesPerView = 1;
61699 s.slidesPerColumn = 1;
61700 s.slidesPerGroup = 1;
61701 s.watchSlidesProgress = true;
61702 s.spaceBetween = 0;
61703 s.setWrapperSize = false;
61704 s.virtualTranslate = true;
61705 }
61706 // Wrapper
61707 s._wrapper = (s.container.querySelector('.' + CLS.wrapper));
61708 // Pagination
61709 if (s.paginationType) {
61710 s._paginationContainer = (s.container.querySelector('.swiper-pagination'));
61711 if (s.paginationType === 'bullets') {
61712 s._paginationContainer.classList.add(CLS.paginationModifier + 'clickable');
61713 }
61714 s._paginationContainer.classList.add(CLS.paginationModifier + s.paginationType);
61715 }
61716 // Next/Prev Buttons
61717 // if (s.nextButton || s.prevButton) {
61718 // if (s.nextButton) {
61719 // s.nextButton = <any>s.container.closest('ion-content').querySelector(s.nextButton);
61720 // }
61721 // if (s.prevButton) {
61722 // s.prevButton = <any>s.container.closest('ion-content').querySelector(s.prevButton);
61723 // }
61724 // }
61725 // RTL
61726 s._rtl = isHorizontal(s) && (s.container.dir.toLowerCase() === 'rtl' || s.container.style.direction === 'rtl');
61727 if (s._rtl) {
61728 s._classNames.push(containerModifierClass + 'rtl');
61729 }
61730 // Columns
61731 if (s.slidesPerColumn > 1) {
61732 s._classNames.push(containerModifierClass + 'multirow');
61733 }
61734 // Check for Android
61735 if (plt.is('android')) {
61736 s._classNames.push(containerModifierClass + 'android');
61737 }
61738 // Add classes
61739 s._classNames.forEach(function (clsName) {
61740 s.container.classList.add(clsName);
61741 });
61742 // Translate
61743 s._translate = 0;
61744 // Progress
61745 s.progress = 0;
61746 // Velocity
61747 s.velocity = 0;
61748 /*=========================
61749 Autoplay
61750 ===========================*/
61751 s._autoplayTimeoutId = undefined;
61752 s._autoplaying = false;
61753 s._autoplayPaused = false;
61754 s._allowClick = true;
61755 // Animating Flag
61756 s._animating = false;
61757 // Touches information
61758 s._touches = {
61759 startX: 0,
61760 startY: 0,
61761 currentX: 0,
61762 currentY: 0,
61763 diff: 0
61764 };
61765 if (s.loop) {
61766 createLoop(s);
61767 }
61768 updateContainerSize(s, plt);
61769 updateSlidesSize(s, plt);
61770 updatePagination(s);
61771 if (effect !== 'slide' && SWIPER_EFFECTS[effect]) {
61772 if (!s.loop) {
61773 updateProgress(s);
61774 }
61775 SWIPER_EFFECTS[effect].setTranslate(s, plt);
61776 }
61777 if (s.loop) {
61778 slideTo(s, plt, s.initialSlide + s.loopedSlides, 0, s.runCallbacksOnInit);
61779 }
61780 else {
61781 slideTo(s, plt, s.initialSlide, 0, s.runCallbacksOnInit);
61782 if (s.initialSlide === 0) {
61783 parallaxSetTranslate(s);
61784 }
61785 }
61786 if (s.autoplay) {
61787 startAutoplay(s, plt);
61788 }
61789}
61790/**
61791 * @param {?} s
61792 * @param {?} plt
61793 * @return {?}
61794 */
61795function autoplay(s, plt) {
61796 var /** @type {?} */ autoplayDelay = s.autoplay;
61797 var /** @type {?} */ activeSlide = s._slides[s._activeIndex];
61798 if (activeSlide.hasAttribute('data-swiper-autoplay')) {
61799 autoplayDelay = ((activeSlide.getAttribute('data-swiper-autoplay') || s.autoplay));
61800 }
61801 s._autoplayTimeoutId = plt.timeout(function () {
61802 s._zone.run(function () {
61803 if (s.loop) {
61804 fixLoop(s, plt);
61805 slideNext(s, plt, true, undefined, true);
61806 s.ionSlideAutoplay.emit(s);
61807 }
61808 else {
61809 if (!s._isEnd) {
61810 slideNext(s, plt, true, undefined, true);
61811 s.ionSlideAutoplay.emit(s);
61812 }
61813 else {
61814 if (!s.autoplayStopOnLast) {
61815 slideTo(s, plt, 0);
61816 s.ionSlideAutoplay.emit(s);
61817 }
61818 else {
61819 stopAutoplay(s);
61820 }
61821 }
61822 }
61823 });
61824 }, autoplayDelay);
61825}
61826/**
61827 * @param {?} s
61828 * @param {?} plt
61829 * @return {?}
61830 */
61831function startAutoplay(s, plt) {
61832 if (typeof s._autoplayTimeoutId !== 'undefined')
61833 return false;
61834 if (!s.autoplay || s._autoplaying) {
61835 return false;
61836 }
61837 s._autoplaying = true;
61838 s._zone.run(function () {
61839 s.ionSlideAutoplayStart.emit(s);
61840 });
61841 autoplay(s, plt);
61842}
61843/**
61844 * @param {?} s
61845 * @return {?}
61846 */
61847function stopAutoplay(s) {
61848 if (!s._autoplayTimeoutId)
61849 return;
61850 if (s._autoplayTimeoutId)
61851 clearTimeout(s._autoplayTimeoutId);
61852 s._autoplaying = false;
61853 s._autoplayTimeoutId = undefined;
61854 s._zone.run(function () {
61855 s.ionSlideAutoplayStop.emit(s);
61856 });
61857}
61858/**
61859 * @param {?} s
61860 * @param {?} plt
61861 * @param {?=} speed
61862 * @return {?}
61863 */
61864function pauseAutoplay(s, plt, speed) {
61865 if (s._autoplayPaused)
61866 return;
61867 if (s._autoplayTimeoutId)
61868 clearTimeout(s._autoplayTimeoutId);
61869 s._autoplayPaused = true;
61870 if (speed === 0) {
61871 s._autoplayPaused = false;
61872 autoplay(s, plt);
61873 }
61874 else {
61875 plt.transitionEnd(s._wrapper, function () {
61876 if (!s)
61877 return;
61878 s._autoplayPaused = false;
61879 if (!s._autoplaying) {
61880 stopAutoplay(s);
61881 }
61882 else {
61883 autoplay(s, plt);
61884 }
61885 });
61886 }
61887}
61888/**
61889 * @param {?} s
61890 * @return {?}
61891 */
61892function updateAutoHeight(s) {
61893 var /** @type {?} */ activeSlides = [];
61894 var /** @type {?} */ newHeight = 0;
61895 var /** @type {?} */ i;
61896 // Find slides currently in view
61897 if (s.slidesPerView !== 'auto' && s.slidesPerView > 1) {
61898 for (i = 0; i < Math.ceil(/** @type {?} */ (s.slidesPerView)); i++) {
61899 var /** @type {?} */ index = s._activeIndex + i;
61900 if (index > s._slides.length)
61901 break;
61902 activeSlides.push(s._slides[index]);
61903 }
61904 }
61905 else {
61906 activeSlides.push(s._slides[s._activeIndex]);
61907 }
61908 // Find new height from heighest slide in view
61909 for (i = 0; i < activeSlides.length; i++) {
61910 if (typeof activeSlides[i] !== 'undefined') {
61911 var /** @type {?} */ height = activeSlides[i].offsetHeight;
61912 newHeight = height > newHeight ? height : newHeight;
61913 }
61914 }
61915 // Update Height
61916 if (newHeight) {
61917 s._wrapper.style.height = newHeight + 'px';
61918 }
61919}
61920/**
61921 * @param {?} s
61922 * @param {?} plt
61923 * @return {?}
61924 */
61925function updateContainerSize(s, plt) {
61926 var /** @type {?} */ container = s.container;
61927 var /** @type {?} */ width;
61928 var /** @type {?} */ height;
61929 if (typeof s.width !== 'undefined') {
61930 // manually assign user width
61931 width = s.width;
61932 }
61933 else {
61934 width = container.clientWidth;
61935 }
61936 if (typeof s.renderedHeight !== 'undefined') {
61937 // manually assign user height
61938 height = s.renderedHeight;
61939 }
61940 else {
61941 height = container.clientHeight;
61942 }
61943 if (width === 0 && isHorizontal(s) || height === 0 && !isHorizontal(s)) {
61944 return;
61945 }
61946 // Subtract paddings
61947 var /** @type {?} */ containerStyles = plt.getElementComputedStyle(container);
61948 width = width - parseInt(containerStyles.paddingLeft, 10) - parseInt(containerStyles.paddingRight, 10);
61949 height = height - parseInt(containerStyles.paddingTop, 10) - parseInt(containerStyles.paddingBottom, 10);
61950 // Store values
61951 s.renderedWidth = width;
61952 s.renderedHeight = height;
61953 s._renderedSize = isHorizontal(s) ? width : height;
61954}
61955/**
61956 * @param {?} s
61957 * @param {?} plt
61958 * @return {?}
61959 */
61960function updateSlidesSize(s, plt) {
61961 s._slides = ((s._wrapper.querySelectorAll('.' + CLS.slide)));
61962 s._snapGrid = [];
61963 s._slidesGrid = [];
61964 s._slidesSizesGrid = [];
61965 var /** @type {?} */ spaceBetween = s.spaceBetween;
61966 var /** @type {?} */ slidePosition = -s.slidesOffsetBefore;
61967 var /** @type {?} */ i;
61968 var /** @type {?} */ prevSlideSize = 0;
61969 var /** @type {?} */ index = 0;
61970 if (typeof s._renderedSize === 'undefined')
61971 return;
61972 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
61973 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s._renderedSize;
61974 }
61975 s._virtualSize = -spaceBetween;
61976 // reset margins
61977 if (s._rtl) {
61978 inlineStyle(s._slides, { marginLeft: '', marginTop: '' });
61979 }
61980 else {
61981 inlineStyle(s._slides, { marginRight: '', marginBottom: '' });
61982 }
61983 var /** @type {?} */ slidesNumberEvenToRows;
61984 if (s.slidesPerColumn > 1) {
61985 if (Math.floor(s._slides.length / s.slidesPerColumn) === s._slides.length / s.slidesPerColumn) {
61986 slidesNumberEvenToRows = s._slides.length;
61987 }
61988 else {
61989 slidesNumberEvenToRows = Math.ceil(s._slides.length / s.slidesPerColumn) * s.slidesPerColumn;
61990 }
61991 if (s.slidesPerView !== 'auto' && s.slidesPerColumnFill === 'row') {
61992 slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, /** @type {?} */ (s.slidesPerView) * s.slidesPerColumn);
61993 }
61994 }
61995 // Calc slides
61996 var /** @type {?} */ slideSize;
61997 var /** @type {?} */ slidesPerColumn = s.slidesPerColumn;
61998 var /** @type {?} */ slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
61999 var /** @type {?} */ numFullColumns = slidesPerRow - (s.slidesPerColumn * slidesPerRow - s._slides.length);
62000 for (i = 0; i < s._slides.length; i++) {
62001 slideSize = 0;
62002 var /** @type {?} */ slide = s._slides[i];
62003 if (s.slidesPerColumn > 1) {
62004 // Set slides order
62005 var /** @type {?} */ newSlideOrderIndex;
62006 var /** @type {?} */ column;
62007 var /** @type {?} */ row;
62008 if (s.slidesPerColumnFill === 'column') {
62009 column = Math.floor(i / slidesPerColumn);
62010 row = i - column * slidesPerColumn;
62011 if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) {
62012 if (++row >= slidesPerColumn) {
62013 row = 0;
62014 column++;
62015 }
62016 }
62017 newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
62018 inlineStyle(slide, {
62019 '-webkit-box-ordinal-group': newSlideOrderIndex,
62020 '-moz-box-ordinal-group': newSlideOrderIndex,
62021 '-ms-flex-order': newSlideOrderIndex,
62022 '-webkit-order': newSlideOrderIndex,
62023 'order': newSlideOrderIndex
62024 });
62025 }
62026 else {
62027 row = Math.floor(i / slidesPerRow);
62028 column = i - row * slidesPerRow;
62029 }
62030 var /** @type {?} */ cssVal = (row !== 0 && s.spaceBetween) && (s.spaceBetween + 'px');
62031 var /** @type {?} */ cssObj = {};
62032 if (isHorizontal(s)) {
62033 cssObj['marginTop'] = cssVal;
62034 }
62035 else {
62036 cssObj['marginLeft'] = cssVal;
62037 }
62038 inlineStyle(slide, cssObj);
62039 slide.setAttribute('data-swiper-column', /** @type {?} */ (column));
62040 slide.setAttribute('data-swiper-row', /** @type {?} */ (row));
62041 }
62042 if (slide.style.display === 'none') {
62043 continue;
62044 }
62045 if (s.slidesPerView === 'auto') {
62046 var /** @type {?} */ styles = plt.getElementComputedStyle(slide);
62047 if (isHorizontal(s)) {
62048 slideSize = slide.offsetWidth + parseFloat(styles.marginRight) + parseFloat(styles.marginLeft);
62049 }
62050 else {
62051 slideSize = slide.offsetHeight + parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
62052 }
62053 if (s.roundLengths)
62054 slideSize = round(slideSize);
62055 }
62056 else {
62057 slideSize = (s._renderedSize - ((s.slidesPerView) - 1) * spaceBetween) / (s.slidesPerView);
62058 if (s.roundLengths)
62059 slideSize = round(slideSize);
62060 if (isHorizontal(s)) {
62061 s._slides[i].style.width = slideSize + 'px';
62062 }
62063 else {
62064 s._slides[i].style.height = slideSize + 'px';
62065 }
62066 }
62067 s._slides[i].swiperSlideSize = slideSize;
62068 s._slidesSizesGrid.push(slideSize);
62069 if (s.centeredSlides) {
62070 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
62071 if (i === 0)
62072 slidePosition = slidePosition - s._renderedSize / 2 - spaceBetween;
62073 if (Math.abs(slidePosition) < 1 / 1000)
62074 slidePosition = 0;
62075 if ((index) % s.slidesPerGroup === 0)
62076 s._snapGrid.push(slidePosition);
62077 s._slidesGrid.push(slidePosition);
62078 }
62079 else {
62080 if ((index) % s.slidesPerGroup === 0)
62081 s._snapGrid.push(slidePosition);
62082 s._slidesGrid.push(slidePosition);
62083 slidePosition = slidePosition + slideSize + spaceBetween;
62084 }
62085 s._virtualSize += slideSize + spaceBetween;
62086 prevSlideSize = slideSize;
62087 index++;
62088 }
62089 s._virtualSize = Math.max(s._virtualSize, s._renderedSize) + s.slidesOffsetAfter;
62090 var /** @type {?} */ newSlidesGrid;
62091 if (s._rtl && (s.effect === 'slide' || s.effect === 'coverflow')) {
62092 inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
62093 }
62094 if (s.setWrapperSize) {
62095 if (isHorizontal(s)) {
62096 inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
62097 }
62098 else {
62099 inlineStyle(s._wrapper, { height: s._virtualSize + s.spaceBetween + 'px' });
62100 }
62101 }
62102 if (s.slidesPerColumn > 1) {
62103 s._virtualSize = (slideSize + s.spaceBetween) * slidesNumberEvenToRows;
62104 s._virtualSize = Math.ceil(s._virtualSize / s.slidesPerColumn) - s.spaceBetween;
62105 if (isHorizontal(s)) {
62106 inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
62107 }
62108 else {
62109 inlineStyle(s._wrapper, { height: s._virtualSize + s.spaceBetween + 'px' });
62110 }
62111 if (s.centeredSlides) {
62112 newSlidesGrid = [];
62113 for (i = 0; i < s._snapGrid.length; i++) {
62114 if (s._snapGrid[i] < s._virtualSize + s._snapGrid[0])
62115 newSlidesGrid.push(s._snapGrid[i]);
62116 }
62117 s._snapGrid = newSlidesGrid;
62118 }
62119 }
62120 // Remove last grid elements depending on width
62121 if (!s.centeredSlides) {
62122 newSlidesGrid = [];
62123 for (i = 0; i < s._snapGrid.length; i++) {
62124 if (s._snapGrid[i] <= s._virtualSize - s._renderedSize) {
62125 newSlidesGrid.push(s._snapGrid[i]);
62126 }
62127 }
62128 s._snapGrid = newSlidesGrid;
62129 if (Math.floor(s._virtualSize - s._renderedSize) - Math.floor(s._snapGrid[s._snapGrid.length - 1]) > 1) {
62130 s._snapGrid.push(s._virtualSize - s._renderedSize);
62131 }
62132 }
62133 if (s._snapGrid.length === 0)
62134 s._snapGrid = [0];
62135 if (s.spaceBetween !== 0) {
62136 if (isHorizontal(s)) {
62137 if (s._rtl) {
62138 inlineStyle(s._slides, { marginLeft: spaceBetween + 'px' });
62139 }
62140 else {
62141 inlineStyle(s._slides, { marginRight: spaceBetween + 'px' });
62142 }
62143 }
62144 else {
62145 inlineStyle(s._slides, { marginBottom: spaceBetween + 'px' });
62146 }
62147 }
62148 if (s.watchSlidesProgress) {
62149 updateSlidesOffset(s);
62150 }
62151}
62152/**
62153 * @param {?} s
62154 * @return {?}
62155 */
62156function currentSlidesPerView(s) {
62157 var /** @type {?} */ spv = 1;
62158 var /** @type {?} */ i;
62159 var /** @type {?} */ j;
62160 if (s.centeredSlides) {
62161 var /** @type {?} */ size = s._slides[s._activeIndex].swiperSlideSize;
62162 var /** @type {?} */ breakLoop;
62163 for (i = s._activeIndex + 1; i < s._slides.length; i++) {
62164 if (s._slides[i] && !breakLoop) {
62165 size += s._slides[i].swiperSlideSize;
62166 spv++;
62167 if (size > s._renderedSize)
62168 breakLoop = true;
62169 }
62170 }
62171 for (j = s._activeIndex - 1; j >= 0; j--) {
62172 if (s._slides[j] && !breakLoop) {
62173 size += s._slides[j].swiperSlideSize;
62174 spv++;
62175 if (size > s._renderedSize)
62176 breakLoop = true;
62177 }
62178 }
62179 }
62180 else {
62181 for (i = s._activeIndex + 1; i < s._slides.length; i++) {
62182 if (s._slidesGrid[i] - s._slidesGrid[s._activeIndex] < s._renderedSize) {
62183 spv++;
62184 }
62185 }
62186 }
62187 return spv;
62188}
62189/**
62190 * @param {?} s
62191 * @param {?} plt
62192 * @param {?=} updateTranslate
62193 * @return {?}
62194 */
62195function update(s, plt, updateTranslate) {
62196 if (!s)
62197 return;
62198 updateContainerSize(s, plt);
62199 updateSlidesSize(s, plt);
62200 updateProgress(s);
62201 updatePagination(s);
62202 updateClasses(s);
62203 if (s.zoom) {
62204 resetZoomEvents(s, plt);
62205 }
62206 var /** @type {?} */ translated;
62207 var /** @type {?} */ newTranslate;
62208 /**
62209 * @return {?}
62210 */
62211 function forceSetTranslate() {
62212 newTranslate = Math.min(Math.max(s._translate, maxTranslate(s)), minTranslate(s));
62213 setWrapperTranslate(s, plt, newTranslate);
62214 updateActiveIndex(s);
62215 updateClasses(s);
62216 }
62217 if (updateTranslate) {
62218 if (s._spline) {
62219 s._spline = undefined;
62220 }
62221 if (s.freeMode) {
62222 forceSetTranslate();
62223 if (s.autoHeight) {
62224 updateAutoHeight(s);
62225 }
62226 }
62227 else {
62228 if ((s.slidesPerView === 'auto' || s.slidesPerView > 1) && s._isEnd && !s.centeredSlides) {
62229 translated = slideTo(s, plt, s._slides.length - 1, 0, false, true);
62230 }
62231 else {
62232 translated = slideTo(s, plt, s._activeIndex, 0, false, true);
62233 }
62234 if (!translated) {
62235 forceSetTranslate();
62236 }
62237 }
62238 }
62239 else if (s.autoHeight) {
62240 updateAutoHeight(s);
62241 }
62242}
62243/**
62244 * @param {?} s
62245 * @return {?}
62246 */
62247function createLoop(s) {
62248 // Remove duplicated slides
62249 eachChild(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate, function (ele) {
62250 ele.parentElement.removeChild(ele);
62251 });
62252 var /** @type {?} */ slides = (s._wrapper.querySelectorAll('.' + CLS.slide));
62253 if (s.slidesPerView === 'auto' && !s.loopedSlides) {
62254 s.loopedSlides = slides.length;
62255 }
62256 s.loopedSlides = parseInt(/** @type {?} */ ((s.loopedSlides || s.slidesPerView)), 10);
62257 s.loopedSlides = s.loopedSlides + s.loopAdditionalSlides;
62258 if (s.loopedSlides > slides.length) {
62259 s.loopedSlides = slides.length;
62260 }
62261 var /** @type {?} */ prependSlides = [];
62262 var /** @type {?} */ appendSlides = [];
62263 for (var /** @type {?} */ i = 0; i < slides.length; i++) {
62264 var /** @type {?} */ slide = slides[i];
62265 if (i < s.loopedSlides)
62266 appendSlides.push(slide);
62267 if (i < slides.length && i >= slides.length - s.loopedSlides)
62268 prependSlides.push(slide);
62269 slide.setAttribute('data-swiper-slide-index', /** @type {?} */ (i));
62270 }
62271 for (i = 0; i < appendSlides.length; i++) {
62272 var /** @type {?} */ appendClone = appendSlides[i].cloneNode(true);
62273 addClass(appendClone, CLS.slideDuplicate);
62274 s._wrapper.appendChild(appendClone);
62275 }
62276 for (i = prependSlides.length - 1; i >= 0; i--) {
62277 var /** @type {?} */ prependClone = prependSlides[i].cloneNode(true);
62278 addClass(prependClone, CLS.slideDuplicate);
62279 s._wrapper.insertBefore(prependClone, s._wrapper.firstElementChild);
62280 }
62281}
62282/**
62283 * @param {?} s
62284 * @return {?}
62285 */
62286function destroyLoop(s) {
62287 eachChild(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate, function (ele) {
62288 ele.parentElement.removeChild(ele);
62289 });
62290 if (s._slides) {
62291 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
62292 s._slides[i].removeAttribute('data-swiper-slide-index');
62293 }
62294 }
62295}
62296/**
62297 * @param {?} s
62298 * @param {?} plt
62299 * @return {?}
62300 */
62301function fixLoop(s, plt) {
62302 var /** @type {?} */ newIndex;
62303 if (s._activeIndex < s.loopedSlides) {
62304 // Fix For Negative Oversliding
62305 newIndex = s._slides.length - s.loopedSlides * 3 + s._activeIndex;
62306 newIndex = newIndex + s.loopedSlides;
62307 slideTo(s, plt, newIndex, 0, false, true);
62308 }
62309 else if ((s.slidesPerView === 'auto' && s._activeIndex >= s.loopedSlides * 2) || (s._activeIndex > s._slides.length - (s.slidesPerView) * 2)) {
62310 // Fix For Positive Oversliding
62311 newIndex = -s._slides.length + s._activeIndex + s.loopedSlides;
62312 newIndex = newIndex + s.loopedSlides;
62313 slideTo(s, plt, newIndex, 0, false, true);
62314 }
62315}
62316/**
62317 * @param {?} s
62318 * @param {?} plt
62319 * @param {?=} slideIndex
62320 * @param {?=} speed
62321 * @param {?=} runCallbacks
62322 * @param {?=} internal
62323 * @return {?}
62324 */
62325function slideTo(s, plt, slideIndex, speed, runCallbacks, internal) {
62326 if (runCallbacks === void 0) { runCallbacks = true; }
62327 if (typeof slideIndex === 'undefined')
62328 slideIndex = 0;
62329 if (slideIndex < 0)
62330 slideIndex = 0;
62331 s._snapIndex = Math.floor(slideIndex / s.slidesPerGroup);
62332 if (s._snapIndex >= s._snapGrid.length)
62333 s._snapIndex = s._snapGrid.length - 1;
62334 var /** @type {?} */ translate = -s._snapGrid[s._snapIndex];
62335 // Stop autoplay
62336 if (s.autoplay && s._autoplaying) {
62337 if (internal || !s.autoplayDisableOnInteraction) {
62338 pauseAutoplay(s, plt, speed);
62339 }
62340 else {
62341 stopAutoplay(s);
62342 }
62343 }
62344 // Update progress
62345 updateProgress(s, translate);
62346 // Directions locks
62347 if (!s._allowSwipeToNext && translate < s._translate && translate < minTranslate(s)) {
62348 return false;
62349 }
62350 if (!s._allowSwipeToPrev && translate > s._translate && translate > maxTranslate(s)) {
62351 if ((s._activeIndex || 0) !== slideIndex)
62352 return false;
62353 }
62354 // Update Index
62355 if (typeof speed === 'undefined')
62356 speed = s.speed;
62357 s._previousIndex = s._activeIndex || 0;
62358 s._activeIndex = slideIndex;
62359 updateRealIndex(s);
62360 if ((s._rtl && -translate === s._translate) || (!s._rtl && translate === s._translate)) {
62361 // Update Height
62362 if (s.autoHeight) {
62363 updateAutoHeight(s);
62364 }
62365 updateClasses(s);
62366 if (s.effect !== 'slide') {
62367 setWrapperTranslate(s, plt, translate);
62368 }
62369 return false;
62370 }
62371 updateClasses(s);
62372 onTransitionStart(s, runCallbacks);
62373 if (speed === 0) {
62374 setWrapperTranslate(s, plt, translate);
62375 setWrapperTransition(s, plt, 0);
62376 onTransitionEnd(s, plt, runCallbacks);
62377 }
62378 else {
62379 setWrapperTranslate(s, plt, translate);
62380 setWrapperTransition(s, plt, speed);
62381 if (!s._animating) {
62382 s._animating = true;
62383 plt.transitionEnd(s._wrapper, function () {
62384 if (!s)
62385 return;
62386 onTransitionEnd(s, plt, runCallbacks);
62387 });
62388 }
62389 }
62390 return true;
62391}
62392/**
62393 * @param {?} s
62394 * @param {?=} runCallbacks
62395 * @return {?}
62396 */
62397function onTransitionStart(s, runCallbacks) {
62398 if (runCallbacks === void 0) { runCallbacks = true; }
62399 if (s.autoHeight) {
62400 updateAutoHeight(s);
62401 }
62402 if (runCallbacks) {
62403 s._zone.run(function () {
62404 s.ionSlideTransitionStart.emit(s);
62405 if (s._activeIndex !== s._previousIndex) {
62406 s.ionSlideWillChange.emit(s);
62407 if (s._activeIndex > s._previousIndex) {
62408 s.ionSlideNextStart.emit(s);
62409 }
62410 else {
62411 s.ionSlidePrevStart.emit(s);
62412 }
62413 }
62414 });
62415 }
62416}
62417/**
62418 * @param {?} s
62419 * @param {?} plt
62420 * @param {?=} runCallbacks
62421 * @return {?}
62422 */
62423function onTransitionEnd(s, plt, runCallbacks) {
62424 if (runCallbacks === void 0) { runCallbacks = true; }
62425 s._animating = false;
62426 setWrapperTransition(s, plt, 0);
62427 if (runCallbacks) {
62428 s._zone.run(function () {
62429 s.ionSlideTransitionEnd.emit(s);
62430 if (s._activeIndex !== s._previousIndex) {
62431 s.ionSlideDidChange.emit(s);
62432 if (s._activeIndex > s._previousIndex) {
62433 s.ionSlideNextEnd.emit(s);
62434 }
62435 else {
62436 s.ionSlidePrevEnd.emit(s);
62437 }
62438 }
62439 });
62440 }
62441}
62442/**
62443 * @param {?} s
62444 * @param {?} plt
62445 * @param {?=} runCallbacks
62446 * @param {?=} speed
62447 * @param {?=} internal
62448 * @return {?}
62449 */
62450function slideNext(s, plt, runCallbacks, speed, internal) {
62451 if (s.loop) {
62452 if (s._animating)
62453 return false;
62454 fixLoop(s, plt);
62455 s.container.clientLeft;
62456 return slideTo(s, plt, s._activeIndex + s.slidesPerGroup, speed, runCallbacks, internal);
62457 }
62458 var /** @type {?} */ nextSlide = s._activeIndex + s.slidesPerGroup;
62459 if (nextSlide < s._slides.length) {
62460 return slideTo(s, plt, nextSlide, speed, runCallbacks, internal);
62461 }
62462 return false;
62463}
62464/**
62465 * @param {?} s
62466 * @param {?} plt
62467 * @param {?=} runCallbacks
62468 * @param {?=} speed
62469 * @param {?=} internal
62470 * @return {?}
62471 */
62472function slidePrev(s, plt, runCallbacks, speed, internal) {
62473 if (s.loop) {
62474 if (s._animating)
62475 return false;
62476 fixLoop(s, plt);
62477 s.container.clientLeft;
62478 return slideTo(s, plt, s._activeIndex - 1, speed, runCallbacks, internal);
62479 }
62480 var /** @type {?} */ previousSlide = s._activeIndex - 1;
62481 if (previousSlide >= 0) {
62482 return slideTo(s, plt, s._activeIndex - 1, speed, runCallbacks, internal);
62483 }
62484 return false;
62485}
62486/**
62487 * @param {?} s
62488 * @param {?} plt
62489 * @param {?=} runCallbacks
62490 * @param {?=} speed
62491 * @return {?}
62492 */
62493function slideReset(s, plt, runCallbacks, speed) {
62494 return slideTo(s, plt, s._activeIndex, speed, runCallbacks, true);
62495}
62496/**
62497 * @param {?} s
62498 * @return {?}
62499 */
62500
62501/**
62502 * @param {?} s
62503 * @return {?}
62504 */
62505
62506/**
62507 * @param {?} s
62508 * @return {?}
62509 */
62510function cleanupStyles(s) {
62511 if (!s.container || !s._wrapper) {
62512 // fix #10830
62513 return;
62514 }
62515 // Container
62516 if (s.container) {
62517 removeClass(s.container, s._classNames);
62518 s.container.removeAttribute('style');
62519 }
62520 // Wrapper
62521 s._wrapper.removeAttribute('style');
62522 // Slides
62523 if (s._slides && s._slides.length) {
62524 removeClass(s._slides, [
62525 CLS.slideVisible,
62526 CLS.slideActive,
62527 CLS.slideNext,
62528 CLS.slidePrev
62529 ]);
62530 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
62531 var /** @type {?} */ slide = s._slides[i];
62532 slide.removeAttribute('style');
62533 slide.removeAttribute('data-swiper-column');
62534 slide.removeAttribute('data-swiper-row');
62535 }
62536 }
62537 // Pagination/Bullets
62538 removeClass(s._bullets, CLS.bulletActive);
62539 // Buttons
62540 removeClass(s.prevButton, CLS.buttonDisabled);
62541 removeClass(s.nextButton, CLS.buttonDisabled);
62542}
62543/**
62544 * @param {?} s
62545 * @return {?}
62546 */
62547function destroySwiper(s) {
62548 // Stop autoplay
62549 stopAutoplay(s);
62550 // Destroy loop
62551 if (s.loop) {
62552 destroyLoop(s);
62553 }
62554 // Cleanup styles
62555 cleanupStyles(s);
62556}
62557
62558/**
62559 * @param {?} s
62560 * @param {?} plt
62561 * @param {?} e
62562 * @return {?}
62563 */
62564function handleKeyboard(s, plt, e) {
62565 var /** @type {?} */ win = plt.win();
62566 var /** @type {?} */ kc = e.keyCode || e.charCode;
62567 // Directions locks
62568 if (!s._allowSwipeToNext && (isHorizontal(s) && kc === 39 || !isHorizontal(s) && kc === 40)) {
62569 return false;
62570 }
62571 if (!s._allowSwipeToPrev && (isHorizontal(s) && kc === 37 || !isHorizontal(s) && kc === 38)) {
62572 return false;
62573 }
62574 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
62575 return;
62576 }
62577 var /** @type {?} */ activeEle = plt.getActiveElement();
62578 if (activeEle && activeEle.nodeName && (activeEle.nodeName.toLowerCase() === 'input' || activeEle.nodeName.toLowerCase() === 'textarea')) {
62579 return;
62580 }
62581 if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
62582 var /** @type {?} */ inView = false;
62583 // Check that swiper should be inside of visible area of window
62584 if (s.container.closest('.' + CLS.slide) && !s.container.closest('.' + CLS.slideActive)) {
62585 return;
62586 }
62587 var /** @type {?} */ windowScroll = {
62588 left: win.pageXOffset,
62589 top: win.pageYOffset
62590 };
62591 var /** @type {?} */ windowWidth = plt.width();
62592 var /** @type {?} */ windowHeight = plt.height();
62593 var /** @type {?} */ swiperOffset = offset(s.container, plt);
62594 if (s._rtl) {
62595 swiperOffset.left = swiperOffset.left - s.container.scrollLeft;
62596 }
62597 var /** @type {?} */ swiperCoord = [
62598 [swiperOffset.left, swiperOffset.top],
62599 [swiperOffset.left + s.renderedWidth, swiperOffset.top],
62600 [swiperOffset.left, swiperOffset.top + s.renderedHeight],
62601 [swiperOffset.left + s.renderedWidth, swiperOffset.top + s.renderedHeight]
62602 ];
62603 for (var /** @type {?} */ i = 0; i < swiperCoord.length; i++) {
62604 var /** @type {?} */ point = swiperCoord[i];
62605 if (point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
62606 point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight) {
62607 inView = true;
62608 }
62609 }
62610 if (!inView)
62611 return;
62612 }
62613 if (isHorizontal(s)) {
62614 if (kc === 37 || kc === 39) {
62615 if (e.preventDefault) {
62616 e.preventDefault();
62617 }
62618 else {
62619 e.returnValue = false;
62620 }
62621 }
62622 if ((kc === 39 && !s._rtl) || (kc === 37 && s._rtl)) {
62623 slideNext(s, plt);
62624 }
62625 if ((kc === 37 && !s._rtl) || (kc === 39 && s._rtl)) {
62626 slidePrev(s, plt);
62627 }
62628 }
62629 else {
62630 if (kc === 38 || kc === 40) {
62631 if (e.preventDefault) {
62632 e.preventDefault();
62633 }
62634 else {
62635 e.returnValue = false;
62636 }
62637 }
62638 if (kc === 40) {
62639 slideNext(s, plt);
62640 }
62641 if (kc === 38) {
62642 slidePrev(s, plt);
62643 }
62644 }
62645}
62646/**
62647 * @param {?} s
62648 * @param {?} plt
62649 * @param {?} shouldEnable
62650 * @return {?}
62651 */
62652function enableKeyboardControl(s, plt, shouldEnable) {
62653 if (shouldEnable && !s._keyboardUnReg) {
62654 s._keyboardUnReg = plt.registerListener(plt.doc(), 'keydown', function (ev) {
62655 handleKeyboard(s, plt, ev);
62656 }, { zone: false });
62657 }
62658 else if (!shouldEnable && s._keyboardUnReg) {
62659 s._keyboardUnReg();
62660 }
62661}
62662
62663/**
62664 * @param {?} s
62665 * @param {?} plt
62666 * @return {?}
62667 */
62668function initEvents(s, plt) {
62669 var /** @type {?} */ win = plt.win();
62670 var /** @type {?} */ doc = plt.doc();
62671 s._supportTouch = (function () {
62672 return !!(('ontouchstart' in win) || win.DocumentTouch && doc instanceof win.DocumentTouch);
62673 })();
62674 // Define Touch Events
62675 s._touchEventsDesktop = { start: 'mousedown', move: 'mousemove', end: 'mouseup' };
62676 if (win.navigator.pointerEnabled) {
62677 s._touchEventsDesktop = { start: 'pointerdown', move: 'pointermove', end: 'pointerup' };
62678 }
62679 else if (win.navigator.msPointerEnabled) {
62680 s._touchEventsDesktop = { start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp' };
62681 }
62682 s._touchEvents = {
62683 start: s._supportTouch || !s.simulateTouch ? 'touchstart' : s._touchEventsDesktop.start,
62684 move: s._supportTouch || !s.simulateTouch ? 'touchmove' : s._touchEventsDesktop.move,
62685 end: s._supportTouch || !s.simulateTouch ? 'touchend' : s._touchEventsDesktop.end
62686 };
62687 // WP8 Touch Events Fix
62688 if (win.navigator.pointerEnabled || win.navigator.msPointerEnabled) {
62689 (s.touchEventsTarget === 'container' ? s.container : s._wrapper).classList.add('swiper-wp8-' + s.direction);
62690 }
62691 var /** @type {?} */ unregs = [];
62692 var /** @type {?} */ touchEventsTarget = s.touchEventsTarget === 'container' ? s.container : s._wrapper;
62693 // Touch Events
62694 if (s._supportTouch) {
62695 // touchstart
62696 plt.registerListener(touchEventsTarget, s._touchEvents.start, function (ev) {
62697 onTouchStart$1(s, plt, ev);
62698 }, { passive: true, zone: false }, unregs);
62699 // touchmove
62700 plt.registerListener(touchEventsTarget, s._touchEvents.move, function (ev) {
62701 onTouchMove$1(s, plt, ev);
62702 }, { zone: false }, unregs);
62703 // touchend
62704 plt.registerListener(touchEventsTarget, s._touchEvents.end, function (ev) {
62705 onTouchEnd$1(s, plt, ev);
62706 }, { passive: true, zone: false }, unregs);
62707 }
62708 if ((s.simulateTouch && !plt.is('ios') && !plt.is('android')) || (s.simulateTouch && !s._supportTouch && plt.is('ios')) || plt.getQueryParam('ionicPlatform')) {
62709 // mousedown
62710 plt.registerListener(touchEventsTarget, 'mousedown', function (ev) {
62711 onTouchStart$1(s, plt, ev);
62712 }, { zone: false }, unregs);
62713 // mousemove
62714 plt.registerListener(plt.doc(), 'mousemove', function (ev) {
62715 onTouchMove$1(s, plt, ev);
62716 }, { zone: false }, unregs);
62717 // mouseup
62718 plt.registerListener(plt.doc(), 'mouseup', function (ev) {
62719 onTouchEnd$1(s, plt, ev);
62720 }, { zone: false }, unregs);
62721 }
62722 // onresize
62723 var /** @type {?} */ resizeObs = plt.resize.subscribe(function () { return onResize(s, plt, false); });
62724 // Next, Prev, Index
62725 if (s.nextButton) {
62726 plt.registerListener(s.nextButton, 'click', function (ev) {
62727 onClickNext(s, plt, ev);
62728 }, { zone: false }, unregs);
62729 }
62730 if (s.prevButton) {
62731 plt.registerListener(s.prevButton, 'click', function (ev) {
62732 onClickPrev(s, plt, ev);
62733 }, { zone: false }, unregs);
62734 }
62735 if (s.paginationType) {
62736 plt.registerListener(s._paginationContainer, 'click', function (ev) {
62737 onClickIndex(s, plt, ev);
62738 }, { zone: false }, unregs);
62739 }
62740 // Prevent Links Clicks
62741 if (s.preventClicks || s.preventClicksPropagation) {
62742 plt.registerListener(touchEventsTarget, 'click', function (ev) {
62743 preventClicks(s, ev);
62744 }, { zone: false, capture: true }, unregs);
62745 }
62746 // return a function that removes all of the added listeners
62747 return function () {
62748 resizeObs.unsubscribe();
62749 unregs.forEach(function (unreg) {
62750 unreg();
62751 });
62752 unregs = null;
62753 };
62754}
62755/**
62756 * @param {?} s
62757 * @param {?} e
62758 * @return {?}
62759 */
62760function preventClicks(s, e) {
62761 if (!s._allowClick) {
62762 if (s.preventClicks) {
62763 e.preventDefault();
62764 }
62765 if (s.preventClicksPropagation && s._animating) {
62766 e.stopPropagation();
62767 e.stopImmediatePropagation();
62768 }
62769 }
62770}
62771/**
62772 * @param {?} s
62773 * @param {?} plt
62774 * @param {?} e
62775 * @return {?}
62776 */
62777function onClickNext(s, plt, e) {
62778 e.preventDefault();
62779 if (s._isEnd && !s.loop) {
62780 return;
62781 }
62782 slideNext(s, plt);
62783}
62784/**
62785 * @param {?} s
62786 * @param {?} plt
62787 * @param {?} e
62788 * @return {?}
62789 */
62790function onClickPrev(s, plt, e) {
62791 e.preventDefault();
62792 if (s._isBeginning && !s.loop) {
62793 return;
62794 }
62795 slidePrev(s, plt);
62796}
62797/**
62798 * @param {?} s
62799 * @param {?} plt
62800 * @param {?} e
62801 * @return {?}
62802 */
62803function onClickIndex(s, plt, e) {
62804 var /** @type {?} */ indexStr = ((e.target)).getAttribute('data-slide-index');
62805 if (indexStr) {
62806 var /** @type {?} */ index = parseInt(indexStr, 10);
62807 e.preventDefault();
62808 if (s.loop) {
62809 index = index + s.loopedSlides;
62810 }
62811 slideTo(s, plt, index);
62812 }
62813}
62814/**
62815 * @param {?} e
62816 * @param {?} selector
62817 * @return {?}
62818 */
62819function findElementInEvent(e, selector) {
62820 var /** @type {?} */ el = (e.target);
62821 if (!el.matches(selector)) {
62822 if (typeof selector === 'string') {
62823 el = (el.closest(selector));
62824 }
62825 else if (selector.nodeType) {
62826 var /** @type {?} */ parentEl = el.parentElement;
62827 while (parentEl) {
62828 if (parentEl === selector) {
62829 return selector;
62830 }
62831 }
62832 return undefined;
62833 }
62834 }
62835 return el;
62836}
62837/**
62838 * @param {?} s
62839 * @param {?} plt
62840 * @param {?} e
62841 * @return {?}
62842 */
62843function updateClickedSlide(s, plt, e) {
62844 var /** @type {?} */ slide = (findElementInEvent(e, '.' + CLS.slide));
62845 var /** @type {?} */ slideIndex = -1;
62846 if (slide) {
62847 for (var /** @type {?} */ i = 0; i < s._slides.length; i++) {
62848 if (s._slides[i] === slide) {
62849 slideIndex = i;
62850 break;
62851 }
62852 }
62853 }
62854 if (slide && slideIndex > -1) {
62855 s.clickedSlide = slide;
62856 s.clickedIndex = slideIndex;
62857 }
62858 else {
62859 s.clickedSlide = undefined;
62860 s.clickedIndex = undefined;
62861 return;
62862 }
62863 if (s.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s._activeIndex) {
62864 var /** @type {?} */ slideToIndex = s.clickedIndex;
62865 var /** @type {?} */ realIndex;
62866 var /** @type {?} */ slidesPerView = s.slidesPerView === 'auto' ? currentSlidesPerView(s) : (s.slidesPerView);
62867 if (s.loop) {
62868 if (s._animating)
62869 return;
62870 realIndex = parseInt(s.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
62871 if (s.centeredSlides) {
62872 if ((slideToIndex < s.loopedSlides - slidesPerView / 2) || (slideToIndex > s._slides.length - s.loopedSlides + slidesPerView / 2)) {
62873 fixLoop(s, plt);
62874 slideToIndex = getElementIndex(s._wrapper.querySelector('.' + CLS.slide + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + CLS.slideDuplicate + ')'));
62875 plt.timeout(function () {
62876 slideTo(s, plt, slideToIndex);
62877 });
62878 }
62879 else {
62880 slideTo(s, plt, slideToIndex);
62881 }
62882 }
62883 else {
62884 if (slideToIndex > s._slides.length - slidesPerView) {
62885 fixLoop(s, plt);
62886 slideToIndex = getElementIndex(s._wrapper.querySelector('.' + CLS.slide + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + CLS.slideDuplicate + ')'));
62887 plt.timeout(function () {
62888 slideTo(s, plt, slideToIndex);
62889 });
62890 }
62891 else {
62892 slideTo(s, plt, slideToIndex);
62893 }
62894 }
62895 }
62896 else {
62897 slideTo(s, plt, slideToIndex);
62898 }
62899 }
62900}
62901var isTouched;
62902var isMoved;
62903var allowTouchCallbacks;
62904var touchStartTime;
62905var isScrolling;
62906var currentTranslate;
62907var startTranslate;
62908var allowThresholdMove;
62909// Last click time
62910var lastClickTime = Date.now();
62911var clickTimeout;
62912// Velocities
62913var velocities = [];
62914var allowMomentumBounce;
62915// Touch handlers
62916var isTouchEvent;
62917var startMoving;
62918/**
62919 * @param {?} s
62920 * @param {?} plt
62921 * @param {?} ev
62922 * @return {?}
62923 */
62924function onTouchStart$1(s, plt, ev) {
62925 (void 0) /* console.debug */;
62926 if (ev.originalEvent) {
62927 ev = ev.originalEvent;
62928 }
62929 s.originalEvent = ev;
62930 isTouchEvent = ev.type === 'touchstart';
62931 if (!isTouchEvent && 'which' in ev && ev.which === 3) {
62932 return;
62933 }
62934 if (s.noSwiping && findElementInEvent(ev, '.' + CLS.noSwiping)) {
62935 s._allowClick = true;
62936 return;
62937 }
62938 if (s.swipeHandler) {
62939 if (!findElementInEvent(ev, s.swipeHandler))
62940 return;
62941 }
62942 var /** @type {?} */ startX = s._touches.currentX = ev.type === 'touchstart' ? ev.targetTouches[0].pageX : ev.pageX;
62943 var /** @type {?} */ startY = s._touches.currentY = ev.type === 'touchstart' ? ev.targetTouches[0].pageY : ev.pageY;
62944 // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
62945 if (plt.is('ios') && s.iOSEdgeSwipeDetection && startX <= s.iOSEdgeSwipeThreshold) {
62946 return;
62947 }
62948 isTouched = true;
62949 isMoved = false;
62950 allowTouchCallbacks = true;
62951 isScrolling = undefined;
62952 startMoving = undefined;
62953 s._touches.startX = startX;
62954 s._touches.startY = startY;
62955 touchStartTime = Date.now();
62956 s._allowClick = true;
62957 updateContainerSize(s, plt);
62958 s.swipeDirection = undefined;
62959 if (s.threshold > 0) {
62960 allowThresholdMove = false;
62961 }
62962 if (ev.type !== 'touchstart') {
62963 var /** @type {?} */ preventDefault = true;
62964 if (isFormElement(ev.target)) {
62965 preventDefault = false;
62966 }
62967 plt.focusOutActiveElement();
62968 if (preventDefault) {
62969 ev.preventDefault();
62970 }
62971 }
62972 s.ionSlideTouchStart.emit(ev);
62973}
62974/**
62975 * @param {?} s
62976 * @param {?} plt
62977 * @param {?} ev
62978 * @return {?}
62979 */
62980function onTouchMove$1(s, plt, ev) {
62981 (void 0) /* console.debug */;
62982 if (ev.originalEvent) {
62983 ev = ev.originalEvent;
62984 }
62985 s.originalEvent = ev;
62986 if (isTouchEvent && ev.type === 'mousemove')
62987 return;
62988 if (ev.preventedByNestedSwiper) {
62989 s._touches.startX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
62990 s._touches.startY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
62991 return;
62992 }
62993 if (s.onlyExternal) {
62994 // isMoved = true;
62995 s._allowClick = false;
62996 if (isTouched) {
62997 s._touches.startX = s._touches.currentX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
62998 s._touches.startY = s._touches.currentY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
62999 touchStartTime = Date.now();
63000 }
63001 return;
63002 }
63003 if (isTouchEvent && s.touchReleaseOnEdges && !s.loop) {
63004 if (!isHorizontal(s)) {
63005 // Vertical
63006 if ((s._touches.currentY < s._touches.startY && s._translate <= maxTranslate(s)) ||
63007 (s._touches.currentY > s._touches.startY && s._translate >= minTranslate(s))) {
63008 return;
63009 }
63010 }
63011 else {
63012 if ((s._touches.currentX < s._touches.startX && s._translate <= maxTranslate(s)) ||
63013 (s._touches.currentX > s._touches.startX && s._translate >= minTranslate(s))) {
63014 return;
63015 }
63016 }
63017 }
63018 var /** @type {?} */ activeEle = plt.getActiveElement();
63019 if (isTouchEvent && activeEle) {
63020 if (ev.target === activeEle && isFormElement(ev.target)) {
63021 isMoved = true;
63022 s._allowClick = false;
63023 return;
63024 }
63025 }
63026 if (ev.targetTouches && ev.targetTouches.length > 1)
63027 return;
63028 s._touches.currentX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
63029 s._touches.currentY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
63030 if (typeof isScrolling === 'undefined') {
63031 var /** @type {?} */ touchAngle;
63032 if (isHorizontal(s) && s._touches.currentY === s._touches.startY || !isHorizontal(s) && s._touches.currentX === s._touches.startX) {
63033 isScrolling = false;
63034 }
63035 else {
63036 touchAngle = Math.atan2(Math.abs(s._touches.currentY - s._touches.startY), Math.abs(s._touches.currentX - s._touches.startX)) * 180 / Math.PI;
63037 isScrolling = isHorizontal(s) ? touchAngle > s.touchAngle : (90 - touchAngle > s.touchAngle);
63038 }
63039 }
63040 if (!isTouched)
63041 return;
63042 if (isScrolling) {
63043 isTouched = false;
63044 return;
63045 }
63046 s._allowClick = false;
63047 s.ionSlideDrag.emit(s);
63048 ev.preventDefault();
63049 if (s.touchMoveStopPropagation) {
63050 ev.stopPropagation();
63051 }
63052 if (!isMoved) {
63053 if (s.loop) {
63054 fixLoop(s, plt);
63055 }
63056 startTranslate = getWrapperTranslate(s, plt);
63057 setWrapperTransition(s, plt, 0);
63058 if (s._animating) {
63059 triggerTransitionEnd(plt, s._wrapper);
63060 }
63061 if (s.autoplay && s._autoplaying) {
63062 if (s.autoplayDisableOnInteraction) {
63063 stopAutoplay(s);
63064 }
63065 else {
63066 pauseAutoplay(s, plt);
63067 }
63068 }
63069 allowMomentumBounce = false;
63070 }
63071 isMoved = true;
63072 var /** @type {?} */ diff = s._touches.diff = isHorizontal(s) ? s._touches.currentX - s._touches.startX : s._touches.currentY - s._touches.startY;
63073 diff = diff * s.touchRatio;
63074 if (s._rtl)
63075 diff = -diff;
63076 s.swipeDirection = diff > 0 ? 'prev' : 'next';
63077 currentTranslate = diff + startTranslate;
63078 var /** @type {?} */ disableParentSwiper = true;
63079 if ((diff > 0 && currentTranslate > minTranslate(s))) {
63080 disableParentSwiper = false;
63081 if (s.resistance) {
63082 currentTranslate = minTranslate(s) - 1 + Math.pow(-minTranslate(s) + startTranslate + diff, s.resistanceRatio);
63083 }
63084 }
63085 else if (diff < 0 && currentTranslate < maxTranslate(s)) {
63086 disableParentSwiper = false;
63087 if (s.resistance)
63088 currentTranslate = maxTranslate(s) + 1 - Math.pow(maxTranslate(s) - startTranslate - diff, s.resistanceRatio);
63089 }
63090 if (disableParentSwiper) {
63091 ev.preventedByNestedSwiper = true;
63092 }
63093 // Directions locks
63094 if (!s._allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
63095 currentTranslate = startTranslate;
63096 }
63097 if (!s._allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
63098 currentTranslate = startTranslate;
63099 }
63100 // Threshold
63101 if (s.threshold > 0) {
63102 if (Math.abs(diff) > s.threshold || allowThresholdMove) {
63103 if (!allowThresholdMove) {
63104 allowThresholdMove = true;
63105 s._touches.startX = s._touches.currentX;
63106 s._touches.startY = s._touches.currentY;
63107 currentTranslate = startTranslate;
63108 s._touches.diff = isHorizontal(s) ? s._touches.currentX - s._touches.startX : s._touches.currentY - s._touches.startY;
63109 return;
63110 }
63111 }
63112 else {
63113 currentTranslate = startTranslate;
63114 return;
63115 }
63116 }
63117 if (!s.followFinger)
63118 return;
63119 // Update active index in free mode
63120 if (s.freeMode || s.watchSlidesProgress) {
63121 updateActiveIndex(s);
63122 }
63123 if (s.freeMode) {
63124 // Velocity
63125 if (velocities.length === 0) {
63126 velocities.push({
63127 position: ((s._touches))[isHorizontal(s) ? 'startX' : 'startY'],
63128 time: touchStartTime
63129 });
63130 }
63131 velocities.push({
63132 position: ((s._touches))[isHorizontal(s) ? 'currentX' : 'currentY'],
63133 time: (new Date()).getTime()
63134 });
63135 }
63136 // Update progress
63137 updateProgress(s, currentTranslate);
63138 // Update translate
63139 setWrapperTranslate(s, plt, currentTranslate);
63140}
63141/**
63142 * @param {?} s
63143 * @param {?} plt
63144 * @param {?} ev
63145 * @return {?}
63146 */
63147function onTouchEnd$1(s, plt, ev) {
63148 (void 0) /* console.debug */;
63149 if (ev.originalEvent) {
63150 ev = ev.originalEvent;
63151 }
63152 s.originalEvent = ev;
63153 if (allowTouchCallbacks) {
63154 s.ionSlideTouchEnd.emit(ev);
63155 }
63156 allowTouchCallbacks = false;
63157 if (!isTouched)
63158 return;
63159 // Time diff
63160 var /** @type {?} */ touchEndTime = Date.now();
63161 var /** @type {?} */ timeDiff = touchEndTime - touchStartTime;
63162 // Tap, doubleTap, Click
63163 if (s._allowClick) {
63164 updateClickedSlide(s, plt, ev);
63165 s._zone.run(function () {
63166 s.ionSlideTap.emit(s);
63167 if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
63168 if (clickTimeout) {
63169 plt.cancelTimeout(clickTimeout);
63170 }
63171 clickTimeout = plt.timeout(function () {
63172 if (!s)
63173 return;
63174 if (s.paginationHide && s._paginationContainer && !((ev.target)).classList.contains(CLS.bullet)) {
63175 s._paginationContainer.classList.toggle(CLS.paginationHidden);
63176 }
63177 }, 300);
63178 }
63179 if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
63180 if (clickTimeout)
63181 clearTimeout(clickTimeout);
63182 s.ionSlideDoubleTap.emit(s);
63183 }
63184 });
63185 }
63186 lastClickTime = Date.now();
63187 plt.timeout(function () {
63188 if (s) {
63189 s._allowClick = true;
63190 }
63191 });
63192 if (!isTouched || !isMoved || !s.swipeDirection || s._touches.diff === 0 || currentTranslate === startTranslate) {
63193 isTouched = isMoved = false;
63194 return;
63195 }
63196 isTouched = isMoved = false;
63197 var /** @type {?} */ currentPos;
63198 if (s.followFinger) {
63199 currentPos = s._rtl ? s._translate : -s._translate;
63200 }
63201 else {
63202 currentPos = -currentTranslate;
63203 }
63204 if (s.freeMode) {
63205 if (currentPos < -minTranslate(s)) {
63206 slideTo(s, plt, s._activeIndex);
63207 return;
63208 }
63209 else if (currentPos > -maxTranslate(s)) {
63210 if (s._slides.length < s._snapGrid.length) {
63211 slideTo(s, plt, s._snapGrid.length - 1);
63212 }
63213 else {
63214 slideTo(s, plt, s._slides.length - 1);
63215 }
63216 return;
63217 }
63218 if (s.freeModeMomentum) {
63219 if (velocities.length > 1) {
63220 var /** @type {?} */ lastMoveEvent = velocities.pop(), /** @type {?} */ velocityEvent = velocities.pop();
63221 var /** @type {?} */ distance = lastMoveEvent.position - velocityEvent.position;
63222 var /** @type {?} */ time = lastMoveEvent.time - velocityEvent.time;
63223 s.velocity = distance / time;
63224 s.velocity = s.velocity / 2;
63225 if (Math.abs(s.velocity) < s.freeModeMinimumVelocity) {
63226 s.velocity = 0;
63227 }
63228 // this implies that the user stopped moving a finger then released.
63229 // There would be no events with distance zero, so the last event is stale.
63230 if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) {
63231 s.velocity = 0;
63232 }
63233 }
63234 else {
63235 s.velocity = 0;
63236 }
63237 s.velocity = s.velocity * s.freeModeMomentumVelocityRatio;
63238 velocities.length = 0;
63239 var /** @type {?} */ momentumDuration = 1000 * s.freeModeMomentumRatio;
63240 var /** @type {?} */ momentumDistance = s.velocity * momentumDuration;
63241 var /** @type {?} */ newPosition = s._translate + momentumDistance;
63242 if (s._rtl)
63243 newPosition = -newPosition;
63244 var /** @type {?} */ doBounce = false;
63245 var /** @type {?} */ afterBouncePosition;
63246 var /** @type {?} */ bounceAmount = Math.abs(s.velocity) * 20 * s.freeModeMomentumBounceRatio;
63247 if (newPosition < maxTranslate(s)) {
63248 if (s.freeModeMomentumBounce) {
63249 if (newPosition + maxTranslate(s) < -bounceAmount) {
63250 newPosition = maxTranslate(s) - bounceAmount;
63251 }
63252 afterBouncePosition = maxTranslate(s);
63253 doBounce = true;
63254 allowMomentumBounce = true;
63255 }
63256 else {
63257 newPosition = maxTranslate(s);
63258 }
63259 }
63260 else if (newPosition > minTranslate(s)) {
63261 if (s.freeModeMomentumBounce) {
63262 if (newPosition - minTranslate(s) > bounceAmount) {
63263 newPosition = minTranslate(s) + bounceAmount;
63264 }
63265 afterBouncePosition = minTranslate(s);
63266 doBounce = true;
63267 allowMomentumBounce = true;
63268 }
63269 else {
63270 newPosition = minTranslate(s);
63271 }
63272 }
63273 else if (s.freeModeSticky) {
63274 var /** @type {?} */ j = 0;
63275 var /** @type {?} */ nextSlide;
63276 for (j = 0; j < s._snapGrid.length; j += 1) {
63277 if (s._snapGrid[j] > -newPosition) {
63278 nextSlide = j;
63279 break;
63280 }
63281 }
63282 if (Math.abs(s._snapGrid[nextSlide] - newPosition) < Math.abs(s._snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
63283 newPosition = s._snapGrid[nextSlide];
63284 }
63285 else {
63286 newPosition = s._snapGrid[nextSlide - 1];
63287 }
63288 if (!s._rtl)
63289 newPosition = -newPosition;
63290 }
63291 // Fix duration
63292 if (s.velocity !== 0) {
63293 if (s._rtl) {
63294 momentumDuration = Math.abs((-newPosition - s._translate) / s.velocity);
63295 }
63296 else {
63297 momentumDuration = Math.abs((newPosition - s._translate) / s.velocity);
63298 }
63299 }
63300 else if (s.freeModeSticky) {
63301 slideReset(s, plt);
63302 return;
63303 }
63304 if (s.freeModeMomentumBounce && doBounce) {
63305 updateProgress(s, afterBouncePosition);
63306 setWrapperTransition(s, plt, momentumDuration);
63307 setWrapperTranslate(s, plt, newPosition);
63308 onTransitionStart(s);
63309 s._animating = true;
63310 plt.transitionEnd(s._wrapper, function () {
63311 if (!s || !allowMomentumBounce)
63312 return;
63313 setWrapperTransition(s, plt, s.speed);
63314 setWrapperTranslate(s, plt, afterBouncePosition);
63315 plt.transitionEnd(s._wrapper, function () {
63316 if (!s)
63317 return;
63318 onTransitionEnd(s, plt);
63319 });
63320 });
63321 }
63322 else if (s.velocity) {
63323 updateProgress(s, newPosition);
63324 setWrapperTransition(s, plt, momentumDuration);
63325 setWrapperTranslate(s, plt, newPosition);
63326 onTransitionStart(s);
63327 if (!s._animating) {
63328 s._animating = true;
63329 plt.transitionEnd(s._wrapper, function () {
63330 if (!s)
63331 return;
63332 onTransitionEnd(s, plt);
63333 });
63334 }
63335 }
63336 else {
63337 updateProgress(s, newPosition);
63338 }
63339 updateActiveIndex(s);
63340 }
63341 if (!s.freeModeMomentum || timeDiff >= s.longSwipesMs) {
63342 updateProgress(s);
63343 updateActiveIndex(s);
63344 }
63345 return;
63346 }
63347 // Find current slide
63348 var /** @type {?} */ stopIndex = 0;
63349 var /** @type {?} */ groupSize = s._slidesSizesGrid[0];
63350 for (var /** @type {?} */ i = 0; i < s._slidesGrid.length; i += s.slidesPerGroup) {
63351 if (typeof s._slidesGrid[i + s.slidesPerGroup] !== 'undefined') {
63352 if (currentPos >= s._slidesGrid[i] && currentPos < s._slidesGrid[i + s.slidesPerGroup]) {
63353 stopIndex = i;
63354 groupSize = s._slidesGrid[i + s.slidesPerGroup] - s._slidesGrid[i];
63355 }
63356 }
63357 else {
63358 if (currentPos >= s._slidesGrid[i]) {
63359 stopIndex = i;
63360 groupSize = s._slidesGrid[s._slidesGrid.length - 1] - s._slidesGrid[s._slidesGrid.length - 2];
63361 }
63362 }
63363 }
63364 // Find current slide size
63365 var /** @type {?} */ ratio = (currentPos - s._slidesGrid[stopIndex]) / groupSize;
63366 if (timeDiff > s.longSwipesMs) {
63367 // Long touches
63368 if (!s.longSwipes) {
63369 slideTo(s, plt, s._activeIndex);
63370 return;
63371 }
63372 if (s.swipeDirection === 'next') {
63373 if (ratio >= s.longSwipesRatio) {
63374 slideTo(s, plt, stopIndex + s.slidesPerGroup);
63375 }
63376 else {
63377 slideTo(s, plt, stopIndex);
63378 }
63379 }
63380 if (s.swipeDirection === 'prev') {
63381 if (ratio > (1 - s.longSwipesRatio)) {
63382 slideTo(s, plt, stopIndex + s.slidesPerGroup);
63383 }
63384 else {
63385 slideTo(s, plt, stopIndex);
63386 }
63387 }
63388 }
63389 else {
63390 // Short swipes
63391 if (!s.shortSwipes) {
63392 slideTo(s, plt, s._activeIndex);
63393 return;
63394 }
63395 if (s.swipeDirection === 'next') {
63396 slideTo(s, plt, stopIndex + s.slidesPerGroup);
63397 }
63398 if (s.swipeDirection === 'prev') {
63399 slideTo(s, plt, stopIndex);
63400 }
63401 }
63402}
63403/*=========================
63404 Resize Handler
63405 ===========================*/
63406var resizeId;
63407/**
63408 * @param {?} s
63409 * @param {?} plt
63410 * @param {?} forceUpdatePagination
63411 * @return {?}
63412 */
63413function onResize(s, plt, forceUpdatePagination) {
63414 // TODO: hacky, we should use Resize Observer in the future
63415 if (resizeId) {
63416 plt.cancelTimeout(resizeId);
63417 resizeId = null;
63418 }
63419 resizeId = plt.timeout(function () { return doResize(s, plt, forceUpdatePagination); }, 200);
63420}
63421/**
63422 * @param {?} s
63423 * @param {?} plt
63424 * @param {?} forceUpdatePagination
63425 * @return {?}
63426 */
63427function doResize(s, plt, forceUpdatePagination) {
63428 resizeId = null;
63429 // Disable locks on resize
63430 var /** @type {?} */ allowSwipeToPrev = s._allowSwipeToPrev;
63431 var /** @type {?} */ allowSwipeToNext = s._allowSwipeToNext;
63432 s._allowSwipeToPrev = s._allowSwipeToNext = true;
63433 updateContainerSize(s, plt);
63434 updateSlidesSize(s, plt);
63435 if (s.slidesPerView === 'auto' || s.freeMode || forceUpdatePagination) {
63436 updatePagination(s);
63437 }
63438 if (s._spline) {
63439 s._spline = undefined;
63440 }
63441 var /** @type {?} */ slideChangedBySlideTo = false;
63442 if (s.freeMode) {
63443 var /** @type {?} */ newTranslate = Math.min(Math.max(s._translate, maxTranslate(s)), minTranslate(s));
63444 setWrapperTranslate(s, plt, newTranslate);
63445 updateActiveIndex(s);
63446 updateClasses(s);
63447 if (s.autoHeight) {
63448 updateAutoHeight(s);
63449 }
63450 }
63451 else {
63452 updateClasses(s);
63453 if ((s.slidesPerView === 'auto' || s.slidesPerView > 1) && s._isEnd && !s.centeredSlides) {
63454 slideChangedBySlideTo = slideTo(s, plt, s._slides.length - 1, 0, false, true);
63455 }
63456 else {
63457 slideChangedBySlideTo = slideTo(s, plt, s._activeIndex, 0, false, true);
63458 }
63459 }
63460 // Return locks after resize
63461 s._allowSwipeToPrev = allowSwipeToPrev;
63462 s._allowSwipeToNext = allowSwipeToNext;
63463}
63464
63465var __extends$76 = (undefined && undefined.__extends) || (function () {
63466 var extendStatics = Object.setPrototypeOf ||
63467 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
63468 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
63469 return function (d, b) {
63470 extendStatics(d, b);
63471 function __() { this.constructor = d; }
63472 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
63473 };
63474})();
63475/**
63476 * \@name Slides
63477 * \@description
63478 * The Slides component is a multi-section container. Each section can be swiped
63479 * or dragged between. It contains any number of [Slide](../Slide) components.
63480 *
63481 *
63482 * ### Creating
63483 * You should use a template to create slides and listen to slide events. The template
63484 * should contain the slide container, an `<ion-slides>` element, and any number of
63485 * [Slide](../Slide) components, written as `<ion-slide>`. Basic configuration
63486 * values can be set as input properties, which are listed below. Slides events
63487 * can also be listened to such as the slide changing by placing the event on the
63488 * `<ion-slides>` element. See [Usage](#usage) below for more information.
63489 *
63490 *
63491 * ### Navigating
63492 * After creating and configuring the slides, you can navigate between them
63493 * by swiping or calling methods on the `Slides` instance. You can call `slideTo()` to
63494 * navigate to a specific slide, or `slideNext()` to change to the slide that follows
63495 * the active slide. All of the [methods](#instance-members) provided by the `Slides`
63496 * instance are listed below. See [Usage](#usage) below for more information on
63497 * navigating between slides.
63498 *
63499 *
63500 * \@usage
63501 *
63502 * You can add slides to a `\@Component` using the following template:
63503 *
63504 * ```html
63505 * <ion-slides>
63506 * <ion-slide>
63507 * <h1>Slide 1</h1>
63508 * </ion-slide>
63509 * <ion-slide>
63510 * <h1>Slide 2</h1>
63511 * </ion-slide>
63512 * <ion-slide>
63513 * <h1>Slide 3</h1>
63514 * </ion-slide>
63515 * </ion-slides>
63516 * ```
63517 *
63518 * Next, we can use `ViewChild` to assign the Slides instance to
63519 * your `slides` property. Now we can call any of the `Slides`
63520 * [methods](#instance-members), for example we can use the Slide's
63521 * `slideTo()` method in order to navigate to a specific slide on
63522 * a button click. Below we call the `goToSlide()` method and it
63523 * navigates to the 3rd slide:
63524 *
63525 * ```ts
63526 * import { ViewChild } from '\@angular/core';
63527 * import { Slides } from 'ionic-angular';
63528 *
63529 * class MyPage {
63530 * \@ViewChild(Slides) slides: Slides;
63531 *
63532 * goToSlide() {
63533 * this.slides.slideTo(2, 500);
63534 * }
63535 * }
63536 * ```
63537 *
63538 * We can also add events to listen to on the `<ion-slides>` element.
63539 * Let's add the `ionSlideDidChange` event and call a method when the slide changes:
63540 *
63541 * ```html
63542 * <ion-slides (ionSlideDidChange)="slideChanged()">
63543 * ```
63544 *
63545 * In our class, we add the `slideChanged()` method which gets the active
63546 * index and prints it:
63547 *
63548 * ```ts
63549 * class MyPage {
63550 * ...
63551 *
63552 * slideChanged() {
63553 * let currentIndex = this.slides.getActiveIndex();
63554 * console.log('Current index is', currentIndex);
63555 * }
63556 * }
63557 * ```
63558 *
63559 * ### Zooming
63560 * If your slides contain images, you can enable zooming on them by setting `zoom="true" and
63561 * wrapping each image in a `div` with the class `swiper-zoom-container`. Zoom supports
63562 * `img`, `svg`, `canvas`, and `ion-img`.
63563 *
63564 * ```html
63565 * <ion-slidesj zoom="true">
63566 * <ion-slide>
63567 * <div class="swiper-zoom-container">
63568 * <img src="assets/img/dog.jpg">
63569 * </div>
63570 * <ion-label>Woof</ion-label>
63571 * </ion-slide>
63572 * <ion-slide>
63573 * <div class="swiper-zoom-container">
63574 * <img src="assets/img/cat.jpg">
63575 * </div>
63576 * <ion-label>Meow</ion-label>
63577 * </ion-slide>
63578 * <ion-slide>
63579 * <div class="swiper-zoom-container">
63580 * <img src="assets/img/fish.jpg">
63581 * </div>
63582 * <ion-label>Just keep swimming</ion-label>
63583 * </ion-slide>
63584 * </ion-slides>
63585 * ```
63586 *
63587 * \@advanced
63588 *
63589 * There are several options available to create customized slides. Ionic exposes
63590 * the most commonly used options as [inputs](http://learnangular2.com/inputs/).
63591 * In order to use an option that isn't exposed as an input the following code
63592 * should be used, where `freeMode` is the option to change:
63593 *
63594 * ```ts
63595 * import { ViewChild } from '\@angular/core';
63596 * import { Slides } from 'ionic-angular';
63597 * class MyPage {
63598 * \@ViewChild(Slides) slides: Slides;
63599 *
63600 * ngAfterViewInit() {
63601 * this.slides.freeMode = true;
63602 * }
63603 * }
63604 *
63605 * ```
63606 *
63607 * To see all of the available options, take a look at the
63608 * [source for slides](https://github.com/ionic-team/ionic/blob/master/src/components/slides/slides.ts).
63609 *
63610 * \@demo /docs/demos/src/slides/
63611 * @see {\@link /docs/components#slides Slides Component Docs}
63612 *
63613 * Adopted from Swiper.js:
63614 * The most modern mobile touch slider and framework with
63615 * hardware accelerated transitions.
63616 *
63617 * http://www.idangero.us/swiper/
63618 *
63619 * Copyright 2016, Vladimir Kharlampidi
63620 * The iDangero.us
63621 * http://www.idangero.us/
63622 *
63623 * Licensed under MIT
63624 */
63625var Slides = (function (_super) {
63626 __extends$76(Slides, _super);
63627 /**
63628 * @param {?} config
63629 * @param {?} _plt
63630 * @param {?} zone
63631 * @param {?} viewCtrl
63632 * @param {?} elementRef
63633 * @param {?} renderer
63634 */
63635 function Slides(config, _plt, zone, viewCtrl, elementRef, renderer) {
63636 var _this = _super.call(this, config, elementRef, renderer, 'slides') || this;
63637 _this._plt = _plt;
63638 _this._control = null;
63639 _this._effectName = 'slide';
63640 _this._direction = 'horizontal';
63641 _this._initialSlide = 0;
63642 _this._isLoop = false;
63643 _this._pager = false;
63644 _this._paginationType = 'bullets';
63645 /**
63646 * @hidden
63647 */
63648 _this.paginationBulletRender = null;
63649 _this._isParallax = false;
63650 _this._speedMs = 300;
63651 _this._isZoom = false;
63652 /**
63653 * @hidden
63654 * Enabled this option and swiper will be operated as usual except it will
63655 * not move, real translate values on wrapper will not be set. Useful when
63656 * you may need to create custom slide transition.
63657 */
63658 _this.virtualTranslate = false;
63659 /**
63660 * @hidden
63661 * Set to true to round values of slides width and height to prevent blurry
63662 * texts on usual resolution screens (if you have such)
63663 */
63664 _this.roundLengths = false;
63665 _this._spaceBetween = 0;
63666 _this._slidesPerView = 1;
63667 _this._centeredSlides = false;
63668 /**
63669 * @hidden
63670 */
63671 _this.slidesPerColumn = 1;
63672 /**
63673 * @hidden
63674 */
63675 _this.slidesPerColumnFill = 'column';
63676 /**
63677 * @hidden
63678 */
63679 _this.slidesPerGroup = 1;
63680 /**
63681 * @hidden
63682 */
63683 _this.slidesOffsetBefore = 0;
63684 /**
63685 * @hidden
63686 */
63687 _this.slidesOffsetAfter = 0;
63688 /**
63689 * @hidden
63690 */
63691 _this.autoplayDisableOnInteraction = true;
63692 /**
63693 * @hidden
63694 */
63695 _this.autoplayStopOnLast = false;
63696 /**
63697 * @hidden
63698 */
63699 _this.freeMode = false;
63700 /**
63701 * @hidden
63702 */
63703 _this.freeModeMomentum = true;
63704 /**
63705 * @hidden
63706 */
63707 _this.freeModeMomentumRatio = 1;
63708 /**
63709 * @hidden
63710 */
63711 _this.freeModeMomentumBounce = true;
63712 /**
63713 * @hidden
63714 */
63715 _this.freeModeMomentumBounceRatio = 1;
63716 /**
63717 * @hidden
63718 */
63719 _this.freeModeMomentumVelocityRatio = 1;
63720 /**
63721 * @hidden
63722 */
63723 _this.freeModeSticky = false;
63724 /**
63725 * @hidden
63726 */
63727 _this.freeModeMinimumVelocity = 0.02;
63728 /**
63729 * @hidden
63730 */
63731 _this.autoHeight = false;
63732 /**
63733 * @hidden
63734 */
63735 _this.setWrapperSize = false;
63736 /**
63737 * @hidden
63738 */
63739 _this.zoomMax = 3;
63740 /**
63741 * @hidden
63742 */
63743 _this.zoomMin = 1;
63744 /**
63745 * @hidden
63746 */
63747 _this.zoomToggle = true;
63748 /**
63749 * @hidden
63750 */
63751 _this.touchRatio = 1;
63752 /**
63753 * @hidden
63754 */
63755 _this.touchAngle = 45;
63756 /**
63757 * @hidden
63758 */
63759 _this.simulateTouch = true;
63760 /**
63761 * @hidden
63762 */
63763 _this.shortSwipes = true;
63764 /**
63765 * @hidden
63766 */
63767 _this.longSwipes = true;
63768 /**
63769 * @hidden
63770 */
63771 _this.longSwipesRatio = 0.5;
63772 /**
63773 * @hidden
63774 */
63775 _this.longSwipesMs = 300;
63776 /**
63777 * @hidden
63778 */
63779 _this.followFinger = true;
63780 /**
63781 * @hidden
63782 */
63783 _this.onlyExternal = false;
63784 /**
63785 * @hidden
63786 */
63787 _this.threshold = 0;
63788 /**
63789 * @hidden
63790 */
63791 _this.touchMoveStopPropagation = true;
63792 /**
63793 * @hidden
63794 */
63795 _this.touchReleaseOnEdges = false;
63796 /**
63797 * @hidden
63798 */
63799 _this.iOSEdgeSwipeDetection = false;
63800 /**
63801 * @hidden
63802 */
63803 _this.iOSEdgeSwipeThreshold = 20;
63804 /**
63805 * @hidden
63806 */
63807 _this.paginationClickable = false;
63808 /**
63809 * @hidden
63810 */
63811 _this.paginationHide = false;
63812 /**
63813 * @hidden
63814 */
63815 _this.resistance = true;
63816 /**
63817 * @hidden
63818 */
63819 _this.resistanceRatio = 0.85;
63820 /**
63821 * @hidden
63822 */
63823 _this.watchSlidesProgress = false;
63824 /**
63825 * @hidden
63826 */
63827 _this.watchSlidesVisibility = false;
63828 /**
63829 * @hidden
63830 */
63831 _this.preventClicks = true;
63832 /**
63833 * @hidden
63834 */
63835 _this.preventClicksPropagation = true;
63836 /**
63837 * @hidden
63838 */
63839 _this.slideToClickedSlide = false;
63840 /**
63841 * @hidden
63842 */
63843 _this.loopAdditionalSlides = 0;
63844 /**
63845 * @hidden
63846 */
63847 _this.loopedSlides = null;
63848 /**
63849 * @hidden
63850 */
63851 _this.swipeHandler = null;
63852 /**
63853 * @hidden
63854 */
63855 _this.noSwiping = true;
63856 /**
63857 * @hidden
63858 */
63859 _this.runCallbacksOnInit = true;
63860 // Controller
63861 _this.controlBy = 'slide';
63862 _this.controlInverse = false;
63863 /**
63864 * @hidden
63865 */
63866 _this.keyboardControl = true;
63867 /**
63868 * @hidden
63869 */
63870 _this.coverflow = {
63871 rotate: 50,
63872 stretch: 0,
63873 depth: 100,
63874 modifier: 1,
63875 slideShadows: true
63876 };
63877 /**
63878 * @hidden
63879 */
63880 _this.flip = {
63881 slideShadows: true,
63882 limitRotation: true
63883 };
63884 /**
63885 * @hidden
63886 */
63887 _this.cube = {
63888 slideShadows: true,
63889 shadow: true,
63890 shadowOffset: 20,
63891 shadowScale: 0.94
63892 };
63893 /**
63894 * @hidden
63895 */
63896 _this.fade = {
63897 crossFade: false
63898 };
63899 /**
63900 * @hidden
63901 */
63902 _this.prevSlideMessage = 'Previous slide';
63903 /**
63904 * @hidden
63905 */
63906 _this.nextSlideMessage = 'Next slide';
63907 /**
63908 * @hidden
63909 */
63910 _this.firstSlideMessage = 'This is the first slide';
63911 /**
63912 * @hidden
63913 */
63914 _this.lastSlideMessage = 'This is the last slide';
63915 /**
63916 * \@output {Slides} Emitted when a slide change starts.
63917 */
63918 _this.ionSlideWillChange = new EventEmitter();
63919 /**
63920 * \@output {Slides} Emitted when a slide change ends.
63921 */
63922 _this.ionSlideDidChange = new EventEmitter();
63923 /**
63924 * \@output {Slides} Emitted when a slide moves.
63925 */
63926 _this.ionSlideDrag = new EventEmitter();
63927 /**
63928 * \@output {Slides} Emitted when slides reaches its beginning (initial position).
63929 */
63930 _this.ionSlideReachStart = new EventEmitter();
63931 /**
63932 * \@output {Slides} Emitted when slides reaches its last slide.
63933 */
63934 _this.ionSlideReachEnd = new EventEmitter();
63935 /**
63936 * \@output {Slides} Emitted when a slide moves.
63937 */
63938 _this.ionSlideAutoplay = new EventEmitter();
63939 /**
63940 * \@output {Slides} Emitted when a autoplay starts.
63941 */
63942 _this.ionSlideAutoplayStart = new EventEmitter();
63943 /**
63944 * \@output {Slides} Emitted when a autoplay stops.
63945 */
63946 _this.ionSlideAutoplayStop = new EventEmitter();
63947 /**
63948 * \@output {Slides} Emitted when a slide change starts with the "forward" direction.
63949 */
63950 _this.ionSlideNextStart = new EventEmitter();
63951 /**
63952 * \@output {Slides} Emitted when a slide change starts with the "backward" direction.
63953 */
63954 _this.ionSlidePrevStart = new EventEmitter();
63955 /**
63956 * \@output {Slides} Emitted when a slide change ends with the "forward" direction.
63957 */
63958 _this.ionSlideNextEnd = new EventEmitter();
63959 /**
63960 * \@output {Slides} Emitted when a slide change ends with the "backward" direction.
63961 */
63962 _this.ionSlidePrevEnd = new EventEmitter();
63963 /**
63964 * \@output {Slides} Emitted when the user taps/clicks on the slide's container.
63965 */
63966 _this.ionSlideTap = new EventEmitter();
63967 /**
63968 * \@output {Slides} Emitted when the user double taps on the slide's container.
63969 */
63970 _this.ionSlideDoubleTap = new EventEmitter();
63971 /**
63972 * @hidden
63973 */
63974 _this.ionSlideProgress = new EventEmitter();
63975 /**
63976 * @hidden
63977 */
63978 _this.ionSlideTransitionStart = new EventEmitter();
63979 /**
63980 * @hidden
63981 */
63982 _this.ionSlideTransitionEnd = new EventEmitter();
63983 /**
63984 * @hidden
63985 */
63986 _this.ionSlideTouchStart = new EventEmitter();
63987 /**
63988 * @hidden
63989 */
63990 _this.ionSlideTouchEnd = new EventEmitter();
63991 _this._unregs = [];
63992 /**
63993 * \@internal
63994 */
63995 _this._allowSwipeToNext = true;
63996 /**
63997 * \@internal
63998 */
63999 _this._allowSwipeToPrev = true;
64000 _this._zone = zone;
64001 _this.id = ++slidesId;
64002 _this.slideId = 'slides-' + _this.id;
64003 _this.setElementClass(_this.slideId, true);
64004 // only initialize the slides whent the content is ready
64005 if (viewCtrl) {
64006 var subscription = viewCtrl.readReady.subscribe(function () {
64007 subscription.unsubscribe();
64008 _this._initSlides();
64009 });
64010 }
64011 return _this;
64012 }
64013 Object.defineProperty(Slides.prototype, "autoplay", {
64014 /**
64015 * \@input {number} Delay between transitions (in milliseconds). If this
64016 * parameter is not passed, autoplay is disabled. Default does
64017 * not have a value and does not autoplay.
64018 * Default: `null`.
64019 * @return {?}
64020 */
64021 get: function () {
64022 return this._autoplayMs;
64023 },
64024 /**
64025 * @param {?} val
64026 * @return {?}
64027 */
64028 set: function (val) {
64029 this._autoplayMs = parseInt(val, 10);
64030 },
64031 enumerable: true,
64032 configurable: true
64033 });
64034 Object.defineProperty(Slides.prototype, "control", {
64035 /**
64036 * \@input {Slides} Pass another Slides instance or array of Slides instances
64037 * that should be controlled by this Slides instance.
64038 * Default: `null`.
64039 * @return {?}
64040 */
64041 get: function () {
64042 return this._control;
64043 },
64044 /**
64045 * @param {?} val
64046 * @return {?}
64047 */
64048 set: function (val) {
64049 if (val instanceof Slides || Array.isArray(val)) {
64050 this._control = val;
64051 }
64052 },
64053 enumerable: true,
64054 configurable: true
64055 });
64056 Object.defineProperty(Slides.prototype, "effect", {
64057 /**
64058 * \@input {string} The animation effect of the slides.
64059 * Possible values are: `slide`, `fade`, `cube`, `coverflow` or `flip`.
64060 * Default: `slide`.
64061 * @return {?}
64062 */
64063 get: function () {
64064 return this._effectName;
64065 },
64066 /**
64067 * @param {?} effectName
64068 * @return {?}
64069 */
64070 set: function (effectName) {
64071 if (SWIPER_EFFECTS[effectName]) {
64072 this._effectName = effectName;
64073 }
64074 },
64075 enumerable: true,
64076 configurable: true
64077 });
64078 Object.defineProperty(Slides.prototype, "direction", {
64079 /**
64080 * \@input {string} Swipe direction: 'horizontal' or 'vertical'.
64081 * Default: `horizontal`.
64082 * @return {?}
64083 */
64084 get: function () {
64085 return this._direction;
64086 },
64087 /**
64088 * @param {?} val
64089 * @return {?}
64090 */
64091 set: function (val) {
64092 if (val === 'horizontal' || val === 'vertical') {
64093 this._direction = val;
64094 }
64095 },
64096 enumerable: true,
64097 configurable: true
64098 });
64099 Object.defineProperty(Slides.prototype, "initialSlide", {
64100 /**
64101 * \@input {number} Index number of initial slide. Default: `0`.
64102 * @return {?}
64103 */
64104 get: function () {
64105 return this._initialSlide;
64106 },
64107 /**
64108 * @param {?} val
64109 * @return {?}
64110 */
64111 set: function (val) {
64112 this._initialSlide = parseInt(val, 10);
64113 },
64114 enumerable: true,
64115 configurable: true
64116 });
64117 Object.defineProperty(Slides.prototype, "loop", {
64118 /**
64119 * \@input {boolean} If true, continuously loop from the last slide to the
64120 * first slide.
64121 * @return {?}
64122 */
64123 get: function () {
64124 return this._isLoop;
64125 },
64126 /**
64127 * @param {?} val
64128 * @return {?}
64129 */
64130 set: function (val) {
64131 this._isLoop = isTrueProperty(val);
64132 },
64133 enumerable: true,
64134 configurable: true
64135 });
64136 Object.defineProperty(Slides.prototype, "pager", {
64137 /**
64138 * \@input {boolean} If true, show the pager.
64139 * @return {?}
64140 */
64141 get: function () {
64142 return this._pager;
64143 },
64144 /**
64145 * @param {?} val
64146 * @return {?}
64147 */
64148 set: function (val) {
64149 this._pager = isTrueProperty(val);
64150 },
64151 enumerable: true,
64152 configurable: true
64153 });
64154 Object.defineProperty(Slides.prototype, "dir", {
64155 /**
64156 * \@input {string} If dir attribute is equal to rtl, set interal _rtl to true;
64157 * @param {?} val
64158 * @return {?}
64159 */
64160 set: function (val) {
64161 this._rtl = (val.toLowerCase() === 'rtl');
64162 },
64163 enumerable: true,
64164 configurable: true
64165 });
64166 Object.defineProperty(Slides.prototype, "paginationType", {
64167 /**
64168 * \@input {string} Type of pagination. Possible values are:
64169 * `bullets`, `fraction`, `progress`. Default: `bullets`.
64170 * (Note that the pager will not show unless `pager` input
64171 * is set to true).
64172 * @return {?}
64173 */
64174 get: function () {
64175 return this._paginationType;
64176 },
64177 /**
64178 * @param {?} val
64179 * @return {?}
64180 */
64181 set: function (val) {
64182 if (val === 'bullets' || val === 'fraction' || val === 'progress') {
64183 this._paginationType = val;
64184 }
64185 },
64186 enumerable: true,
64187 configurable: true
64188 });
64189 Object.defineProperty(Slides.prototype, "parallax", {
64190 /**
64191 * \@input {boolean} If true, allows you to use "parallaxed" elements inside of
64192 * slider.
64193 * @return {?}
64194 */
64195 get: function () {
64196 return this._isParallax;
64197 },
64198 /**
64199 * @param {?} val
64200 * @return {?}
64201 */
64202 set: function (val) {
64203 this._isParallax = isTrueProperty(val);
64204 },
64205 enumerable: true,
64206 configurable: true
64207 });
64208 Object.defineProperty(Slides.prototype, "speed", {
64209 /**
64210 * \@input {number} Duration of transition between slides
64211 * (in milliseconds). Default: `300`.
64212 * @return {?}
64213 */
64214 get: function () {
64215 return this._speedMs;
64216 },
64217 /**
64218 * @param {?} val
64219 * @return {?}
64220 */
64221 set: function (val) {
64222 this._speedMs = parseInt(val, 10);
64223 },
64224 enumerable: true,
64225 configurable: true
64226 });
64227 Object.defineProperty(Slides.prototype, "zoom", {
64228 /**
64229 * \@input {boolean} If true, enables zooming functionality.
64230 * @return {?}
64231 */
64232 get: function () {
64233 return this._isZoom;
64234 },
64235 /**
64236 * @param {?} val
64237 * @return {?}
64238 */
64239 set: function (val) {
64240 this._isZoom = isTrueProperty(val);
64241 },
64242 enumerable: true,
64243 configurable: true
64244 });
64245 Object.defineProperty(Slides.prototype, "spaceBetween", {
64246 /**
64247 * \@input {number} Distance between slides in px. Default: `0`.
64248 * @return {?}
64249 */
64250 get: function () {
64251 return this._spaceBetween;
64252 },
64253 /**
64254 * @param {?} val
64255 * @return {?}
64256 */
64257 set: function (val) {
64258 this._spaceBetween = parseInt(val, 10);
64259 },
64260 enumerable: true,
64261 configurable: true
64262 });
64263 Object.defineProperty(Slides.prototype, "slidesPerView", {
64264 /**
64265 * \@input {number} Slides per view. Slides visible at the same time. Default: `1`.
64266 * @return {?}
64267 */
64268 get: function () {
64269 return this._slidesPerView;
64270 },
64271 /**
64272 * @param {?} val
64273 * @return {?}
64274 */
64275 set: function (val) {
64276 this._slidesPerView = val === 'auto' ? 'auto' : parseFloat(val);
64277 },
64278 enumerable: true,
64279 configurable: true
64280 });
64281 Object.defineProperty(Slides.prototype, "centeredSlides", {
64282 /**
64283 * \@input {boolean} Center a slide in the middle of the screen.
64284 * @return {?}
64285 */
64286 get: function () {
64287 return this._centeredSlides;
64288 },
64289 /**
64290 * @param {?} val
64291 * @return {?}
64292 */
64293 set: function (val) {
64294 this._centeredSlides = isTrueProperty(val);
64295 },
64296 enumerable: true,
64297 configurable: true
64298 });
64299 /**
64300 * @return {?}
64301 */
64302 Slides.prototype._initSlides = function () {
64303 if (!this._init) {
64304 (void 0) /* console.debug */;
64305 var /** @type {?} */ s = this;
64306 var /** @type {?} */ plt = s._plt;
64307 s.container = this.getNativeElement().children[0];
64308 // init swiper core
64309 initSwiper(s, plt);
64310 // init core event listeners
64311 this._unregs.push(initEvents(s, plt));
64312 if (this.zoom) {
64313 // init zoom event listeners
64314 this._unregs.push(initZoom(s, plt));
64315 }
64316 if (this.keyboardControl) {
64317 // init keyboard event listeners
64318 s.enableKeyboardControl(true);
64319 }
64320 this._init = true;
64321 }
64322 };
64323 /**
64324 * @hidden
64325 * @return {?}
64326 */
64327 Slides.prototype.ngAfterContentInit = function () {
64328 var _this = this;
64329 this._plt.timeout(function () {
64330 _this._initSlides();
64331 }, 300);
64332 };
64333 /**
64334 * Update the underlying slider implementation. Call this if you've added or removed
64335 * child slides.
64336 * @param {?=} debounce
64337 * @return {?}
64338 */
64339 Slides.prototype.update = function (debounce$$1) {
64340 var _this = this;
64341 if (debounce$$1 === void 0) { debounce$$1 = 300; }
64342 if (this._init) {
64343 this._plt.cancelTimeout(this._tmr);
64344 this._tmr = this._plt.timeout(function () {
64345 update(_this, _this._plt);
64346 // Don't allow pager to show with > 10 slides
64347 if (_this.length() > 10) {
64348 _this.paginationType = undefined;
64349 }
64350 }, debounce$$1);
64351 }
64352 };
64353 /**
64354 * @return {?}
64355 */
64356 Slides.prototype.resize = function () {
64357 if (this._init) {
64358 }
64359 };
64360 /**
64361 * Transition to the specified slide.
64362 *
64363 * @param {?} index
64364 * @param {?=} speed
64365 * @param {?=} runCallbacks
64366 * @return {?}
64367 */
64368 Slides.prototype.slideTo = function (index, speed, runCallbacks) {
64369 slideTo(this, this._plt, index, speed, runCallbacks);
64370 };
64371 /**
64372 * Transition to the next slide.
64373 *
64374 * @param {?=} speed
64375 * @param {?=} runCallbacks
64376 * @return {?}
64377 */
64378 Slides.prototype.slideNext = function (speed, runCallbacks) {
64379 slideNext(this, this._plt, runCallbacks, speed, true);
64380 };
64381 /**
64382 * Transition to the previous slide.
64383 *
64384 * @param {?=} speed
64385 * @param {?=} runCallbacks
64386 * @return {?}
64387 */
64388 Slides.prototype.slidePrev = function (speed, runCallbacks) {
64389 slidePrev(this, this._plt, runCallbacks, speed, true);
64390 };
64391 /**
64392 * Get the index of the active slide.
64393 *
64394 * @return {?}
64395 */
64396 Slides.prototype.getActiveIndex = function () {
64397 return this._activeIndex;
64398 };
64399 /**
64400 * Get the index of the previous slide.
64401 *
64402 * @return {?}
64403 */
64404 Slides.prototype.getPreviousIndex = function () {
64405 return this._previousIndex;
64406 };
64407 /**
64408 * Get the total number of slides.
64409 *
64410 * @return {?}
64411 */
64412 Slides.prototype.length = function () {
64413 return this._slides.length;
64414 };
64415 /**
64416 * Get whether or not the current slide is the last slide.
64417 *
64418 * @return {?}
64419 */
64420 Slides.prototype.isEnd = function () {
64421 return this._isEnd;
64422 };
64423 /**
64424 * Get whether or not the current slide is the first slide.
64425 *
64426 * @return {?}
64427 */
64428 Slides.prototype.isBeginning = function () {
64429 return this._isBeginning;
64430 };
64431 /**
64432 * Start auto play.
64433 * @return {?}
64434 */
64435 Slides.prototype.startAutoplay = function () {
64436 startAutoplay(this, this._plt);
64437 };
64438 /**
64439 * Stop auto play.
64440 * @return {?}
64441 */
64442 Slides.prototype.stopAutoplay = function () {
64443 stopAutoplay(this);
64444 };
64445 /**
64446 * Lock or unlock the ability to slide to the next slides.
64447 * Set to false to unlock this behaviour.
64448 * @param {?} shouldLockSwipeToNext
64449 * @return {?}
64450 */
64451 Slides.prototype.lockSwipeToNext = function (shouldLockSwipeToNext) {
64452 this._allowSwipeToNext = !shouldLockSwipeToNext;
64453 };
64454 /**
64455 * Lock or unlock the ability to slide to the previous slides.
64456 * Set to false to unlock this behaviour.
64457 * @param {?} shouldLockSwipeToPrev
64458 * @return {?}
64459 */
64460 Slides.prototype.lockSwipeToPrev = function (shouldLockSwipeToPrev) {
64461 this._allowSwipeToPrev = !shouldLockSwipeToPrev;
64462 };
64463 /**
64464 * Lock or unlock the ability to slide to change slides.
64465 * False allows swiping in both directions.
64466 * @param {?} shouldLockSwipes
64467 * @return {?}
64468 */
64469 Slides.prototype.lockSwipes = function (shouldLockSwipes) {
64470 this._allowSwipeToNext = this._allowSwipeToPrev = !shouldLockSwipes;
64471 };
64472 /**
64473 * Enable or disable keyboard control.
64474 * @param {?} shouldEnableKeyboard
64475 * @return {?}
64476 */
64477 Slides.prototype.enableKeyboardControl = function (shouldEnableKeyboard) {
64478 enableKeyboardControl(this, this._plt, shouldEnableKeyboard);
64479 };
64480 /**
64481 * @hidden
64482 * @return {?}
64483 */
64484 Slides.prototype.ngOnDestroy = function () {
64485 this._init = false;
64486 this._unregs.forEach(function (unReg) {
64487 unReg();
64488 });
64489 this._unregs.length = 0;
64490 destroySwiper(this);
64491 this.enableKeyboardControl(false);
64492 };
64493 return Slides;
64494}(Ion));
64495Slides.decorators = [
64496 { type: Component, args: [{
64497 selector: 'ion-slides',
64498 template: '<div class="swiper-container" [attr.dir]="_rtl? \'rtl\' : null">' +
64499 '<div class="swiper-wrapper">' +
64500 '<ng-content></ng-content>' +
64501 '</div>' +
64502 '<div [class.hide]="!pager" class="swiper-pagination"></div>' +
64503 '</div>',
64504 changeDetection: ChangeDetectionStrategy.OnPush,
64505 encapsulation: ViewEncapsulation.None,
64506 },] },
64507];
64508/**
64509 * @nocollapse
64510 */
64511Slides.ctorParameters = function () { return [
64512 { type: Config, },
64513 { type: Platform, },
64514 { type: NgZone, },
64515 { type: ViewController, decorators: [{ type: Optional },] },
64516 { type: ElementRef, },
64517 { type: Renderer, },
64518]; };
64519Slides.propDecorators = {
64520 'autoplay': [{ type: Input },],
64521 'control': [{ type: Input },],
64522 'effect': [{ type: Input },],
64523 'direction': [{ type: Input },],
64524 'initialSlide': [{ type: Input },],
64525 'loop': [{ type: Input },],
64526 'pager': [{ type: Input },],
64527 'dir': [{ type: Input },],
64528 'paginationType': [{ type: Input },],
64529 'parallax': [{ type: Input },],
64530 'speed': [{ type: Input },],
64531 'zoom': [{ type: Input },],
64532 'spaceBetween': [{ type: Input },],
64533 'slidesPerView': [{ type: Input },],
64534 'centeredSlides': [{ type: Input },],
64535 'ionSlideWillChange': [{ type: Output },],
64536 'ionSlideDidChange': [{ type: Output },],
64537 'ionSlideDrag': [{ type: Output },],
64538 'ionSlideReachStart': [{ type: Output },],
64539 'ionSlideReachEnd': [{ type: Output },],
64540 'ionSlideAutoplay': [{ type: Output },],
64541 'ionSlideAutoplayStart': [{ type: Output },],
64542 'ionSlideAutoplayStop': [{ type: Output },],
64543 'ionSlideNextStart': [{ type: Output },],
64544 'ionSlidePrevStart': [{ type: Output },],
64545 'ionSlideNextEnd': [{ type: Output },],
64546 'ionSlidePrevEnd': [{ type: Output },],
64547 'ionSlideTap': [{ type: Output },],
64548 'ionSlideDoubleTap': [{ type: Output },],
64549};
64550var slidesId = -1;
64551
64552/**
64553 * \@name Slide
64554 * \@description
64555 * The Slide component is a child component of [Slides](../Slides). The template
64556 * should be written as `ion-slide`. Any slide content should be written
64557 * in this component and it should be used in conjunction with [Slides](../Slides).
64558 *
64559 * See the [Slides API Docs](../Slides) for more usage information.
64560 *
64561 * \@demo /docs/demos/src/slides/
64562 * @see {\@link /docs/api/components/slides/Slides/ Slides API Docs}
64563 */
64564var Slide = (function () {
64565 /**
64566 * @param {?} elementRef
64567 * @param {?} renderer
64568 * @param {?} _slides
64569 */
64570 function Slide(elementRef, renderer, _slides) {
64571 this._slides = _slides;
64572 renderer.setElementClass(elementRef.nativeElement, 'swiper-slide', true);
64573 _slides.update(10);
64574 }
64575 /**
64576 * @hidden
64577 * @return {?}
64578 */
64579 Slide.prototype.ngOnDestroy = function () {
64580 this._slides.update(10);
64581 };
64582 return Slide;
64583}());
64584Slide.decorators = [
64585 { type: Component, args: [{
64586 selector: 'ion-slide',
64587 template: '<div class="slide-zoom">' +
64588 '<ng-content></ng-content>' +
64589 '</div>',
64590 changeDetection: ChangeDetectionStrategy.OnPush,
64591 encapsulation: ViewEncapsulation.None,
64592 },] },
64593];
64594/**
64595 * @nocollapse
64596 */
64597Slide.ctorParameters = function () { return [
64598 { type: ElementRef, },
64599 { type: Renderer, },
64600 { type: Slides, },
64601]; };
64602
64603var __extends$77 = (undefined && undefined.__extends) || (function () {
64604 var extendStatics = Object.setPrototypeOf ||
64605 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
64606 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
64607 return function (d, b) {
64608 extendStatics(d, b);
64609 function __() { this.constructor = d; }
64610 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
64611 };
64612})();
64613/**
64614 * \@name Spinner
64615 * \@description
64616 * The `ion-spinner` component provides a variety of animated SVG spinners.
64617 * Spinners enables you to give users feedback that the app is actively
64618 * processing/thinking/waiting/chillin’ out, or whatever you’d like it to indicate.
64619 * By default, the `ion-refresher` feature uses this spinner component while it's
64620 * the refresher is in the `refreshing` state.
64621 *
64622 * Ionic offers a handful of spinners out of the box, and by default, it will use
64623 * the appropriate spinner for the platform on which it’s running.
64624 *
64625 * <table class="table spinner-table">
64626 * <tr>
64627 * <th>
64628 * <code>ios</code>
64629 * </th>
64630 * <td>
64631 * <ion-spinner name="ios"></ion-spinner>
64632 * </td>
64633 * </tr>
64634 * <tr>
64635 * <th>
64636 * <code>ios-small</code>
64637 * </th>
64638 * <td>
64639 * <ion-spinner name="ios-small"></ion-spinner>
64640 * </td>
64641 * </tr>
64642 * <tr>
64643 * <th>
64644 * <code>bubbles</code>
64645 * </th>
64646 * <td>
64647 * <ion-spinner name="bubbles"></ion-spinner>
64648 * </td>
64649 * </tr>
64650 * <tr>
64651 * <th>
64652 * <code>circles</code>
64653 * </th>
64654 * <td>
64655 * <ion-spinner name="circles"></ion-spinner>
64656 * </td>
64657 * </tr>
64658 * <tr>
64659 * <th>
64660 * <code>crescent</code>
64661 * </th>
64662 * <td>
64663 * <ion-spinner name="crescent"></ion-spinner>
64664 * </td>
64665 * </tr>
64666 * <tr>
64667 * <th>
64668 * <code>dots</code>
64669 * </th>
64670 * <td>
64671 * <ion-spinner name="dots"></ion-spinner>
64672 * </td>
64673 * </tr>
64674 * </table>
64675 *
64676 * \@usage
64677 * The following code would use the default spinner for the platform it's
64678 * running from. If it's neither iOS or Android, it'll default to use `ios`.
64679 *
64680 * ```html
64681 * <ion-spinner></ion-spinner>
64682 * ```
64683 *
64684 * By setting the `name` property, you can specify which predefined spinner to
64685 * use, no matter what the platform is.
64686 *
64687 * ```html
64688 * <ion-spinner name="bubbles"></ion-spinner>
64689 * ```
64690 *
64691 * ## Styling SVG with CSS
64692 * One cool thing about SVG is its ability to be styled with CSS! One thing to note
64693 * is that some of the CSS properties on an SVG element have different names. For
64694 * example, SVG uses the term `stroke` instead of `border`, and `fill` instead
64695 * of `background-color`.
64696 *
64697 * ```css
64698 * ion-spinner * {
64699 * width: 28px;
64700 * height: 28px;
64701 * stroke: #444;
64702 * fill: #222;
64703 * }
64704 * ```
64705 */
64706var Spinner = (function (_super) {
64707 __extends$77(Spinner, _super);
64708 /**
64709 * @param {?} config
64710 * @param {?} elementRef
64711 * @param {?} renderer
64712 */
64713 function Spinner(config, elementRef, renderer) {
64714 var _this = _super.call(this, config, elementRef, renderer, 'spinner') || this;
64715 _this._dur = null;
64716 _this._paused = false;
64717 return _this;
64718 }
64719 Object.defineProperty(Spinner.prototype, "name", {
64720 /**
64721 * \@input {string} SVG spinner name.
64722 * @return {?}
64723 */
64724 get: function () {
64725 return this._name;
64726 },
64727 /**
64728 * @param {?} val
64729 * @return {?}
64730 */
64731 set: function (val) {
64732 this._name = val;
64733 this.load();
64734 },
64735 enumerable: true,
64736 configurable: true
64737 });
64738 Object.defineProperty(Spinner.prototype, "duration", {
64739 /**
64740 * \@input {string} How long it takes it to do one loop.
64741 * @return {?}
64742 */
64743 get: function () {
64744 return this._dur;
64745 },
64746 /**
64747 * @param {?} val
64748 * @return {?}
64749 */
64750 set: function (val) {
64751 this._dur = val;
64752 this.load();
64753 },
64754 enumerable: true,
64755 configurable: true
64756 });
64757 Object.defineProperty(Spinner.prototype, "paused", {
64758 /**
64759 * \@input {boolean} If true, pause the animation.
64760 * @return {?}
64761 */
64762 get: function () {
64763 return this._paused;
64764 },
64765 /**
64766 * @param {?} val
64767 * @return {?}
64768 */
64769 set: function (val) {
64770 this._paused = isTrueProperty(val);
64771 },
64772 enumerable: true,
64773 configurable: true
64774 });
64775 /**
64776 * @hidden
64777 * @return {?}
64778 */
64779 Spinner.prototype.ngOnInit = function () {
64780 this._init = true;
64781 this.load();
64782 };
64783 /**
64784 * @hidden
64785 * @return {?}
64786 */
64787 Spinner.prototype.load = function () {
64788 if (this._init) {
64789 this._l = [];
64790 this._c = [];
64791 var /** @type {?} */ name = this._name || this._config.get('spinner', 'ios');
64792 var /** @type {?} */ spinner = SPINNERS[name];
64793 if (spinner) {
64794 if (spinner.lines) {
64795 for (var /** @type {?} */ i = 0, /** @type {?} */ l = spinner.lines; i < l; i++) {
64796 this._l.push(this._loadEle(spinner, i, l));
64797 }
64798 }
64799 else if (spinner.circles) {
64800 for (var /** @type {?} */ i = 0, /** @type {?} */ l = spinner.circles; i < l; i++) {
64801 this._c.push(this._loadEle(spinner, i, l));
64802 }
64803 }
64804 this.setElementClass("spinner-" + name, true);
64805 this.setElementClass("spinner-" + this._mode + "-" + name, true);
64806 }
64807 }
64808 };
64809 /**
64810 * @param {?} spinner
64811 * @param {?} index
64812 * @param {?} total
64813 * @return {?}
64814 */
64815 Spinner.prototype._loadEle = function (spinner, index, total) {
64816 var /** @type {?} */ duration = this._dur || spinner.dur;
64817 var /** @type {?} */ data = spinner.fn(duration, index, total);
64818 data.style.animationDuration = duration + 'ms';
64819 return data;
64820 };
64821 return Spinner;
64822}(Ion));
64823Spinner.decorators = [
64824 { type: Component, args: [{
64825 selector: 'ion-spinner',
64826 template: '<svg viewBox="0 0 64 64" *ngFor="let i of _c" [ngStyle]="i.style">' +
64827 '<circle [attr.r]="i.r" transform="translate(32,32)"></circle>' +
64828 '</svg>' +
64829 '<svg viewBox="0 0 64 64" *ngFor="let i of _l" [ngStyle]="i.style">' +
64830 '<line [attr.y1]="i.y1" [attr.y2]="i.y2" transform="translate(32,32)"></line>' +
64831 '</svg>',
64832 host: {
64833 '[class.spinner-paused]': '_paused'
64834 },
64835 changeDetection: ChangeDetectionStrategy.OnPush,
64836 encapsulation: ViewEncapsulation.None,
64837 },] },
64838];
64839/**
64840 * @nocollapse
64841 */
64842Spinner.ctorParameters = function () { return [
64843 { type: Config, },
64844 { type: ElementRef, },
64845 { type: Renderer, },
64846]; };
64847Spinner.propDecorators = {
64848 'name': [{ type: Input },],
64849 'duration': [{ type: Input },],
64850 'paused': [{ type: Input },],
64851};
64852var SPINNERS = {
64853 ios: {
64854 dur: 1000,
64855 lines: 12,
64856 fn: function (dur, index, total) {
64857 var /** @type {?} */ transform = 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)';
64858 var /** @type {?} */ animationDelay = -(dur - ((dur / total) * index)) + 'ms';
64859 return {
64860 y1: 17,
64861 y2: 29,
64862 style: {
64863 transform: transform,
64864 webkitTransform: transform,
64865 animationDelay: animationDelay,
64866 webkitAnimationDelay: animationDelay
64867 }
64868 };
64869 }
64870 },
64871 'ios-small': {
64872 dur: 1000,
64873 lines: 12,
64874 fn: function (dur, index, total) {
64875 var /** @type {?} */ transform = 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)';
64876 var /** @type {?} */ animationDelay = -(dur - ((dur / total) * index)) + 'ms';
64877 return {
64878 y1: 12,
64879 y2: 20,
64880 style: {
64881 transform: transform,
64882 webkitTransform: transform,
64883 animationDelay: animationDelay,
64884 webkitAnimationDelay: animationDelay
64885 }
64886 };
64887 }
64888 },
64889 bubbles: {
64890 dur: 1000,
64891 circles: 9,
64892 fn: function (dur, index, total) {
64893 var /** @type {?} */ animationDelay = -(dur - ((dur / total) * index)) + 'ms';
64894 return {
64895 r: 5,
64896 style: {
64897 top: (9 * Math.sin(2 * Math.PI * index / total)) + 'px',
64898 left: (9 * Math.cos(2 * Math.PI * index / total)) + 'px',
64899 animationDelay: animationDelay,
64900 webkitAnimationDelay: animationDelay
64901 }
64902 };
64903 }
64904 },
64905 circles: {
64906 dur: 1000,
64907 circles: 8,
64908 fn: function (dur, index, total) {
64909 var /** @type {?} */ animationDelay = -(dur - ((dur / total) * index)) + 'ms';
64910 return {
64911 r: 5,
64912 style: {
64913 top: (9 * Math.sin(2 * Math.PI * index / total)) + 'px',
64914 left: (9 * Math.cos(2 * Math.PI * index / total)) + 'px',
64915 animationDelay: animationDelay,
64916 webkitAnimationDelay: animationDelay
64917 }
64918 };
64919 }
64920 },
64921 crescent: {
64922 dur: 750,
64923 circles: 1,
64924 fn: function () {
64925 return {
64926 r: 26,
64927 style: {}
64928 };
64929 }
64930 },
64931 dots: {
64932 dur: 750,
64933 circles: 3,
64934 fn: function (_dur, index) {
64935 var /** @type {?} */ animationDelay = -(110 * index) + 'ms';
64936 return {
64937 r: 6,
64938 style: {
64939 left: (9 - (9 * index)) + 'px',
64940 animationDelay: animationDelay,
64941 webkitAnimationDelay: animationDelay
64942 }
64943 };
64944 }
64945 }
64946};
64947
64948/**
64949 * @hidden
64950 */
64951var TabHighlight = (function () {
64952 /**
64953 * @param {?} _elementRef
64954 * @param {?} _dom
64955 */
64956 function TabHighlight(_elementRef, _dom) {
64957 this._elementRef = _elementRef;
64958 this._dom = _dom;
64959 }
64960 /**
64961 * @param {?} tab
64962 * @return {?}
64963 */
64964 TabHighlight.prototype.select = function (tab) {
64965 var _this = this;
64966 if (!tab) {
64967 return;
64968 }
64969 var /** @type {?} */ dom = this._dom;
64970 dom.read(function () {
64971 var /** @type {?} */ btnEle = tab.btn.getNativeElement();
64972 var /** @type {?} */ transform = "translate3d(" + btnEle.offsetLeft + "px,0,0) scaleX(" + btnEle.offsetWidth + ")";
64973 dom.write(function () {
64974 var /** @type {?} */ ele = _this._elementRef.nativeElement;
64975 ((ele.style))[dom.plt.Css.transform] = transform;
64976 if (!_this._init) {
64977 _this._init = true;
64978 dom.write(function () {
64979 ele.classList.add('animate');
64980 }, 80);
64981 }
64982 });
64983 }, 32);
64984 };
64985 return TabHighlight;
64986}());
64987TabHighlight.decorators = [
64988 { type: Directive, args: [{
64989 selector: '.tab-highlight'
64990 },] },
64991];
64992/**
64993 * @nocollapse
64994 */
64995TabHighlight.ctorParameters = function () { return [
64996 { type: ElementRef, },
64997 { type: DomController, },
64998]; };
64999
65000var __extends$79 = (undefined && undefined.__extends) || (function () {
65001 var extendStatics = Object.setPrototypeOf ||
65002 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
65003 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
65004 return function (d, b) {
65005 extendStatics(d, b);
65006 function __() { this.constructor = d; }
65007 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
65008 };
65009})();
65010/**
65011 * \@name Tabs
65012 * \@description
65013 * Tabs make it easy to navigate between different pages or functional
65014 * aspects of an app. The Tabs component, written as `<ion-tabs>`, is
65015 * a container of individual [Tab](../Tab/) components. Each individual `ion-tab`
65016 * is a declarative component for a [NavController](../../../navigation/NavController/)
65017 *
65018 * For more information on using nav controllers like Tab or [Nav](../../nav/Nav/),
65019 * take a look at the [NavController API Docs](../../../navigation/NavController/).
65020 *
65021 * ### Placement
65022 *
65023 * The position of the tabs relative to the content varies based on
65024 * the mode. The tabs are placed at the bottom of the screen
65025 * for iOS and Android, and at the top for Windows by default. The position can
65026 * be configured using the `tabsPlacement` attribute on the `<ion-tabs>` component,
65027 * or in an app's [config](../../config/Config/).
65028 * See the [Input Properties](#input-properties) below for the available
65029 * values of `tabsPlacement`.
65030 *
65031 * ### Layout
65032 *
65033 * The layout for all of the tabs can be defined using the `tabsLayout`
65034 * property. If the individual tab has a title and icon, the icons will
65035 * show on top of the title by default. All tabs can be changed by setting
65036 * the value of `tabsLayout` on the `<ion-tabs>` element, or in your
65037 * app's [config](../../config/Config/). For example, this is useful if
65038 * you want to show tabs with a title only on Android, but show icons
65039 * and a title for iOS. See the [Input Properties](#input-properties)
65040 * below for the available values of `tabsLayout`.
65041 *
65042 * ### Selecting a Tab
65043 *
65044 * There are different ways you can select a specific tab from the tabs
65045 * component. You can use the `selectedIndex` property to set the index
65046 * on the `<ion-tabs>` element, or you can call `select()` from the `Tabs`
65047 * instance after creation. See [usage](#usage) below for more information.
65048 *
65049 * \@usage
65050 *
65051 * You can add a basic tabs template to a `\@Component` using the following
65052 * template:
65053 *
65054 * ```html
65055 * <ion-tabs>
65056 * <ion-tab [root]="tab1Root"></ion-tab>
65057 * <ion-tab [root]="tab2Root"></ion-tab>
65058 * <ion-tab [root]="tab3Root"></ion-tab>
65059 * </ion-tabs>
65060 * ```
65061 *
65062 * Where `tab1Root`, `tab2Root`, and `tab3Root` are each a page:
65063 *
65064 * ```ts
65065 * \@Component({
65066 * templateUrl: 'build/pages/tabs/tabs.html'
65067 * })
65068 * export class TabsPage {
65069 * // this tells the tabs component which Pages
65070 * // should be each tab's root Page
65071 * tab1Root = Page1;
65072 * tab2Root = Page2;
65073 * tab3Root = Page3;
65074 *
65075 * constructor() {
65076 *
65077 * }
65078 * }
65079 * ```
65080 *
65081 * By default, the first tab will be selected upon navigation to the
65082 * Tabs page. We can change the selected tab by using `selectedIndex`
65083 * on the `<ion-tabs>` element:
65084 *
65085 * ```html
65086 * <ion-tabs selectedIndex="2">
65087 * <ion-tab [root]="tab1Root"></ion-tab>
65088 * <ion-tab [root]="tab2Root"></ion-tab>
65089 * <ion-tab [root]="tab3Root"></ion-tab>
65090 * </ion-tabs>
65091 * ```
65092 *
65093 * Since the index starts at `0`, this will select the 3rd tab which has
65094 * root set to `tab3Root`. If you wanted to change it dynamically from
65095 * your class, you could use [property binding](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding).
65096 *
65097 * Alternatively, you can grab the `Tabs` instance and call the `select()`
65098 * method. This requires the `<ion-tabs>` element to have an `id`. For
65099 * example, set the value of `id` to `myTabs`:
65100 *
65101 * ```html
65102 * <ion-tabs #myTabs>
65103 * <ion-tab [root]="tab1Root"></ion-tab>
65104 * <ion-tab [root]="tab2Root"></ion-tab>
65105 * <ion-tab [root]="tab3Root"></ion-tab>
65106 * </ion-tabs>
65107 * ```
65108 *
65109 * Then in your class you can grab the `Tabs` instance and call `select()`,
65110 * passing the index of the tab as the argument. Here we're grabbing the tabs
65111 * by using ViewChild.
65112 *
65113 * ```ts
65114 * export class TabsPage {
65115 *
65116 * \@ViewChild('myTabs') tabRef: Tabs;
65117 *
65118 * ionViewDidEnter() {
65119 * this.tabRef.select(2);
65120 * }
65121 *
65122 * }
65123 * ```
65124 *
65125 * You can also switch tabs from a child component by calling `select()` on the
65126 * parent view using the `NavController` instance. For example, assuming you have
65127 * a `TabsPage` component, you could call the following from any of the child
65128 * components to switch to `TabsRoot3`:
65129 *
65130 * ```ts
65131 * switchTabs() {
65132 * this.navCtrl.parent.select(2);
65133 * }
65134 * ```
65135 * \@demo /docs/demos/src/tabs/
65136 *
65137 * @see {\@link /docs/components#tabs Tabs Component Docs}
65138 * @see {\@link ../Tab Tab API Docs}
65139 * @see {\@link ../../config/Config Config API Docs}
65140 *
65141 */
65142var Tabs = (function (_super) {
65143 __extends$79(Tabs, _super);
65144 /**
65145 * @param {?} parent
65146 * @param {?} viewCtrl
65147 * @param {?} _app
65148 * @param {?} config
65149 * @param {?} elementRef
65150 * @param {?} _plt
65151 * @param {?} renderer
65152 * @param {?} _linker
65153 * @param {?=} keyboard
65154 */
65155 function Tabs(parent, viewCtrl, _app, config, elementRef, _plt, renderer, _linker, keyboard) {
65156 var _this = _super.call(this, config, elementRef, renderer, 'tabs') || this;
65157 _this.viewCtrl = viewCtrl;
65158 _this._app = _app;
65159 _this._plt = _plt;
65160 _this._linker = _linker;
65161 /**
65162 * \@internal
65163 */
65164 _this._ids = -1;
65165 /**
65166 * \@internal
65167 */
65168 _this._tabs = [];
65169 /**
65170 * \@internal
65171 */
65172 _this._selectHistory = [];
65173 /**
65174 * \@internal
65175 */
65176 _this._onDestroy = new Subject_2();
65177 /**
65178 * \@output {any} Emitted when the tab changes.
65179 */
65180 _this.ionChange = new EventEmitter();
65181 _this.parent = parent;
65182 _this.id = 't' + (++tabIds);
65183 _this._sbPadding = config.getBoolean('statusbarPadding');
65184 _this.tabsHighlight = config.getBoolean('tabsHighlight');
65185 if (_this.parent) {
65186 // this Tabs has a parent Nav
65187 _this.parent.registerChildNav(_this);
65188 }
65189 else if (viewCtrl && viewCtrl.getNav()) {
65190 // this Nav was opened from a modal
65191 _this.parent = viewCtrl.getNav();
65192 _this.parent.registerChildNav(_this);
65193 }
65194 else if (_this._app) {
65195 // this is the root navcontroller for the entire app
65196 _this._app.registerRootNav(_this);
65197 }
65198 // Tabs may also be an actual ViewController which was navigated to
65199 // if Tabs is static and not navigated to within a NavController
65200 // then skip this and don't treat it as it's own ViewController
65201 if (viewCtrl) {
65202 viewCtrl._setContent(_this);
65203 viewCtrl._setContentRef(elementRef);
65204 }
65205 var keyboardResizes = config.getBoolean('keyboardResizes', false);
65206 if (keyboard && keyboardResizes) {
65207 keyboard.willHide
65208 .takeUntil(_this._onDestroy)
65209 .subscribe(function () {
65210 _this._plt.timeout(function () { return _this.setTabbarHidden(false); }, 50);
65211 });
65212 keyboard.willShow
65213 .takeUntil(_this._onDestroy)
65214 .subscribe(function () { return _this.setTabbarHidden(true); });
65215 }
65216 return _this;
65217 }
65218 /**
65219 * \@internal
65220 * @param {?} tabbarHidden
65221 * @return {?}
65222 */
65223 Tabs.prototype.setTabbarHidden = function (tabbarHidden) {
65224 this.setElementClass('tabbar-hidden', tabbarHidden);
65225 this.resize();
65226 };
65227 /**
65228 * \@internal
65229 * @return {?}
65230 */
65231 Tabs.prototype.ngOnDestroy = function () {
65232 this._onDestroy.next();
65233 this.parent.unregisterChildNav(this);
65234 };
65235 /**
65236 * \@internal
65237 * @return {?}
65238 */
65239 Tabs.prototype.ngAfterViewInit = function () {
65240 var _this = this;
65241 this._setConfig('tabsPlacement', 'bottom');
65242 this._setConfig('tabsLayout', 'icon-top');
65243 this._setConfig('tabsHighlight', this.tabsHighlight);
65244 if (this.tabsHighlight) {
65245 this._plt.resize
65246 .takeUntil(this._onDestroy)
65247 .subscribe(function () { return _this._highlight.select(_this.getSelected()); });
65248 }
65249 this.initTabs();
65250 };
65251 /**
65252 * \@internal
65253 * @return {?}
65254 */
65255 Tabs.prototype.initTabs = function () {
65256 // get the selected index from the input
65257 // otherwise default it to use the first index
65258 var /** @type {?} */ selectedIndex = (isBlank$1(this.selectedIndex) ? 0 : parseInt(/** @type {?} */ (this.selectedIndex), 10));
65259 // now see if the deep linker can find a tab index
65260 var /** @type {?} */ tabsSegment = this._linker.getSegmentByNavIdOrName(this.id, this.name);
65261 if (tabsSegment) {
65262 // we found a segment which probably represents which tab to select
65263 selectedIndex = this._getSelectedTabIndex(tabsSegment.secondaryId, selectedIndex);
65264 }
65265 // get the selectedIndex and ensure it isn't hidden or disabled
65266 var /** @type {?} */ selectedTab = this._tabs.find(function (t, i) { return i === selectedIndex && t.enabled && t.show; });
65267 if (!selectedTab) {
65268 // wasn't able to select the tab they wanted
65269 // try to find the first tab that's available
65270 selectedTab = this._tabs.find(function (t) { return t.enabled && t.show; });
65271 }
65272 if (selectedTab) {
65273 if (tabsSegment) {
65274 selectedTab._lazyRootFromUrl = tabsSegment.name;
65275 selectedTab._lazyRootFromUrlData = tabsSegment.data;
65276 }
65277 this.select(selectedTab);
65278 }
65279 // set the initial href attribute values for each tab
65280 this._tabs.forEach(function (t) {
65281 t.updateHref(t.root, t.rootParams);
65282 });
65283 };
65284 /**
65285 * \@internal
65286 * @param {?} attrKey
65287 * @param {?} fallback
65288 * @return {?}
65289 */
65290 Tabs.prototype._setConfig = function (attrKey, fallback) {
65291 var /** @type {?} */ val = ((this))[attrKey];
65292 if (isBlank$1(val)) {
65293 val = this._config.get(attrKey, fallback);
65294 }
65295 this.setElementAttribute(attrKey, val);
65296 };
65297 /**
65298 * @hidden
65299 * @param {?} tab
65300 * @return {?}
65301 */
65302 Tabs.prototype.add = function (tab) {
65303 this._tabs.push(tab);
65304 return this.id + '-' + (++this._ids);
65305 };
65306 /**
65307 * @param {?} tabOrIndex
65308 * @param {?=} opts
65309 * @param {?=} fromUrl
65310 * @return {?}
65311 */
65312 Tabs.prototype.select = function (tabOrIndex, opts, fromUrl) {
65313 var _this = this;
65314 if (opts === void 0) { opts = {}; }
65315 if (fromUrl === void 0) { fromUrl = false; }
65316 var /** @type {?} */ selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
65317 if (isBlank$1(selectedTab)) {
65318 return;
65319 }
65320 // If the selected tab is the current selected tab, we do not switch
65321 var /** @type {?} */ currentTab = this.getSelected();
65322 if (selectedTab === currentTab && currentTab.getActive()) {
65323 return this._updateCurrentTab(selectedTab, fromUrl);
65324 }
65325 // If the selected tab does not have a root, we do not switch (#9392)
65326 // it's possible the tab is only for opening modal's or signing out
65327 // and doesn't actually have content. In the case there's no content
65328 // for a tab then do nothing and leave the current view as is
65329 if (selectedTab.root) {
65330 // At this point we are going to perform a page switch
65331 // Let's fire willLeave in the current tab page
65332 var /** @type {?} */ currentPage;
65333 if (currentTab) {
65334 currentPage = currentTab.getActive();
65335 currentPage && currentPage._willLeave(false);
65336 }
65337 // Fire willEnter in the new selected tab
65338 var /** @type {?} */ selectedPage_1 = selectedTab.getActive();
65339 selectedPage_1 && selectedPage_1._willEnter();
65340 // Let's start the transition
65341 opts.animate = false;
65342 selectedTab.load(opts, function () {
65343 _this._tabSwitchEnd(selectedTab, selectedPage_1, currentPage);
65344 if (opts.updateUrl !== false) {
65345 _this._linker.navChange(DIRECTION_SWITCH);
65346 }
65347 (void 0) /* assert */;
65348 _this._fireChangeEvent(selectedTab);
65349 });
65350 }
65351 else {
65352 this._fireChangeEvent(selectedTab);
65353 }
65354 };
65355 /**
65356 * @param {?} selectedTab
65357 * @return {?}
65358 */
65359 Tabs.prototype._fireChangeEvent = function (selectedTab) {
65360 selectedTab.ionSelect.emit(selectedTab);
65361 this.ionChange.emit(selectedTab);
65362 };
65363 /**
65364 * @param {?} selectedTab
65365 * @param {?} selectedPage
65366 * @param {?} currentPage
65367 * @return {?}
65368 */
65369 Tabs.prototype._tabSwitchEnd = function (selectedTab, selectedPage, currentPage) {
65370 (void 0) /* assert */;
65371 (void 0) /* assert */;
65372 // Update tabs selection state
65373 var /** @type {?} */ tabs = this._tabs;
65374 var /** @type {?} */ tab;
65375 for (var /** @type {?} */ i = 0; i < tabs.length; i++) {
65376 tab = tabs[i];
65377 tab.setSelected(tab === selectedTab);
65378 }
65379 if (this.tabsHighlight) {
65380 this._highlight.select(selectedTab);
65381 }
65382 // Fire didEnter/didLeave lifecycle events
65383 selectedPage && selectedPage._didEnter();
65384 currentPage && currentPage._didLeave();
65385 // track the order of which tabs have been selected, by their index
65386 // do not track if the tab index is the same as the previous
65387 if (this._selectHistory[this._selectHistory.length - 1] !== selectedTab.id) {
65388 this._selectHistory.push(selectedTab.id);
65389 }
65390 };
65391 /**
65392 * Get the previously selected Tab which is currently not disabled or hidden.
65393 * @param {?=} trimHistory
65394 * @return {?}
65395 */
65396 Tabs.prototype.previousTab = function (trimHistory) {
65397 var _this = this;
65398 if (trimHistory === void 0) { trimHistory = true; }
65399 // walk backwards through the tab selection history
65400 // and find the first previous tab that is enabled and shown
65401 (void 0) /* console.debug */;
65402 for (var /** @type {?} */ i = this._selectHistory.length - 2; i >= 0; i--) {
65403 var /** @type {?} */ tab = this._tabs.find(function (t) { return t.id === _this._selectHistory[i]; });
65404 if (tab && tab.enabled && tab.show) {
65405 if (trimHistory) {
65406 this._selectHistory.splice(i + 1);
65407 }
65408 return tab;
65409 }
65410 }
65411 return null;
65412 };
65413 /**
65414 * @param {?} index
65415 * @return {?}
65416 */
65417 Tabs.prototype.getByIndex = function (index) {
65418 return this._tabs[index];
65419 };
65420 /**
65421 * @return {?}
65422 */
65423 Tabs.prototype.getSelected = function () {
65424 var /** @type {?} */ tabs = this._tabs;
65425 for (var /** @type {?} */ i = 0; i < tabs.length; i++) {
65426 if (tabs[i].isSelected) {
65427 return tabs[i];
65428 }
65429 }
65430 return null;
65431 };
65432 /**
65433 * \@internal
65434 * @return {?}
65435 */
65436 Tabs.prototype.getActiveChildNavs = function () {
65437 var /** @type {?} */ selected = this.getSelected();
65438 return selected ? [selected] : [];
65439 };
65440 /**
65441 * \@internal
65442 * @return {?}
65443 */
65444 Tabs.prototype.getAllChildNavs = function () {
65445 return this._tabs;
65446 };
65447 /**
65448 * \@internal
65449 * @param {?} tab
65450 * @return {?}
65451 */
65452 Tabs.prototype.getIndex = function (tab) {
65453 return this._tabs.indexOf(tab);
65454 };
65455 /**
65456 * \@internal
65457 * @return {?}
65458 */
65459 Tabs.prototype.length = function () {
65460 return this._tabs.length;
65461 };
65462 /**
65463 * "Touch" the active tab, going back to the root view of the tab
65464 * or optionally letting the tab handle the event
65465 * @param {?} tab
65466 * @param {?} fromUrl
65467 * @return {?}
65468 */
65469 Tabs.prototype._updateCurrentTab = function (tab, fromUrl) {
65470 var /** @type {?} */ active = tab.getActive();
65471 if (active) {
65472 if (fromUrl && tab._lazyRootFromUrl) {
65473 // see if the view controller exists
65474 var /** @type {?} */ vc = tab.getViewById(tab._lazyRootFromUrl);
65475 if (vc) {
65476 // the view is already in the stack
65477 tab.popTo(vc, {
65478 animate: false,
65479 updateUrl: false,
65480 });
65481 }
65482 else {
65483 tab.setRoot(tab._lazyRootFromUrl, tab._lazyRootFromUrlData, {
65484 animate: false, updateUrl: false
65485 });
65486 tab._lazyRootFromUrl = null;
65487 tab._lazyRootFromUrlData = null;
65488 }
65489 }
65490 else if (active._cmp && active._cmp.instance.ionSelected) {
65491 // if they have a custom tab selected handler, call it
65492 active._cmp.instance.ionSelected();
65493 }
65494 else if (tab.length() > 1) {
65495 // if we're a few pages deep, pop to root
65496 tab.popToRoot();
65497 }
65498 else {
65499 getComponent(this._linker, tab.root).then(function (viewController) {
65500 if (viewController.component !== active.component) {
65501 // Otherwise, if the page we're on is not our real root
65502 // reset it to our default root type
65503 return tab.setRoot(tab.root);
65504 }
65505 }).catch(function () {
65506 (void 0) /* console.debug */;
65507 });
65508 }
65509 }
65510 };
65511 /**
65512 * \@internal
65513 * DOM WRITE
65514 * @param {?} top
65515 * @param {?} bottom
65516 * @return {?}
65517 */
65518 Tabs.prototype.setTabbarPosition = function (top, bottom) {
65519 if (this._top !== top || this._bottom !== bottom) {
65520 var /** @type {?} */ tabbarEle = (this._tabbar.nativeElement);
65521 tabbarEle.style.top = (top > -1 ? top + 'px' : '');
65522 tabbarEle.style.bottom = (bottom > -1 ? bottom + 'px' : '');
65523 tabbarEle.classList.add('show-tabbar');
65524 this._top = top;
65525 this._bottom = bottom;
65526 }
65527 };
65528 /**
65529 * \@internal
65530 * @return {?}
65531 */
65532 Tabs.prototype.resize = function () {
65533 var /** @type {?} */ tab = this.getSelected();
65534 tab && tab.resize();
65535 };
65536 /**
65537 * \@internal
65538 * @return {?}
65539 */
65540 Tabs.prototype.initPane = function () {
65541 var /** @type {?} */ isMain = this._elementRef.nativeElement.hasAttribute('main');
65542 return isMain;
65543 };
65544 /**
65545 * \@internal
65546 * @param {?} isPane
65547 * @return {?}
65548 */
65549 Tabs.prototype.paneChanged = function (isPane) {
65550 if (isPane) {
65551 this.resize();
65552 }
65553 };
65554 /**
65555 * @param {?} opts
65556 * @return {?}
65557 */
65558 Tabs.prototype.goToRoot = function (opts) {
65559 if (this._tabs.length) {
65560 return this.select(this._tabs[0], opts);
65561 }
65562 };
65563 /**
65564 * @return {?}
65565 */
65566 Tabs.prototype.getType = function () {
65567 return 'tabs';
65568 };
65569 /**
65570 * @return {?}
65571 */
65572 Tabs.prototype.getSecondaryIdentifier = function () {
65573 var /** @type {?} */ tabs = this.getActiveChildNavs();
65574 if (tabs && tabs.length) {
65575 return this._linker._getTabSelector(tabs[0]);
65576 }
65577 return '';
65578 };
65579 /**
65580 * @param {?=} secondaryId
65581 * @param {?=} fallbackIndex
65582 * @return {?}
65583 */
65584 Tabs.prototype._getSelectedTabIndex = function (secondaryId, fallbackIndex) {
65585 if (secondaryId === void 0) { secondaryId = ''; }
65586 if (fallbackIndex === void 0) { fallbackIndex = 0; }
65587 // we found a segment which probably represents which tab to select
65588 var /** @type {?} */ indexMatch = secondaryId.match(/tab-(\d+)/);
65589 if (indexMatch) {
65590 // awesome, the segment name was something "tab-0", and
65591 // the numbe represents which tab to select
65592 return parseInt(indexMatch[1], 10);
65593 }
65594 // wasn't in the "tab-0" format so maybe it's using a word
65595 var /** @type {?} */ tab = this._tabs.find(function (t) {
65596 return (isPresent(t.tabUrlPath) && t.tabUrlPath === secondaryId) ||
65597 (isPresent(t.tabTitle) && formatUrlPart(t.tabTitle) === secondaryId);
65598 });
65599 return isPresent(tab) ? tab.index : fallbackIndex;
65600 };
65601 return Tabs;
65602}(Ion));
65603Tabs.decorators = [
65604 { type: Component, args: [{
65605 selector: 'ion-tabs',
65606 template: '<div class="tabbar" role="tablist" #tabbar>' +
65607 '<a *ngFor="let t of _tabs" [tab]="t" class="tab-button" role="tab" href="#" (ionSelect)="select(t)"></a>' +
65608 '<div class="tab-highlight"></div>' +
65609 '</div>' +
65610 '<ng-content></ng-content>' +
65611 '<div #portal tab-portal></div>',
65612 encapsulation: ViewEncapsulation.None,
65613 providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Tabs; }) }]
65614 },] },
65615];
65616/**
65617 * @nocollapse
65618 */
65619Tabs.ctorParameters = function () { return [
65620 { type: NavController, decorators: [{ type: Optional },] },
65621 { type: ViewController, decorators: [{ type: Optional },] },
65622 { type: App, },
65623 { type: Config, },
65624 { type: ElementRef, },
65625 { type: Platform, },
65626 { type: Renderer, },
65627 { type: DeepLinker, },
65628 { type: Keyboard, },
65629]; };
65630Tabs.propDecorators = {
65631 'name': [{ type: Input },],
65632 'selectedIndex': [{ type: Input },],
65633 'tabsLayout': [{ type: Input },],
65634 'tabsPlacement': [{ type: Input },],
65635 'tabsHighlight': [{ type: Input },],
65636 'ionChange': [{ type: Output },],
65637 '_highlight': [{ type: ViewChild, args: [TabHighlight,] },],
65638 '_tabbar': [{ type: ViewChild, args: ['tabbar',] },],
65639 'portal': [{ type: ViewChild, args: ['portal', { read: ViewContainerRef },] },],
65640};
65641var tabIds = -1;
65642
65643var __extends$78 = (undefined && undefined.__extends) || (function () {
65644 var extendStatics = Object.setPrototypeOf ||
65645 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
65646 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
65647 return function (d, b) {
65648 extendStatics(d, b);
65649 function __() { this.constructor = d; }
65650 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
65651 };
65652})();
65653/**
65654 * \@name Tab
65655 * \@description
65656 * The Tab component, written `<ion-tab>`, is styled based on the mode and should
65657 * be used in conjunction with the [Tabs](../Tabs/) component.
65658 *
65659 * Each `ion-tab` is a declarative component for a [NavController](../../../navigation/NavController/).
65660 * Basically, each tab is a `NavController`. For more information on using
65661 * navigation controllers take a look at the [NavController API Docs](../../../navigation/NavController/).
65662 *
65663 * See the [Tabs API Docs](../Tabs/) for more details on configuring Tabs.
65664 *
65665 * \@usage
65666 *
65667 * To add a basic tab, you can use the following markup where the `root` property
65668 * is the page you want to load for that tab, `tabTitle` is the optional text to
65669 * display on the tab, and `tabIcon` is the optional [icon](../../icon/Icon/).
65670 *
65671 * ```html
65672 * <ion-tabs>
65673 * <ion-tab [root]="chatRoot" tabTitle="Chat" tabIcon="chat"></ion-tab>
65674 * </ion-tabs>
65675 * ```
65676 *
65677 * Then, in your class you can set `chatRoot` to an imported class:
65678 *
65679 * ```ts
65680 * import { ChatPage } from '../chat/chat';
65681 *
65682 * export class Tabs {
65683 * // here we'll set the property of chatRoot to
65684 * // the imported class of ChatPage
65685 * chatRoot = ChatPage;
65686 *
65687 * constructor() {
65688 *
65689 * }
65690 * }
65691 * ```
65692 *
65693 * You can also pass some parameters to the root page of the tab through
65694 * `rootParams`. Below we pass `chatParams` to the Chat tab:
65695 *
65696 * ```html
65697 * <ion-tabs>
65698 * <ion-tab [root]="chatRoot" [rootParams]="chatParams" tabTitle="Chat" tabIcon="chat"></ion-tab>
65699 * </ion-tabs>
65700 * ```
65701 *
65702 * ```ts
65703 * export class Tabs {
65704 * chatRoot = ChatPage;
65705 *
65706 * // set some user information on chatParams
65707 * chatParams = {
65708 * user1: 'admin',
65709 * user2: 'ionic'
65710 * };
65711 *
65712 * constructor() {
65713 *
65714 * }
65715 * }
65716 * ```
65717 *
65718 * And in `ChatPage` you can get the data from `NavParams`:
65719 *
65720 * ```ts
65721 * export class ChatPage {
65722 * constructor(navParams: NavParams) {
65723 * console.log('Passed params', navParams.data);
65724 * }
65725 * }
65726 * ```
65727 *
65728 * Sometimes you may want to call a method instead of navigating to a new
65729 * page. You can use the `(ionSelect)` event to call a method on your class when
65730 * the tab is selected. Below is an example of presenting a modal from one of
65731 * the tabs.
65732 *
65733 * ```html
65734 * <ion-tabs>
65735 * <ion-tab (ionSelect)="chat()" tabTitle="Show Modal"></ion-tab>
65736 * </ion-tabs>pop
65737 * ```
65738 *
65739 * ```ts
65740 * export class Tabs {
65741 * constructor(public modalCtrl: ModalController) {
65742 *
65743 * }
65744 *
65745 * chat() {
65746 * let modal = this.modalCtrl.create(ChatPage);
65747 * modal.present();
65748 * }
65749 * }
65750 * ```
65751 *
65752 *
65753 * \@demo /docs/demos/src/tabs/
65754 * @see {\@link /docs/components#tabs Tabs Component Docs}
65755 * @see {\@link ../../tabs/Tabs Tabs API Docs}
65756 * @see {\@link ../../nav/Nav Nav API Docs}
65757 * @see {\@link ../../nav/NavController NavController API Docs}
65758 */
65759var Tab = (function (_super) {
65760 __extends$78(Tab, _super);
65761 /**
65762 * @param {?} parent
65763 * @param {?} app
65764 * @param {?} config
65765 * @param {?} plt
65766 * @param {?} elementRef
65767 * @param {?} zone
65768 * @param {?} renderer
65769 * @param {?} cfr
65770 * @param {?} _cd
65771 * @param {?} gestureCtrl
65772 * @param {?} transCtrl
65773 * @param {?} linker
65774 * @param {?} _dom
65775 * @param {?} errHandler
65776 */
65777 function Tab(parent, app, config, plt, elementRef, zone, renderer, cfr, _cd, gestureCtrl, transCtrl, linker, _dom, errHandler) {
65778 var _this =
65779 // A Tab is a NavController for its child pages
65780 _super.call(this, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler) || this;
65781 _this._cd = _cd;
65782 _this.linker = linker;
65783 _this._dom = _dom;
65784 /**
65785 * @hidden
65786 */
65787 _this._isEnabled = true;
65788 /**
65789 * @hidden
65790 */
65791 _this._isShown = true;
65792 /**
65793 * \@output {Tab} Emitted when the current tab is selected.
65794 */
65795 _this.ionSelect = new EventEmitter();
65796 _this.id = parent.add(_this);
65797 _this._tabsHideOnSubPages = config.getBoolean('tabsHideOnSubPages');
65798 _this._tabId = 'tabpanel-' + _this.id;
65799 _this._btnId = 'tab-' + _this.id;
65800 return _this;
65801 }
65802 Object.defineProperty(Tab.prototype, "enabled", {
65803 /**
65804 * \@input {boolean} If true, enable the tab. If false,
65805 * the user cannot interact with this element.
65806 * Default: `true`.
65807 * @return {?}
65808 */
65809 get: function () {
65810 return this._isEnabled;
65811 },
65812 /**
65813 * @param {?} val
65814 * @return {?}
65815 */
65816 set: function (val) {
65817 this._isEnabled = isTrueProperty(val);
65818 },
65819 enumerable: true,
65820 configurable: true
65821 });
65822 Object.defineProperty(Tab.prototype, "show", {
65823 /**
65824 * \@input {boolean} If true, the tab button is visible within the
65825 * tabbar. Default: `true`.
65826 * @return {?}
65827 */
65828 get: function () {
65829 return this._isShown;
65830 },
65831 /**
65832 * @param {?} val
65833 * @return {?}
65834 */
65835 set: function (val) {
65836 this._isShown = isTrueProperty(val);
65837 },
65838 enumerable: true,
65839 configurable: true
65840 });
65841 Object.defineProperty(Tab.prototype, "tabsHideOnSubPages", {
65842 /**
65843 * \@input {boolean} If true, hide the tabs on child pages.
65844 * @return {?}
65845 */
65846 get: function () {
65847 return this._tabsHideOnSubPages;
65848 },
65849 /**
65850 * @param {?} val
65851 * @return {?}
65852 */
65853 set: function (val) {
65854 this._tabsHideOnSubPages = isTrueProperty(val);
65855 },
65856 enumerable: true,
65857 configurable: true
65858 });
65859 Object.defineProperty(Tab.prototype, "_vp", {
65860 /**
65861 * @hidden
65862 * @param {?} val
65863 * @return {?}
65864 */
65865 set: function (val) {
65866 this.setViewport(val);
65867 },
65868 enumerable: true,
65869 configurable: true
65870 });
65871 /**
65872 * @hidden
65873 * @return {?}
65874 */
65875 Tab.prototype.ngOnInit = function () {
65876 this.tabBadgeStyle = this.tabBadgeStyle ? this.tabBadgeStyle : 'default';
65877 };
65878 /**
65879 * @hidden
65880 * @param {?} opts
65881 * @param {?=} done
65882 * @return {?}
65883 */
65884 Tab.prototype.load = function (opts, done) {
65885 var _this = this;
65886 if (this._lazyRootFromUrl || (!this._loaded && this.root)) {
65887 this.setElementClass('show-tab', true);
65888 // okay, first thing we need to do if check if the view already exists
65889 var /** @type {?} */ nameToUse = this._lazyRootFromUrl ? this._lazyRootFromUrl : this.root;
65890 var /** @type {?} */ dataToUse = this._lazyRootFromUrlData ? this._lazyRootFromUrlData : this.rootParams;
65891 var /** @type {?} */ numViews = this.length() - 1;
65892 for (var /** @type {?} */ i = numViews; i >= 0; i--) {
65893 var /** @type {?} */ viewController = this.getByIndex(i);
65894 if (viewController && (viewController.id === nameToUse || viewController.component === nameToUse)) {
65895 if (i === numViews) {
65896 // this is the last view in the stack and it's the same
65897 // as the segment so there's no change needed
65898 if (done) {
65899 done(false, false);
65900 }
65901 return;
65902 }
65903 else {
65904 // it's not the exact view as the end
65905 // let's have this nav go back to this exact view
65906 return this.popTo(viewController, {
65907 animate: false,
65908 updateUrl: false,
65909 }, done);
65910 }
65911 }
65912 }
65913 this.push(nameToUse, dataToUse, opts, done);
65914 this._lazyRootFromUrl = null;
65915 this._lazyRootFromUrlData = null;
65916 this._loaded = true;
65917 }
65918 else {
65919 // if this is not the Tab's initial load then we need
65920 // to refresh the tabbar and content dimensions to be sure
65921 // they're lined up correctly
65922 this._dom.read(function () {
65923 _this.resize();
65924 });
65925 if (done) {
65926 done(false, false);
65927 }
65928 return;
65929 }
65930 };
65931 /**
65932 * @hidden
65933 * @return {?}
65934 */
65935 Tab.prototype.resize = function () {
65936 var /** @type {?} */ active = this.getActive();
65937 if (!active) {
65938 return;
65939 }
65940 var /** @type {?} */ content = active.getIONContent();
65941 content && content.resize();
65942 };
65943 /**
65944 * @hidden
65945 * @param {?} viewCtrl
65946 * @param {?} componentRef
65947 * @param {?} viewport
65948 * @return {?}
65949 */
65950 Tab.prototype._viewAttachToDOM = function (viewCtrl, componentRef, viewport) {
65951 var /** @type {?} */ isTabSubPage = (this._tabsHideOnSubPages && viewCtrl.index > 0);
65952 if (isTabSubPage) {
65953 viewport = this.parent.portal;
65954 }
65955 _super.prototype._viewAttachToDOM.call(this, viewCtrl, componentRef, viewport);
65956 if (isTabSubPage) {
65957 // add the .tab-subpage css class to tabs pages that should act like subpages
65958 var /** @type {?} */ pageEleRef = viewCtrl.pageRef();
65959 if (pageEleRef) {
65960 this._renderer.setElementClass(pageEleRef.nativeElement, 'tab-subpage', true);
65961 }
65962 }
65963 };
65964 /**
65965 * @hidden
65966 * @param {?} isSelected
65967 * @return {?}
65968 */
65969 Tab.prototype.setSelected = function (isSelected) {
65970 this.isSelected = isSelected;
65971 this.setElementClass('show-tab', isSelected);
65972 this.setElementAttribute('aria-hidden', (!isSelected).toString());
65973 if (isSelected) {
65974 // this is the selected tab, detect changes
65975 this._cd.reattach();
65976 }
65977 else {
65978 // this tab is not selected, do not detect changes
65979 this._cd.detach();
65980 }
65981 };
65982 Object.defineProperty(Tab.prototype, "index", {
65983 /**
65984 * @hidden
65985 * @return {?}
65986 */
65987 get: function () {
65988 return this.parent.getIndex(this);
65989 },
65990 enumerable: true,
65991 configurable: true
65992 });
65993 /**
65994 * @hidden
65995 * @param {?} component
65996 * @param {?} data
65997 * @return {?}
65998 */
65999 Tab.prototype.updateHref = function (component, data) {
66000 if (this.btn && this.linker) {
66001 var /** @type {?} */ href = this.linker.createUrl(this.parent, component, data) || '#';
66002 this.btn.updateHref(href);
66003 }
66004 };
66005 /**
66006 * @hidden
66007 * @return {?}
66008 */
66009 Tab.prototype.ngOnDestroy = function () {
66010 this.destroy();
66011 };
66012 /**
66013 * @hidden
66014 * @return {?}
66015 */
66016 Tab.prototype.getType = function () {
66017 return 'tab';
66018 };
66019 /**
66020 * @param {?} opts
66021 * @return {?}
66022 */
66023 Tab.prototype.goToRoot = function (opts) {
66024 return this.setRoot(this.root, this.rootParams, opts, null);
66025 };
66026 return Tab;
66027}(NavControllerBase));
66028Tab.decorators = [
66029 { type: Component, args: [{
66030 selector: 'ion-tab',
66031 template: '<div #viewport></div><div class="nav-decor"></div>',
66032 host: {
66033 '[attr.id]': '_tabId',
66034 '[attr.aria-labelledby]': '_btnId',
66035 'role': 'tabpanel'
66036 },
66037 encapsulation: ViewEncapsulation.None,
66038 },] },
66039];
66040/**
66041 * @nocollapse
66042 */
66043Tab.ctorParameters = function () { return [
66044 { type: Tabs, },
66045 { type: App, },
66046 { type: Config, },
66047 { type: Platform, },
66048 { type: ElementRef, },
66049 { type: NgZone, },
66050 { type: Renderer, },
66051 { type: ComponentFactoryResolver, },
66052 { type: ChangeDetectorRef, },
66053 { type: GestureController, },
66054 { type: TransitionController, },
66055 { type: DeepLinker, decorators: [{ type: Optional },] },
66056 { type: DomController, },
66057 { type: ErrorHandler, },
66058]; };
66059Tab.propDecorators = {
66060 'root': [{ type: Input },],
66061 'rootParams': [{ type: Input },],
66062 'tabUrlPath': [{ type: Input },],
66063 'tabTitle': [{ type: Input },],
66064 'tabIcon': [{ type: Input },],
66065 'tabBadge': [{ type: Input },],
66066 'tabBadgeStyle': [{ type: Input },],
66067 'enabled': [{ type: Input },],
66068 'show': [{ type: Input },],
66069 'tabsHideOnSubPages': [{ type: Input },],
66070 'ionSelect': [{ type: Output },],
66071 '_vp': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
66072};
66073
66074var __extends$80 = (undefined && undefined.__extends) || (function () {
66075 var extendStatics = Object.setPrototypeOf ||
66076 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
66077 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
66078 return function (d, b) {
66079 extendStatics(d, b);
66080 function __() { this.constructor = d; }
66081 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
66082 };
66083})();
66084/**
66085 * @hidden
66086 */
66087var TabButton = (function (_super) {
66088 __extends$80(TabButton, _super);
66089 /**
66090 * @param {?} config
66091 * @param {?} elementRef
66092 * @param {?} renderer
66093 */
66094 function TabButton(config, elementRef, renderer) {
66095 var _this = _super.call(this, config, elementRef, renderer) || this;
66096 _this.ionSelect = new EventEmitter();
66097 _this.disHover = (config.get('hoverCSS') === false);
66098 _this.layout = config.get('tabsLayout');
66099 return _this;
66100 }
66101 /**
66102 * @return {?}
66103 */
66104 TabButton.prototype.ngOnInit = function () {
66105 this.tab.btn = this;
66106 this.layout = this.tab.parent.tabsLayout || this.layout;
66107 this.hasTitle = !!this.tab.tabTitle;
66108 this.hasIcon = !!this.tab.tabIcon && this.layout !== 'icon-hide';
66109 this.hasTitleOnly = (this.hasTitle && !this.hasIcon);
66110 this.hasIconOnly = (this.hasIcon && !this.hasTitle);
66111 this.hasBadge = !!this.tab.tabBadge;
66112 };
66113 /**
66114 * @return {?}
66115 */
66116 TabButton.prototype.onClick = function () {
66117 this.ionSelect.emit(this.tab);
66118 return false;
66119 };
66120 /**
66121 * @param {?} href
66122 * @return {?}
66123 */
66124 TabButton.prototype.updateHref = function (href) {
66125 this.setElementAttribute('href', href);
66126 };
66127 return TabButton;
66128}(Ion));
66129TabButton.decorators = [
66130 { type: Component, args: [{
66131 selector: '.tab-button',
66132 template: '<ion-icon *ngIf="tab.tabIcon" [name]="tab.tabIcon" [isActive]="tab.isSelected" class="tab-button-icon"></ion-icon>' +
66133 '<span *ngIf="tab.tabTitle" class="tab-button-text">{{tab.tabTitle}}</span>' +
66134 '<ion-badge *ngIf="tab.tabBadge" class="tab-badge" [color]="tab.tabBadgeStyle">{{tab.tabBadge}}</ion-badge>' +
66135 '<div class="button-effect"></div>',
66136 host: {
66137 '[attr.id]': 'tab._btnId',
66138 '[attr.aria-controls]': 'tab._tabId',
66139 '[attr.aria-selected]': 'tab.isSelected',
66140 '[class.has-title]': 'hasTitle',
66141 '[class.has-icon]': 'hasIcon',
66142 '[class.has-title-only]': 'hasTitleOnly',
66143 '[class.icon-only]': 'hasIconOnly',
66144 '[class.has-badge]': 'hasBadge',
66145 '[class.disable-hover]': 'disHover',
66146 '[class.tab-disabled]': '!tab.enabled',
66147 '[class.tab-hidden]': '!tab.show',
66148 }
66149 },] },
66150];
66151/**
66152 * @nocollapse
66153 */
66154TabButton.ctorParameters = function () { return [
66155 { type: Config, },
66156 { type: ElementRef, },
66157 { type: Renderer, },
66158]; };
66159TabButton.propDecorators = {
66160 'tab': [{ type: Input },],
66161 'ionSelect': [{ type: Output },],
66162 'onClick': [{ type: HostListener, args: ['click',] },],
66163};
66164
66165/**
66166 * @hidden
66167 */
66168var ToastCmp = (function () {
66169 /**
66170 * @param {?} _viewCtrl
66171 * @param {?} _config
66172 * @param {?} _elementRef
66173 * @param {?} params
66174 * @param {?} renderer
66175 */
66176 function ToastCmp(_viewCtrl, _config, _elementRef, params, renderer) {
66177 this._viewCtrl = _viewCtrl;
66178 this._config = _config;
66179 this._elementRef = _elementRef;
66180 this.dismissTimeout = undefined;
66181 renderer.setElementClass(_elementRef.nativeElement, "toast-" + _config.get('mode'), true);
66182 this.d = params.data;
66183 if (this.d.cssClass) {
66184 this.d.cssClass.split(' ').forEach(function (cssClass) {
66185 // Make sure the class isn't whitespace, otherwise it throws exceptions
66186 if (cssClass.trim() !== '')
66187 renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
66188 });
66189 }
66190 this.id = (++toastIds);
66191 if (this.d.message) {
66192 this.hdrId = 'toast-hdr-' + this.id;
66193 }
66194 }
66195 /**
66196 * @return {?}
66197 */
66198 ToastCmp.prototype.ngAfterViewInit = function () {
66199 var _this = this;
66200 // if there's a `duration` set, automatically dismiss.
66201 if (this.d.duration) {
66202 this.dismissTimeout = ((setTimeout(function () {
66203 _this.dismiss('backdrop');
66204 }, this.d.duration)));
66205 }
66206 this.enabled = true;
66207 };
66208 /**
66209 * @return {?}
66210 */
66211 ToastCmp.prototype.ionViewDidEnter = function () {
66212 var activeElement = document.activeElement;
66213 if (activeElement) {
66214 activeElement.blur();
66215 }
66216 var /** @type {?} */ focusableEle = this._elementRef.nativeElement.querySelector('button');
66217 if (focusableEle) {
66218 focusableEle.focus();
66219 }
66220 };
66221 /**
66222 * @return {?}
66223 */
66224 ToastCmp.prototype.cbClick = function () {
66225 if (this.enabled) {
66226 this.dismiss('close');
66227 }
66228 };
66229 /**
66230 * @param {?} role
66231 * @return {?}
66232 */
66233 ToastCmp.prototype.dismiss = function (role) {
66234 clearTimeout(this.dismissTimeout);
66235 this.dismissTimeout = undefined;
66236 return this._viewCtrl.dismiss(null, role, { disableApp: false });
66237 };
66238 return ToastCmp;
66239}());
66240ToastCmp.decorators = [
66241 { type: Component, args: [{
66242 selector: 'ion-toast',
66243 template: '<div class="toast-wrapper" ' +
66244 '[class.toast-bottom]="d.position === \'bottom\'" ' +
66245 '[class.toast-middle]="d.position === \'middle\'" ' +
66246 '[class.toast-top]="d.position === \'top\'"> ' +
66247 '<div class="toast-container"> ' +
66248 '<div class="toast-message" id="{{hdrId}}" *ngIf="d.message">{{d.message}}</div> ' +
66249 '<button ion-button clear class="toast-button" *ngIf="d.showCloseButton" (click)="cbClick()"> ' +
66250 '{{ d.closeButtonText || \'Close\' }} ' +
66251 '</button> ' +
66252 '</div> ' +
66253 '</div>',
66254 host: {
66255 'role': 'dialog',
66256 '[attr.aria-labelledby]': 'hdrId',
66257 '[attr.aria-describedby]': 'descId',
66258 },
66259 },] },
66260];
66261/**
66262 * @nocollapse
66263 */
66264ToastCmp.ctorParameters = function () { return [
66265 { type: ViewController, },
66266 { type: Config, },
66267 { type: ElementRef, },
66268 { type: NavParams, },
66269 { type: Renderer, },
66270]; };
66271var toastIds = -1;
66272
66273var __extends$82 = (undefined && undefined.__extends) || (function () {
66274 var extendStatics = Object.setPrototypeOf ||
66275 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
66276 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
66277 return function (d, b) {
66278 extendStatics(d, b);
66279 function __() { this.constructor = d; }
66280 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
66281 };
66282})();
66283var ToastSlideIn = (function (_super) {
66284 __extends$82(ToastSlideIn, _super);
66285 function ToastSlideIn() {
66286 return _super !== null && _super.apply(this, arguments) || this;
66287 }
66288 /**
66289 * @return {?}
66290 */
66291 ToastSlideIn.prototype.init = function () {
66292 // DOM READS
66293 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
66294 var /** @type {?} */ wrapperEle = (ele.querySelector('.toast-wrapper'));
66295 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66296 if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
66297 // top
66298 // by default, it is -100% hidden (above the screen)
66299 // so move from that to 10px below top: 0px;
66300 wrapper.fromTo('translateY', '-100%', 10 + "px");
66301 }
66302 else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
66303 // Middle
66304 // just center it and fade it in
66305 var /** @type {?} */ topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
66306 // DOM WRITE
66307 wrapperEle.style.top = topPosition + "px";
66308 wrapper.fromTo('opacity', 0.01, 1);
66309 }
66310 else {
66311 // bottom
66312 // by default, it is 100% hidden (below the screen),
66313 // so move from that to 10 px above bottom: 0px
66314 wrapper.fromTo('translateY', '100%', 0 - 10 + "px");
66315 }
66316 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(wrapper);
66317 };
66318 return ToastSlideIn;
66319}(Transition));
66320var ToastSlideOut = (function (_super) {
66321 __extends$82(ToastSlideOut, _super);
66322 function ToastSlideOut() {
66323 return _super !== null && _super.apply(this, arguments) || this;
66324 }
66325 /**
66326 * @return {?}
66327 */
66328 ToastSlideOut.prototype.init = function () {
66329 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
66330 var /** @type {?} */ wrapperEle = (ele.querySelector('.toast-wrapper'));
66331 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66332 if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
66333 // top
66334 // reverse arguments from enter transition
66335 wrapper.fromTo('translateY', 10 + "px", '-100%');
66336 }
66337 else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
66338 // Middle
66339 // just fade it out
66340 wrapper.fromTo('opacity', 0.99, 0);
66341 }
66342 else {
66343 // bottom
66344 // reverse arguments from enter transition
66345 wrapper.fromTo('translateY', 0 - 10 + "px", '100%');
66346 }
66347 this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(wrapper);
66348 };
66349 return ToastSlideOut;
66350}(Transition));
66351var ToastMdSlideIn = (function (_super) {
66352 __extends$82(ToastMdSlideIn, _super);
66353 function ToastMdSlideIn() {
66354 return _super !== null && _super.apply(this, arguments) || this;
66355 }
66356 /**
66357 * @return {?}
66358 */
66359 ToastMdSlideIn.prototype.init = function () {
66360 // DOM reads
66361 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
66362 var /** @type {?} */ wrapperEle = ele.querySelector('.toast-wrapper');
66363 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66364 if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
66365 // top
66366 // by default, it is -100% hidden (above the screen)
66367 // so move from that to top: 0px;
66368 wrapper.fromTo('translateY', '-100%', "0%");
66369 }
66370 else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
66371 // Middle
66372 // just center it and fade it in
66373 var /** @type {?} */ topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
66374 // DOM WRITE
66375 wrapperEle.style.top = topPosition + "px";
66376 wrapper.fromTo('opacity', 0.01, 1);
66377 }
66378 else {
66379 // bottom
66380 // by default, it is 100% hidden (below the screen),
66381 // so move from that to bottom: 0px
66382 wrapper.fromTo('translateY', '100%', "0%");
66383 }
66384 this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(wrapper);
66385 };
66386 return ToastMdSlideIn;
66387}(Transition));
66388var ToastMdSlideOut = (function (_super) {
66389 __extends$82(ToastMdSlideOut, _super);
66390 function ToastMdSlideOut() {
66391 return _super !== null && _super.apply(this, arguments) || this;
66392 }
66393 /**
66394 * @return {?}
66395 */
66396 ToastMdSlideOut.prototype.init = function () {
66397 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
66398 var /** @type {?} */ wrapperEle = ele.querySelector('.toast-wrapper');
66399 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66400 if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
66401 // top
66402 // reverse arguments from enter transition
66403 wrapper.fromTo('translateY', 0 + "%", '-100%');
66404 }
66405 else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
66406 // Middle
66407 // just fade it out
66408 wrapper.fromTo('opacity', 0.99, 0);
66409 }
66410 else {
66411 // bottom
66412 // reverse arguments from enter transition
66413 wrapper.fromTo('translateY', 0 + "%", '100%');
66414 }
66415 this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(wrapper);
66416 };
66417 return ToastMdSlideOut;
66418}(Transition));
66419var ToastWpPopIn = (function (_super) {
66420 __extends$82(ToastWpPopIn, _super);
66421 function ToastWpPopIn() {
66422 return _super !== null && _super.apply(this, arguments) || this;
66423 }
66424 /**
66425 * @return {?}
66426 */
66427 ToastWpPopIn.prototype.init = function () {
66428 var /** @type {?} */ ele = this.enteringView.pageRef().nativeElement;
66429 var /** @type {?} */ wrapperEle = ele.querySelector('.toast-wrapper');
66430 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66431 if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
66432 // top
66433 wrapper.fromTo('opacity', 0.01, 1);
66434 wrapper.fromTo('scale', 1.3, 1);
66435 }
66436 else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
66437 // Middle
66438 // just center it and fade it in
66439 var /** @type {?} */ topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
66440 // DOM WRITE
66441 wrapperEle.style.top = topPosition + "px";
66442 wrapper.fromTo('opacity', 0.01, 1);
66443 wrapper.fromTo('scale', 1.3, 1);
66444 }
66445 else {
66446 // bottom
66447 wrapper.fromTo('opacity', 0.01, 1);
66448 wrapper.fromTo('scale', 1.3, 1);
66449 }
66450 this.easing('cubic-bezier(0,0,0.05,1)').duration(200).add(wrapper);
66451 };
66452 return ToastWpPopIn;
66453}(Transition));
66454var ToastWpPopOut = (function (_super) {
66455 __extends$82(ToastWpPopOut, _super);
66456 function ToastWpPopOut() {
66457 return _super !== null && _super.apply(this, arguments) || this;
66458 }
66459 /**
66460 * @return {?}
66461 */
66462 ToastWpPopOut.prototype.init = function () {
66463 // DOM reads
66464 var /** @type {?} */ ele = this.leavingView.pageRef().nativeElement;
66465 var /** @type {?} */ wrapperEle = ele.querySelector('.toast-wrapper');
66466 var /** @type {?} */ wrapper = new Animation(this.plt, wrapperEle);
66467 if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
66468 // top
66469 // reverse arguments from enter transition
66470 wrapper.fromTo('opacity', 0.99, 0);
66471 wrapper.fromTo('scale', 1, 1.3);
66472 }
66473 else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
66474 // Middle
66475 // just fade it out
66476 wrapper.fromTo('opacity', 0.99, 0);
66477 wrapper.fromTo('scale', 1, 1.3);
66478 }
66479 else {
66480 // bottom
66481 // reverse arguments from enter transition
66482 wrapper.fromTo('opacity', 0.99, 0);
66483 wrapper.fromTo('scale', 1, 1.3);
66484 }
66485 // DOM writes
66486 var /** @type {?} */ EASE = 'ease-out';
66487 var /** @type {?} */ DURATION = 150;
66488 this.easing(EASE).duration(DURATION).add(wrapper);
66489 };
66490 return ToastWpPopOut;
66491}(Transition));
66492var TOAST_POSITION_TOP$1 = 'top';
66493var TOAST_POSITION_MIDDLE$1 = 'middle';
66494
66495var __extends$81 = (undefined && undefined.__extends) || (function () {
66496 var extendStatics = Object.setPrototypeOf ||
66497 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
66498 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
66499 return function (d, b) {
66500 extendStatics(d, b);
66501 function __() { this.constructor = d; }
66502 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
66503 };
66504})();
66505/**
66506 * @hidden
66507 */
66508var Toast = (function (_super) {
66509 __extends$81(Toast, _super);
66510 /**
66511 * @param {?} app
66512 * @param {?=} opts
66513 * @param {?=} config
66514 */
66515 function Toast(app, opts, config) {
66516 if (opts === void 0) { opts = {}; }
66517 var _this = this;
66518 opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
66519 _this = _super.call(this, ToastCmp, opts, null) || this;
66520 _this._app = app;
66521 // set the position to the bottom if not provided
66522 if (!opts.position || !_this.isValidPosition(opts.position)) {
66523 opts.position = TOAST_POSITION_BOTTOM;
66524 }
66525 _this.isOverlay = true;
66526 config.setTransition('toast-slide-in', ToastSlideIn);
66527 config.setTransition('toast-slide-out', ToastSlideOut);
66528 config.setTransition('toast-md-slide-in', ToastMdSlideIn);
66529 config.setTransition('toast-md-slide-out', ToastMdSlideOut);
66530 config.setTransition('toast-wp-slide-out', ToastWpPopOut);
66531 config.setTransition('toast-wp-slide-in', ToastWpPopIn);
66532 return _this;
66533 }
66534 /**
66535 * @hidden
66536 * @param {?} direction
66537 * @return {?}
66538 */
66539 Toast.prototype.getTransitionName = function (direction) {
66540 var /** @type {?} */ key = 'toast' + (direction === 'back' ? 'Leave' : 'Enter');
66541 return this._nav && this._nav.config.get(key);
66542 };
66543 /**
66544 * @hidden
66545 * @param {?} position
66546 * @return {?}
66547 */
66548 Toast.prototype.isValidPosition = function (position) {
66549 return position === TOAST_POSITION_TOP || position === TOAST_POSITION_MIDDLE || position === TOAST_POSITION_BOTTOM;
66550 };
66551 /**
66552 * @param {?} message
66553 * @return {?}
66554 */
66555 Toast.prototype.setMessage = function (message) {
66556 this.data.message = message;
66557 return this;
66558 };
66559 /**
66560 * @param {?} dur
66561 * @return {?}
66562 */
66563 Toast.prototype.setDuration = function (dur) {
66564 this.data.duration = dur;
66565 return this;
66566 };
66567 /**
66568 * @param {?} pos
66569 * @return {?}
66570 */
66571 Toast.prototype.setPosition = function (pos) {
66572 this.data.position = pos;
66573 return this;
66574 };
66575 /**
66576 * @param {?} cssClass
66577 * @return {?}
66578 */
66579 Toast.prototype.setCssClass = function (cssClass) {
66580 this.data.cssClass = cssClass;
66581 return this;
66582 };
66583 /**
66584 * @param {?} closeButton
66585 * @return {?}
66586 */
66587 Toast.prototype.setShowCloseButton = function (closeButton) {
66588 this.data.showCloseButton = closeButton;
66589 return this;
66590 };
66591 /**
66592 * Present the toast instance.
66593 *
66594 * @param {?=} navOptions
66595 * @return {?}
66596 */
66597 Toast.prototype.present = function (navOptions) {
66598 if (navOptions === void 0) { navOptions = {}; }
66599 navOptions.disableApp = false;
66600 navOptions.keyboardClose = false;
66601 return this._app.present(this, navOptions, PORTAL_TOAST);
66602 };
66603 /**
66604 * Dismiss all toast components which have been presented.
66605 * @return {?}
66606 */
66607 Toast.prototype.dismissAll = function () {
66608 this._nav && this._nav.popAll();
66609 };
66610 return Toast;
66611}(ViewController));
66612var TOAST_POSITION_TOP = 'top';
66613var TOAST_POSITION_MIDDLE = 'middle';
66614var TOAST_POSITION_BOTTOM = 'bottom';
66615
66616/**
66617 * \@name ToastController
66618 * \@description
66619 * A Toast is a subtle notification commonly used in modern applications.
66620 * It can be used to provide feedback about an operation or to
66621 * display a system message. The toast appears on top of the app's content,
66622 * and can be dismissed by the app to resume user interaction with
66623 * the app.
66624 *
66625 * ### Creating
66626 * All of the toast options should be passed in the first argument of
66627 * the create method: `create(opts)`. The message to display should be
66628 * passed in the `message` property. The `showCloseButton` option can be set to
66629 * true in order to display a close button on the toast. See the [create](#create)
66630 * method below for all available options.
66631 *
66632 * ### Positioning
66633 * Toasts can be positioned at the top, bottom or middle of the
66634 * view port. The position can be passed to the `Toast.create(opts)` method.
66635 * The position option is a string, and the values accepted are `top`, `bottom` and `middle`.
66636 * If the position is not specified, the toast will be displayed at the bottom of the view port.
66637 *
66638 * ### Dismissing
66639 * The toast can be dismissed automatically after a specific amount of time
66640 * by passing the number of milliseconds to display it in the `duration` of
66641 * the toast options. If `showCloseButton` is set to true, then the close button
66642 * will dismiss the toast. To dismiss the toast after creation, call the `dismiss()`
66643 * method on the Toast instance. The `onDidDismiss` function can be called to perform an action after the toast
66644 * is dismissed.
66645 *
66646 * \@usage
66647 * ```ts
66648 * import { ToastController } from 'ionic-angular';
66649 *
66650 * constructor(public toastCtrl: ToastController) { }
66651 *
66652 * presentToast() {
66653 * const toast = this.toastCtrl.create({
66654 * message: 'User was added successfully',
66655 * duration: 3000,
66656 * position: 'top'
66657 * });
66658 *
66659 * toast.onDidDismiss(() => {
66660 * console.log('Dismissed toast');
66661 * });
66662 *
66663 * toast.present();
66664 * }
66665 * ```
66666 * \@advanced
66667 * | Property | Type | Default | Description |
66668 * |-----------------------|-----------|-----------------|---------------------------------------------------------------------------------------------------------------|
66669 * | message | `string` | - | The message for the toast. Long strings will wrap and the toast container will expand. |
66670 * | duration | `number` | - | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. |
66671 * | position | `string` | "bottom" | The position of the toast on the screen. Accepted values: "top", "middle", "bottom". |
66672 * | cssClass | `string` | - | Additional classes for custom styles, separated by spaces. |
66673 * | showCloseButton | `boolean` | false | Whether or not to show a button to close the toast. |
66674 * | closeButtonText | `string` | "Close" | Text to display in the close button. |
66675 * | dismissOnPageChange | `boolean` | false | Whether to dismiss the toast when navigating to a new page. |
66676 *
66677 * \@demo /docs/demos/src/toast/
66678 */
66679var ToastController = (function () {
66680 /**
66681 * @param {?} _app
66682 * @param {?} config
66683 */
66684 function ToastController(_app, config) {
66685 this._app = _app;
66686 this.config = config;
66687 }
66688 /**
66689 * Create a new toast component. See options below
66690 * @param {?=} opts
66691 * @return {?}
66692 */
66693 ToastController.prototype.create = function (opts) {
66694 if (opts === void 0) { opts = {}; }
66695 return new Toast(this._app, opts, this.config);
66696 };
66697 return ToastController;
66698}());
66699ToastController.decorators = [
66700 { type: Injectable },
66701];
66702/**
66703 * @nocollapse
66704 */
66705ToastController.ctorParameters = function () { return [
66706 { type: App, },
66707 { type: Config, },
66708]; };
66709
66710var __extends$84 = (undefined && undefined.__extends) || (function () {
66711 var extendStatics = Object.setPrototypeOf ||
66712 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
66713 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
66714 return function (d, b) {
66715 extendStatics(d, b);
66716 function __() { this.constructor = d; }
66717 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
66718 };
66719})();
66720/**
66721 * @hidden
66722 */
66723var ToggleGesture = (function (_super) {
66724 __extends$84(ToggleGesture, _super);
66725 /**
66726 * @param {?} plt
66727 * @param {?} toggle
66728 * @param {?} gestureCtrl
66729 * @param {?} domCtrl
66730 */
66731 function ToggleGesture(plt, toggle, gestureCtrl, domCtrl) {
66732 var _this = _super.call(this, plt, toggle.getNativeElement(), {
66733 threshold: 0,
66734 zone: false,
66735 domController: domCtrl,
66736 gesture: gestureCtrl.createGesture({
66737 name: GESTURE_TOGGLE,
66738 priority: GESTURE_PRIORITY_TOGGLE
66739 })
66740 }) || this;
66741 _this.toggle = toggle;
66742 return _this;
66743 }
66744 /**
66745 * @return {?}
66746 */
66747 ToggleGesture.prototype.canStart = function () {
66748 return true;
66749 };
66750 /**
66751 * @param {?} ev
66752 * @return {?}
66753 */
66754 ToggleGesture.prototype.onDragStart = function (ev) {
66755 ev.preventDefault();
66756 this.toggle._onDragStart(pointerCoord(ev).x);
66757 };
66758 /**
66759 * @param {?} ev
66760 * @return {?}
66761 */
66762 ToggleGesture.prototype.onDragMove = function (ev) {
66763 ev.preventDefault();
66764 this.toggle._onDragMove(pointerCoord(ev).x);
66765 };
66766 /**
66767 * @param {?} ev
66768 * @return {?}
66769 */
66770 ToggleGesture.prototype.onDragEnd = function (ev) {
66771 ev.preventDefault();
66772 this.toggle._onDragEnd(pointerCoord(ev).x);
66773 };
66774 return ToggleGesture;
66775}(PanGesture));
66776
66777var __extends$83 = (undefined && undefined.__extends) || (function () {
66778 var extendStatics = Object.setPrototypeOf ||
66779 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
66780 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
66781 return function (d, b) {
66782 extendStatics(d, b);
66783 function __() { this.constructor = d; }
66784 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
66785 };
66786})();
66787/**
66788 * \@name Toggle
66789 * \@description
66790 * A toggle technically is the same thing as an HTML checkbox input,
66791 * except it looks different and is easier to use on a touch device.
66792 * Toggles can also have colors assigned to them, by adding any color
66793 * attribute.
66794 *
66795 * See the [Angular Docs](https://angular.io/docs/ts/latest/guide/forms.html)
66796 * for more info on forms and inputs.
66797 *
66798 * \@usage
66799 * ```html
66800 *
66801 * <ion-list>
66802 *
66803 * <ion-item>
66804 * <ion-label>Pepperoni</ion-label>
66805 * <ion-toggle [(ngModel)]="pepperoni"></ion-toggle>
66806 * </ion-item>
66807 *
66808 * <ion-item>
66809 * <ion-label>Sausage</ion-label>
66810 * <ion-toggle [(ngModel)]="sausage" disabled="true"></ion-toggle>
66811 * </ion-item>
66812 *
66813 * <ion-item>
66814 * <ion-label>Mushrooms</ion-label>
66815 * <ion-toggle [(ngModel)]="mushrooms"></ion-toggle>
66816 * </ion-item>
66817 *
66818 * </ion-list>
66819 * ```
66820 *
66821 * \@demo /docs/demos/src/toggle/
66822 * @see {\@link /docs/components#toggle Toggle Component Docs}
66823 */
66824var Toggle = (function (_super) {
66825 __extends$83(Toggle, _super);
66826 /**
66827 * @param {?} form
66828 * @param {?} config
66829 * @param {?} _plt
66830 * @param {?} elementRef
66831 * @param {?} renderer
66832 * @param {?} _haptic
66833 * @param {?} item
66834 * @param {?} _gestureCtrl
66835 * @param {?} _domCtrl
66836 * @param {?} _zone
66837 */
66838 function Toggle(form, config, _plt, elementRef, renderer, _haptic, item, _gestureCtrl, _domCtrl, _zone) {
66839 var _this = _super.call(this, config, elementRef, renderer, 'toggle', false, form, item, null) || this;
66840 _this._plt = _plt;
66841 _this._haptic = _haptic;
66842 _this._gestureCtrl = _gestureCtrl;
66843 _this._domCtrl = _domCtrl;
66844 _this._zone = _zone;
66845 _this._activated = false;
66846 return _this;
66847 }
66848 Object.defineProperty(Toggle.prototype, "checked", {
66849 /**
66850 * \@input {boolean} If true, the element is selected.
66851 * @return {?}
66852 */
66853 get: function () {
66854 return this.value;
66855 },
66856 /**
66857 * @param {?} val
66858 * @return {?}
66859 */
66860 set: function (val) {
66861 this.value = val;
66862 },
66863 enumerable: true,
66864 configurable: true
66865 });
66866 /**
66867 * @hidden
66868 * @return {?}
66869 */
66870 Toggle.prototype.ngAfterContentInit = function () {
66871 this._initialize();
66872 this._gesture = new ToggleGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
66873 this._gesture.listen();
66874 };
66875 /**
66876 * @hidden
66877 * @return {?}
66878 */
66879 Toggle.prototype._inputUpdated = function () { };
66880 /**
66881 * @hidden
66882 * @param {?} val
66883 * @return {?}
66884 */
66885 Toggle.prototype._inputNormalize = function (val) {
66886 return isTrueProperty(val);
66887 };
66888 /**
66889 * @hidden
66890 * @param {?} startX
66891 * @return {?}
66892 */
66893 Toggle.prototype._onDragStart = function (startX) {
66894 var _this = this;
66895 (void 0) /* assert */;
66896 (void 0) /* console.debug */;
66897 this._zone.run(function () {
66898 _this._startX = startX;
66899 _this._fireFocus();
66900 _this._activated = true;
66901 });
66902 };
66903 /**
66904 * @hidden
66905 * @param {?} currentX
66906 * @return {?}
66907 */
66908 Toggle.prototype._onDragMove = function (currentX) {
66909 var _this = this;
66910 if (!this._startX) {
66911 (void 0) /* assert */;
66912 return;
66913 }
66914 if (this._shouldToggle(currentX, -15)) {
66915 this._zone.run(function () {
66916 _this.value = !_this.value;
66917 _this._startX = currentX;
66918 _this._haptic.selection();
66919 });
66920 }
66921 };
66922 /**
66923 * @hidden
66924 * @param {?} endX
66925 * @return {?}
66926 */
66927 Toggle.prototype._onDragEnd = function (endX) {
66928 var _this = this;
66929 if (!this._startX) {
66930 (void 0) /* assert */;
66931 return;
66932 }
66933 (void 0) /* console.debug */;
66934 this._zone.run(function () {
66935 if (_this._shouldToggle(endX, 4)) {
66936 _this.value = !_this.value;
66937 _this._haptic.selection();
66938 }
66939 _this._activated = false;
66940 _this._fireBlur();
66941 _this._startX = null;
66942 });
66943 };
66944 /**
66945 * @hidden
66946 * @param {?} currentX
66947 * @param {?} margin
66948 * @return {?}
66949 */
66950 Toggle.prototype._shouldToggle = function (currentX, margin) {
66951 var /** @type {?} */ isLTR = !this._plt.isRTL;
66952 var /** @type {?} */ startX = this._startX;
66953 if (this._value) {
66954 return (isLTR && (startX + margin > currentX)) ||
66955 (!isLTR && (startX - margin < currentX));
66956 }
66957 else {
66958 return (isLTR && (startX - margin < currentX)) ||
66959 (!isLTR && (startX + margin > currentX));
66960 }
66961 };
66962 /**
66963 * @hidden
66964 * @param {?} ev
66965 * @return {?}
66966 */
66967 Toggle.prototype._keyup = function (ev) {
66968 if (ev.keyCode === KEY_SPACE || ev.keyCode === KEY_ENTER) {
66969 (void 0) /* console.debug */;
66970 ev.preventDefault();
66971 ev.stopPropagation();
66972 this.value = !this.value;
66973 }
66974 };
66975 /**
66976 * @hidden
66977 * @return {?}
66978 */
66979 Toggle.prototype.ngOnDestroy = function () {
66980 _super.prototype.ngOnDestroy.call(this);
66981 this._gesture && this._gesture.destroy();
66982 };
66983 return Toggle;
66984}(BaseInput));
66985Toggle.decorators = [
66986 { type: Component, args: [{
66987 selector: 'ion-toggle',
66988 template: '<div class="toggle-icon">' +
66989 '<div class="toggle-inner"></div>' +
66990 '</div>' +
66991 '<button role="checkbox" ' +
66992 'type="button" ' +
66993 'ion-button="item-cover" ' +
66994 '[id]="id" ' +
66995 '[attr.aria-checked]="_value" ' +
66996 '[attr.aria-labelledby]="_labelId" ' +
66997 '[attr.aria-disabled]="_disabled" ' +
66998 'class="item-cover" disable-activated>' +
66999 '</button>',
67000 host: {
67001 '[class.toggle-disabled]': '_disabled',
67002 '[class.toggle-checked]': '_value',
67003 '[class.toggle-activated]': '_activated',
67004 },
67005 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Toggle, multi: true }],
67006 encapsulation: ViewEncapsulation.None,
67007 },] },
67008];
67009/**
67010 * @nocollapse
67011 */
67012Toggle.ctorParameters = function () { return [
67013 { type: Form, },
67014 { type: Config, },
67015 { type: Platform, },
67016 { type: ElementRef, },
67017 { type: Renderer, },
67018 { type: Haptic, },
67019 { type: Item, decorators: [{ type: Optional },] },
67020 { type: GestureController, },
67021 { type: DomController, },
67022 { type: NgZone, },
67023]; };
67024Toggle.propDecorators = {
67025 'checked': [{ type: Input },],
67026 '_keyup': [{ type: HostListener, args: ['keyup', ['$event'],] },],
67027};
67028
67029var __extends$85 = (undefined && undefined.__extends) || (function () {
67030 var extendStatics = Object.setPrototypeOf ||
67031 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67032 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67033 return function (d, b) {
67034 extendStatics(d, b);
67035 function __() { this.constructor = d; }
67036 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67037 };
67038})();
67039/**
67040 * \@name Footer
67041 * \@description
67042 * Footer is a root component of a page that sits at the bottom of the page.
67043 * Footer can be a wrapper for `ion-toolbar` to make sure the content area is sized correctly.
67044 *
67045 * \@usage
67046 *
67047 * ```html
67048 * <ion-content></ion-content>
67049 *
67050 * <ion-footer>
67051 * <ion-toolbar>
67052 * <ion-title>Footer</ion-title>
67053 * </ion-toolbar>
67054 * </ion-footer>
67055 * ```
67056 *
67057 */
67058var Footer = (function (_super) {
67059 __extends$85(Footer, _super);
67060 /**
67061 * @param {?} config
67062 * @param {?} elementRef
67063 * @param {?} renderer
67064 * @param {?} viewCtrl
67065 */
67066 function Footer(config, elementRef, renderer, viewCtrl) {
67067 var _this = _super.call(this, config, elementRef, renderer, 'footer') || this;
67068 viewCtrl && viewCtrl._setFooter(_this);
67069 return _this;
67070 }
67071 return Footer;
67072}(Ion));
67073Footer.decorators = [
67074 { type: Directive, args: [{
67075 selector: 'ion-footer'
67076 },] },
67077];
67078/**
67079 * @nocollapse
67080 */
67081Footer.ctorParameters = function () { return [
67082 { type: Config, },
67083 { type: ElementRef, },
67084 { type: Renderer, },
67085 { type: ViewController, decorators: [{ type: Optional },] },
67086]; };
67087
67088var __extends$86 = (undefined && undefined.__extends) || (function () {
67089 var extendStatics = Object.setPrototypeOf ||
67090 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67091 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67092 return function (d, b) {
67093 extendStatics(d, b);
67094 function __() { this.constructor = d; }
67095 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67096 };
67097})();
67098/**
67099 * \@name Header
67100 * \@description
67101 * Header is a parent component that holds the navbar and toolbar component.
67102 * It's important to note that `ion-header` needs to be one of the three root elements of a page
67103 *
67104 * \@usage
67105 *
67106 * ```html
67107 * <ion-header>
67108 * <ion-navbar>
67109 * <ion-title>Page1</ion-title>
67110 * </ion-navbar>
67111 *
67112 * <ion-toolbar>
67113 * <ion-title>Subheader</ion-title>
67114 * </ion-toolbar>
67115 * </ion-header>
67116 *
67117 * <ion-content></ion-content>
67118 * ```
67119 *
67120 */
67121var Header = (function (_super) {
67122 __extends$86(Header, _super);
67123 /**
67124 * @param {?} config
67125 * @param {?} elementRef
67126 * @param {?} renderer
67127 * @param {?} viewCtrl
67128 */
67129 function Header(config, elementRef, renderer, viewCtrl) {
67130 var _this = _super.call(this, config, elementRef, renderer, 'header') || this;
67131 viewCtrl && viewCtrl._setHeader(_this);
67132 return _this;
67133 }
67134 return Header;
67135}(Ion));
67136Header.decorators = [
67137 { type: Directive, args: [{
67138 selector: 'ion-header'
67139 },] },
67140];
67141/**
67142 * @nocollapse
67143 */
67144Header.ctorParameters = function () { return [
67145 { type: Config, },
67146 { type: ElementRef, },
67147 { type: Renderer, },
67148 { type: ViewController, decorators: [{ type: Optional },] },
67149]; };
67150
67151var __extends$87 = (undefined && undefined.__extends) || (function () {
67152 var extendStatics = Object.setPrototypeOf ||
67153 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67154 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67155 return function (d, b) {
67156 extendStatics(d, b);
67157 function __() { this.constructor = d; }
67158 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67159 };
67160})();
67161/**
67162 * \@name Toolbar
67163 * \@description
67164 * A Toolbar is a generic bar that is positioned above or below content.
67165 * Unlike a [Navbar](../Navbar/), a toolbar can be used as a subheader.
67166 * When toolbars are placed within an `<ion-header>` or `<ion-footer>`,
67167 * the toolbars stay fixed in their respective location. When placed within
67168 * `<ion-content>`, toolbars will scroll with the content.
67169 *
67170 *
67171 * ### Buttons in a Toolbar
67172 * Buttons placed in a toolbar should be placed inside of the `<ion-buttons>`
67173 * element. An exception to this is a [menuToggle](../../menu/MenuToggle) button.
67174 * It should not be placed inside of the `<ion-buttons>` element. Both the
67175 * `<ion-buttons>` element and the `menuToggle` can be positioned inside of the
67176 * toolbar using different properties. The below chart has a description of each
67177 * property.
67178 *
67179 * | Property | Description |
67180 * |-------------|-----------------------------------------------------------------------------------------------------------------------|
67181 * | `start` | Positions element to the left of the content in `ios` mode, and directly to the right in `md` and `wp` mode. |
67182 * | `end` | Positions element to the right of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
67183 * | `left` | Positions element to the left of all other elements. |
67184 * | `right` | Positions element to the right of all other elements. |
67185 *
67186 *
67187 * ### Header / Footer Box Shadow and Border
67188 * In `md` mode, the `<ion-header>` will receive a box-shadow on the bottom, and the
67189 * `<ion-footer>` will receive a box-shadow on the top. In `ios` mode, the `<ion-header>`
67190 * will receive a border on the bottom, and the `<ion-footer>` will receive a border on the
67191 * top. Both the `md` box-shadow and the `ios` border can be removed by adding the `no-border`
67192 * attribute to the element.
67193 *
67194 * ```html
67195 * <ion-header no-border>
67196 * <ion-toolbar>
67197 * <ion-title>Header</ion-title>
67198 * </ion-toolbar>
67199 * </ion-header>
67200 *
67201 * <ion-content>
67202 * </ion-content>
67203 *
67204 * <ion-footer no-border>
67205 * <ion-toolbar>
67206 * <ion-title>Footer</ion-title>
67207 * </ion-toolbar>
67208 * </ion-footer>
67209 * ```
67210 *
67211 * \@usage
67212 *
67213 * ```html
67214 *
67215 * <ion-header no-border>
67216 *
67217 * <ion-toolbar>
67218 * <ion-title>My Toolbar Title</ion-title>
67219 * </ion-toolbar>
67220 *
67221 * <ion-toolbar>
67222 * <ion-title>I'm a subheader</ion-title>
67223 * </ion-toolbar>
67224 *
67225 * <ion-header>
67226 *
67227 *
67228 * <ion-content>
67229 *
67230 * <ion-toolbar>
67231 * <ion-title>Scrolls with the content</ion-title>
67232 * </ion-toolbar>
67233 *
67234 * </ion-content>
67235 *
67236 *
67237 * <ion-footer no-border>
67238 *
67239 * <ion-toolbar>
67240 * <ion-title>I'm a footer</ion-title>
67241 * </ion-toolbar>
67242 *
67243 * </ion-footer>
67244 * ```
67245 *
67246 * \@demo /docs/demos/src/toolbar/
67247 * @see {\@link ../Navbar/ Navbar API Docs}
67248 */
67249var Toolbar = (function (_super) {
67250 __extends$87(Toolbar, _super);
67251 /**
67252 * @param {?} config
67253 * @param {?} elementRef
67254 * @param {?} renderer
67255 */
67256 function Toolbar(config, elementRef, renderer) {
67257 var _this = _super.call(this, config, elementRef, renderer) || this;
67258 _this._sbPadding = config.getBoolean('statusbarPadding');
67259 return _this;
67260 }
67261 return Toolbar;
67262}(ToolbarBase));
67263Toolbar.decorators = [
67264 { type: Component, args: [{
67265 selector: 'ion-toolbar',
67266 template: '<div class="toolbar-background" [ngClass]="\'toolbar-background-\' + _mode"></div>' +
67267 '<ng-content select="[menuToggle],ion-buttons[left]"></ng-content>' +
67268 '<ng-content select="ion-buttons[start]"></ng-content>' +
67269 '<ng-content select="ion-buttons[end],ion-buttons[right]"></ng-content>' +
67270 '<div class="toolbar-content" [ngClass]="\'toolbar-content-\' + _mode">' +
67271 '<ng-content></ng-content>' +
67272 '</div>',
67273 host: {
67274 'class': 'toolbar',
67275 '[class.statusbar-padding]': '_sbPadding'
67276 },
67277 changeDetection: ChangeDetectionStrategy.OnPush,
67278 },] },
67279];
67280/**
67281 * @nocollapse
67282 */
67283Toolbar.ctorParameters = function () { return [
67284 { type: Config, },
67285 { type: ElementRef, },
67286 { type: Renderer, },
67287]; };
67288
67289var __extends$88 = (undefined && undefined.__extends) || (function () {
67290 var extendStatics = Object.setPrototypeOf ||
67291 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67292 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67293 return function (d, b) {
67294 extendStatics(d, b);
67295 function __() { this.constructor = d; }
67296 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67297 };
67298})();
67299/**
67300 * @hidden
67301 */
67302var ToolbarItem = (function (_super) {
67303 __extends$88(ToolbarItem, _super);
67304 /**
67305 * @param {?} config
67306 * @param {?} elementRef
67307 * @param {?} renderer
67308 * @param {?} toolbar
67309 * @param {?} navbar
67310 */
67311 function ToolbarItem(config, elementRef, renderer, toolbar, navbar) {
67312 var _this = _super.call(this, config, elementRef, renderer, 'bar-buttons') || this;
67313 _this.inToolbar = !!(toolbar || navbar);
67314 return _this;
67315 }
67316 Object.defineProperty(ToolbarItem.prototype, "_buttons", {
67317 /**
67318 * @param {?} buttons
67319 * @return {?}
67320 */
67321 set: function (buttons) {
67322 if (this.inToolbar) {
67323 buttons.forEach(function (button) {
67324 button.setRole('bar-button');
67325 });
67326 }
67327 },
67328 enumerable: true,
67329 configurable: true
67330 });
67331 return ToolbarItem;
67332}(Ion));
67333ToolbarItem.decorators = [
67334 { type: Directive, args: [{
67335 selector: 'ion-buttons,[menuToggle]'
67336 },] },
67337];
67338/**
67339 * @nocollapse
67340 */
67341ToolbarItem.ctorParameters = function () { return [
67342 { type: Config, },
67343 { type: ElementRef, },
67344 { type: Renderer, },
67345 { type: Toolbar, decorators: [{ type: Optional },] },
67346 { type: Navbar, decorators: [{ type: Optional }, { type: Inject, args: [forwardRef(function () { return Navbar; }),] },] },
67347]; };
67348ToolbarItem.propDecorators = {
67349 '_buttons': [{ type: ContentChildren, args: [Button,] },],
67350};
67351
67352var __extends$89 = (undefined && undefined.__extends) || (function () {
67353 var extendStatics = Object.setPrototypeOf ||
67354 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67355 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67356 return function (d, b) {
67357 extendStatics(d, b);
67358 function __() { this.constructor = d; }
67359 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67360 };
67361})();
67362/**
67363 * \@name Title
67364 * \@description
67365 * `ion-title` is a component that sets the title of the `Toolbar` or `Navbar`
67366 *
67367 * \@usage
67368 *
67369 * ```html
67370 * <ion-header>
67371 *
67372 * <ion-navbar>
67373 * <ion-title>Settings</ion-title>
67374 * </ion-navbar>
67375 *
67376 * </ion-header>
67377 * ```
67378 *
67379 * Or to create a navbar with a toolbar as a subheader:
67380 *
67381 * ```html
67382 * <ion-header>
67383 *
67384 * <ion-navbar>
67385 * <ion-title>Main Header</ion-title>
67386 * </ion-navbar>
67387 *
67388 * <ion-toolbar>
67389 * <ion-title>Subheader</ion-title>
67390 * </ion-toolbar>
67391 *
67392 * </ion-header>
67393 * ```
67394 *
67395 * \@demo /docs/demos/src/title/
67396 */
67397var ToolbarTitle = (function (_super) {
67398 __extends$89(ToolbarTitle, _super);
67399 /**
67400 * @param {?} config
67401 * @param {?} elementRef
67402 * @param {?} renderer
67403 * @param {?} toolbar
67404 * @param {?} navbar
67405 */
67406 function ToolbarTitle(config, elementRef, renderer, toolbar, navbar) {
67407 var _this = _super.call(this, config, elementRef, renderer, 'title') || this;
67408 toolbar && toolbar._setTitle(_this);
67409 navbar && navbar._setTitle(_this);
67410 return _this;
67411 }
67412 /**
67413 * @hidden
67414 * @return {?}
67415 */
67416 ToolbarTitle.prototype.getTitleText = function () {
67417 return this._elementRef.nativeElement.textContent;
67418 };
67419 return ToolbarTitle;
67420}(Ion));
67421ToolbarTitle.decorators = [
67422 { type: Component, args: [{
67423 selector: 'ion-title',
67424 template: '<div class="toolbar-title" [ngClass]="\'toolbar-title-\' + _mode">' +
67425 '<ng-content></ng-content>' +
67426 '</div>',
67427 changeDetection: ChangeDetectionStrategy.OnPush,
67428 encapsulation: ViewEncapsulation.None,
67429 },] },
67430];
67431/**
67432 * @nocollapse
67433 */
67434ToolbarTitle.ctorParameters = function () { return [
67435 { type: Config, },
67436 { type: ElementRef, },
67437 { type: Renderer, },
67438 { type: Toolbar, decorators: [{ type: Optional },] },
67439 { type: Navbar, decorators: [{ type: Optional }, { type: Inject, args: [forwardRef(function () { return Navbar; }),] },] },
67440]; };
67441
67442/**
67443 * \@name Thumbnail
67444 * \@module ionic
67445 * \@description
67446 * A Thumbnail is a component that creates a squared image for an item.
67447 * Thumbnails can be place on the left or right side of an item with the `item-start` or `item-end` directive.
67448 * @see {\@link /docs/components/#thumbnail-list Thumbnail Component Docs}
67449 */
67450var Thumbnail = (function () {
67451 function Thumbnail() {
67452 }
67453 return Thumbnail;
67454}());
67455Thumbnail.decorators = [
67456 { type: Directive, args: [{
67457 selector: 'ion-thumbnail'
67458 },] },
67459];
67460/**
67461 * @nocollapse
67462 */
67463Thumbnail.ctorParameters = function () { return []; };
67464
67465var __extends$90 = (undefined && undefined.__extends) || (function () {
67466 var extendStatics = Object.setPrototypeOf ||
67467 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
67468 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
67469 return function (d, b) {
67470 extendStatics(d, b);
67471 function __() { this.constructor = d; }
67472 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
67473 };
67474})();
67475/**
67476 * \@name Typography
67477 * \@module ionic
67478 * \@description
67479 *
67480 * The Typography component is a simple component that can be used to style the text color of any element.
67481 * The `ion-text` attribute should be added to the element in order to pass a color from the Sass `$colors`
67482 * map and change the text color of that element.
67483 *
67484 * \@usage
67485 *
67486 * ```html
67487 * <h1 ion-text color="secondary">H1: The quick brown fox jumps over the lazy dog</h1>
67488 *
67489 * <h2 ion-text color="primary">H2: The quick brown fox jumps over the lazy dog</h2>
67490 *
67491 * <h3 ion-text color="light">H3: The quick brown fox jumps over the lazy dog</h3>
67492 *
67493 * <h4 ion-text color="danger">H4: The quick brown fox jumps over the lazy dog</h4>
67494 *
67495 * <h5 ion-text color="dark">H5: The quick brown fox jumps over the lazy dog</h5>
67496 *
67497 * <h6 ion-text [color]="dynamicColor">H6: The quick brown fox jumps over the lazy dog</h6>
67498 *
67499 * <p>
67500 * I saw a werewolf with a Chinese menu in his hand.
67501 * Walking through the <sub ion-text color="danger">streets</sub> of Soho in the rain.
67502 * He <i ion-text color="primary">was</i> looking for a place called Lee Ho Fook's.
67503 * Gonna get a <a ion-text color="secondary">big dish of beef chow mein.</a>
67504 * </p>
67505 *
67506 * <p>
67507 * He's the hairy-handed gent who ran amuck in Kent.
67508 * Lately he's <sup ion-text color="primary">been</sup> overheard in Mayfair.
67509 * Better stay away from him.
67510 * He'll rip your lungs out, Jim.
67511 * I'd like to meet his tailor.
67512 * </p>
67513 * ```
67514 *
67515 */
67516var Typography = (function (_super) {
67517 __extends$90(Typography, _super);
67518 /**
67519 * @param {?} config
67520 * @param {?} elementRef
67521 * @param {?} renderer
67522 */
67523 function Typography(config, elementRef, renderer) {
67524 return _super.call(this, config, elementRef, renderer, 'text') || this;
67525 }
67526 return Typography;
67527}(Ion));
67528Typography.decorators = [
67529 { type: Directive, args: [{
67530 selector: '[ion-text]'
67531 },] },
67532];
67533/**
67534 * @nocollapse
67535 */
67536Typography.ctorParameters = function () { return [
67537 { type: Config, },
67538 { type: ElementRef, },
67539 { type: Renderer, },
67540]; };
67541
67542/**
67543 * @hidden
67544 */
67545var VirtualFooter = (function () {
67546 /**
67547 * @param {?} templateRef
67548 */
67549 function VirtualFooter(templateRef) {
67550 this.templateRef = templateRef;
67551 }
67552 return VirtualFooter;
67553}());
67554VirtualFooter.decorators = [
67555 { type: Directive, args: [{ selector: '[virtualFooter]' },] },
67556];
67557/**
67558 * @nocollapse
67559 */
67560VirtualFooter.ctorParameters = function () { return [
67561 { type: TemplateRef, },
67562]; };
67563
67564/**
67565 * @hidden
67566 */
67567var VirtualHeader = (function () {
67568 /**
67569 * @param {?} templateRef
67570 */
67571 function VirtualHeader(templateRef) {
67572 this.templateRef = templateRef;
67573 }
67574 return VirtualHeader;
67575}());
67576VirtualHeader.decorators = [
67577 { type: Directive, args: [{ selector: '[virtualHeader]' },] },
67578];
67579/**
67580 * @nocollapse
67581 */
67582VirtualHeader.ctorParameters = function () { return [
67583 { type: TemplateRef, },
67584]; };
67585
67586/**
67587 * @hidden
67588 */
67589var VirtualItem = (function () {
67590 /**
67591 * @param {?} templateRef
67592 * @param {?} viewContainer
67593 */
67594 function VirtualItem(templateRef, viewContainer) {
67595 this.templateRef = templateRef;
67596 this.viewContainer = viewContainer;
67597 }
67598 return VirtualItem;
67599}());
67600VirtualItem.decorators = [
67601 { type: Directive, args: [{ selector: '[virtualItem]' },] },
67602];
67603/**
67604 * @nocollapse
67605 */
67606VirtualItem.ctorParameters = function () { return [
67607 { type: TemplateRef, },
67608 { type: ViewContainerRef, },
67609]; };
67610
67611var PREVIOUS_CELL = {
67612 row: 0,
67613 width: 0,
67614 height: 0,
67615 top: 0,
67616 left: 0,
67617 tmpl: -1
67618};
67619/**
67620 * NO DOM
67621 * @param {?} stopAtHeight
67622 * @param {?} records
67623 * @param {?} cells
67624 * @param {?} headerFn
67625 * @param {?} footerFn
67626 * @param {?} data
67627 * @return {?}
67628 */
67629function processRecords(stopAtHeight, records, cells, headerFn, footerFn, data) {
67630 var /** @type {?} */ record;
67631 var /** @type {?} */ startRecordIndex;
67632 var /** @type {?} */ previousCell;
67633 var /** @type {?} */ tmpData;
67634 var /** @type {?} */ lastRecordIndex = records ? (records.length - 1) : -1;
67635 if (cells.length) {
67636 // we already have cells
67637 previousCell = cells[cells.length - 1];
67638 if (previousCell.top + previousCell.height > stopAtHeight) {
67639 return;
67640 }
67641 startRecordIndex = (previousCell.record + 1);
67642 }
67643 else {
67644 // no cells have been created yet
67645 previousCell = PREVIOUS_CELL;
67646 startRecordIndex = 0;
67647 }
67648 var /** @type {?} */ processedTotal = 0;
67649 for (var /** @type {?} */ recordIndex = startRecordIndex; recordIndex <= lastRecordIndex; recordIndex++) {
67650 record = records[recordIndex];
67651 if (headerFn) {
67652 tmpData = headerFn(record, recordIndex, records);
67653 if (tmpData !== null) {
67654 // add header data
67655 previousCell = addCell(previousCell, recordIndex, TEMPLATE_HEADER, tmpData, data.hdrWidth, data.hdrHeight, data.viewWidth);
67656 cells.push(previousCell);
67657 }
67658 }
67659 // add item data
67660 previousCell = addCell(previousCell, recordIndex, TEMPLATE_ITEM, null, data.itmWidth, data.itmHeight, data.viewWidth);
67661 cells.push(previousCell);
67662 if (footerFn) {
67663 tmpData = footerFn(record, recordIndex, records);
67664 if (tmpData !== null) {
67665 // add footer data
67666 previousCell = addCell(previousCell, recordIndex, TEMPLATE_FOOTER, tmpData, data.ftrWidth, data.ftrHeight, data.viewWidth);
67667 cells.push(previousCell);
67668 }
67669 }
67670 if (previousCell.record === lastRecordIndex) {
67671 previousCell.isLast = true;
67672 }
67673 // should always process at least 3 records
67674 processedTotal++;
67675 if (previousCell.top + previousCell.height + data.itmHeight > stopAtHeight && processedTotal > 3) {
67676 return;
67677 }
67678 }
67679}
67680/**
67681 * @param {?} previousCell
67682 * @param {?} recordIndex
67683 * @param {?} tmpl
67684 * @param {?} tmplData
67685 * @param {?} cellWidth
67686 * @param {?} cellHeight
67687 * @param {?} viewportWidth
67688 * @return {?}
67689 */
67690function addCell(previousCell, recordIndex, tmpl, tmplData, cellWidth, cellHeight, viewportWidth) {
67691 var /** @type {?} */ newCell;
67692 if (previousCell.left + previousCell.width + cellWidth > viewportWidth) {
67693 // add a new cell in a new row
67694 newCell = {
67695 record: recordIndex,
67696 tmpl: tmpl,
67697 row: (previousCell.row + 1),
67698 width: cellWidth,
67699 height: cellHeight,
67700 top: (previousCell.top + previousCell.height),
67701 left: 0,
67702 reads: 0,
67703 };
67704 }
67705 else {
67706 // add a new cell in the same row
67707 newCell = {
67708 record: recordIndex,
67709 tmpl: tmpl,
67710 row: previousCell.row,
67711 width: cellWidth,
67712 height: cellHeight,
67713 top: previousCell.top,
67714 left: (previousCell.left + previousCell.width),
67715 reads: 0,
67716 };
67717 }
67718 if (tmplData) {
67719 newCell.data = tmplData;
67720 }
67721 return newCell;
67722}
67723/**
67724 * NO DOM
67725 * @param {?} startCellIndex
67726 * @param {?} endCellIndex
67727 * @param {?} scrollingDown
67728 * @param {?} cells
67729 * @param {?} records
67730 * @param {?} nodes
67731 * @param {?} viewContainer
67732 * @param {?} itmTmp
67733 * @param {?} hdrTmp
67734 * @param {?} ftrTmp
67735 * @param {?} initialLoad
67736 * @return {?}
67737 */
67738function populateNodeData(startCellIndex, endCellIndex, scrollingDown, cells, records, nodes, viewContainer, itmTmp, hdrTmp, ftrTmp, initialLoad) {
67739 if (!records || records.length === 0) {
67740 nodes.length = 0;
67741 return true;
67742 }
67743 var /** @type {?} */ recordsLength = records.length;
67744 var /** @type {?} */ hasChanges = false;
67745 var /** @type {?} */ node;
67746 var /** @type {?} */ availableNode;
67747 var /** @type {?} */ cell;
67748 var /** @type {?} */ isAlreadyRendered;
67749 var /** @type {?} */ viewInsertIndex = null;
67750 var /** @type {?} */ totalNodes = nodes.length;
67751 var /** @type {?} */ templateRef;
67752 startCellIndex = Math.max(startCellIndex, 0);
67753 endCellIndex = Math.min(endCellIndex, cells.length - 1);
67754 for (var /** @type {?} */ cellIndex = startCellIndex; cellIndex <= endCellIndex; cellIndex++) {
67755 cell = cells[cellIndex];
67756 availableNode = null;
67757 isAlreadyRendered = false;
67758 // find the first one that's available
67759 if (!initialLoad) {
67760 for (var /** @type {?} */ i = 0; i < totalNodes; i++) {
67761 node = nodes[i];
67762 if (cell.tmpl !== node.tmpl || i === 0 && cellIndex !== 0) {
67763 // the cell must use the correct template
67764 // first node can only be used by the first cell (css :first-child reasons)
67765 // this node is never available to be reused
67766 continue;
67767 }
67768 if (node.cell === cellIndex) {
67769 isAlreadyRendered = true;
67770 break;
67771 }
67772 if (node.cell < startCellIndex || node.cell > endCellIndex) {
67773 if (!availableNode) {
67774 // havent gotten an available node yet
67775 availableNode = nodes[i];
67776 }
67777 else if (scrollingDown) {
67778 // scrolling down
67779 if (node.cell < availableNode.cell) {
67780 availableNode = nodes[i];
67781 }
67782 }
67783 else {
67784 // scrolling up
67785 if (node.cell > availableNode.cell) {
67786 availableNode = nodes[i];
67787 }
67788 }
67789 }
67790 }
67791 if (isAlreadyRendered) {
67792 continue;
67793 }
67794 }
67795 if (!availableNode) {
67796 // did not find an available node to put the cell data into
67797 // insert a new node before the last record nodes
67798 if (viewInsertIndex === null) {
67799 viewInsertIndex = -1;
67800 for (var /** @type {?} */ j = totalNodes - 1; j >= 0; j--) {
67801 node = nodes[j];
67802 if (node) {
67803 viewInsertIndex = viewContainer.indexOf(node.view);
67804 break;
67805 }
67806 }
67807 }
67808 // select which templateRef should be used for this cell
67809 templateRef = cell.tmpl === TEMPLATE_HEADER ? hdrTmp : cell.tmpl === TEMPLATE_FOOTER ? ftrTmp : itmTmp;
67810 if (!templateRef) {
67811 console.error("virtual" + (cell.tmpl === TEMPLATE_HEADER ? 'Header' : cell.tmpl === TEMPLATE_FOOTER ? 'Footer' : 'Item') + " template required");
67812 continue;
67813 }
67814 availableNode = {
67815 tmpl: cell.tmpl,
67816 view: viewContainer.createEmbeddedView(templateRef, new VirtualContext(null, null, null), viewInsertIndex)
67817 };
67818 totalNodes = nodes.push(availableNode);
67819 }
67820 // assign who's the new cell index for this node
67821 availableNode.cell = cellIndex;
67822 // apply the cell's data to this node
67823 var /** @type {?} */ context = availableNode.view.context;
67824 context.$implicit = cell.data || records[cell.record];
67825 context.index = cellIndex;
67826 context.count = recordsLength;
67827 availableNode.hasChanges = true;
67828 availableNode.lastTransform = null;
67829 hasChanges = true;
67830 }
67831 return hasChanges;
67832}
67833/**
67834 * DOM READ
67835 * @param {?} plt
67836 * @param {?} nodes
67837 * @param {?} cells
67838 * @param {?} data
67839 * @return {?}
67840 */
67841function initReadNodes(plt, nodes, cells, data) {
67842 if (nodes.length && cells.length) {
67843 // first node
67844 // ******** DOM READ ****************
67845 var /** @type {?} */ ele = getElement(nodes[0]);
67846 var /** @type {?} */ firstCell = cells[0];
67847 firstCell.top = ele.clientTop;
67848 firstCell.left = ele.clientLeft;
67849 firstCell.row = 0;
67850 // ******** DOM READ ****************
67851 updateDimensions(plt, nodes, cells, data, true);
67852 }
67853}
67854/**
67855 * DOM READ
67856 * @param {?} plt
67857 * @param {?} nodes
67858 * @param {?} cells
67859 * @param {?} data
67860 * @param {?} initialUpdate
67861 * @return {?}
67862 */
67863function updateDimensions(plt, nodes, cells, data, initialUpdate) {
67864 var /** @type {?} */ node;
67865 var /** @type {?} */ element;
67866 var /** @type {?} */ cell;
67867 var /** @type {?} */ previousCell;
67868 var /** @type {?} */ totalCells = cells.length;
67869 for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
67870 node = nodes[i];
67871 cell = cells[node.cell];
67872 // read element dimensions if they haven't been checked enough times
67873 if (cell && cell.reads < REQUIRED_DOM_READS) {
67874 element = getElement(node);
67875 // ******** DOM READ ****************
67876 readElements(plt, cell, element);
67877 if (initialUpdate) {
67878 // update estimated dimensions with more accurate dimensions
67879 if (cell.tmpl === TEMPLATE_HEADER) {
67880 data.hdrHeight = cell.height;
67881 if (cell.left === 0) {
67882 data.hdrWidth = cell.width;
67883 }
67884 }
67885 else if (cell.tmpl === TEMPLATE_FOOTER) {
67886 data.ftrHeight = cell.height;
67887 if (cell.left === 0) {
67888 data.ftrWidth = cell.width;
67889 }
67890 }
67891 else {
67892 data.itmHeight = cell.height;
67893 if (cell.left === 0) {
67894 data.itmWidth = cell.width;
67895 }
67896 }
67897 }
67898 cell.reads++;
67899 }
67900 }
67901 // figure out which cells are currently viewable within the viewport
67902 var /** @type {?} */ viewableBottom = (data.scrollTop + data.viewHeight);
67903 data.topViewCell = totalCells;
67904 data.bottomViewCell = 0;
67905 if (totalCells > 0) {
67906 // completely realign position to ensure they're all accurately placed
67907 cell = cells[0];
67908 previousCell = {
67909 row: 0,
67910 width: 0,
67911 height: 0,
67912 top: cell.top,
67913 left: 0,
67914 tmpl: -1
67915 };
67916 for (var /** @type {?} */ i_1 = 0; i_1 < totalCells; i_1++) {
67917 cell = cells[i_1];
67918 if (previousCell.left + previousCell.width + cell.width > data.viewWidth) {
67919 // new row
67920 cell.row++;
67921 cell.top = (previousCell.top + previousCell.height);
67922 cell.left = 0;
67923 }
67924 else {
67925 // same row
67926 cell.row = previousCell.row;
67927 cell.top = previousCell.top;
67928 cell.left = (previousCell.left + previousCell.width);
67929 }
67930 // figure out which cells are viewable within the viewport
67931 if (cell.top + cell.height > data.scrollTop && i_1 < data.topViewCell) {
67932 data.topViewCell = i_1;
67933 }
67934 else if (cell.top < viewableBottom && i_1 > data.bottomViewCell) {
67935 data.bottomViewCell = i_1;
67936 }
67937 previousCell = cell;
67938 }
67939 }
67940}
67941/**
67942 * @param {?} nodes
67943 * @param {?} cells
67944 * @param {?} data
67945 * @return {?}
67946 */
67947function updateNodeContext(nodes, cells, data) {
67948 // ensure each node has the correct bounds in its context
67949 var /** @type {?} */ node;
67950 var /** @type {?} */ cell;
67951 var /** @type {?} */ bounds;
67952 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = nodes.length; i < ilen; i++) {
67953 node = nodes[i];
67954 cell = cells[node.cell];
67955 if (node && cell) {
67956 bounds = node.view.context.bounds;
67957 bounds.top = cell.top + data.viewTop;
67958 bounds.bottom = bounds.top + cell.height;
67959 bounds.left = cell.left + data.viewLeft;
67960 bounds.right = bounds.left + cell.width;
67961 bounds.width = cell.width;
67962 bounds.height = cell.height;
67963 }
67964 }
67965}
67966/**
67967 * DOM READ
67968 * @param {?} plt
67969 * @param {?} cell
67970 * @param {?} element
67971 * @return {?}
67972 */
67973function readElements(plt, cell, element) {
67974 // ******** DOM READ ****************
67975 var /** @type {?} */ styles = plt.getElementComputedStyle(/** @type {?} */ (element));
67976 // ******** DOM READ ****************
67977 cell.left = (element.clientLeft - parseFloat(styles.marginLeft));
67978 // ******** DOM READ ****************
67979 cell.width = (element.offsetWidth + parseFloat(styles.marginLeft) + parseFloat(styles.marginRight));
67980 // ******** DOM READ ****************
67981 cell.height = (element.offsetHeight + parseFloat(styles.marginTop) + parseFloat(styles.marginBottom));
67982}
67983/**
67984 * DOM WRITE
67985 * @param {?} plt
67986 * @param {?} nodes
67987 * @param {?} cells
67988 * @param {?} totalRecords
67989 * @return {?}
67990 */
67991function writeToNodes(plt, nodes, cells, totalRecords) {
67992 var /** @type {?} */ node;
67993 var /** @type {?} */ element;
67994 var /** @type {?} */ cell;
67995 var /** @type {?} */ transform;
67996 var /** @type {?} */ totalCells = Math.max(totalRecords, cells.length);
67997 for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = nodes.length; i < ilen; i++) {
67998 node = nodes[i];
67999 cell = cells[node.cell];
68000 transform = "translate3d(" + cell.left + "px," + cell.top + "px,0px)";
68001 if (node.lastTransform !== transform) {
68002 element = getElement(node);
68003 if (element) {
68004 // ******** DOM WRITE ****************
68005 element.style[plt.Css.transform] = node.lastTransform = transform;
68006 // ******** DOM WRITE ****************
68007 element.classList.add('virtual-position');
68008 // https://www.w3.org/TR/wai-aria/states_and_properties#aria-posinset
68009 // ******** DOM WRITE ****************
68010 element.setAttribute('aria-posinset', node.cell + 1);
68011 // https://www.w3.org/TR/wai-aria/states_and_properties#aria-setsize
68012 // ******** DOM WRITE ****************
68013 element.setAttribute('aria-setsize', totalCells);
68014 }
68015 }
68016 }
68017}
68018/**
68019 * NO DOM
68020 * @param {?} cells
68021 * @param {?} data
68022 * @return {?}
68023 */
68024function adjustRendered(cells, data) {
68025 // figure out which cells should be rendered
68026 var /** @type {?} */ cell;
68027 var /** @type {?} */ lastRow = -1;
68028 var /** @type {?} */ cellsRenderHeight = 0;
68029 var /** @type {?} */ maxRenderHeight = (data.renderHeight - data.itmHeight);
68030 var /** @type {?} */ totalCells = cells.length;
68031 var /** @type {?} */ viewableRenderedPadding = (data.itmHeight < 90 ? VIEWABLE_RENDERED_PADDING : 0);
68032 if (data.scrollDiff > 0) {
68033 // scrolling down
68034 data.topCell = Math.max(data.topViewCell - viewableRenderedPadding, 0);
68035 data.bottomCell = Math.min(data.topCell + 2, totalCells - 1);
68036 for (var /** @type {?} */ i = data.topCell; i < totalCells; i++) {
68037 cell = cells[i];
68038 if (cell.row !== lastRow) {
68039 cellsRenderHeight += cell.height;
68040 lastRow = cell.row;
68041 }
68042 if (i > data.bottomCell) {
68043 data.bottomCell = i;
68044 }
68045 if (cellsRenderHeight >= maxRenderHeight) {
68046 break;
68047 }
68048 }
68049 }
68050 else {
68051 // scroll up
68052 data.bottomCell = Math.min(data.bottomViewCell + viewableRenderedPadding, totalCells - 1);
68053 data.topCell = Math.max(data.bottomCell - 2, 0);
68054 for (var /** @type {?} */ i_2 = data.bottomCell; i_2 >= 0; i_2--) {
68055 cell = cells[i_2];
68056 if (cell.row !== lastRow) {
68057 cellsRenderHeight += cell.height;
68058 lastRow = cell.row;
68059 }
68060 if (i_2 < data.topCell) {
68061 data.topCell = i_2;
68062 }
68063 if (cellsRenderHeight >= maxRenderHeight) {
68064 break;
68065 }
68066 }
68067 }
68068}
68069/**
68070 * NO DOM
68071 * @param {?} totalRecords
68072 * @param {?} lastCell
68073 * @return {?}
68074 */
68075function getVirtualHeight(totalRecords, lastCell) {
68076 if (lastCell.record >= totalRecords - 1) {
68077 return (lastCell.top + lastCell.height);
68078 }
68079 var /** @type {?} */ unknownRecords = (totalRecords - lastCell.record - 1);
68080 var /** @type {?} */ knownHeight = (lastCell.top + lastCell.height);
68081 return Math.ceil(knownHeight + ((knownHeight / (totalRecords - unknownRecords)) * unknownRecords));
68082}
68083/**
68084 * NO DOM
68085 * @param {?} totalRecords
68086 * @param {?} lastCell
68087 * @param {?} existingHeight
68088 * @param {?} difference
68089 * @return {?}
68090 */
68091function estimateHeight(totalRecords, lastCell, existingHeight, difference) {
68092 if (!totalRecords || !lastCell) {
68093 return 0;
68094 }
68095 var /** @type {?} */ newHeight = getVirtualHeight(totalRecords, lastCell);
68096 var /** @type {?} */ percentToBottom = (lastCell.record / (totalRecords - 1));
68097 var /** @type {?} */ diff = Math.abs(existingHeight - newHeight);
68098 if ((diff > (newHeight * difference)) ||
68099 (percentToBottom > .995)) {
68100 return newHeight;
68101 }
68102 return existingHeight;
68103}
68104/**
68105 * DOM READ
68106 * @param {?} data
68107 * @param {?} virtualScrollElement
68108 * @param {?} approxItemWidth
68109 * @param {?} approxItemHeight
68110 * @param {?} appoxHeaderWidth
68111 * @param {?} approxHeaderHeight
68112 * @param {?} approxFooterWidth
68113 * @param {?} approxFooterHeight
68114 * @param {?} bufferRatio
68115 * @return {?}
68116 */
68117function calcDimensions(data, virtualScrollElement, approxItemWidth, approxItemHeight, appoxHeaderWidth, approxHeaderHeight, approxFooterWidth, approxFooterHeight, bufferRatio) {
68118 // get the parent container's viewport bounds
68119 var /** @type {?} */ viewportElement = virtualScrollElement.parentElement;
68120 // ******** DOM READ ****************
68121 data.viewWidth = viewportElement.offsetWidth;
68122 // ******** DOM READ ****************
68123 data.viewHeight = viewportElement.offsetHeight;
68124 // get the virtual scroll element's offset data
68125 // ******** DOM READ ****************
68126 data.viewTop = virtualScrollElement.offsetTop;
68127 // ******** DOM READ ****************
68128 data.viewLeft = virtualScrollElement.offsetLeft;
68129 // the height we'd like to render, which is larger than viewable
68130 data.renderHeight = (data.viewHeight * bufferRatio);
68131 if (data.viewWidth > 0 && data.viewHeight > 0) {
68132 data.itmWidth = calcWidth(data.viewWidth, approxItemWidth);
68133 data.itmHeight = calcHeight(data.viewHeight, approxItemHeight);
68134 data.hdrWidth = calcWidth(data.viewWidth, appoxHeaderWidth);
68135 data.hdrHeight = calcHeight(data.viewHeight, approxHeaderHeight);
68136 data.ftrWidth = calcWidth(data.viewWidth, approxFooterWidth);
68137 data.ftrHeight = calcHeight(data.viewHeight, approxFooterHeight);
68138 data.valid = true;
68139 }
68140}
68141/**
68142 * NO DOM
68143 * @param {?} viewportWidth
68144 * @param {?} approxWidth
68145 * @return {?}
68146 */
68147function calcWidth(viewportWidth, approxWidth) {
68148 if (approxWidth.indexOf('%') > 0) {
68149 return (viewportWidth * (parseFloat(approxWidth) / 100));
68150 }
68151 else if (approxWidth.indexOf('px') > 0) {
68152 return parseFloat(approxWidth);
68153 }
68154 throw 'virtual scroll width can only use "%" or "px" units';
68155}
68156/**
68157 * NO DOM
68158 * @param {?} _viewportHeight
68159 * @param {?} approxHeight
68160 * @return {?}
68161 */
68162function calcHeight(_viewportHeight, approxHeight) {
68163 if (approxHeight.indexOf('px') > 0) {
68164 return parseFloat(approxHeight);
68165 }
68166 throw 'virtual scroll height must use "px" units';
68167}
68168/**
68169 * NO DOM
68170 * @param {?} node
68171 * @return {?}
68172 */
68173function getElement(node) {
68174 var /** @type {?} */ rootNodes = node.view.rootNodes;
68175 for (var /** @type {?} */ i = 0; i < rootNodes.length; i++) {
68176 if (rootNodes[i].nodeType === 1) {
68177 return rootNodes[i];
68178 }
68179 }
68180 return null;
68181}
68182var VirtualContext = (function () {
68183 /**
68184 * @param {?} $implicit
68185 * @param {?} index
68186 * @param {?} count
68187 */
68188 function VirtualContext($implicit, index, count) {
68189 this.$implicit = $implicit;
68190 this.index = index;
68191 this.count = count;
68192 this.bounds = {};
68193 }
68194 Object.defineProperty(VirtualContext.prototype, "first", {
68195 /**
68196 * @return {?}
68197 */
68198 get: function () { return this.index === 0; },
68199 enumerable: true,
68200 configurable: true
68201 });
68202 Object.defineProperty(VirtualContext.prototype, "last", {
68203 /**
68204 * @return {?}
68205 */
68206 get: function () { return this.index === this.count - 1; },
68207 enumerable: true,
68208 configurable: true
68209 });
68210 Object.defineProperty(VirtualContext.prototype, "even", {
68211 /**
68212 * @return {?}
68213 */
68214 get: function () { return this.index % 2 === 0; },
68215 enumerable: true,
68216 configurable: true
68217 });
68218 Object.defineProperty(VirtualContext.prototype, "odd", {
68219 /**
68220 * @return {?}
68221 */
68222 get: function () { return !this.even; },
68223 enumerable: true,
68224 configurable: true
68225 });
68226 return VirtualContext;
68227}());
68228var TEMPLATE_ITEM = 0;
68229var TEMPLATE_HEADER = 1;
68230var TEMPLATE_FOOTER = 2;
68231var VIEWABLE_RENDERED_PADDING = 3;
68232var REQUIRED_DOM_READS = 2;
68233
68234/**
68235 * \@name VirtualScroll
68236 * \@description
68237 * Virtual Scroll displays a virtual, "infinite" list. An array of records
68238 * is passed to the virtual scroll containing the data to create templates
68239 * for. The template created for each record, referred to as a cell, can
68240 * consist of items, headers, and footers.
68241 *
68242 * For performance reasons, not every record in the list is rendered at once;
68243 * instead a small subset of records (enough to fill the viewport) are rendered
68244 * and reused as the user scrolls.
68245 *
68246 * ### The Basics
68247 *
68248 * The array of records should be passed to the `virtualScroll` property.
68249 * The data given to the `virtualScroll` property must be an array. An item
68250 * template with the `*virtualItem` property is required in the `virtualScroll`.
68251 * The `virtualScroll` and `*virtualItem` properties can be added to any element.
68252 *
68253 * ```html
68254 * <ion-list [virtualScroll]="items">
68255 *
68256 * <ion-item *virtualItem="let item">
68257 * {% raw %}{{ item }}{% endraw %}
68258 * </ion-item>
68259 *
68260 * </ion-list>
68261 * ```
68262 *
68263 *
68264 * ### Section Headers and Footers
68265 *
68266 * Section headers and footers are optional. They can be dynamically created
68267 * from developer-defined functions. For example, a large list of contacts
68268 * usually has a divider for each letter in the alphabet. Developers provide
68269 * their own custom function to be called on each record. The logic in the
68270 * custom function should determine whether to create the section template
68271 * and what data to provide to the template. The custom function should
68272 * return `null` if a template shouldn't be created.
68273 *
68274 * ```html
68275 * <ion-list [virtualScroll]="items" [headerFn]="myHeaderFn">
68276 *
68277 * <ion-item-divider *virtualHeader="let header">
68278 * Header: {% raw %}{{ header }}{% endraw %}
68279 * </ion-item-divider>
68280 *
68281 * <ion-item *virtualItem="let item">
68282 * Item: {% raw %}{{ item }}{% endraw %}
68283 * </ion-item>
68284 *
68285 * </ion-list>
68286 * ```
68287 *
68288 * Below is an example of a custom function called on every record. It
68289 * gets passed the individual record, the record's index number,
68290 * and the entire array of records. In this example, after every 20
68291 * records a header will be inserted. So between the 19th and 20th records,
68292 * between the 39th and 40th, and so on, a `<ion-item-divider>` will
68293 * be created and the template's data will come from the function's
68294 * returned data.
68295 *
68296 * ```ts
68297 * myHeaderFn(record, recordIndex, records) {
68298 * if (recordIndex % 20 === 0) {
68299 * return 'Header ' + recordIndex;
68300 * }
68301 * return null;
68302 * }
68303 * ```
68304 *
68305 *
68306 * ### Approximate Widths and Heights
68307 *
68308 * If the height of items in the virtual scroll are not close to the
68309 * default size of 40px, it is extremely important to provide a value for
68310 * approxItemHeight height. An exact pixel-perfect size is not necessary,
68311 * but without an estimate the virtual scroll will not render correctly.
68312 *
68313 * The approximate width and height of each template is used to help
68314 * determine how many cells should be created, and to help calculate
68315 * the height of the scrollable area. Note that the actual rendered size
68316 * of each cell comes from the app's CSS, whereas this approximation
68317 * is only used to help calculate initial dimensions.
68318 *
68319 * It's also important to know that Ionic's default item sizes have
68320 * slightly different heights between platforms, which is perfectly fine.
68321 *
68322 *
68323 * ### Images Within Virtual Scroll
68324 *
68325 * HTTP requests, image decoding, and image rendering can cause jank while
68326 * scrolling. In order to better control images, Ionic provides `<ion-img>`
68327 * to manage HTTP requests and image rendering. While scrolling through items
68328 * quickly, `<ion-img>` knows when and when not to make requests, when and
68329 * when not to render images, and only loads the images that are viewable
68330 * after scrolling. [Read more about `ion-img`.](../../img/Img/)
68331 *
68332 * It's also important for app developers to ensure image sizes are locked in,
68333 * and after images have fully loaded they do not change size and affect any
68334 * other element sizes. Simply put, to ensure rendering bugs are not introduced,
68335 * it's vital that elements within a virtual item does not dynamically change.
68336 *
68337 * For virtual scrolling, the natural effects of the `<img>` are not desirable
68338 * features. We recommend using the `<ion-img>` component over the native
68339 * `<img>` element because when an `<img>` element is added to the DOM, it
68340 * immediately makes a HTTP request for the image file. Additionally, `<img>`
68341 * renders whenever it wants which could be while the user is scrolling. However,
68342 * `<ion-img>` is governed by the containing `ion-content` and does not render
68343 * images while scrolling quickly.
68344 *
68345 * ```html
68346 * <ion-list [virtualScroll]="items">
68347 *
68348 * <ion-item *virtualItem="let item">
68349 * <ion-avatar item-start>
68350 * <ion-img [src]="item.avatarUrl"></ion-img>
68351 * </ion-avatar>
68352 * {% raw %} {{ item.firstName }} {{ item.lastName }}{% endraw %}
68353 * </ion-item>
68354 *
68355 * </ion-list>
68356 * ```
68357 *
68358 *
68359 * ### Custom Components
68360 *
68361 * If a custom component is going to be used within Virtual Scroll, it's best
68362 * to wrap it with a good old `<div>` to ensure the component is rendered
68363 * correctly. Since each custom component's implementation and internals can be
68364 * quite different, wrapping within a `<div>` is a safe way to make sure
68365 * dimensions are measured correctly.
68366 *
68367 * ```html
68368 * <ion-list [virtualScroll]="items">
68369 *
68370 * <div *virtualItem="let item">
68371 * <my-custom-item [item]="item">
68372 * {% raw %} {{ item }}{% endraw %}
68373 * </my-custom-item>
68374 * </div>
68375 *
68376 * </ion-list>
68377 * ```
68378 *
68379 *
68380 * ## Virtual Scroll Performance Tips
68381 *
68382 * #### iOS Cordova WKWebView
68383 *
68384 * When deploying to iOS with Cordova, it's highly recommended to use the
68385 * [WKWebView plugin](http://blog.ionic.io/cordova-ios-performance-improvements-drop-in-speed-with-wkwebview/)
68386 * in order to take advantage of iOS's higher performimg webview. Additionally,
68387 * WKWebView is superior at scrolling efficiently in comparision to the older
68388 * UIWebView.
68389 *
68390 * #### Lock in element dimensions and locations
68391 *
68392 * In order for virtual scroll to efficiently size and locate every item, it's
68393 * very important every element within each virtual item does not dynamically
68394 * change its dimensions or location. The best way to ensure size and location
68395 * does not change, it's recommended each virtual item has locked in its size
68396 * via CSS.
68397 *
68398 * #### Use `ion-img` for images
68399 *
68400 * When including images within Virtual Scroll, be sure to use
68401 * [`ion-img`](../img/Img/) rather than the standard `<img>` HTML element.
68402 * With `ion-img`, images are lazy loaded so only the viewable ones are
68403 * rendered, and HTTP requests are efficiently controlled while scrolling.
68404 *
68405 * #### Set Approximate Widths and Heights
68406 *
68407 * As mentioned above, all elements should lock in their dimensions. However,
68408 * virtual scroll isn't aware of the dimensions until after they have been
68409 * rendered. For the initial render, virtual scroll still needs to set
68410 * how many items should be built. With "approx" property inputs, such as
68411 * `approxItemHeight`, we're able to give virtual scroll an approximate size,
68412 * therefore allowing virtual scroll to decide how many items should be
68413 * created.
68414 *
68415 * #### Changing dataset should use `virtualTrackBy`
68416 *
68417 * It is possible for the identities of elements in the iterator to change
68418 * while the data does not. This can happen, for example, if the iterator
68419 * produced from an RPC to the server, and that RPC is re-run. Even if the
68420 * "data" hasn't changed, the second response will produce objects with
68421 * different identities, and Ionic will tear down the entire DOM and rebuild
68422 * it. This is an expensive operation and should be avoided if possible.
68423 *
68424 * #### Efficient headers and footer functions
68425 *
68426 * Each virtual item must stay extremely efficient, but one way to really
68427 * kill its performance is to perform any DOM operations within section header
68428 * and footer functions. These functions are called for every record in the
68429 * dataset, so please make sure they're performant.
68430 *
68431 */
68432var VirtualScroll = (function () {
68433 /**
68434 * @param {?} _iterableDiffers
68435 * @param {?} _elementRef
68436 * @param {?} _renderer
68437 * @param {?} _zone
68438 * @param {?} _cd
68439 * @param {?} _content
68440 * @param {?} _plt
68441 * @param {?} _ctrl
68442 * @param {?} _config
68443 * @param {?} _dom
68444 */
68445 function VirtualScroll(_iterableDiffers, _elementRef, _renderer, _zone, _cd, _content, _plt, _ctrl, _config, _dom) {
68446 var _this = this;
68447 this._iterableDiffers = _iterableDiffers;
68448 this._elementRef = _elementRef;
68449 this._renderer = _renderer;
68450 this._zone = _zone;
68451 this._cd = _cd;
68452 this._content = _content;
68453 this._plt = _plt;
68454 this._ctrl = _ctrl;
68455 this._config = _config;
68456 this._dom = _dom;
68457 this._init = false;
68458 this._lastEle = false;
68459 this._records = [];
68460 this._cells = [];
68461 this._nodes = [];
68462 this._vHeight = 0;
68463 this._lastCheck = 0;
68464 this._recordSize = 0;
68465 this._data = {
68466 scrollTop: 0,
68467 };
68468 this._queue = SCROLL_QUEUE_NO_CHANGES;
68469 /**
68470 * \@input {number} The buffer ratio is used to decide how many cells
68471 * should get created when initially rendered. The number is a
68472 * multiplier against the viewable area's height. For example, if it
68473 * takes `20` cells to fill up the height of the viewable area, then
68474 * with a buffer ratio of `3` it will create `60` cells that are
68475 * available for reuse while scrolling. For better performance, it's
68476 * better to have more cells than what are required to fill the
68477 * viewable area. Default is `3`.
68478 */
68479 this.bufferRatio = 3;
68480 /**
68481 * \@input {string} The approximate width of each item template's cell.
68482 * This dimension is used to help determine how many cells should
68483 * be created when initialized, and to help calculate the height of
68484 * the scrollable area. This value can use either `px` or `%` units.
68485 * Note that the actual rendered size of each cell comes from the
68486 * app's CSS, whereas this approximation is used to help calculate
68487 * initial dimensions before the item has been rendered. Default is
68488 * `100%`.
68489 */
68490 this.approxItemWidth = '100%';
68491 /**
68492 * \@input {string} The approximate width of each header template's cell.
68493 * This dimension is used to help determine how many cells should
68494 * be created when initialized, and to help calculate the height of
68495 * the scrollable area. This value can use either `px` or `%` units.
68496 * Note that the actual rendered size of each cell comes from the
68497 * app's CSS, whereas this approximation is used to help calculate
68498 * initial dimensions. Default is `100%`.
68499 */
68500 this.approxHeaderWidth = '100%';
68501 /**
68502 * \@input {string} The approximate height of each header template's cell.
68503 * This dimension is used to help determine how many cells should
68504 * be created when initialized, and to help calculate the height of
68505 * the scrollable area. This height value can only use `px` units.
68506 * Note that the actual rendered size of each cell comes from the
68507 * app's CSS, whereas this approximation is used to help calculate
68508 * initial dimensions before the item has been rendered. Default is `40px`.
68509 */
68510 this.approxHeaderHeight = '40px';
68511 /**
68512 * \@input {string} The approximate width of each footer template's cell.
68513 * This dimension is used to help determine how many cells should
68514 * be created when initialized, and to help calculate the height of
68515 * the scrollable area. This value can use either `px` or `%` units.
68516 * Note that the actual rendered size of each cell comes from the
68517 * app's CSS, whereas this approximation is used to help calculate
68518 * initial dimensions before the item has been rendered. Default is `100%`.
68519 */
68520 this.approxFooterWidth = '100%';
68521 /**
68522 * \@input {string} The approximate height of each footer template's cell.
68523 * This dimension is used to help determine how many cells should
68524 * be created when initialized, and to help calculate the height of
68525 * the scrollable area. This height value can only use `px` units.
68526 * Note that the actual rendered size of each cell comes from the
68527 * app's CSS, whereas this approximation is used to help calculate
68528 * initial dimensions before the item has been rendered. Default is `40px`.
68529 */
68530 this.approxFooterHeight = '40px';
68531 // hide the virtual scroll element with opacity so we don't
68532 // see jank as it loads up, but we're still able to read
68533 // dimensions because it's still rendered and only opacity hidden
68534 this.setElementClass('virtual-loading', true);
68535 // wait for the content to be rendered and has readable dimensions
68536 var readSub = _ctrl.readReady.subscribe(function () {
68537 readSub.unsubscribe();
68538 _this.readUpdate(true);
68539 });
68540 // wait for the content to be writable
68541 var writeSub = _ctrl.writeReady.subscribe(function () {
68542 writeSub.unsubscribe();
68543 _this._init = true;
68544 _this.writeUpdate(true);
68545 _this._listeners();
68546 });
68547 }
68548 Object.defineProperty(VirtualScroll.prototype, "virtualScroll", {
68549 /**
68550 * \@input {array} The data that builds the templates within the virtual scroll.
68551 * This is the same data that you'd pass to `*ngFor`. It's important to note
68552 * that when this data has changed, then the entire virtual scroll is reset,
68553 * which is an expensive operation and should be avoided if possible.
68554 * @param {?} val
68555 * @return {?}
68556 */
68557 set: function (val) {
68558 this._records = val;
68559 this._updateDiffer();
68560 },
68561 enumerable: true,
68562 configurable: true
68563 });
68564 Object.defineProperty(VirtualScroll.prototype, "headerFn", {
68565 /**
68566 * \@input {function} Section headers and the data used within its given
68567 * template can be dynamically created by passing a function to `headerFn`.
68568 * For example, a large list of contacts usually has dividers between each
68569 * letter in the alphabet. App's can provide their own custom `headerFn`
68570 * which is called with each record within the dataset. The logic within
68571 * the header function can decide if the header template should be used,
68572 * and what data to give to the header template. The function must return
68573 * `null` if a header cell shouldn't be created.
68574 * @param {?} val
68575 * @return {?}
68576 */
68577 set: function (val) {
68578 if (isFunction$1(val)) {
68579 this._hdrFn = val.bind((this._ctrl._cmp) || this);
68580 }
68581 },
68582 enumerable: true,
68583 configurable: true
68584 });
68585 Object.defineProperty(VirtualScroll.prototype, "footerFn", {
68586 /**
68587 * \@input {function} Section footers and the data used within its given
68588 * template can be dynamically created by passing a function to `footerFn`.
68589 * The logic within the footer function can decide if the footer template
68590 * should be used, and what data to give to the footer template. The function
68591 * must return `null` if a footer cell shouldn't be created.
68592 * @param {?} val
68593 * @return {?}
68594 */
68595 set: function (val) {
68596 if (isFunction$1(val)) {
68597 this._ftrFn = val.bind((this._ctrl._cmp) || this);
68598 }
68599 },
68600 enumerable: true,
68601 configurable: true
68602 });
68603 Object.defineProperty(VirtualScroll.prototype, "virtualTrackBy", {
68604 /**
68605 * @return {?}
68606 */
68607 get: function () {
68608 return this._virtualTrackBy;
68609 },
68610 /**
68611 * \@input {function} Same as `ngForTrackBy` which can be used on `ngFor`.
68612 * @param {?} val
68613 * @return {?}
68614 */
68615 set: function (val) {
68616 if (isPresent(val)) {
68617 this._virtualTrackBy = val;
68618 this._updateDiffer();
68619 }
68620 },
68621 enumerable: true,
68622 configurable: true
68623 });
68624 /**
68625 * @hidden
68626 * @return {?}
68627 */
68628 VirtualScroll.prototype.firstRecord = function () {
68629 var /** @type {?} */ cells = this._cells;
68630 return (cells.length > 0) ? cells[0].record : 0;
68631 };
68632 /**
68633 * @hidden
68634 * @return {?}
68635 */
68636 VirtualScroll.prototype.lastRecord = function () {
68637 var /** @type {?} */ cells = this._cells;
68638 return (cells.length > 0) ? cells[cells.length - 1].record : 0;
68639 };
68640 /**
68641 * @hidden
68642 * @return {?}
68643 */
68644 VirtualScroll.prototype.ngDoCheck = function () {
68645 // only continue if we've already initialized
68646 if (!this._init) {
68647 return;
68648 }
68649 // and if there actually are changes
68650 var /** @type {?} */ changes = this._changes();
68651 if (!isPresent(changes)) {
68652 return;
68653 }
68654 var /** @type {?} */ needClean = false;
68655 if (changes) {
68656 var /** @type {?} */ lastRecord = this._recordSize;
68657 changes.forEachOperation(function (_, pindex, cindex) {
68658 // add new record after current position
68659 if (pindex === null && (cindex < lastRecord)) {
68660 (void 0) /* console.debug */;
68661 needClean = true;
68662 return;
68663 }
68664 // remove record after current position
68665 if (pindex < lastRecord && cindex === null) {
68666 (void 0) /* console.debug */;
68667 needClean = true;
68668 return;
68669 }
68670 });
68671 }
68672 else {
68673 needClean = true;
68674 }
68675 this._recordSize = this._records.length;
68676 this.readUpdate(needClean);
68677 this.writeUpdate(needClean);
68678 };
68679 /**
68680 * @hidden
68681 * @param {?} needClean
68682 * @return {?}
68683 */
68684 VirtualScroll.prototype.readUpdate = function (needClean) {
68685 if (needClean) {
68686 // reset everything
68687 (void 0) /* console.debug */;
68688 this._cells.length = 0;
68689 this._nodes.length = 0;
68690 this._itmTmp.viewContainer.clear();
68691 // ******** DOM READ ****************
68692 this.calcDimensions();
68693 }
68694 else {
68695 (void 0) /* console.debug */;
68696 }
68697 };
68698 /**
68699 * @hidden
68700 * @param {?} needClean
68701 * @return {?}
68702 */
68703 VirtualScroll.prototype.writeUpdate = function (needClean) {
68704 (void 0) /* console.debug */;
68705 var /** @type {?} */ data = this._data;
68706 var /** @type {?} */ stopAtHeight = (data.scrollTop + data.renderHeight);
68707 data.scrollDiff = SCROLL_DIFFERENCE_MINIMUM + 1;
68708 processRecords(stopAtHeight, this._records, this._cells, this._hdrFn, this._ftrFn, this._data);
68709 // ******** DOM WRITE ****************
68710 this.renderVirtual(needClean);
68711 };
68712 /**
68713 * @hidden
68714 * @return {?}
68715 */
68716 VirtualScroll.prototype.calcDimensions = function () {
68717 calcDimensions(this._data, this._elementRef.nativeElement, this.approxItemWidth, this.approxItemHeight, this.approxHeaderWidth, this.approxHeaderHeight, this.approxFooterWidth, this.approxFooterHeight, this.bufferRatio);
68718 };
68719 /**
68720 * @return {?}
68721 */
68722 VirtualScroll.prototype._changes = function () {
68723 if (isPresent(this._records) && isPresent(this._differ)) {
68724 return this._differ.diff(this._records);
68725 }
68726 return null;
68727 };
68728 /**
68729 * @return {?}
68730 */
68731 VirtualScroll.prototype._updateDiffer = function () {
68732 if (isPresent(this._records)) {
68733 this._differ = this._iterableDiffers.find(this._records).create(this._virtualTrackBy);
68734 }
68735 };
68736 /**
68737 * @hidden
68738 * DOM WRITE
68739 * @param {?} needClean
68740 * @return {?}
68741 */
68742 VirtualScroll.prototype.renderVirtual = function (needClean) {
68743 var _this = this;
68744 this._plt.raf(function () {
68745 var /** @type {?} */ nodes = _this._nodes;
68746 var /** @type {?} */ cells = _this._cells;
68747 var /** @type {?} */ data = _this._data;
68748 var /** @type {?} */ records = _this._records;
68749 if (needClean) {
68750 // ******** DOM WRITE ****************
68751 updateDimensions(_this._plt, nodes, cells, data, true);
68752 data.topCell = 0;
68753 data.bottomCell = (cells.length - 1);
68754 }
68755 adjustRendered(cells, data);
68756 _this._zone.run(function () {
68757 populateNodeData(data.topCell, data.bottomCell, true, cells, records, nodes, _this._itmTmp.viewContainer, _this._itmTmp.templateRef, _this._hdrTmp && _this._hdrTmp.templateRef, _this._ftrTmp && _this._ftrTmp.templateRef, needClean);
68758 });
68759 if (needClean) {
68760 _this._cd.detectChanges();
68761 }
68762 // at this point, this fn was called from within another
68763 // requestAnimationFrame, so the next dom reads/writes within the next frame
68764 // wait a frame before trying to read and calculate the dimensions
68765 // ******** DOM READ ****************
68766 _this._dom.read(function () { return initReadNodes(_this._plt, nodes, cells, data); });
68767 _this._dom.write(function () {
68768 // update the bound context for each node
68769 updateNodeContext(nodes, cells, data);
68770 // ******** DOM WRITE ****************
68771 _this._stepChangeDetection();
68772 // ******** DOM WRITE ****************
68773 _this._stepDOMWrite();
68774 // ******** DOM WRITE ****************
68775 _this._content.imgsUpdate();
68776 // First time load
68777 if (!_this._lastEle) {
68778 // add an element at the end so :last-child css doesn't get messed up
68779 // ******** DOM WRITE ****************
68780 var /** @type {?} */ ele = _this._elementRef.nativeElement;
68781 var /** @type {?} */ lastEle = _this._renderer.createElement(ele, 'div');
68782 lastEle.className = 'virtual-last';
68783 _this._lastEle = true;
68784 // ******** DOM WRITE ****************
68785 _this.setElementClass('virtual-scroll', true);
68786 // ******** DOM WRITE ****************
68787 _this.setElementClass('virtual-loading', false);
68788 }
68789 (void 0) /* assert */;
68790 });
68791 });
68792 };
68793 /**
68794 * @hidden
68795 * @return {?}
68796 */
68797 VirtualScroll.prototype.resize = function () {
68798 // only continue if we've already initialized
68799 if (!this._init) {
68800 return;
68801 }
68802 (void 0) /* console.debug */;
68803 this.calcDimensions();
68804 this.writeUpdate(false);
68805 };
68806 /**
68807 * @hidden
68808 * @return {?}
68809 */
68810 VirtualScroll.prototype._stepDOMWrite = function () {
68811 var /** @type {?} */ cells = this._cells;
68812 var /** @type {?} */ nodes = this._nodes;
68813 var /** @type {?} */ recordsLength = this._records.length;
68814 // ******** DOM WRITE ****************
68815 writeToNodes(this._plt, nodes, cells, recordsLength);
68816 // ******** DOM WRITE ****************
68817 this._setHeight(estimateHeight(recordsLength, cells[cells.length - 1], this._vHeight, 0.25));
68818 // we're done here, good work
68819 this._queue = SCROLL_QUEUE_NO_CHANGES;
68820 };
68821 /**
68822 * @hidden
68823 * @return {?}
68824 */
68825 VirtualScroll.prototype._stepChangeDetection = function () {
68826 // we need to do some change detection in this frame
68827 // we've got work painting do, let's throw it in the
68828 // domWrite callback so everyone plays nice
68829 // ******** DOM WRITE ****************
68830 var /** @type {?} */ nodes = this._nodes;
68831 for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
68832 if (nodes[i].hasChanges) {
68833 ((nodes[i].view)).detectChanges();
68834 }
68835 }
68836 // on the next frame we need write to the dom nodes manually
68837 this._queue = SCROLL_QUEUE_DOM_WRITE;
68838 };
68839 /**
68840 * @hidden
68841 * @return {?}
68842 */
68843 VirtualScroll.prototype._stepNoChanges = function () {
68844 var /** @type {?} */ data = this._data;
68845 // let's see if we've scroll far enough to require another check
68846 var /** @type {?} */ diff = data.scrollDiff = (data.scrollTop - this._lastCheck);
68847 if (Math.abs(diff) < SCROLL_DIFFERENCE_MINIMUM) {
68848 return;
68849 }
68850 var /** @type {?} */ cells = this._cells;
68851 var /** @type {?} */ nodes = this._nodes;
68852 var /** @type {?} */ records = this._records;
68853 // don't bother updating if the scrollTop hasn't changed much
68854 this._lastCheck = data.scrollTop;
68855 if (diff > 0) {
68856 // load data we may not have processed yet
68857 var /** @type {?} */ stopAtHeight = (data.scrollTop + data.renderHeight);
68858 processRecords(stopAtHeight, records, cells, this._hdrFn, this._ftrFn, data);
68859 }
68860 // ******** DOM READ ****************
68861 updateDimensions(this._plt, nodes, cells, data, false);
68862 adjustRendered(cells, data);
68863 var /** @type {?} */ hasChanges = populateNodeData(data.topCell, data.bottomCell, diff > 0, cells, records, nodes, this._itmTmp.viewContainer, this._itmTmp.templateRef, this._hdrTmp && this._hdrTmp.templateRef, this._ftrTmp && this._ftrTmp.templateRef, false);
68864 if (hasChanges) {
68865 // queue making updates in the next frame
68866 this._queue = SCROLL_QUEUE_CHANGE_DETECTION;
68867 // update the bound context for each node
68868 updateNodeContext(nodes, cells, data);
68869 }
68870 };
68871 /**
68872 * @hidden
68873 * @param {?} ev
68874 * @return {?}
68875 */
68876 VirtualScroll.prototype.scrollUpdate = function (ev) {
68877 var _this = this;
68878 // set the scroll top from the scroll event
68879 this._data.scrollTop = ev.scrollTop;
68880 // there is a queue system so that we can
68881 // spread out the work over multiple frames
68882 var /** @type {?} */ queue = this._queue;
68883 if (queue === SCROLL_QUEUE_NO_CHANGES) {
68884 // no dom writes or change detection to take care of
68885 this._stepNoChanges();
68886 }
68887 else if (queue === SCROLL_QUEUE_CHANGE_DETECTION) {
68888 this._dom.write(function () { return _this._stepChangeDetection(); });
68889 }
68890 else {
68891 (void 0) /* assert */;
68892 // there are DOM writes we need to take care of in this frame
68893 this._dom.write(function () { return _this._stepDOMWrite(); });
68894 }
68895 };
68896 /**
68897 * @hidden
68898 * DOM WRITE
68899 * @return {?}
68900 */
68901 VirtualScroll.prototype.scrollEnd = function () {
68902 var _this = this;
68903 // ******** DOM READ ****************
68904 updateDimensions(this._plt, this._nodes, this._cells, this._data, false);
68905 adjustRendered(this._cells, this._data);
68906 // ******** DOM WRITE ***************
68907 this._dom.write(function () {
68908 // update the bound context for each node
68909 updateNodeContext(_this._nodes, _this._cells, _this._data);
68910 // ******** DOM WRITE ***************
68911 _this._stepChangeDetection();
68912 // ******** DOM WRITE ****************
68913 _this._stepDOMWrite();
68914 });
68915 };
68916 /**
68917 * @hidden
68918 * NO DOM
68919 * @return {?}
68920 */
68921 VirtualScroll.prototype._listeners = function () {
68922 (void 0) /* assert */;
68923 if (!this._scrollSub) {
68924 if (this._config.getBoolean('virtualScrollEventAssist')) {
68925 // use JS scrolling for iOS UIWebView
68926 // goal is to completely remove this when iOS
68927 // fully supports scroll events
68928 // listen to JS scroll events
68929 this._content.enableJsScroll();
68930 }
68931 this._resizeSub = this._plt.resize.subscribe(this.resize.bind(this));
68932 this._scrollSub = this._content.ionScroll.subscribe(this.scrollUpdate.bind(this));
68933 this._scrollEndSub = this._content.ionScrollEnd.subscribe(this.scrollEnd.bind(this));
68934 }
68935 };
68936 /**
68937 * @hidden
68938 * DOM WRITE
68939 * @param {?} newVirtualHeight
68940 * @return {?}
68941 */
68942 VirtualScroll.prototype._setHeight = function (newVirtualHeight) {
68943 if (newVirtualHeight !== this._vHeight) {
68944 // ******** DOM WRITE ****************
68945 this._renderer.setElementStyle(this._elementRef.nativeElement, 'height', newVirtualHeight > 0 ? newVirtualHeight + 'px' : '');
68946 this._vHeight = newVirtualHeight;
68947 (void 0) /* console.debug */;
68948 }
68949 };
68950 /**
68951 * @hidden
68952 * @return {?}
68953 */
68954 VirtualScroll.prototype.ngAfterContentInit = function () {
68955 (void 0) /* assert */;
68956 if (!this.approxItemHeight) {
68957 this.approxItemHeight = '40px';
68958 console.warn('Virtual Scroll: Please provide an "approxItemHeight" input to ensure proper virtual scroll rendering');
68959 }
68960 };
68961 /**
68962 * @hidden
68963 * @param {?} className
68964 * @param {?} add
68965 * @return {?}
68966 */
68967 VirtualScroll.prototype.setElementClass = function (className, add) {
68968 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
68969 };
68970 /**
68971 * @hidden
68972 * @return {?}
68973 */
68974 VirtualScroll.prototype.ngOnDestroy = function () {
68975 this._resizeSub && this._resizeSub.unsubscribe();
68976 this._scrollSub && this._scrollSub.unsubscribe();
68977 this._scrollEndSub && this._scrollEndSub.unsubscribe();
68978 this._resizeSub = this._scrollEndSub = this._scrollSub = null;
68979 this._hdrFn = this._ftrFn = this._records = this._cells = this._nodes = this._data = null;
68980 };
68981 return VirtualScroll;
68982}());
68983VirtualScroll.decorators = [
68984 { type: Directive, args: [{
68985 selector: '[virtualScroll]'
68986 },] },
68987];
68988/**
68989 * @nocollapse
68990 */
68991VirtualScroll.ctorParameters = function () { return [
68992 { type: IterableDiffers, },
68993 { type: ElementRef, },
68994 { type: Renderer, },
68995 { type: NgZone, },
68996 { type: ChangeDetectorRef, },
68997 { type: Content, },
68998 { type: Platform, },
68999 { type: ViewController, },
69000 { type: Config, },
69001 { type: DomController, },
69002]; };
69003VirtualScroll.propDecorators = {
69004 '_itmTmp': [{ type: ContentChild, args: [VirtualItem,] },],
69005 '_hdrTmp': [{ type: ContentChild, args: [VirtualHeader,] },],
69006 '_ftrTmp': [{ type: ContentChild, args: [VirtualFooter,] },],
69007 'virtualScroll': [{ type: Input },],
69008 'bufferRatio': [{ type: Input },],
69009 'approxItemWidth': [{ type: Input },],
69010 'approxItemHeight': [{ type: Input },],
69011 'approxHeaderWidth': [{ type: Input },],
69012 'approxHeaderHeight': [{ type: Input },],
69013 'approxFooterWidth': [{ type: Input },],
69014 'approxFooterHeight': [{ type: Input },],
69015 'headerFn': [{ type: Input },],
69016 'footerFn': [{ type: Input },],
69017 'virtualTrackBy': [{ type: Input },],
69018};
69019var SCROLL_DIFFERENCE_MINIMUM = 40;
69020var SCROLL_QUEUE_NO_CHANGES = 1;
69021var SCROLL_QUEUE_CHANGE_DETECTION = 2;
69022var SCROLL_QUEUE_DOM_WRITE = 3;
69023
69024/**
69025 * \@name IonicPage
69026 * \@description
69027 * The Ionic Page handles registering and displaying specific pages based on URLs. It's used
69028 * underneath `NavController` so it will never have to be interacted with directly. When a new
69029 * page is pushed with `NavController`, the URL is updated to match the path to this page.
69030 *
69031 * Unlike traditional web apps, URLs don't dictate navigation in Ionic apps.
69032 * Instead, URLs help us link to specific pieces of content as a breadcrumb.
69033 * The current URL gets updated as we navigate, but we use the `NavController`
69034 * push and pop, or `NavPush` and `NavPop` to move around. This makes it much easier
69035 * to handle complicated nested navigation.
69036 *
69037 * We refer to our URL system as a deep link system instead of a router to encourage
69038 * Ionic developers to think of URLs as a breadcrumb rather than as the source of
69039 * truth in navigation. This encourages flexible navigation design and happy apps all
69040 * over the world.
69041 *
69042 *
69043 * \@usage
69044 *
69045 * The first step to setting up deep links is to add the page that should be
69046 * a deep link in the `IonicPageModule.forChild` import of the page's module.
69047 * For our examples, this will be `MyPage`:
69048 *
69049 * ```ts
69050 * \@NgModule({
69051 * declarations: [
69052 * MyPage
69053 * ],
69054 * imports: [
69055 * IonicPageModule.forChild(MyPage)
69056 * ],
69057 * entryComponents: [
69058 * MyPage
69059 * ]
69060 * })
69061 * export class MyPageModule {}
69062 * ```
69063 *
69064 * Then, add the `\@IonicPage` decorator to the component. The most simple usage is adding an
69065 * empty decorator:
69066 *
69067 * ```ts
69068 * \@IonicPage()
69069 * \@Component({
69070 * templateUrl: 'main.html'
69071 * })
69072 * export class MyPage {}
69073 * ```
69074 *
69075 * This will automatically create a link to the `MyPage` component using the same name as the class,
69076 * `name`: `'MyPage'`. The page can now be navigated to by using this name. For example:
69077 *
69078 * ```ts
69079 * \@Component({
69080 * templateUrl: 'another-page.html'
69081 * })
69082 * export class AnotherPage {
69083 * constructor(public navCtrl: NavController) {}
69084 *
69085 * goToMyPage() {
69086 * // go to the MyPage component
69087 * this.navCtrl.push('MyPage');
69088 * }
69089 * }
69090 * ```
69091 *
69092 * The `\@IonicPage` decorator accepts a `DeepLinkMetadataType` object. This object accepts
69093 * the following properties: `name`, `segment`, `defaultHistory`, and `priority`. All of them
69094 * are optional but can be used to create complex navigation links.
69095 *
69096 *
69097 * ### Changing Name
69098 *
69099 * As mentioned previously, the `name` property will be set to the class name if it isn't provided.
69100 * Changing the name of the link is extremely simple. To change the name used to link to the
69101 * component, simply pass it in the decorator like so:
69102 *
69103 * ```ts
69104 * \@IonicPage({
69105 * name: 'my-page'
69106 * })
69107 * ```
69108 *
69109 * This will create a link to the `MyPage` component using the name `'my-page'`. Similar to the previous
69110 * example, the page can be navigated to by using the name:
69111 *
69112 * ```ts
69113 * goToMyPage() {
69114 * // go to the MyPage component
69115 * this.navCtrl.push('my-page');
69116 * }
69117 * ```
69118 *
69119 *
69120 * ### Setting URL Path
69121 *
69122 * The `segment` property is used to set the URL to the page. If this property isn't provided, the
69123 * `segment` will use the value of `name`. Since components can be loaded anywhere in the app, the
69124 * `segment` doesn't require a full URL path. When a page becomes the active page, the `segment` is
69125 * appended to the URL.
69126 *
69127 * The `segment` can be changed to anything and doesn't have to match the `name`. For example, passing
69128 * a value for `name` and `segment`:
69129 *
69130 * ```ts
69131 * \@IonicPage({
69132 * name: 'my-page',
69133 * segment: 'some-path'
69134 * })
69135 * ```
69136 *
69137 * When navigating to this page as the first page in the app, the URL will look something like:
69138 *
69139 * ```
69140 * http://localhost:8101/#/some-path
69141 * ```
69142 *
69143 * However, navigating to the page will still use the `name` like the previous examples do.
69144 *
69145 *
69146 * ### Dynamic Links
69147 *
69148 * The `segment` property is useful for creating dynamic links. Sometimes the URL isn't known ahead
69149 * of time, so it can be passed as a variable.
69150 *
69151 * Since passing data around is common practice in an app, it can be reflected in the app's URL by
69152 * using the `:param` syntax. For example, set the `segment` in the `\@IonicPage` decorator:
69153 *
69154 * ```ts
69155 * \@IonicPage({
69156 * name: 'detail-page',
69157 * segment: 'detail/:id'
69158 * })
69159 * ```
69160 *
69161 * In this case, when we `push` to a new instance of `'detail-page'`, the value of `id` will
69162 * in the `detailInfo` data being passed to `push` will replace `:id` in the URL.
69163 *
69164 * Important: The property needs to be something that can be converted into a string, objects
69165 * are not supported.
69166 *
69167 * For example, to push the `'detail-page'` in the `ListPage` component, the following code could
69168 * be used:
69169 *
69170 * ```ts
69171 * \@IonicPage({
69172 * name: 'list'
69173 * })
69174 * export class ListPage {
69175 * constructor(public navCtrl: NavController) {}
69176 *
69177 * pushPage(detailInfo) {
69178 * // Push an `id` to the `'detail-page'`
69179 * this.navCtrl.push('detail-page', {
69180 * 'id': detailInfo.id
69181 * })
69182 * }
69183 * }
69184 * ```
69185 *
69186 * If the value of `detailInfo.id` is `12`, for example, the URL would end up looking like this:
69187 *
69188 * ```
69189 * http://localhost:8101/#/list/detail/12
69190 * ```
69191 *
69192 * Since this `id` will be used to pull in the data of the specific detail page, it's Important
69193 * that the `id` is unique.
69194 *
69195 * Note: Even though the `name` is `detail-page`, the `segment` uses `detail/:id`, and the URL
69196 * will use the `segment`.
69197 *
69198 *
69199 * ### Default History
69200 *
69201 * Pages can be navigated to using deep links from anywhere in the app, but sometimes the app is
69202 * launched from a URL and the page needs to have the same history as if it were navigated to from
69203 * inside of the app.
69204 *
69205 * By default, the page would be navigated to as the first page in the stack with no prior history.
69206 * A good example is the App Store on iOS. Clicking on a URL to an application in the App Store will
69207 * load the details of the application with no back button, as if it were the first page ever viewed.
69208 *
69209 * The default history of any page can be set in the `defaultHistory` property. This history will only
69210 * be used if the history doesn't already exist, meaning if you navigate to the page the history will
69211 * be the pages that were navigated from.
69212 *
69213 * The `defaultHistory` property takes an array of strings. For example, setting the history of the
69214 * detail page to the list page where the `name` is `list`:
69215 *
69216 * ```ts
69217 * \@IonicPage({
69218 * name: 'detail-page',
69219 * segment: 'detail/:id',
69220 * defaultHistory: ['list']
69221 * })
69222 * ```
69223 *
69224 * In this example, if the app is launched at `http://localhost:8101/#/detail/my-detail` the displayed page
69225 * will be the `'detail-page'` with an id of `my-detail` and it will show a back button that goes back to
69226 * the `'list'` page.
69227 *
69228 * An example of an application with a set history stack is the Instagram application. Opening a link
69229 * to an image on Instagram will show the details for that image with a back button to the user's profile
69230 * page. There is no "right" way of setting the history for a page, it is up to the application.
69231 *
69232 * ### Priority
69233 *
69234 * The `priority` property is only used during preloading. By default, preloading is turned off so setting
69235 * this property would do nothing. Preloading eagerly loads all deep links after the application boots
69236 * instead of on demand as needed. To enable preloading, set `preloadModules` in the main application module
69237 * config to `true`:
69238 *
69239 * ```ts
69240 * \@NgModule({
69241 * declarations: [
69242 * MyApp
69243 * ],
69244 * imports: [
69245 * BrowserModule,
69246 * IonicModule.forRoot(MyApp, {
69247 * preloadModules: true
69248 * })
69249 * ],
69250 * bootstrap: [IonicApp],
69251 * entryComponents: [
69252 * MyApp
69253 * ]
69254 * })
69255 * export class AppModule { }
69256 * ```
69257 *
69258 * If preloading is turned on, it will load the modules based on the value of `priority`. The following
69259 * values are possible for `priority`: `"high"`, `"low"`, and `"off"`. When there is no `priority`, it
69260 * will be set to `"low"`.
69261 *
69262 * All deep links with their priority set to `"high"` will be loaded first. Upon completion of loading the
69263 * `"high"` priority modules, all deep links with a priority of `"low"` (or no priority) will be loaded. If
69264 * the priority is set to `"off"` the link will not be preloaded. Setting the `priority` is as simple as
69265 * passing it to the `\@IonicPage` decorator:
69266 *
69267 * ```ts
69268 * \@IonicPage({
69269 * name: 'my-page',
69270 * priority: 'high'
69271 * })
69272 * ```
69273 *
69274 * We recommend setting the `priority` to `"high"` on the pages that will be viewed first when launching
69275 * the application.
69276 *
69277 * @param {?=} _config
69278 * @return {?}
69279 */
69280function IonicPage(_config) {
69281 return function (clazz) {
69282 return clazz;
69283 };
69284}
69285
69286/**
69287 * @abstract
69288 */
69289/**
69290 * @param {?} ev
69291 * @param {?} activatableEle
69292 * @return {?}
69293 */
69294function isActivatedDisabled(ev, activatableEle) {
69295 if (!activatableEle || !activatableEle.parentNode) {
69296 return true;
69297 }
69298 if (!ev) {
69299 return false;
69300 }
69301 if (ev.defaultPrevented) {
69302 return true;
69303 }
69304 var /** @type {?} */ targetEle = ev.target;
69305 for (var /** @type {?} */ i = 0; i < 4; i++) {
69306 if (!targetEle) {
69307 break;
69308 }
69309 if (targetEle.hasAttribute('disable-activated')) {
69310 return true;
69311 }
69312 targetEle = targetEle.parentElement;
69313 }
69314 return false;
69315}
69316
69317var Activator = (function () {
69318 /**
69319 * @param {?} app
69320 * @param {?} config
69321 * @param {?} dom
69322 */
69323 function Activator(app, config, dom) {
69324 this.app = app;
69325 this.dom = dom;
69326 this._queue = [];
69327 this._active = [];
69328 this.activatedDelay = ADD_ACTIVATED_DEFERS;
69329 this.clearDelay = CLEAR_STATE_DEFERS;
69330 this._css = config.get('activatedClass', 'activated');
69331 }
69332 /**
69333 * @param {?} ev
69334 * @param {?} activatableEle
69335 * @param {?} _startCoord
69336 * @return {?}
69337 */
69338 Activator.prototype.clickAction = function (ev, activatableEle, _startCoord) {
69339 if (isActivatedDisabled(ev, activatableEle)) {
69340 return;
69341 }
69342 // a click happened, so immediately deactive all activated elements
69343 this._scheduleClear();
69344 this._queue.length = 0;
69345 for (var /** @type {?} */ i = 0; i < this._active.length; i++) {
69346 this._active[i].classList.remove(this._css);
69347 }
69348 this._active.length = 0;
69349 // then immediately activate this element
69350 if (activatableEle && activatableEle.parentNode) {
69351 this._active.push(activatableEle);
69352 activatableEle.classList.add(this._css);
69353 }
69354 };
69355 /**
69356 * @param {?} ev
69357 * @param {?} activatableEle
69358 * @param {?} _startCoord
69359 * @return {?}
69360 */
69361 Activator.prototype.downAction = function (ev, activatableEle, _startCoord) {
69362 var _this = this;
69363 // the user just pressed down
69364 if (isActivatedDisabled(ev, activatableEle)) {
69365 return;
69366 }
69367 this.unscheduleClear();
69368 this.deactivate(true);
69369 // queue to have this element activated
69370 this._queue.push(activatableEle);
69371 this._activeDefer = this.dom.write(function () {
69372 _this._activeDefer = null;
69373 var /** @type {?} */ activatableEle;
69374 for (var /** @type {?} */ i = 0; i < _this._queue.length; i++) {
69375 activatableEle = _this._queue[i];
69376 _this._active.push(activatableEle);
69377 activatableEle.classList.add(_this._css);
69378 }
69379 _this._queue.length = 0;
69380 }, this.activatedDelay);
69381 };
69382 /**
69383 * @param {?} _ev
69384 * @param {?} _activatableEle
69385 * @param {?} _startCoord
69386 * @return {?}
69387 */
69388 Activator.prototype.upAction = function (_ev, _activatableEle, _startCoord) {
69389 this._scheduleClear();
69390 };
69391 /**
69392 * @return {?}
69393 */
69394 Activator.prototype._scheduleClear = function () {
69395 var _this = this;
69396 if (this._clearDefer) {
69397 return;
69398 }
69399 this._clearDefer = this.dom.write(function () {
69400 _this.clearState(true);
69401 _this._clearDefer = null;
69402 }, this.clearDelay);
69403 };
69404 /**
69405 * @return {?}
69406 */
69407 Activator.prototype.unscheduleClear = function () {
69408 if (this._clearDefer) {
69409 this._clearDefer();
69410 this._clearDefer = null;
69411 }
69412 };
69413 /**
69414 * @param {?} animated
69415 * @return {?}
69416 */
69417 Activator.prototype.clearState = function (animated) {
69418 var _this = this;
69419 if (!this.app.isEnabled()) {
69420 // the app is actively disabled, so don't bother deactivating anything.
69421 // this makes it easier on the GPU so it doesn't have to redraw any
69422 // buttons during a transition. This will retry in XX milliseconds.
69423 this.dom.write(function () {
69424 _this.clearState(animated);
69425 }, 600);
69426 }
69427 else {
69428 // not actively transitioning, good to deactivate any elements
69429 this.deactivate(animated);
69430 }
69431 };
69432 /**
69433 * @param {?} animated
69434 * @return {?}
69435 */
69436 Activator.prototype.deactivate = function (animated) {
69437 this._clearDeferred();
69438 this._queue.length = 0;
69439 var /** @type {?} */ ele;
69440 for (var /** @type {?} */ i = 0; i < this._active.length; i++) {
69441 ele = this._active[i];
69442 ((ele.style))[this.dom.plt.Css.transition] = animated ? '' : 'none';
69443 ele.classList.remove(this._css);
69444 }
69445 this._active.length = 0;
69446 };
69447 /**
69448 * @return {?}
69449 */
69450 Activator.prototype._clearDeferred = function () {
69451 // Clear any active deferral
69452 if (this._activeDefer) {
69453 this._activeDefer();
69454 this._activeDefer = null;
69455 }
69456 };
69457 return Activator;
69458}());
69459var ADD_ACTIVATED_DEFERS = 80;
69460var CLEAR_STATE_DEFERS = 80;
69461
69462/**
69463 * @hidden
69464 */
69465var RippleActivator = (function () {
69466 /**
69467 * @param {?} app
69468 * @param {?} config
69469 * @param {?} dom
69470 */
69471 function RippleActivator(app, config, dom) {
69472 this.dom = dom;
69473 this.highlight = new Activator(app, config, dom);
69474 }
69475 /**
69476 * @param {?} ev
69477 * @param {?} activatableEle
69478 * @param {?} startCoord
69479 * @return {?}
69480 */
69481 RippleActivator.prototype.clickAction = function (ev, activatableEle, startCoord) {
69482 // Highlight
69483 this.highlight && this.highlight.clickAction(ev, activatableEle, startCoord);
69484 // Ripple
69485 this._clickAction(ev, activatableEle, startCoord);
69486 };
69487 /**
69488 * @param {?} ev
69489 * @param {?} activatableEle
69490 * @param {?} startCoord
69491 * @return {?}
69492 */
69493 RippleActivator.prototype.downAction = function (ev, activatableEle, startCoord) {
69494 // Highlight
69495 this.highlight && this.highlight.downAction(ev, activatableEle, startCoord);
69496 // Ripple
69497 this._downAction(ev, activatableEle, startCoord);
69498 };
69499 /**
69500 * @param {?} ev
69501 * @param {?} activatableEle
69502 * @param {?} startCoord
69503 * @return {?}
69504 */
69505 RippleActivator.prototype.upAction = function (ev, activatableEle, startCoord) {
69506 // Highlight
69507 this.highlight && this.highlight.upAction(ev, activatableEle, startCoord);
69508 // Ripple
69509 this._upAction(ev, activatableEle, startCoord);
69510 };
69511 /**
69512 * @param {?} animated
69513 * @return {?}
69514 */
69515 RippleActivator.prototype.clearState = function (animated) {
69516 // Highlight
69517 this.highlight && this.highlight.clearState(animated);
69518 };
69519 /**
69520 * @param {?} ev
69521 * @param {?} activatableEle
69522 * @param {?} _startCoord
69523 * @return {?}
69524 */
69525 RippleActivator.prototype._downAction = function (ev, activatableEle, _startCoord) {
69526 if (isActivatedDisabled(ev, activatableEle)) {
69527 return;
69528 }
69529 var /** @type {?} */ j = activatableEle.childElementCount;
69530 while (j--) {
69531 var /** @type {?} */ rippleEle = activatableEle.children[j];
69532 if (rippleEle.classList.contains('button-effect')) {
69533 // DOM READ
69534 var /** @type {?} */ clientRect = activatableEle.getBoundingClientRect();
69535 rippleEle.$top = clientRect.top;
69536 rippleEle.$left = clientRect.left;
69537 rippleEle.$width = clientRect.width;
69538 rippleEle.$height = clientRect.height;
69539 break;
69540 }
69541 }
69542 };
69543 /**
69544 * @param {?} ev
69545 * @param {?} activatableEle
69546 * @param {?} startCoord
69547 * @return {?}
69548 */
69549 RippleActivator.prototype._upAction = function (ev, activatableEle, startCoord) {
69550 if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
69551 var /** @type {?} */ i = activatableEle.childElementCount;
69552 while (i--) {
69553 var /** @type {?} */ rippleEle = activatableEle.children[i];
69554 if (rippleEle.classList.contains('button-effect')) {
69555 // DOM WRITE
69556 this.startRippleEffect(rippleEle, activatableEle, startCoord);
69557 break;
69558 }
69559 }
69560 }
69561 };
69562 /**
69563 * @param {?} _ev
69564 * @param {?} _activatableEle
69565 * @param {?} _startCoord
69566 * @return {?}
69567 */
69568 RippleActivator.prototype._clickAction = function (_ev, _activatableEle, _startCoord) {
69569 // NOTHING
69570 };
69571 /**
69572 * @param {?} rippleEle
69573 * @param {?} activatableEle
69574 * @param {?} startCoord
69575 * @return {?}
69576 */
69577 RippleActivator.prototype.startRippleEffect = function (rippleEle, activatableEle, startCoord) {
69578 if (!startCoord) {
69579 return;
69580 }
69581 var /** @type {?} */ clientPointerX = (startCoord.x - rippleEle.$left);
69582 var /** @type {?} */ clientPointerY = (startCoord.y - rippleEle.$top);
69583 var /** @type {?} */ x = Math.max(Math.abs(rippleEle.$width - clientPointerX), clientPointerX) * 2;
69584 var /** @type {?} */ y = Math.max(Math.abs(rippleEle.$height - clientPointerY), clientPointerY) * 2;
69585 var /** @type {?} */ diameter = Math.min(Math.max(Math.hypot(x, y), 64), 240);
69586 if (activatableEle.hasAttribute('ion-item')) {
69587 diameter = Math.min(diameter, 140);
69588 }
69589 clientPointerX -= diameter / 2;
69590 clientPointerY -= diameter / 2;
69591 clientPointerX = Math.round(clientPointerX);
69592 clientPointerY = Math.round(clientPointerY);
69593 diameter = Math.round(diameter);
69594 // Reset ripple
69595 // DOM WRITE
69596 var /** @type {?} */ Css = this.dom.plt.Css;
69597 rippleEle.style.opacity = '';
69598 rippleEle.style[Css.transform] = "translate3d(" + clientPointerX + "px, " + clientPointerY + "px, 0px) scale(0.001)";
69599 rippleEle.style[Css.transition] = '';
69600 // Start ripple animation
69601 var /** @type {?} */ radius = Math.sqrt(rippleEle.$width + rippleEle.$height);
69602 var /** @type {?} */ scaleTransitionDuration = Math.max(1600 * Math.sqrt(radius / TOUCH_DOWN_ACCEL) + 0.5, 260);
69603 var /** @type {?} */ opacityTransitionDuration = Math.round(scaleTransitionDuration * 0.7);
69604 var /** @type {?} */ opacityTransitionDelay = Math.round(scaleTransitionDuration - opacityTransitionDuration);
69605 scaleTransitionDuration = Math.round(scaleTransitionDuration);
69606 var /** @type {?} */ transform = "translate3d(" + clientPointerX + "px, " + clientPointerY + "px, 0px) scale(1)";
69607 var /** @type {?} */ transition = "transform " + scaleTransitionDuration + "ms,opacity " + opacityTransitionDuration + "ms " + opacityTransitionDelay + "ms";
69608 this.dom.write(function () {
69609 // DOM WRITE
69610 rippleEle.style.width = rippleEle.style.height = diameter + 'px';
69611 rippleEle.style.opacity = '0';
69612 rippleEle.style[Css.transform] = transform;
69613 rippleEle.style[Css.transition] = transition;
69614 }, 16);
69615 };
69616 return RippleActivator;
69617}());
69618var TOUCH_DOWN_ACCEL = 300;
69619
69620/**
69621 * @hidden
69622 */
69623var TapClick = (function () {
69624 /**
69625 * @param {?} config
69626 * @param {?} plt
69627 * @param {?} dom
69628 * @param {?} app
69629 * @param {?} gestureCtrl
69630 */
69631 function TapClick(config, plt, dom, app, gestureCtrl) {
69632 this.plt = plt;
69633 this.app = app;
69634 this.gestureCtrl = gestureCtrl;
69635 this.disableClick = 0;
69636 this.events = new UIEventManager(plt);
69637 var activator = config.get('activator');
69638 if (activator === 'ripple') {
69639 this.activator = new RippleActivator(app, config, dom);
69640 }
69641 else if (activator === 'highlight') {
69642 this.activator = new Activator(app, config, dom);
69643 }
69644 this.usePolyfill = config.getBoolean('tapPolyfill');
69645 (void 0) /* console.debug */;
69646 var doc = plt.doc();
69647 this.events.listen(doc, 'click', this.click.bind(this), { passive: false, capture: true });
69648 this.pointerEvents = this.events.pointerEvents({
69649 element: doc,
69650 pointerDown: this.pointerStart.bind(this),
69651 pointerMove: this.pointerMove.bind(this),
69652 pointerUp: this.pointerEnd.bind(this),
69653 passive: true
69654 });
69655 this.pointerEvents.mouseWait = DISABLE_NATIVE_CLICK_AMOUNT;
69656 }
69657 /**
69658 * @param {?} ev
69659 * @return {?}
69660 */
69661 TapClick.prototype.pointerStart = function (ev) {
69662 if (this.startCoord) {
69663 return false;
69664 }
69665 if (!this.app.isEnabled()) {
69666 return false;
69667 }
69668 this.lastTouchEnd = 0;
69669 this.dispatchClick = true;
69670 if (this.plt.doc() === ev.target) {
69671 this.startCoord = pointerCoord(ev);
69672 return true;
69673 }
69674 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
69675 if (!activatableEle) {
69676 this.startCoord = null;
69677 return false;
69678 }
69679 this.startCoord = pointerCoord(ev);
69680 this.activator && this.activator.downAction(ev, activatableEle, this.startCoord);
69681 return true;
69682 };
69683 /**
69684 * @param {?} ev
69685 * @return {?}
69686 */
69687 TapClick.prototype.pointerMove = function (ev) {
69688 if (this.startCoord && this.shouldCancelEvent(ev)) {
69689 this.pointerCancel(ev);
69690 }
69691 };
69692 /**
69693 * @param {?} ev
69694 * @param {?} pointerEventType
69695 * @return {?}
69696 */
69697 TapClick.prototype.pointerEnd = function (ev, pointerEventType) {
69698 if (!this.dispatchClick)
69699 return;
69700 (void 0) /* runInDev */;
69701 if (!this.startCoord) {
69702 return;
69703 }
69704 if (this.activator && ev.target !== this.plt.doc()) {
69705 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
69706 if (activatableEle) {
69707 this.activator.upAction(ev, activatableEle, this.startCoord);
69708 }
69709 }
69710 if (this.usePolyfill && pointerEventType === POINTER_EVENT_TYPE_TOUCH && this.app.isEnabled()) {
69711 this.handleTapPolyfill(ev);
69712 }
69713 this.startCoord = null;
69714 };
69715 /**
69716 * @param {?} ev
69717 * @return {?}
69718 */
69719 TapClick.prototype.pointerCancel = function (ev) {
69720 (void 0) /* console.debug */;
69721 this.startCoord = null;
69722 this.dispatchClick = false;
69723 this.activator && this.activator.clearState(false);
69724 this.pointerEvents.stop();
69725 };
69726 /**
69727 * @param {?} ev
69728 * @return {?}
69729 */
69730 TapClick.prototype.shouldCancelEvent = function (ev) {
69731 return (this.app.isScrolling() ||
69732 this.gestureCtrl.isCaptured() ||
69733 hasPointerMoved(POINTER_TOLERANCE, this.startCoord, pointerCoord(ev)));
69734 };
69735 /**
69736 * @param {?} ev
69737 * @return {?}
69738 */
69739 TapClick.prototype.click = function (ev) {
69740 if (this.shouldCancelClick(ev)) {
69741 ev.preventDefault();
69742 ev.stopPropagation();
69743 return;
69744 }
69745 if (this.activator && this.plt.doc() !== ev.target) {
69746 // cool, a click is gonna happen, let's tell the activator
69747 // so the element can get the given "active" style
69748 var /** @type {?} */ activatableEle = getActivatableTarget(ev.target);
69749 if (activatableEle) {
69750 this.activator.clickAction(ev, activatableEle, this.startCoord);
69751 }
69752 }
69753 (void 0) /* runInDev */;
69754 };
69755 /**
69756 * @param {?} ev
69757 * @return {?}
69758 */
69759 TapClick.prototype.shouldCancelClick = function (ev) {
69760 if (this.usePolyfill) {
69761 if (!ev.isIonicTap && this.isDisabledNativeClick()) {
69762 (void 0) /* console.debug */;
69763 return true;
69764 }
69765 }
69766 else if (!this.dispatchClick) {
69767 (void 0) /* console.debug */;
69768 return true;
69769 }
69770 if (!this.app.isEnabled()) {
69771 (void 0) /* console.debug */;
69772 return true;
69773 }
69774 if (this.gestureCtrl.isCaptured()) {
69775 (void 0) /* console.debug */;
69776 return true;
69777 }
69778 return false;
69779 };
69780 /**
69781 * @param {?} ev
69782 * @return {?}
69783 */
69784 TapClick.prototype.profileClickDelay = function (ev) {
69785 if (this.lastTouchEnd) {
69786 var /** @type {?} */ diff = Date.now() - this.lastTouchEnd;
69787 if (diff < 100) {
69788 (void 0) /* console.debug */;
69789 }
69790 else {
69791 console.warn("SLOW click dispatched. Delay(ms):", diff, ev);
69792 }
69793 this.lastTouchEnd = null;
69794 }
69795 else {
69796 (void 0) /* console.debug */;
69797 }
69798 };
69799 /**
69800 * @param {?} ev
69801 * @return {?}
69802 */
69803 TapClick.prototype.handleTapPolyfill = function (ev) {
69804 (void 0) /* assert */;
69805 // only dispatch mouse click events from a touchend event
69806 // when tapPolyfill config is true, and the startCoordand endCoord
69807 // are not too far off from each other
69808 var /** @type {?} */ endCoord = pointerCoord(ev);
69809 if (hasPointerMoved(POINTER_TOLERANCE, this.startCoord, endCoord)) {
69810 (void 0) /* console.debug */;
69811 return;
69812 }
69813 // prevent native mouse click events for XX amount of time
69814 this.disableClick = Date.now() + DISABLE_NATIVE_CLICK_AMOUNT;
69815 if (this.app.isScrolling()) {
69816 // do not fire off a click event while the app was scrolling
69817 (void 0) /* console.debug */;
69818 }
69819 else {
69820 // dispatch a mouse click event
69821 (void 0) /* console.debug */;
69822 var /** @type {?} */ clickEvent = this.plt.doc().createEvent('MouseEvents');
69823 clickEvent.initMouseEvent('click', true, true, this.plt.win(), 1, 0, 0, endCoord.x, endCoord.y, false, false, false, false, 0, null);
69824 clickEvent.isIonicTap = true;
69825 ev.target.dispatchEvent(clickEvent);
69826 }
69827 };
69828 /**
69829 * @return {?}
69830 */
69831 TapClick.prototype.isDisabledNativeClick = function () {
69832 return this.disableClick > Date.now();
69833 };
69834 return TapClick;
69835}());
69836TapClick.decorators = [
69837 { type: Injectable },
69838];
69839/**
69840 * @nocollapse
69841 */
69842TapClick.ctorParameters = function () { return [
69843 { type: Config, },
69844 { type: Platform, },
69845 { type: DomController, },
69846 { type: App, },
69847 { type: GestureController, },
69848]; };
69849/**
69850 * @param {?} ele
69851 * @return {?}
69852 */
69853function getActivatableTarget(ele) {
69854 var /** @type {?} */ targetEle = ele;
69855 for (var /** @type {?} */ x = 0; x < 10; x++) {
69856 if (!targetEle)
69857 break;
69858 if (isActivatable(targetEle)) {
69859 return targetEle;
69860 }
69861 targetEle = targetEle.parentElement;
69862 }
69863 return null;
69864}
69865/**
69866 * @hidden
69867 * @param {?} ele
69868 * @return {?}
69869 */
69870function isActivatable(ele) {
69871 if (ACTIVATABLE_ELEMENTS.indexOf(ele.tagName) > -1) {
69872 return true;
69873 }
69874 for (var /** @type {?} */ i = 0, /** @type {?} */ l = ACTIVATABLE_ATTRIBUTES.length; i < l; i++) {
69875 if (ele.hasAttribute && ele.hasAttribute(ACTIVATABLE_ATTRIBUTES[i])) {
69876 return true;
69877 }
69878 }
69879 return false;
69880}
69881var ACTIVATABLE_ELEMENTS = ['A', 'BUTTON'];
69882var ACTIVATABLE_ATTRIBUTES = ['tappable', 'ion-button'];
69883var POINTER_TOLERANCE = 100;
69884var DISABLE_NATIVE_CLICK_AMOUNT = 2500;
69885/**
69886 * @hidden
69887 * @param {?} config
69888 * @param {?} plt
69889 * @param {?} dom
69890 * @param {?} app
69891 * @param {?} gestureCtrl
69892 * @return {?}
69893 */
69894function setupTapClick(config, plt, dom, app, gestureCtrl) {
69895 return function () {
69896 return new TapClick(config, plt, dom, app, gestureCtrl);
69897 };
69898}
69899
69900/* tslint:disable */
69901var win$1 = window;
69902var doc = document;
69903/*! Hammer.JS - v2.0.6 - 2015-12-23
69904 * http://hammerjs.github.io/
69905 *
69906 * Copyright (c) 2015 Jorik Tangelder;
69907 * Licensed under the license */
69908var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
69909var TEST_ELEMENT = doc.createElement('div');
69910var TYPE_FUNCTION = 'function';
69911var round$1 = Math.round;
69912var abs = Math.abs;
69913var now = Date.now;
69914/**
69915 * set a timeout with a given scope
69916 * @param {?} fn
69917 * @param {?} timeout
69918 * @param {?} context
69919 * @return {?}
69920 */
69921function setTimeoutContext(fn, timeout, context) {
69922 return setTimeout(bindFn(fn, context), timeout);
69923}
69924/**
69925 * if the argument is an array, we want to execute the fn on each entry
69926 * if it aint an array we don't want to do a thing.
69927 * this is used by all the methods that accept a single and array argument.
69928 * @param {?} arg
69929 * @param {?} fn
69930 * @param {?} context
69931 * @return {?}
69932 */
69933function invokeArrayArg(arg, fn, context) {
69934 if (Array.isArray(arg)) {
69935 each(arg, context[fn], context);
69936 return true;
69937 }
69938 return false;
69939}
69940/**
69941 * walk objects and arrays
69942 * @param {?} obj
69943 * @param {?} iterator
69944 * @param {?=} context
69945 * @return {?}
69946 */
69947function each(obj, iterator, context) {
69948 var /** @type {?} */ i;
69949 if (!obj) {
69950 return;
69951 }
69952 if (obj.forEach) {
69953 obj.forEach(iterator, context);
69954 }
69955 else if (obj.length !== undefined) {
69956 i = 0;
69957 while (i < obj.length) {
69958 iterator.call(context, obj[i], i, obj);
69959 i++;
69960 }
69961 }
69962 else {
69963 for (i in obj) {
69964 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
69965 }
69966 }
69967}
69968/**
69969 * simple class inheritance
69970 * @param {?} child
69971 * @param {?} base
69972 * @param {?} properties
69973 * @return {?}
69974 */
69975function inherit(child, base, properties) {
69976 var /** @type {?} */ baseP = base.prototype, /** @type {?} */ childP;
69977 childP = child.prototype = Object.create(baseP);
69978 childP.constructor = child;
69979 childP._super = baseP;
69980 if (properties) {
69981 Object.assign(childP, properties);
69982 }
69983}
69984/**
69985 * simple function bind
69986 * @param {?} fn
69987 * @param {?} context
69988 * @return {?}
69989 */
69990function bindFn(fn, context) {
69991 return function boundFn() {
69992 return fn.apply(context, arguments);
69993 };
69994}
69995/**
69996 * let a boolean value also be a function that must return a boolean
69997 * this first item in args will be used as the context
69998 * @param {?} val
69999 * @param {?} args
70000 * @return {?}
70001 */
70002function boolOrFn(val, args) {
70003 if (typeof val == TYPE_FUNCTION) {
70004 return val.apply(args ? args[0] || undefined : undefined, args);
70005 }
70006 return val;
70007}
70008/**
70009 * use the val2 when val1 is undefined
70010 * @param {?} val1
70011 * @param {?} val2
70012 * @return {?}
70013 */
70014function ifUndefined(val1, val2) {
70015 return (val1 === undefined) ? val2 : val1;
70016}
70017/**
70018 * addEventListener with multiple events at once
70019 * @param {?} target
70020 * @param {?} types
70021 * @param {?} handler
70022 * @return {?}
70023 */
70024function addEventListeners(target, types, handler) {
70025 each(splitStr(types), function (type) {
70026 target.addEventListener(type, handler, false);
70027 });
70028}
70029/**
70030 * removeEventListener with multiple events at once
70031 * @param {?} target
70032 * @param {?} types
70033 * @param {?} handler
70034 * @return {?}
70035 */
70036function removeEventListeners(target, types, handler) {
70037 each(splitStr(types), function (type) {
70038 target.removeEventListener(type, handler, false);
70039 });
70040}
70041/**
70042 * find if a node is in the given parent
70043 * \@method hasParent
70044 * @param {?} node
70045 * @param {?} parent
70046 * @return {?}
70047 */
70048function hasParent(node, parent) {
70049 while (node) {
70050 if (node == parent) {
70051 return true;
70052 }
70053 node = node.parentNode;
70054 }
70055 return false;
70056}
70057/**
70058 * small indexOf wrapper
70059 * @param {?} str
70060 * @param {?} find
70061 * @return {?}
70062 */
70063function inStr(str, find) {
70064 return str.indexOf(find) > -1;
70065}
70066/**
70067 * split string on whitespace
70068 * @param {?} str
70069 * @return {?}
70070 */
70071function splitStr(str) {
70072 return str.trim().split(/\s+/g);
70073}
70074/**
70075 * find if a array contains the object using indexOf or a simple polyFill
70076 * @param {?} src
70077 * @param {?} find
70078 * @param {?=} findByKey
70079 * @return {?}
70080 */
70081function inArray(src, find, findByKey) {
70082 if (src.indexOf && !findByKey) {
70083 return src.indexOf(find);
70084 }
70085 else {
70086 var /** @type {?} */ i = 0;
70087 while (i < src.length) {
70088 if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
70089 return i;
70090 }
70091 i++;
70092 }
70093 return -1;
70094 }
70095}
70096/**
70097 * convert array-like objects to real arrays
70098 * @param {?} obj
70099 * @return {?}
70100 */
70101function toArray(obj) {
70102 return Array.prototype.slice.call(obj, 0);
70103}
70104/**
70105 * unique array with objects based on a key (like 'id') or just by the array's value
70106 * @param {?} src
70107 * @param {?} key
70108 * @param {?} sort
70109 * @return {?}
70110 */
70111function uniqueArray(src, key, sort) {
70112 var /** @type {?} */ results = [];
70113 var /** @type {?} */ values = [];
70114 var /** @type {?} */ i = 0;
70115 while (i < src.length) {
70116 var /** @type {?} */ val = key ? src[i][key] : src[i];
70117 if (inArray(values, val) < 0) {
70118 results.push(src[i]);
70119 }
70120 values[i] = val;
70121 i++;
70122 }
70123 if (sort) {
70124 if (!key) {
70125 results = results.sort();
70126 }
70127 else {
70128 results = results.sort(function sortUniqueArray(a, b) {
70129 return a[key] > b[key] ? 1 : 0;
70130 });
70131 }
70132 }
70133 return results;
70134}
70135/**
70136 * get the prefixed property
70137 * @param {?} obj
70138 * @param {?} property
70139 * @return {?}
70140 */
70141function prefixed(obj, property) {
70142 var /** @type {?} */ prefix, /** @type {?} */ prop;
70143 var /** @type {?} */ camelProp = property[0].toUpperCase() + property.slice(1);
70144 var /** @type {?} */ i = 0;
70145 while (i < VENDOR_PREFIXES.length) {
70146 prefix = VENDOR_PREFIXES[i];
70147 prop = (prefix) ? prefix + camelProp : property;
70148 if (prop in obj) {
70149 return prop;
70150 }
70151 i++;
70152 }
70153 return undefined;
70154}
70155/**
70156 * get a unique id
70157 */
70158var _uniqueId = 1;
70159/**
70160 * @return {?}
70161 */
70162function uniqueId() {
70163 return _uniqueId++;
70164}
70165/**
70166 * get the window object of an element
70167 * @param {?} element
70168 * @return {?}
70169 */
70170function getWindowForElement(element) {
70171 var /** @type {?} */ doc = element.ownerDocument || element;
70172 return (doc.defaultView || doc.parentWindow || window);
70173}
70174var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
70175var SUPPORT_TOUCH = ('ontouchstart' in window);
70176var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
70177var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
70178var INPUT_TYPE_TOUCH = 'touch';
70179var INPUT_TYPE_PEN = 'pen';
70180var INPUT_TYPE_MOUSE = 'mouse';
70181var INPUT_TYPE_KINECT = 'kinect';
70182var COMPUTE_INTERVAL = 25;
70183var INPUT_START = 1;
70184var INPUT_MOVE = 2;
70185var INPUT_END = 4;
70186var INPUT_CANCEL = 8;
70187var DIRECTION_NONE = 1;
70188var DIRECTION_LEFT = 2;
70189var DIRECTION_RIGHT = 4;
70190var DIRECTION_UP = 8;
70191var DIRECTION_DOWN = 16;
70192var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
70193var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
70194var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
70195var PROPS_XY = ['x', 'y'];
70196var PROPS_CLIENT_XY = ['clientX', 'clientY'];
70197/**
70198 * create new input type manager
70199 * @param {?} manager
70200 * @param {?} callback
70201 * @return {?}
70202 */
70203function Input$1(manager, callback) {
70204 var /** @type {?} */ self = this;
70205 this.manager = manager;
70206 this.callback = callback;
70207 this.element = manager.element;
70208 this.target = manager.options.inputTarget;
70209 // smaller wrapper around the handler, for the scope and the enabled state of the manager,
70210 // so when disabled the input events are completely bypassed.
70211 this.domHandler = function (ev) {
70212 if (boolOrFn(manager.options.enable, [manager])) {
70213 self.handler(ev);
70214 }
70215 };
70216 this.init();
70217}
70218Input$1.prototype = {
70219 /**
70220 * should handle the inputEvent data and trigger the callback
70221 * @virtual
70222 */
70223 handler: function () { },
70224 /**
70225 * bind the events
70226 */
70227 init: function () {
70228 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
70229 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
70230 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
70231 },
70232 /**
70233 * unbind the events
70234 */
70235 destroy: function () {
70236 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
70237 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
70238 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
70239 }
70240};
70241/**
70242 * create new input type manager
70243 * called by the Manager constructor
70244 * @param {?} manager
70245 * @return {?}
70246 */
70247function createInputInstance(manager) {
70248 var /** @type {?} */ Type;
70249 var /** @type {?} */ inputClass = manager.options.inputClass;
70250 if (inputClass) {
70251 Type = inputClass;
70252 }
70253 else if (SUPPORT_POINTER_EVENTS) {
70254 Type = PointerEventInput;
70255 }
70256 else if (SUPPORT_ONLY_TOUCH) {
70257 Type = TouchInput;
70258 }
70259 else if (!SUPPORT_TOUCH) {
70260 Type = MouseInput;
70261 }
70262 else {
70263 Type = TouchMouseInput;
70264 }
70265 return new (Type)(manager, inputHandler);
70266}
70267/**
70268 * handle input events
70269 * @param {?} manager
70270 * @param {?} eventType
70271 * @param {?} input
70272 * @return {?}
70273 */
70274function inputHandler(manager, eventType, input) {
70275 var /** @type {?} */ pointersLen = input.pointers.length;
70276 var /** @type {?} */ changedPointersLen = input.changedPointers.length;
70277 var /** @type {?} */ isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
70278 var /** @type {?} */ isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
70279 input.isFirst = !!isFirst;
70280 input.isFinal = !!isFinal;
70281 if (isFirst) {
70282 manager.session = {};
70283 }
70284 // source event is the normalized value of the domEvents
70285 // like 'touchstart, mouseup, pointerdown'
70286 input.eventType = eventType;
70287 // compute scale, rotation etc
70288 computeInputData(manager, input);
70289 // emit secret event
70290 manager.emit('hammer.input', input);
70291 manager.recognize(input);
70292 manager.session.prevInput = input;
70293}
70294/**
70295 * extend the data with some usable properties like scale, rotate, velocity etc
70296 * @param {?} manager
70297 * @param {?} input
70298 * @return {?}
70299 */
70300function computeInputData(manager, input) {
70301 var /** @type {?} */ session = manager.session;
70302 var /** @type {?} */ pointers = input.pointers;
70303 var /** @type {?} */ pointersLength = pointers.length;
70304 // store the first input to calculate the distance and direction
70305 if (!session.firstInput) {
70306 session.firstInput = simpleCloneInputData(input);
70307 }
70308 // to compute scale and rotation we need to store the multiple touches
70309 if (pointersLength > 1 && !session.firstMultiple) {
70310 session.firstMultiple = simpleCloneInputData(input);
70311 }
70312 else if (pointersLength === 1) {
70313 session.firstMultiple = false;
70314 }
70315 var /** @type {?} */ firstInput = session.firstInput;
70316 var /** @type {?} */ firstMultiple = session.firstMultiple;
70317 var /** @type {?} */ offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
70318 var /** @type {?} */ center = input.center = getCenter(pointers);
70319 input.timeStamp = now();
70320 input.deltaTime = input.timeStamp - firstInput.timeStamp;
70321 input.angle = getAngle(offsetCenter, center);
70322 input.distance = getDistance(offsetCenter, center);
70323 computeDeltaXY(session, input);
70324 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
70325 var /** @type {?} */ overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
70326 input.overallVelocityX = overallVelocity.x;
70327 input.overallVelocityY = overallVelocity.y;
70328 input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
70329 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
70330 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
70331 input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
70332 session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
70333 computeIntervalInputData(session, input);
70334 // find the correct target
70335 var /** @type {?} */ target = manager.element;
70336 if (hasParent(input.srcEvent.target, target)) {
70337 target = input.srcEvent.target;
70338 }
70339 input.target = target;
70340}
70341/**
70342 * @param {?} session
70343 * @param {?} input
70344 * @return {?}
70345 */
70346function computeDeltaXY(session, input) {
70347 var /** @type {?} */ center = input.center;
70348 var /** @type {?} */ offset = session.offsetDelta || {};
70349 var /** @type {?} */ prevDelta = session.prevDelta || {};
70350 var /** @type {?} */ prevInput = session.prevInput || {};
70351 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
70352 prevDelta = session.prevDelta = {
70353 x: prevInput.deltaX || 0,
70354 y: prevInput.deltaY || 0
70355 };
70356 offset = session.offsetDelta = {
70357 x: center.x,
70358 y: center.y
70359 };
70360 }
70361 input.deltaX = prevDelta.x + (center.x - offset.x);
70362 input.deltaY = prevDelta.y + (center.y - offset.y);
70363}
70364/**
70365 * velocity is calculated every x ms
70366 * @param {?} session
70367 * @param {?} input
70368 * @return {?}
70369 */
70370function computeIntervalInputData(session, input) {
70371 var /** @type {?} */ last = session.lastInterval || input, /** @type {?} */ deltaTime = input.timeStamp - last.timeStamp, /** @type {?} */ velocity, /** @type {?} */ velocityX, /** @type {?} */ velocityY, /** @type {?} */ direction;
70372 if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
70373 var /** @type {?} */ deltaX = input.deltaX - last.deltaX;
70374 var /** @type {?} */ deltaY = input.deltaY - last.deltaY;
70375 var /** @type {?} */ v = getVelocity(deltaTime, deltaX, deltaY);
70376 velocityX = v.x;
70377 velocityY = v.y;
70378 velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
70379 direction = getDirection(deltaX, deltaY);
70380 session.lastInterval = input;
70381 }
70382 else {
70383 // use latest velocity info if it doesn't overtake a minimum period
70384 velocity = last.velocity;
70385 velocityX = last.velocityX;
70386 velocityY = last.velocityY;
70387 direction = last.direction;
70388 }
70389 input.velocity = velocity;
70390 input.velocityX = velocityX;
70391 input.velocityY = velocityY;
70392 input.direction = direction;
70393}
70394/**
70395 * create a simple clone from the input used for storage of firstInput and firstMultiple
70396 * @param {?} input
70397 * @return {?}
70398 */
70399function simpleCloneInputData(input) {
70400 // make a simple copy of the pointers because we will get a reference if we don't
70401 // we only need clientXY for the calculations
70402 var /** @type {?} */ pointers = [];
70403 var /** @type {?} */ i = 0;
70404 while (i < input.pointers.length) {
70405 pointers[i] = {
70406 clientX: round$1(input.pointers[i].clientX),
70407 clientY: round$1(input.pointers[i].clientY)
70408 };
70409 i++;
70410 }
70411 return {
70412 timeStamp: now(),
70413 pointers: pointers,
70414 center: getCenter(pointers),
70415 deltaX: input.deltaX,
70416 deltaY: input.deltaY
70417 };
70418}
70419/**
70420 * get the center of all the pointers
70421 * @param {?} pointers
70422 * @return {?}
70423 */
70424function getCenter(pointers) {
70425 var /** @type {?} */ pointersLength = pointers.length;
70426 // no need to loop when only one touch
70427 if (pointersLength === 1) {
70428 return {
70429 x: round$1(pointers[0].clientX),
70430 y: round$1(pointers[0].clientY)
70431 };
70432 }
70433 var /** @type {?} */ x = 0, /** @type {?} */ y = 0, /** @type {?} */ i = 0;
70434 while (i < pointersLength) {
70435 x += pointers[i].clientX;
70436 y += pointers[i].clientY;
70437 i++;
70438 }
70439 return {
70440 x: round$1(x / pointersLength),
70441 y: round$1(y / pointersLength)
70442 };
70443}
70444/**
70445 * calculate the velocity between two points. unit is in px per ms.
70446 * @param {?} deltaTime
70447 * @param {?} x
70448 * @param {?} y
70449 * @return {?}
70450 */
70451function getVelocity(deltaTime, x, y) {
70452 return {
70453 x: x / deltaTime || 0,
70454 y: y / deltaTime || 0
70455 };
70456}
70457/**
70458 * get the direction between two points
70459 * @param {?} x
70460 * @param {?} y
70461 * @return {?}
70462 */
70463function getDirection(x, y) {
70464 if (x === y) {
70465 return DIRECTION_NONE;
70466 }
70467 if (abs(x) >= abs(y)) {
70468 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
70469 }
70470 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
70471}
70472/**
70473 * calculate the absolute distance between two points
70474 * @param {?} p1
70475 * @param {?} p2
70476 * @param {?=} props
70477 * @return {?}
70478 */
70479function getDistance(p1, p2, props) {
70480 if (!props) {
70481 props = PROPS_XY;
70482 }
70483 var /** @type {?} */ x = p2[props[0]] - p1[props[0]], /** @type {?} */ y = p2[props[1]] - p1[props[1]];
70484 return Math.sqrt((x * x) + (y * y));
70485}
70486/**
70487 * calculate the angle between two coordinates
70488 * @param {?} p1
70489 * @param {?} p2
70490 * @param {?=} props
70491 * @return {?}
70492 */
70493function getAngle(p1, p2, props) {
70494 if (!props) {
70495 props = PROPS_XY;
70496 }
70497 var /** @type {?} */ x = p2[props[0]] - p1[props[0]], /** @type {?} */ y = p2[props[1]] - p1[props[1]];
70498 return Math.atan2(y, x) * 180 / Math.PI;
70499}
70500/**
70501 * calculate the rotation degrees between two pointersets
70502 * @param {?} start
70503 * @param {?} end
70504 * @return {?}
70505 */
70506function getRotation(start, end) {
70507 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
70508}
70509/**
70510 * calculate the scale factor between two pointersets
70511 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
70512 * @param {?} start
70513 * @param {?} end
70514 * @return {?}
70515 */
70516function getScale(start, end) {
70517 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
70518}
70519var MOUSE_INPUT_MAP = {
70520 mousedown: INPUT_START,
70521 mousemove: INPUT_MOVE,
70522 mouseup: INPUT_END
70523};
70524var MOUSE_ELEMENT_EVENTS = 'mousedown';
70525var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
70526/**
70527 * Mouse events input
70528 * @param {?} _manager
70529 * @param {?} _handler
70530 * @return {?}
70531 */
70532function MouseInput(_manager, _handler) {
70533 this.evEl = MOUSE_ELEMENT_EVENTS;
70534 this.evWin = MOUSE_WINDOW_EVENTS;
70535 this.allow = true; // used by Input.TouchMouse to disable mouse events
70536 this.pressed = false; // mousedown state
70537 Input$1.apply(this, arguments);
70538}
70539inherit(MouseInput, Input$1, {
70540 /**
70541 * handle mouse events
70542 * @param {Object} ev
70543 */
70544 handler: function MEhandler(ev) {
70545 var /** @type {?} */ eventType = MOUSE_INPUT_MAP[ev.type];
70546 // on start we want to have the left mouse button down
70547 if (eventType & INPUT_START && ev.button === 0) {
70548 this.pressed = true;
70549 }
70550 if (eventType & INPUT_MOVE && ev.which !== 1) {
70551 eventType = INPUT_END;
70552 }
70553 // mouse must be down, and mouse events are allowed (see the TouchMouse input)
70554 if (!this.pressed || !this.allow) {
70555 return;
70556 }
70557 if (eventType & INPUT_END) {
70558 this.pressed = false;
70559 }
70560 this.callback(this.manager, eventType, {
70561 pointers: [ev],
70562 changedPointers: [ev],
70563 pointerType: INPUT_TYPE_MOUSE,
70564 srcEvent: ev
70565 });
70566 }
70567});
70568var POINTER_INPUT_MAP = {
70569 pointerdown: INPUT_START,
70570 pointermove: INPUT_MOVE,
70571 pointerup: INPUT_END,
70572 pointercancel: INPUT_CANCEL,
70573 pointerout: INPUT_CANCEL
70574};
70575// in IE10 the pointer types is defined as an enum
70576var IE10_POINTER_TYPE_ENUM = {
70577 2: INPUT_TYPE_TOUCH,
70578 3: INPUT_TYPE_PEN,
70579 4: INPUT_TYPE_MOUSE,
70580 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
70581};
70582var POINTER_ELEMENT_EVENTS = 'pointerdown';
70583var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
70584// IE10 has prefixed support, and case-sensitive
70585if (win$1.MSPointerEvent && !win$1.PointerEvent) {
70586 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
70587 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
70588}
70589/**
70590 * Pointer events input
70591 * @return {?}
70592 */
70593function PointerEventInput() {
70594 this.evEl = POINTER_ELEMENT_EVENTS;
70595 this.evWin = POINTER_WINDOW_EVENTS;
70596 Input$1.apply(this, arguments);
70597 this.store = (this.manager.session.pointerEvents = []);
70598}
70599inherit(PointerEventInput, Input$1, {
70600 /**
70601 * handle mouse events
70602 * @param {Object} ev
70603 */
70604 handler: function PEhandler(ev) {
70605 var /** @type {?} */ store = this.store;
70606 var /** @type {?} */ removePointer = false;
70607 var /** @type {?} */ eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
70608 var /** @type {?} */ eventType = POINTER_INPUT_MAP[eventTypeNormalized];
70609 var /** @type {?} */ pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
70610 var /** @type {?} */ isTouch = (pointerType == INPUT_TYPE_TOUCH);
70611 // get index of the event in the store
70612 var /** @type {?} */ storeIndex = inArray(store, ev.pointerId, 'pointerId');
70613 // start and mouse must be down
70614 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
70615 if (storeIndex < 0) {
70616 store.push(ev);
70617 storeIndex = store.length - 1;
70618 }
70619 }
70620 else if (eventType & (INPUT_END | INPUT_CANCEL)) {
70621 removePointer = true;
70622 }
70623 // it not found, so the pointer hasn't been down (so it's probably a hover)
70624 if (storeIndex < 0) {
70625 return;
70626 }
70627 // update the event in the store
70628 store[storeIndex] = ev;
70629 this.callback(this.manager, eventType, {
70630 pointers: store,
70631 changedPointers: [ev],
70632 pointerType: pointerType,
70633 srcEvent: ev
70634 });
70635 if (removePointer) {
70636 // remove from the store
70637 store.splice(storeIndex, 1);
70638 }
70639 }
70640});
70641var SINGLE_TOUCH_INPUT_MAP = {
70642 touchstart: INPUT_START,
70643 touchmove: INPUT_MOVE,
70644 touchend: INPUT_END,
70645 touchcancel: INPUT_CANCEL
70646};
70647var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
70648var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
70649/**
70650 * Touch events input
70651 * @return {?}
70652 */
70653function SingleTouchInput() {
70654 this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
70655 this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
70656 this.started = false;
70657 Input$1.apply(this, arguments);
70658}
70659inherit(SingleTouchInput, Input$1, {
70660 handler: function TEhandler(ev) {
70661 var /** @type {?} */ type = SINGLE_TOUCH_INPUT_MAP[ev.type];
70662 // should we handle the touch events?
70663 if (type === INPUT_START) {
70664 this.started = true;
70665 }
70666 if (!this.started) {
70667 return;
70668 }
70669 var /** @type {?} */ touches = normalizeSingleTouches.call(this, ev, type);
70670 // when done, reset the started state
70671 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
70672 this.started = false;
70673 }
70674 this.callback(this.manager, type, {
70675 pointers: touches[0],
70676 changedPointers: touches[1],
70677 pointerType: INPUT_TYPE_TOUCH,
70678 srcEvent: ev
70679 });
70680 }
70681});
70682/**
70683 * @param {?} ev
70684 * @param {?} type
70685 * @return {?}
70686 */
70687function normalizeSingleTouches(ev, type) {
70688 var /** @type {?} */ all = toArray(ev.touches);
70689 var /** @type {?} */ changed = toArray(ev.changedTouches);
70690 if (type & (INPUT_END | INPUT_CANCEL)) {
70691 all = uniqueArray(all.concat(changed), 'identifier', true);
70692 }
70693 return [all, changed];
70694}
70695var TOUCH_INPUT_MAP = {
70696 touchstart: INPUT_START,
70697 touchmove: INPUT_MOVE,
70698 touchend: INPUT_END,
70699 touchcancel: INPUT_CANCEL
70700};
70701var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
70702/**
70703 * Multi-user touch events input
70704 * @param {?} _manager
70705 * @param {?} _handler
70706 * @return {?}
70707 */
70708function TouchInput(_manager, _handler) {
70709 this.evTarget = TOUCH_TARGET_EVENTS;
70710 this.targetIds = {};
70711 Input$1.apply(this, arguments);
70712}
70713inherit(TouchInput, Input$1, {
70714 handler: function MTEhandler(ev) {
70715 var /** @type {?} */ type = TOUCH_INPUT_MAP[ev.type];
70716 var /** @type {?} */ touches = getTouches.call(this, ev, type);
70717 if (!touches) {
70718 return;
70719 }
70720 this.callback(this.manager, type, {
70721 pointers: touches[0],
70722 changedPointers: touches[1],
70723 pointerType: INPUT_TYPE_TOUCH,
70724 srcEvent: ev
70725 });
70726 }
70727});
70728/**
70729 * @param {?} ev
70730 * @param {?} type
70731 * @return {?}
70732 */
70733function getTouches(ev, type) {
70734 var /** @type {?} */ allTouches = toArray(ev.touches);
70735 var /** @type {?} */ targetIds = this.targetIds;
70736 // when there is only one touch, the process can be simplified
70737 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
70738 targetIds[allTouches[0].identifier] = true;
70739 return [allTouches, allTouches];
70740 }
70741 var /** @type {?} */ i, /** @type {?} */ targetTouches, /** @type {?} */ changedTouches = toArray(ev.changedTouches), /** @type {?} */ changedTargetTouches = [], /** @type {?} */ target = this.target;
70742 // get target touches from touches
70743 targetTouches = allTouches.filter(function (touch) {
70744 return hasParent(touch.target, target);
70745 });
70746 // collect touches
70747 if (type === INPUT_START) {
70748 i = 0;
70749 while (i < targetTouches.length) {
70750 targetIds[targetTouches[i].identifier] = true;
70751 i++;
70752 }
70753 }
70754 // filter changed touches to only contain touches that exist in the collected target ids
70755 i = 0;
70756 while (i < changedTouches.length) {
70757 if (targetIds[changedTouches[i].identifier]) {
70758 changedTargetTouches.push(changedTouches[i]);
70759 }
70760 // cleanup removed touches
70761 if (type & (INPUT_END | INPUT_CANCEL)) {
70762 delete targetIds[changedTouches[i].identifier];
70763 }
70764 i++;
70765 }
70766 if (!changedTargetTouches.length) {
70767 return;
70768 }
70769 return [
70770 // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
70771 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
70772 changedTargetTouches
70773 ];
70774}
70775/**
70776 * Combined touch and mouse input
70777 *
70778 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
70779 * This because touch devices also emit mouse events while doing a touch.
70780 *
70781 * @return {?}
70782 */
70783function TouchMouseInput() {
70784 Input$1.apply(this, arguments);
70785 var /** @type {?} */ handler = bindFn(this.handler, this);
70786 this.touch = new ((TouchInput))(this.manager, handler);
70787 this.mouse = new ((MouseInput))(this.manager, handler);
70788}
70789inherit(TouchMouseInput, Input$1, {
70790 /**
70791 * handle mouse and touch events
70792 * @param {Hammer} manager
70793 * @param {String} inputEvent
70794 * @param {Object} inputData
70795 */
70796 handler: function TMEhandler(manager, inputEvent, inputData) {
70797 var /** @type {?} */ isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), /** @type {?} */ isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
70798 // when we're in a touch event, so block all upcoming mouse events
70799 // most mobile browser also emit mouseevents, right after touchstart
70800 if (isTouch) {
70801 this.mouse.allow = false;
70802 }
70803 else if (isMouse && !this.mouse.allow) {
70804 return;
70805 }
70806 // reset the allowMouse when we're done
70807 if (inputEvent & (INPUT_END | INPUT_CANCEL)) {
70808 this.mouse.allow = true;
70809 }
70810 this.callback(manager, inputEvent, inputData);
70811 },
70812 /**
70813 * remove the event listeners
70814 */
70815 destroy: function destroy() {
70816 this.touch.destroy();
70817 this.mouse.destroy();
70818 }
70819});
70820var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
70821var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
70822// magical touchAction value
70823var TOUCH_ACTION_COMPUTE = 'compute';
70824var TOUCH_ACTION_AUTO = 'auto';
70825var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
70826var TOUCH_ACTION_NONE = 'none';
70827var TOUCH_ACTION_PAN_X = 'pan-x';
70828var TOUCH_ACTION_PAN_Y = 'pan-y';
70829/**
70830 * Touch Action
70831 * sets the touchAction property or uses the js alternative
70832 * @param {?} manager
70833 * @param {?} value
70834 * @return {?}
70835 */
70836function TouchAction(manager, value) {
70837 this.manager = manager;
70838 this.set(value);
70839}
70840TouchAction.prototype = {
70841 /**
70842 * set the touchAction value on the element or enable the polyfill
70843 * @param {String} value
70844 */
70845 set: function (value) {
70846 // find out the touch-action by the event handlers
70847 if (value == TOUCH_ACTION_COMPUTE) {
70848 value = this.compute();
70849 }
70850 if (NATIVE_TOUCH_ACTION && this.manager.element.style) {
70851 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
70852 }
70853 this.actions = value.toLowerCase().trim();
70854 },
70855 /**
70856 * just re-set the touchAction value
70857 */
70858 update: function () {
70859 this.set(this.manager.options.touchAction);
70860 },
70861 /**
70862 * compute the value for the touchAction property based on the recognizer's settings
70863 * @returns {String} value
70864 */
70865 compute: function () {
70866 var /** @type {?} */ actions = [];
70867 each(this.manager.recognizers, function (recognizer) {
70868 if (boolOrFn(recognizer.options.enable, [recognizer])) {
70869 actions = actions.concat(recognizer.getTouchAction());
70870 }
70871 });
70872 return cleanTouchActions(actions.join(' '));
70873 },
70874 /**
70875 * this method is called on each input cycle and provides the preventing of the browser behavior
70876 * @param {Object} input
70877 */
70878 preventDefaults: function (input) {
70879 // not needed with native support for the touchAction property
70880 if (NATIVE_TOUCH_ACTION) {
70881 return;
70882 }
70883 var /** @type {?} */ srcEvent = input.srcEvent;
70884 var /** @type {?} */ direction = input.offsetDirection;
70885 // if the touch action did prevented once this session
70886 if (this.manager.session.prevented) {
70887 srcEvent.preventDefault();
70888 return;
70889 }
70890 var /** @type {?} */ actions = this.actions;
70891 var /** @type {?} */ hasNone = inStr(actions, TOUCH_ACTION_NONE);
70892 var /** @type {?} */ hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
70893 var /** @type {?} */ hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
70894 if (hasNone) {
70895 //do not prevent defaults if this is a tap gesture
70896 var /** @type {?} */ isTapPointer = input.pointers.length === 1;
70897 var /** @type {?} */ isTapMovement = input.distance < 2;
70898 var /** @type {?} */ isTapTouchTime = input.deltaTime < 250;
70899 if (isTapPointer && isTapMovement && isTapTouchTime) {
70900 return;
70901 }
70902 }
70903 if (hasPanX && hasPanY) {
70904 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
70905 return;
70906 }
70907 if (hasNone ||
70908 (hasPanY && direction & DIRECTION_HORIZONTAL) ||
70909 (hasPanX && direction & DIRECTION_VERTICAL)) {
70910 return this.preventSrc(srcEvent);
70911 }
70912 },
70913 /**
70914 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
70915 * @param {Object} srcEvent
70916 */
70917 preventSrc: function (srcEvent) {
70918 this.manager.session.prevented = true;
70919 srcEvent.preventDefault();
70920 }
70921};
70922/**
70923 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
70924 * @param {?} actions
70925 * @return {?}
70926 */
70927function cleanTouchActions(actions) {
70928 // none
70929 if (inStr(actions, TOUCH_ACTION_NONE)) {
70930 return TOUCH_ACTION_NONE;
70931 }
70932 var /** @type {?} */ hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
70933 var /** @type {?} */ hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
70934 // if both pan-x and pan-y are set (different recognizers
70935 // for different directions, e.g. horizontal pan but vertical swipe?)
70936 // we need none (as otherwise with pan-x pan-y combined none of these
70937 // recognizers will work, since the browser would handle all panning
70938 if (hasPanX && hasPanY) {
70939 return TOUCH_ACTION_NONE;
70940 }
70941 // pan-x OR pan-y
70942 if (hasPanX || hasPanY) {
70943 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
70944 }
70945 // manipulation
70946 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
70947 return TOUCH_ACTION_MANIPULATION;
70948 }
70949 return TOUCH_ACTION_AUTO;
70950}
70951/**
70952 * Recognizer flow explained; *
70953 * All recognizers have the initial state of POSSIBLE when a input session starts.
70954 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
70955 * Example session for mouse-input: mousedown -> mousemove -> mouseup
70956 *
70957 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
70958 * which determines with state it should be.
70959 *
70960 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
70961 * POSSIBLE to give it another change on the next cycle.
70962 *
70963 * Possible
70964 * |
70965 * +-----+---------------+
70966 * | |
70967 * +-----+-----+ |
70968 * | | |
70969 * Failed Cancelled |
70970 * +-------+------+
70971 * | |
70972 * Recognized Began
70973 * |
70974 * Changed
70975 * |
70976 * Ended/Recognized
70977 */
70978var STATE_POSSIBLE = 1;
70979var STATE_BEGAN = 2;
70980var STATE_CHANGED = 4;
70981var STATE_ENDED = 8;
70982var STATE_RECOGNIZED = STATE_ENDED;
70983var STATE_CANCELLED = 16;
70984var STATE_FAILED = 32;
70985/**
70986 * Recognizer
70987 * Every recognizer needs to extend from this class.
70988 * @param {?} options
70989 * @return {?}
70990 */
70991function Recognizer(options) {
70992 this.options = Object.assign({}, this.defaults, options || {});
70993 this.id = uniqueId();
70994 this.manager = null;
70995 // default is enable true
70996 this.options.enable = ifUndefined(this.options.enable, true);
70997 this.state = STATE_POSSIBLE;
70998 this.simultaneous = {};
70999 this.requireFail = [];
71000}
71001Recognizer.prototype = {
71002 /**
71003 * @virtual
71004 * @type {Object}
71005 */
71006 defaults: {},
71007 /**
71008 * set options
71009 * @param {Object} options
71010 * @return {Recognizer}
71011 */
71012 set: function (options) {
71013 Object.assign(this.options, options);
71014 // also update the touchAction, in case something changed about the directions/enabled state
71015 this.manager && this.manager.touchAction.update();
71016 return this;
71017 },
71018 /**
71019 * recognize simultaneous with an other recognizer.
71020 * @param {Recognizer} otherRecognizer
71021 * @returns {Recognizer} this
71022 */
71023 recognizeWith: function (otherRecognizer) {
71024 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
71025 return this;
71026 }
71027 var /** @type {?} */ simultaneous = this.simultaneous;
71028 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
71029 if (!simultaneous[otherRecognizer.id]) {
71030 simultaneous[otherRecognizer.id] = otherRecognizer;
71031 otherRecognizer.recognizeWith(this);
71032 }
71033 return this;
71034 },
71035 /**
71036 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
71037 * @param {Recognizer} otherRecognizer
71038 * @returns {Recognizer} this
71039 */
71040 dropRecognizeWith: function (otherRecognizer) {
71041 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
71042 return this;
71043 }
71044 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
71045 delete this.simultaneous[otherRecognizer.id];
71046 return this;
71047 },
71048 /**
71049 * recognizer can only run when an other is failing
71050 * @param {Recognizer} otherRecognizer
71051 * @returns {Recognizer} this
71052 */
71053 requireFailure: function (otherRecognizer) {
71054 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
71055 return this;
71056 }
71057 var /** @type {?} */ requireFail = this.requireFail;
71058 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
71059 if (inArray(requireFail, otherRecognizer) === -1) {
71060 requireFail.push(otherRecognizer);
71061 otherRecognizer.requireFailure(this);
71062 }
71063 return this;
71064 },
71065 /**
71066 * drop the requireFailure link. it does not remove the link on the other recognizer.
71067 * @param {Recognizer} otherRecognizer
71068 * @returns {Recognizer} this
71069 */
71070 dropRequireFailure: function (otherRecognizer) {
71071 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
71072 return this;
71073 }
71074 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
71075 var /** @type {?} */ index = inArray(this.requireFail, otherRecognizer);
71076 if (index > -1) {
71077 this.requireFail.splice(index, 1);
71078 }
71079 return this;
71080 },
71081 /**
71082 * has require failures boolean
71083 * @returns {boolean}
71084 */
71085 hasRequireFailures: function () {
71086 return this.requireFail.length > 0;
71087 },
71088 /**
71089 * if the recognizer can recognize simultaneous with an other recognizer
71090 * @param {Recognizer} otherRecognizer
71091 * @returns {Boolean}
71092 */
71093 canRecognizeWith: function (otherRecognizer) {
71094 return !!this.simultaneous[otherRecognizer.id];
71095 },
71096 /**
71097 * You should use `tryEmit` instead of `emit` directly to check
71098 * that all the needed recognizers has failed before emitting.
71099 * @param {Object} input
71100 */
71101 emit: function (input) {
71102 var /** @type {?} */ self = this;
71103 var /** @type {?} */ state = this.state;
71104 /**
71105 * @param {?} event
71106 * @return {?}
71107 */
71108 function emit(event) {
71109 self.manager.emit(event, input);
71110 }
71111 // 'panstart' and 'panmove'
71112 if (state < STATE_ENDED) {
71113 emit(self.options.event + stateStr(state));
71114 }
71115 emit(self.options.event); // simple 'eventName' events
71116 if (input.additionalEvent) {
71117 emit(input.additionalEvent);
71118 }
71119 // panend and pancancel
71120 if (state >= STATE_ENDED) {
71121 emit(self.options.event + stateStr(state));
71122 }
71123 },
71124 /**
71125 * Check that all the require failure recognizers has failed,
71126 * if true, it emits a gesture event,
71127 * otherwise, setup the state to FAILED.
71128 * @param {Object} input
71129 */
71130 tryEmit: function (input) {
71131 if (this.canEmit()) {
71132 return this.emit(input);
71133 }
71134 // it's failing anyway
71135 this.state = STATE_FAILED;
71136 },
71137 /**
71138 * can we emit?
71139 * @returns {boolean}
71140 */
71141 canEmit: function () {
71142 var /** @type {?} */ i = 0;
71143 while (i < this.requireFail.length) {
71144 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
71145 return false;
71146 }
71147 i++;
71148 }
71149 return true;
71150 },
71151 /**
71152 * update the recognizer
71153 * @param {Object} inputData
71154 */
71155 recognize: function (inputData) {
71156 // make a new copy of the inputData
71157 // so we can change the inputData without messing up the other recognizers
71158 var /** @type {?} */ inputDataClone = Object.assign({}, inputData);
71159 // is is enabled and allow recognizing?
71160 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
71161 this.reset();
71162 this.state = STATE_FAILED;
71163 return;
71164 }
71165 // reset when we've reached the end
71166 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
71167 this.state = STATE_POSSIBLE;
71168 }
71169 this.state = this.process(inputDataClone);
71170 // the recognizer has recognized a gesture
71171 // so trigger an event
71172 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
71173 this.tryEmit(inputDataClone);
71174 }
71175 },
71176 /**
71177 * return the state of the recognizer
71178 * the actual recognizing happens in this method
71179 * @virtual
71180 * @param {Object} inputData
71181 * @returns {Const} STATE
71182 */
71183 process: function (_inputData) { },
71184 /**
71185 * return the preferred touch-action
71186 * @virtual
71187 * @returns {Array}
71188 */
71189 getTouchAction: function () { },
71190 /**
71191 * called when the gesture isn't allowed to recognize
71192 * like when another is being recognized or it is disabled
71193 * @virtual
71194 */
71195 reset: function () { }
71196};
71197/**
71198 * get a usable string, used as event postfix
71199 * @param {?} state
71200 * @return {?}
71201 */
71202function stateStr(state) {
71203 if (state & STATE_CANCELLED) {
71204 return 'cancel';
71205 }
71206 else if (state & STATE_ENDED) {
71207 return 'end';
71208 }
71209 else if (state & STATE_CHANGED) {
71210 return 'move';
71211 }
71212 else if (state & STATE_BEGAN) {
71213 return 'start';
71214 }
71215 return '';
71216}
71217/**
71218 * direction cons to string
71219 * @param {?} direction
71220 * @return {?}
71221 */
71222function directionStr(direction) {
71223 if (direction == DIRECTION_DOWN) {
71224 return 'down';
71225 }
71226 else if (direction == DIRECTION_UP) {
71227 return 'up';
71228 }
71229 else if (direction == DIRECTION_LEFT) {
71230 return 'left';
71231 }
71232 else if (direction == DIRECTION_RIGHT) {
71233 return 'right';
71234 }
71235 return '';
71236}
71237/**
71238 * get a recognizer by name if it is bound to a manager
71239 * @param {?} otherRecognizer
71240 * @param {?} recognizer
71241 * @return {?}
71242 */
71243function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
71244 var /** @type {?} */ manager = recognizer.manager;
71245 if (manager) {
71246 return manager.get(otherRecognizer);
71247 }
71248 return otherRecognizer;
71249}
71250/**
71251 * This recognizer is just used as a base for the simple attribute recognizers.
71252 * @return {?}
71253 */
71254function AttrRecognizer() {
71255 Recognizer.apply(this, arguments);
71256}
71257inherit(AttrRecognizer, Recognizer, {
71258 /**
71259 * @namespace
71260 * @memberof AttrRecognizer
71261 */
71262 defaults: {
71263 /**
71264 * @type {Number}
71265 * @default 1
71266 */
71267 pointers: 1
71268 },
71269 /**
71270 * Used to check if it the recognizer receives valid input, like input.distance > 10.
71271 * @memberof AttrRecognizer
71272 * @param {Object} input
71273 * @returns {Boolean} recognized
71274 */
71275 attrTest: function (input) {
71276 var /** @type {?} */ optionPointers = this.options.pointers;
71277 return optionPointers === 0 || input.pointers.length === optionPointers;
71278 },
71279 /**
71280 * Process the input and return the state for the recognizer
71281 * @memberof AttrRecognizer
71282 * @param {Object} input
71283 * @returns {*} State
71284 */
71285 process: function (input) {
71286 var /** @type {?} */ state = this.state;
71287 var /** @type {?} */ eventType = input.eventType;
71288 var /** @type {?} */ isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
71289 var /** @type {?} */ isValid = this.attrTest(input);
71290 // on cancel input and we've recognized before, return STATE_CANCELLED
71291 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
71292 return state | STATE_CANCELLED;
71293 }
71294 else if (isRecognized || isValid) {
71295 if (eventType & INPUT_END) {
71296 return state | STATE_ENDED;
71297 }
71298 else if (!(state & STATE_BEGAN)) {
71299 return STATE_BEGAN;
71300 }
71301 return state | STATE_CHANGED;
71302 }
71303 return STATE_FAILED;
71304 }
71305});
71306/**
71307 * Pan
71308 * Recognized when the pointer is down and moved in the allowed direction.
71309 * @return {?}
71310 */
71311function PanRecognizer$1() {
71312 AttrRecognizer.apply(this, arguments);
71313 this.pX = null;
71314 this.pY = null;
71315}
71316inherit(PanRecognizer$1, AttrRecognizer, {
71317 /**
71318 * @namespace
71319 * @memberof PanRecognizer
71320 */
71321 defaults: {
71322 event: 'pan',
71323 threshold: 10,
71324 pointers: 1,
71325 direction: DIRECTION_ALL
71326 },
71327 getTouchAction: function () {
71328 var /** @type {?} */ direction = this.options.direction;
71329 var /** @type {?} */ actions = [];
71330 if (direction & DIRECTION_HORIZONTAL) {
71331 actions.push(TOUCH_ACTION_PAN_Y);
71332 }
71333 if (direction & DIRECTION_VERTICAL) {
71334 actions.push(TOUCH_ACTION_PAN_X);
71335 }
71336 return actions;
71337 },
71338 directionTest: function (input) {
71339 var /** @type {?} */ options = this.options;
71340 var /** @type {?} */ hasMoved = true;
71341 var /** @type {?} */ distance = input.distance;
71342 var /** @type {?} */ direction = input.direction;
71343 var /** @type {?} */ x = input.deltaX;
71344 var /** @type {?} */ y = input.deltaY;
71345 // lock to axis?
71346 if (!(direction & options.direction)) {
71347 if (options.direction & DIRECTION_HORIZONTAL) {
71348 direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
71349 hasMoved = x != this.pX;
71350 distance = Math.abs(input.deltaX);
71351 }
71352 else {
71353 direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
71354 hasMoved = y != this.pY;
71355 distance = Math.abs(input.deltaY);
71356 }
71357 }
71358 input.direction = direction;
71359 return hasMoved && distance > options.threshold && direction & options.direction;
71360 },
71361 attrTest: function (input) {
71362 return AttrRecognizer.prototype.attrTest.call(this, input) &&
71363 (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
71364 },
71365 emit: function (input) {
71366 this.pX = input.deltaX;
71367 this.pY = input.deltaY;
71368 var /** @type {?} */ direction = directionStr(input.direction);
71369 if (direction) {
71370 input.additionalEvent = this.options.event + direction;
71371 }
71372 this._super.emit.call(this, input);
71373 }
71374});
71375/**
71376 * Pinch
71377 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
71378 * @return {?}
71379 */
71380function PinchRecognizer() {
71381 AttrRecognizer.apply(this, arguments);
71382}
71383inherit(PinchRecognizer, AttrRecognizer, {
71384 /**
71385 * @namespace
71386 * @memberof PinchRecognizer
71387 */
71388 defaults: {
71389 event: 'pinch',
71390 threshold: 0,
71391 pointers: 2
71392 },
71393 getTouchAction: function () {
71394 return [TOUCH_ACTION_NONE];
71395 },
71396 attrTest: function (input) {
71397 return this._super.attrTest.call(this, input) &&
71398 (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
71399 },
71400 emit: function (input) {
71401 if (input.scale !== 1) {
71402 var /** @type {?} */ inOut = input.scale < 1 ? 'in' : 'out';
71403 input.additionalEvent = this.options.event + inOut;
71404 }
71405 this._super.emit.call(this, input);
71406 }
71407});
71408/**
71409 * Press
71410 * Recognized when the pointer is down for x ms without any movement.
71411 * @return {?}
71412 */
71413function PressRecognizer() {
71414 Recognizer.apply(this, arguments);
71415 this._timer = null;
71416 this._input = null;
71417}
71418inherit(PressRecognizer, Recognizer, {
71419 /**
71420 * @namespace
71421 * @memberof PressRecognizer
71422 */
71423 defaults: {
71424 event: 'press',
71425 pointers: 1,
71426 time: 251,
71427 threshold: 9 // a minimal movement is ok, but keep it low
71428 },
71429 getTouchAction: function () {
71430 return [TOUCH_ACTION_AUTO];
71431 },
71432 process: function (input) {
71433 var /** @type {?} */ options = this.options;
71434 var /** @type {?} */ validPointers = input.pointers.length === options.pointers;
71435 var /** @type {?} */ validMovement = input.distance < options.threshold;
71436 var /** @type {?} */ validTime = input.deltaTime > options.time;
71437 this._input = input;
71438 // we only allow little movement
71439 // and we've reached an end event, so a tap is possible
71440 if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
71441 this.reset();
71442 }
71443 else if (input.eventType & INPUT_START) {
71444 this.reset();
71445 this._timer = setTimeoutContext(function () {
71446 this.state = STATE_RECOGNIZED;
71447 this.tryEmit();
71448 }, options.time, this);
71449 }
71450 else if (input.eventType & INPUT_END) {
71451 return STATE_RECOGNIZED;
71452 }
71453 return STATE_FAILED;
71454 },
71455 reset: function () {
71456 clearTimeout(this._timer);
71457 },
71458 emit: function (input) {
71459 if (this.state !== STATE_RECOGNIZED) {
71460 return;
71461 }
71462 if (input && (input.eventType & INPUT_END)) {
71463 this.manager.emit(this.options.event + 'up', input);
71464 }
71465 else {
71466 this._input.timeStamp = now();
71467 this.manager.emit(this.options.event, this._input);
71468 }
71469 }
71470});
71471/**
71472 * Rotate
71473 * Recognized when two or more pointer are moving in a circular motion.
71474 * @return {?}
71475 */
71476function RotateRecognizer() {
71477 AttrRecognizer.apply(this, arguments);
71478}
71479inherit(RotateRecognizer, AttrRecognizer, {
71480 /**
71481 * @namespace
71482 * @memberof RotateRecognizer
71483 */
71484 defaults: {
71485 event: 'rotate',
71486 threshold: 0,
71487 pointers: 2
71488 },
71489 getTouchAction: function () {
71490 return [TOUCH_ACTION_NONE];
71491 },
71492 attrTest: function (input) {
71493 return this._super.attrTest.call(this, input) &&
71494 (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
71495 }
71496});
71497/**
71498 * Swipe
71499 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
71500 * @return {?}
71501 */
71502function SwipeRecognizer() {
71503 AttrRecognizer.apply(this, arguments);
71504}
71505inherit(SwipeRecognizer, AttrRecognizer, {
71506 /**
71507 * @namespace
71508 * @memberof SwipeRecognizer
71509 */
71510 defaults: {
71511 event: 'swipe',
71512 threshold: 10,
71513 velocity: 0.3,
71514 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
71515 pointers: 1
71516 },
71517 getTouchAction: function () {
71518 return PanRecognizer$1.prototype.getTouchAction.call(this);
71519 },
71520 attrTest: function (input) {
71521 var /** @type {?} */ direction = this.options.direction;
71522 var /** @type {?} */ velocity;
71523 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
71524 velocity = input.overallVelocity;
71525 }
71526 else if (direction & DIRECTION_HORIZONTAL) {
71527 velocity = input.overallVelocityX;
71528 }
71529 else if (direction & DIRECTION_VERTICAL) {
71530 velocity = input.overallVelocityY;
71531 }
71532 return this._super.attrTest.call(this, input) &&
71533 direction & input.offsetDirection &&
71534 input.distance > this.options.threshold &&
71535 input.maxPointers == this.options.pointers &&
71536 abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
71537 },
71538 emit: function (input) {
71539 var /** @type {?} */ direction = directionStr(input.offsetDirection);
71540 if (direction) {
71541 this.manager.emit(this.options.event + direction, input);
71542 }
71543 this.manager.emit(this.options.event, input);
71544 }
71545});
71546/**
71547 * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
71548 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
71549 * a single tap.
71550 *
71551 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
71552 * multi-taps being recognized.
71553 * @return {?}
71554 */
71555function TapRecognizer() {
71556 Recognizer.apply(this, arguments);
71557 // previous time and center,
71558 // used for tap counting
71559 this.pTime = false;
71560 this.pCenter = false;
71561 this._timer = null;
71562 this._input = null;
71563 this.count = 0;
71564}
71565inherit(TapRecognizer, Recognizer, {
71566 /**
71567 * @namespace
71568 * @memberof PinchRecognizer
71569 */
71570 defaults: {
71571 event: 'tap',
71572 pointers: 1,
71573 taps: 1,
71574 interval: 300,
71575 time: 250,
71576 threshold: 9,
71577 posThreshold: 10 // a multi-tap can be a bit off the initial position
71578 },
71579 getTouchAction: function () {
71580 return [TOUCH_ACTION_MANIPULATION];
71581 },
71582 process: function (input) {
71583 var /** @type {?} */ options = this.options;
71584 var /** @type {?} */ validPointers = input.pointers.length === options.pointers;
71585 var /** @type {?} */ validMovement = input.distance < options.threshold;
71586 var /** @type {?} */ validTouchTime = input.deltaTime < options.time;
71587 this.reset();
71588 if ((input.eventType & INPUT_START) && (this.count === 0)) {
71589 return this.failTimeout();
71590 }
71591 // we only allow little movement
71592 // and we've reached an end event, so a tap is possible
71593 if (validMovement && validTouchTime && validPointers) {
71594 if (input.eventType != INPUT_END) {
71595 return this.failTimeout();
71596 }
71597 var /** @type {?} */ validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
71598 var /** @type {?} */ validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
71599 this.pTime = input.timeStamp;
71600 this.pCenter = input.center;
71601 if (!validMultiTap || !validInterval) {
71602 this.count = 1;
71603 }
71604 else {
71605 this.count += 1;
71606 }
71607 this._input = input;
71608 // if tap count matches we have recognized it,
71609 // else it has began recognizing...
71610 var /** @type {?} */ tapCount = this.count % options.taps;
71611 if (tapCount === 0) {
71612 // no failing requirements, immediately trigger the tap event
71613 // or wait as long as the multitap interval to trigger
71614 if (!this.hasRequireFailures()) {
71615 return STATE_RECOGNIZED;
71616 }
71617 else {
71618 this._timer = setTimeoutContext(function () {
71619 this.state = STATE_RECOGNIZED;
71620 this.tryEmit();
71621 }, options.interval, this);
71622 return STATE_BEGAN;
71623 }
71624 }
71625 }
71626 return STATE_FAILED;
71627 },
71628 failTimeout: function () {
71629 this._timer = setTimeoutContext(function () {
71630 this.state = STATE_FAILED;
71631 }, this.options.interval, this);
71632 return STATE_FAILED;
71633 },
71634 reset: function () {
71635 clearTimeout(this._timer);
71636 },
71637 emit: function () {
71638 if (this.state == STATE_RECOGNIZED) {
71639 this._input.tapCount = this.count;
71640 this.manager.emit(this.options.event, this._input);
71641 }
71642 }
71643});
71644/**
71645 * Simple way to create a manager with a default set of recognizers.
71646 * @param {?} element
71647 * @param {?} options
71648 * @return {?}
71649 */
71650function Hammer$1(element, options) {
71651 options = options || {};
71652 options.recognizers = ifUndefined(options.recognizers, _defaults.preset);
71653 return new ((Manager))(element, options);
71654}
71655/**
71656 * default settings
71657 * \@namespace
71658 */
71659var _defaults = {
71660 /**
71661 * set if DOM events are being triggered.
71662 * But this is slower and unused by simple implementations, so disabled by default.
71663 * @type {Boolean}
71664 * @default false
71665 */
71666 domEvents: false,
71667 /**
71668 * The value for the touchAction property/fallback.
71669 * When set to `compute` it will magically set the correct value based on the added recognizers.
71670 * @type {String}
71671 * @default compute
71672 */
71673 touchAction: TOUCH_ACTION_COMPUTE,
71674 /**
71675 * @type {Boolean}
71676 * @default true
71677 */
71678 enable: true,
71679 /**
71680 * EXPERIMENTAL FEATURE -- can be removed/changed
71681 * Change the parent input target element.
71682 * If Null, then it is being set the to main element.
71683 * @type {Null|EventTarget}
71684 * @default null
71685 */
71686 inputTarget: null,
71687 /**
71688 * force an input class
71689 * @type {Null|Function}
71690 * @default null
71691 */
71692 inputClass: null,
71693 /**
71694 * Default recognizer setup when calling `Hammer()`
71695 * When creating a new Manager these will be skipped.
71696 * @type {Array}
71697 */
71698 preset: [
71699 // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
71700 [RotateRecognizer, { enable: false }],
71701 [PinchRecognizer, { enable: false }, ['rotate']],
71702 [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }],
71703 [PanRecognizer$1, { direction: DIRECTION_HORIZONTAL }, ['swipe']],
71704 [TapRecognizer],
71705 [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']],
71706 [PressRecognizer]
71707 ],
71708 /**
71709 * Some CSS properties can be used to improve the working of Hammer.
71710 * Add them to this method and they will be set when creating a new Manager.
71711 * @namespace
71712 */
71713 cssProps: {
71714 /**
71715 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
71716 * @type {String}
71717 * @default 'none'
71718 */
71719 userSelect: 'none',
71720 /**
71721 * Disable the Windows Phone grippers when pressing an element.
71722 * @type {String}
71723 * @default 'none'
71724 */
71725 touchSelect: 'none',
71726 /**
71727 * Disables the default callout shown when you touch and hold a touch target.
71728 * On iOS, when you touch and hold a touch target such as a link, Safari displays
71729 * a callout containing information about the link. This property allows you to disable that callout.
71730 * @type {String}
71731 * @default 'none'
71732 */
71733 touchCallout: 'none',
71734 /**
71735 * Specifies whether zooming is enabled. Used by IE10>
71736 * @type {String}
71737 * @default 'none'
71738 */
71739 contentZooming: 'none',
71740 /**
71741 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
71742 * @type {String}
71743 * @default 'none'
71744 */
71745 userDrag: 'none',
71746 /**
71747 * Overrides the highlight color shown when the user taps a link or a JavaScript
71748 * clickable element in iOS. This property obeys the alpha value, if specified.
71749 * @type {String}
71750 * @default 'rgba(0,0,0,0)'
71751 */
71752 tapHighlightColor: 'rgba(0,0,0,0)'
71753 }
71754};
71755var STOP = 1;
71756var FORCED_STOP = 2;
71757/**
71758 * Manager
71759 * @param {?} element
71760 * @param {?} options
71761 * @return {?}
71762 */
71763function Manager(element, options) {
71764 this.options = Object.assign({}, _defaults, options || {});
71765 this.options.inputTarget = this.options.inputTarget || element;
71766 this.handlers = {};
71767 this.session = {};
71768 this.recognizers = [];
71769 this.element = element;
71770 this.input = createInputInstance(this);
71771 this.touchAction = new ((TouchAction))(this, this.options.touchAction);
71772 toggleCssProps(this, true);
71773 each(this.options.recognizers, function (item) {
71774 var /** @type {?} */ recognizer = this.add(new (item[0])(item[1]));
71775 item[2] && recognizer.recognizeWith(item[2]);
71776 item[3] && recognizer.requireFailure(item[3]);
71777 }, this);
71778}
71779Manager.prototype = {
71780 /**
71781 * set options
71782 * @param {Object} options
71783 * @returns {Manager}
71784 */
71785 set: function (options) {
71786 Object.assign(this.options, options);
71787 // Options that need a little more setup
71788 if (options.touchAction) {
71789 this.touchAction.update();
71790 }
71791 if (options.inputTarget) {
71792 // Clean up existing event listeners and reinitialize
71793 this.input.destroy();
71794 this.input.target = options.inputTarget;
71795 this.input.init();
71796 }
71797 return this;
71798 },
71799 /**
71800 * stop recognizing for this session.
71801 * This session will be discarded, when a new [input]start event is fired.
71802 * When forced, the recognizer cycle is stopped immediately.
71803 * @param {Boolean} [force]
71804 */
71805 stop: function (force) {
71806 this.session.stopped = force ? FORCED_STOP : STOP;
71807 },
71808 /**
71809 * run the recognizers!
71810 * called by the inputHandler function on every movement of the pointers (touches)
71811 * it walks through all the recognizers and tries to detect the gesture that is being made
71812 * @param {Object} inputData
71813 */
71814 recognize: function (inputData) {
71815 var /** @type {?} */ session = this.session;
71816 if (session.stopped) {
71817 return;
71818 }
71819 // run the touch-action polyfill
71820 this.touchAction.preventDefaults(inputData);
71821 var /** @type {?} */ recognizer;
71822 var /** @type {?} */ recognizers = this.recognizers;
71823 // this holds the recognizer that is being recognized.
71824 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
71825 // if no recognizer is detecting a thing, it is set to `null`
71826 var /** @type {?} */ curRecognizer = session.curRecognizer;
71827 // reset when the last recognizer is recognized
71828 // or when we're in a new session
71829 if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
71830 curRecognizer = session.curRecognizer = null;
71831 }
71832 var /** @type {?} */ i = 0;
71833 while (i < recognizers.length) {
71834 recognizer = recognizers[i];
71835 // find out if we are allowed try to recognize the input for this one.
71836 // 1. allow if the session is NOT forced stopped (see the .stop() method)
71837 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
71838 // that is being recognized.
71839 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
71840 // this can be setup with the `recognizeWith()` method on the recognizer.
71841 if (session.stopped !== FORCED_STOP && (!curRecognizer || recognizer == curRecognizer ||
71842 recognizer.canRecognizeWith(curRecognizer))) {
71843 recognizer.recognize(inputData);
71844 }
71845 else {
71846 recognizer.reset();
71847 }
71848 // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
71849 // current active recognizer. but only if we don't already have an active recognizer
71850 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
71851 curRecognizer = session.curRecognizer = recognizer;
71852 }
71853 i++;
71854 }
71855 },
71856 /**
71857 * get a recognizer by its event name.
71858 * @param {Recognizer|String} recognizer
71859 * @returns {Recognizer|Null}
71860 */
71861 get: function (recognizer) {
71862 if (recognizer instanceof Recognizer) {
71863 return recognizer;
71864 }
71865 var /** @type {?} */ recognizers = this.recognizers;
71866 for (var /** @type {?} */ i = 0; i < recognizers.length; i++) {
71867 if (recognizers[i].options.event == recognizer) {
71868 return recognizers[i];
71869 }
71870 }
71871 return null;
71872 },
71873 /**
71874 * add a recognizer to the manager
71875 * existing recognizers with the same event name will be removed
71876 * @param {Recognizer} recognizer
71877 * @returns {Recognizer|Manager}
71878 */
71879 add: function (recognizer) {
71880 if (invokeArrayArg(recognizer, 'add', this)) {
71881 return this;
71882 }
71883 // remove existing
71884 var /** @type {?} */ existing = this.get(recognizer.options.event);
71885 if (existing) {
71886 this.remove(existing);
71887 }
71888 this.recognizers.push(recognizer);
71889 recognizer.manager = this;
71890 this.touchAction.update();
71891 return recognizer;
71892 },
71893 /**
71894 * remove a recognizer by name or instance
71895 * @param {Recognizer|String} recognizer
71896 * @returns {Manager}
71897 */
71898 remove: function (recognizer) {
71899 if (invokeArrayArg(recognizer, 'remove', this)) {
71900 return this;
71901 }
71902 recognizer = this.get(recognizer);
71903 // let's make sure this recognizer exists
71904 if (recognizer) {
71905 var /** @type {?} */ recognizers = this.recognizers;
71906 var /** @type {?} */ index = inArray(recognizers, recognizer);
71907 if (index !== -1) {
71908 recognizers.splice(index, 1);
71909 this.touchAction.update();
71910 }
71911 }
71912 return this;
71913 },
71914 /**
71915 * bind event
71916 * @param {String} events
71917 * @param {Function} handler
71918 * @returns {EventEmitter} this
71919 */
71920 on: function (events, handler) {
71921 var /** @type {?} */ handlers = this.handlers;
71922 each(splitStr(events), function (event) {
71923 handlers[event] = handlers[event] || [];
71924 handlers[event].push(handler);
71925 });
71926 return this;
71927 },
71928 /**
71929 * unbind event, leave emit blank to remove all handlers
71930 * @param {String} events
71931 * @param {Function} [handler]
71932 * @returns {EventEmitter} this
71933 */
71934 off: function (events, handler) {
71935 var /** @type {?} */ handlers = this.handlers;
71936 each(splitStr(events), function (event) {
71937 if (!handler) {
71938 delete handlers[event];
71939 }
71940 else {
71941 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
71942 }
71943 });
71944 return this;
71945 },
71946 /**
71947 * emit event to the listeners
71948 * @param {String} event
71949 * @param {Object} data
71950 */
71951 emit: function (event, data) {
71952 // we also want to trigger dom events
71953 if (this.options.domEvents) {
71954 triggerDomEvent(event, data);
71955 }
71956 // no handlers, so skip it all
71957 var /** @type {?} */ handlers = this.handlers[event] && this.handlers[event].slice();
71958 if (!handlers || !handlers.length) {
71959 return;
71960 }
71961 data.type = event;
71962 data.preventDefault = function () {
71963 data.srcEvent.preventDefault();
71964 };
71965 var /** @type {?} */ i = 0;
71966 while (i < handlers.length) {
71967 handlers[i](data);
71968 i++;
71969 }
71970 },
71971 /**
71972 * destroy the manager and unbinds all events
71973 * it doesn't unbind dom events, that is the user own responsibility
71974 */
71975 destroy: function () {
71976 this.element && toggleCssProps(this, false);
71977 this.handlers = {};
71978 this.session = {};
71979 this.input.destroy();
71980 this.element = null;
71981 }
71982};
71983/**
71984 * add/remove the css properties as defined in manager.options.cssProps
71985 * @param {?} manager
71986 * @param {?} add
71987 * @return {?}
71988 */
71989function toggleCssProps(manager, add) {
71990 var /** @type {?} */ element = manager.element;
71991 if (!element.style) {
71992 return;
71993 }
71994 each(manager.options.cssProps, function (value, name) {
71995 element.style[prefixed(element.style, name)] = add ? value : '';
71996 });
71997}
71998/**
71999 * trigger dom event
72000 * @param {?} event
72001 * @param {?} data
72002 * @return {?}
72003 */
72004function triggerDomEvent(event, data) {
72005 var /** @type {?} */ gestureEvent = doc.createEvent('Event');
72006 gestureEvent.initEvent(event, true, true);
72007 gestureEvent.gesture = data;
72008 data.target.dispatchEvent(gestureEvent);
72009}
72010Object.assign(Hammer$1, {
72011 INPUT_START: INPUT_START,
72012 INPUT_MOVE: INPUT_MOVE,
72013 INPUT_END: INPUT_END,
72014 INPUT_CANCEL: INPUT_CANCEL,
72015 STATE_POSSIBLE: STATE_POSSIBLE,
72016 STATE_BEGAN: STATE_BEGAN,
72017 STATE_CHANGED: STATE_CHANGED,
72018 STATE_ENDED: STATE_ENDED,
72019 STATE_RECOGNIZED: STATE_RECOGNIZED,
72020 STATE_CANCELLED: STATE_CANCELLED,
72021 STATE_FAILED: STATE_FAILED,
72022 DIRECTION_NONE: DIRECTION_NONE,
72023 DIRECTION_LEFT: DIRECTION_LEFT,
72024 DIRECTION_RIGHT: DIRECTION_RIGHT,
72025 DIRECTION_UP: DIRECTION_UP,
72026 DIRECTION_DOWN: DIRECTION_DOWN,
72027 DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
72028 DIRECTION_VERTICAL: DIRECTION_VERTICAL,
72029 DIRECTION_ALL: DIRECTION_ALL,
72030 Manager: Manager,
72031 Input: Input$1,
72032 TouchAction: TouchAction,
72033 TouchInput: TouchInput,
72034 MouseInput: MouseInput,
72035 PointerEventInput: PointerEventInput,
72036 TouchMouseInput: TouchMouseInput,
72037 SingleTouchInput: SingleTouchInput,
72038 Recognizer: Recognizer,
72039 AttrRecognizer: AttrRecognizer,
72040 Tap: TapRecognizer,
72041 Pan: PanRecognizer$1,
72042 Swipe: SwipeRecognizer,
72043 Pinch: PinchRecognizer,
72044 Rotate: RotateRecognizer,
72045 Press: PressRecognizer,
72046 on: addEventListeners,
72047 off: removeEventListeners,
72048 each: each,
72049 inherit: inherit,
72050 bindFn: bindFn,
72051 prefixed: prefixed
72052});
72053win$1.Hammer = Hammer$1;
72054
72055/**
72056 * @hidden
72057 * A gesture recognizer class.
72058 *
72059 * TODO(mlynch): Re-enable the DOM event simulation that was causing issues (or verify hammer does this already, it might);
72060 */
72061var Gesture = (function () {
72062 /**
72063 * @param {?} element
72064 * @param {?=} opts
72065 */
72066 function Gesture(element, opts) {
72067 if (opts === void 0) { opts = {}; }
72068 this._callbacks = {};
72069 this.isListening = false;
72070 defaults(opts, {
72071 domEvents: true
72072 });
72073 this.element = element;
72074 // Map 'x' or 'y' string to hammerjs opts
72075 this.direction = opts.direction || 'x';
72076 opts.direction = this.direction === 'x' ?
72077 DIRECTION_HORIZONTAL :
72078 DIRECTION_VERTICAL;
72079 this._options = opts;
72080 }
72081 /**
72082 * @param {?} opts
72083 * @return {?}
72084 */
72085 Gesture.prototype.options = function (opts) {
72086 Object.assign(this._options, opts);
72087 };
72088 /**
72089 * @param {?} type
72090 * @param {?} cb
72091 * @return {?}
72092 */
72093 Gesture.prototype.on = function (type, cb) {
72094 if (type === 'pinch' || type === 'rotate') {
72095 this._hammer.get(type).set({ enable: true });
72096 }
72097 this._hammer.on(type, cb);
72098 (this._callbacks[type] || (this._callbacks[type] = [])).push(cb);
72099 };
72100 /**
72101 * @param {?} type
72102 * @param {?} cb
72103 * @return {?}
72104 */
72105 Gesture.prototype.off = function (type, cb) {
72106 this._hammer.off(type, this._callbacks[type] ? cb : null);
72107 };
72108 /**
72109 * @return {?}
72110 */
72111 Gesture.prototype.listen = function () {
72112 if (!this.isListening) {
72113 this._hammer = Hammer$1(this.element, this._options);
72114 }
72115 this.isListening = true;
72116 };
72117 /**
72118 * @return {?}
72119 */
72120 Gesture.prototype.unlisten = function () {
72121 var /** @type {?} */ eventType;
72122 var /** @type {?} */ i;
72123 if (this._hammer && this.isListening) {
72124 for (eventType in this._callbacks) {
72125 for (i = 0; i < this._callbacks[eventType].length; i++) {
72126 this._hammer.off(eventType, this._callbacks[eventType]);
72127 }
72128 }
72129 this._hammer.destroy();
72130 }
72131 this._callbacks = {};
72132 this._hammer = null;
72133 this.isListening = false;
72134 };
72135 /**
72136 * @return {?}
72137 */
72138 Gesture.prototype.destroy = function () {
72139 this.unlisten();
72140 this.element = this._options = null;
72141 };
72142 return Gesture;
72143}());
72144
72145/**
72146 * \@name Events
72147 * \@description
72148 * Events is a publish-subscribe style event system for sending and responding to application-level
72149 * events across your app.
72150 *
72151 * \@usage
72152 * ```ts
72153 * import { Events } from 'ionic-angular';
72154 *
72155 * // first page (publish an event when a user is created)
72156 * constructor(public events: Events) { }
72157 *
72158 * createUser(user) {
72159 * console.log('User created!')
72160 * this.events.publish('user:created', user, Date.now());
72161 * }
72162 *
72163 *
72164 * // second page (listen for the user created event after function is called)
72165 * constructor(public events: Events) {
72166 * events.subscribe('user:created', (user, time) => {
72167 * // user and time are the same arguments passed in `events.publish(user, time)`
72168 * console.log('Welcome', user, 'at', time);
72169 * });
72170 * }
72171 *
72172 * ```
72173 * \@demo /docs/demos/src/events/
72174 */
72175var Events = (function () {
72176 function Events() {
72177 this._channels = [];
72178 }
72179 /**
72180 * Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
72181 *
72182 * @param {?} topic
72183 * @param {...?} handlers
72184 * @return {?}
72185 */
72186 Events.prototype.subscribe = function (topic) {
72187 var _this = this;
72188 var handlers = [];
72189 for (var _i = 1; _i < arguments.length; _i++) {
72190 handlers[_i - 1] = arguments[_i];
72191 }
72192 if (!this._channels[topic]) {
72193 this._channels[topic] = [];
72194 }
72195 handlers.forEach(function (handler) {
72196 _this._channels[topic].push(handler);
72197 });
72198 };
72199 /**
72200 * Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
72201 *
72202 *
72203 * @param {?} topic
72204 * @param {?=} handler
72205 * @return {?} true if a handler was removed
72206 */
72207 Events.prototype.unsubscribe = function (topic, handler) {
72208 if (handler === void 0) { handler = null; }
72209 var /** @type {?} */ t = this._channels[topic];
72210 if (!t) {
72211 // Wasn't found, wasn't removed
72212 return false;
72213 }
72214 if (!handler) {
72215 // Remove all handlers for this topic
72216 delete this._channels[topic];
72217 return true;
72218 }
72219 // We need to find and remove a specific handler
72220 var /** @type {?} */ i = t.indexOf(handler);
72221 if (i < 0) {
72222 // Wasn't found, wasn't removed
72223 return false;
72224 }
72225 t.splice(i, 1);
72226 // If the channel is empty now, remove it from the channel map
72227 if (!t.length) {
72228 delete this._channels[topic];
72229 }
72230 return true;
72231 };
72232 /**
72233 * Publish an event to the given topic.
72234 *
72235 * @param {?} topic
72236 * @param {...?} args
72237 * @return {?}
72238 */
72239 Events.prototype.publish = function (topic) {
72240 var args = [];
72241 for (var _i = 1; _i < arguments.length; _i++) {
72242 args[_i - 1] = arguments[_i];
72243 }
72244 var /** @type {?} */ t = this._channels[topic];
72245 if (!t) {
72246 return null;
72247 }
72248 var /** @type {?} */ responses = [];
72249 t.forEach(function (handler) {
72250 responses.push(handler.apply(void 0, args));
72251 });
72252 return responses;
72253 };
72254 return Events;
72255}());
72256/**
72257 * @hidden
72258 * @param {?} plt
72259 * @param {?} dom
72260 * @return {?}
72261 */
72262function setupEvents(plt, dom) {
72263 var /** @type {?} */ events = new Events();
72264 var /** @type {?} */ win = plt.win();
72265 var /** @type {?} */ doc = plt.doc();
72266 // start listening for resizes XXms after the app starts
72267 plt.timeout(function () {
72268 win.addEventListener('online', function (ev) {
72269 events.publish('app:online', ev);
72270 }, false);
72271 win.addEventListener('offline', function (ev) {
72272 events.publish('app:offline', ev);
72273 }, false);
72274 win.addEventListener('orientationchange', function (ev) {
72275 events.publish('app:rotated', ev);
72276 });
72277 // When that status taps, we respond
72278 win.addEventListener('statusTap', function () {
72279 // TODO: Make this more better
72280 var /** @type {?} */ el = (doc.elementFromPoint(plt.width() / 2, plt.height() / 2));
72281 if (!el) {
72282 return;
72283 }
72284 var /** @type {?} */ contentEle = (el.closest('.scroll-content'));
72285 if (contentEle) {
72286 var /** @type {?} */ style = contentEle.style;
72287 var /** @type {?} */ scroll = new ScrollView(null, plt, dom);
72288 scroll._el = contentEle;
72289 // We need to stop scrolling if it's happening and scroll up
72290 style['WebkitBackfaceVisibility'] = 'hidden';
72291 style['WebkitTransform'] = 'translate3d(0,0,0)';
72292 dom.write(function () {
72293 style.overflow = 'hidden';
72294 /**
72295 * @return {?}
72296 */
72297 function finish() {
72298 style.overflow = '';
72299 style['WebkitBackfaceVisibility'] = '';
72300 style['WebkitTransform'] = '';
72301 }
72302 var /** @type {?} */ didScrollTimeout = plt.timeout(function () {
72303 finish();
72304 }, 400);
72305 scroll.scrollTo(0, 0, 300).then(function () {
72306 plt.cancelTimeout(didScrollTimeout);
72307 finish();
72308 });
72309 });
72310 }
72311 });
72312 }, 2000);
72313 return events;
72314}
72315/**
72316 * @hidden
72317 * @param {?} plt
72318 * @param {?} dom
72319 * @return {?}
72320 */
72321function setupProvideEvents(plt, dom) {
72322 return function () {
72323 return setupEvents(plt, dom);
72324 };
72325}
72326
72327var __extends$91 = (undefined && undefined.__extends) || (function () {
72328 var extendStatics = Object.setPrototypeOf ||
72329 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
72330 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
72331 return function (d, b) {
72332 extendStatics(d, b);
72333 function __() { this.constructor = d; }
72334 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
72335 };
72336})();
72337/**
72338 * \@name IonicErrorHandler
72339 * \@description
72340 * The `IonicErrorHandler` intercepts the default `Console` error handling
72341 * and displays runtime errors as an overlay when using Ionic's Dev Build Server.
72342 *
72343 *
72344 * ### IonicErrorHandler Example
72345 *
72346 * ```typescript
72347 * import { ErrorHandler, NgModule } from '\@angular/core';
72348 * import { IonicErrorHandler } from 'ionic-angular';
72349 *
72350 * \@NgModule({
72351 * providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
72352 * })
72353 * class AppModule { }
72354 * ```
72355 *
72356 *
72357 * ### Custom Error Handlers
72358 *
72359 * Custom error handlers can be built to replace the default, or extend Ionic's
72360 * error handler.
72361 *
72362 * ```typescript
72363 * class MyErrorHandler implements ErrorHandler {
72364 * handleError(err: any): void {
72365 * // do something with the error
72366 * }
72367 * }
72368 *
72369 * \@NgModule({
72370 * providers: [{ provide: ErrorHandler, useClass: MyErrorHandler }]
72371 * })
72372 * class AppModule { }
72373 * ```
72374 *
72375 * More information about Angular's [`ErrorHandler`](https://angular.io/docs/ts/latest/api/core/index/ErrorHandler-class.html).
72376 */
72377var IonicErrorHandler = (function (_super) {
72378 __extends$91(IonicErrorHandler, _super);
72379 function IonicErrorHandler() {
72380 return _super.call(this, false) || this;
72381 }
72382 /**
72383 * \@internal
72384 * @param {?} err
72385 * @return {?}
72386 */
72387 IonicErrorHandler.prototype.handleError = function (err) {
72388 _super.prototype.handleError.call(this, err);
72389 try {
72390 var /** @type {?} */ win = window;
72391 var /** @type {?} */ monitor = void 0;
72392 monitor = win['IonicDevServer'];
72393 monitor && monitor.handleError && monitor.handleError(err);
72394 monitor = (win['Ionic'] = win['Ionic'] || {}).Monitor;
72395 monitor && monitor.handleError && monitor.handleError(err);
72396 }
72397 catch (e) { }
72398 };
72399 return IonicErrorHandler;
72400}(ErrorHandler));
72401
72402var PLATFORM_CONFIGS = {
72403 /**
72404 * core
72405 */
72406 'core': {
72407 settings: {
72408 mode: 'md',
72409 keyboardHeight: 290
72410 }
72411 },
72412 /**
72413 * mobile
72414 */
72415 'mobile': {},
72416 /**
72417 * phablet
72418 */
72419 'phablet': {
72420 /**
72421 * @param {?} plt
72422 * @return {?}
72423 */
72424 isMatch: function (plt) {
72425 var /** @type {?} */ smallest = Math.min(plt.width(), plt.height());
72426 var /** @type {?} */ largest = Math.max(plt.width(), plt.height());
72427 return (smallest > 390 && smallest < 520) &&
72428 (largest > 620 && largest < 800);
72429 }
72430 },
72431 /**
72432 * tablet
72433 */
72434 'tablet': {
72435 /**
72436 * @param {?} plt
72437 * @return {?}
72438 */
72439 isMatch: function (plt) {
72440 var /** @type {?} */ smallest = Math.min(plt.width(), plt.height());
72441 var /** @type {?} */ largest = Math.max(plt.width(), plt.height());
72442 return (smallest > 460 && smallest < 820) &&
72443 (largest > 780 && largest < 1400);
72444 }
72445 },
72446 /**
72447 * android
72448 */
72449 'android': {
72450 superset: 'mobile',
72451 subsets: [
72452 'phablet',
72453 'tablet'
72454 ],
72455 settings: {
72456 activator: function (plt) {
72457 // md mode defaults to use ripple activator
72458 // however, under-powered devices shouldn't use ripple
72459 // if this a linux device, and is using Android Chrome v36 (Android 5.0)
72460 // or above then use ripple, otherwise do not use a ripple effect
72461 if (plt.testNavigatorPlatform('linux')) {
72462 var /** @type {?} */ chromeVersion = plt.matchUserAgentVersion(/Chrome\/(\d+).(\d+)?/);
72463 if (chromeVersion) {
72464 // linux android device using modern android chrome browser gets ripple
72465 if (parseInt(chromeVersion.major, 10) < 36 || plt.version().major < 5) {
72466 return 'none';
72467 }
72468 else {
72469 return 'ripple';
72470 }
72471 }
72472 // linux android device not using chrome browser checks just android's version
72473 if (plt.version().major < 5) {
72474 return 'none';
72475 }
72476 }
72477 // fallback to always use ripple
72478 return 'ripple';
72479 },
72480 autoFocusAssist: 'immediate',
72481 inputCloning: true,
72482 scrollAssist: true,
72483 hoverCSS: false,
72484 keyboardHeight: 300,
72485 mode: 'md',
72486 },
72487 /**
72488 * @param {?} plt
72489 * @return {?}
72490 */
72491 isMatch: function (plt) {
72492 return plt.isPlatformMatch('android', ['android', 'silk'], ['windows phone']);
72493 },
72494 /**
72495 * @param {?} plt
72496 * @return {?}
72497 */
72498 versionParser: function (plt) {
72499 return plt.matchUserAgentVersion(/Android (\d+).(\d+)?/);
72500 }
72501 },
72502 /**
72503 * ios
72504 */
72505 'ios': {
72506 superset: 'mobile',
72507 subsets: [
72508 'ipad',
72509 'iphone'
72510 ],
72511 settings: {
72512 autoFocusAssist: 'delay',
72513 hideCaretOnScroll: true,
72514 hoverCSS: false,
72515 inputBlurring: isIos,
72516 inputCloning: isIos,
72517 keyboardHeight: 300,
72518 mode: 'ios',
72519 scrollAssist: isIos,
72520 statusbarPadding: isCordova,
72521 swipeBackEnabled: isIos,
72522 tapPolyfill: isIosUIWebView,
72523 virtualScrollEventAssist: isIosUIWebView,
72524 disableScrollAssist: isIos,
72525 keyboardResizes: keyboardResizes,
72526 resizeAssist: keyboardResizes,
72527 },
72528 /**
72529 * @param {?} plt
72530 * @return {?}
72531 */
72532 isMatch: function (plt) {
72533 return plt.isPlatformMatch('ios', ['iphone', 'ipad', 'ipod'], ['windows phone']);
72534 },
72535 /**
72536 * @param {?} plt
72537 * @return {?}
72538 */
72539 versionParser: function (plt) {
72540 return plt.matchUserAgentVersion(/OS (\d+)_(\d+)?/);
72541 }
72542 },
72543 /**
72544 * ipad
72545 */
72546 'ipad': {
72547 superset: 'tablet',
72548 settings: {
72549 keyboardHeight: 500,
72550 },
72551 /**
72552 * @param {?} plt
72553 * @return {?}
72554 */
72555 isMatch: function (plt) {
72556 return plt.isPlatformMatch('ipad');
72557 }
72558 },
72559 /**
72560 * iphone
72561 */
72562 'iphone': {
72563 subsets: [
72564 'phablet'
72565 ],
72566 /**
72567 * @param {?} plt
72568 * @return {?}
72569 */
72570 isMatch: function (plt) {
72571 return plt.isPlatformMatch('iphone');
72572 }
72573 },
72574 /**
72575 * Windows
72576 */
72577 'windows': {
72578 superset: 'mobile',
72579 subsets: [
72580 'phablet',
72581 'tablet'
72582 ],
72583 settings: {
72584 mode: 'wp',
72585 autoFocusAssist: 'immediate',
72586 hoverCSS: false
72587 },
72588 /**
72589 * @param {?} plt
72590 * @return {?}
72591 */
72592 isMatch: function (plt) {
72593 return plt.isPlatformMatch('windows', ['windows phone']);
72594 },
72595 /**
72596 * @param {?} plt
72597 * @return {?}
72598 */
72599 versionParser: function (plt) {
72600 return plt.matchUserAgentVersion(/Windows Phone (\d+).(\d+)?/);
72601 }
72602 },
72603 /**
72604 * cordova
72605 */
72606 'cordova': {
72607 isEngine: true,
72608 initialize: function (plt) {
72609 // prepare a custom "ready" for cordova "deviceready"
72610 plt.prepareReady = function () {
72611 // 1) ionic bootstrapped
72612 plt.windowLoad(function (win, doc) {
72613 // 2) window onload triggered or completed
72614 doc.addEventListener('deviceready', function () {
72615 // 3) cordova deviceready event triggered
72616 // add cordova listeners to emit platform events
72617 doc.addEventListener('backbutton', function (ev) {
72618 plt.zone.run(function () {
72619 plt.backButton.emit(ev);
72620 });
72621 });
72622 doc.addEventListener('pause', function (ev) {
72623 plt.zone.run(function () {
72624 plt.pause.emit(ev);
72625 });
72626 });
72627 doc.addEventListener('resume', function (ev) {
72628 plt.zone.run(function () {
72629 plt.resume.emit(ev);
72630 });
72631 });
72632 // cordova has its own exitApp method
72633 plt.exitApp = function () {
72634 ((win))['navigator']['app'].exitApp();
72635 };
72636 // cordova has fully loaded and we've added listeners
72637 plt.triggerReady('cordova');
72638 });
72639 });
72640 };
72641 },
72642 /**
72643 * @param {?} plt
72644 * @return {?}
72645 */
72646 isMatch: function (plt) {
72647 return isCordova(plt);
72648 }
72649 },
72650 /**
72651 * electron
72652 */
72653 'electron': {
72654 superset: 'core',
72655 initialize: function (plt) {
72656 plt.prepareReady = function () {
72657 // 1) ionic bootstrapped
72658 plt.windowLoad(function () {
72659 plt.triggerReady('electron');
72660 });
72661 };
72662 },
72663 /**
72664 * @param {?} plt
72665 * @return {?}
72666 */
72667 isMatch: function (plt) {
72668 return isElectron(plt);
72669 }
72670 }
72671};
72672/**
72673 * @param {?} plt
72674 * @return {?}
72675 */
72676function keyboardResizes(plt) {
72677 var /** @type {?} */ win = (plt.win());
72678 if (win.Ionic && win.Ionic.keyboardResizes === true) {
72679 return true;
72680 }
72681 return false;
72682}
72683var PlatformConfigToken = new OpaqueToken('PLTCONFIG');
72684/**
72685 * @return {?}
72686 */
72687function providePlatformConfigs() {
72688 return PLATFORM_CONFIGS;
72689}
72690
72691var MODE_IOS = {
72692 activator: 'highlight',
72693 actionSheetEnter: 'action-sheet-slide-in',
72694 actionSheetLeave: 'action-sheet-slide-out',
72695 alertEnter: 'alert-pop-in',
72696 alertLeave: 'alert-pop-out',
72697 backButtonText: 'Back',
72698 backButtonIcon: 'ios-arrow-back',
72699 iconMode: 'ios',
72700 loadingEnter: 'loading-pop-in',
72701 loadingLeave: 'loading-pop-out',
72702 menuType: 'reveal',
72703 modalEnter: 'modal-slide-in',
72704 modalLeave: 'modal-slide-out',
72705 pageTransition: 'ios-transition',
72706 pickerEnter: 'picker-slide-in',
72707 pickerLeave: 'picker-slide-out',
72708 pickerRotateFactor: -0.46,
72709 pickerScaleFactor: 1,
72710 popoverEnter: 'popover-pop-in',
72711 popoverLeave: 'popover-pop-out',
72712 spinner: 'ios',
72713 tabsHighlight: false,
72714 tabsPlacement: 'bottom',
72715 tabsHideOnSubPages: false,
72716 toastEnter: 'toast-slide-in',
72717 toastLeave: 'toast-slide-out',
72718};
72719var MODE_MD = {
72720 activator: 'ripple',
72721 actionSheetEnter: 'action-sheet-md-slide-in',
72722 actionSheetLeave: 'action-sheet-md-slide-out',
72723 alertEnter: 'alert-md-pop-in',
72724 alertLeave: 'alert-md-pop-out',
72725 backButtonText: '',
72726 backButtonIcon: 'md-arrow-back',
72727 iconMode: 'md',
72728 loadingEnter: 'loading-md-pop-in',
72729 loadingLeave: 'loading-md-pop-out',
72730 menuType: 'overlay',
72731 modalEnter: 'modal-md-slide-in',
72732 modalLeave: 'modal-md-slide-out',
72733 pageTransition: 'md-transition',
72734 pickerEnter: 'picker-slide-in',
72735 pickerLeave: 'picker-slide-out',
72736 pickerRotateFactor: 0,
72737 pickerScaleFactor: 0.81,
72738 popoverEnter: 'popover-md-pop-in',
72739 popoverLeave: 'popover-md-pop-out',
72740 spinner: 'crescent',
72741 tabsHighlight: false,
72742 tabsPlacement: 'bottom',
72743 tabsHideOnSubPages: false,
72744 toastEnter: 'toast-md-slide-in',
72745 toastLeave: 'toast-md-slide-out',
72746};
72747var MODE_WP = {
72748 activator: 'highlight',
72749 actionSheetEnter: 'action-sheet-wp-slide-in',
72750 actionSheetLeave: 'action-sheet-wp-slide-out',
72751 alertEnter: 'alert-wp-pop-in',
72752 alertLeave: 'alert-wp-pop-out',
72753 backButtonText: '',
72754 backButtonIcon: 'ios-arrow-back',
72755 iconMode: 'ios',
72756 loadingEnter: 'loading-wp-pop-in',
72757 loadingLeave: 'loading-wp-pop-out',
72758 menuType: 'overlay',
72759 modalEnter: 'modal-md-slide-in',
72760 modalLeave: 'modal-md-slide-out',
72761 pageTransition: 'wp-transition',
72762 pickerEnter: 'picker-slide-in',
72763 pickerLeave: 'picker-slide-out',
72764 pickerRotateFactor: 0,
72765 pickerScaleFactor: 0.81,
72766 popoverEnter: 'popover-md-pop-in',
72767 popoverLeave: 'popover-md-pop-out',
72768 spinner: 'circles',
72769 tabsHighlight: false,
72770 tabsPlacement: 'top',
72771 tabsHideOnSubPages: true,
72772 toastEnter: 'toast-wp-slide-in',
72773 toastLeave: 'toast-wp-slide-out',
72774};
72775/**
72776 * @param {?} config
72777 * @return {?}
72778 */
72779function registerModeConfigs(config) {
72780 return function () {
72781 // iOS Mode Settings
72782 config.setModeConfig('ios', MODE_IOS);
72783 // Material Design Mode Settings
72784 config.setModeConfig('md', MODE_MD);
72785 // Windows Mode Settings
72786 config.setModeConfig('wp', MODE_WP);
72787 };
72788}
72789
72790var __extends$92 = (undefined && undefined.__extends) || (function () {
72791 var extendStatics = Object.setPrototypeOf ||
72792 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
72793 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
72794 return function (d, b) {
72795 extendStatics(d, b);
72796 function __() { this.constructor = d; }
72797 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
72798 };
72799})();
72800/**
72801 * @hidden
72802 * This class overrides the default Angular gesture config.
72803 */
72804var IonicGestureConfig = (function (_super) {
72805 __extends$92(IonicGestureConfig, _super);
72806 function IonicGestureConfig() {
72807 return _super !== null && _super.apply(this, arguments) || this;
72808 }
72809 /**
72810 * @param {?} element
72811 * @return {?}
72812 */
72813 IonicGestureConfig.prototype.buildHammer = function (element) {
72814 var /** @type {?} */ mc = new ((window)).Hammer(element);
72815 for (var /** @type {?} */ eventName in this.overrides) {
72816 mc.get(eventName).set(this.overrides[eventName]);
72817 }
72818 return mc;
72819 };
72820 return IonicGestureConfig;
72821}(HammerGestureConfig));
72822IonicGestureConfig.decorators = [
72823 { type: Injectable },
72824];
72825/**
72826 * @nocollapse
72827 */
72828IonicGestureConfig.ctorParameters = function () { return []; };
72829
72830/**
72831 * @hidden
72832 */
72833var ClickBlock = (function () {
72834 /**
72835 * @param {?} app
72836 * @param {?} config
72837 * @param {?} plt
72838 * @param {?} elementRef
72839 * @param {?} renderer
72840 */
72841 function ClickBlock(app, config, plt, elementRef, renderer) {
72842 this.plt = plt;
72843 this.elementRef = elementRef;
72844 this.renderer = renderer;
72845 this._showing = false;
72846 app._clickBlock = this;
72847 var enabled = this.isEnabled = config.getBoolean('clickBlock', true);
72848 if (enabled) {
72849 this._setElementClass('click-block-enabled', true);
72850 }
72851 }
72852 /**
72853 * @param {?} shouldShow
72854 * @param {?=} expire
72855 * @param {?=} minDuration
72856 * @return {?}
72857 */
72858 ClickBlock.prototype.activate = function (shouldShow, expire, minDuration) {
72859 if (expire === void 0) { expire = 100; }
72860 if (minDuration === void 0) { minDuration = 0; }
72861 if (this.isEnabled) {
72862 this.plt.cancelTimeout(this._tmr);
72863 if (shouldShow) {
72864 // remember when we started the click block
72865 this._start = Date.now();
72866 // figure out the minimum time it should be showing until
72867 // this is useful for transitions that are less than 300ms
72868 this._minEnd = this._start + (minDuration || 0);
72869 this._activate(true);
72870 }
72871 this._tmr = this.plt.timeout(this._activate.bind(this, false), expire);
72872 }
72873 };
72874 /**
72875 * \@internal
72876 * @param {?} shouldShow
72877 * @return {?}
72878 */
72879 ClickBlock.prototype._activate = function (shouldShow) {
72880 if (this._showing !== shouldShow) {
72881 if (!shouldShow) {
72882 // check if it was enabled before the minimum duration
72883 // this is useful for transitions that are less than 300ms
72884 var /** @type {?} */ now = Date.now();
72885 if (now < this._minEnd) {
72886 this._tmr = this.plt.timeout(this._activate.bind(this, false), this._minEnd - now);
72887 return;
72888 }
72889 }
72890 this._setElementClass('click-block-active', shouldShow);
72891 this._showing = shouldShow;
72892 }
72893 };
72894 /**
72895 * @param {?} className
72896 * @param {?} add
72897 * @return {?}
72898 */
72899 ClickBlock.prototype._setElementClass = function (className, add) {
72900 this.renderer.setElementClass(this.elementRef.nativeElement, className, add);
72901 };
72902 return ClickBlock;
72903}());
72904ClickBlock.decorators = [
72905 { type: Directive, args: [{
72906 selector: '.click-block'
72907 },] },
72908];
72909/**
72910 * @nocollapse
72911 */
72912ClickBlock.ctorParameters = function () { return [
72913 { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
72914 { type: Config, },
72915 { type: Platform, },
72916 { type: ElementRef, },
72917 { type: Renderer, },
72918]; };
72919
72920/**
72921 * Import Angular
72922 */
72923/**
72924 * Global Providers
72925 */
72926/**
72927 * Import Components/Directives/Etc
72928 */
72929/**
72930 * \@name IonicModule
72931 * \@description
72932 * IonicModule is an [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html) that bootstraps
72933 * an Ionic App. By passing a root component, IonicModule will make sure that all of the components,
72934 * directives, and providers from the framework are imported.
72935 *
72936 * Any configuration for the app can be passed as the second argument to `forRoot`. This can be any
72937 * valid property from the [Config](/docs/api/config/Config/).
72938 *
72939 * \@usage
72940 * ```ts
72941 * import { NgModule } from '\@angular/core';
72942 *
72943 * import { IonicApp, IonicModule } from 'ionic-angular';
72944 *
72945 * import { MyApp } from './app.component';
72946 * import { HomePage } from '../pages/home/home';
72947 *
72948 * \@NgModule({
72949 * declarations: [
72950 * MyApp,
72951 * HomePage
72952 * ],
72953 * imports: [
72954 * BrowserModule,
72955 * IonicModule.forRoot(MyApp, {
72956 *
72957 * })
72958 * ],
72959 * bootstrap: [IonicApp],
72960 * entryComponents: [
72961 * MyApp,
72962 * HomePage
72963 * ],
72964 * providers: []
72965 * })
72966 * export class AppModule {}
72967 * ```
72968 */
72969var IonicModule = (function () {
72970 function IonicModule() {
72971 }
72972 /**
72973 * Set the root app component for you IonicModule
72974 * @param {?} appRoot
72975 * @param {?=} config
72976 * @param {?=} deepLinkConfig
72977 * @return {?}
72978 */
72979 IonicModule.forRoot = function (appRoot, config, deepLinkConfig) {
72980 if (config === void 0) { config = null; }
72981 if (deepLinkConfig === void 0) { deepLinkConfig = null; }
72982 return {
72983 ngModule: IonicModule,
72984 providers: [
72985 // useValue: bootstrap values
72986 { provide: AppRootToken, useValue: appRoot },
72987 { provide: ConfigToken, useValue: config },
72988 { provide: DeepLinkConfigToken, useValue: deepLinkConfig },
72989 { provide: APP_BASE_HREF, useValue: '/' },
72990 // useFactory: user values
72991 { provide: PlatformConfigToken, useFactory: providePlatformConfigs },
72992 // useFactory: ionic core providers
72993 { provide: Platform, useFactory: setupPlatform, deps: [DOCUMENT$1, PlatformConfigToken, NgZone] },
72994 { provide: Config, useFactory: setupConfig, deps: [ConfigToken, Platform] },
72995 // useFactory: ionic app initializers
72996 { provide: APP_INITIALIZER, useFactory: registerModeConfigs, deps: [Config], multi: true },
72997 { provide: APP_INITIALIZER, useFactory: setupProvideEvents, deps: [Platform, DomController], multi: true },
72998 { provide: APP_INITIALIZER, useFactory: setupTapClick, deps: [Config, Platform, DomController, App, GestureController], multi: true },
72999 { provide: APP_INITIALIZER, useFactory: setupPreloading, deps: [Config, DeepLinkConfigToken, ModuleLoader, NgZone], multi: true },
73000 // useClass
73001 { provide: HAMMER_GESTURE_CONFIG, useClass: IonicGestureConfig },
73002 // useValue
73003 { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: appRoot, multi: true },
73004 // ionic providers
73005 ActionSheetController,
73006 AlertController,
73007 App,
73008 DomController,
73009 Events,
73010 Form,
73011 GestureController,
73012 Haptic,
73013 Keyboard,
73014 LoadingController,
73015 Location,
73016 MenuController,
73017 ModalController,
73018 NgModuleLoader,
73019 PickerController,
73020 PopoverController,
73021 TapClick,
73022 ToastController,
73023 TransitionController,
73024 { provide: ModuleLoader, useFactory: provideModuleLoader, deps: [NgModuleLoader, Injector] },
73025 { provide: LocationStrategy, useFactory: provideLocationStrategy, deps: [PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], Config] },
73026 { provide: UrlSerializer, useFactory: setupUrlSerializer, deps: [App, DeepLinkConfigToken] },
73027 { provide: DeepLinker, useFactory: setupDeepLinker, deps: [App, UrlSerializer, Location, ModuleLoader, ComponentFactoryResolver] },
73028 ]
73029 };
73030 };
73031 return IonicModule;
73032}());
73033IonicModule.decorators = [
73034 { type: NgModule, args: [{
73035 declarations: [
73036 ActionSheetCmp,
73037 AlertCmp,
73038 ClickBlock,
73039 IonicApp,
73040 OverlayPortal,
73041 Avatar,
73042 Backdrop,
73043 Badge,
73044 Button,
73045 Card,
73046 CardContent,
73047 CardHeader,
73048 CardTitle,
73049 Checkbox,
73050 Chip,
73051 Col,
73052 Content,
73053 DateTime,
73054 FabButton,
73055 FabContainer,
73056 FabList,
73057 Grid,
73058 Img,
73059 Icon,
73060 InfiniteScroll,
73061 InfiniteScrollContent,
73062 Item,
73063 ItemContent,
73064 ItemDivider,
73065 ItemGroup,
73066 ItemOptions,
73067 ItemReorder,
73068 ItemSliding,
73069 Label,
73070 List,
73071 ListHeader,
73072 Reorder,
73073 LoadingCmp,
73074 Menu,
73075 MenuClose,
73076 MenuToggle,
73077 ModalCmp,
73078 Nav,
73079 NavPop,
73080 NavPopAnchor,
73081 NavPush,
73082 NavPushAnchor,
73083 Note,
73084 Option,
73085 PickerCmp,
73086 PickerColumnCmp,
73087 PopoverCmp,
73088 RadioButton,
73089 RadioGroup,
73090 Range,
73091 RangeKnob,
73092 Refresher,
73093 RefresherContent,
73094 Row,
73095 Scroll,
73096 Searchbar,
73097 Segment,
73098 SegmentButton,
73099 Select,
73100 SelectPopover,
73101 ShowWhen,
73102 HideWhen,
73103 Slide,
73104 Slides,
73105 Spinner,
73106 SplitPane,
73107 Tab,
73108 TabButton,
73109 TabHighlight,
73110 Tabs,
73111 TextInput,
73112 Thumbnail,
73113 ToastCmp,
73114 Toggle,
73115 Footer,
73116 Header,
73117 Toolbar,
73118 ToolbarItem,
73119 ToolbarTitle,
73120 Navbar,
73121 Typography,
73122 VirtualFooter,
73123 VirtualHeader,
73124 VirtualItem,
73125 VirtualScroll
73126 ],
73127 imports: [
73128 CommonModule,
73129 FormsModule,
73130 ReactiveFormsModule,
73131 ],
73132 exports: [
73133 CommonModule,
73134 FormsModule,
73135 ReactiveFormsModule,
73136 ActionSheetCmp,
73137 AlertCmp,
73138 ClickBlock,
73139 IonicApp,
73140 OverlayPortal,
73141 Avatar,
73142 Backdrop,
73143 Badge,
73144 Button,
73145 Card,
73146 CardContent,
73147 CardHeader,
73148 CardTitle,
73149 Checkbox,
73150 Chip,
73151 Col,
73152 Content,
73153 DateTime,
73154 FabButton,
73155 FabContainer,
73156 FabList,
73157 Grid,
73158 Img,
73159 Icon,
73160 InfiniteScroll,
73161 InfiniteScrollContent,
73162 Item,
73163 ItemContent,
73164 ItemDivider,
73165 ItemGroup,
73166 ItemOptions,
73167 ItemReorder,
73168 ItemSliding,
73169 Label,
73170 List,
73171 ListHeader,
73172 Reorder,
73173 LoadingCmp,
73174 Menu,
73175 MenuClose,
73176 MenuToggle,
73177 ModalCmp,
73178 Nav,
73179 NavPop,
73180 NavPopAnchor,
73181 NavPush,
73182 NavPushAnchor,
73183 Note,
73184 Option,
73185 PickerCmp,
73186 PickerColumnCmp,
73187 PopoverCmp,
73188 RadioButton,
73189 RadioGroup,
73190 Range,
73191 RangeKnob,
73192 Refresher,
73193 RefresherContent,
73194 Row,
73195 Scroll,
73196 Searchbar,
73197 Segment,
73198 SegmentButton,
73199 Select,
73200 SelectPopover,
73201 ShowWhen,
73202 HideWhen,
73203 Slide,
73204 Slides,
73205 Spinner,
73206 SplitPane,
73207 Tab,
73208 TabButton,
73209 TabHighlight,
73210 Tabs,
73211 TextInput,
73212 Thumbnail,
73213 ToastCmp,
73214 Toggle,
73215 Footer,
73216 Header,
73217 Toolbar,
73218 ToolbarItem,
73219 ToolbarTitle,
73220 Navbar,
73221 Typography,
73222 VirtualFooter,
73223 VirtualHeader,
73224 VirtualItem,
73225 VirtualScroll
73226 ],
73227 entryComponents: [
73228 ActionSheetCmp,
73229 AlertCmp,
73230 IonicApp,
73231 LoadingCmp,
73232 ModalCmp,
73233 PickerCmp,
73234 PopoverCmp,
73235 SelectPopover,
73236 ToastCmp
73237 ]
73238 },] },
73239];
73240/**
73241 * @nocollapse
73242 */
73243IonicModule.ctorParameters = function () { return []; };
73244/**
73245 * \@name IonicPageModule
73246 * \@description
73247 * IonicPageModule is an [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html) that
73248 * bootstraps a child [IonicPage](../navigation/IonicPage/) in order to set up routing.
73249 *
73250 * \@usage
73251 * ```ts
73252 * import { NgModule } from '\@angular/core';
73253 *
73254 * import { IonicPageModule } from 'ionic-angular';
73255 *
73256 * import { HomePage } from './home';
73257 *
73258 * \@NgModule({
73259 * declarations: [
73260 * HomePage
73261 * ],
73262 * imports: [
73263 * IonicPageModule.forChild(HomePage)
73264 * ],
73265 * entryComponents: [
73266 * HomePage
73267 * ]
73268 * })
73269 * export class HomePageModule { }
73270 * ```
73271 */
73272var IonicPageModule = (function () {
73273 function IonicPageModule() {
73274 }
73275 /**
73276 * @param {?} page
73277 * @return {?}
73278 */
73279 IonicPageModule.forChild = function (page) {
73280 return {
73281 ngModule: IonicPageModule,
73282 providers: [
73283 { provide: /** @type {?} */ (LAZY_LOADED_TOKEN), useValue: page },
73284 { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: page, multi: true },
73285 ]
73286 };
73287 };
73288 return IonicPageModule;
73289}());
73290IonicPageModule.decorators = [
73291 { type: NgModule, args: [{
73292 imports: [IonicModule],
73293 exports: [IonicModule]
73294 },] },
73295];
73296/**
73297 * @nocollapse
73298 */
73299IonicPageModule.ctorParameters = function () { return []; };
73300/**
73301 * @hidden
73302 * @param {?} platformLocationStrategy
73303 * @param {?} baseHref
73304 * @param {?} config
73305 * @return {?}
73306 */
73307function provideLocationStrategy(platformLocationStrategy, baseHref, config) {
73308 return config.get('locationStrategy') === 'path' ?
73309 new PathLocationStrategy(platformLocationStrategy, baseHref) :
73310 new HashLocationStrategy(platformLocationStrategy, baseHref);
73311}
73312
73313exports.IonicApp = IonicApp;
73314exports.MenuController = MenuController;
73315exports.ActionSheet = ActionSheet;
73316exports.ActionSheetController = ActionSheetController;
73317exports.ActionSheetCmp = ActionSheetCmp;
73318exports.Alert = Alert;
73319exports.AlertController = AlertController;
73320exports.AlertCmp = AlertCmp;
73321exports.App = App;
73322exports.Avatar = Avatar;
73323exports.Backdrop = Backdrop;
73324exports.Badge = Badge;
73325exports.Button = Button;
73326exports.Card = Card;
73327exports.CardContent = CardContent;
73328exports.CardHeader = CardHeader;
73329exports.CardTitle = CardTitle;
73330exports.Checkbox = Checkbox;
73331exports.Chip = Chip;
73332exports.Content = Content;
73333exports.DateTime = DateTime;
73334exports.FabButton = FabButton;
73335exports.FabContainer = FabContainer;
73336exports.FabList = FabList;
73337exports.Col = Col;
73338exports.Grid = Grid;
73339exports.Row = Row;
73340exports.Ion = Ion;
73341exports.Icon = Icon;
73342exports.Img = Img;
73343exports.InfiniteScroll = InfiniteScroll;
73344exports.InfiniteScrollContent = InfiniteScrollContent;
73345exports.TextInput = TextInput;
73346exports.Item = Item;
73347exports.ItemContent = ItemContent;
73348exports.ItemDivider = ItemDivider;
73349exports.ItemGroup = ItemGroup;
73350exports.ItemOptions = ItemOptions;
73351exports.ItemReorder = ItemReorder;
73352exports.ItemSliding = ItemSliding;
73353exports.Reorder = Reorder;
73354exports.Label = Label;
73355exports.List = List;
73356exports.ListHeader = ListHeader;
73357exports.Loading = Loading;
73358exports.LoadingController = LoadingController;
73359exports.LoadingCmp = LoadingCmp;
73360exports.Menu = Menu;
73361exports.MenuClose = MenuClose;
73362exports.MenuToggle = MenuToggle;
73363exports.MenuType = MenuType;
73364exports.Modal = Modal;
73365exports.ModalCmp = ModalCmp;
73366exports.ModalController = ModalController;
73367exports.Nav = Nav;
73368exports.NavPop = NavPop;
73369exports.NavPopAnchor = NavPopAnchor;
73370exports.NavPush = NavPush;
73371exports.NavPushAnchor = NavPushAnchor;
73372exports.Note = Note;
73373exports.Option = Option;
73374exports.Picker = Picker;
73375exports.PickerCmp = PickerCmp;
73376exports.PickerColumnCmp = PickerColumnCmp;
73377exports.PickerController = PickerController;
73378exports.Popover = Popover;
73379exports.PopoverCmp = PopoverCmp;
73380exports.PopoverController = PopoverController;
73381exports.RadioButton = RadioButton;
73382exports.RadioGroup = RadioGroup;
73383exports.Range = Range;
73384exports.RangeKnob = RangeKnob;
73385exports.Refresher = Refresher;
73386exports.RefresherContent = RefresherContent;
73387exports.Scroll = Scroll;
73388exports.Searchbar = Searchbar;
73389exports.Segment = Segment;
73390exports.SegmentButton = SegmentButton;
73391exports.Select = Select;
73392exports.SelectPopover = SelectPopover;
73393exports.ShowWhen = ShowWhen;
73394exports.DisplayWhen = DisplayWhen;
73395exports.HideWhen = HideWhen;
73396exports.Slide = Slide;
73397exports.Slides = Slides;
73398exports.Spinner = Spinner;
73399exports.SplitPane = SplitPane;
73400exports.RootNode = RootNode;
73401exports.Tab = Tab;
73402exports.TabButton = TabButton;
73403exports.TabHighlight = TabHighlight;
73404exports.Tabs = Tabs;
73405exports.Toast = Toast;
73406exports.ToastCmp = ToastCmp;
73407exports.ToastController = ToastController;
73408exports.Toggle = Toggle;
73409exports.Footer = Footer;
73410exports.Header = Header;
73411exports.Toolbar = Toolbar;
73412exports.ToolbarItem = ToolbarItem;
73413exports.ToolbarTitle = ToolbarTitle;
73414exports.Navbar = Navbar;
73415exports.Thumbnail = Thumbnail;
73416exports.Typography = Typography;
73417exports.VirtualFooter = VirtualFooter;
73418exports.VirtualHeader = VirtualHeader;
73419exports.VirtualItem = VirtualItem;
73420exports.VirtualScroll = VirtualScroll;
73421exports.Config = Config;
73422exports.setupConfig = setupConfig;
73423exports.ConfigToken = ConfigToken;
73424exports.DomController = DomController;
73425exports.Platform = Platform;
73426exports.setupPlatform = setupPlatform;
73427exports.Haptic = Haptic;
73428exports.DeepLinker = DeepLinker;
73429exports.IonicPage = IonicPage;
73430exports.NavController = NavController;
73431exports.NavControllerBase = NavControllerBase;
73432exports.NavParams = NavParams;
73433exports.DeepLinkMetadata = DeepLinkMetadata;
73434exports.DeepLinkMetadataFactory = DeepLinkMetadataFactory;
73435exports.TapClick = TapClick;
73436exports.setupTapClick = setupTapClick;
73437exports.isActivatable = isActivatable;
73438exports.UrlSerializer = UrlSerializer;
73439exports.DeepLinkConfigToken = DeepLinkConfigToken;
73440exports.ViewController = ViewController;
73441exports.PanGesture = PanGesture;
73442exports.Gesture = Gesture;
73443exports.SlideEdgeGesture = SlideEdgeGesture;
73444exports.SlideGesture = SlideGesture;
73445exports.BLOCK_ALL = BLOCK_ALL;
73446exports.GESTURE_GO_BACK_SWIPE = GESTURE_GO_BACK_SWIPE;
73447exports.GESTURE_MENU_SWIPE = GESTURE_MENU_SWIPE;
73448exports.GESTURE_ITEM_SWIPE = GESTURE_ITEM_SWIPE;
73449exports.GESTURE_REFRESHER = GESTURE_REFRESHER;
73450exports.GESTURE_TOGGLE = GESTURE_TOGGLE;
73451exports.GestureController = GestureController;
73452exports.GestureDelegate = GestureDelegate;
73453exports.BlockerDelegate = BlockerDelegate;
73454exports.Events = Events;
73455exports.setupEvents = setupEvents;
73456exports.setupProvideEvents = setupProvideEvents;
73457exports.IonicErrorHandler = IonicErrorHandler;
73458exports.Keyboard = Keyboard;
73459exports.Form = Form;
73460exports.IonicFormInput = IonicFormInput;
73461exports.IonicTapInput = IonicTapInput;
73462exports.reorderArray = reorderArray;
73463exports.normalizeURL = normalizeURL;
73464exports.Animation = Animation;
73465exports.PageTransition = PageTransition;
73466exports.Transition = Transition;
73467exports.PlatformConfigToken = PlatformConfigToken;
73468exports.registerModeConfigs = registerModeConfigs;
73469exports.IonicGestureConfig = IonicGestureConfig;
73470exports.IonicModule = IonicModule;
73471exports.IonicPageModule = IonicPageModule;
73472exports.provideLocationStrategy = provideLocationStrategy;
73473
73474Object.defineProperty(exports, '__esModule', { value: true });
73475
73476})));