UNPKG

@angular/core

Version:

Angular - the core framework

607 lines 49.3 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Google Inc. 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 { assertDefined } from '../util/assert'; import { assertLViewOrUndefined } from './assert'; import { executeHooks } from './hooks'; import { BINDING_INDEX, CONTEXT, DECLARATION_VIEW, FLAGS, TVIEW } from './interfaces/view'; import { setCachedStylingContext } from './styling/state'; import { resetPreOrderHookFlags } from './util/view_utils'; /** * Store the element depth count. This is used to identify the root elements of the template * so that we can than attach `LView` to only those elements. * @type {?} */ let elementDepthCount; /** * @return {?} */ export function getElementDepthCount() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return elementDepthCount; } /** * @return {?} */ export function increaseElementDepthCount() { elementDepthCount++; } /** * @return {?} */ export function decreaseElementDepthCount() { elementDepthCount--; } /** @type {?} */ let currentDirectiveDef = null; /** * @return {?} */ export function getCurrentDirectiveDef() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return currentDirectiveDef; } /** * @param {?} def * @return {?} */ export function setCurrentDirectiveDef(def) { currentDirectiveDef = def; } /** * Stores whether directives should be matched to elements. * * When template contains `ngNonBindable` than we need to prevent the runtime form matching * directives on children of that element. * * Example: * ``` * <my-comp my-directive> * Should match component / directive. * </my-comp> * <div ngNonBindable> * <my-comp my-directive> * Should not match component / directive because we are in ngNonBindable. * </my-comp> * </div> * ``` * @type {?} */ let bindingsEnabled; /** * @return {?} */ export function getBindingsEnabled() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return bindingsEnabled; } /** * Enables directive matching on elements. * * * Example: * ``` * <my-comp my-directive> * Should match component / directive. * </my-comp> * <div ngNonBindable> * <!-- ɵɵdisableBindings() --> * <my-comp my-directive> * Should not match component / directive because we are in ngNonBindable. * </my-comp> * <!-- ɵɵenableBindings() --> * </div> * ``` * * \@codeGenApi * @return {?} */ export function ɵɵenableBindings() { bindingsEnabled = true; } /** * Disables directive matching on element. * * * Example: * ``` * <my-comp my-directive> * Should match component / directive. * </my-comp> * <div ngNonBindable> * <!-- ɵɵdisableBindings() --> * <my-comp my-directive> * Should not match component / directive because we are in ngNonBindable. * </my-comp> * <!-- ɵɵenableBindings() --> * </div> * ``` * * \@codeGenApi * @return {?} */ export function ɵɵdisableBindings() { bindingsEnabled = false; } /** * @return {?} */ export function getLView() { return lView; } /** * Used as the starting directive id value. * * All subsequent directives are incremented from this value onwards. * The reason why this value is `1` instead of `0` is because the `0` * value is reserved for the template. * @type {?} */ const MIN_DIRECTIVE_ID = 1; /** @type {?} */ let activeDirectiveId = MIN_DIRECTIVE_ID; /** * Position depth (with respect from leaf to root) in a directive sub-class inheritance chain. * @type {?} */ let activeDirectiveSuperClassDepthPosition = 0; /** * Total count of how many directives are a part of an inheritance chain. * * When directives are sub-classed (extended) from one to another, Angular * needs to keep track of exactly how many were encountered so it can accurately * generate the next directive id (once the next directive id is visited). * Normally the next directive id just a single incremented value from the * previous one, however, if the previous directive is a part of an inheritance * chain (a series of sub-classed directives) then the incremented value must * also take into account the total amount of sub-classed values. * * Note that this value resets back to zero once the next directive is * visited (when `incrementActiveDirectiveId` or `setActiveHostElement` * is called). * @type {?} */ let activeDirectiveSuperClassHeight = 0; /** * Sets the active directive host element and resets the directive id value * (when the provided elementIndex value has changed). * * @param {?=} elementIndex the element index value for the host element where * the directive/component instance lives * @return {?} */ export function setActiveHostElement(elementIndex = null) { if (_selectedIndex !== elementIndex) { setSelectedIndex(elementIndex == null ? -1 : elementIndex); activeDirectiveId = elementIndex == null ? 0 : MIN_DIRECTIVE_ID; activeDirectiveSuperClassDepthPosition = 0; activeDirectiveSuperClassHeight = 0; } } /** * Returns the current id value of the current directive. * * For example we have an element that has two directives on it: * <div dir-one dir-two></div> * * dirOne->hostBindings() (id == 1) * dirTwo->hostBindings() (id == 2) * * Note that this is only active when `hostBinding` functions are being processed. * * Note that directive id values are specific to an element (this means that * the same id value could be present on another element with a completely * different set of directives). * @return {?} */ export function getActiveDirectiveId() { return activeDirectiveId; } /** * Increments the current directive id value. * * For example we have an element that has two directives on it: * <div dir-one dir-two></div> * * dirOne->hostBindings() (index = 1) * // increment * dirTwo->hostBindings() (index = 2) * * Depending on whether or not a previous directive had any inherited * directives present, that value will be incremented in addition * to the id jumping up by one. * * Note that this is only active when `hostBinding` functions are being processed. * * Note that directive id values are specific to an element (this means that * the same id value could be present on another element with a completely * different set of directives). * @return {?} */ export function incrementActiveDirectiveId() { activeDirectiveId += 1 + activeDirectiveSuperClassHeight; // because we are dealing with a new directive this // means we have exited out of the inheritance chain activeDirectiveSuperClassDepthPosition = 0; activeDirectiveSuperClassHeight = 0; } /** * Set the current super class (reverse inheritance) position depth for a directive. * * For example we have two directives: Child and Other (but Child is a sub-class of Parent) * <div child-dir other-dir></div> * * // increment * parentInstance->hostBindings() (depth = 1) * // decrement * childInstance->hostBindings() (depth = 0) * otherInstance->hostBindings() (depth = 0 b/c it's a different directive) * * Note that this is only active when `hostBinding` functions are being processed. * @param {?} delta * @return {?} */ export function adjustActiveDirectiveSuperClassDepthPosition(delta) { activeDirectiveSuperClassDepthPosition += delta; // we keep track of the height value so that when the next directive is visited // then Angular knows to generate a new directive id value which has taken into // account how many sub-class directives were a part of the previous directive. activeDirectiveSuperClassHeight = Math.max(activeDirectiveSuperClassHeight, activeDirectiveSuperClassDepthPosition); } /** * Returns he current depth of the super/sub class inheritance chain. * * This will return how many inherited directive/component classes * exist in the current chain. * * ```typescript * \@Directive({ selector: '[super-dir]' }) * class SuperDir {} * / selector: '[sub-dir]' }) * class SubDir extends SuperDir {} * * // if `<div sub-dir>` is used then the super class height is `1` * // if `<div super-dir>` is used then the super class height is `0` * ``` * @return {?} */ export function getActiveDirectiveSuperClassHeight() { return activeDirectiveSuperClassHeight; } /** * Returns the current super class (reverse inheritance) depth for a directive. * * This is designed to help instruction code distinguish different hostBindings * calls from each other when a directive has extended from another directive. * Normally using the directive id value is enough, but with the case * of parent/sub-class directive inheritance more information is required. * * Note that this is only active when `hostBinding` functions are being processed. * @return {?} */ export function getActiveDirectiveSuperClassDepth() { return activeDirectiveSuperClassDepthPosition; } /** * Restores `contextViewData` to the given OpaqueViewState instance. * * Used in conjunction with the getCurrentView() instruction to save a snapshot * of the current view and restore it when listeners are invoked. This allows * walking the declaration view tree in listeners to get vars from parent views. * * \@codeGenApi * @param {?} viewToRestore The OpaqueViewState instance to restore. * * @return {?} */ export function ɵɵrestoreView(viewToRestore) { contextLView = (/** @type {?} */ ((/** @type {?} */ (viewToRestore)))); } /** * Used to set the parent property when nodes are created and track query results. * @type {?} */ let previousOrParentTNode; /** * @return {?} */ export function getPreviousOrParentTNode() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return previousOrParentTNode; } /** * @param {?} tNode * @param {?} _isParent * @return {?} */ export function setPreviousOrParentTNode(tNode, _isParent) { previousOrParentTNode = tNode; isParent = _isParent; } /** * @param {?} tNode * @param {?} view * @return {?} */ export function setTNodeAndViewData(tNode, view) { ngDevMode && assertLViewOrUndefined(view); previousOrParentTNode = tNode; lView = view; } /** * If `isParent` is: * - `true`: then `previousOrParentTNode` points to a parent node. * - `false`: then `previousOrParentTNode` points to previous node (sibling). * @type {?} */ let isParent; /** * @return {?} */ export function getIsParent() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return isParent; } /** * @return {?} */ export function setIsNotParent() { isParent = false; } /** * @return {?} */ export function setIsParent() { isParent = true; } /** * Checks whether a given view is in creation mode * @param {?=} view * @return {?} */ export function isCreationMode(view = lView) { return (view[FLAGS] & 4 /* CreationMode */) === 4 /* CreationMode */; } /** * State of the current view being processed. * * An array of nodes (text, element, container, etc), pipes, their bindings, and * any local variables that need to be stored between invocations. * @type {?} */ let lView; /** * The last viewData retrieved by nextContext(). * Allows building nextContext() and reference() calls. * * e.g. const inner = x().$implicit; const outer = x().$implicit; * @type {?} */ let contextLView = (/** @type {?} */ (null)); /** * @return {?} */ export function getContextLView() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return contextLView; } /** * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error. * * Necessary to support ChangeDetectorRef.checkNoChanges(). * @type {?} */ let checkNoChangesMode = false; /** * @return {?} */ export function getCheckNoChangesMode() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return checkNoChangesMode; } /** * @param {?} mode * @return {?} */ export function setCheckNoChangesMode(mode) { checkNoChangesMode = mode; } /** * The root index from which pure function instructions should calculate their binding * indices. In component views, this is TView.bindingStartIndex. In a host binding * context, this is the TView.expandoStartIndex + any dirs/hostVars before the given dir. * @type {?} */ let bindingRootIndex = -1; // top level variables should not be exported for performance reasons (PERF_NOTES.md) /** * @return {?} */ export function getBindingRoot() { return bindingRootIndex; } /** * @param {?} value * @return {?} */ export function setBindingRoot(value) { bindingRootIndex = value; } /** * Current index of a View or Content Query which needs to be processed next. * We iterate over the list of Queries and increment current query index at every step. * @type {?} */ let currentQueryIndex = 0; /** * @return {?} */ export function getCurrentQueryIndex() { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return currentQueryIndex; } /** * @param {?} value * @return {?} */ export function setCurrentQueryIndex(value) { currentQueryIndex = value; } /** * Swap the current state with a new state. * * For performance reasons we store the state in the top level of the module. * This way we minimize the number of properties to read. Whenever a new view * is entered we have to store the state for later, and when the view is * exited the state has to be restored * * @param {?} newView New state to become active * @param {?} hostTNode * @return {?} the previous state; */ export function enterView(newView, hostTNode) { ngDevMode && assertLViewOrUndefined(newView); /** @type {?} */ const oldView = lView; if (newView) { /** @type {?} */ const tView = newView[TVIEW]; bindingRootIndex = tView.bindingStartIndex; } previousOrParentTNode = (/** @type {?} */ (hostTNode)); isParent = true; lView = contextLView = newView; return oldView; } /** * @template T * @param {?=} level * @return {?} */ export function nextContextImpl(level = 1) { contextLView = walkUpViews(level, (/** @type {?} */ (contextLView))); return (/** @type {?} */ (contextLView[CONTEXT])); } /** * @param {?} nestingLevel * @param {?} currentView * @return {?} */ function walkUpViews(nestingLevel, currentView) { while (nestingLevel > 0) { ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.'); currentView = (/** @type {?} */ (currentView[DECLARATION_VIEW])); nestingLevel--; } return currentView; } /** * Resets the application state. * @return {?} */ export function resetComponentState() { isParent = false; previousOrParentTNode = (/** @type {?} */ (null)); elementDepthCount = 0; bindingsEnabled = true; } /** * Used in lieu of enterView to make it clear when we are exiting a child view. This makes * the direction of traversal (up or down the view tree) a bit clearer. * * @param {?} newView New state to become active * @param {?} safeToRunHooks Whether the runtime is in a state where running lifecycle hooks is valid. * This is not always the case (for example, the application may have crashed and `leaveView` is * being executed while unwinding the call stack). * @return {?} */ export function leaveView(newView, safeToRunHooks) { /** @type {?} */ const tView = lView[TVIEW]; if (isCreationMode(lView)) { lView[FLAGS] &= ~4 /* CreationMode */; } else { try { resetPreOrderHookFlags(lView); safeToRunHooks && executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode, 2 /* AfterViewInitHooksToBeRun */, undefined); } finally { // Views are clean and in update mode after being checked, so these bits are cleared lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */); lView[BINDING_INDEX] = tView.bindingStartIndex; } } setCachedStylingContext(null); enterView(newView, null); } /** @type {?} */ let _selectedIndex = -1; /** * Gets the most recent index passed to {\@link select} * * Used with {\@link property} instruction (and more in the future) to identify the index in the * current `LView` to act on. * @return {?} */ export function getSelectedIndex() { return _selectedIndex; } /** * Sets the most recent index passed to {\@link select} * * Used with {\@link property} instruction (and more in the future) to identify the index in the * current `LView` to act on. * @param {?} index * @return {?} */ export function setSelectedIndex(index) { _selectedIndex = index; // remove the styling context from the cache // because we are now on a different element setCachedStylingContext(null); } /** @type {?} */ let _currentNamespace = null; /** * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state. * * \@codeGenApi * @return {?} */ export function ɵɵnamespaceSVG() { _currentNamespace = 'http://www.w3.org/2000/svg'; } /** * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state. * * \@codeGenApi * @return {?} */ export function ɵɵnamespaceMathML() { _currentNamespace = 'http://www.w3.org/1998/MathML/'; } /** * Sets the namespace used to create elements no `null`, which forces element creation to use * `createElement` rather than `createElementNS`. * * \@codeGenApi * @return {?} */ export function ɵɵnamespaceHTML() { _currentNamespace = null; } /** * @return {?} */ export function getNamespace() { return _currentNamespace; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3N0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFDLGFBQWEsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRSxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDaEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUdyQyxPQUFPLEVBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQXNELEtBQUssRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQzdJLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3hELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7SUFRckQsaUJBQTJCOzs7O0FBRS9CLE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMscUZBQXFGO0lBQ3JGLE9BQU8saUJBQWlCLENBQUM7QUFDM0IsQ0FBQzs7OztBQUVELE1BQU0sVUFBVSx5QkFBeUI7SUFDdkMsaUJBQWlCLEVBQUUsQ0FBQztBQUN0QixDQUFDOzs7O0FBRUQsTUFBTSxVQUFVLHlCQUF5QjtJQUN2QyxpQkFBaUIsRUFBRSxDQUFDO0FBQ3RCLENBQUM7O0lBRUcsbUJBQW1CLEdBQTZDLElBQUk7Ozs7QUFFeEUsTUFBTSxVQUFVLHNCQUFzQjtJQUNwQyxxRkFBcUY7SUFDckYsT0FBTyxtQkFBbUIsQ0FBQztBQUM3QixDQUFDOzs7OztBQUVELE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxHQUErQztJQUNwRixtQkFBbUIsR0FBRyxHQUFHLENBQUM7QUFDNUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFvQkcsZUFBMEI7Ozs7QUFFOUIsTUFBTSxVQUFVLGtCQUFrQjtJQUNoQyxx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RCxNQUFNLFVBQVUsaUJBQWlCO0lBQy9CLGlCQUFpQixHQUFHLGdDQUFnQyxDQUFDO0FBQ3ZELENBQUM7Ozs7Ozs7O0FBUUQsTUFBTSxVQUFVLGVBQWU7SUFDN0IsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0FBQzNCLENBQUM7Ozs7QUFFRCxNQUFNLFVBQVUsWUFBWTtJQUMxQixPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7YXNzZXJ0RGVmaW5lZCwgYXNzZXJ0R3JlYXRlclRoYW59IGZyb20gJy4uL3V0aWwvYXNzZXJ0JztcblxuaW1wb3J0IHthc3NlcnRMVmlld09yVW5kZWZpbmVkfSBmcm9tICcuL2Fzc2VydCc7XG5pbXBvcnQge2V4ZWN1dGVIb29rc30gZnJvbSAnLi9ob29rcyc7XG5pbXBvcnQge0NvbXBvbmVudERlZiwgRGlyZWN0aXZlRGVmfSBmcm9tICcuL2ludGVyZmFjZXMvZGVmaW5pdGlvbic7XG5pbXBvcnQge1RFbGVtZW50Tm9kZSwgVE5vZGUsIFRWaWV3Tm9kZX0gZnJvbSAnLi9pbnRlcmZhY2VzL25vZGUnO1xuaW1wb3J0IHtCSU5ESU5HX0lOREVYLCBDT05URVhULCBERUNMQVJBVElPTl9WSUVXLCBGTEFHUywgSW5pdFBoYXNlU3RhdGUsIExWaWV3LCBMVmlld0ZsYWdzLCBPcGFxdWVWaWV3U3RhdGUsIFRWSUVXfSBmcm9tICcuL2ludGVyZmFjZXMvdmlldyc7XG5pbXBvcnQge3NldENhY2hlZFN0eWxpbmdDb250ZXh0fSBmcm9tICcuL3N0eWxpbmcvc3RhdGUnO1xuaW1wb3J0IHtyZXNldFByZU9yZGVySG9va0ZsYWdzfSBmcm9tICcuL3V0aWwvdmlld191dGlscyc7XG5cblxuXG4vKipcbiAqIFN0b3JlIHRoZSBlbGVtZW50IGRlcHRoIGNvdW50LiBUaGlzIGlzIHVzZWQgdG8gaWRlbnRpZnkgdGhlIHJvb3QgZWxlbWVudHMgb2YgdGhlIHRlbXBsYXRlXG4gKiBzbyB0aGF0IHdlIGNhbiB0aGFuIGF0dGFjaCBgTFZpZXdgIHRvIG9ubHkgdGhvc2UgZWxlbWVudHMuXG4gKi9cbmxldCBlbGVtZW50RGVwdGhDb3VudCAhOiBudW1iZXI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbGVtZW50RGVwdGhDb3VudCgpIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gZWxlbWVudERlcHRoQ291bnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmNyZWFzZUVsZW1lbnREZXB0aENvdW50KCkge1xuICBlbGVtZW50RGVwdGhDb3VudCsrO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVjcmVhc2VFbGVtZW50RGVwdGhDb3VudCgpIHtcbiAgZWxlbWVudERlcHRoQ291bnQtLTtcbn1cblxubGV0IGN1cnJlbnREaXJlY3RpdmVEZWY6IERpcmVjdGl2ZURlZjxhbnk+fENvbXBvbmVudERlZjxhbnk+fG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudERpcmVjdGl2ZURlZigpOiBEaXJlY3RpdmVEZWY8YW55PnxDb21wb25lbnREZWY8YW55PnxudWxsIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gY3VycmVudERpcmVjdGl2ZURlZjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEN1cnJlbnREaXJlY3RpdmVEZWYoZGVmOiBEaXJlY3RpdmVEZWY8YW55PnwgQ29tcG9uZW50RGVmPGFueT58IG51bGwpOiB2b2lkIHtcbiAgY3VycmVudERpcmVjdGl2ZURlZiA9IGRlZjtcbn1cblxuLyoqXG4gKiBTdG9yZXMgd2hldGhlciBkaXJlY3RpdmVzIHNob3VsZCBiZSBtYXRjaGVkIHRvIGVsZW1lbnRzLlxuICpcbiAqIFdoZW4gdGVtcGxhdGUgY29udGFpbnMgYG5nTm9uQmluZGFibGVgIHRoYW4gd2UgbmVlZCB0byBwcmV2ZW50IHRoZSBydW50aW1lIGZvcm0gbWF0Y2hpbmdcbiAqIGRpcmVjdGl2ZXMgb24gY2hpbGRyZW4gb2YgdGhhdCBlbGVtZW50LlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBcbiAqIDxteS1jb21wIG15LWRpcmVjdGl2ZT5cbiAqICAgU2hvdWxkIG1hdGNoIGNvbXBvbmVudCAvIGRpcmVjdGl2ZS5cbiAqIDwvbXktY29tcD5cbiAqIDxkaXYgbmdOb25CaW5kYWJsZT5cbiAqICAgPG15LWNvbXAgbXktZGlyZWN0aXZlPlxuICogICAgIFNob3VsZCBub3QgbWF0Y2ggY29tcG9uZW50IC8gZGlyZWN0aXZlIGJlY2F1c2Ugd2UgYXJlIGluIG5nTm9uQmluZGFibGUuXG4gKiAgIDwvbXktY29tcD5cbiAqIDwvZGl2PlxuICogYGBgXG4gKi9cbmxldCBiaW5kaW5nc0VuYWJsZWQgITogYm9vbGVhbjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpbmRpbmdzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gYmluZGluZ3NFbmFibGVkO1xufVxuXG5cbi8qKlxuICogRW5hYmxlcyBkaXJlY3RpdmUgbWF0Y2hpbmcgb24gZWxlbWVudHMuXG4gKlxuICogICogRXhhbXBsZTpcbiAqIGBgYFxuICogPG15LWNvbXAgbXktZGlyZWN0aXZlPlxuICogICBTaG91bGQgbWF0Y2ggY29tcG9uZW50IC8gZGlyZWN0aXZlLlxuICogPC9teS1jb21wPlxuICogPGRpdiBuZ05vbkJpbmRhYmxlPlxuICogICA8IS0tIMm1ybVkaXNhYmxlQmluZGluZ3MoKSAtLT5cbiAqICAgPG15LWNvbXAgbXktZGlyZWN0aXZlPlxuICogICAgIFNob3VsZCBub3QgbWF0Y2ggY29tcG9uZW50IC8gZGlyZWN0aXZlIGJlY2F1c2Ugd2UgYXJlIGluIG5nTm9uQmluZGFibGUuXG4gKiAgIDwvbXktY29tcD5cbiAqICAgPCEtLSDJtcm1ZW5hYmxlQmluZGluZ3MoKSAtLT5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVlbmFibGVCaW5kaW5ncygpOiB2b2lkIHtcbiAgYmluZGluZ3NFbmFibGVkID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXNhYmxlcyBkaXJlY3RpdmUgbWF0Y2hpbmcgb24gZWxlbWVudC5cbiAqXG4gKiAgKiBFeGFtcGxlOlxuICogYGBgXG4gKiA8bXktY29tcCBteS1kaXJlY3RpdmU+XG4gKiAgIFNob3VsZCBtYXRjaCBjb21wb25lbnQgLyBkaXJlY3RpdmUuXG4gKiA8L215LWNvbXA+XG4gKiA8ZGl2IG5nTm9uQmluZGFibGU+XG4gKiAgIDwhLS0gybXJtWRpc2FibGVCaW5kaW5ncygpIC0tPlxuICogICA8bXktY29tcCBteS1kaXJlY3RpdmU+XG4gKiAgICAgU2hvdWxkIG5vdCBtYXRjaCBjb21wb25lbnQgLyBkaXJlY3RpdmUgYmVjYXVzZSB3ZSBhcmUgaW4gbmdOb25CaW5kYWJsZS5cbiAqICAgPC9teS1jb21wPlxuICogICA8IS0tIMm1ybVlbmFibGVCaW5kaW5ncygpIC0tPlxuICogPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtWRpc2FibGVCaW5kaW5ncygpOiB2b2lkIHtcbiAgYmluZGluZ3NFbmFibGVkID0gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMVmlldygpOiBMVmlldyB7XG4gIHJldHVybiBsVmlldztcbn1cblxuLyoqXG4gKiBVc2VkIGFzIHRoZSBzdGFydGluZyBkaXJlY3RpdmUgaWQgdmFsdWUuXG4gKlxuICogQWxsIHN1YnNlcXVlbnQgZGlyZWN0aXZlcyBhcmUgaW5jcmVtZW50ZWQgZnJvbSB0aGlzIHZhbHVlIG9ud2FyZHMuXG4gKiBUaGUgcmVhc29uIHdoeSB0aGlzIHZhbHVlIGlzIGAxYCBpbnN0ZWFkIG9mIGAwYCBpcyBiZWNhdXNlIHRoZSBgMGBcbiAqIHZhbHVlIGlzIHJlc2VydmVkIGZvciB0aGUgdGVtcGxhdGUuXG4gKi9cbmNvbnN0IE1JTl9ESVJFQ1RJVkVfSUQgPSAxO1xuXG5sZXQgYWN0aXZlRGlyZWN0aXZlSWQgPSBNSU5fRElSRUNUSVZFX0lEO1xuXG4vKipcbiAqIFBvc2l0aW9uIGRlcHRoICh3aXRoIHJlc3BlY3QgZnJvbSBsZWFmIHRvIHJvb3QpIGluIGEgZGlyZWN0aXZlIHN1Yi1jbGFzcyBpbmhlcml0YW5jZSBjaGFpbi5cbiAqL1xubGV0IGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NEZXB0aFBvc2l0aW9uID0gMDtcblxuLyoqXG4gKiBUb3RhbCBjb3VudCBvZiBob3cgbWFueSBkaXJlY3RpdmVzIGFyZSBhIHBhcnQgb2YgYW4gaW5oZXJpdGFuY2UgY2hhaW4uXG4gKlxuICogV2hlbiBkaXJlY3RpdmVzIGFyZSBzdWItY2xhc3NlZCAoZXh0ZW5kZWQpIGZyb20gb25lIHRvIGFub3RoZXIsIEFuZ3VsYXJcbiAqIG5lZWRzIHRvIGtlZXAgdHJhY2sgb2YgZXhhY3RseSBob3cgbWFueSB3ZXJlIGVuY291bnRlcmVkIHNvIGl0IGNhbiBhY2N1cmF0ZWx5XG4gKiBnZW5lcmF0ZSB0aGUgbmV4dCBkaXJlY3RpdmUgaWQgKG9uY2UgdGhlIG5leHQgZGlyZWN0aXZlIGlkIGlzIHZpc2l0ZWQpLlxuICogTm9ybWFsbHkgdGhlIG5leHQgZGlyZWN0aXZlIGlkIGp1c3QgYSBzaW5nbGUgaW5jcmVtZW50ZWQgdmFsdWUgZnJvbSB0aGVcbiAqIHByZXZpb3VzIG9uZSwgaG93ZXZlciwgaWYgdGhlIHByZXZpb3VzIGRpcmVjdGl2ZSBpcyBhIHBhcnQgb2YgYW4gaW5oZXJpdGFuY2VcbiAqIGNoYWluIChhIHNlcmllcyBvZiBzdWItY2xhc3NlZCBkaXJlY3RpdmVzKSB0aGVuIHRoZSBpbmNyZW1lbnRlZCB2YWx1ZSBtdXN0XG4gKiBhbHNvIHRha2UgaW50byBhY2NvdW50IHRoZSB0b3RhbCBhbW91bnQgb2Ygc3ViLWNsYXNzZWQgdmFsdWVzLlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIHZhbHVlIHJlc2V0cyBiYWNrIHRvIHplcm8gb25jZSB0aGUgbmV4dCBkaXJlY3RpdmUgaXNcbiAqIHZpc2l0ZWQgKHdoZW4gYGluY3JlbWVudEFjdGl2ZURpcmVjdGl2ZUlkYCBvciBgc2V0QWN0aXZlSG9zdEVsZW1lbnRgXG4gKiBpcyBjYWxsZWQpLlxuICovXG5sZXQgYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0hlaWdodCA9IDA7XG5cbi8qKlxuICogU2V0cyB0aGUgYWN0aXZlIGRpcmVjdGl2ZSBob3N0IGVsZW1lbnQgYW5kIHJlc2V0cyB0aGUgZGlyZWN0aXZlIGlkIHZhbHVlXG4gKiAod2hlbiB0aGUgcHJvdmlkZWQgZWxlbWVudEluZGV4IHZhbHVlIGhhcyBjaGFuZ2VkKS5cbiAqXG4gKiBAcGFyYW0gZWxlbWVudEluZGV4IHRoZSBlbGVtZW50IGluZGV4IHZhbHVlIGZvciB0aGUgaG9zdCBlbGVtZW50IHdoZXJlXG4gKiAgICAgICAgICAgICAgICAgICAgIHRoZSBkaXJlY3RpdmUvY29tcG9uZW50IGluc3RhbmNlIGxpdmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRBY3RpdmVIb3N0RWxlbWVudChlbGVtZW50SW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsKSB7XG4gIGlmIChfc2VsZWN0ZWRJbmRleCAhPT0gZWxlbWVudEluZGV4KSB7XG4gICAgc2V0U2VsZWN0ZWRJbmRleChlbGVtZW50SW5kZXggPT0gbnVsbCA/IC0xIDogZWxlbWVudEluZGV4KTtcbiAgICBhY3RpdmVEaXJlY3RpdmVJZCA9IGVsZW1lbnRJbmRleCA9PSBudWxsID8gMCA6IE1JTl9ESVJFQ1RJVkVfSUQ7XG4gICAgYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0RlcHRoUG9zaXRpb24gPSAwO1xuICAgIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQgPSAwO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBpZCB2YWx1ZSBvZiB0aGUgY3VycmVudCBkaXJlY3RpdmUuXG4gKlxuICogRm9yIGV4YW1wbGUgd2UgaGF2ZSBhbiBlbGVtZW50IHRoYXQgaGFzIHR3byBkaXJlY3RpdmVzIG9uIGl0OlxuICogPGRpdiBkaXItb25lIGRpci10d28+PC9kaXY+XG4gKlxuICogZGlyT25lLT5ob3N0QmluZGluZ3MoKSAoaWQgPT0gMSlcbiAqIGRpclR3by0+aG9zdEJpbmRpbmdzKCkgKGlkID09IDIpXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhY3RpdmUgd2hlbiBgaG9zdEJpbmRpbmdgIGZ1bmN0aW9ucyBhcmUgYmVpbmcgcHJvY2Vzc2VkLlxuICpcbiAqIE5vdGUgdGhhdCBkaXJlY3RpdmUgaWQgdmFsdWVzIGFyZSBzcGVjaWZpYyB0byBhbiBlbGVtZW50ICh0aGlzIG1lYW5zIHRoYXRcbiAqIHRoZSBzYW1lIGlkIHZhbHVlIGNvdWxkIGJlIHByZXNlbnQgb24gYW5vdGhlciBlbGVtZW50IHdpdGggYSBjb21wbGV0ZWx5XG4gKiBkaWZmZXJlbnQgc2V0IG9mIGRpcmVjdGl2ZXMpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZlRGlyZWN0aXZlSWQoKSB7XG4gIHJldHVybiBhY3RpdmVEaXJlY3RpdmVJZDtcbn1cblxuLyoqXG4gKiBJbmNyZW1lbnRzIHRoZSBjdXJyZW50IGRpcmVjdGl2ZSBpZCB2YWx1ZS5cbiAqXG4gKiBGb3IgZXhhbXBsZSB3ZSBoYXZlIGFuIGVsZW1lbnQgdGhhdCBoYXMgdHdvIGRpcmVjdGl2ZXMgb24gaXQ6XG4gKiA8ZGl2IGRpci1vbmUgZGlyLXR3bz48L2Rpdj5cbiAqXG4gKiBkaXJPbmUtPmhvc3RCaW5kaW5ncygpIChpbmRleCA9IDEpXG4gKiAvLyBpbmNyZW1lbnRcbiAqIGRpclR3by0+aG9zdEJpbmRpbmdzKCkgKGluZGV4ID0gMilcbiAqXG4gKiBEZXBlbmRpbmcgb24gd2hldGhlciBvciBub3QgYSBwcmV2aW91cyBkaXJlY3RpdmUgaGFkIGFueSBpbmhlcml0ZWRcbiAqIGRpcmVjdGl2ZXMgcHJlc2VudCwgdGhhdCB2YWx1ZSB3aWxsIGJlIGluY3JlbWVudGVkIGluIGFkZGl0aW9uXG4gKiB0byB0aGUgaWQganVtcGluZyB1cCBieSBvbmUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhY3RpdmUgd2hlbiBgaG9zdEJpbmRpbmdgIGZ1bmN0aW9ucyBhcmUgYmVpbmcgcHJvY2Vzc2VkLlxuICpcbiAqIE5vdGUgdGhhdCBkaXJlY3RpdmUgaWQgdmFsdWVzIGFyZSBzcGVjaWZpYyB0byBhbiBlbGVtZW50ICh0aGlzIG1lYW5zIHRoYXRcbiAqIHRoZSBzYW1lIGlkIHZhbHVlIGNvdWxkIGJlIHByZXNlbnQgb24gYW5vdGhlciBlbGVtZW50IHdpdGggYSBjb21wbGV0ZWx5XG4gKiBkaWZmZXJlbnQgc2V0IG9mIGRpcmVjdGl2ZXMpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50QWN0aXZlRGlyZWN0aXZlSWQoKSB7XG4gIGFjdGl2ZURpcmVjdGl2ZUlkICs9IDEgKyBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzSGVpZ2h0O1xuXG4gIC8vIGJlY2F1c2Ugd2UgYXJlIGRlYWxpbmcgd2l0aCBhIG5ldyBkaXJlY3RpdmUgdGhpc1xuICAvLyBtZWFucyB3ZSBoYXZlIGV4aXRlZCBvdXQgb2YgdGhlIGluaGVyaXRhbmNlIGNoYWluXG4gIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NEZXB0aFBvc2l0aW9uID0gMDtcbiAgYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0hlaWdodCA9IDA7XG59XG5cbi8qKlxuICogU2V0IHRoZSBjdXJyZW50IHN1cGVyIGNsYXNzIChyZXZlcnNlIGluaGVyaXRhbmNlKSBwb3NpdGlvbiBkZXB0aCBmb3IgYSBkaXJlY3RpdmUuXG4gKlxuICogRm9yIGV4YW1wbGUgd2UgaGF2ZSB0d28gZGlyZWN0aXZlczogQ2hpbGQgYW5kIE90aGVyIChidXQgQ2hpbGQgaXMgYSBzdWItY2xhc3Mgb2YgUGFyZW50KVxuICogPGRpdiBjaGlsZC1kaXIgb3RoZXItZGlyPjwvZGl2PlxuICpcbiAqIC8vIGluY3JlbWVudFxuICogcGFyZW50SW5zdGFuY2UtPmhvc3RCaW5kaW5ncygpIChkZXB0aCA9IDEpXG4gKiAvLyBkZWNyZW1lbnRcbiAqIGNoaWxkSW5zdGFuY2UtPmhvc3RCaW5kaW5ncygpIChkZXB0aCA9IDApXG4gKiBvdGhlckluc3RhbmNlLT5ob3N0QmluZGluZ3MoKSAoZGVwdGggPSAwIGIvYyBpdCdzIGEgZGlmZmVyZW50IGRpcmVjdGl2ZSlcbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBpcyBvbmx5IGFjdGl2ZSB3aGVuIGBob3N0QmluZGluZ2AgZnVuY3Rpb25zIGFyZSBiZWluZyBwcm9jZXNzZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGp1c3RBY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGhQb3NpdGlvbihkZWx0YTogbnVtYmVyKSB7XG4gIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NEZXB0aFBvc2l0aW9uICs9IGRlbHRhO1xuXG4gIC8vIHdlIGtlZXAgdHJhY2sgb2YgdGhlIGhlaWdodCB2YWx1ZSBzbyB0aGF0IHdoZW4gdGhlIG5leHQgZGlyZWN0aXZlIGlzIHZpc2l0ZWRcbiAgLy8gdGhlbiBBbmd1bGFyIGtub3dzIHRvIGdlbmVyYXRlIGEgbmV3IGRpcmVjdGl2ZSBpZCB2YWx1ZSB3aGljaCBoYXMgdGFrZW4gaW50b1xuICAvLyBhY2NvdW50IGhvdyBtYW55IHN1Yi1jbGFzcyBkaXJlY3RpdmVzIHdlcmUgYSBwYXJ0IG9mIHRoZSBwcmV2aW91cyBkaXJlY3RpdmUuXG4gIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQgPVxuICAgICAgTWF0aC5tYXgoYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0hlaWdodCwgYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0RlcHRoUG9zaXRpb24pO1xufVxuXG4vKipcbiAqIFJldHVybnMgaGUgY3VycmVudCBkZXB0aCBvZiB0aGUgc3VwZXIvc3ViIGNsYXNzIGluaGVyaXRhbmNlIGNoYWluLlxuICpcbiAqIFRoaXMgd2lsbCByZXR1cm4gaG93IG1hbnkgaW5oZXJpdGVkIGRpcmVjdGl2ZS9jb21wb25lbnQgY2xhc3Nlc1xuICogZXhpc3QgaW4gdGhlIGN1cnJlbnQgY2hhaW4uXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnW3N1cGVyLWRpcl0nIH0pXG4gKiBjbGFzcyBTdXBlckRpciB7fVxuICpcbiAqIEBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tzdWItZGlyXScgfSlcbiAqIGNsYXNzIFN1YkRpciBleHRlbmRzIFN1cGVyRGlyIHt9XG4gKlxuICogLy8gaWYgYDxkaXYgc3ViLWRpcj5gIGlzIHVzZWQgdGhlbiB0aGUgc3VwZXIgY2xhc3MgaGVpZ2h0IGlzIGAxYFxuICogLy8gaWYgYDxkaXYgc3VwZXItZGlyPmAgaXMgdXNlZCB0aGVuIHRoZSBzdXBlciBjbGFzcyBoZWlnaHQgaXMgYDBgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQoKSB7XG4gIHJldHVybiBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzSGVpZ2h0O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGN1cnJlbnQgc3VwZXIgY2xhc3MgKHJldmVyc2UgaW5oZXJpdGFuY2UpIGRlcHRoIGZvciBhIGRpcmVjdGl2ZS5cbiAqXG4gKiBUaGlzIGlzIGRlc2lnbmVkIHRvIGhlbHAgaW5zdHJ1Y3Rpb24gY29kZSBkaXN0aW5ndWlzaCBkaWZmZXJlbnQgaG9zdEJpbmRpbmdzXG4gKiBjYWxscyBmcm9tIGVhY2ggb3RoZXIgd2hlbiBhIGRpcmVjdGl2ZSBoYXMgZXh0ZW5kZWQgZnJvbSBhbm90aGVyIGRpcmVjdGl2ZS5cbiAqIE5vcm1hbGx5IHVzaW5nIHRoZSBkaXJlY3RpdmUgaWQgdmFsdWUgaXMgZW5vdWdoLCBidXQgd2l0aCB0aGUgY2FzZVxuICogb2YgcGFyZW50L3N1Yi1jbGFzcyBkaXJlY3RpdmUgaW5oZXJpdGFuY2UgbW9yZSBpbmZvcm1hdGlvbiBpcyByZXF1aXJlZC5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBpcyBvbmx5IGFjdGl2ZSB3aGVuIGBob3N0QmluZGluZ2AgZnVuY3Rpb25zIGFyZSBiZWluZyBwcm9jZXNzZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGgoKSB7XG4gIHJldHVybiBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGhQb3NpdGlvbjtcbn1cblxuLyoqXG4gKiBSZXN0b3JlcyBgY29udGV4dFZpZXdEYXRhYCB0byB0aGUgZ2l2ZW4gT3BhcXVlVmlld1N0YXRlIGluc3RhbmNlLlxuICpcbiAqIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgZ2V0Q3VycmVudFZpZXcoKSBpbnN0cnVjdGlvbiB0byBzYXZlIGEgc25hcHNob3RcbiAqIG9mIHRoZSBjdXJyZW50IHZpZXcgYW5kIHJlc3RvcmUgaXQgd2hlbiBsaXN0ZW5lcnMgYXJlIGludm9rZWQuIFRoaXMgYWxsb3dzXG4gKiB3YWxraW5nIHRoZSBkZWNsYXJhdGlvbiB2aWV3IHRyZWUgaW4gbGlzdGVuZXJzIHRvIGdldCB2YXJzIGZyb20gcGFyZW50IHZpZXdzLlxuICpcbiAqIEBwYXJhbSB2aWV3VG9SZXN0b3JlIFRoZSBPcGFxdWVWaWV3U3RhdGUgaW5zdGFuY2UgdG8gcmVzdG9yZS5cbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtXJlc3RvcmVWaWV3KHZpZXdUb1Jlc3RvcmU6IE9wYXF1ZVZpZXdTdGF0ZSkge1xuICBjb250ZXh0TFZpZXcgPSB2aWV3VG9SZXN0b3JlIGFzIGFueSBhcyBMVmlldztcbn1cblxuLyoqIFVzZWQgdG8gc2V0IHRoZSBwYXJlbnQgcHJvcGVydHkgd2hlbiBub2RlcyBhcmUgY3JlYXRlZCBhbmQgdHJhY2sgcXVlcnkgcmVzdWx0cy4gKi9cbmxldCBwcmV2aW91c09yUGFyZW50VE5vZGU6IFROb2RlO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJldmlvdXNPclBhcmVudFROb2RlKCk6IFROb2RlIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gcHJldmlvdXNPclBhcmVudFROb2RlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0UHJldmlvdXNPclBhcmVudFROb2RlKHROb2RlOiBUTm9kZSwgX2lzUGFyZW50OiBib29sZWFuKSB7XG4gIHByZXZpb3VzT3JQYXJlbnRUTm9kZSA9IHROb2RlO1xuICBpc1BhcmVudCA9IF9pc1BhcmVudDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFROb2RlQW5kVmlld0RhdGEodE5vZGU6IFROb2RlLCB2aWV3OiBMVmlldykge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TFZpZXdPclVuZGVmaW5lZCh2aWV3KTtcbiAgcHJldmlvdXNPclBhcmVudFROb2RlID0gdE5vZGU7XG4gIGxWaWV3ID0gdmlldztcbn1cblxuLyoqXG4gKiBJZiBgaXNQYXJlbnRgIGlzOlxuICogIC0gYHRydWVgOiB0aGVuIGBwcmV2aW91c09yUGFyZW50VE5vZGVgIHBvaW50cyB0byBhIHBhcmVudCBub2RlLlxuICogIC0gYGZhbHNlYDogdGhlbiBgcHJldmlvdXNPclBhcmVudFROb2RlYCBwb2ludHMgdG8gcHJldmlvdXMgbm9kZSAoc2libGluZykuXG4gKi9cbmxldCBpc1BhcmVudDogYm9vbGVhbjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldElzUGFyZW50KCk6IGJvb2xlYW4ge1xuICAvLyB0b3AgbGV2ZWwgdmFyaWFibGVzIHNob3VsZCBub3QgYmUgZXhwb3J0ZWQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgKFBFUkZfTk9URVMubWQpXG4gIHJldHVybiBpc1BhcmVudDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldElzTm90UGFyZW50KCk6IHZvaWQge1xuICBpc1BhcmVudCA9IGZhbHNlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNldElzUGFyZW50KCk6IHZvaWQge1xuICBpc1BhcmVudCA9IHRydWU7XG59XG5cblxuLyoqIENoZWNrcyB3aGV0aGVyIGEgZ2l2ZW4gdmlldyBpcyBpbiBjcmVhdGlvbiBtb2RlICovXG5leHBvcnQgZnVuY3Rpb24gaXNDcmVhdGlvbk1vZGUodmlldzogTFZpZXcgPSBsVmlldyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKHZpZXdbRkxBR1NdICYgTFZpZXdGbGFncy5DcmVhdGlvbk1vZGUpID09PSBMVmlld0ZsYWdzLkNyZWF0aW9uTW9kZTtcbn1cblxuLyoqXG4gKiBTdGF0ZSBvZiB0aGUgY3VycmVudCB2aWV3IGJlaW5nIHByb2Nlc3NlZC5cbiAqXG4gKiBBbiBhcnJheSBvZiBub2RlcyAodGV4dCwgZWxlbWVudCwgY29udGFpbmVyLCBldGMpLCBwaXBlcywgdGhlaXIgYmluZGluZ3MsIGFuZFxuICogYW55IGxvY2FsIHZhcmlhYmxlcyB0aGF0IG5lZWQgdG8gYmUgc3RvcmVkIGJldHdlZW4gaW52b2NhdGlvbnMuXG4gKi9cbmxldCBsVmlldzogTFZpZXc7XG5cbi8qKlxuICogVGhlIGxhc3Qgdmlld0RhdGEgcmV0cmlldmVkIGJ5IG5leHRDb250ZXh0KCkuXG4gKiBBbGxvd3MgYnVpbGRpbmcgbmV4dENvbnRleHQoKSBhbmQgcmVmZXJlbmNlKCkgY2FsbHMuXG4gKlxuICogZS5nLiBjb25zdCBpbm5lciA9IHgoKS4kaW1wbGljaXQ7IGNvbnN0IG91dGVyID0geCgpLiRpbXBsaWNpdDtcbiAqL1xubGV0IGNvbnRleHRMVmlldzogTFZpZXcgPSBudWxsICE7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250ZXh0TFZpZXcoKTogTFZpZXcge1xuICAvLyB0b3AgbGV2ZWwgdmFyaWFibGVzIHNob3VsZCBub3QgYmUgZXhwb3J0ZWQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgKFBFUkZfTk9URVMubWQpXG4gIHJldHVybiBjb250ZXh0TFZpZXc7XG59XG5cbi8qKlxuICogSW4gdGhpcyBtb2RlLCBhbnkgY2hhbmdlcyBpbiBiaW5kaW5ncyB3aWxsIHRocm93IGFuIEV4cHJlc3Npb25DaGFuZ2VkQWZ0ZXJDaGVja2VkIGVycm9yLlxuICpcbiAqIE5lY2Vzc2FyeSB0byBzdXBwb3J0IENoYW5nZURldGVjdG9yUmVmLmNoZWNrTm9DaGFuZ2VzKCkuXG4gKi9cbmxldCBjaGVja05vQ2hhbmdlc01vZGUgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoZWNrTm9DaGFuZ2VzTW9kZSgpOiBib29sZWFuIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gY2hlY2tOb0NoYW5nZXNNb2RlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0Q2hlY2tOb0NoYW5nZXNNb2RlKG1vZGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY2hlY2tOb0NoYW5nZXNNb2RlID0gbW9kZTtcbn1cblxuLyoqXG4gKiBUaGUgcm9vdCBpbmRleCBmcm9tIHdoaWNoIHB1cmUgZnVuY3Rpb24gaW5zdHJ1Y3Rpb25zIHNob3VsZCBjYWxjdWxhdGUgdGhlaXIgYmluZGluZ1xuICogaW5kaWNlcy4gSW4gY29tcG9uZW50IHZpZXdzLCB0aGlzIGlzIFRWaWV3LmJpbmRpbmdTdGFydEluZGV4LiBJbiBhIGhvc3QgYmluZGluZ1xuICogY29udGV4dCwgdGhpcyBpcyB0aGUgVFZpZXcuZXhwYW5kb1N0YXJ0SW5kZXggKyBhbnkgZGlycy9ob3N0VmFycyBiZWZvcmUgdGhlIGdpdmVuIGRpci5cbiAqL1xubGV0IGJpbmRpbmdSb290SW5kZXg6IG51bWJlciA9IC0xO1xuXG4vLyB0b3AgbGV2ZWwgdmFyaWFibGVzIHNob3VsZCBub3QgYmUgZXhwb3J0ZWQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgKFBFUkZfTk9URVMubWQpXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmluZGluZ1Jvb3QoKSB7XG4gIHJldHVybiBiaW5kaW5nUm9vdEluZGV4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0QmluZGluZ1Jvb3QodmFsdWU6IG51bWJlcikge1xuICBiaW5kaW5nUm9vdEluZGV4ID0gdmFsdWU7XG59XG5cbi8qKlxuICogQ3VycmVudCBpbmRleCBvZiBhIFZpZXcgb3IgQ29udGVudCBRdWVyeSB3aGljaCBuZWVkcyB0byBiZSBwcm9jZXNzZWQgbmV4dC5cbiAqIFdlIGl0ZXJhdGUgb3ZlciB0aGUgbGlzdCBvZiBRdWVyaWVzIGFuZCBpbmNyZW1lbnQgY3VycmVudCBxdWVyeSBpbmRleCBhdCBldmVyeSBzdGVwLlxuICovXG5sZXQgY3VycmVudFF1ZXJ5SW5kZXg6IG51bWJlciA9IDA7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJyZW50UXVlcnlJbmRleCgpOiBudW1iZXIge1xuICAvLyB0b3AgbGV2ZWwgdmFyaWFibGVzIHNob3VsZCBub3QgYmUgZXhwb3J0ZWQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgKFBFUkZfTk9URVMubWQpXG4gIHJldHVybiBjdXJyZW50UXVlcnlJbmRleDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEN1cnJlbnRRdWVyeUluZGV4KHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgY3VycmVudFF1ZXJ5SW5kZXggPSB2YWx1ZTtcbn1cblxuLyoqXG4gKiBTd2FwIHRoZSBjdXJyZW50IHN0YXRlIHdpdGggYSBuZXcgc3RhdGUuXG4gKlxuICogRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgd2Ugc3RvcmUgdGhlIHN0YXRlIGluIHRoZSB0b3AgbGV2ZWwgb2YgdGhlIG1vZHVsZS5cbiAqIFRoaXMgd2F5IHdlIG1pbmltaXplIHRoZSBudW1iZXIgb2YgcHJvcGVydGllcyB0byByZWFkLiBXaGVuZXZlciBhIG5ldyB2aWV3XG4gKiBpcyBlbnRlcmVkIHdlIGhhdmUgdG8gc3RvcmUgdGhlIHN0YXRlIGZvciBsYXRlciwgYW5kIHdoZW4gdGhlIHZpZXcgaXNcbiAqIGV4aXRlZCB0aGUgc3RhdGUgaGFzIHRvIGJlIHJlc3RvcmVkXG4gKlxuICogQHBhcmFtIG5ld1ZpZXcgTmV3IHN0YXRlIHRvIGJlY29tZSBhY3RpdmVcbiAqIEBwYXJhbSBob3N0IEVsZW1lbnQgdG8gd2hpY2ggdGhlIFZpZXcgaXMgYSBjaGlsZCBvZlxuICogQHJldHVybnMgdGhlIHByZXZpb3VzIHN0YXRlO1xuICovXG5leHBvcnQgZnVuY3Rpb24gZW50ZXJWaWV3KG5ld1ZpZXc6IExWaWV3LCBob3N0VE5vZGU6IFRFbGVtZW50Tm9kZSB8IFRWaWV3Tm9kZSB8IG51bGwpOiBMVmlldyB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRMVmlld09yVW5kZWZpbmVkKG5ld1ZpZXcpO1xuICBjb25zdCBvbGRWaWV3ID0gbFZpZXc7XG4gIGlmIChuZXdWaWV3KSB7XG4gICAgY29uc3QgdFZpZXcgPSBuZXdWaWV3W1RWSUVXXTtcbiAgICBiaW5kaW5nUm9vdEluZGV4ID0gdFZpZXcuYmluZGluZ1N0YXJ0SW5kZXg7XG4gIH1cblxuICBwcmV2aW91c09yUGFyZW50VE5vZGUgPSBob3N0VE5vZGUgITtcbiAgaXNQYXJlbnQgPSB0cnVlO1xuXG4gIGxWaWV3ID0gY29udGV4dExWaWV3ID0gbmV3VmlldztcbiAgcmV0dXJuIG9sZFZpZXc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBuZXh0Q29udGV4dEltcGw8VCA9IGFueT4obGV2ZWw6IG51bWJlciA9IDEpOiBUIHtcbiAgY29udGV4dExWaWV3ID0gd2Fsa1VwVmlld3MobGV2ZWwsIGNvbnRleHRMVmlldyAhKTtcbiAgcmV0dXJuIGNvbnRleHRMVmlld1tDT05URVhUXSBhcyBUO1xufVxuXG5mdW5jdGlvbiB3YWxrVXBWaWV3cyhuZXN0aW5nTGV2ZWw6IG51bWJlciwgY3VycmVudFZpZXc6IExWaWV3KTogTFZpZXcge1xuICB3aGlsZSAobmVzdGluZ0xldmVsID4gMCkge1xuICAgIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKFxuICAgICAgICAgICAgICAgICAgICAgY3VycmVudFZpZXdbREVDTEFSQVRJT05fVklFV10sXG4gICAgICAgICAgICAgICAgICAgICAnRGVjbGFyYXRpb24gdmlldyBzaG91bGQgYmUgZGVmaW5lZCBpZiBuZXN0aW5nIGxldmVsIGlzIGdyZWF0ZXIgdGhhbiAwLicpO1xuICAgIGN1cnJlbnRWaWV3ID0gY3VycmVudFZpZXdbREVDTEFSQVRJT05fVklFV10gITtcbiAgICBuZXN0aW5nTGV2ZWwtLTtcbiAgfVxuICByZXR1cm4gY3VycmVudFZpZXc7XG59XG5cbi8qKlxuICogUmVzZXRzIHRoZSBhcHBsaWNhdGlvbiBzdGF0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0Q29tcG9uZW50U3RhdGUoKSB7XG4gIGlzUGFyZW50ID0gZmFsc2U7XG4gIHByZXZpb3VzT3JQYXJlbnRUTm9kZSA9IG51bGwgITtcbiAgZWxlbWVudERlcHRoQ291bnQgPSAwO1xuICBiaW5kaW5nc0VuYWJsZWQgPSB0cnVlO1xufVxuXG4vKipcbiAqIFVzZWQgaW4gbGlldSBvZiBlbnRlclZpZXcgdG8gbWFrZSBpdCBjbGVhciB3aGVuIHdlIGFyZSBleGl0aW5nIGEgY2hpbGQgdmlldy4gVGhpcyBtYWtlc1xuICogdGhlIGRpcmVjdGlvbiBvZiB0cmF2ZXJzYWwgKHVwIG9yIGRvd24gdGhlIHZpZXcgdHJlZSkgYSBiaXQgY2xlYXJlci5cbiAqXG4gKiBAcGFyYW0gbmV3VmlldyBOZXcgc3RhdGUgdG8gYmVjb21lIGFjdGl2ZVxuICogQHBhcmFtIHNhZmVUb1J1bkhvb2tzIFdoZXRoZXIgdGhlIHJ1bnRpbWUgaXMgaW4gYSBzdGF0ZSB3aGVyZSBydW5uaW5nIGxpZmVjeWNsZSBob29rcyBpcyB2YWxpZC5cbiAqIFRoaXMgaXMgbm90IGFsd2F5cyB0aGUgY2FzZSAoZm9yIGV4YW1wbGUsIHRoZSBhcHBsaWNhdGlvbiBtYXkgaGF2ZSBjcmFzaGVkIGFuZCBgbGVhdmVWaWV3YCBpc1xuICogYmVpbmcgZXhlY3V0ZWQgd2hpbGUgdW53aW5kaW5nIHRoZSBjYWxsIHN0YWNrKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlYXZlVmlldyhuZXdWaWV3OiBMVmlldywgc2FmZVRvUnVuSG9va3M6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgdFZpZXcgPSBsVmlld1tUVklFV107XG4gIGlmIChpc0NyZWF0aW9uTW9kZShsVmlldykpIHtcbiAgICBsVmlld1tGTEFHU10gJj0gfkxWaWV3RmxhZ3MuQ3JlYXRpb25Nb2RlO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICByZXNldFByZU9yZGVySG9va0ZsYWdzKGxWaWV3KTtcbiAgICAgIHNhZmVUb1J1bkhvb2tzICYmIGV4ZWN1dGVIb29rcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsVmlldywgdFZpZXcudmlld0hvb2tzLCB0Vmlldy52aWV3Q2hlY2tIb29rcywgY2hlY2tOb0NoYW5nZXNNb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluaXRQaGFzZVN0YXRlLkFmdGVyVmlld0luaXRIb29rc1RvQmVSdW4sIHVuZGVmaW5lZCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIC8vIFZpZXdzIGFyZSBjbGVhbiBhbmQgaW4gdXBkYXRlIG1vZGUgYWZ0ZXIgYmVpbmcgY2hlY2tlZCwgc28gdGhlc2UgYml0cyBhcmUgY2xlYXJlZFxuICAgICAgbFZpZXdbRkxBR1NdICY9IH4oTFZpZXdGbGFncy5EaXJ0eSB8IExWaWV3RmxhZ3MuRmlyc3RMVmlld1Bhc3MpO1xuICAgICAgbFZpZXdbQklORElOR19JTkRFWF0gPSB0Vmlldy5iaW5kaW5nU3RhcnRJbmRleDtcbiAgICB9XG4gIH1cbiAgc2V0Q2FjaGVkU3R5bGluZ0NvbnRleHQobnVsbCk7XG4gIGVudGVyVmlldyhuZXdWaWV3LCBudWxsKTtcbn1cblxubGV0IF9zZWxlY3RlZEluZGV4ID0gLTE7XG5cbi8qKlxuICogR2V0cyB0aGUgbW9zdCByZWNlbnQgaW5kZXggcGFzc2VkIHRvIHtAbGluayBzZWxlY3R9XG4gKlxuICogVXNlZCB3aXRoIHtAbGluayBwcm9wZXJ0eX0gaW5zdHJ1Y3Rpb24gKGFuZCBtb3JlIGluIHRoZSBmdXR1cmUpIHRvIGlkZW50aWZ5IHRoZSBpbmRleCBpbiB0aGVcbiAqIGN1cnJlbnQgYExWaWV3YCB0byBhY3Qgb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWxlY3RlZEluZGV4KCkge1xuICByZXR1cm4gX3NlbGVjdGVkSW5kZXg7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgbW9zdCByZWNlbnQgaW5kZXggcGFzc2VkIHRvIHtAbGluayBzZWxlY3R9XG4gKlxuICogVXNlZCB3aXRoIHtAbGluayBwcm9wZXJ0eX0gaW5zdHJ1Y3Rpb24gKGFuZCBtb3JlIGluIHRoZSBmdXR1cmUpIHRvIGlkZW50aWZ5IHRoZSBpbmRleCBpbiB0aGVcbiAqIGN1cnJlbnQgYExWaWV3YCB0byBhY3Qgb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRTZWxlY3RlZEluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgX3NlbGVjdGVkSW5kZXggPSBpbmRleDtcblxuICAvLyByZW1vdmUgdGhlIHN0eWxpbmcgY29udGV4dCBmcm9tIHRoZSBjYWNoZVxuICAvLyBiZWNhdXNlIHdlIGFyZSBub3cgb24gYSBkaWZmZXJlbnQgZWxlbWVudFxuICBzZXRDYWNoZWRTdHlsaW5nQ29udGV4dChudWxsKTtcbn1cblxuXG5sZXQgX2N1cnJlbnROYW1lc3BhY2U6IHN0cmluZ3xudWxsID0gbnVsbDtcblxuLyoqXG4gKiBTZXRzIHRoZSBuYW1lc3BhY2UgdXNlZCB0byBjcmVhdGUgZWxlbWVudHMgdG8gYCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZydgIGluIGdsb2JhbCBzdGF0ZS5cbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtW5hbWVzcGFjZVNWRygpIHtcbiAgX2N1cnJlbnROYW1lc3BhY2UgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIG5hbWVzcGFjZSB1c2VkIHRvIGNyZWF0ZSBlbGVtZW50cyB0byBgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aE1MLydgIGluIGdsb2JhbCBzdGF0ZS5cbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtW5hbWVzcGFjZU1hdGhNTCgpIHtcbiAgX2N1cnJlbnROYW1lc3BhY2UgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoTUwvJztcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSBuYW1lc3BhY2UgdXNlZCB0byBjcmVhdGUgZWxlbWVudHMgbm8gYG51bGxgLCB3aGljaCBmb3JjZXMgZWxlbWVudCBjcmVhdGlvbiB0byB1c2VcbiAqIGBjcmVhdGVFbGVtZW50YCByYXRoZXIgdGhhbiBgY3JlYXRlRWxlbWVudE5TYC5cbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtW5hbWVzcGFjZUhUTUwoKSB7XG4gIF9jdXJyZW50TmFtZXNwYWNlID0gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5hbWVzcGFjZSgpOiBzdHJpbmd8bnVsbCB7XG4gIHJldHVybiBfY3VycmVudE5hbWVzcGFjZTtcbn1cbiJdfQ==