@angular/core
Version:
Angular - the core framework
257 lines • 35.6 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, assertDefined, assertEqual } from '../../util/assert';
import { assertHasParent } from '../assert';
import { attachPatchData } from '../context_discovery';
import { registerPostOrderHooks } from '../hooks';
import { BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST } from '../interfaces/view';
import { assertNodeType } from '../node_assert';
import { appendChild } from '../node_manipulation';
import { applyOnCreateInstructions } from '../node_util';
import { decreaseElementDepthCount, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, getSelectedIndex, increaseElementDepthCount, setIsNotParent, setPreviousOrParentTNode } from '../state';
import { getInitialClassNameValue, getInitialStyleStringValue, initializeStaticContext, patchContextWithStaticAttrs, renderInitialClasses, renderInitialStyles } from '../styling/class_and_style_bindings';
import { getStylingContextFromLView, hasClassInput, hasStyleInput } from '../styling/util';
import { registerInitialStylingIntoContext } from '../styling_next/instructions';
import { runtimeIsNewStylingInUse } from '../styling_next/state';
import { attrsStylingIndexOf, setUpAttributes } from '../util/attrs_utils';
import { getNativeByTNode, getTNode } from '../util/view_utils';
import { createDirectivesAndLocals, elementCreate, executeContentQueries, getOrCreateTNode, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate } from './shared';
import { getActiveDirectiveStylingIndex } from './styling';
/**
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
*
* \@codeGenApi
* @param {?} index Index of the element in the LView array
* @param {?} name Name of the DOM Node
* @param {?=} attrs Statically bound set of attributes, classes, and styles to be written into the DOM
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
* @param {?=} localRefs A set of local reference bindings on the element.
*
* Attributes and localRefs are passed as an array of strings where elements with an even index
* hold an attribute name and elements with an odd index hold an attribute value, ex.:
* ['id', 'warning5', 'class', 'alert']
*
* @return {?}
*/
export function ɵɵelementStart(index, name, attrs, localRefs) {
/** @type {?} */
const lView = getLView();
/** @type {?} */
const tView = lView[TVIEW];
ngDevMode && assertEqual(lView[BINDING_INDEX], tView.bindingStartIndex, 'elements should be created before any bindings ');
ngDevMode && ngDevMode.rendererCreateElement++;
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
/** @type {?} */
const native = lView[index + HEADER_OFFSET] = elementCreate(name);
/** @type {?} */
const renderer = lView[RENDERER];
/** @type {?} */
const tNode = getOrCreateTNode(tView, lView[T_HOST], index, 3 /* Element */, name, attrs || null);
/** @type {?} */
let initialStylesIndex = 0;
/** @type {?} */
let initialClassesIndex = 0;
/** @type {?} */
let lastAttrIndex = -1;
if (attrs) {
lastAttrIndex = setUpAttributes(native, attrs);
// it's important to only prepare styling-related datastructures once for a given
// tNode and not each time an element is created. Also, the styling code is designed
// to be patched and constructed at various points, but only up until the styling
// template is first allocated (which happens when the very first style/class binding
// value is evaluated). When the template is allocated (when it turns into a context)
// then the styling template is locked and cannot be further extended (it can only be
// instantiated into a context per element)
setNodeStylingTemplate(tView, tNode, attrs, lastAttrIndex);
/** @type {?} */
const stylingTemplate = tNode.stylingTemplate;
if (stylingTemplate) {
// the initial style/class values are rendered immediately after having been
// initialized into the context so the element styling is ready when directives
// are initialized (since they may read style/class values in their constructor)
initialStylesIndex = renderInitialStyles(native, stylingTemplate, renderer);
initialClassesIndex = renderInitialClasses(native, stylingTemplate, renderer);
}
}
appendChild(native, tNode, lView);
createDirectivesAndLocals(tView, lView, localRefs);
// any immediate children of a component or template container must be pre-emptively
// monkey-patched with the component view data so that the element can be inspected
// later on using any element discovery utility methods (see `element_discovery.ts`)
if (getElementDepthCount() === 0) {
attachPatchData(native, lView);
}
increaseElementDepthCount();
// if a directive contains a host binding for "class" then all class-based data will
// flow through that (except for `[class.prop]` bindings). This also includes initial
// static class values as well. (Note that this will be fixed once map-based `[style]`
// and `[class]` bindings work for multiple directives.)
if (tView.firstTemplatePass) {
/** @type {?} */
const inputData = initializeTNodeInputs(tNode);
if (inputData && inputData.hasOwnProperty('class')) {
tNode.flags |= 8 /* hasClassInput */;
}
if (inputData && inputData.hasOwnProperty('style')) {
tNode.flags |= 16 /* hasStyleInput */;
}
}
// we render the styling again below in case any directives have set any `style` and/or
// `class` host attribute values...
if (tNode.stylingTemplate) {
renderInitialClasses(native, tNode.stylingTemplate, renderer, initialClassesIndex);
renderInitialStyles(native, tNode.stylingTemplate, renderer, initialStylesIndex);
}
if (runtimeIsNewStylingInUse() && lastAttrIndex >= 0) {
registerInitialStylingIntoContext(tNode, (/** @type {?} */ (attrs)), lastAttrIndex);
}
/** @type {?} */
const currentQueries = lView[QUERIES];
if (currentQueries) {
currentQueries.addNode(tNode);
lView[QUERIES] = currentQueries.clone(tNode);
}
executeContentQueries(tView, tNode, lView);
}
/**
* Mark the end of the element.
*
* \@codeGenApi
* @return {?}
*/
export function ɵɵelementEnd() {
/** @type {?} */
let previousOrParentTNode = getPreviousOrParentTNode();
ngDevMode && assertDefined(previousOrParentTNode, 'No parent node to close.');
if (getIsParent()) {
setIsNotParent();
}
else {
ngDevMode && assertHasParent(getPreviousOrParentTNode());
previousOrParentTNode = (/** @type {?} */ (previousOrParentTNode.parent));
setPreviousOrParentTNode(previousOrParentTNode, false);
}
// this is required for all host-level styling-related instructions to run
// in the correct order
previousOrParentTNode.onElementCreationFns && applyOnCreateInstructions(previousOrParentTNode);
ngDevMode && assertNodeType(previousOrParentTNode, 3 /* Element */);
/** @type {?} */
const lView = getLView();
/** @type {?} */
const currentQueries = lView[QUERIES];
// Go back up to parent queries only if queries have been cloned on this element.
if (currentQueries && previousOrParentTNode.index === currentQueries.nodeIndex) {
lView[QUERIES] = currentQueries.parent;
}
registerPostOrderHooks(lView[TVIEW], previousOrParentTNode);
decreaseElementDepthCount();
// this is fired at the end of elementEnd because ALL of the stylingBindings code
// (for directives and the template) have now executed which means the styling
// context can be instantiated properly.
/** @type {?} */
let stylingContext = null;
if (hasClassInput(previousOrParentTNode)) {
stylingContext = getStylingContextFromLView(previousOrParentTNode.index, lView);
setInputsForProperty(lView, (/** @type {?} */ ((/** @type {?} */ (previousOrParentTNode.inputs))['class'])), getInitialClassNameValue(stylingContext));
}
if (hasStyleInput(previousOrParentTNode)) {
stylingContext =
stylingContext || getStylingContextFromLView(previousOrParentTNode.index, lView);
setInputsForProperty(lView, (/** @type {?} */ ((/** @type {?} */ (previousOrParentTNode.inputs))['style'])), getInitialStyleStringValue(stylingContext));
}
}
/**
* Creates an empty element using {\@link elementStart} and {\@link elementEnd}
*
* \@codeGenApi
* @param {?} index Index of the element in the data array
* @param {?} name Name of the DOM Node
* @param {?=} attrs Statically bound set of attributes, classes, and styles to be written into the DOM
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
* @param {?=} localRefs A set of local reference bindings on the element.
*
* @return {?}
*/
export function ɵɵelement(index, name, attrs, localRefs) {
ɵɵelementStart(index, name, attrs, localRefs);
ɵɵelementEnd();
}
/**
* Assign static attribute values to a host element.
*
* This instruction will assign static attribute values as well as class and style
* values to an element within the host bindings function. Since attribute values
* can consist of different types of values, the `attrs` array must include the values in
* the following format:
*
* attrs = [
* // static attributes (like `title`, `name`, `id`...)
* attr1, value1, attr2, value,
*
* // a single namespace value (like `x:id`)
* NAMESPACE_MARKER, namespaceUri1, name1, value1,
*
* // another single namespace value (like `x:name`)
* NAMESPACE_MARKER, namespaceUri2, name2, value2,
*
* // a series of CSS classes that will be applied to the element (no spaces)
* CLASSES_MARKER, class1, class2, class3,
*
* // a series of CSS styles (property + value) that will be applied to the element
* STYLES_MARKER, prop1, value1, prop2, value2
* ]
*
* All non-class and non-style attributes must be defined at the start of the list
* first before all class and style values are set. When there is a change in value
* type (like when classes and styles are introduced) a marker must be used to separate
* the entries. The marker values themselves are set via entries found in the
* [AttributeMarker] enum.
*
* NOTE: This instruction is meant to used from `hostBindings` function only.
*
* \@codeGenApi
* @param {?} attrs An array of static values (attributes, classes and styles) with the correct marker
* values.
*
* @return {?}
*/
export function ɵɵelementHostAttrs(attrs) {
/** @type {?} */
const hostElementIndex = getSelectedIndex();
/** @type {?} */
const lView = getLView();
/** @type {?} */
const tNode = getTNode(hostElementIndex, lView);
// non-element nodes (e.g. `<ng-container>`) are not rendered as actual
// element nodes and adding styles/classes on to them will cause runtime
// errors...
if (tNode.type === 3 /* Element */) {
/** @type {?} */
const native = (/** @type {?} */ (getNativeByTNode(tNode, lView)));
/** @type {?} */
const lastAttrIndex = setUpAttributes(native, attrs);
/** @type {?} */
const stylingAttrsStartIndex = attrsStylingIndexOf(attrs, lastAttrIndex);
if (stylingAttrsStartIndex >= 0) {
/** @type {?} */
const directiveStylingIndex = getActiveDirectiveStylingIndex();
if (tNode.stylingTemplate) {
patchContextWithStaticAttrs(tNode.stylingTemplate, attrs, stylingAttrsStartIndex, directiveStylingIndex);
}
else {
tNode.stylingTemplate =
initializeStaticContext(attrs, stylingAttrsStartIndex, directiveStylingIndex);
}
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaW5zdHJ1Y3Rpb25zL2VsZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFPQSxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2hGLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUloRCxPQUFPLEVBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN2RCxPQUFPLEVBQUMseUJBQXlCLEVBQUUsb0JBQW9CLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSx3QkFBd0IsRUFBRSxnQkFBZ0IsRUFBRSx5QkFBeUIsRUFBRSxjQUFjLEVBQUUsd0JBQXdCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDak4sT0FBTyxFQUFDLHdCQUF3QixFQUFFLDBCQUEwQixFQUFFLHVCQUF1QixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDMU0sT0FBTyxFQUFDLDBCQUEwQixFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RixPQUFPLEVB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QUFlLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFLHFCQUFxQixDQUFDLENBQUM7YUFDbEY7aUJBQU07Z0JBQ0wsS0FBSyxDQUFDLGVBQWU7b0JBQ2pCLHVCQUF1QixDQUFDLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO2FBQ25GO1NBQ0Y7S0FDRjtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQge2Fzc2VydERhdGFJblJhbmdlLCBhc3NlcnREZWZpbmVkLCBhc3NlcnRFcXVhbH0gZnJvbSAnLi4vLi4vdXRpbC9hc3NlcnQnO1xuaW1wb3J0IHthc3NlcnRIYXNQYXJlbnR9IGZyb20gJy4uL2Fzc2VydCc7XG5pbXBvcnQge2F0dGFjaFBhdGNoRGF0YX0gZnJvbSAnLi4vY29udGV4dF9kaXNjb3ZlcnknO1xuaW1wb3J0IHtyZWdpc3RlclBvc3RPcmRlckhvb2tzfSBmcm9tICcuLi9ob29rcyc7XG5pbXBvcnQge1RBdHRyaWJ1dGVzLCBUTm9kZUZsYWdzLCBUTm9kZVR5cGV9IGZyb20gJy4uL2ludGVyZmFjZXMvbm9kZSc7XG5pbXBvcnQge1JFbGVtZW50fSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlbmRlcmVyJztcbmltcG9ydCB7U3R5bGluZ0NvbnRleHR9IGZyb20gJy4uL2ludGVyZmFjZXMvc3R5bGluZyc7XG5pbXBvcnQge0JJTkRJTkdfSU5ERVgsIEhFQURFUl9PRkZTRVQsIFFVRVJJRVMsIFJFTkRFUkVSLCBUVklFVywgVF9IT1NUfSBmcm9tICcuLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthc3NlcnROb2RlVHlwZX0gZnJvbSAnLi4vbm9kZV9hc3NlcnQnO1xuaW1wb3J0IHthcHBlbmRDaGlsZH0gZnJvbSAnLi4vbm9kZV9tYW5pcHVsYXRpb24nO1xuaW1wb3J0IHthcHBseU9uQ3JlYXRlSW5zdHJ1Y3Rpb25zfSBmcm9tICcuLi9ub2RlX3V0aWwnO1xuaW1wb3J0IHtkZWNyZWFzZUVsZW1lbnREZXB0aENvdW50LCBnZXRFbGVtZW50RGVwdGhDb3VudCwgZ2V0SXNQYXJlbnQsIGdldExWaWV3LCBnZXRQcmV2aW91c09yUGFyZW50VE5vZGUsIGdldFNlbGVjdGVkSW5kZXgsIGluY3JlYXNlRWxlbWVudERlcHRoQ291bnQsIHNldElzTm90UGFyZW50LCBzZXRQcmV2aW91c09yUGFyZW50VE5vZGV9IGZyb20gJy4uL3N0YXRlJztcbmltcG9ydCB7Z2V0SW5pdGlhbENsYXNzTmFtZVZhbHVlLCBnZXRJbml0aWFsU3R5bGVTdHJpbmdWYWx1ZSwgaW5pdGlhbGl6ZVN0YXRpY0NvbnRleHQsIHBhdGNoQ29udGV4dFdpdGhTdGF0aWNBdHRycywgcmVuZGVySW5pdGlhbENsYXNzZXMsIHJlbmRlckluaXRpYWxTdHlsZXN9IGZyb20gJy4uL3N0eWxpbmcvY2xhc3NfYW5kX3N0eWxlX2JpbmRpbmdzJztcbmltcG9ydCB7Z2V0U3R5bGluZ0NvbnRleHRGcm9tTFZpZXcsIGhhc0NsYXNzSW5wdXQsIGhhc1N0eWxlSW5wdXR9IGZyb20gJy4uL3N0eWxpbmcvdXRpbCc7XG5pbXBvcnQge3JlZ2lzdGVySW5pdGlhbFN0eWxpbmdJbnRvQ29udGV4dH0gZnJvbSAnLi4vc3R5bGluZ19uZXh0L2luc3RydWN0aW9ucyc7XG5pbXBvcnQge3J1bnRpbWVJc05ld1N0eWxpbmdJblVzZX0gZnJvbSAnLi4vc3R5bGluZ19uZXh0L3N0YXRlJztcbmltcG9ydCB7YXR0cnNTdHlsaW5nSW5kZXhPZiwgc2V0VXBBdHRyaWJ1dGVzfSBmcm9tICcuLi91dGlsL2F0dHJzX3V0aWxzJztcbmltcG9ydCB7Z2V0TmF0aXZlQnlUTm9kZSwgZ2V0VE5vZGV9IGZyb20gJy4uL3V0aWwvdmlld191dGlscyc7XG5cbmltcG9ydCB7Y3JlYXRlRGlyZWN0aXZlc0FuZExvY2FscywgZWxlbWVudENyZWF0ZSwgZXhlY3V0ZUNvbnRlbnRRdWVyaWVzLCBnZXRPckNyZWF0ZVROb2RlLCBpbml0aWFsaXplVE5vZGVJbnB1dHMsIHNldElucHV0c0ZvclByb3BlcnR5LCBzZXROb2RlU3R5bGluZ1RlbXBsYXRlfSBmcm9tICcuL3NoYXJlZCc7XG5pbXBvcnQge2dldEFjdGl2ZURpcmVjdGl2ZVN0eWxpbmdJbmRleH0gZnJvbSAnLi9zdHlsaW5nJztcblxuXG5cbi8qKlxuICogQ3JlYXRlIERPTSBlbGVtZW50LiBUaGUgaW5zdHJ1Y3Rpb24gbXVzdCBsYXRlciBiZSBmb2xsb3dlZCBieSBgZWxlbWVudEVuZCgpYCBjYWxsLlxuICpcbiAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB0aGUgZWxlbWVudCBpbiB0aGUgTFZpZXcgYXJyYXlcbiAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIERPTSBOb2RlXG4gKiBAcGFyYW0gYXR0cnMgU3RhdGljYWxseSBib3VuZCBzZXQgb2YgYXR0cmlidXRlcywgY2xhc3NlcywgYW5kIHN0eWxlcyB0byBiZSB3cml0dGVuIGludG8gdGhlIERPTVxuICogICAgICAgICAgICAgIGVsZW1lbnQgb24gY3JlYXRpb24uIFVzZSBbQXR0cmlidXRlTWFya2VyXSB0byBkZW5vdGUgdGhlIG1lYW5pbmcgb2YgdGhpcyBhcnJheS5cbiAqIEBwYXJhbSBsb2NhbFJlZnMgQSBzZXQgb2YgbG9jYWwgcmVmZXJlbmNlIGJpbmRpbmdzIG9uIHRoZSBlbGVtZW50LlxuICpcbiAqIEF0dHJpYnV0ZXMgYW5kIGxvY2FsUmVmcyBhcmUgcGFzc2VkIGFzIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2hlcmUgZWxlbWVudHMgd2l0aCBhbiBldmVuIGluZGV4XG4gKiBob2xkIGFuIGF0dHJpYnV0ZSBuYW1lIGFuZCBlbGVtZW50cyB3aXRoIGFuIG9kZCBpbmRleCBob2xkIGFuIGF0dHJpYnV0ZSB2YWx1ZSwgZXguOlxuICogWydpZCcsICd3YXJuaW5nNScsICdjbGFzcycsICdhbGVydCddXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVlbGVtZW50U3RhcnQoXG4gICAgaW5kZXg6IG51bWJlciwgbmFtZTogc3RyaW5nLCBhdHRycz86IFRBdHRyaWJ1dGVzIHwgbnVsbCwgbG9jYWxSZWZzPzogc3RyaW5nW10gfCBudWxsKTogdm9pZCB7XG4gIGNvbnN0IGxWaWV3ID0gZ2V0TFZpZXcoKTtcbiAgY29uc3QgdFZpZXcgPSBsVmlld1tUVklFV107XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRFcXVhbChcbiAgICAgICAgICAgICAgICAgICBsVmlld1tCSU5ESU5HX0lOREVYXSwgdFZpZXcuYmluZGluZ1N0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgICAgJ2VsZW1lbnRzIHNob3VsZCBiZSBjcmVhdGVkIGJlZm9yZSBhbnkgYmluZGluZ3MgJyk7XG5cbiAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlckNyZWF0ZUVsZW1lbnQrKztcbiAgbmdEZXZNb2RlICYmIGFzc2VydERhdGFJblJhbmdlKGxWaWV3LCBpbmRleCArIEhFQURFUl9PRkZTRVQpO1xuICBjb25zdCBuYXRpdmUgPSBsVmlld1tpbmRleCArIEhFQURFUl9PRkZTRVRdID0gZWxlbWVudENyZWF0ZShuYW1lKTtcbiAgY29uc3QgcmVuZGVyZXIgPSBsVmlld1tSRU5ERVJFUl07XG4gIGNvbnN0IHROb2RlID1cbiAgICAgIGdldE9yQ3JlYXRlVE5vZGUodFZpZXcsIGxWaWV3W1RfSE9TVF0sIGluZGV4LCBUTm9kZVR5cGUuRWxlbWVudCwgbmFtZSwgYXR0cnMgfHwgbnVsbCk7XG4gIGxldCBpbml0aWFsU3R5bGVzSW5kZXggPSAwO1xuICBsZXQgaW5pdGlhbENsYXNzZXNJbmRleCA9IDA7XG5cbiAgbGV0IGxhc3RBdHRySW5kZXggPSAtMTtcbiAgaWYgKGF0dHJzKSB7XG4gICAgbGFzdEF0dHJJbmRleCA9IHNldFVwQXR0cmlidXRlcyhuYXRpdmUsIGF0dHJzKTtcblxuICAgIC8vIGl0J3MgaW1wb3J0YW50IHRvIG9ubHkgcHJlcGFyZSBzdHlsaW5nLXJlbGF0ZWQgZGF0YXN0cnVjdHVyZXMgb25jZSBmb3IgYSBnaXZlblxuICAgIC8vIHROb2RlIGFuZCBub3QgZWFjaCB0aW1lIGFuIGVsZW1lbnQgaXMgY3JlYXRlZC4gQWxzbywgdGhlIHN0eWxpbmcgY29kZSBpcyBkZXNpZ25lZFxuICAgIC8vIHRvIGJlIHBhdGNoZWQgYW5kIGNvbnN0cnVjdGVkIGF0IHZhcmlvdXMgcG9pbnRzLCBidXQgb25seSB1cCB1bnRpbCB0aGUgc3R5bGluZ1xuICAgIC8vIHRlbXBsYXRlIGlzIGZpcnN0IGFsbG9jYXRlZCAod2hpY2ggaGFwcGVucyB3aGVuIHRoZSB2ZXJ5IGZpcnN0IHN0eWxlL2NsYXNzIGJpbmRpbmdcbiAgICAvLyB2YWx1ZSBpcyBldmFsdWF0ZWQpLiBXaGVuIHRoZSB0ZW1wbGF0ZSBpcyBhbGxvY2F0ZWQgKHdoZW4gaXQgdHVybnMgaW50byBhIGNvbnRleHQpXG4gICAgLy8gdGhlbiB0aGUgc3R5bGluZyB0ZW1wbGF0ZSBpcyBsb2NrZWQgYW5kIGNhbm5vdCBiZSBmdXJ0aGVyIGV4dGVuZGVkIChpdCBjYW4gb25seSBiZVxuICAgIC8vIGluc3RhbnRpYXRlZCBpbnRvIGEgY29udGV4dCBwZXIgZWxlbWVudClcbiAgICBzZXROb2RlU3R5bGluZ1RlbXBsYXRlKHRWaWV3LCB0Tm9kZSwgYXR0cnMsIGxhc3RBdHRySW5kZXgpO1xuXG4gICAgY29uc3Qgc3R5bGluZ1RlbXBsYXRlID0gdE5vZGUuc3R5bGluZ1RlbXBsYXRlO1xuICAgIGlmIChzdHlsaW5nVGVtcGxhdGUpIHtcbiAgICAgIC8vIHRoZSBpbml0aWFsIHN0eWxlL2NsYXNzIHZhbHVlcyBhcmUgcmVuZGVyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaGF2aW5nIGJlZW5cbiAgICAgIC8vIGluaXRpYWxpemVkIGludG8gdGhlIGNvbnRleHQgc28gdGhlIGVsZW1lbnQgc3R5bGluZyBpcyByZWFkeSB3aGVuIGRpcmVjdGl2ZXNcbiAgICAgIC8vIGFyZSBpbml0aWFsaXplZCAoc2luY2UgdGhleSBtYXkgcmVhZCBzdHlsZS9jbGFzcyB2YWx1ZXMgaW4gdGhlaXIgY29uc3RydWN0b3IpXG4gICAgICBpbml0aWFsU3R5bGVzSW5kZXggPSByZW5kZXJJbml0aWFsU3R5bGVzKG5hdGl2ZSwgc3R5bGluZ1RlbXBsYXRlLCByZW5kZXJlcik7XG4gICAgICBpbml0aWFsQ2xhc3Nlc0luZGV4ID0gcmVuZGVySW5pdGlhbENsYXNzZXMobmF0aXZlLCBzdHlsaW5nVGVtcGxhdGUsIHJlbmRlcmVyKTtcbiAgICB9XG4gIH1cblxuICBhcHBlbmRDaGlsZChuYXRpdmUsIHROb2RlLCBsVmlldyk7XG4gIGNyZWF0ZURpcmVjdGl2ZXNBbmRMb2NhbHModFZpZXcsIGxWaWV3LCBsb2NhbFJlZnMpO1xuXG4gIC8vIGFueSBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgYSBjb21wb25lbnQgb3IgdGVtcGxhdGUgY29udGFpbmVyIG11c3QgYmUgcHJlLWVtcHRpdmVseVxuICAvLyBtb25rZXktcGF0Y2hlZCB3aXRoIHRoZSBjb21wb25lbnQgdmlldyBkYXRhIHNvIHRoYXQgdGhlIGVsZW1lbnQgY2FuIGJlIGluc3BlY3RlZFxuICAvLyBsYXRlciBvbiB1c2luZyBhbnkgZWxlbWVudCBkaXNjb3ZlcnkgdXRpbGl0eSBtZXRob2RzIChzZWUgYGVsZW1lbnRfZGlzY292ZXJ5LnRzYClcbiAgaWYgKGdldEVsZW1lbnREZXB0aENvdW50KCkgPT09IDApIHtcbiAgICBhdHRhY2hQYXRjaERhdGEobmF0aXZlLCBsVmlldyk7XG4gIH1cbiAgaW5jcmVhc2VFbGVtZW50RGVwdGhDb3VudCgpO1xuXG4gIC8vIGlmIGEgZGlyZWN0aXZlIGNvbnRhaW5zIGEgaG9zdCBiaW5kaW5nIGZvciBcImNsYXNzXCIgdGhlbiBhbGwgY2xhc3MtYmFzZWQgZGF0YSB3aWxsXG4gIC8vIGZsb3cgdGhyb3VnaCB0aGF0IChleGNlcHQgZm9yIGBbY2xhc3MucHJvcF1gIGJpbmRpbmdzKS4gVGhpcyBhbHNvIGluY2x1ZGVzIGluaXRpYWxcbiAgLy8gc3RhdGljIGNsYXNzIHZhbHVlcyBhcyB3ZWxsLiAoTm90ZSB0aGF0IHRoaXMgd2lsbCBiZSBmaXhlZCBvbmNlIG1hcC1iYXNlZCBgW3N0eWxlXWBcbiAgLy8gYW5kIGBbY2xhc3NdYCBiaW5kaW5ncyB3b3JrIGZvciBtdWx0aXBsZSBkaXJlY3RpdmVzLilcbiAgaWYgKHRWaWV3LmZpcnN0VGVtcGxhdGVQYXNzKSB7XG4gICAgY29uc3QgaW5wdXREYXRhID0gaW5pdGlhbGl6ZVROb2RlSW5wdXRzKHROb2RlKTtcbiAgICBpZiAoaW5wdXREYXRhICYmIGlucHV0RGF0YS5oYXNPd25Qcm9wZXJ0eSgnY2xhc3MnKSkge1xuICAgICAgdE5vZGUuZmxhZ3MgfD0gVE5vZGVGbGFncy5oYXNDbGFzc0lucHV0O1xuICAgIH1cbiAgICBpZiAoaW5wdXREYXRhICYmIGlucHV0RGF0YS5oYXNPd25Qcm9wZXJ0eSgnc3R5bGUnKSkge1xuICAgICAgdE5vZGUuZmxhZ3MgfD0gVE5vZGVGbGFncy5oYXNTdHlsZUlucHV0O1xuICAgIH1cbiAgfVxuXG4gIC8vIHdlIHJlbmRlciB0aGUgc3R5bGluZyBhZ2FpbiBiZWxvdyBpbiBjYXNlIGFueSBkaXJlY3RpdmVzIGhhdmUgc2V0IGFueSBgc3R5bGVgIGFuZC9vclxuICAvLyBgY2xhc3NgIGhvc3QgYXR0cmlidXRlIHZhbHVlcy4uLlxuICBpZiAodE5vZGUuc3R5bGluZ1RlbXBsYXRlKSB7XG4gICAgcmVuZGVySW5pdGlhbENsYXNzZXMobmF0aXZlLCB0Tm9kZS5zdHlsaW5nVGVtcGxhdGUsIHJlbmRlcmVyLCBpbml0aWFsQ2xhc3Nlc0luZGV4KTtcbiAgICByZW5kZXJJbml0aWFsU3R5bGVzKG5hdGl2ZSwgdE5vZGUuc3R5bGluZ1RlbXBsYXRlLCByZW5kZXJlciwgaW5pdGlhbFN0eWxlc0luZGV4KTtcbiAgfVxuXG4gIGlmIChydW50aW1lSXNOZXdTdHlsaW5nSW5Vc2UoKSAmJiBsYXN0QXR0ckluZGV4ID49IDApIHtcbiAgICByZWdpc3RlckluaXRpYWxTdHlsaW5nSW50b0NvbnRleHQodE5vZGUsIGF0dHJzIGFzIFRBdHRyaWJ1dGVzLCBsYXN0QXR0ckluZGV4KTtcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnRRdWVyaWVzID0gbFZpZXdbUVVFUklFU107XG4gIGlmIChjdXJyZW50UXVlcmllcykge1xuICAgIGN1cnJlbnRRdWVyaWVzLmFkZE5vZGUodE5vZGUpO1xuICAgIGxWaWV3W1FVRVJJRVNdID0gY3VycmVudFF1ZXJpZXMuY2xvbmUodE5vZGUpO1xuICB9XG4gIGV4ZWN1dGVDb250ZW50UXVlcmllcyh0VmlldywgdE5vZGUsIGxWaWV3KTtcbn1cblxuLyoqXG4gKiBNYXJrIHRoZSBlbmQgb2YgdGhlIGVsZW1lbnQuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVlbGVtZW50RW5kKCk6IHZvaWQge1xuICBsZXQgcHJldmlvdXNPclBhcmVudFROb2RlID0gZ2V0UHJldmlvdXNPclBhcmVudFROb2RlKCk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKHByZXZpb3VzT3JQYXJlbnRUTm9kZSwgJ05vIHBhcmVudCBub2RlIHRvIGNsb3NlLicpO1xuICBpZiAoZ2V0SXNQYXJlbnQoKSkge1xuICAgIHNldElzTm90UGFyZW50KCk7XG4gIH0gZWxzZSB7XG4gICAgbmdEZXZNb2RlICYmIGFzc2VydEhhc1BhcmVudChnZXRQcmV2aW91c09yUGFyZW50VE5vZGUoKSk7XG4gICAgcHJldmlvdXNPclBhcmVudFROb2RlID0gcHJldmlvdXNPclBhcmVudFROb2RlLnBhcmVudCAhO1xuICAgIHNldFByZXZpb3VzT3JQYXJlbnRUTm9kZShwcmV2aW91c09yUGFyZW50VE5vZGUsIGZhbHNlKTtcbiAgfVxuXG4gIC8vIHRoaXMgaXMgcmVxdWlyZWQgZm9yIGFsbCBob3N0LWxldmVsIHN0eWxpbmctcmVsYXRlZCBpbnN0cnVjdGlvbnMgdG8gcnVuXG4gIC8vIGluIHRoZSBjb3JyZWN0IG9yZGVyXG4gIHByZXZpb3VzT3JQYXJlbnRUTm9kZS5vbkVsZW1lbnRDcmVhdGlvbkZucyAmJiBhcHBseU9uQ3JlYXRlSW5zdHJ1Y3Rpb25zKHByZXZpb3VzT3JQYXJlbnRUTm9kZSk7XG5cbiAgbmdEZXZNb2RlICYmIGFzc2VydE5vZGVUeXBlKHByZXZpb3VzT3JQYXJlbnRUTm9kZSwgVE5vZGVUeXBlLkVsZW1lbnQpO1xuICBjb25zdCBsVmlldyA9IGdldExWaWV3KCk7XG4gIGNvbnN0IGN1cnJlbnRRdWVyaWVzID0gbFZpZXdbUVVFUklFU107XG4gIC8vIEdvIGJhY2sgdXAgdG8gcGFyZW50IHF1ZXJpZXMgb25seSBpZiBxdWVyaWVzIGhhdmUgYmVlbiBjbG9uZWQgb24gdGhpcyBlbGVtZW50LlxuICBpZiAoY3VycmVudFF1ZXJpZXMgJiYgcHJldmlvdXNPclBhcmVudFROb2RlLmluZGV4ID09PSBjdXJyZW50UXVlcmllcy5ub2RlSW5kZXgpIHtcbiAgICBsVmlld1tRVUVSSUVTXSA9IGN1cnJlbnRRdWVyaWVzLnBhcmVudDtcbiAgfVxuXG4gIHJlZ2lzdGVyUG9zdE9yZGVySG9va3MobFZpZXdbVFZJRVddLCBwcmV2aW91c09yUGFyZW50VE5vZGUpO1xuICBkZWNyZWFzZUVsZW1lbnREZXB0aENvdW50KCk7XG5cbiAgLy8gdGhpcyBpcyBmaXJlZCBhdCB0aGUgZW5kIG9mIGVsZW1lbnRFbmQgYmVjYXVzZSBBTEwgb2YgdGhlIHN0eWxpbmdCaW5kaW5ncyBjb2RlXG4gIC8vIChmb3IgZGlyZWN0aXZlcyBhbmQgdGhlIHRlbXBsYXRlKSBoYXZlIG5vdyBleGVjdXRlZCB3aGljaCBtZWFucyB0aGUgc3R5bGluZ1xuICAvLyBjb250ZXh0IGNhbiBiZSBpbnN0YW50aWF0ZWQgcHJvcGVybHkuXG4gIGxldCBzdHlsaW5nQ29udGV4dDogU3R5bGluZ0NvbnRleHR8bnVsbCA9IG51bGw7XG4gIGlmIChoYXNDbGFzc0lucHV0KHByZXZpb3VzT3JQYXJlbnRUTm9kZSkpIHtcbiAgICBzdHlsaW5nQ29udGV4dCA9IGdldFN0eWxpbmdDb250ZXh0RnJvbUxWaWV3KHByZXZpb3VzT3JQYXJlbnRUTm9kZS5pbmRleCwgbFZpZXcpO1xuICAgIHNldElucHV0c0ZvclByb3BlcnR5KFxuICAgICAgICBsVmlldywgcHJldmlvdXNPclBhcmVudFROb2RlLmlucHV0cyAhWydjbGFzcyddICEsIGdldEluaXRpYWxDbGFzc05hbWVWYWx1ZShzdHlsaW5nQ29udGV4dCkpO1xuICB9XG4gIGlmIChoYXNTdHlsZUlucHV0KHByZXZpb3VzT3JQYXJlbnRUTm9kZSkpIHtcbiAgICBzdHlsaW5nQ29udGV4dCA9XG4gICAgICAgIHN0eWxpbmdDb250ZXh0IHx8IGdldFN0eWxpbmdDb250ZXh0RnJvbUxWaWV3KHByZXZpb3VzT3JQYXJlbnRUTm9kZS5pbmRleCwgbFZpZXcpO1xuICAgIHNldElucHV0c0ZvclByb3BlcnR5KFxuICAgICAgICBsVmlldywgcHJldmlvdXNPclBhcmVudFROb2RlLmlucHV0cyAhWydzdHlsZSddICEsXG4gICAgICAgIGdldEluaXRpYWxTdHlsZVN0cmluZ1ZhbHVlKHN0eWxpbmdDb250ZXh0KSk7XG4gIH1cbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gZW1wdHkgZWxlbWVudCB1c2luZyB7QGxpbmsgZWxlbWVudFN0YXJ0fSBhbmQge0BsaW5rIGVsZW1lbnRFbmR9XG4gKlxuICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHRoZSBlbGVtZW50IGluIHRoZSBkYXRhIGFycmF5XG4gKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBET00gTm9kZVxuICogQHBhcmFtIGF0dHJzIFN0YXRpY2FsbHkgYm91bmQgc2V0IG9mIGF0dHJpYnV0ZXMsIGNsYXNzZXMsIGFuZCBzdHlsZXMgdG8gYmUgd3JpdHRlbiBpbnRvIHRoZSBET01cbiAqICAgICAgICAgICAgICBlbGVtZW50IG9uIGNyZWF0aW9uLiBVc2UgW0F0dHJpYnV0ZU1hcmtlcl0gdG8gZGVub3RlIHRoZSBtZWFuaW5nIG9mIHRoaXMgYXJyYXkuXG4gKiBAcGFyYW0gbG9jYWxSZWZzIEEgc2V0IG9mIGxvY2FsIHJlZmVyZW5jZSBiaW5kaW5ncyBvbiB0aGUgZWxlbWVudC5cbiAqXG4gKiBAY29kZUdlbkFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gybXJtWVsZW1lbnQoXG4gICAgaW5kZXg6IG51bWJlciwgbmFtZTogc3RyaW5nLCBhdHRycz86IFRBdHRyaWJ1dGVzIHwgbnVsbCwgbG9jYWxSZWZzPzogc3RyaW5nW10gfCBudWxsKTogdm9pZCB7XG4gIMm1ybVlbGVtZW50U3RhcnQoaW5kZXgsIG5hbWUsIGF0dHJzLCBsb2NhbFJlZnMpO1xuICDJtcm1ZWxlbWVudEVuZCgpO1xufVxuXG4vKipcbiAqIEFzc2lnbiBzdGF0aWMgYXR0cmlidXRlIHZhbHVlcyB0byBhIGhvc3QgZWxlbWVudC5cbiAqXG4gKiBUaGlzIGluc3RydWN0aW9uIHdpbGwgYXNzaWduIHN0YXRpYyBhdHRyaWJ1dGUgdmFsdWVzIGFzIHdlbGwgYXMgY2xhc3MgYW5kIHN0eWxlXG4gKiB2YWx1ZXMgdG8gYW4gZWxlbWVudCB3aXRoaW4gdGhlIGhvc3QgYmluZGluZ3MgZnVuY3Rpb24uIFNpbmNlIGF0dHJpYnV0ZSB2YWx1ZXNcbiAqIGNhbiBjb25zaXN0IG9mIGRpZmZlcmVudCB0eXBlcyBvZiB2YWx1ZXMsIHRoZSBgYXR0cnNgIGFycmF5IG11c3QgaW5jbHVkZSB0aGUgdmFsdWVzIGluXG4gKiB0aGUgZm9sbG93aW5nIGZvcm1hdDpcbiAqXG4gKiBhdHRycyA9IFtcbiAqICAgLy8gc3RhdGljIGF0dHJpYnV0ZXMgKGxpa2UgYHRpdGxlYCwgYG5hbWVgLCBgaWRgLi4uKVxuICogICBhdHRyMSwgdmFsdWUxLCBhdHRyMiwgdmFsdWUsXG4gKlxuICogICAvLyBhIHNpbmdsZSBuYW1lc3BhY2UgdmFsdWUgKGxpa2UgYHg6aWRgKVxuICogICBOQU1FU1BBQ0VfTUFSS0VSLCBuYW1lc3BhY2VVcmkxLCBuYW1lMSwgdmFsdWUxLFxuICpcbiAqICAgLy8gYW5vdGhlciBzaW5nbGUgbmFtZXNwYWNlIHZhbHVlIChsaWtlIGB4Om5hbWVgKVxuICogICBOQU1FU1BBQ0VfTUFSS0VSLCBuYW1lc3BhY2VVcmkyLCBuYW1lMiwgdmFsdWUyLFxuICpcbiAqICAgLy8gYSBzZXJpZXMgb2YgQ1NTIGNsYXNzZXMgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQgKG5vIHNwYWNlcylcbiAqICAgQ0xBU1NFU19NQVJLRVIsIGNsYXNzMSwgY2xhc3MyLCBjbGFzczMsXG4gKlxuICogICAvLyBhIHNlcmllcyBvZiBDU1Mgc3R5bGVzIChwcm9wZXJ0eSArIHZhbHVlKSB0aGF0IHdpbGwgYmUgYXBwbGllZCB0byB0aGUgZWxlbWVudFxuICogICBTVFlMRVNfTUFSS0VSLCBwcm9wMSwgdmFsdWUxLCBwcm9wMiwgdmFsdWUyXG4gKiBdXG4gKlxuICogQWxsIG5vbi1jbGFzcyBhbmQgbm9uLXN0eWxlIGF0dHJpYnV0ZXMgbXVzdCBiZSBkZWZpbmVkIGF0IHRoZSBzdGFydCBvZiB0aGUgbGlzdFxuICogZmlyc3QgYmVmb3JlIGFsbCBjbGFzcyBhbmQgc3R5bGUgdmFsdWVzIGFyZSBzZXQuIFdoZW4gdGhlcmUgaXMgYSBjaGFuZ2UgaW4gdmFsdWVcbiAqIHR5cGUgKGxpa2Ugd2hlbiBjbGFzc2VzIGFuZCBzdHlsZXMgYXJlIGludHJvZHVjZWQpIGEgbWFya2VyIG11c3QgYmUgdXNlZCB0byBzZXBhcmF0ZVxuICogdGhlIGVudHJpZXMuIFRoZSBtYXJrZXIgdmFsdWVzIHRoZW1zZWx2ZXMgYXJlIHNldCB2aWEgZW50cmllcyBmb3VuZCBpbiB0aGVcbiAqIFtBdHRyaWJ1dGVNYXJrZXJdIGVudW0uXG4gKlxuICogTk9URTogVGhpcyBpbnN0cnVjdGlvbiBpcyBtZWFudCB0byB1c2VkIGZyb20gYGhvc3RCaW5kaW5nc2AgZnVuY3Rpb24gb25seS5cbiAqXG4gKiBAcGFyYW0gZGlyZWN0aXZlIEEgZGlyZWN0aXZlIGluc3RhbmNlIHRoZSBzdHlsaW5nIGlzIGFzc29jaWF0ZWQgd2l0aC5cbiAqIEBwYXJhbSBhdHRycyBBbiBhcnJheSBvZiBzdGF0aWMgdmFsdWVzIChhdHRyaWJ1dGVzLCBjbGFzc2VzIGFuZCBzdHlsZXMpIHdpdGggdGhlIGNvcnJlY3QgbWFya2VyXG4gKiB2YWx1ZXMuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVlbGVtZW50SG9zdEF0dHJzKGF0dHJzOiBUQXR0cmlidXRlcykge1xuICBjb25zdCBob3N0RWxlbWVudEluZGV4ID0gZ2V0U2VsZWN0ZWRJbmRleCgpO1xuICBjb25zdCBsVmlldyA9IGdldExWaWV3KCk7XG4gIGNvbnN0IHROb2RlID0gZ2V0VE5vZGUoaG9zdEVsZW1lbnRJbmRleCwgbFZpZXcpO1xuXG4gIC8vIG5vbi1lbGVtZW50IG5vZGVzIChlLmcuIGA8bmctY29udGFpbmVyPmApIGFyZSBub3QgcmVuZGVyZWQgYXMgYWN0dWFsXG4gIC8vIGVsZW1lbnQgbm9kZXMgYW5kIGFkZGluZyBzdHlsZXMvY2xhc3NlcyBvbiB0byB0aGVtIHdpbGwgY2F1c2UgcnVudGltZVxuICAvLyBlcnJvcnMuLi5cbiAgaWYgKHROb2RlLnR5cGUgPT09IFROb2RlVHlwZS5FbGVtZW50KSB7XG4gICAgY29uc3QgbmF0aXZlID0gZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgbFZpZXcpIGFzIFJFbGVtZW50O1xuICAgIGNvbnN0IGxhc3RBdHRySW5kZXggPSBzZXRVcEF0dHJpYnV0ZXMobmF0aXZlLCBhdHRycyk7XG4gICAgY29uc3Qgc3R5bGluZ0F0dHJzU3RhcnRJbmRleCA9IGF0dHJzU3R5bGluZ0luZGV4T2YoYXR0cnMsIGxhc3RBdHRySW5kZXgpO1xuICAgIGlmIChzdHlsaW5nQXR0cnNTdGFydEluZGV4ID49IDApIHtcbiAgICAgIGNvbnN0IGRpcmVjdGl2ZVN0eWxpbmdJbmRleCA9IGdldEFjdGl2ZURpcmVjdGl2ZVN0eWxpbmdJbmRleCgpO1xuICAgICAgaWYgKHROb2RlLnN0eWxpbmdUZW1wbGF0ZSkge1xuICAgICAgICBwYXRjaENvbnRleHRXaXRoU3RhdGljQXR0cnMoXG4gICAgICAgICAgICB0Tm9kZS5zdHlsaW5nVGVtcGxhdGUsIGF0dHJzLCBzdHlsaW5nQXR0cnNTdGFydEluZGV4LCBkaXJlY3RpdmVTdHlsaW5nSW5kZXgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdE5vZGUuc3R5bGluZ1RlbXBsYXRlID1cbiAgICAgICAgICAgIGluaXRpYWxpemVTdGF0aWNDb250ZXh0KGF0dHJzLCBzdHlsaW5nQXR0cnNTdGFydEluZGV4LCBkaXJlY3RpdmVTdHlsaW5nSW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19