@bespunky/angular-zen
Version:
The Angular tools you always wished were there.
154 lines • 21.9 kB
JavaScript
import { Observable } from 'rxjs';
import { Directive, Input } from '@angular/core';
import { OnObserverBaseDirective } from '../abstraction/on-observer-base.directive';
import * as i0 from "@angular/core";
/**
* Documentation in {@link OnObserverActiveDirective.onObserver} to allow in-template tooltips.
*
* @export
* @class OnObserverDirective
* @extends {OnObserverBaseDirective<T>}
* @template T The type of value the observable emits.
*/
export class OnObserverDirective extends OnObserverBaseDirective {
constructor() {
super(...arguments);
this.selector = 'onObserver';
}
/**
* Renders the template when the specified observable makes any of the calls specified using {@link OnObserverDirective.onObserverCalls `calls`}.
*
* ## Features
*
* #### View Context
* Use the microsyntax `as` keyword to assign resolved values to a variable.
* Use the microsyntax `let` keyword to assign the {@link OnObserverContext full context object} to a variable (e.g. `let context`).
*
* #### Delayed rendering
* Specify a value for {@link OnObserverBaseDirective.showAfter `showAfter`} to delay rendering.
*
* #### Auto destroy
* Specify {@link OnObserverBaseDirective.showFor `showFor`} to automatically destroy the view after a certain duration.
*
* #### Countdown updates
* When {@link OnObserverBaseDirective.showFor `showFor`} is specified, the view context will be updated with the time remaining until the view
* is destroyed and the time elapsed since it was rendered. This allows giving the user feedback in a progress bar, a spinner, a textual timer
* or any other UI component.
*
* Remaining is provided by the {@link OnObserverContext.remaining `remaining`} property. Elapsed time is provided by the {@link OnObserverContext.elapsed `elapsed`}
* property. Access it by assigning a variable using `let`, like so:
* `let remaining = remaining`
*
* #### Multi view mode
* Specify {@link OnObserverBaseDirective.viewMode `viewMode = 'multiple'`} to enable rendering a new view for each intercepted call
* instead of updating a single rendered view. This allows stacking logs, notification snackbars, or any other aggregation functionality.
* Combined with {@link OnObserverBaseDirective.showFor `showFor`}, this is great for disappearing messages/notifications.
*
* #### View index
* In multi-view mode, the context will contain the index of the view, which can be used for calculations and styling.
*
* #### Multi call interception
* Create different interception combinations by specifying more than one call name using {@link OnObserverDirective.onObserverCalls `calls`}.
* This is how, for example, the combination of `'error'` and `'complete'` was used to create the `*onObserverFinalized` directive.
*/
set onObserver(value) { this.input.next(value); }
/**
* Defines the calls to intercept from the observable. Only intercepted calls will render the template.
*/
set onObserverCalls(calls) { this.renderOnCallsTo = calls; }
/**
* (Optional) The view mode the directive will operate in:
* `'single'` - A single view will be rendered on intercepted calls. If a view has already been rendered when a call is intercepted,
* the existing view will be updated with data from the new call.
*
* `'multiple'` - Every new intercepted call will render a new view with its own context and data encapsulated from the current call.
*
* Default is `'single'`.
*/
set onObserverViewMode(viewMode) { this.viewMode = viewMode; }
/**
* (Optional) The duration for which the directive should wait before rendering the view once an intercepted call is made.
*
* You can specify a number, which will be treated as milliseconds, or a string with the format of `<number><ms | s | ms>`.
* Numbers can be either integers or floats.
* For example:
* - `3000` - Wait for 3 seconds, then render the view.
* - `'10s'` - Wait for 10 seconds, then render the view.
* - `'0.5m'` - Wait for 30 seconds, then render the view.
* - `'100ms'` - Wait for 100 milliseconds, then render the view.
*
* Default is `0`, meaning immediately render the view.
*
* TODO: ADD LINK TO TOUR OR FULL WIKI PAGE
* Read more {@link OnObserverBaseDirective About render flow}.
**/
set onObserverShowAfter(duration) { this.showAfter = duration; }
/**
* (Optional) The duration for which the view should be rendered. When the duration passes, the view will be auto destroyed.
*
* You can specify a number, which will be treated as milliseconds, or a string with the format of `<number><ms | s | ms>`.
* Numbers can be either integers or floats.
* For example:
* - `3000` - The view will be destroyed after 3 seconds.
* - `'10s'` - The view will be destroyed after 10 seconds.
* - `'0.5m'` - The view will be destroyed after 30 seconds.
* - `'100ms'` - The view will be destroyed after 100 milliseconds.
*
* During the time the view is rendered, the context will be updated with a countdown object to facilitate any UI part used to
* indicate countdown to the user. The countdown will be exposed through the {@link OnObserverContext.remaining `remaining`}
* property and the elapsed time through {@link OnObserverContext.elapsed `elapsed`} property in the view context and can both
* be accessed be declaring a `let` variable (e.g. `let remaining = remaining`).
* See {@link OnObserverBaseDirective.countdownInterval `countdownInterval`} for changing the updates interval.
*
* When unspecified, the view will be destroyed immediately once the observer detects a call different to the intercepted ones.
*
* TODO: ADD LINK TO TOUR OR FULL WIKI PAGE
* Read more {@link OnObserverBaseDirective About render flow}.
**/
set onObserverShowFor(duration) { this.showFor = duration; }
;
/**
* ### Only used when passing a value to {@link OnObserverBaseDirective.showFor `showFor`}.
*
* (Optional) The interval with which countdown updates should be made to the view's context before it auto destroys.
* The lower the value, the more updates will be made to the context, but the more resources your directive will consume.
*
* You can specify a number, which will be treated as milliseconds, or a string with the format of `<number><ms | s | ms>`.
* Numbers can be either integers or floats.
* For example:
* - `3000` - 3 seconds between each update.
* - `'10s'` - 10 seconds between each update.
* - `'0.5m'` - 30 seconds between each update.
* - `'100ms'` - 100 milliseconds between each update.
*
* You can also specify `'animationFrames'` so the countdown gets updated each time the browser is working on animations.
*
* When unspecified, the total duration of the countdown will be divided by {@link DefaultCountdownUpdateCount `DefaultCountdownUpdateCount`}
* to get a fixed interval which will make for {@link DefaultCountdownUpdateCount `DefaultCountdownUpdateCount`} countdown updates.
*/
set onObserverCountdownInterval(duration) { this.countdownInterval = duration; }
;
static ngTemplateContextGuard(directive, context) { return true; }
}
OnObserverDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: OnObserverDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
OnObserverDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: OnObserverDirective, selector: "[onObserver]", inputs: { onObserver: "onObserver", onObserverCalls: "onObserverCalls", onObserverViewMode: "onObserverViewMode", onObserverShowAfter: "onObserverShowAfter", onObserverShowFor: "onObserverShowFor", onObserverCountdownInterval: "onObserverCountdownInterval" }, usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: OnObserverDirective, decorators: [{
type: Directive,
args: [{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: '[onObserver]'
}]
}], propDecorators: { onObserver: [{
type: Input
}], onObserverCalls: [{
type: Input
}], onObserverViewMode: [{
type: Input
}], onObserverShowAfter: [{
type: Input
}], onObserverShowFor: [{
type: Input
}], onObserverCountdownInterval: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib24tb2JzZXJ2ZXIuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyLXplbi9jb3JlL3NyYy9yeGpzL29uLW9ic2VydmVyL2RpcmVjdGl2ZXMvb24tb2JzZXJ2ZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQVEsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFJakQsT0FBTyxFQUFFLHVCQUF1QixFQUFxQixNQUFNLDJDQUEyQyxDQUFDOztBQUV2Rzs7Ozs7OztHQU9HO0FBS0gsTUFBTSxPQUFPLG1CQUF1QixTQUFRLHVCQUEwQjtJQUp0RTs7UUFNYyxhQUFRLEdBQUcsWUFBWSxDQUFDO0tBc0hyQztJQW5IRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FtQ0c7SUFDSCxJQUFvQixVQUFVLENBQUMsS0FBb0IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFaEY7O09BRUc7SUFDSCxJQUFvQixlQUFlLENBQUMsS0FBb0MsSUFBSSxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFM0c7Ozs7Ozs7O09BUUc7SUFDSCxJQUFvQixrQkFBa0IsQ0FBVSxRQUFrQixJQUFjLElBQUksQ0FBQyxRQUFRLEdBQVksUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNwSDs7Ozs7Ozs7Ozs7Ozs7O1FBZUk7SUFDSixJQUFvQixtQkFBbUIsQ0FBUyxRQUE0QixJQUFJLElBQUksQ0FBQyxTQUFTLEdBQVcsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNwSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBcUJJO0lBQ0osSUFBb0IsaUJBQWlCLENBQVcsUUFBNEIsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFhLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFBQSxDQUFDO0lBQ3JIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FrQkc7SUFDSCxJQUFvQiwyQkFBMkIsQ0FBQyxRQUFnRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQUEsQ0FBQztJQUV6SSxNQUFNLENBQUMsc0JBQXNCLENBQUksU0FBaUMsRUFBRSxPQUFnQixJQUFxQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7O2lIQXZIOUgsbUJBQW1CO3FHQUFuQixtQkFBbUI7NEZBQW5CLG1CQUFtQjtrQkFKL0IsU0FBUzttQkFBQztvQkFDUCw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSxjQUFjO2lCQUMzQjs4QkEwQ3VCLFVBQVU7c0JBQTdCLEtBQUs7Z0JBS2MsZUFBZTtzQkFBbEMsS0FBSztnQkFXYyxrQkFBa0I7c0JBQXJDLEtBQUs7Z0JBaUJjLG1CQUFtQjtzQkFBdEMsS0FBSztnQkF1QmMsaUJBQWlCO3NCQUFwQyxLQUFLO2dCQW9CYywyQkFBMkI7c0JBQTlDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlICAgICAgIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBEaXJlY3RpdmUsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IER1cmF0aW9uQW5ub3RhdGlvbiwgT2JzZXJ2ZXJOYW1lLCBWaWV3TW9kZSB9IGZyb20gJy4uL2Fic3RyYWN0aW9uL3R5cGVzL2dlbmVyYWwnO1xuaW1wb3J0IHsgT25PYnNlcnZlckNvbnRleHQgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZnJvbSAnLi4vYWJzdHJhY3Rpb24vdHlwZXMvb24tb2JzZXJ2ZXItY29udGV4dCc7XG5pbXBvcnQgeyBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZSAgICAgICAgICAgICAgICAgICAgfSBmcm9tICcuLi9hYnN0cmFjdGlvbi9vbi1vYnNlcnZlci1iYXNlLmRpcmVjdGl2ZSc7XG5cbi8qKlxuICogRG9jdW1lbnRhdGlvbiBpbiB7QGxpbmsgT25PYnNlcnZlckFjdGl2ZURpcmVjdGl2ZS5vbk9ic2VydmVyfSB0byBhbGxvdyBpbi10ZW1wbGF0ZSB0b29sdGlwcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgT25PYnNlcnZlckRpcmVjdGl2ZVxuICogQGV4dGVuZHMge09uT2JzZXJ2ZXJCYXNlRGlyZWN0aXZlPFQ+fVxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdmFsdWUgdGhlIG9ic2VydmFibGUgZW1pdHMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gICAgc2VsZWN0b3I6ICdbb25PYnNlcnZlcl0nXG59KVxuZXhwb3J0IGNsYXNzIE9uT2JzZXJ2ZXJEaXJlY3RpdmU8VD4gZXh0ZW5kcyBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZTxUPlxue1xuICAgIHByb3RlY3RlZCBzZWxlY3RvciA9ICdvbk9ic2VydmVyJztcbiAgICBwcm90ZWN0ZWQgcmVuZGVyT25DYWxsc1RvITogT2JzZXJ2ZXJOYW1lIHwgT2JzZXJ2ZXJOYW1lW107XG4gICAgXG4gICAgLyoqXG4gICAgICogUmVuZGVycyB0aGUgdGVtcGxhdGUgd2hlbiB0aGUgc3BlY2lmaWVkIG9ic2VydmFibGUgbWFrZXMgYW55IG9mIHRoZSBjYWxscyBzcGVjaWZpZWQgdXNpbmcge0BsaW5rIE9uT2JzZXJ2ZXJEaXJlY3RpdmUub25PYnNlcnZlckNhbGxzIGBjYWxsc2B9LlxuICAgICAqIFxuICAgICAqICMjIEZlYXR1cmVzXG4gICAgICogXG4gICAgICogIyMjIyBWaWV3IENvbnRleHRcbiAgICAgKiBVc2UgdGhlIG1pY3Jvc3ludGF4IGBhc2Aga2V5d29yZCB0byBhc3NpZ24gcmVzb2x2ZWQgdmFsdWVzIHRvIGEgdmFyaWFibGUuXG4gICAgICogVXNlIHRoZSBtaWNyb3N5bnRheCBgbGV0YCBrZXl3b3JkIHRvIGFzc2lnbiB0aGUge0BsaW5rIE9uT2JzZXJ2ZXJDb250ZXh0IGZ1bGwgY29udGV4dCBvYmplY3R9IHRvIGEgdmFyaWFibGUgKGUuZy4gYGxldCBjb250ZXh0YCkuXG4gICAgICogIFxuICAgICAqICMjIyMgRGVsYXllZCByZW5kZXJpbmdcbiAgICAgKiBTcGVjaWZ5IGEgdmFsdWUgZm9yIHtAbGluayBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZS5zaG93QWZ0ZXIgYHNob3dBZnRlcmB9IHRvIGRlbGF5IHJlbmRlcmluZy5cbiAgICAgKiBcbiAgICAgKiAjIyMjIEF1dG8gZGVzdHJveVxuICAgICAqIFNwZWNpZnkge0BsaW5rIE9uT2JzZXJ2ZXJCYXNlRGlyZWN0aXZlLnNob3dGb3IgYHNob3dGb3JgfSB0byBhdXRvbWF0aWNhbGx5IGRlc3Ryb3kgdGhlIHZpZXcgYWZ0ZXIgYSBjZXJ0YWluIGR1cmF0aW9uLlxuICAgICAqIFxuICAgICAqICMjIyMgQ291bnRkb3duIHVwZGF0ZXNcbiAgICAgKiBXaGVuIHtAbGluayBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZS5zaG93Rm9yIGBzaG93Rm9yYH0gaXMgc3BlY2lmaWVkLCB0aGUgdmlldyBjb250ZXh0IHdpbGwgYmUgdXBkYXRlZCB3aXRoIHRoZSB0aW1lIHJlbWFpbmluZyB1bnRpbCB0aGUgdmlld1xuICAgICAqIGlzIGRlc3Ryb3llZCBhbmQgdGhlIHRpbWUgZWxhcHNlZCBzaW5jZSBpdCB3YXMgcmVuZGVyZWQuIFRoaXMgYWxsb3dzIGdpdmluZyB0aGUgdXNlciBmZWVkYmFjayBpbiBhIHByb2dyZXNzIGJhciwgYSBzcGlubmVyLCBhIHRleHR1YWwgdGltZXJcbiAgICAgKiBvciBhbnkgb3RoZXIgVUkgY29tcG9uZW50LiBcbiAgICAgKiBcbiAgICAgKiBSZW1haW5pbmcgaXMgcHJvdmlkZWQgYnkgdGhlIHtAbGluayBPbk9ic2VydmVyQ29udGV4dC5yZW1haW5pbmcgYHJlbWFpbmluZ2B9IHByb3BlcnR5LiBFbGFwc2VkIHRpbWUgaXMgcHJvdmlkZWQgYnkgdGhlIHtAbGluayBPbk9ic2VydmVyQ29udGV4dC5lbGFwc2VkIGBlbGFwc2VkYH1cbiAgICAgKiBwcm9wZXJ0eS4gQWNjZXNzIGl0IGJ5IGFzc2lnbmluZyBhIHZhcmlhYmxlIHVzaW5nIGBsZXRgLCBsaWtlIHNvOiAgXG4gICAgICogYGxldCByZW1haW5pbmcgPSByZW1haW5pbmdgXG4gICAgICogXG4gICAgICogIyMjIyBNdWx0aSB2aWV3IG1vZGVcbiAgICAgKiBTcGVjaWZ5IHtAbGluayBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZS52aWV3TW9kZSBgdmlld01vZGUgPSAnbXVsdGlwbGUnYH0gdG8gZW5hYmxlIHJlbmRlcmluZyBhIG5ldyB2aWV3IGZvciBlYWNoIGludGVyY2VwdGVkIGNhbGxcbiAgICAgKiBpbnN0ZWFkIG9mIHVwZGF0aW5nIGEgc2luZ2xlIHJlbmRlcmVkIHZpZXcuIFRoaXMgYWxsb3dzIHN0YWNraW5nIGxvZ3MsIG5vdGlmaWNhdGlvbiBzbmFja2JhcnMsIG9yIGFueSBvdGhlciBhZ2dyZWdhdGlvbiBmdW5jdGlvbmFsaXR5LlxuICAgICAqIENvbWJpbmVkIHdpdGgge0BsaW5rIE9uT2JzZXJ2ZXJCYXNlRGlyZWN0aXZlLnNob3dGb3IgYHNob3dGb3JgfSwgdGhpcyBpcyBncmVhdCBmb3IgZGlzYXBwZWFyaW5nIG1lc3NhZ2VzL25vdGlmaWNhdGlvbnMuXG4gICAgICogXG4gICAgICogIyMjIyBWaWV3IGluZGV4XG4gICAgICogSW4gbXVsdGktdmlldyBtb2RlLCB0aGUgY29udGV4dCB3aWxsIGNvbnRhaW4gdGhlIGluZGV4IG9mIHRoZSB2aWV3LCB3aGljaCBjYW4gYmUgdXNlZCBmb3IgY2FsY3VsYXRpb25zIGFuZCBzdHlsaW5nLlxuICAgICAqXG4gICAgICogIyMjIyBNdWx0aSBjYWxsIGludGVyY2VwdGlvblxuICAgICAqIENyZWF0ZSBkaWZmZXJlbnQgaW50ZXJjZXB0aW9uIGNvbWJpbmF0aW9ucyBieSBzcGVjaWZ5aW5nIG1vcmUgdGhhbiBvbmUgY2FsbCBuYW1lIHVzaW5nIHtAbGluayBPbk9ic2VydmVyRGlyZWN0aXZlLm9uT2JzZXJ2ZXJDYWxscyBgY2FsbHNgfS5cbiAgICAgKiBUaGlzIGlzIGhvdywgZm9yIGV4YW1wbGUsIHRoZSBjb21iaW5hdGlvbiBvZiBgJ2Vycm9yJ2AgYW5kIGAnY29tcGxldGUnYCB3YXMgdXNlZCB0byBjcmVhdGUgdGhlIGAqb25PYnNlcnZlckZpbmFsaXplZGAgZGlyZWN0aXZlLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzZXQgb25PYnNlcnZlcih2YWx1ZTogT2JzZXJ2YWJsZTxUPikgeyB0aGlzLmlucHV0Lm5leHQodmFsdWUpOyB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSBjYWxscyB0byBpbnRlcmNlcHQgZnJvbSB0aGUgb2JzZXJ2YWJsZS4gT25seSBpbnRlcmNlcHRlZCBjYWxscyB3aWxsIHJlbmRlciB0aGUgdGVtcGxhdGUuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHNldCBvbk9ic2VydmVyQ2FsbHMoY2FsbHM6IE9ic2VydmVyTmFtZSB8IE9ic2VydmVyTmFtZVtdKSB7IHRoaXMucmVuZGVyT25DYWxsc1RvID0gY2FsbHM7IH1cblxuICAgIC8qKlxuICAgICAqIChPcHRpb25hbCkgVGhlIHZpZXcgbW9kZSB0aGUgZGlyZWN0aXZlIHdpbGwgb3BlcmF0ZSBpbjogIFxuICAgICAqIGAnc2luZ2xlJ2AgLSBBIHNpbmdsZSB2aWV3IHdpbGwgYmUgcmVuZGVyZWQgb24gaW50ZXJjZXB0ZWQgY2FsbHMuIElmIGEgdmlldyBoYXMgYWxyZWFkeSBiZWVuIHJlbmRlcmVkIHdoZW4gYSBjYWxsIGlzIGludGVyY2VwdGVkLFxuICAgICAqIHRoZSBleGlzdGluZyB2aWV3IHdpbGwgYmUgdXBkYXRlZCB3aXRoIGRhdGEgZnJvbSB0aGUgbmV3IGNhbGwuXG4gICAgICogXG4gICAgICogYCdtdWx0aXBsZSdgIC0gRXZlcnkgbmV3IGludGVyY2VwdGVkIGNhbGwgd2lsbCByZW5kZXIgYSBuZXcgdmlldyB3aXRoIGl0cyBvd24gY29udGV4dCBhbmQgZGF0YSBlbmNhcHN1bGF0ZWQgZnJvbSB0aGUgY3VycmVudCBjYWxsLlxuICAgICAqIFxuICAgICAqIERlZmF1bHQgaXMgYCdzaW5nbGUnYC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc2V0IG9uT2JzZXJ2ZXJWaWV3TW9kZSAgICAgICAgICh2aWV3TW9kZTogVmlld01vZGUgICAgICAgICAgKSB7IHRoaXMudmlld01vZGUgICAgICAgICAgPSB2aWV3TW9kZTsgfVxuICAgIC8qKlxuICAgICAqIChPcHRpb25hbCkgVGhlIGR1cmF0aW9uIGZvciB3aGljaCB0aGUgZGlyZWN0aXZlIHNob3VsZCB3YWl0IGJlZm9yZSByZW5kZXJpbmcgdGhlIHZpZXcgb25jZSBhbiBpbnRlcmNlcHRlZCBjYWxsIGlzIG1hZGUuXG4gICAgICogXG4gICAgICogWW91IGNhbiBzcGVjaWZ5IGEgbnVtYmVyLCB3aGljaCB3aWxsIGJlIHRyZWF0ZWQgYXMgbWlsbGlzZWNvbmRzLCBvciBhIHN0cmluZyB3aXRoIHRoZSBmb3JtYXQgb2YgYDxudW1iZXI+PG1zIHwgcyB8IG1zPmAuXG4gICAgICogTnVtYmVycyBjYW4gYmUgZWl0aGVyIGludGVnZXJzIG9yIGZsb2F0cy5cbiAgICAgKiBGb3IgZXhhbXBsZTpcbiAgICAgKiAtIGAzMDAwYCAtIFdhaXQgZm9yIDMgc2Vjb25kcywgdGhlbiByZW5kZXIgdGhlIHZpZXcuXG4gICAgICogLSBgJzEwcydgIC0gV2FpdCBmb3IgMTAgc2Vjb25kcywgdGhlbiByZW5kZXIgdGhlIHZpZXcuXG4gICAgICogLSBgJzAuNW0nYCAtIFdhaXQgZm9yIDMwIHNlY29uZHMsIHRoZW4gcmVuZGVyIHRoZSB2aWV3LlxuICAgICAqIC0gYCcxMDBtcydgIC0gV2FpdCBmb3IgMTAwIG1pbGxpc2Vjb25kcywgdGhlbiByZW5kZXIgdGhlIHZpZXcuXG4gICAgICogXG4gICAgICogRGVmYXVsdCBpcyBgMGAsIG1lYW5pbmcgaW1tZWRpYXRlbHkgcmVuZGVyIHRoZSB2aWV3LlxuICAgICAqXG4gICAgICogVE9ETzogQUREIExJTksgVE8gVE9VUiBPUiBGVUxMIFdJS0kgUEFHRVxuICAgICAqIFJlYWQgbW9yZSB7QGxpbmsgT25PYnNlcnZlckJhc2VEaXJlY3RpdmUgQWJvdXQgcmVuZGVyIGZsb3d9LlxuICAgICAqKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc2V0IG9uT2JzZXJ2ZXJTaG93QWZ0ZXIgICAgICAgIChkdXJhdGlvbjogRHVyYXRpb25Bbm5vdGF0aW9uKSB7IHRoaXMuc2hvd0FmdGVyICAgICAgICAgPSBkdXJhdGlvbjsgfVxuICAgIC8qKlxuICAgICAqIChPcHRpb25hbCkgVGhlIGR1cmF0aW9uIGZvciB3aGljaCB0aGUgdmlldyBzaG91bGQgYmUgcmVuZGVyZWQuIFdoZW4gdGhlIGR1cmF0aW9uIHBhc3NlcywgdGhlIHZpZXcgd2lsbCBiZSBhdXRvIGRlc3Ryb3llZC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gc3BlY2lmeSBhIG51bWJlciwgd2hpY2ggd2lsbCBiZSB0cmVhdGVkIGFzIG1pbGxpc2Vjb25kcywgb3IgYSBzdHJpbmcgd2l0aCB0aGUgZm9ybWF0IG9mIGA8bnVtYmVyPjxtcyB8IHMgfCBtcz5gLlxuICAgICAqIE51bWJlcnMgY2FuIGJlIGVpdGhlciBpbnRlZ2VycyBvciBmbG9hdHMuXG4gICAgICogRm9yIGV4YW1wbGU6XG4gICAgICogLSBgMzAwMGAgLSBUaGUgdmlldyB3aWxsIGJlIGRlc3Ryb3llZCBhZnRlciAzIHNlY29uZHMuXG4gICAgICogLSBgJzEwcydgIC0gVGhlIHZpZXcgd2lsbCBiZSBkZXN0cm95ZWQgYWZ0ZXIgMTAgc2Vjb25kcy5cbiAgICAgKiAtIGAnMC41bSdgIC0gVGhlIHZpZXcgd2lsbCBiZSBkZXN0cm95ZWQgYWZ0ZXIgMzAgc2Vjb25kcy5cbiAgICAgKiAtIGAnMTAwbXMnYCAtIFRoZSB2aWV3IHdpbGwgYmUgZGVzdHJveWVkIGFmdGVyIDEwMCBtaWxsaXNlY29uZHMuXG4gICAgICogXG4gICAgICogRHVyaW5nIHRoZSB0aW1lIHRoZSB2aWV3IGlzIHJlbmRlcmVkLCB0aGUgY29udGV4dCB3aWxsIGJlIHVwZGF0ZWQgd2l0aCBhIGNvdW50ZG93biBvYmplY3QgdG8gZmFjaWxpdGF0ZSBhbnkgVUkgcGFydCB1c2VkIHRvXG4gICAgICogaW5kaWNhdGUgY291bnRkb3duIHRvIHRoZSB1c2VyLiBUaGUgY291bnRkb3duIHdpbGwgYmUgZXhwb3NlZCB0aHJvdWdoIHRoZSB7QGxpbmsgT25PYnNlcnZlckNvbnRleHQucmVtYWluaW5nIGByZW1haW5pbmdgfVxuICAgICAqIHByb3BlcnR5IGFuZCB0aGUgZWxhcHNlZCB0aW1lIHRocm91Z2gge0BsaW5rIE9uT2JzZXJ2ZXJDb250ZXh0LmVsYXBzZWQgYGVsYXBzZWRgfSBwcm9wZXJ0eSBpbiB0aGUgdmlldyBjb250ZXh0IGFuZCBjYW4gYm90aFxuICAgICAqIGJlIGFjY2Vzc2VkIGJlIGRlY2xhcmluZyBhIGBsZXRgIHZhcmlhYmxlIChlLmcuIGBsZXQgcmVtYWluaW5nID0gcmVtYWluaW5nYCkuXG4gICAgICogU2VlIHtAbGluayBPbk9ic2VydmVyQmFzZURpcmVjdGl2ZS5jb3VudGRvd25JbnRlcnZhbCBgY291bnRkb3duSW50ZXJ2YWxgfSBmb3IgY2hhbmdpbmcgdGhlIHVwZGF0ZXMgaW50ZXJ2YWwuXG4gICAgICogXG4gICAgICogV2hlbiB1bnNwZWNpZmllZCwgdGhlIHZpZXcgd2lsbCBiZSBkZXN0cm95ZWQgaW1tZWRpYXRlbHkgb25jZSB0aGUgb2JzZXJ2ZXIgZGV0ZWN0cyBhIGNhbGwgZGlmZmVyZW50IHRvIHRoZSBpbnRlcmNlcHRlZCBvbmVzLlxuICAgICAqIFxuICAgICAqIFRPRE86IEFERCBMSU5LIFRPIFRPVVIgT1IgRlVMTCBXSUtJIFBBR0VcbiAgICAgKiBSZWFkIG1vcmUge0BsaW5rIE9uT2JzZXJ2ZXJCYXNlRGlyZWN0aXZlIEFib3V0IHJlbmRlciBmbG93fS5cbiAgICAgKiovXG4gICAgQElucHV0KCkgcHVibGljIHNldCBvbk9ic2VydmVyU2hvd0ZvciAgICAgICAgICAoZHVyYXRpb246IER1cmF0aW9uQW5ub3RhdGlvbikgeyB0aGlzLnNob3dGb3IgICAgICAgICAgID0gZHVyYXRpb247IH07XG4gICAgLyoqXG4gICAgICogIyMjIE9ubHkgdXNlZCB3aGVuIHBhc3NpbmcgYSB2YWx1ZSB0byB7QGxpbmsgT25PYnNlcnZlckJhc2VEaXJlY3RpdmUuc2hvd0ZvciBgc2hvd0ZvcmB9LlxuICAgICAqIFxuICAgICAqIChPcHRpb25hbCkgVGhlIGludGVydmFsIHdpdGggd2hpY2ggY291bnRkb3duIHVwZGF0ZXMgc2hvdWxkIGJlIG1hZGUgdG8gdGhlIHZpZXcncyBjb250ZXh0IGJlZm9yZSBpdCBhdXRvIGRlc3Ryb3lzLlxuICAgICAqIFRoZSBsb3dlciB0aGUgdmFsdWUsIHRoZSBtb3JlIHVwZGF0ZXMgd2lsbCBiZSBtYWRlIHRvIHRoZSBjb250ZXh0LCBidXQgdGhlIG1vcmUgcmVzb3VyY2VzIHlvdXIgZGlyZWN0aXZlIHdpbGwgY29uc3VtZS5cbiAgICAgKiBcbiAgICAgKiBZb3UgY2FuIHNwZWNpZnkgYSBudW1iZXIsIHdoaWNoIHdpbGwgYmUgdHJlYXRlZCBhcyBtaWxsaXNlY29uZHMsIG9yIGEgc3RyaW5nIHdpdGggdGhlIGZvcm1hdCBvZiBgPG51bWJlcj48bXMgfCBzIHwgbXM+YC5cbiAgICAgKiBOdW1iZXJzIGNhbiBiZSBlaXRoZXIgaW50ZWdlcnMgb3IgZmxvYXRzLlxuICAgICAqIEZvciBleGFtcGxlOlxuICAgICAqIC0gYDMwMDBgIC0gMyBzZWNvbmRzIGJldHdlZW4gZWFjaCB1cGRhdGUuXG4gICAgICogLSBgJzEwcydgIC0gMTAgc2Vjb25kcyBiZXR3ZWVuIGVhY2ggdXBkYXRlLlxuICAgICAqIC0gYCcwLjVtJ2AgLSAzMCBzZWNvbmRzIGJldHdlZW4gZWFjaCB1cGRhdGUuXG4gICAgICogLSBgJzEwMG1zJ2AgLSAxMDAgbWlsbGlzZWNvbmRzIGJldHdlZW4gZWFjaCB1cGRhdGUuXG4gICAgICogXG4gICAgICogWW91IGNhbiBhbHNvIHNwZWNpZnkgYCdhbmltYXRpb25GcmFtZXMnYCBzbyB0aGUgY291bnRkb3duIGdldHMgdXBkYXRlZCBlYWNoIHRpbWUgdGhlIGJyb3dzZXIgaXMgd29ya2luZyBvbiBhbmltYXRpb25zLlxuICAgICAqIFxuICAgICAqIFdoZW4gdW5zcGVjaWZpZWQsIHRoZSB0b3RhbCBkdXJhdGlvbiBvZiB0aGUgY291bnRkb3duIHdpbGwgYmUgZGl2aWRlZCBieSB7QGxpbmsgRGVmYXVsdENvdW50ZG93blVwZGF0ZUNvdW50IGBEZWZhdWx0Q291bnRkb3duVXBkYXRlQ291bnRgfVxuICAgICAqIHRvIGdldCBhIGZpeGVkIGludGVydmFsIHdoaWNoIHdpbGwgbWFrZSBmb3Ige0BsaW5rIERlZmF1bHRDb3VudGRvd25VcGRhdGVDb3VudCBgRGVmYXVsdENvdW50ZG93blVwZGF0ZUNvdW50YH0gY291bnRkb3duIHVwZGF0ZXMuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHNldCBvbk9ic2VydmVyQ291bnRkb3duSW50ZXJ2YWwoZHVyYXRpb246IER1cmF0aW9uQW5ub3RhdGlvbiB8ICdhbmltYXRpb25GcmFtZXMnKSB7IHRoaXMuY291bnRkb3duSW50ZXJ2YWwgPSBkdXJhdGlvbjsgfTtcbiBcbiAgICBzdGF0aWMgbmdUZW1wbGF0ZUNvbnRleHRHdWFyZDxUPihkaXJlY3RpdmU6IE9uT2JzZXJ2ZXJEaXJlY3RpdmU8VD4sIGNvbnRleHQ6IHVua25vd24pOiBjb250ZXh0IGlzIE9uT2JzZXJ2ZXJDb250ZXh0PFQ+IHsgcmV0dXJuIHRydWU7IH1cbn0iXX0=