@angular/core
Version:
Angular - the core framework
311 lines • 37.5 kB
JavaScript
/**
* @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 { assertDataInRange } from '../util/assert';
import { assertComponentType } from './assert';
import { getComponentDef } from './definition';
import { diPublicInInjector, getOrCreateNodeInjectorForNode } from './di';
import { registerPostOrderHooks, registerPreOrderHooks } from './hooks';
import { CLEAN_PROMISE, addToViewTree, createLView, createTView, getOrCreateTNode, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews } from './instructions/shared';
import { domRendererFactory3 } from './interfaces/renderer';
import { CONTEXT, FLAGS, HEADER_OFFSET, HOST, RENDERER, TVIEW } from './interfaces/view';
import { applyOnCreateInstructions } from './node_util';
import { enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setActiveHostElement } from './state';
import { renderInitialClasses, renderInitialStyles } from './styling/class_and_style_bindings';
import { publishDefaultGlobalUtils } from './util/global_utils';
import { defaultScheduler, stringifyForError } from './util/misc_utils';
import { getRootContext } from './util/view_traversal_utils';
import { readPatchedLView, resetPreOrderHookFlags } from './util/view_utils';
/**
* Options that control how the component should be bootstrapped.
* @record
*/
export function CreateComponentOptions() { }
if (false) {
/**
* Which renderer factory to use.
* @type {?|undefined}
*/
CreateComponentOptions.prototype.rendererFactory;
/**
* A custom sanitizer instance
* @type {?|undefined}
*/
CreateComponentOptions.prototype.sanitizer;
/**
* A custom animation player handler
* @type {?|undefined}
*/
CreateComponentOptions.prototype.playerHandler;
/**
* Host element on which the component will be bootstrapped. If not specified,
* the component definition's `tag` is used to query the existing DOM for the
* element to bootstrap.
* @type {?|undefined}
*/
CreateComponentOptions.prototype.host;
/**
* Module injector for the component. If unspecified, the injector will be NULL_INJECTOR.
* @type {?|undefined}
*/
CreateComponentOptions.prototype.injector;
/**
* List of features to be applied to the created component. Features are simply
* functions that decorate a component with a certain behavior.
*
* Typically, the features in this list are features that cannot be added to the
* other features list in the component definition because they rely on other factors.
*
* Example: `LifecycleHooksFeature` is a function that adds lifecycle hook capabilities
* to root components in a tree-shakable way. It cannot be added to the component
* features list because there's no way of knowing when the component will be used as
* a root component.
* @type {?|undefined}
*/
CreateComponentOptions.prototype.hostFeatures;
/**
* A function which is used to schedule change detection work in the future.
*
* When marking components as dirty, it is necessary to schedule the work of
* change detection in the future. This is done to coalesce multiple
* {\@link markDirty} calls into a single changed detection processing.
*
* The default value of the scheduler is the `requestAnimationFrame` function.
*
* It is also useful to override this function for testing purposes.
* @type {?|undefined}
*/
CreateComponentOptions.prototype.scheduler;
}
// TODO: A hack to not pull in the NullInjector from @angular/core.
const ɵ0 = /**
* @param {?} token
* @param {?=} notFoundValue
* @return {?}
*/
(token, notFoundValue) => {
throw new Error('NullInjector: Not found: ' + stringifyForError(token));
};
/** @type {?} */
export const NULL_INJECTOR = {
get: (ɵ0)
};
/**
* Bootstraps a Component into an existing host element and returns an instance
* of the component.
*
* Use this function to bootstrap a component into the DOM tree. Each invocation
* of this function will create a separate tree of components, injectors and
* change detection cycles and lifetimes. To dynamically insert a new component
* into an existing tree such that it shares the same injection, change detection
* and object lifetime, use {\@link ViewContainer#createComponent}.
*
* @template T
* @param {?} componentType Component to bootstrap
* @param {?=} opts
* @return {?}
*/
export function renderComponent(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts = {}) {
ngDevMode && publishDefaultGlobalUtils();
ngDevMode && assertComponentType(componentType);
// this is preemptively set to avoid having test and debug code accidentally
// read data from a previous application state...
setActiveHostElement(null);
/** @type {?} */
const rendererFactory = opts.rendererFactory || domRendererFactory3;
/** @type {?} */
const sanitizer = opts.sanitizer || null;
/** @type {?} */
const componentDef = (/** @type {?} */ (getComponentDef(componentType)));
if (componentDef.type != componentType)
componentDef.type = componentType;
// The first index of the first selector is the tag name.
/** @type {?} */
const componentTag = (/** @type {?} */ ((/** @type {?} */ ((/** @type {?} */ (componentDef.selectors))[0]))[0]));
/** @type {?} */
const hostRNode = locateHostElement(rendererFactory, opts.host || componentTag);
/** @type {?} */
const rootFlags = componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
16 /* CheckAlways */ | 512 /* IsRoot */;
/** @type {?} */
const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
/** @type {?} */
const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
/** @type {?} */
const rootView = createLView(null, createTView(-1, null, 1, 0, null, null, null, null), rootContext, rootFlags, null, null, rendererFactory, renderer, undefined, opts.injector || null);
/** @type {?} */
const oldView = enterView(rootView, null);
/** @type {?} */
let component;
// Will become true if the `try` block executes with no errors.
/** @type {?} */
let safeToRunHooks = false;
try {
if (rendererFactory.begin)
rendererFactory.begin();
/** @type {?} */
const componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
addToViewTree(rootView, componentView);
refreshDescendantViews(rootView); // creation mode pass
rootView[FLAGS] &= ~4 /* CreationMode */;
resetPreOrderHookFlags(rootView);
refreshDescendantViews(rootView); // update mode pass
safeToRunHooks = true;
}
finally {
leaveView(oldView, safeToRunHooks);
if (rendererFactory.end)
rendererFactory.end();
}
return component;
}
/**
* Creates the root component view and the root component node.
*
* @param {?} rNode Render host element.
* @param {?} def ComponentDef
* @param {?} rootView The parent view where the host node is stored
* @param {?} rendererFactory
* @param {?} renderer The current renderer
* @param {?=} sanitizer The sanitizer, if provided
*
* @return {?} Component view created
*/
export function createRootComponentView(rNode, def, rootView, rendererFactory, renderer, sanitizer) {
resetComponentState();
/** @type {?} */
const tView = rootView[TVIEW];
ngDevMode && assertDataInRange(rootView, 0 + HEADER_OFFSET);
rootView[0 + HEADER_OFFSET] = rNode;
/** @type {?} */
const tNode = getOrCreateTNode(tView, null, 0, 3 /* Element */, null, null);
/** @type {?} */
const componentView = createLView(rootView, getOrCreateTView(def), null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, rootView[HEADER_OFFSET], tNode, rendererFactory, renderer, sanitizer);
if (tView.firstTemplatePass) {
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), rootView, def.type);
tNode.flags = 1 /* isComponent */;
initNodeFlags(tNode, rootView.length, 1);
queueComponentIndexForCheck(tNode);
}
// Store component view at node index, with node as the HOST
return rootView[HEADER_OFFSET] = componentView;
}
/**
* Creates a root component and sets it up with features and host bindings. Shared by
* renderComponent() and ViewContainerRef.createComponent().
* @template T
* @param {?} componentView
* @param {?} componentDef
* @param {?} rootView
* @param {?} rootContext
* @param {?} hostFeatures
* @return {?}
*/
export function createRootComponent(componentView, componentDef, rootView, rootContext, hostFeatures) {
/** @type {?} */
const tView = rootView[TVIEW];
// Create directive instance with factory() and store at next index in viewData
/** @type {?} */
const component = instantiateRootComponent(tView, rootView, componentDef);
rootContext.components.push(component);
componentView[CONTEXT] = component;
hostFeatures && hostFeatures.forEach((/**
* @param {?} feature
* @return {?}
*/
(feature) => feature(component, componentDef)));
// We want to generate an empty QueryList for root content queries for backwards
// compatibility with ViewEngine.
if (componentDef.contentQueries) {
componentDef.contentQueries(1 /* Create */, component, rootView.length - 1);
}
/** @type {?} */
const rootTNode = getPreviousOrParentTNode();
if (tView.firstTemplatePass && componentDef.hostBindings) {
/** @type {?} */
const elementIndex = rootTNode.index - HEADER_OFFSET;
setActiveHostElement(elementIndex);
/** @type {?} */
const expando = (/** @type {?} */ (tView.expandoInstructions));
invokeHostBindingsInCreationMode(componentDef, expando, component, rootTNode, tView.firstTemplatePass);
rootTNode.onElementCreationFns && applyOnCreateInstructions(rootTNode);
setActiveHostElement(null);
}
if (rootTNode.stylingTemplate) {
/** @type {?} */
const native = (/** @type {?} */ ((/** @type {?} */ (componentView[HOST]))));
renderInitialClasses(native, rootTNode.stylingTemplate, componentView[RENDERER]);
renderInitialStyles(native, rootTNode.stylingTemplate, componentView[RENDERER]);
}
return component;
}
/**
* @param {?=} scheduler
* @param {?=} playerHandler
* @return {?}
*/
export function createRootContext(scheduler, playerHandler) {
return {
components: [],
scheduler: scheduler || defaultScheduler,
clean: CLEAN_PROMISE,
playerHandler: playerHandler || null,
flags: 0 /* Empty */
};
}
/**
* Used to enable lifecycle hooks on the root component.
*
* Include this feature when calling `renderComponent` if the root component
* you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
* be called properly.
*
* Example:
*
* ```
* renderComponent(AppComponent, {features: [RootLifecycleHooks]});
* ```
* @param {?} component
* @param {?} def
* @return {?}
*/
export function LifecycleHooksFeature(component, def) {
/** @type {?} */
const rootTView = (/** @type {?} */ (readPatchedLView(component)))[TVIEW];
/** @type {?} */
const dirIndex = rootTView.data.length - 1;
registerPreOrderHooks(dirIndex, def, rootTView, -1, -1, -1);
// TODO(misko): replace `as TNode` with createTNode call. (needs refactoring to lose dep on
// LNode).
registerPostOrderHooks(rootTView, (/** @type {?} */ ({ directiveStart: dirIndex, directiveEnd: dirIndex + 1 })));
}
/**
* Wait on component until it is rendered.
*
* This function returns a `Promise` which is resolved when the component's
* change detection is executed. This is determined by finding the scheduler
* associated with the `component`'s render tree and waiting until the scheduler
* flushes. If nothing is scheduled, the function returns a resolved promise.
*
* Example:
* ```
* await whenRendered(myComponent);
* ```
*
* @param {?} component Component to wait upon
* @return {?} Promise which resolves when the component is rendered.
*/
export function whenRendered(component) {
return getRootContext(component).clean;
}
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvcmVuZGVyMy9jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFhQSxPQUFPLEVBQUMsaUJBQWlCLEVBQWMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5RCxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDN0MsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsOEJBQThCLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDeEUsT0FBTyxFQUFDLHNCQUFzQixFQUFFLHFCQUFxQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLHdCQUF3QixFQUFFLGdDQUFnQyxFQUFFLGlCQUFpQixFQUFFLDJCQUEyQixFQUFFLHNCQUFzQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFJcFIsT0FBTyxFQUF3QyxtQkFBbUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pHLE9BQU8sRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQXFCLFFBQVEsRUFBaUMsS0FBSyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDekksT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3RELE9BQU8sRUFBQyxTQUFTLEVBQUUsd0JBQXdCLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQ2xILE9BQU8sRUFBQyxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQzdGLE9B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OUIsQ0FBQztBQUNKLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZUQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLFNBQWMsRUFBRSxHQUFzQjs7VUFDcEUsU0FBUyxHQUFHLG1CQUFBLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDOztVQUNoRCxRQUFRLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztJQUUxQyxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVELDJGQUEyRjtJQUMzRixVQUFVO0lBQ1Ysc0JBQXNCLENBQ2xCLFNBQVMsRUFBRSxtQkFBQSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFFBQVEsR0FBRyxDQUFDLEVBQUUsRUFBUyxDQUFDLENBQUM7QUFDcEYsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrQkQsTUFBTSxVQUFVLFlBQVksQ0FBQyxTQUFjO0lBQ3pDLE9BQU8sY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssQ0FBQztBQUN6QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG4vLyBXZSBhcmUgdGVtcG9yYXJpbHkgaW1wb3J0aW5nIHRoZSBleGlzdGluZyB2aWV3RW5naW5lIGZyb20gY29yZSBzbyB3ZSBjYW4gYmUgc3VyZSB3ZSBhcmVcbi8vIGNvcnJlY3RseSBpbXBsZW1lbnRpbmcgaXRzIGludGVyZmFjZXMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuaW1wb3J0IHtUeXBlfSBmcm9tICcuLi9jb3JlJztcbmltcG9ydCB7SW5qZWN0b3J9IGZyb20gJy4uL2RpL2luamVjdG9yJztcbmltcG9ydCB7U2FuaXRpemVyfSBmcm9tICcuLi9zYW5pdGl6YXRpb24vc2VjdXJpdHknO1xuaW1wb3J0IHthc3NlcnREYXRhSW5SYW5nZSwgYXNzZXJ0RXF1YWx9IGZyb20gJy4uL3V0aWwvYXNzZXJ0JztcblxuaW1wb3J0IHthc3NlcnRDb21wb25lbnRUeXBlfSBmcm9tICcuL2Fzc2VydCc7XG5pbXBvcnQge2dldENvbXBvbmVudERlZn0gZnJvbSAnLi9kZWZpbml0aW9uJztcbmltcG9ydCB7ZGlQdWJsaWNJbkluamVjdG9yLCBnZXRPckNyZWF0ZU5vZGVJbmplY3RvckZvck5vZGV9IGZyb20gJy4vZGknO1xuaW1wb3J0IHtyZWdpc3RlclBvc3RPcmRlckhvb2tzLCByZWdpc3RlclByZU9yZGVySG9va3N9IGZyb20gJy4vaG9va3MnO1xuaW1wb3J0IHtDTEVBTl9QUk9NSVNFLCBhZGRUb1ZpZXdUcmVlLCBjcmVhdGVMVmlldywgY3JlYXRlVFZpZXcsIGdldE9yQ3JlYXRlVE5vZGUsIGdldE9yQ3JlYXRlVFZpZXcsIGluaXROb2RlRmxhZ3MsIGluc3RhbnRpYXRlUm9vdENvbXBvbmVudCwgaW52b2tlSG9zdEJpbmRpbmdzSW5DcmVhdGlvbk1vZGUsIGxvY2F0ZUhvc3RFbGVtZW50LCBxdWV1ZUNvbXBvbmVudEluZGV4Rm9yQ2hlY2ssIHJlZnJlc2hEZXNjZW5kYW50Vmlld3N9IGZyb20gJy4vaW5zdHJ1Y3Rpb25zL3NoYXJlZCc7XG5pbXBvcnQge0NvbXBvbmVudERlZiwgQ29tcG9uZW50VHlwZSwgUmVuZGVyRmxhZ3N9IGZyb20gJy4vaW50ZXJmYWNlcy9kZWZpbml0aW9uJztcbmltcG9ydCB7VEVsZW1lbnROb2RlLCBUTm9kZSwgVE5vZGVGbGFncywgVE5vZGVUeXBlfSBmcm9tICcuL2ludGVyZmFjZXMvbm9kZSc7XG5pbXBvcnQge1BsYXllckhhbmRsZXJ9IGZyb20gJy4vaW50ZXJmYWNlcy9wbGF5ZXInO1xuaW1wb3J0IHtSRWxlbWVudCwgUmVuZGVyZXIzLCBSZW5kZXJlckZhY3RvcnkzLCBkb21SZW5kZXJlckZhY3RvcnkzfSBmcm9tICcuL2ludGVyZmFjZXMvcmVuZGVyZXInO1xuaW1wb3J0IHtDT05URVhULCBGTEFHUywgSEVBREVSX09GRlNFVCwgSE9TVCwgTFZpZXcsIExWaWV3RmxhZ3MsIFJFTkRFUkVSLCBSb290Q29udGV4dCwgUm9vdENvbnRleHRGbGFncywgVFZJRVd9IGZyb20gJy4vaW50ZXJmYWNlcy92aWV3JztcbmltcG9ydCB7YXBwbHlPbkNyZWF0ZUluc3RydWN0aW9uc30gZnJvbSAnLi9ub2RlX3V0aWwnO1xuaW1wb3J0IHtlbnRlclZpZXcsIGdldFByZXZpb3VzT3JQYXJlbnRUTm9kZSwgbGVhdmVWaWV3LCByZXNldENvbXBvbmVudFN0YXRlLCBzZXRBY3RpdmVIb3N0RWxlbWVudH0gZnJvbSAnLi9zdGF0ZSc7XG5pbXBvcnQge3JlbmRlckluaXRpYWxDbGFzc2VzLCByZW5kZXJJbml0aWFsU3R5bGVzfSBmcm9tICcuL3N0eWxpbmcvY2xhc3NfYW5kX3N0eWxlX2JpbmRpbmdzJztcbmltcG9ydCB7cHVibGlzaERlZmF1bHRHbG9iYWxVdGlsc30gZnJvbSAnLi91dGlsL2dsb2JhbF91dGlscyc7XG5pbXBvcnQge2RlZmF1bHRTY2hlZHVsZXIsIHN0cmluZ2lmeUZvckVycm9yfSBmcm9tICcuL3V0aWwvbWlzY191dGlscyc7XG5pbXBvcnQge2dldFJvb3RDb250ZXh0fSBmcm9tICcuL3V0aWwvdmlld190cmF2ZXJzYWxfdXRpbHMnO1xuaW1wb3J0IHtyZWFkUGF0Y2hlZExWaWV3LCByZXNldFByZU9yZGVySG9va0ZsYWdzfSBmcm9tICcuL3V0aWwvdmlld191dGlscyc7XG5cblxuXG4vKiogT3B0aW9ucyB0aGF0IGNvbnRyb2wgaG93IHRoZSBjb21wb25lbnQgc2hvdWxkIGJlIGJvb3RzdHJhcHBlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlQ29tcG9uZW50T3B0aW9ucyB7XG4gIC8qKiBXaGljaCByZW5kZXJlciBmYWN0b3J5IHRvIHVzZS4gKi9cbiAgcmVuZGVyZXJGYWN0b3J5PzogUmVuZGVyZXJGYWN0b3J5MztcblxuICAvKiogQSBjdXN0b20gc2FuaXRpemVyIGluc3RhbmNlICovXG4gIHNhbml0aXplcj86IFNhbml0aXplcjtcblxuICAvKiogQSBjdXN0b20gYW5pbWF0aW9uIHBsYXllciBoYW5kbGVyICovXG4gIHBsYXllckhhbmRsZXI/OiBQbGF5ZXJIYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBIb3N0IGVsZW1lbnQgb24gd2hpY2ggdGhlIGNvbXBvbmVudCB3aWxsIGJlIGJvb3RzdHJhcHBlZC4gSWYgbm90IHNwZWNpZmllZCxcbiAgICogdGhlIGNvbXBvbmVudCBkZWZpbml0aW9uJ3MgYHRhZ2AgaXMgdXNlZCB0byBxdWVyeSB0aGUgZXhpc3RpbmcgRE9NIGZvciB0aGVcbiAgICogZWxlbWVudCB0byBib290c3RyYXAuXG4gICAqL1xuICBob3N0PzogUkVsZW1lbnR8c3RyaW5nO1xuXG4gIC8qKiBNb2R1bGUgaW5qZWN0b3IgZm9yIHRoZSBjb21wb25lbnQuIElmIHVuc3BlY2lmaWVkLCB0aGUgaW5qZWN0b3Igd2lsbCBiZSBOVUxMX0lOSkVDVE9SLiAqL1xuICBpbmplY3Rvcj86IEluamVjdG9yO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGZlYXR1cmVzIHRvIGJlIGFwcGxpZWQgdG8gdGhlIGNyZWF0ZWQgY29tcG9uZW50LiBGZWF0dXJlcyBhcmUgc2ltcGx5XG4gICAqIGZ1bmN0aW9ucyB0aGF0IGRlY29yYXRlIGEgY29tcG9uZW50IHdpdGggYSBjZXJ0YWluIGJlaGF2aW9yLlxuICAgKlxuICAgKiBUeXBpY2FsbHksIHRoZSBmZWF0dXJlcyBpbiB0aGlzIGxpc3QgYXJlIGZlYXR1cmVzIHRoYXQgY2Fubm90IGJlIGFkZGVkIHRvIHRoZVxuICAgKiBvdGhlciBmZWF0dXJlcyBsaXN0IGluIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbiBiZWNhdXNlIHRoZXkgcmVseSBvbiBvdGhlciBmYWN0b3JzLlxuICAgKlxuICAgKiBFeGFtcGxlOiBgTGlmZWN5Y2xlSG9va3NGZWF0dXJlYCBpcyBhIGZ1bmN0aW9uIHRoYXQgYWRkcyBsaWZlY3ljbGUgaG9vayBjYXBhYmlsaXRpZXNcbiAgICogdG8gcm9vdCBjb21wb25lbnRzIGluIGEgdHJlZS1zaGFrYWJsZSB3YXkuIEl0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGUgY29tcG9uZW50XG4gICAqIGZlYXR1cmVzIGxpc3QgYmVjYXVzZSB0aGVyZSdzIG5vIHdheSBvZiBrbm93aW5nIHdoZW4gdGhlIGNvbXBvbmVudCB3aWxsIGJlIHVzZWQgYXNcbiAgICogYSByb290IGNvbXBvbmVudC5cbiAgICovXG4gIGhvc3RGZWF0dXJlcz86IEhvc3RGZWF0dXJlW107XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gd2hpY2ggaXMgdXNlZCB0byBzY2hlZHVsZSBjaGFuZ2UgZGV0ZWN0aW9uIHdvcmsgaW4gdGhlIGZ1dHVyZS5cbiAgICpcbiAgICogV2hlbiBtYXJraW5nIGNvbXBvbmVudHMgYXMgZGlydHksIGl0IGlzIG5lY2Vzc2FyeSB0byBzY2hlZHVsZSB0aGUgd29yayBvZlxuICAgKiBjaGFuZ2UgZGV0ZWN0aW9uIGluIHRoZSBmdXR1cmUuIFRoaXMgaXMgZG9uZSB0byBjb2FsZXNjZSBtdWx0aXBsZVxuICAgKiB7QGxpbmsgbWFya0RpcnR5fSBjYWxscyBpbnRvIGEgc2luZ2xlIGNoYW5nZWQgZGV0ZWN0aW9uIHByb2Nlc3NpbmcuXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSBzY2hlZHVsZXIgaXMgdGhlIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBJdCBpcyBhbHNvIHVzZWZ1bCB0byBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgKi9cbiAgc2NoZWR1bGVyPzogKHdvcms6ICgpID0+IHZvaWQpID0+IHZvaWQ7XG59XG5cbi8qKiBTZWUgQ3JlYXRlQ29tcG9uZW50T3B0aW9ucy5ob3N0RmVhdHVyZXMgKi9cbnR5cGUgSG9zdEZlYXR1cmUgPSAoPFQ+KGNvbXBvbmVudDogVCwgY29tcG9uZW50RGVmOiBDb21wb25lbnREZWY8VD4pID0+IHZvaWQpO1xuXG4vLyBUT0RPOiBBIGhhY2sgdG8gbm90IHB1bGwgaW4gdGhlIE51bGxJbmplY3RvciBmcm9tIEBhbmd1bGFyL2NvcmUuXG5leHBvcnQgY29uc3QgTlVMTF9JTkpFQ1RPUjogSW5qZWN0b3IgPSB7XG4gIGdldDogKHRva2VuOiBhbnksIG5vdEZvdW5kVmFsdWU/OiBhbnkpID0+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ051bGxJbmplY3RvcjogTm90IGZvdW5kOiAnICsgc3RyaW5naWZ5Rm9yRXJyb3IodG9rZW4pKTtcbiAgfVxufTtcblxuLyoqXG4gKiBCb290c3RyYXBzIGEgQ29tcG9uZW50IGludG8gYW4gZXhpc3RpbmcgaG9zdCBlbGVtZW50IGFuZCByZXR1cm5zIGFuIGluc3RhbmNlXG4gKiBvZiB0aGUgY29tcG9uZW50LlxuICpcbiAqIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIGJvb3RzdHJhcCBhIGNvbXBvbmVudCBpbnRvIHRoZSBET00gdHJlZS4gRWFjaCBpbnZvY2F0aW9uXG4gKiBvZiB0aGlzIGZ1bmN0aW9uIHdpbGwgY3JlYXRlIGEgc2VwYXJhdGUgdHJlZSBvZiBjb21wb25lbnRzLCBpbmplY3RvcnMgYW5kXG4gKiBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlcyBhbmQgbGlmZXRpbWVzLiBUbyBkeW5hbWljYWxseSBpbnNlcnQgYSBuZXcgY29tcG9uZW50XG4gKiBpbnRvIGFuIGV4aXN0aW5nIHRyZWUgc3VjaCB0aGF0IGl0IHNoYXJlcyB0aGUgc2FtZSBpbmplY3Rpb24sIGNoYW5nZSBkZXRlY3Rpb25cbiAqIGFuZCBvYmplY3QgbGlmZXRpbWUsIHVzZSB7QGxpbmsgVmlld0NvbnRhaW5lciNjcmVhdGVDb21wb25lbnR9LlxuICpcbiAqIEBwYXJhbSBjb21wb25lbnRUeXBlIENvbXBvbmVudCB0byBib290c3RyYXBcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIHBhcmFtZXRlcnMgd2hpY2ggY29udHJvbCBib290c3RyYXBwaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJDb21wb25lbnQ8VD4oXG4gICAgY29tcG9uZW50VHlwZTogQ29tcG9uZW50VHlwZTxUPnxcbiAgICAgICAgVHlwZTxUPi8qIFR5cGUgYXMgd29ya2Fyb3VuZCBmb3I6IE1pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy80ODgxICovXG4gICAgLFxuICAgIG9wdHM6IENyZWF0ZUNvbXBvbmVudE9wdGlvbnMgPSB7fSk6IFQge1xuICBuZ0Rldk1vZGUgJiYgcHVibGlzaERlZmF1bHRHbG9iYWxVdGlscygpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0Q29tcG9uZW50VHlwZShjb21wb25lbnRUeXBlKTtcblxuICAvLyB0aGlzIGlzIHByZWVtcHRpdmVseSBzZXQgdG8gYXZvaWQgaGF2aW5nIHRlc3QgYW5kIGRlYnVnIGNvZGUgYWNjaWRlbnRhbGx5XG4gIC8vIHJlYWQgZGF0YSBmcm9tIGEgcHJldmlvdXMgYXBwbGljYXRpb24gc3RhdGUuLi5cbiAgc2V0QWN0aXZlSG9zdEVsZW1lbnQobnVsbCk7XG5cbiAgY29uc3QgcmVuZGVyZXJGYWN0b3J5ID0gb3B0cy5yZW5kZXJlckZhY3RvcnkgfHwgZG9tUmVuZGVyZXJGYWN0b3J5MztcbiAgY29uc3Qgc2FuaXRpemVyID0gb3B0cy5zYW5pdGl6ZXIgfHwgbnVsbDtcbiAgY29uc3QgY29tcG9uZW50RGVmID0gZ2V0Q29tcG9uZW50RGVmPFQ+KGNvbXBvbmVudFR5cGUpICE7XG4gIGlmIChjb21wb25lbnREZWYudHlwZSAhPSBjb21wb25lbnRUeXBlKSBjb21wb25lbnREZWYudHlwZSA9IGNvbXBvbmVudFR5cGU7XG5cbiAgLy8gVGhlIGZpcnN0IGluZGV4IG9mIHRoZSBmaXJzdCBzZWxlY3RvciBpcyB0aGUgdGFnIG5hbWUuXG4gIGNvbnN0IGNvbXBvbmVudFRhZyA9IGNvbXBvbmVudERlZi5zZWxlY3RvcnMgIVswXSAhWzBdIGFzIHN0cmluZztcbiAgY29uc3QgaG9zdFJOb2RlID0gbG9jYXRlSG9zdEVsZW1lbnQocmVuZGVyZXJGYWN0b3J5LCBvcHRzLmhvc3QgfHwgY29tcG9uZW50VGFnKTtcbiAgY29uc3Qgcm9vdEZsYWdzID0gY29tcG9uZW50RGVmLm9uUHVzaCA/IExWaWV3RmxhZ3MuRGlydHkgfCBMVmlld0ZsYWdzLklzUm9vdCA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMVmlld0ZsYWdzLkNoZWNrQWx3YXlzIHwgTFZpZXdGbGFncy5Jc1Jvb3Q7XG4gIGNvbnN0IHJvb3RDb250ZXh0ID0gY3JlYXRlUm9vdENvbnRleHQob3B0cy5zY2hlZHVsZXIsIG9wdHMucGxheWVySGFuZGxlcik7XG5cbiAgY29uc3QgcmVuZGVyZXIgPSByZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIoaG9zdFJOb2RlLCBjb21wb25lbnREZWYpO1xuICBjb25zdCByb290VmlldzogTFZpZXcgPSBjcmVhdGVMVmlldyhcbiAgICAgIG51bGwsIGNyZWF0ZVRWaWV3KC0xLCBudWxsLCAxLCAwLCBudWxsLCBudWxsLCBudWxsLCBudWxsKSwgcm9vdENvbnRleHQsIHJvb3RGbGFncywgbnVsbCwgbnVsbCxcbiAgICAgIHJlbmRlcmVyRmFjdG9yeSwgcmVuZGVyZXIsIHVuZGVmaW5lZCwgb3B0cy5pbmplY3RvciB8fCBudWxsKTtcblxuICBjb25zdCBvbGRWaWV3ID0gZW50ZXJWaWV3KHJvb3RWaWV3LCBudWxsKTtcbiAgbGV0IGNvbXBvbmVudDogVDtcblxuICAvLyBXaWxsIGJlY29tZSB0cnVlIGlmIHRoZSBgdHJ5YCBibG9jayBleGVjdXRlcyB3aXRoIG5vIGVycm9ycy5cbiAgbGV0IHNhZmVUb1J1bkhvb2tzID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgaWYgKHJlbmRlcmVyRmFjdG9yeS5iZWdpbikgcmVuZGVyZXJGYWN0b3J5LmJlZ2luKCk7XG4gICAgY29uc3QgY29tcG9uZW50VmlldyA9IGNyZWF0ZVJvb3RDb21wb25lbnRWaWV3KFxuICAgICAgICBob3N0Uk5vZGUsIGNvbXBvbmVudERlZiwgcm9vdFZpZXcsIHJlbmRlcmVyRmFjdG9yeSwgcmVuZGVyZXIsIHNhbml0aXplcik7XG4gICAgY29tcG9uZW50ID0gY3JlYXRlUm9vdENvbXBvbmVudChcbiAgICAgICAgY29tcG9uZW50VmlldywgY29tcG9uZW50RGVmLCByb290Vmlldywgcm9vdENvbnRleHQsIG9wdHMuaG9zdEZlYXR1cmVzIHx8IG51bGwpO1xuXG4gICAgYWRkVG9WaWV3VHJlZShyb290VmlldywgY29tcG9uZW50Vmlldyk7XG5cbiAgICByZWZyZXNoRGVzY2VuZGFudFZpZXdzKHJvb3RWaWV3KTsgIC8vIGNyZWF0aW9uIG1vZGUgcGFzc1xuICAgIHJvb3RWaWV3W0ZMQUdTXSAmPSB+TFZpZXdGbGFncy5DcmVhdGlvbk1vZGU7XG4gICAgcmVzZXRQcmVPcmRlckhvb2tGbGFncyhyb290Vmlldyk7XG4gICAgcmVmcmVzaERlc2NlbmRhbnRWaWV3cyhyb290Vmlldyk7ICAvLyB1cGRhdGUgbW9kZSBwYXNzXG4gICAgc2FmZVRvUnVuSG9va3MgPSB0cnVlO1xuICB9IGZpbmFsbHkge1xuICAgIGxlYXZlVmlldyhvbGRWaWV3LCBzYWZlVG9SdW5Ib29rcyk7XG4gICAgaWYgKHJlbmRlcmVyRmFjdG9yeS5lbmQpIHJlbmRlcmVyRmFjdG9yeS5lbmQoKTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgcm9vdCBjb21wb25lbnQgdmlldyBhbmQgdGhlIHJvb3QgY29tcG9uZW50IG5vZGUuXG4gKlxuICogQHBhcmFtIHJOb2RlIFJlbmRlciBob3N0IGVsZW1lbnQuXG4gKiBAcGFyYW0gZGVmIENvbXBvbmVudERlZlxuICogQHBhcmFtIHJvb3RWaWV3IFRoZSBwYXJlbnQgdmlldyB3aGVyZSB0aGUgaG9zdCBub2RlIGlzIHN0b3JlZFxuICogQHBhcmFtIHJlbmRlcmVyIFRoZSBjdXJyZW50IHJlbmRlcmVyXG4gKiBAcGFyYW0gc2FuaXRpemVyIFRoZSBzYW5pdGl6ZXIsIGlmIHByb3ZpZGVkXG4gKlxuICogQHJldHVybnMgQ29tcG9uZW50IHZpZXcgY3JlYXRlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUm9vdENvbXBvbmVudFZpZXcoXG4gICAgck5vZGU6IFJFbGVtZW50IHwgbnVsbCwgZGVmOiBDb21wb25lbnREZWY8YW55Piwgcm9vdFZpZXc6IExWaWV3LFxuICAgIHJlbmRlcmVyRmFjdG9yeTogUmVuZGVyZXJGYWN0b3J5MywgcmVuZGVyZXI6IFJlbmRlcmVyMywgc2FuaXRpemVyPzogU2FuaXRpemVyIHwgbnVsbCk6IExWaWV3IHtcbiAgcmVzZXRDb21wb25lbnRTdGF0ZSgpO1xuICBjb25zdCB0VmlldyA9IHJvb3RWaWV3W1RWSUVXXTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERhdGFJblJhbmdlKHJvb3RWaWV3LCAwICsgSEVBREVSX09GRlNFVCk7XG4gIHJvb3RWaWV3WzAgKyBIRUFERVJfT0ZGU0VUXSA9IHJOb2RlO1xuICBjb25zdCB0Tm9kZTogVEVsZW1lbnROb2RlID0gZ2V0T3JDcmVhdGVUTm9kZSh0VmlldywgbnVsbCwgMCwgVE5vZGVUeXBlLkVsZW1lbnQsIG51bGwsIG51bGwpO1xuICBjb25zdCBjb21wb25lbnRWaWV3ID0gY3JlYXRlTFZpZXcoXG4gICAgICByb290VmlldywgZ2V0T3JDcmVhdGVUVmlldyhkZWYpLCBudWxsLCBkZWYub25QdXNoID8gTFZpZXdGbGFncy5EaXJ0eSA6IExWaWV3RmxhZ3MuQ2hlY2tBbHdheXMsXG4gICAgICByb290Vmlld1tIRUFERVJfT0ZGU0VUXSwgdE5vZGUsIHJlbmRlcmVyRmFjdG9yeSwgcmVuZGVyZXIsIHNhbml0aXplcik7XG5cbiAgaWYgKHRWaWV3LmZpcnN0VGVtcGxhdGVQYXNzKSB7XG4gICAgZGlQdWJsaWNJbkluamVjdG9yKGdldE9yQ3JlYXRlTm9kZUluamVjdG9yRm9yTm9kZSh0Tm9kZSwgcm9vdFZpZXcpLCByb290VmlldywgZGVmLnR5cGUpO1xuICAgIHROb2RlLmZsYWdzID0gVE5vZGVGbGFncy5pc0NvbXBvbmVudDtcbiAgICBpbml0Tm9kZUZsYWdzKHROb2RlLCByb290Vmlldy5sZW5ndGgsIDEpO1xuICAgIHF1ZXVlQ29tcG9uZW50SW5kZXhGb3JDaGVjayh0Tm9kZSk7XG4gIH1cblxuICAvLyBTdG9yZSBjb21wb25lbnQgdmlldyBhdCBub2RlIGluZGV4LCB3aXRoIG5vZGUgYXMgdGhlIEhPU1RcbiAgcmV0dXJuIHJvb3RWaWV3W0hFQURFUl9PRkZTRVRdID0gY29tcG9uZW50Vmlldztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgcm9vdCBjb21wb25lbnQgYW5kIHNldHMgaXQgdXAgd2l0aCBmZWF0dXJlcyBhbmQgaG9zdCBiaW5kaW5ncy4gU2hhcmVkIGJ5XG4gKiByZW5kZXJDb21wb25lbnQoKSBhbmQgVmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJvb3RDb21wb25lbnQ8VD4oXG4gICAgY29tcG9uZW50VmlldzogTFZpZXcsIGNvbXBvbmVudERlZjogQ29tcG9uZW50RGVmPFQ+LCByb290VmlldzogTFZpZXcsIHJvb3RDb250ZXh0OiBSb290Q29udGV4dCxcbiAgICBob3N0RmVhdHVyZXM6IEhvc3RGZWF0dXJlW10gfCBudWxsKTogYW55IHtcbiAgY29uc3QgdFZpZXcgPSByb290Vmlld1tUVklFV107XG4gIC8vIENyZWF0ZSBkaXJlY3RpdmUgaW5zdGFuY2Ugd2l0aCBmYWN0b3J5KCkgYW5kIHN0b3JlIGF0IG5leHQgaW5kZXggaW4gdmlld0RhdGFcbiAgY29uc3QgY29tcG9uZW50ID0gaW5zdGFudGlhdGVSb290Q29tcG9uZW50KHRWaWV3LCByb290VmlldywgY29tcG9uZW50RGVmKTtcblxuICByb290Q29udGV4dC5jb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbiAgY29tcG9uZW50Vmlld1tDT05URVhUXSA9IGNvbXBvbmVudDtcblxuICBob3N0RmVhdHVyZXMgJiYgaG9zdEZlYXR1cmVzLmZvckVhY2goKGZlYXR1cmUpID0+IGZlYXR1cmUoY29tcG9uZW50LCBjb21wb25lbnREZWYpKTtcblxuICAvLyBXZSB3YW50IHRvIGdlbmVyYXRlIGFuIGVtcHR5IFF1ZXJ5TGlzdCBmb3Igcm9vdCBjb250ZW50IHF1ZXJpZXMgZm9yIGJhY2t3YXJkc1xuICAvLyBjb21wYXRpYmlsaXR5IHdpdGggVmlld0VuZ2luZS5cbiAgaWYgKGNvbXBvbmVudERlZi5jb250ZW50UXVlcmllcykge1xuICAgIGNvbXBvbmVudERlZi5jb250ZW50UXVlcmllcyhSZW5kZXJGbGFncy5DcmVhdGUsIGNvbXBvbmVudCwgcm9vdFZpZXcubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBjb25zdCByb290VE5vZGUgPSBnZXRQcmV2aW91c09yUGFyZW50VE5vZGUoKTtcbiAgaWYgKHRWaWV3LmZpcnN0VGVtcGxhdGVQYXNzICYmIGNvbXBvbmVudERlZi5ob3N0QmluZGluZ3MpIHtcbiAgICBjb25zdCBlbGVtZW50SW5kZXggPSByb290VE5vZGUuaW5kZXggLSBIRUFERVJfT0ZGU0VUO1xuICAgIHNldEFjdGl2ZUhvc3RFbGVtZW50KGVsZW1lbnRJbmRleCk7XG5cbiAgICBjb25zdCBleHBhbmRvID0gdFZpZXcuZXhwYW5kb0luc3RydWN0aW9ucyAhO1xuICAgIGludm9rZUhvc3RCaW5kaW5nc0luQ3JlYXRpb25Nb2RlKFxuICAgICAgICBjb21wb25lbnREZWYsIGV4cGFuZG8sIGNvbXBvbmVudCwgcm9vdFROb2RlLCB0Vmlldy5maXJzdFRlbXBsYXRlUGFzcyk7XG4gICAgcm9vdFROb2RlLm9uRWxlbWVudENyZWF0aW9uRm5zICYmIGFwcGx5T25DcmVhdGVJbnN0cnVjdGlvbnMocm9vdFROb2RlKTtcblxuICAgIHNldEFjdGl2ZUhvc3RFbGVtZW50KG51bGwpO1xuICB9XG5cbiAgaWYgKHJvb3RUTm9kZS5zdHlsaW5nVGVtcGxhdGUpIHtcbiAgICBjb25zdCBuYXRpdmUgPSBjb21wb25lbnRWaWV3W0hPU1RdICFhcyBSRWxlbWVudDtcbiAgICByZW5kZXJJbml0aWFsQ2xhc3NlcyhuYXRpdmUsIHJvb3RUTm9kZS5zdHlsaW5nVGVtcGxhdGUsIGNvbXBvbmVudFZpZXdbUkVOREVSRVJdKTtcbiAgICByZW5kZXJJbml0aWFsU3R5bGVzKG5hdGl2ZSwgcm9vdFROb2RlLnN0eWxpbmdUZW1wbGF0ZSwgY29tcG9uZW50Vmlld1tSRU5ERVJFUl0pO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudDtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUm9vdENvbnRleHQoXG4gICAgc2NoZWR1bGVyPzogKHdvcmtGbjogKCkgPT4gdm9pZCkgPT4gdm9pZCwgcGxheWVySGFuZGxlcj86IFBsYXllckhhbmRsZXJ8bnVsbCk6IFJvb3RDb250ZXh0IHtcbiAgcmV0dXJuIHtcbiAgICBjb21wb25lbnRzOiBbXSxcbiAgICBzY2hlZHVsZXI6IHNjaGVkdWxlciB8fCBkZWZhdWx0U2NoZWR1bGVyLFxuICAgIGNsZWFuOiBDTEVBTl9QUk9NSVNFLFxuICAgIHBsYXllckhhbmRsZXI6IHBsYXllckhhbmRsZXIgfHwgbnVsbCxcbiAgICBmbGFnczogUm9vdENvbnRleHRGbGFncy5FbXB0eVxuICB9O1xufVxuXG4vKipcbiAqIFVzZWQgdG8gZW5hYmxlIGxpZmVjeWNsZSBob29rcyBvbiB0aGUgcm9vdCBjb21wb25lbnQuXG4gKlxuICogSW5jbHVkZSB0aGlzIGZlYXR1cmUgd2hlbiBjYWxsaW5nIGByZW5kZXJDb21wb25lbnRgIGlmIHRoZSByb290IGNvbXBvbmVudFxuICogeW91IGFyZSByZW5kZXJpbmcgaGFzIGxpZmVjeWNsZSBob29rcyBkZWZpbmVkLiBPdGhlcndpc2UsIHRoZSBob29rcyB3b24ndFxuICogYmUgY2FsbGVkIHByb3Blcmx5LlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogYGBgXG4gKiByZW5kZXJDb21wb25lbnQoQXBwQ29tcG9uZW50LCB7ZmVhdHVyZXM6IFtSb290TGlmZWN5Y2xlSG9va3NdfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExpZmVjeWNsZUhvb2tzRmVhdHVyZShjb21wb25lbnQ6IGFueSwgZGVmOiBDb21wb25lbnREZWY8YW55Pik6IHZvaWQge1xuICBjb25zdCByb290VFZpZXcgPSByZWFkUGF0Y2hlZExWaWV3KGNvbXBvbmVudCkgIVtUVklFV107XG4gIGNvbnN0IGRpckluZGV4ID0gcm9vdFRWaWV3LmRhdGEubGVuZ3RoIC0gMTtcblxuICByZWdpc3RlclByZU9yZGVySG9va3MoZGlySW5kZXgsIGRlZiwgcm9vdFRWaWV3LCAtMSwgLTEsIC0xKTtcbiAgLy8gVE9ETyhtaXNrbyk6IHJlcGxhY2UgYGFzIFROb2RlYCB3aXRoIGNyZWF0ZVROb2RlIGNhbGwuIChuZWVkcyByZWZhY3RvcmluZyB0byBsb3NlIGRlcCBvblxuICAvLyBMTm9kZSkuXG4gIHJlZ2lzdGVyUG9zdE9yZGVySG9va3MoXG4gICAgICByb290VFZpZXcsIHsgZGlyZWN0aXZlU3RhcnQ6IGRpckluZGV4LCBkaXJlY3RpdmVFbmQ6IGRpckluZGV4ICsgMSB9IGFzIFROb2RlKTtcbn1cblxuLyoqXG4gKiBXYWl0IG9uIGNvbXBvbmVudCB1bnRpbCBpdCBpcyByZW5kZXJlZC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYSBgUHJvbWlzZWAgd2hpY2ggaXMgcmVzb2x2ZWQgd2hlbiB0aGUgY29tcG9uZW50J3NcbiAqIGNoYW5nZSBkZXRlY3Rpb24gaXMgZXhlY3V0ZWQuIFRoaXMgaXMgZGV0ZXJtaW5lZCBieSBmaW5kaW5nIHRoZSBzY2hlZHVsZXJcbiAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgYGNvbXBvbmVudGAncyByZW5kZXIgdHJlZSBhbmQgd2FpdGluZyB1bnRpbCB0aGUgc2NoZWR1bGVyXG4gKiBmbHVzaGVzLiBJZiBub3RoaW5nIGlzIHNjaGVkdWxlZCwgdGhlIGZ1bmN0aW9uIHJldHVybnMgYSByZXNvbHZlZCBwcm9taXNlLlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBcbiAqIGF3YWl0IHdoZW5SZW5kZXJlZChteUNvbXBvbmVudCk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gY29tcG9uZW50IENvbXBvbmVudCB0byB3YWl0IHVwb25cbiAqIEByZXR1cm5zIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgY29tcG9uZW50IGlzIHJlbmRlcmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2hlblJlbmRlcmVkKGNvbXBvbmVudDogYW55KTogUHJvbWlzZTxudWxsPiB7XG4gIHJldHVybiBnZXRSb290Q29udGV4dChjb21wb25lbnQpLmNsZWFuO1xufVxuIl19