UNPKG

@angular/common

Version:

Angular - commonly needed directives and services

154 lines 19.6 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { ChangeDetectorRef, Pipe, untracked, ɵisPromise, ɵisSubscribable, } from '@angular/core'; import { invalidPipeArgumentError } from './invalid_pipe_argument_error'; import * as i0 from "@angular/core"; class SubscribableStrategy { createSubscription(async, updateLatestValue) { // Subscription can be side-effectful, and we don't want any signal reads which happen in the // side effect of the subscription to be tracked by a component's template when that // subscription is triggered via the async pipe. So we wrap the subscription in `untracked` to // decouple from the current reactive context. // // `untracked` also prevents signal _writes_ which happen in the subscription side effect from // being treated as signal writes during the template evaluation (which throws errors). return untracked(() => async.subscribe({ next: updateLatestValue, error: (e) => { throw e; }, })); } dispose(subscription) { // See the comment in `createSubscription` above on the use of `untracked`. untracked(() => subscription.unsubscribe()); } } class PromiseStrategy { createSubscription(async, updateLatestValue) { return async.then(updateLatestValue, (e) => { throw e; }); } dispose(subscription) { } } const _promiseStrategy = new PromiseStrategy(); const _subscribableStrategy = new SubscribableStrategy(); /** * @ngModule CommonModule * @description * * Unwraps a value from an asynchronous primitive. * * The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has * emitted. When a new value is emitted, the `async` pipe marks the component to be checked for * changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid * potential memory leaks. When the reference of the expression changes, the `async` pipe * automatically unsubscribes from the old `Observable` or `Promise` and subscribes to the new one. * * @usageNotes * * ### Examples * * This example binds a `Promise` to the view. Clicking the `Resolve` button resolves the * promise. * * {@example common/pipes/ts/async_pipe.ts region='AsyncPipePromise'} * * It's also possible to use `async` with Observables. The example below binds the `time` Observable * to the view. The Observable continuously updates the view with the current time. * * {@example common/pipes/ts/async_pipe.ts region='AsyncPipeObservable'} * * @publicApi */ export class AsyncPipe { constructor(ref) { this._latestValue = null; this.markForCheckOnValueUpdate = true; this._subscription = null; this._obj = null; this._strategy = null; // Assign `ref` into `this._ref` manually instead of declaring `_ref` in the constructor // parameter list, as the type of `this._ref` includes `null` unlike the type of `ref`. this._ref = ref; } ngOnDestroy() { if (this._subscription) { this._dispose(); } // Clear the `ChangeDetectorRef` and its association with the view data, to mitigate // potential memory leaks in Observables that could otherwise cause the view data to // be retained. // https://github.com/angular/angular/issues/17624 this._ref = null; } transform(obj) { if (!this._obj) { if (obj) { try { // Only call `markForCheck` if the value is updated asynchronously. // Synchronous updates _during_ subscription should not wastefully mark for check - // this value is already going to be returned from the transform function. this.markForCheckOnValueUpdate = false; this._subscribe(obj); } finally { this.markForCheckOnValueUpdate = true; } } return this._latestValue; } if (obj !== this._obj) { this._dispose(); return this.transform(obj); } return this._latestValue; } _subscribe(obj) { this._obj = obj; this._strategy = this._selectStrategy(obj); this._subscription = this._strategy.createSubscription(obj, (value) => this._updateLatestValue(obj, value)); } _selectStrategy(obj) { if (ɵisPromise(obj)) { return _promiseStrategy; } if (ɵisSubscribable(obj)) { return _subscribableStrategy; } throw invalidPipeArgumentError(AsyncPipe, obj); } _dispose() { // Note: `dispose` is only called if a subscription has been initialized before, indicating // that `this._strategy` is also available. this._strategy.dispose(this._subscription); this._latestValue = null; this._subscription = null; this._obj = null; } _updateLatestValue(async, value) { if (async === this._obj) { this._latestValue = value; if (this.markForCheckOnValueUpdate) { this._ref?.markForCheck(); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: AsyncPipe, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.9", ngImport: i0, type: AsyncPipe, isStandalone: true, name: "async", pure: false }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: AsyncPipe, decorators: [{ type: Pipe, args: [{ name: 'async', pure: false, standalone: true, }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmNfcGlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvcGlwZXMvYXN5bmNfcGlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQ0wsaUJBQWlCLEVBR2pCLElBQUksRUFFSixTQUFTLEVBQ1QsVUFBVSxFQUNWLGVBQWUsR0FDaEIsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sK0JBQStCLENBQUM7O0FBVXZFLE1BQU0sb0JBQW9CO0lBQ3hCLGtCQUFrQixDQUFDLEtBQXdCLEVBQUUsaUJBQXNCO1FBQ2pFLDZGQUE2RjtRQUM3RixvRkFBb0Y7UUFDcEYsOEZBQThGO1FBQzlGLDhDQUE4QztRQUM5QyxFQUFFO1FBQ0YsOEZBQThGO1FBQzlGLHVGQUF1RjtRQUN2RixPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FDcEIsS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUNkLElBQUksRUFBRSxpQkFBaUI7WUFDdkIsS0FBSyxFQUFFLENBQUMsQ0FBTSxFQUFFLEVBQUU7Z0JBQ2hCLE1BQU0sQ0FBQyxDQUFDO1lBQ1YsQ0FBQztTQUNGLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sQ0FBQyxZQUE0QjtRQUNsQywyRUFBMkU7UUFDM0UsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7Q0FDRjtBQUVELE1BQU0sZUFBZTtJQUNuQixrQkFBa0IsQ0FBQyxLQUFtQixFQUFFLGlCQUFrQztRQUN4RSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUN6QyxNQUFNLENBQUMsQ0FBQztRQUNWLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8s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RyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVPLGtCQUFrQixDQUFDLEtBQVUsRUFBRSxLQUFhO1FBQ2xELElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUMxQixJQUFJLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzt5SEEvRlUsU0FBUzt1SEFBVCxTQUFTOztzR0FBVCxTQUFTO2tCQUxyQixJQUFJO21CQUFDO29CQUNKLElBQUksRUFBRSxPQUFPO29CQUNiLElBQUksRUFBRSxLQUFLO29CQUNYLFVBQVUsRUFBRSxJQUFJO2lCQUNqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBPbkRlc3Ryb3ksXG4gIFBpcGUsXG4gIFBpcGVUcmFuc2Zvcm0sXG4gIHVudHJhY2tlZCxcbiAgybVpc1Byb21pc2UsXG4gIMm1aXNTdWJzY3JpYmFibGUsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpYmFibGUsIFVuc3Vic2NyaWJhYmxlfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3J9IGZyb20gJy4vaW52YWxpZF9waXBlX2FyZ3VtZW50X2Vycm9yJztcblxuaW50ZXJmYWNlIFN1YnNjcmlwdGlvblN0cmF0ZWd5IHtcbiAgY3JlYXRlU3Vic2NyaXB0aW9uKFxuICAgIGFzeW5jOiBTdWJzY3JpYmFibGU8YW55PiB8IFByb21pc2U8YW55PixcbiAgICB1cGRhdGVMYXRlc3RWYWx1ZTogYW55LFxuICApOiBVbnN1YnNjcmliYWJsZSB8IFByb21pc2U8YW55PjtcbiAgZGlzcG9zZShzdWJzY3JpcHRpb246IFVuc3Vic2NyaWJhYmxlIHwgUHJvbWlzZTxhbnk+KTogdm9pZDtcbn1cblxuY2xhc3MgU3Vic2NyaWJhYmxlU3RyYXRlZ3kgaW1wbGVtZW50cyBTdWJzY3JpcHRpb25TdHJhdGVneSB7XG4gIGNyZWF0ZVN1YnNjcmlwdGlvbihhc3luYzogU3Vic2NyaWJhYmxlPGFueT4sIHVwZGF0ZUxhdGVzdFZhbHVlOiBhbnkpOiBVbnN1YnNjcmliYWJsZSB7XG4gICAgLy8gU3Vic2NyaXB0aW9uIGNhbiBiZSBzaWRlLWVmZmVjdGZ1bCwgYW5kIHdlIGRvbid0IHdhbnQgYW55IHNpZ25hbCByZWFkcyB3aGljaCBoYXBwZW4gaW4gdGhlXG4gICAgLy8gc2lkZSBlZmZlY3Qgb2YgdGhlIHN1YnNjcmlwdGlvbiB0byBiZSB0cmFja2VkIGJ5IGEgY29tcG9uZW50J3MgdGVtcGxhdGUgd2hlbiB0aGF0XG4gICAgLy8gc3Vic2NyaXB0aW9uIGlzIHRyaWdnZXJlZCB2aWEgdGhlIGFzeW5jIHBpcGUuIFNvIHdlIHdyYXAgdGhlIHN1YnNjcmlwdGlvbiBpbiBgdW50cmFja2VkYCB0b1xuICAgIC8vIGRlY291cGxlIGZyb20gdGhlIGN1cnJlbnQgcmVhY3RpdmUgY29udGV4dC5cbiAgICAvL1xuICAgIC8vIGB1bnRyYWNrZWRgIGFsc28gcHJldmVudHMgc2lnbmFsIF93cml0ZXNfIHdoaWNoIGhhcHBlbiBpbiB0aGUgc3Vic2NyaXB0aW9uIHNpZGUgZWZmZWN0IGZyb21cbiAgICAvLyBiZWluZyB0cmVhdGVkIGFzIHNpZ25hbCB3cml0ZXMgZHVyaW5nIHRoZSB0ZW1wbGF0ZSBldmFsdWF0aW9uICh3aGljaCB0aHJvd3MgZXJyb3JzKS5cbiAgICByZXR1cm4gdW50cmFja2VkKCgpID0+XG4gICAgICBhc3luYy5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiB1cGRhdGVMYXRlc3RWYWx1ZSxcbiAgICAgICAgZXJyb3I6IChlOiBhbnkpID0+IHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIGRpc3Bvc2Uoc3Vic2NyaXB0aW9uOiBVbnN1YnNjcmliYWJsZSk6IHZvaWQge1xuICAgIC8vIFNlZSB0aGUgY29tbWVudCBpbiBgY3JlYXRlU3Vic2NyaXB0aW9uYCBhYm92ZSBvbiB0aGUgdXNlIG9mIGB1bnRyYWNrZWRgLlxuICAgIHVudHJhY2tlZCgoKSA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKSk7XG4gIH1cbn1cblxuY2xhc3MgUHJvbWlzZVN0cmF0ZWd5IGltcGxlbWVudHMgU3Vic2NyaXB0aW9uU3RyYXRlZ3kge1xuICBjcmVhdGVTdWJzY3JpcHRpb24oYXN5bmM6IFByb21pc2U8YW55PiwgdXBkYXRlTGF0ZXN0VmFsdWU6ICh2OiBhbnkpID0+IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIGFzeW5jLnRoZW4odXBkYXRlTGF0ZXN0VmFsdWUsIChlKSA9PiB7XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xuICB9XG5cbiAgZGlzcG9zZShzdWJzY3JpcHRpb246IFByb21pc2U8YW55Pik6IHZvaWQge31cbn1cblxuY29uc3QgX3Byb21pc2VTdHJhdGVneSA9IG5ldyBQcm9taXNlU3RyYXRlZ3koKTtcbmNvbnN0IF9zdWJzY3JpYmFibGVTdHJhdGVneSA9IG5ldyBTdWJzY3JpYmFibGVTdHJhdGVneSgpO1xuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIFVud3JhcHMgYSB2YWx1ZSBmcm9tIGFuIGFzeW5jaHJvbm91cyBwcmltaXRpdmUuXG4gKlxuICogVGhlIGBhc3luY2AgcGlwZSBzdWJzY3JpYmVzIHRvIGFuIGBPYnNlcnZhYmxlYCBvciBgUHJvbWlzZWAgYW5kIHJldHVybnMgdGhlIGxhdGVzdCB2YWx1ZSBpdCBoYXNcbiAqIGVtaXR0ZWQuIFdoZW4gYSBuZXcgdmFsdWUgaXMgZW1pdHRlZCwgdGhlIGBhc3luY2AgcGlwZSBtYXJrcyB0aGUgY29tcG9uZW50IHRvIGJlIGNoZWNrZWQgZm9yXG4gKiBjaGFuZ2VzLiBXaGVuIHRoZSBjb21wb25lbnQgZ2V0cyBkZXN0cm95ZWQsIHRoZSBgYXN5bmNgIHBpcGUgdW5zdWJzY3JpYmVzIGF1dG9tYXRpY2FsbHkgdG8gYXZvaWRcbiAqIHBvdGVudGlhbCBtZW1vcnkgbGVha3MuIFdoZW4gdGhlIHJlZmVyZW5jZSBvZiB0aGUgZXhwcmVzc2lvbiBjaGFuZ2VzLCB0aGUgYGFzeW5jYCBwaXBlXG4gKiBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyBmcm9tIHRoZSBvbGQgYE9ic2VydmFibGVgIG9yIGBQcm9taXNlYCBhbmQgc3Vic2NyaWJlcyB0byB0aGUgbmV3IG9uZS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqICMjIyBFeGFtcGxlc1xuICpcbiAqIFRoaXMgZXhhbXBsZSBiaW5kcyBhIGBQcm9taXNlYCB0byB0aGUgdmlldy4gQ2xpY2tpbmcgdGhlIGBSZXNvbHZlYCBidXR0b24gcmVzb2x2ZXMgdGhlXG4gKiBwcm9taXNlLlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMvYXN5bmNfcGlwZS50cyByZWdpb249J0FzeW5jUGlwZVByb21pc2UnfVxuICpcbiAqIEl0J3MgYWxzbyBwb3NzaWJsZSB0byB1c2UgYGFzeW5jYCB3aXRoIE9ic2VydmFibGVzLiBUaGUgZXhhbXBsZSBiZWxvdyBiaW5kcyB0aGUgYHRpbWVgIE9ic2VydmFibGVcbiAqIHRvIHRoZSB2aWV3LiBUaGUgT2JzZXJ2YWJsZSBjb250aW51b3VzbHkgdXBkYXRlcyB0aGUgdmlldyB3aXRoIHRoZSBjdXJyZW50IHRpbWUuXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9waXBlcy90cy9hc3luY19waXBlLnRzIHJlZ2lvbj0nQXN5bmNQaXBlT2JzZXJ2YWJsZSd9XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5AUGlwZSh7XG4gIG5hbWU6ICdhc3luYycsXG4gIHB1cmU6IGZhbHNlLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBBc3luY1BpcGUgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIFBpcGVUcmFuc2Zvcm0ge1xuICBwcml2YXRlIF9yZWY6IENoYW5nZURldGVjdG9yUmVmIHwgbnVsbDtcbiAgcHJpdmF0ZSBfbGF0ZXN0VmFsdWU6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgbWFya0ZvckNoZWNrT25WYWx1ZVVwZGF0ZSA9IHRydWU7XG5cbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uOiBVbnN1YnNjcmliYWJsZSB8IFByb21pc2U8YW55PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9vYmo6IFN1YnNjcmliYWJsZTxhbnk+IHwgUHJvbWlzZTxhbnk+IHwgRXZlbnRFbWl0dGVyPGFueT4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc3RyYXRlZ3k6IFN1YnNjcmlwdGlvblN0cmF0ZWd5IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIC8vIEFzc2lnbiBgcmVmYCBpbnRvIGB0aGlzLl9yZWZgIG1hbnVhbGx5IGluc3RlYWQgb2YgZGVjbGFyaW5nIGBfcmVmYCBpbiB0aGUgY29uc3RydWN0b3JcbiAgICAvLyBwYXJhbWV0ZXIgbGlzdCwgYXMgdGhlIHR5cGUgb2YgYHRoaXMuX3JlZmAgaW5jbHVkZXMgYG51bGxgIHVubGlrZSB0aGUgdHlwZSBvZiBgcmVmYC5cbiAgICB0aGlzLl9yZWYgPSByZWY7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fc3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9kaXNwb3NlKCk7XG4gICAgfVxuICAgIC8vIENsZWFyIHRoZSBgQ2hhbmdlRGV0ZWN0b3JSZWZgIGFuZCBpdHMgYXNzb2NpYXRpb24gd2l0aCB0aGUgdmlldyBkYXRhLCB0byBtaXRpZ2F0ZVxuICAgIC8vIHBvdGVudGlhbCBtZW1vcnkgbGVha3MgaW4gT2JzZXJ2YWJsZXMgdGhhdCBjb3VsZCBvdGhlcndpc2UgY2F1c2UgdGhlIHZpZXcgZGF0YSB0b1xuICAgIC8vIGJlIHJldGFpbmVkLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzE3NjI0XG4gICAgdGhpcy5fcmVmID0gbnVsbDtcbiAgfVxuXG4gIC8vIE5PVEUoQGJlbmxlc2gpOiBCZWNhdXNlIE9ic2VydmFibGUgaGFzIGRlcHJlY2F0ZWQgYSBmZXcgY2FsbCBwYXR0ZXJucyBmb3IgYHN1YnNjcmliZWAsXG4gIC8vIFR5cGVTY3JpcHQgaGFzIGEgaGFyZCB0aW1lIG1hdGNoaW5nIE9ic2VydmFibGUgdG8gU3Vic2NyaWJhYmxlLCBmb3IgbW9yZSBpbmZvcm1hdGlvblxuICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy80MzY0M1xuXG4gIHRyYW5zZm9ybTxUPihvYmo6IE9ic2VydmFibGU8VD4gfCBTdWJzY3JpYmFibGU8VD4gfCBQcm9taXNlPFQ+KTogVCB8IG51bGw7XG4gIHRyYW5zZm9ybTxUPihvYmo6IG51bGwgfCB1bmRlZmluZWQpOiBudWxsO1xuICB0cmFuc2Zvcm08VD4ob2JqOiBPYnNlcnZhYmxlPFQ+IHwgU3Vic2NyaWJhYmxlPFQ+IHwgUHJvbWlzZTxUPiB8IG51bGwgfCB1bmRlZmluZWQpOiBUIHwgbnVsbDtcbiAgdHJhbnNmb3JtPFQ+KG9iajogT2JzZXJ2YWJsZTxUPiB8IFN1YnNjcmliYWJsZTxUPiB8IFByb21pc2U8VD4gfCBudWxsIHwgdW5kZWZpbmVkKTogVCB8IG51bGwge1xuICAgIGlmICghdGhpcy5fb2JqKSB7XG4gICAgICBpZiAob2JqKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gT25seSBjYWxsIGBtYXJrRm9yQ2hlY2tgIGlmIHRoZSB2YWx1ZSBpcyB1cGRhdGVkIGFzeW5jaHJvbm91c2x5LlxuICAgICAgICAgIC8vIFN5bmNocm9ub3VzIHVwZGF0ZXMgX2R1cmluZ18gc3Vic2NyaXB0aW9uIHNob3VsZCBub3Qgd2FzdGVmdWxseSBtYXJrIGZvciBjaGVjayAtXG4gICAgICAgICAgLy8gdGhpcyB2YWx1ZSBpcyBhbHJlYWR5IGdvaW5nIHRvIGJlIHJldHVybmVkIGZyb20gdGhlIHRyYW5zZm9ybSBmdW5jdGlvbi5cbiAgICAgICAgICB0aGlzLm1hcmtGb3JDaGVja09uVmFsdWVVcGRhdGUgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLl9zdWJzY3JpYmUob2JqKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aGlzLm1hcmtGb3JDaGVja09uVmFsdWVVcGRhdGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fbGF0ZXN0VmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKG9iaiAhPT0gdGhpcy5fb2JqKSB7XG4gICAgICB0aGlzLl9kaXNwb3NlKCk7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0ob2JqKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fbGF0ZXN0VmFsdWU7XG4gIH1cblxuICBwcml2YXRlIF9zdWJzY3JpYmUob2JqOiBTdWJzY3JpYmFibGU8YW55PiB8IFByb21pc2U8YW55PiB8IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5fb2JqID0gb2JqO1xuICAgIHRoaXMuX3N0cmF0ZWd5ID0gdGhpcy5fc2VsZWN0U3RyYXRlZ3kob2JqKTtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSB0aGlzLl9zdHJhdGVneS5jcmVhdGVTdWJzY3JpcHRpb24ob2JqLCAodmFsdWU6IE9iamVjdCkgPT5cbiAgICAgIHRoaXMuX3VwZGF0ZUxhdGVzdFZhbHVlKG9iaiwgdmFsdWUpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9zZWxlY3RTdHJhdGVneShcbiAgICBvYmo6IFN1YnNjcmliYWJsZTxhbnk+IHwgUHJvbWlzZTxhbnk+IHwgRXZlbnRFbWl0dGVyPGFueT4sXG4gICk6IFN1YnNjcmlwdGlvblN0cmF0ZWd5IHtcbiAgICBpZiAoybVpc1Byb21pc2Uob2JqKSkge1xuICAgICAgcmV0dXJuIF9wcm9taXNlU3RyYXRlZ3k7XG4gICAgfVxuXG4gICAgaWYgKMm1aXNTdWJzY3JpYmFibGUob2JqKSkge1xuICAgICAgcmV0dXJuIF9zdWJzY3JpYmFibGVTdHJhdGVneTtcbiAgICB9XG5cbiAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoQXN5bmNQaXBlLCBvYmopO1xuICB9XG5cbiAgcHJpdmF0ZSBfZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAvLyBOb3RlOiBgZGlzcG9zZWAgaXMgb25seSBjYWxsZWQgaWYgYSBzdWJzY3JpcHRpb24gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYmVmb3JlLCBpbmRpY2F0aW5nXG4gICAgLy8gdGhhdCBgdGhpcy5fc3RyYXRlZ3lgIGlzIGFsc28gYXZhaWxhYmxlLlxuICAgIHRoaXMuX3N0cmF0ZWd5IS5kaXNwb3NlKHRoaXMuX3N1YnNjcmlwdGlvbiEpO1xuICAgIHRoaXMuX2xhdGVzdFZhbHVlID0gbnVsbDtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIHRoaXMuX29iaiA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVMYXRlc3RWYWx1ZShhc3luYzogYW55LCB2YWx1ZTogT2JqZWN0KTogdm9pZCB7XG4gICAgaWYgKGFzeW5jID09PSB0aGlzLl9vYmopIHtcbiAgICAgIHRoaXMuX2xhdGVzdFZhbHVlID0gdmFsdWU7XG4gICAgICBpZiAodGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlKSB7XG4gICAgICAgIHRoaXMuX3JlZj8ubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=