UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

1,926 lines 182 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/platform-browser'), require('rxjs'), require('ng-zorro-antd/core'), require('@angular/cdk/keycodes'), require('@angular/cdk/overlay'), require('@angular/forms'), require('rxjs/operators'), require('@angular/common'), require('ng-zorro-antd/empty'), require('ng-zorro-antd/icon'), require('ng-zorro-antd/input')) :
    typeof define === 'function' && define.amd ? define('ng-zorro-antd/cascader', ['exports', '@angular/core', '@angular/platform-browser', 'rxjs', 'ng-zorro-antd/core', '@angular/cdk/keycodes', '@angular/cdk/overlay', '@angular/forms', 'rxjs/operators', '@angular/common', 'ng-zorro-antd/empty', 'ng-zorro-antd/icon', 'ng-zorro-antd/input'], factory) :
    (factory((global['ng-zorro-antd'] = global['ng-zorro-antd'] || {}, global['ng-zorro-antd'].cascader = {}),global.ng.core,global.ng.platformBrowser,global.rxjs,global['ng-zorro-antd'].core,global.ng.cdk.keycodes,global.ng.cdk.overlay,global.ng.forms,global.rxjs.operators,global.ng.common,global['ng-zorro-antd'].empty,global['ng-zorro-antd'].icon,global['ng-zorro-antd'].input));
}(this, (function (exports,core,platformBrowser,rxjs,core$1,keycodes,overlay,forms,operators,common,empty,icon,input) { 'use strict';

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @param {?} options
     * @return {?}
     */
    function isShowSearchObject(options) {
        return typeof options !== 'boolean';
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @license
     * Copyright Alibaba.com 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://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
     */
    /**
     * @param {?} o
     * @return {?}
     */
    function isChildOption(o) {
        return o.isLeaf || !o.children || !o.children.length;
    }
    /**
     * @param {?} o
     * @return {?}
     */
    function isParentOption(o) {
        return !!o.children && !!o.children.length && !o.isLeaf;
    }

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
            r = Reflect.decorate(decorators, target, key, desc);
        else
            for (var i = decorators.length - 1; i >= 0; i--)
                if (d = decorators[i])
                    r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }
    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
            return Reflect.metadata(metadataKey, metadataValue);
    }
    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m)
            return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                ar.push(r.value);
        }
        catch (error) {
            e = { error: error };
        }
        finally {
            try {
                if (r && !r.done && (m = i["return"]))
                    m.call(i);
            }
            finally {
                if (e)
                    throw e.error;
            }
        }
        return ar;
    }
    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NzCascaderOptionComponent = /** @class */ (function () {
        function NzCascaderOptionComponent(sanitizer, cdr, elementRef, renderer) {
            this.sanitizer = sanitizer;
            this.cdr = cdr;
            this.activated = false;
            this.nzLabelProperty = 'label';
            renderer.addClass(elementRef.nativeElement, 'ant-cascader-menu-item');
        }
        /**
         * @return {?}
         */
        NzCascaderOptionComponent.prototype.getOptionLabel = /**
         * @return {?}
         */
            function () {
                return this.option ? this.option[this.nzLabelProperty] : '';
            };
        /**
         * @param {?} str
         * @return {?}
         */
        NzCascaderOptionComponent.prototype.renderHighlightString = /**
         * @param {?} str
         * @return {?}
         */
            function (str) {
                /** @type {?} */
                var replaceStr = str.replace(new RegExp(this.highlightText, 'g'), "<span class=\"ant-cascader-menu-item-keyword\">" + this.highlightText + "</span>");
                return this.sanitizer.bypassSecurityTrustHtml(replaceStr);
            };
        /**
         * @return {?}
         */
        NzCascaderOptionComponent.prototype.markForCheck = /**
         * @return {?}
         */
            function () {
                this.cdr.markForCheck();
            };
        NzCascaderOptionComponent.decorators = [
            { type: core.Component, args: [{
                        changeDetection: core.ChangeDetectionStrategy.OnPush,
                        encapsulation: core.ViewEncapsulation.None,
                        selector: '[nz-cascader-option]',
                        exportAs: 'nzCascaderOption',
                        template: "<ng-container *ngIf=\"highlightText\">\n  <span [innerHTML]=\"renderHighlightString(getOptionLabel())\"></span>\n</ng-container>\n<ng-container *ngIf=\"!highlightText\">{{ getOptionLabel() }}</ng-container>\n<span\n  *ngIf=\"!option.isLeaf || option.children && option.children.length || option.loading\"\n  class=\"ant-cascader-menu-item-expand-icon\">\n  <i nz-icon [type]=\"option.loading ? 'loading' : 'right'\"></i>\n</span>\n",
                        host: {
                            '[attr.title]': 'option.title || getOptionLabel()',
                            '[class.ant-cascader-menu-item-active]': 'activated',
                            '[class.ant-cascader-menu-item-expand]': '!option.isLeaf',
                            '[class.ant-cascader-menu-item-disabled]': 'option.disabled'
                        }
                    }] }
        ];
        /** @nocollapse */
        NzCascaderOptionComponent.ctorParameters = function () {
            return [
                { type: platformBrowser.DomSanitizer },
                { type: core.ChangeDetectorRef },
                { type: core.ElementRef },
                { type: core.Renderer2 }
            ];
        };
        NzCascaderOptionComponent.propDecorators = {
            option: [{ type: core.Input }],
            activated: [{ type: core.Input }],
            highlightText: [{ type: core.Input }],
            nzLabelProperty: [{ type: core.Input }]
        };
        return NzCascaderOptionComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * All data is stored and parsed in NzCascaderService.
     */
    var NzCascaderService = /** @class */ (function () {
        function NzCascaderService() {
            /**
             * Activated options in each column.
             */
            this.activatedOptions = [];
            /**
             * An array to store cascader items arranged in different layers.
             */
            this.columns = [[]];
            /**
             * If user has entered searching mode.
             */
            this.inSearchingMode = false;
            /**
             * Selected options would be output to user.
             */
            this.selectedOptions = [];
            this.values = []; // tslint:disable-line:no-any
            // tslint:disable-line:no-any
            this.$loading = new rxjs.BehaviorSubject(false);
            /**
             * Emit an event to notify cascader it needs to redraw because activated or
             * selected options are changed.
             */
            this.$redraw = new rxjs.Subject();
            /**
             * Emit an event when an option gets selected.
             * Emit true if a leaf options is selected.
             */
            this.$optionSelected = new rxjs.Subject();
            /**
             * Emit an event to notify cascader it needs to quit searching mode.
             * Only emit when user do select a searching option.
             */
            this.$quitSearching = new rxjs.Subject();
            /**
             * To hold columns before entering searching mode.
             */
            this.columnsSnapshot = [[]];
            /**
             * To hold activated options before entering searching mode.
             */
            this.activatedOptionsSnapshot = [];
        }
        Object.defineProperty(NzCascaderService.prototype, "nzOptions", {
            /** Return cascader options in the first layer. */
            get: /**
             * Return cascader options in the first layer.
             * @return {?}
             */ function () {
                return this.columns[0];
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        NzCascaderService.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                this.$redraw.complete();
                this.$quitSearching.complete();
                this.$optionSelected.complete();
                this.$loading.complete();
            };
        /**
         * Make sure that value matches what is displayed in the dropdown.
         */
        /**
         * Make sure that value matches what is displayed in the dropdown.
         * @param {?=} first
         * @return {?}
         */
        NzCascaderService.prototype.syncOptions = /**
         * Make sure that value matches what is displayed in the dropdown.
         * @param {?=} first
         * @return {?}
         */
            function (first) {
                var _this = this;
                if (first === void 0) {
                    first = false;
                }
                /** @type {?} */
                var values = this.values;
                /** @type {?} */
                var hasValue = values && values.length;
                /** @type {?} */
                var lastColumnIndex = values.length - 1;
                /** @type {?} */
                var initColumnWithIndex = ( /**
                 * @param {?} columnIndex
                 * @return {?}
                 */function (columnIndex) {
                    /** @type {?} */
                    var activatedOptionSetter = ( /**
                     * @return {?}
                     */function () {
                        var _a;
                        /** @type {?} */
                        var currentValue = values[columnIndex];
                        if (!currentValue) {
                            _this.$redraw.next();
                            return;
                        }
                        /** @type {?} */
                        var option = _this.findOptionWithValue(columnIndex, values[columnIndex]) ||
                            (typeof currentValue === 'object'
                                ? currentValue
                                : (_a = {},
                                    _a["" + _this.cascaderComponent.nzValueProperty] = currentValue,
                                    _a["" + _this.cascaderComponent.nzLabelProperty] = currentValue,
                                    _a));
                        _this.setOptionActivated(option, columnIndex, false, false);
                        if (columnIndex < lastColumnIndex) {
                            initColumnWithIndex(columnIndex + 1);
                        }
                        else {
                            _this.dropBehindColumns(columnIndex);
                            _this.selectedOptions = __spread(_this.activatedOptions);
                            _this.$redraw.next();
                        }
                    });
                    if (_this.isLoaded(columnIndex) || !_this.cascaderComponent.nzLoadData) {
                        activatedOptionSetter();
                    }
                    else {
                        /** @type {?} */
                        var option = _this.activatedOptions[columnIndex - 1] || {};
                        _this.loadChildren(option, columnIndex - 1, activatedOptionSetter);
                    }
                });
                this.activatedOptions = [];
                this.selectedOptions = [];
                if (first && this.cascaderComponent.nzLoadData && !hasValue) {
                    return;
                }
                else {
                    initColumnWithIndex(0);
                }
            };
        /**
         * Bind cascader component so this service could use inputs.
         */
        /**
         * Bind cascader component so this service could use inputs.
         * @param {?} cascaderComponent
         * @return {?}
         */
        NzCascaderService.prototype.withComponent = /**
         * Bind cascader component so this service could use inputs.
         * @param {?} cascaderComponent
         * @return {?}
         */
            function (cascaderComponent) {
                this.cascaderComponent = cascaderComponent;
            };
        /**
         * Reset all options. Rebuild searching options if in searching mode.
         */
        /**
         * Reset all options. Rebuild searching options if in searching mode.
         * @param {?} options
         * @return {?}
         */
        NzCascaderService.prototype.withOptions = /**
         * Reset all options. Rebuild searching options if in searching mode.
         * @param {?} options
         * @return {?}
         */
            function (options) {
                this.columnsSnapshot = this.columns = options && options.length ? [options] : [];
                if (this.inSearchingMode) {
                    this.prepareSearchOptions(this.cascaderComponent.inputValue);
                }
                else if (this.columns.length) {
                    this.syncOptions();
                }
            };
        /**
         * Try to set a option as activated.
         * @param option Cascader option
         * @param columnIndex Of which column this option is in
         * @param select Select
         * @param loadingChildren Try to load children asynchronously.
         */
        /**
         * Try to set a option as activated.
         * @param {?} option Cascader option
         * @param {?} columnIndex Of which column this option is in
         * @param {?=} select Select
         * @param {?=} loadingChildren Try to load children asynchronously.
         * @return {?}
         */
        NzCascaderService.prototype.setOptionActivated = /**
         * Try to set a option as activated.
         * @param {?} option Cascader option
         * @param {?} columnIndex Of which column this option is in
         * @param {?=} select Select
         * @param {?=} loadingChildren Try to load children asynchronously.
         * @return {?}
         */
            function (option, columnIndex, select, loadingChildren) {
                if (select === void 0) {
                    select = false;
                }
                if (loadingChildren === void 0) {
                    loadingChildren = true;
                }
                if (option.disabled) {
                    return;
                }
                this.activatedOptions[columnIndex] = option;
                this.trackAncestorActivatedOptions(columnIndex);
                this.dropBehindActivatedOptions(columnIndex);
                /** @type {?} */
                var isParent = isParentOption(option);
                if (isParent) {
                    // Parent option that has children.
                    this.setColumnData(( /** @type {?} */(option.children)), columnIndex + 1, option);
                }
                else if (!option.isLeaf && loadingChildren) {
                    // Parent option that should try to load children asynchronously.
                    this.loadChildren(option, columnIndex);
                }
                else if (option.isLeaf) {
                    // Leaf option.
                    this.dropBehindColumns(columnIndex);
                }
                // Actually perform selection to make an options not only activated but also selected.
                if (select) {
                    this.setOptionSelected(option, columnIndex);
                }
                this.$redraw.next();
            };
        /**
         * Set a searching option as activated, finishing up things.
         * @param option
         */
        /**
         * Set a searching option as activated, finishing up things.
         * @param {?} option
         * @return {?}
         */
        NzCascaderService.prototype.setSearchOptionSelected = /**
         * Set a searching option as activated, finishing up things.
         * @param {?} option
         * @return {?}
         */
            function (option) {
                var _this = this;
                this.activatedOptions = [option];
                this.selectedOptions = __spread(option.path);
                this.prepareEmitValue();
                this.$redraw.next();
                this.$optionSelected.next({ option: option, index: 0 });
                setTimeout(( /**
                 * @return {?}
                 */function () {
                    // Reset data and tell UI only to remove input and reset dropdown width style.
                    _this.$quitSearching.next();
                    _this.$redraw.next();
                    _this.inSearchingMode = false;
                    _this.columns = __spread(_this.columnsSnapshot);
                    _this.activatedOptions = __spread(_this.selectedOptions);
                }), 200);
            };
        /**
         * Filter cascader options to reset `columns`.
         * @param searchValue The string user wants to search.
         */
        /**
         * Filter cascader options to reset `columns`.
         * @param {?} searchValue The string user wants to search.
         * @return {?}
         */
        NzCascaderService.prototype.prepareSearchOptions = /**
         * Filter cascader options to reset `columns`.
         * @param {?} searchValue The string user wants to search.
         * @return {?}
         */
            function (searchValue) {
                var _this = this;
                /** @type {?} */
                var results = [];
                // Search results only have one layer.
                /** @type {?} */
                var path = [];
                /** @type {?} */
                var defaultFilter = ( /**
                 * @param {?} i
                 * @param {?} p
                 * @return {?}
                 */function (i, p) {
                    return p.some(( /**
                     * @param {?} o
                     * @return {?}
                     */function (o) {
                        /** @type {?} */
                        var label = _this.getOptionLabel(o);
                        return !!label && label.indexOf(i) !== -1;
                    }));
                });
                /** @type {?} */
                var showSearch = this.cascaderComponent.nzShowSearch;
                /** @type {?} */
                var filter = isShowSearchObject(showSearch) && showSearch.filter ? showSearch.filter : defaultFilter;
                /** @type {?} */
                var sorter = isShowSearchObject(showSearch) && showSearch.sorter ? showSearch.sorter : null;
                /** @type {?} */
                var loopChild = ( /**
                 * @param {?} node
                 * @param {?=} forceDisabled
                 * @return {?}
                 */function (node, forceDisabled) {
                    if (forceDisabled === void 0) {
                        forceDisabled = false;
                    }
                    var _a;
                    path.push(node);
                    /** @type {?} */
                    var cPath = Array.from(path);
                    if (filter(searchValue, cPath)) {
                        /** @type {?} */
                        var disabled = forceDisabled || node.disabled;
                        /** @type {?} */
                        var option = (_a = {
                            disabled: disabled,
                            isLeaf: true,
                            path: cPath
                        },
                            _a[_this.cascaderComponent.nzLabelProperty] = cPath.map(( /**
                             * @param {?} p
                             * @return {?}
                             */function (p) { return _this.getOptionLabel(p); })).join(' / '),
                            _a);
                        results.push(option);
                    }
                    path.pop();
                });
                /** @type {?} */
                var loopParent = ( /**
                 * @param {?} node
                 * @param {?=} forceDisabled
                 * @return {?}
                 */function (node, forceDisabled) {
                    if (forceDisabled === void 0) {
                        forceDisabled = false;
                    }
                    /** @type {?} */
                    var disabled = forceDisabled || node.disabled;
                    path.push(node);
                    ( /** @type {?} */(node.children)).forEach(( /**
                     * @param {?} sNode
                     * @return {?}
                     */function (sNode) {
                        if (!sNode.parent) {
                            sNode.parent = node;
                        }
                        if (!sNode.isLeaf) {
                            loopParent(sNode, disabled);
                        }
                        if (sNode.isLeaf || !sNode.children || !sNode.children.length) {
                            loopChild(sNode, disabled);
                        }
                    }));
                    path.pop();
                });
                if (!this.columnsSnapshot.length) {
                    this.columns = [[]];
                    return;
                }
                this.columnsSnapshot[0].forEach(( /**
                 * @param {?} o
                 * @return {?}
                 */function (o) { return (isChildOption(o) ? loopChild(o) : loopParent(o)); }));
                if (sorter) {
                    results.sort(( /**
                     * @param {?} a
                     * @param {?} b
                     * @return {?}
                     */function (a, b) { return sorter(a.path, b.path, searchValue); }));
                }
                this.columns = [results];
            };
        /**
         * Toggle searching mode by UI. It deals with things not directly related to UI.
         * @param toSearching If this cascader is entering searching mode
         */
        /**
         * Toggle searching mode by UI. It deals with things not directly related to UI.
         * @param {?} toSearching If this cascader is entering searching mode
         * @return {?}
         */
        NzCascaderService.prototype.toggleSearchingMode = /**
         * Toggle searching mode by UI. It deals with things not directly related to UI.
         * @param {?} toSearching If this cascader is entering searching mode
         * @return {?}
         */
            function (toSearching) {
                this.inSearchingMode = toSearching;
                if (toSearching) {
                    this.activatedOptionsSnapshot = __spread(this.activatedOptions);
                    this.activatedOptions = [];
                    this.selectedOptions = [];
                    this.$redraw.next();
                }
                else {
                    // User quit searching mode without selecting an option.
                    this.activatedOptions = __spread(this.activatedOptionsSnapshot);
                    this.selectedOptions = __spread(this.activatedOptions);
                    this.columns = __spread(this.columnsSnapshot);
                    this.syncOptions();
                    this.$redraw.next();
                }
            };
        /**
         * @param {?} option
         * @param {?} index
         * @return {?}
         */
        NzCascaderService.prototype.setOptionSelected = /**
         * @param {?} option
         * @param {?} index
         * @return {?}
         */
            function (option, index) {
                /** @type {?} */
                var changeOn = this.cascaderComponent.nzChangeOn;
                /** @type {?} */
                var shouldPerformSelection = ( /**
                 * @param {?} o
                 * @param {?} i
                 * @return {?}
                 */function (o, i) {
                    return typeof changeOn === 'function' ? changeOn(o, i) : false;
                });
                if (option.isLeaf || this.cascaderComponent.nzChangeOnSelect || shouldPerformSelection(option, index)) {
                    this.selectedOptions = __spread(this.activatedOptions);
                    this.prepareEmitValue();
                    this.$redraw.next();
                    this.$optionSelected.next({ option: option, index: index });
                }
            };
        /**
         * Clear selected options.
         */
        /**
         * Clear selected options.
         * @return {?}
         */
        NzCascaderService.prototype.clear = /**
         * Clear selected options.
         * @return {?}
         */
            function () {
                this.values = [];
                this.selectedOptions = [];
                this.activatedOptions = [];
                this.dropBehindColumns(0);
                this.prepareEmitValue();
                this.$redraw.next();
                this.$optionSelected.next(null);
            };
        /**
         * @param {?} o
         * @return {?}
         */
        NzCascaderService.prototype.getOptionLabel = /**
         * @param {?} o
         * @return {?}
         */
            function (o) {
                return ( /** @type {?} */(o[this.cascaderComponent.nzLabelProperty || 'label']));
            };
        // tslint:disable-next-line:no-any
        // tslint:disable-next-line:no-any
        /**
         * @param {?} o
         * @return {?}
         */
        NzCascaderService.prototype.getOptionValue =
            // tslint:disable-next-line:no-any
            /**
             * @param {?} o
             * @return {?}
             */
            function (o) {
                return o[this.cascaderComponent.nzValueProperty || 'value'];
            };
        /**
         * Try to insert options into a column.
         * @param options Options to insert
         * @param columnIndex Position
         */
        /**
         * Try to insert options into a column.
         * @private
         * @param {?} options Options to insert
         * @param {?} columnIndex Position
         * @param {?} parent
         * @return {?}
         */
        NzCascaderService.prototype.setColumnData = /**
         * Try to insert options into a column.
         * @private
         * @param {?} options Options to insert
         * @param {?} columnIndex Position
         * @param {?} parent
         * @return {?}
         */
            function (options, columnIndex, parent) {
                /** @type {?} */
                var existingOptions = this.columns[columnIndex];
                if (!core$1.arraysEqual(existingOptions, options)) {
                    options.forEach(( /**
                     * @param {?} o
                     * @return {?}
                     */function (o) { return (o.parent = parent); }));
                    this.columns[columnIndex] = options;
                    this.dropBehindColumns(columnIndex);
                }
            };
        /**
         * Set all ancestor options as activated.
         */
        /**
         * Set all ancestor options as activated.
         * @private
         * @param {?} startIndex
         * @return {?}
         */
        NzCascaderService.prototype.trackAncestorActivatedOptions = /**
         * Set all ancestor options as activated.
         * @private
         * @param {?} startIndex
         * @return {?}
         */
            function (startIndex) {
                for (var i = startIndex - 1; i >= 0; i--) {
                    if (!this.activatedOptions[i]) {
                        this.activatedOptions[i] = ( /** @type {?} */(this.activatedOptions[i + 1].parent));
                    }
                }
            };
        /**
         * @private
         * @param {?} lastReserveIndex
         * @return {?}
         */
        NzCascaderService.prototype.dropBehindActivatedOptions = /**
         * @private
         * @param {?} lastReserveIndex
         * @return {?}
         */
            function (lastReserveIndex) {
                this.activatedOptions = this.activatedOptions.splice(0, lastReserveIndex + 1);
            };
        /**
         * @private
         * @param {?} lastReserveIndex
         * @return {?}
         */
        NzCascaderService.prototype.dropBehindColumns = /**
         * @private
         * @param {?} lastReserveIndex
         * @return {?}
         */
            function (lastReserveIndex) {
                if (lastReserveIndex < this.columns.length - 1) {
                    this.columns = this.columns.slice(0, lastReserveIndex + 1);
                }
            };
        /**
         * Load children of an option asynchronously.
         */
        /**
         * Load children of an option asynchronously.
         * @param {?} option
         * @param {?} columnIndex
         * @param {?=} success
         * @param {?=} failure
         * @return {?}
         */
        NzCascaderService.prototype.loadChildren = /**
         * Load children of an option asynchronously.
         * @param {?} option
         * @param {?} columnIndex
         * @param {?=} success
         * @param {?=} failure
         * @return {?}
         */
            function (option, // tslint:disable-line:no-any
            columnIndex, success, failure) {
                var _this = this;
                /** @type {?} */
                var loadFn = this.cascaderComponent.nzLoadData;
                if (loadFn) {
                    // If there isn't any option in columns.
                    this.$loading.next(columnIndex < 0);
                    if (typeof option === 'object') {
                        option.loading = true;
                    }
                    loadFn(option, columnIndex).then(( /**
                     * @return {?}
                     */function () {
                        option.loading = false;
                        if (option.children) {
                            _this.setColumnData(option.children, columnIndex + 1, option);
                        }
                        if (success) {
                            success();
                        }
                        _this.$loading.next(false);
                        _this.$redraw.next();
                    }), ( /**
                     * @return {?}
                     */function () {
                        option.loading = false;
                        option.isLeaf = true;
                        if (failure) {
                            failure();
                        }
                        _this.$redraw.next();
                    }));
                }
            };
        /**
         * @private
         * @param {?} index
         * @return {?}
         */
        NzCascaderService.prototype.isLoaded = /**
         * @private
         * @param {?} index
         * @return {?}
         */
            function (index) {
                return this.columns[index] && this.columns[index].length > 0;
            };
        /**
         * Find a option that has a given value in a given column.
         */
        /**
         * Find a option that has a given value in a given column.
         * @private
         * @param {?} columnIndex
         * @param {?} value
         * @return {?}
         */
        NzCascaderService.prototype.findOptionWithValue = /**
         * Find a option that has a given value in a given column.
         * @private
         * @param {?} columnIndex
         * @param {?} value
         * @return {?}
         */
            function (columnIndex, value // tslint:disable-line:no-any
            ) {
                var _this = this;
                /** @type {?} */
                var targetColumn = this.columns[columnIndex];
                if (targetColumn) {
                    /** @type {?} */
                    var v_1 = typeof value === 'object' ? this.getOptionValue(value) : value;
                    return ( /** @type {?} */(targetColumn.find(( /**
                     * @param {?} o
                     * @return {?}
                     */function (o) { return v_1 === _this.getOptionValue(o); }))));
                }
                return null;
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderService.prototype.prepareEmitValue = /**
         * @private
         * @return {?}
         */
            function () {
                var _this = this;
                this.values = this.selectedOptions.map(( /**
                 * @param {?} o
                 * @return {?}
                 */function (o) { return _this.getOptionValue(o); }));
            };
        NzCascaderService.decorators = [
            { type: core.Injectable }
        ];
        return NzCascaderService;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var defaultDisplayRender = ( /**
     * @param {?} labels
     * @return {?}
     */function (labels) { return labels.join(' / '); });
    var NzCascaderComponent = /** @class */ (function () {
        function NzCascaderComponent(cascaderService, cdr, elementRef, renderer, noAnimation) {
            this.cascaderService = cascaderService;
            this.cdr = cdr;
            this.noAnimation = noAnimation;
            this.nzShowInput = true;
            this.nzShowArrow = true;
            this.nzAllowClear = true;
            this.nzAutoFocus = false;
            this.nzChangeOnSelect = false;
            this.nzDisabled = false;
            this.nzExpandTrigger = 'click';
            this.nzValueProperty = 'value';
            this.nzLabelProperty = 'label';
            this.nzSize = 'default';
            this.nzPlaceHolder = 'Please select'; // TODO: i18n?
            this.nzMouseEnterDelay = 150; // ms
            // ms
            this.nzMouseLeaveDelay = 150; // ms
            // ms
            this.nzTriggerAction = ( /** @type {?} */(['click']));
            this.nzSelectionChange = new core.EventEmitter();
            this.nzSelect = new core.EventEmitter();
            this.nzClear = new core.EventEmitter();
            this.nzVisibleChange = new core.EventEmitter(); // Not exposed, only for test
            // Not exposed, only for test
            this.nzChange = new core.EventEmitter(); // Not exposed, only for test
            this.dropDownPosition = 'bottom';
            this.menuVisible = false;
            this.isLoading = false;
            this.labelRenderContext = {};
            this.onChange = Function.prototype;
            this.onTouched = Function.prototype;
            this.positions = __spread(core$1.DEFAULT_DROPDOWN_POSITIONS);
            this.isFocused = false;
            this.$destroy = new rxjs.Subject();
            this.inputString = '';
            this.isOpening = false;
            this.el = elementRef.nativeElement;
            this.cascaderService.withComponent(this);
            renderer.addClass(elementRef.nativeElement, 'ant-cascader');
            renderer.addClass(elementRef.nativeElement, 'ant-cascader-picker');
        }
        Object.defineProperty(NzCascaderComponent.prototype, "nzOptions", {
            get: 
            // tslint:disable-line:no-any
            /**
             * @return {?}
             */
            function () {
                return this.cascaderService.nzOptions;
            },
            set: /**
             * @param {?} options
             * @return {?}
             */ function (options) {
                this.cascaderService.withOptions(options);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "inSearchingMode", {
            get: /**
             * @return {?}
             */ function () {
                return this.cascaderService.inSearchingMode;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "inputValue", {
            get: /**
             * @return {?}
             */ function () {
                return this.inputString;
            },
            set: /**
             * @param {?} inputValue
             * @return {?}
             */ function (inputValue) {
                this.inputString = inputValue;
                this.toggleSearchingMode(!!inputValue);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "menuCls", {
            get: /**
             * @return {?}
             */ function () {
                var _a;
                return _a = {}, _a["" + this.nzMenuClassName] = !!this.nzMenuClassName, _a;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "menuColumnCls", {
            get: /**
             * @return {?}
             */ function () {
                var _a;
                return _a = {}, _a["" + this.nzColumnClassName] = !!this.nzColumnClassName, _a;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "hasInput", {
            get: /**
             * @private
             * @return {?}
             */ function () {
                return !!this.inputValue;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "hasValue", {
            get: /**
             * @private
             * @return {?}
             */ function () {
                return this.cascaderService.values && this.cascaderService.values.length > 0;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "showPlaceholder", {
            get: /**
             * @return {?}
             */ function () {
                return !(this.hasInput || this.hasValue);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "clearIconVisible", {
            get: /**
             * @return {?}
             */ function () {
                return this.nzAllowClear && !this.nzDisabled && (this.hasValue || this.hasInput);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzCascaderComponent.prototype, "isLabelRenderTemplate", {
            get: /**
             * @return {?}
             */ function () {
                return !!this.nzLabelRender;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                /** @type {?} */
                var srv = this.cascaderService;
                srv.$redraw.pipe(operators.takeUntil(this.$destroy)).subscribe(( /**
                 * @return {?}
                 */function () {
                    // These operations would not mutate data.
                    _this.checkChildren();
                    _this.buildDisplayLabel();
                    _this.reposition();
                    _this.cdr.markForCheck();
                }));
                srv.$loading.pipe(operators.takeUntil(this.$destroy)).subscribe(( /**
                 * @param {?} loading
                 * @return {?}
                 */function (loading) {
                    _this.isLoading = loading;
                }));
                srv.$optionSelected.pipe(operators.takeUntil(this.$destroy)).subscribe(( /**
                 * @param {?} data
                 * @return {?}
                 */function (data) {
                    if (!data) {
                        _this.onChange([]);
                        _this.nzSelect.emit(null);
                    }
                    else {
                        var option = data.option, index = data.index;
                        /** @type {?} */
                        var shouldClose = option.isLeaf;
                        if (shouldClose) {
                            _this.delaySetMenuVisible(false);
                        }
                        _this.onChange(_this.cascaderService.values);
                        _this.nzSelectionChange.emit(_this.cascaderService.selectedOptions);
                        _this.nzSelect.emit({ option: option, index: index });
                        _this.cdr.markForCheck();
                    }
                }));
                srv.$quitSearching.pipe(operators.takeUntil(this.$destroy)).subscribe(( /**
                 * @return {?}
                 */function () {
                    _this.inputString = '';
                    _this.dropdownWidthStyle = '';
                }));
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                this.$destroy.next();
                this.$destroy.complete();
                this.clearDelayMenuTimer();
                this.clearDelaySelectTimer();
            };
        /**
         * @param {?} fn
         * @return {?}
         */
        NzCascaderComponent.prototype.registerOnChange = /**
         * @param {?} fn
         * @return {?}
         */
            function (fn) {
                this.onChange = fn;
            };
        /**
         * @param {?} fn
         * @return {?}
         */
        NzCascaderComponent.prototype.registerOnTouched = /**
         * @param {?} fn
         * @return {?}
         */
            function (fn) {
                this.onTouched = fn;
            };
        // tslint:disable-next-line:no-any
        // tslint:disable-next-line:no-any
        /**
         * @param {?} value
         * @return {?}
         */
        NzCascaderComponent.prototype.writeValue =
            // tslint:disable-next-line:no-any
            /**
             * @param {?} value
             * @return {?}
             */
            function (value) {
                this.cascaderService.values = core$1.toArray(value);
                this.cascaderService.syncOptions(true);
            };
        /**
         * @param {?} visible
         * @param {?=} delay
         * @param {?=} setOpening
         * @return {?}
         */
        NzCascaderComponent.prototype.delaySetMenuVisible = /**
         * @param {?} visible
         * @param {?=} delay
         * @param {?=} setOpening
         * @return {?}
         */
            function (visible, delay, setOpening) {
                var _this = this;
                if (delay === void 0) {
                    delay = 100;
                }
                if (setOpening === void 0) {
                    setOpening = false;
                }
                this.clearDelayMenuTimer();
                if (delay) {
                    if (visible && setOpening) {
                        this.isOpening = true;
                    }
                    this.delayMenuTimer = setTimeout(( /**
                     * @return {?}
                     */function () {
                        _this.setMenuVisible(visible);
                        _this.cdr.detectChanges();
                        _this.clearDelayMenuTimer();
                        if (visible) {
                            setTimeout(( /**
                             * @return {?}
                             */function () {
                                _this.isOpening = false;
                            }), 100);
                        }
                    }), delay);
                }
                else {
                    this.setMenuVisible(visible);
                }
            };
        /**
         * @param {?} visible
         * @return {?}
         */
        NzCascaderComponent.prototype.setMenuVisible = /**
         * @param {?} visible
         * @return {?}
         */
            function (visible) {
                if (this.nzDisabled || this.menuVisible === visible) {
                    return;
                }
                if (visible) {
                    this.cascaderService.syncOptions();
                }
                this.menuVisible = visible;
                this.nzVisibleChange.emit(visible);
                this.cdr.detectChanges();
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.clearDelayMenuTimer = /**
         * @private
         * @return {?}
         */
            function () {
                if (this.delayMenuTimer) {
                    clearTimeout(this.delayMenuTimer);
                    this.delayMenuTimer = null;
                }
            };
        /**
         * @param {?=} event
         * @return {?}
         */
        NzCascaderComponent.prototype.clearSelection = /**
         * @param {?=} event
         * @return {?}
         */
            function (event) {
                if (event) {
                    event.preventDefault();
                    event.stopPropagation();
                }
                this.labelRenderText = '';
                this.labelRenderContext = {};
                this.inputValue = '';
                this.setMenuVisible(false);
                this.cascaderService.clear();
            };
        // tslint:disable-next-line:no-any
        // tslint:disable-next-line:no-any
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.getSubmitValue =
            // tslint:disable-next-line:no-any
            /**
             * @return {?}
             */
            function () {
                var _this = this;
                return this.cascaderService.selectedOptions.map(( /**
                 * @param {?} o
                 * @return {?}
                 */function (o) { return _this.cascaderService.getOptionValue(o); }));
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.focus = /**
         * @return {?}
         */
            function () {
                if (!this.isFocused) {
                    (this.input ? this.input.nativeElement : this.el).focus();
                    this.isFocused = true;
                }
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.blur = /**
         * @return {?}
         */
            function () {
                if (this.isFocused) {
                    (this.input ? this.input.nativeElement : this.el).blur();
                    this.isFocused = false;
                }
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.handleInputBlur = /**
         * @return {?}
         */
            function () {
                this.menuVisible ? this.focus() : this.blur();
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.handleInputFocus = /**
         * @return {?}
         */
            function () {
                this.focus();
            };
        /**
         * @param {?} event
         * @return {?}
         */
        NzCascaderComponent.prototype.onKeyDown = /**
         * @param {?} event
         * @return {?}
         */
            function (event) {
                /** @type {?} */
                var keyCode = event.keyCode;
                if (keyCode !== keycodes.DOWN_ARROW &&
                    keyCode !== keycodes.UP_ARROW &&
                    keyCode !== keycodes.LEFT_ARROW &&
                    keyCode !== keycodes.RIGHT_ARROW &&
                    keyCode !== keycodes.ENTER &&
                    keyCode !== keycodes.BACKSPACE &&
                    keyCode !== keycodes.ESCAPE) {
                    return;
                }
                // Press any keys above to reopen menu.
                if (!this.menuVisible && keyCode !== keycodes.BACKSPACE && keyCode !== keycodes.ESCAPE) {
                    return this.setMenuVisible(true);
                }
                // Make these keys work as default in searching mode.
                if (this.inSearchingMode && (keyCode === keycodes.BACKSPACE || keyCode === keycodes.LEFT_ARROW || keyCode === keycodes.RIGHT_ARROW)) {
                    return;
                }
                // Interact with the component.
                if (this.menuVisible) {
                    event.preventDefault();
                    if (keyCode === keycodes.DOWN_ARROW) {
                        this.moveUpOrDown(false);
                    }
                    else if (keyCode === keycodes.UP_ARROW) {
                        this.moveUpOrDown(true);
                    }
                    else if (keyCode === keycodes.LEFT_ARROW) {
                        this.moveLeft();
                    }
                    else if (keyCode === keycodes.RIGHT_ARROW) {
                        this.moveRight();
                    }
                    else if (keyCode === keycodes.ENTER) {
                        this.onEnter();
                    }
                }
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.onTriggerClick = /**
         * @return {?}
         */
            function () {
                if (this.nzDisabled) {
                    return;
                }
                if (this.nzShowSearch) {
                    this.focus();
                }
                if (this.isActionTrigger('click')) {
                    this.delaySetMenuVisible(!this.menuVisible, 100);
                }
                this.onTouched();
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.onTriggerMouseEnter = /**
         * @return {?}
         */
            function () {
                if (this.nzDisabled) {
                    return;
                }
                if (this.isActionTrigger('hover')) {
                    this.delaySetMenuVisible(true, this.nzMouseEnterDelay, true);
                }
            };
        /**
         * @param {?} event
         * @return {?}
         */
        NzCascaderComponent.prototype.onTriggerMouseLeave = /**
         * @param {?} event
         * @return {?}
         */
            function (event) {
                if (this.nzDisabled) {
                    return;
                }
                if (!this.menuVisible || this.isOpening) {
                    event.preventDefault();
                    return;
                }
                if (this.isActionTrigger('hover')) {
                    /** @type {?} */
                    var mouseTarget = ( /** @type {?} */(event.relatedTarget));
                    /** @type {?} */
                    var hostEl = this.el;
                    /** @type {?} */
                    var menuEl = this.menu && (( /** @type {?} */(this.menu.nativeElement)));
                    if (hostEl.contains(mouseTarget) || (menuEl && menuEl.contains(mouseTarget))) {
                        return;
                    }
                    this.delaySetMenuVisible(false, this.nzMouseLeaveDelay);
                }
            };
        /**
         * @private
         * @param {?} action
         * @return {?}
         */
        NzCascaderComponent.prototype.isActionTrigger = /**
         * @private
         * @param {?} action
         * @return {?}
         */
            function (action) {
                return typeof this.nzTriggerAction === 'string'
                    ? this.nzTriggerAction === action
                    : this.nzTriggerAction.indexOf(action) !== -1;
            };
        /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
        NzCascaderComponent.prototype.onOptionClick = /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
            function (option, columnIndex, event) {
                if (event) {
                    event.preventDefault();
                }
                if (option && option.disabled) {
                    return;
                }
                this.el.focus();
                this.inSearchingMode
                    ? this.cascaderService.setSearchOptionSelected(( /** @type {?} */(option)))
                    : this.cascaderService.setOptionActivated(option, columnIndex, true);
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.onEnter = /**
         * @private
         * @return {?}
         */
            function () {
                /** @type {?} */
                var columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0);
                /** @type {?} */
                var option = this.cascaderService.activatedOptions[columnIndex];
                if (option && !option.disabled) {
                    this.inSearchingMode
                        ? this.cascaderService.setSearchOptionSelected(( /** @type {?} */(option)))
                        : this.cascaderService.setOptionActivated(option, columnIndex, true);
                }
            };
        /**
         * @private
         * @param {?} isUp
         * @return {?}
         */
        NzCascaderComponent.prototype.moveUpOrDown = /**
         * @private
         * @param {?} isUp
         * @return {?}
         */
            function (isUp) {
                /** @type {?} */
                var columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0);
                /** @type {?} */
                var activeOption = this.cascaderService.activatedOptions[columnIndex];
                /** @type {?} */
                var options = this.cascaderService.columns[columnIndex] || [];
                /** @type {?} */
                var length = options.length;
                /** @type {?} */
                var nextIndex = -1;
                if (!activeOption) {
                    // Not selected options in this column
                    nextIndex = isUp ? length : -1;
                }
                else {
                    nextIndex = options.indexOf(activeOption);
                }
                while (true) {
                    nextIndex = isUp ? nextIndex - 1 : nextIndex + 1;
                    if (nextIndex < 0 || nextIndex >= length) {
                        break;
                    }
                    /** @type {?} */
                    var nextOption = options[nextIndex];
                    if (!nextOption || nextOption.disabled) {
                        continue;
                    }
                    this.cascaderService.setOptionActivated(nextOption, columnIndex);
                    break;
                }
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.moveLeft = /**
         * @private
         * @return {?}
         */
            function () {
                /** @type {?} */
                var options = this.cascaderService.activatedOptions;
                if (options.length) {
                    options.pop(); // Remove the last one
                }
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.moveRight = /**
         * @private
         * @return {?}
         */
            function () {
                /** @type {?} */
                var length = this.cascaderService.activatedOptions.length;
                /** @type {?} */
                var options = this.cascaderService.columns[length];
                if (options && options.length) {
                    /** @type {?} */
                    var nextOpt = options.find(( /**
                     * @param {?} o
                     * @return {?}
                     */function (o) { return !o.disabled; }));
                    if (nextOpt) {
                        this.cascaderService.setOptionActivated(nextOpt, length);
                    }
                }
            };
        /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
        NzCascaderComponent.prototype.onOptionMouseEnter = /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
            function (option, columnIndex, event) {
                event.preventDefault();
                if (this.nzExpandTrigger === 'hover' && !option.isLeaf) {
                    this.delaySelectOption(option, columnIndex, true);
                }
            };
        /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
        NzCascaderComponent.prototype.onOptionMouseLeave = /**
         * @param {?} option
         * @param {?} columnIndex
         * @param {?} event
         * @return {?}
         */
            function (option, columnIndex, event) {
                event.preventDefault();
                if (this.nzExpandTrigger === 'hover' && !option.isLeaf) {
                    this.delaySelectOption(option, columnIndex, false);
                }
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.clearDelaySelectTimer = /**
         * @private
         * @return {?}
         */
            function () {
                if (this.delaySelectTimer) {
                    clearTimeout(this.delaySelectTimer);
                    this.delaySelectTimer = null;
                }
            };
        /**
         * @private
         * @param {?} option
         * @param {?} index
         * @param {?} doSelect
         * @return {?}
         */
        NzCascaderComponent.prototype.delaySelectOption = /**
         * @private
         * @param {?} option
         * @param {?} index
         * @param {?} doSelect
         * @return {?}
         */
            function (option, index, doSelect) {
                var _this = this;
                this.clearDelaySelectTimer();
                if (doSelect) {
                    this.delaySelectTimer = setTimeout(( /**
                     * @return {?}
                     */function () {
                        _this.cascaderService.setOptionActivated(option, index);
                        _this.delaySelectTimer = null;
                    }), 150);
                }
            };
        /**
         * @private
         * @param {?} toSearching
         * @return {?}
         */
        NzCascaderComponent.prototype.toggleSearchingMode = /**
         * @private
         * @param {?} toSearching
         * @return {?}
         */
            function (toSearching) {
                if (this.inSearchingMode !== toSearching) {
                    this.cascaderService.toggleSearchingMode(toSearching);
                    this.dropdownWidthStyle = toSearching ? this.input.nativeElement.offsetWidth + "px" : '';
                }
                if (this.inSearchingMode) {
                    this.cascaderService.prepareSearchOptions(this.inputValue);
                }
            };
        /**
         * @param {?} option
         * @param {?} index
         * @return {?}
         */
        NzCascaderComponent.prototype.isOptionActivated = /**
         * @param {?} option
         * @param {?} index
         * @return {?}
         */
            function (option, index) {
                /** @type {?} */
                var activeOpt = this.cascaderService.activatedOptions[index];
                return activeOpt === option;
            };
        /**
         * @param {?} isDisabled
         * @return {?}
         */
        NzCascaderComponent.prototype.setDisabledState = /**
         * @param {?} isDisabled
         * @return {?}
         */
            function (isDisabled) {
                if (isDisabled) {
                    this.closeMenu();
                }
                this.nzDisabled = isDisabled;
            };
        /**
         * @return {?}
         */
        NzCascaderComponent.prototype.closeMenu = /**
         * @return {?}
         */
            function () {
                this.blur();
                this.clearDelayMenuTimer();
                this.setMenuVisible(false);
            };
        /**
         * @param {?} position
         * @return {?}
         */
        NzCascaderComponent.prototype.onPositionChange = /**
         * @param {?} position
         * @return {?}
         */
            function (position) {
                /** @type {?} */
                var newValue = position.connectionPair.originY === 'bottom' ? 'bottom' : 'top';
                if (this.dropDownPosition !== newValue) {
                    this.dropDownPosition = newValue;
                    this.cdr.detectChanges();
                }
            };
        /**
         * Reposition the cascader panel. When a menu opens, the cascader expands
         * and may exceed the boundary of browser's window.
         */
        /**
         * Reposition the cascader panel. When a menu opens, the cascader expands
         * and may exceed the boundary of browser's window.
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.reposition = /**
         * Reposition the cascader panel. When a menu opens, the cascader expands
         * and may exceed the boundary of browser's window.
         * @private
         * @return {?}
         */
            function () {
                var _this = this;
                if (this.overlay && this.overlay.overlayRef && this.menuVisible) {
                    Promise.resolve().then(( /**
                     * @return {?}
                     */function () {
                        _this.overlay.overlayRef.updatePosition();
                    }));
                }
            };
        /**
         * When a cascader options is changed, a child needs to know that it should re-render.
         */
        /**
         * When a cascader options is changed, a child needs to know that it should re-render.
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.checkChildren = /**
         * When a cascader options is changed, a child needs to know that it should re-render.
         * @private
         * @return {?}
         */
            function () {
                if (this.cascaderItems) {
                    this.cascaderItems.forEach(( /**
                     * @param {?} item
                     * @return {?}
                     */function (item) { return item.markForCheck(); }));
                }
            };
        /**
         * @private
         * @return {?}
         */
        NzCascaderComponent.prototype.buildDisplayLabel = /**
         * @private
         * @return {?}
         */
            function () {
                var _this = this;
                /** @type {?} */
                var selectedOptions = this.cascaderService.selectedOptions;
                /** @type {?} */
                var labels = selectedOptions.map(( /**
                 * @param {?} o
                 * @return {?}
                 */function (o) { return _this.cascaderService.getOptionLabel(o); }));
                if (this.isLabelRenderTemplate) {
                    this.labelRenderContext = { labels: labels, selectedOptions: selectedOptions };
                }
                else {
                    this.labelRenderText = defaultDisplayRender.call(this, labels, selectedOptions);
                }
            };
        NzCascaderComponent.decorators = [
            { type: core.Component, args: [{
                        changeDetection: core.ChangeDetectionStrategy.OnPush,
                        encapsulation: core.ViewEncapsulation.None,
                        selector: 'nz-cascader,[nz-cascader]',
                        exportAs: 'nzCascader',
                        preserveWhitespaces: false,
                        template: "<div\n  cdkOverlayOrigin\n  #origin=\"cdkOverlayOrigin\"\n  #trigger>\n  <div *ngIf=\"nzShowInput\">\n    <input\n      #input\n      nz-input\n      class=\"ant-cascader-input\"\n      [class.ant-cascader-input-disabled]=\"nzDisabled\"\n      [class.ant-cascader-input-lg]=\"nzSize === 'large'\"\n      [class.ant-cascader-input-sm]=\"nzSize === 'small'\"\n      [attr.autoComplete]=\"'off'\"\n      [attr.placeholder]=\"showPlaceholder ? nzPlaceHolder : null\"\n      [attr.autofocus]=\"nzAutoFocus ? 'autofocus' : null\"\n      [readonly]=\"!nzShowSearch\"\n      [disabled]=\"nzDisabled\"\n      [nzSize]=\"nzSize\"\n      [(ngModel)]=\"inputValue\"\n      (blur)=\"handleInputBlur()\"\n      (focus)=\"handleInputFocus()\"\n      (change)=\"$event.stopPropagation()\">\n    <i *ngIf=\"clearIconVisible\"\n      nz-icon\n      type=\"close-circle\"\n      theme=\"fill\"\n      class=\"ant-cascader-picker-clear\"\n      (click)=\"clearSelection($event)\"></i>\n    <i *ngIf=\"nzShowArrow && !isLoading\"\n      nz-icon\n      type=\"down\"\n      class=\"ant-cascader-picker-arrow\"\n      [class.ant-cascader-picker-arrow-expand]=\"menuVisible\">\n    </i>\n    <i *ngIf=\"isLoading\" nz-icon type=\"loading\" class=\"ant-cascader-picker-arrow\"></i>\n    <span\n      class=\"ant-cascader-picker-label\"\n      [class.ant-cascader-show-search]=\"!!nzShowSearch\"\n      [class.ant-focusd]=\"!!nzShowSearch && isFocused && !inputValue\">\n      <ng-container *ngIf=\"!isLabelRenderTemplate; else labelTemplate\">{{ labelRenderText }}</ng-container>\n      <ng-template #labelTemplate>\n        <ng-template [ngTemplateOutlet]=\"nzLabelRender\" [ngTemplateOutletContext]=\"labelRenderContext\"></ng-template>\n      </ng-template>\n    </span>\n  </div>\n  <ng-content></ng-content>\n</div>\n<ng-template\n  cdkConnectedOverlay\n  nzConnectedOverlay\n  cdkConnectedOverlayHasBackdrop\n  [cdkConnectedOverlayOrigin]=\"origin\"\n  [cdkConnectedOverlayPositions]=\"positions\"\n  (backdropClick)=\"closeMenu()\"\n  (detach)=\"closeMenu()\"\n  (positionChange)=\"onPositionChange($event)\"\n  [cdkConnectedOverlayOpen]=\"menuVisible\">\n  <div\n    #menu\n    class=\"ant-cascader-menus\"\n    *ngIf=\"nzOptions && nzOptions.length || inSearchingMode\"\n    [class.ant-cascader-menus-hidden]=\"!menuVisible\"\n    [ngClass]=\"menuCls\"\n    [ngStyle]=\"nzMenuStyle\"\n    [nzNoAnimation]=\"noAnimation?.nzNoAnimation\"\n    [@slideMotion]=\"dropDownPosition\"\n    (mouseleave)=\"onTriggerMouseLeave($event)\">\n    <ul *ngFor=\"let options of cascaderService.columns; let i = index;\" class=\"ant-cascader-menu\"\n      [ngClass]=\"menuColumnCls\"\n      [style.height]=\"inSearchingMode && !cascaderService.columns[0].length ? 'auto': ''\"\n      [style.width]=\"dropdownWidthStyle\">\n      <li\n        nz-cascader-option\n        *ngFor=\"let option of options\"\n        [nzLabelProperty]=\"nzLabelProperty\"\n        [activated]=\"isOptionActivated(option, i)\"\n        [highlightText]=\"inSearchingMode ? inputValue : ''\"\n        [option]=\"option\"\n        (mouseenter)=\"onOptionMouseEnter(option, i, $event)\"\n        (mouseleave)=\"onOptionMouseLeave(option, i, $event)\"\n        (click)=\"onOptionClick(option, i, $event)\">\n      </li>\n      <li *ngIf=\"inSearchingMode && !cascaderService.columns[0].length\"\n        class=\"ant-cascader-menu-item ant-cascader-menu-item-expanded ant-cascader-menu-item-disabled\">\n        <nz-embed-empty [nzComponentName]=\"'cascader'\" [specificContent]=\"nzNotFoundContent\"></nz-embed-empty>\n      </li>\n    </ul>\n  </div>\n</ng-template>\n",
                        animations: [core$1.slideMotion],
                        providers: [
                            {
                                provide: forms.NG_VALUE_ACCESSOR,
                                useExisting: core.forwardRef(( /**
                                 * @return {?}
                                 */function () { return NzCascaderComponent; })),
                                multi: true
                            },
                            NzCascaderService
                        ],
                        host: {
                            '[attr.tabIndex]': '"0"',
                            '[class.ant-cascader-lg]': 'nzSize === "large"',
                            '[class.ant-cascader-sm]': 'nzSize === "small"',
                            '[class.ant-cascader-picker-disabled]': 'nzDisabled',
                            '[class.ant-cascader-picker-open]': 'menuVisible',
                            '[class.ant-cascader-picker-with-value]': '!!inputValue',
                            '[class.ant-cascader-focused]': 'isFocused'
                        },
                        styles: ["\n      .ant-cascader-menus {\n        margin-top: 4px;\n        margin-bottom: 4px;\n        top: 100%;\n        left: 0;\n        position: relative;\n        width: 100%;\n      }\n    "]
                    }] }
        ];
        /** @nocollapse */
        NzCascaderComponent.ctorParameters = function () {
            return [
                { type: NzCascaderService },
                { type: core.ChangeDetectorRef },
                { type: core.ElementRef },
                { type: core.Renderer2 },
                { type: core$1.NzNoAnimationDirective, decorators: [{ type: core.Host }, { type: core.Optional }] }
            ];
        };
        NzCascaderComponent.propDecorators = {
            input: [{ type: core.ViewChild, args: ['input',] }],
            menu: [{ type: core.ViewChild, args: ['menu',] }],
            overlay: [{ type: core.ViewChild, args: [overlay.CdkConnectedOverlay,] }],
            cascaderItems: [{ type: core.ViewChildren, args: [NzCascaderOptionComponent,] }],
            nzShowInput: [{ type: core.Input }],
            nzShowArrow: [{ type: core.Input }],
            nzAllowClear: [{ type: core.Input }],
            nzAutoFocus: [{ type: core.Input }],
            nzChangeOnSelect: [{ type: core.Input }],
            nzDisabled: [{ type: core.Input }],
            nzColumnClassName: [{ type: core.Input }],
            nzExpandTrigger: [{ type: core.Input }],
            nzValueProperty: [{ type: core.Input }],
            nzLabelRender: [{ type: core.Input }],
            nzLabelProperty: [{ type: core.Input }],
            nzNotFoundContent: [{ type: core.Input }],
            nzSize: [{ type: core.Input }],
            nzShowSearch: [{ type: core.Input }],
            nzPlaceHolder: [{ type: core.Input }],
            nzMenuClassName: [{ type: core.Input }],
            nzMenuStyle: [{ type: core.Input }],
            nzMouseEnterDelay: [{ type: core.Input }],
            nzMouseLeaveDelay: [{ type: core.Input }],
            nzTriggerAction: [{ type: core.Input }],
            nzChangeOn: [{ type: core.Input }],
            nzLoadData: [{ type: core.Input }],
            nzOptions: [{ type: core.Input }],
            nzSelectionChange: [{ type: core.Output }],
            nzSelect: [{ type: core.Output }],
            nzClear: [{ type: core.Output }],
            nzVisibleChange: [{ type: core.Output }],
            nzChange: [{ type: core.Output }],
            onKeyDown: [{ type: core.HostListener, args: ['keydown', ['$event'],] }],
            onTriggerClick: [{ type: core.HostListener, args: ['click',] }],
            onTriggerMouseEnter: [{ type: core.HostListener, args: ['mouseenter',] }],
            onTriggerMouseLeave: [{ type: core.HostListener, args: ['mouseleave', ['$event'],] }]
        };
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzShowInput", void 0);
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzShowArrow", void 0);
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzAllowClear", void 0);
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzAutoFocus", void 0);
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzChangeOnSelect", void 0);
        __decorate([
            core$1.InputBoolean(),
            __metadata("design:type", Object)
        ], NzCascaderComponent.prototype, "nzDisabled", void 0);
        return NzCascaderComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NzCascaderModule = /** @class */ (function () {
        function NzCascaderModule() {
        }
        NzCascaderModule.decorators = [
            { type: core.NgModule, args: [{
                        imports: [
                            common.CommonModule,
                            forms.FormsModule,
                            overlay.OverlayModule,
                            input.NzInputModule,
                            icon.NzIconModule,
                            empty.NzEmptyModule,
                            core$1.NzOverlayModule,
                            core$1.NzNoAnimationModule
                        ],
                        declarations: [NzCascaderComponent, NzCascaderOptionComponent],
                        exports: [NzCascaderComponent]
                    },] }
        ];
        return NzCascaderModule;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    exports.isShowSearchObject = isShowSearchObject;
    exports.isChildOption = isChildOption;
    exports.isParentOption = isParentOption;
    exports.NzCascaderComponent = NzCascaderComponent;
    exports.NzCascaderModule = NzCascaderModule;
    exports.NzCascaderService = NzCascaderService;
    exports.NzCascaderOptionComponent = NzCascaderOptionComponent;

    Object.defineProperty(exports, '__esModule', { value: true });

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctem9ycm8tYW50ZC1jYXNjYWRlci51bWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL25nLXpvcnJvLWFudGQvY2FzY2FkZXIvbnotY2FzY2FkZXItZGVmaW5pdGlvbnMudHMiLCJuZzovL25nLXpvcnJvLWFudGQvY2FzY2FkZXIvbnotY2FzY2FkZXItdXRpbHMudHMiLCJub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzIiwibmc6Ly9uZy16b3Jyby1hbnRkL2Nhc2NhZGVyL256LWNhc2NhZGVyLWxpLmNvbXBvbmVudC50cyIsIm5nOi8vbmctem9ycm8tYW50ZC9jYXNjYWRlci9uei1jYXNjYWRlci5zZXJ2aWNlLnRzIiwibmc6Ly9uZy16b3Jyby1hbnRkL2Nhc2NhZGVyL256LWNhc2NhZGVyLmNvbXBvbmVudC50cyIsIm5nOi8vbmctem9ycm8tYW50ZC9jYXNjYWRlci9uei1jYXNjYWRlci5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmV4cG9ydCB0eXBlIE56Q2FzY2FkZXJFeHBhbmRUcmlnZ2VyID0gJ2NsaWNrJyB8ICdob3Zlcic7XG5leHBvcnQgdHlwZSBOekNhc2NhZGVyVHJpZ2dlclR5cGUgPSAnY2xpY2snIHwgJ2hvdmVyJztcbmV4cG9ydCB0eXBlIE56Q2FzY2FkZXJTaXplID0gJ3NtYWxsJyB8ICdsYXJnZScgfCAnZGVmYXVsdCc7XG5cbmV4cG9ydCB0eXBlIE56Q2FzY2FkZXJGaWx0ZXIgPSAoc2VhcmNoVmFsdWU6IHN0cmluZywgcGF0aDogQ2FzY2FkZXJPcHRpb25bXSkgPT4gYm9vbGVhbjtcbmV4cG9ydCB0eXBlIE56Q2FzY2FkZXJTb3J0ZXIgPSAoYTogQ2FzY2FkZXJPcHRpb25bXSwgYjogQ2FzY2FkZXJPcHRpb25bXSwgaW5wdXRWYWx1ZTogc3RyaW5nKSA9PiBudW1iZXI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FzY2FkZXJPcHRpb24ge1xuICB2YWx1ZT86IGFueTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1hbnlcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIGxvYWRpbmc/OiBib29sZWFuO1xuICBpc0xlYWY/OiBib29sZWFuO1xuICBwYXJlbnQ/OiBDYXNjYWRlck9wdGlvbjtcbiAgY2hpbGRyZW4/OiBDYXNjYWRlck9wdGlvbltdO1xuXG4gIFtrZXk6IHN0cmluZ106IGFueTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1hbnlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYXNjYWRlclNlYXJjaE9wdGlvbiBleHRlbmRzIENhc2NhZGVyT3B0aW9uIHtcbiAgcGF0aDogQ2FzY2FkZXJPcHRpb25bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOelNob3dTZWFyY2hPcHRpb25zIHtcbiAgZmlsdGVyPzogTnpDYXNjYWRlckZpbHRlcjtcbiAgc29ydGVyPzogTnpDYXNjYWRlclNvcnRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2hvd1NlYXJjaE9iamVjdChvcHRpb25zOiBOelNob3dTZWFyY2hPcHRpb25zIHwgYm9vbGVhbik6IG9wdGlvbnMgaXMgTnpTaG93U2VhcmNoT3B0aW9ucyB7XG4gIHJldHVybiB0eXBlb2Ygb3B0aW9ucyAhPT0gJ2Jvb2xlYW4nO1xufVxuXG4vKipcbiAqIFRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHByb3ZpZGUgYW4gaW50ZXJmYWNlIG9mIGBOekNhc2NhZGVyQ29tcG9uZW50YFxuICogZm9yIGBOekNhc2NhZGVyU2VydmljZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTnpDYXNjYWRlckNvbXBvbmVudEFzU291cmNlIHtcbiAgaW5wdXRWYWx1ZTogc3RyaW5nO1xuICBuelNob3dTZWFyY2g6IE56U2hvd1NlYXJjaE9wdGlvbnMgfCBib29sZWFuO1xuICBuekxhYmVsUHJvcGVydHk6IHN0cmluZztcbiAgbnpWYWx1ZVByb3BlcnR5OiBzdHJpbmc7XG4gIG56Q2hhbmdlT25TZWxlY3Q6IGJvb2xlYW47XG5cbiAgbnpDaGFuZ2VPbj8ob3B0aW9uOiBDYXNjYWRlck9wdGlvbiwgbGV2ZWw6IG51bWJlcik6IGJvb2xlYW47XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBuekxvYWREYXRhPyhub2RlOiBDYXNjYWRlck9wdGlvbiwgaW5kZXg/OiBudW1iZXIpOiBQcm9taXNlTGlrZTxhbnk+O1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IENhc2NhZGVyT3B0aW9uIH0gZnJvbSAnLi9uei1jYXNjYWRlci1kZWZpbml0aW9ucyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NoaWxkT3B0aW9uKG86IENhc2NhZGVyT3B0aW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiBvLmlzTGVhZiB8fCAhby5jaGlsZHJlbiB8fCAhby5jaGlsZHJlbi5sZW5ndGg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1BhcmVudE9wdGlvbihvOiBDYXNjYWRlck9wdGlvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gISFvLmNoaWxkcmVuICYmICEhby5jaGlsZHJlbi5sZW5ndGggJiYgIW8uaXNMZWFmO1xufVxuIiwiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcclxudGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcclxuTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcblRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRFxyXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxyXG5NRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULlxyXG5cclxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXHJcbmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIGlmIChlLmluZGV4T2YocFtpXSkgPCAwKVxyXG4gICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIGV4cG9ydHMpIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKCFleHBvcnRzLmhhc093blByb3BlcnR5KHApKSBleHBvcnRzW3BdID0gbVtwXTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgcmVzdWx0W2tdID0gbW9kW2tdO1xyXG4gICAgcmVzdWx0LmRlZmF1bHQgPSBtb2Q7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIElucHV0LFxuICBSZW5kZXJlcjIsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlSHRtbCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuXG5pbXBvcnQgeyBDYXNjYWRlck9wdGlvbiB9IGZyb20gJy4vbnotY2FzY2FkZXItZGVmaW5pdGlvbnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHNlbGVjdG9yOiAnW256LWNhc2NhZGVyLW9wdGlvbl0nLFxuICBleHBvcnRBczogJ256Q2FzY2FkZXJPcHRpb24nLFxuICB0ZW1wbGF0ZVVybDogJy4vbnotY2FzY2FkZXItbGkuY29tcG9uZW50Lmh0bWwnLFxuICBob3N0OiB7XG4gICAgJ1thdHRyLnRpdGxlXSc6ICdvcHRpb24udGl0bGUgfHwgZ2V0T3B0aW9uTGFiZWwoKScsXG4gICAgJ1tjbGFzcy5hbnQtY2FzY2FkZXItbWVudS1pdGVtLWFjdGl2ZV0nOiAnYWN0aXZhdGVkJyxcbiAgICAnW2NsYXNzLmFudC1jYXNjYWRlci1tZW51LWl0ZW0tZXhwYW5kXSc6ICchb3B0aW9uLmlzTGVhZicsXG4gICAgJ1tjbGFzcy5hbnQtY2FzY2FkZXItbWVudS1pdGVtLWRpc2FibGVkXSc6ICdvcHRpb24uZGlzYWJsZWQnXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTnpDYXNjYWRlck9wdGlvbkNvbXBvbmVudCB7XG4gIEBJbnB1dCgpIG9wdGlvbjogQ2FzY2FkZXJPcHRpb247XG4gIEBJbnB1dCgpIGFjdGl2YXRlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBoaWdobGlnaHRUZXh0OiBzdHJpbmc7XG4gIEBJbnB1dCgpIG56TGFiZWxQcm9wZXJ0eSA9ICdsYWJlbCc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyXG4gICkge1xuICAgIHJlbmRlcmVyLmFkZENsYXNzKGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2FudC1jYXNjYWRlci1tZW51LWl0ZW0nKTtcbiAgfVxuXG4gIGdldE9wdGlvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9uID8gdGhpcy5vcHRpb25bdGhpcy5uekxhYmVsUHJvcGVydHldIDogJyc7XG4gIH1cblxuICByZW5kZXJIaWdobGlnaHRTdHJpbmcoc3RyOiBzdHJpbmcpOiBTYWZlSHRtbCB7XG4gICAgY29uc3QgcmVwbGFjZVN0ciA9IHN0ci5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cCh0aGlzLmhpZ2hsaWdodFRleHQsICdnJyksXG4gICAgICBgPHNwYW4gY2xhc3M9XCJhbnQtY2FzY2FkZXItbWVudS1pdGVtLWtleXdvcmRcIj4ke3RoaXMuaGlnaGxpZ2h0VGV4dH08L3NwYW4+YFxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwocmVwbGFjZVN0cik7XG4gIH1cblxuICBtYXJrRm9yQ2hlY2soKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBhcnJheXNFcXVhbCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZSc7XG5cbmltcG9ydCB7XG4gIGlzU2hvd1NlYXJjaE9iamVjdCxcbiAgQ2FzY2FkZXJPcHRpb24sXG4gIENhc2NhZGVyU2VhcmNoT3B0aW9uLFxuICBOekNhc2NhZGVyQ29tcG9uZW50QXNTb3VyY2UsXG4gIE56Q2FzY2FkZXJGaWx0ZXJcbn0gZnJvbSAnLi9uei1jYXNjYWRlci1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBpc0NoaWxkT3B0aW9uLCBpc1BhcmVudE9wdGlvbiB9IGZyb20gJy4vbnotY2FzY2FkZXItdXRpbHMnO1xuXG4vKipcbiAqIEFsbCBkYXRhIGlzIHN0b3JlZCBhbmQgcGFyc2VkIGluIE56Q2FzY2FkZXJTZXJ2aWNlLlxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTnpDYXNjYWRlclNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKiogQWN0aXZhdGVkIG9wdGlvbnMgaW4gZWFjaCBjb2x1bW4uICovXG4gIGFjdGl2YXRlZE9wdGlvbnM6IENhc2NhZGVyT3B0aW9uW10gPSBbXTtcblxuICAvKiogQW4gYXJyYXkgdG8gc3RvcmUgY2FzY2FkZXIgaXRlbXMgYXJyYW5nZWQgaW4gZGlmZmVyZW50IGxheWVycy4gKi9cbiAgY29sdW1uczogQ2FzY2FkZXJPcHRpb25bXVtdID0gW1tdXTtcblxuICAvKiogSWYgdXNlciBoYXMgZW50ZXJlZCBzZWFyY2hpbmcgbW9kZS4gKi9cbiAgaW5TZWFyY2hpbmdNb2RlID0gZmFsc2U7XG5cbiAgLyoqIFNlbGVjdGVkIG9wdGlvbnMgd291bGQgYmUgb3V0cHV0IHRvIHVzZXIuICovXG4gIHNlbGVjdGVkT3B0aW9uczogQ2FzY2FkZXJPcHRpb25bXSA9IFtdO1xuXG4gIHZhbHVlczogYW55W10gPSBbXTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1hbnlcblxuICByZWFkb25seSAkbG9hZGluZyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIC8qKlxuICAgKiBFbWl0IGFuIGV2ZW50IHRvIG5vdGlmeSBjYXNjYWRlciBpdCBuZWVkcyB0byByZWRyYXcgYmVjYXVzZSBhY3RpdmF0ZWQgb3JcbiAgICogc2VsZWN0ZWQgb3B0aW9ucyBhcmUgY2hhbmdlZC5cbiAgICovXG4gIHJlYWRvbmx5ICRyZWRyYXcgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qKlxuICAgKiBFbWl0IGFuIGV2ZW50IHdoZW4gYW4gb3B0aW9uIGdldHMgc2VsZWN0ZWQuXG4gICAqIEVtaXQgdHJ1ZSBpZiBhIGxlYWYgb3B0aW9ucyBpcyBzZWxlY3RlZC5cbiAgICovXG4gIHJlYWRvbmx5ICRvcHRpb25TZWxlY3RlZCA9IG5ldyBTdWJqZWN0PHtcbiAgICBvcHRpb246IENhc2NhZGVyT3B0aW9uO1xuICAgIGluZGV4OiBudW1iZXI7XG4gIH0gfCBudWxsPigpO1xuXG4gIC8qKlxuICAgKiBFbWl0IGFuIGV2ZW50IHRvIG5vdGlmeSBjYXNjYWRlciBpdCBuZWVkcyB0byBxdWl0IHNlYXJjaGluZyBtb2RlLlxuICAgKiBPbmx5IGVtaXQgd2hlbiB1c2VyIGRvIHNlbGVjdCBhIHNlYXJjaGluZyBvcHRpb24uXG4gICAqL1xuICByZWFkb25seSAkcXVpdFNlYXJjaGluZyA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIFRvIGhvbGQgY29sdW1ucyBiZWZvcmUgZW50ZXJpbmcgc2VhcmNoaW5nIG1vZGUuICovXG4gIHByaXZhdGUgY29sdW1uc1NuYXBzaG90OiBDYXNjYWRlck9wdGlvbltdW10gPSBbW11dO1xuXG4gIC8qKiBUbyBob2xkIGFjdGl2YXRlZCBvcHRpb25zIGJlZm9yZSBlbnRlcmluZyBzZWFyY2hpbmcgbW9kZS4gKi9cbiAgcHJpdmF0ZSBhY3RpdmF0ZWRPcHRpb25zU25hcHNob3Q6IENhc2NhZGVyT3B0aW9uW10gPSBbXTtcblxuICBwcml2YXRlIGNhc2NhZGVyQ29tcG9uZW50OiBOekNhc2NhZGVyQ29tcG9uZW50QXNTb3VyY2U7XG5cbiAgLyoqIFJldHVybiBjYXNjYWRlciBvcHRpb25zIGluIHRoZSBmaXJzdCBsYXllci4gKi9cbiAgZ2V0IG56T3B0aW9ucygpOiBDYXNjYWRlck9wdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5jb2x1bW5zWzBdO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy4kcmVkcmF3LmNvbXBsZXRlKCk7XG4gICAgdGhpcy4kcXVpdFNlYXJjaGluZy5jb21wbGV0ZSgpO1xuICAgIHRoaXMuJG9wdGlvblNlbGVjdGVkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy4kbG9hZGluZy5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2Ugc3VyZSB0aGF0IHZhbHVlIG1hdGNoZXMgd2hhdCBpcyBkaXNwbGF5ZWQgaW4gdGhlIGRyb3Bkb3duLlxuICAgKi9cbiAgc3luY09wdGlvbnMoZmlyc3Q6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMudmFsdWVzO1xuICAgIGNvbnN0IGhhc1ZhbHVlID0gdmFsdWVzICYmIHZhbHVlcy5sZW5ndGg7XG4gICAgY29uc3QgbGFzdENvbHVtbkluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgY29uc3QgaW5pdENvbHVtbldpdGhJbmRleCA9IChjb2x1bW5JbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBhY3RpdmF0ZWRPcHRpb25TZXR0ZXIgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHZhbHVlc1tjb2x1bW5JbmRleF07XG5cbiAgICAgICAgaWYgKCFjdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICB0aGlzLiRyZWRyYXcubmV4dCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9wdGlvbiA9XG4gICAgICAgICAgdGhpcy5maW5kT3B0aW9uV2l0aFZhbHVlKGNvbHVtbkluZGV4LCB2YWx1ZXNbY29sdW1uSW5kZXhdKSB8fFxuICAgICAgICAgICh0eXBlb2YgY3VycmVudFZhbHVlID09PSAnb2JqZWN0J1xuICAgICAgICAgICAgPyBjdXJyZW50VmFsdWVcbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIFtgJHt0aGlzLmNhc2NhZGVyQ29tcG9uZW50Lm56VmFsdWVQcm9wZXJ0eX1gXTogY3VycmVudFZhbHVlLFxuICAgICAgICAgICAgICAgIFtgJHt0aGlzLmNhc2NhZGVyQ29tcG9uZW50Lm56TGFiZWxQcm9wZXJ0eX1gXTogY3VycmVudFZhbHVlXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc2V0T3B0aW9uQWN0aXZhdGVkKG9wdGlvbiwgY29sdW1uSW5kZXgsIGZhbHNlLCBmYWxzZSk7XG5cbiAgICAgICAgaWYgKGNvbHVtbkluZGV4IDwgbGFzdENvbHVtbkluZGV4KSB7XG4gICAgICAgICAgaW5pdENvbHVtbldpdGhJbmRleChjb2x1bW5JbmRleCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZHJvcEJlaGluZENvbHVtbnMoY29sdW1uSW5kZXgpO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRPcHRpb25zID0gWy4uLnRoaXMuYWN0aXZhdGVkT3B0aW9uc107XG4gICAgICAgICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgaWYgKHRoaXMuaXNMb2FkZWQoY29sdW1uSW5kZXgpIHx8ICF0aGlzLmNhc2NhZGVyQ29tcG9uZW50Lm56TG9hZERhdGEpIHtcbiAgICAgICAgYWN0aXZhdGVkT3B0aW9uU2V0dGVyKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmFjdGl2YXRlZE9wdGlvbnNbY29sdW1uSW5kZXggLSAxXSB8fCB7fTtcbiAgICAgICAgdGhpcy5sb2FkQ2hpbGRyZW4ob3B0aW9uLCBjb2x1bW5JbmRleCAtIDEsIGFjdGl2YXRlZE9wdGlvblNldHRlcik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuYWN0aXZhdGVkT3B0aW9ucyA9IFtdO1xuICAgIHRoaXMuc2VsZWN0ZWRPcHRpb25zID0gW107XG5cbiAgICBpZiAoZmlyc3QgJiYgdGhpcy5jYXNjYWRlckNvbXBvbmVudC5uekxvYWREYXRhICYmICFoYXNWYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbml0Q29sdW1uV2l0aEluZGV4KDApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kIGNhc2NhZGVyIGNvbXBvbmVudCBzbyB0aGlzIHNlcnZpY2UgY291bGQgdXNlIGlucHV0cy5cbiAgICovXG4gIHdpdGhDb21wb25lbnQoY2FzY2FkZXJDb21wb25lbnQ6IE56Q2FzY2FkZXJDb21wb25lbnRBc1NvdXJjZSk6IHZvaWQge1xuICAgIHRoaXMuY2FzY2FkZXJDb21wb25lbnQgPSBjYXNjYWRlckNvbXBvbmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCBhbGwgb3B0aW9ucy4gUmVidWlsZCBzZWFyY2hpbmcgb3B0aW9ucyBpZiBpbiBzZWFyY2hpbmcgbW9kZS5cbiAgICovXG4gIHdpdGhPcHRpb25zKG9wdGlvbnM6IENhc2NhZGVyT3B0aW9uW10gfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5jb2x1bW5zU25hcHNob3QgPSB0aGlzLmNvbHVtbnMgPSBvcHRpb25zICYmIG9wdGlvbnMubGVuZ3RoID8gW29wdGlvbnNdIDogW107XG5cbiAgICBpZiAodGhpcy5pblNlYXJjaGluZ01vZGUpIHtcbiAgICAgIHRoaXMucHJlcGFyZVNlYXJjaE9wdGlvbnModGhpcy5jYXNjYWRlckNvbXBvbmVudC5pbnB1dFZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29sdW1ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuc3luY09wdGlvbnMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJ5IHRvIHNldCBhIG9wdGlvbiBhcyBhY3RpdmF0ZWQuXG4gICAqIEBwYXJhbSBvcHRpb24gQ2FzY2FkZXIgb3B0aW9uXG4gICAqIEBwYXJhbSBjb2x1bW5JbmRleCBPZiB3aGljaCBjb2x1bW4gdGhpcyBvcHRpb24gaXMgaW5cbiAgICogQHBhcmFtIHNlbGVjdCBTZWxlY3RcbiAgICogQHBhcmFtIGxvYWRpbmdDaGlsZHJlbiBUcnkgdG8gbG9hZCBjaGlsZHJlbiBhc3luY2hyb25vdXNseS5cbiAgICovXG4gIHNldE9wdGlvbkFjdGl2YXRlZChcbiAgICBvcHRpb246IENhc2NhZGVyT3B0aW9uLFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgc2VsZWN0OiBib29sZWFuID0gZmFsc2UsXG4gICAgbG9hZGluZ0NoaWxkcmVuOiBib29sZWFuID0gdHJ1ZVxuICApOiB2b2lkIHtcbiAgICBpZiAob3B0aW9uLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hY3RpdmF0ZWRPcHRpb25zW2NvbHVtbkluZGV4XSA9IG9wdGlvbjtcbiAgICB0aGlzLnRyYWNrQW5jZXN0b3JBY3RpdmF0ZWRPcHRpb25zKGNvbHVtbkluZGV4KTtcbiAgICB0aGlzLmRyb3BCZWhpbmRBY3RpdmF0ZWRPcHRpb25zKGNvbHVtbkluZGV4KTtcblxuICAgIGNvbnN0IGlzUGFyZW50ID0gaXNQYXJlbnRPcHRpb24ob3B0aW9uKTtcblxuICAgIGlmIChpc1BhcmVudCkge1xuICAgICAgLy8gUGFyZW50IG9wdGlvbiB0aGF0IGhhcyBjaGlsZHJlbi5cbiAgICAgIHRoaXMuc2V0Q29sdW1uRGF0YShvcHRpb24uY2hpbGRyZW4hLCBjb2x1bW5JbmRleCArIDEsIG9wdGlvbik7XG4gICAgfSBlbHNlIGlmICghb3B0aW9uLmlzTGVhZiAmJiBsb2FkaW5nQ2hpbGRyZW4pIHtcbiAgICAgIC8vIFBhcmVudCBvcHRpb24gdGhhdCBzaG91bGQgdHJ5IHRvIGxvYWQgY2hpbGRyZW4gYXN5bmNocm9ub3VzbHkuXG4gICAgICB0aGlzLmxvYWRDaGlsZHJlbihvcHRpb24sIGNvbHVtbkluZGV4KTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbi5pc0xlYWYpIHtcbiAgICAgIC8vIExlYWYgb3B0aW9uLlxuICAgICAgdGhpcy5kcm9wQmVoaW5kQ29sdW1ucyhjb2x1bW5JbmRleCk7XG4gICAgfVxuXG4gICAgLy8gQWN0dWFsbHkgcGVyZm9ybSBzZWxlY3Rpb24gdG8gbWFrZSBhbiBvcHRpb25zIG5vdCBvbmx5IGFjdGl2YXRlZCBidXQgYWxzbyBzZWxlY3RlZC5cbiAgICBpZiAoc2VsZWN0KSB7XG4gICAgICB0aGlzLnNldE9wdGlvblNlbGVjdGVkKG9wdGlvbiwgY29sdW1uSW5kZXgpO1xuICAgIH1cblxuICAgIHRoaXMuJHJlZHJhdy5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgc2VhcmNoaW5nIG9wdGlvbiBhcyBhY3RpdmF0ZWQsIGZpbmlzaGluZyB1cCB0aGluZ3MuXG4gICAqIEBwYXJhbSBvcHRpb25cbiAgICovXG4gIHNldFNlYXJjaE9wdGlvblNlbGVjdGVkKG9wdGlvbjogQ2FzY2FkZXJTZWFyY2hPcHRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2YXRlZE9wdGlvbnMgPSBbb3B0aW9uXTtcbiAgICB0aGlzLnNlbGVjdGVkT3B0aW9ucyA9IFsuLi5vcHRpb24ucGF0aF07XG4gICAgdGhpcy5wcmVwYXJlRW1pdFZhbHVlKCk7XG4gICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICB0aGlzLiRvcHRpb25TZWxlY3RlZC5uZXh0KHsgb3B0aW9uLCBpbmRleDogMCB9KTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8gUmVzZXQgZGF0YSBhbmQgdGVsbCBVSSBvbmx5IHRvIHJlbW92ZSBpbnB1dCBhbmQgcmVzZXQgZHJvcGRvd24gd2lkdGggc3R5bGUuXG4gICAgICB0aGlzLiRxdWl0U2VhcmNoaW5nLm5leHQoKTtcbiAgICAgIHRoaXMuJHJlZHJhdy5uZXh0KCk7XG4gICAgICB0aGlzLmluU2VhcmNoaW5nTW9kZSA9IGZhbHNlO1xuICAgICAgdGhpcy5jb2x1bW5zID0gWy4uLnRoaXMuY29sdW1uc1NuYXBzaG90XTtcbiAgICAgIHRoaXMuYWN0aXZhdGVkT3B0aW9ucyA9IFsuLi50aGlzLnNlbGVjdGVkT3B0aW9uc107XG4gICAgfSwgMjAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXIgY2FzY2FkZXIgb3B0aW9ucyB0byByZXNldCBgY29sdW1uc2AuXG4gICAqIEBwYXJhbSBzZWFyY2hWYWx1ZSBUaGUgc3RyaW5nIHVzZXIgd2FudHMgdG8gc2VhcmNoLlxuICAgKi9cbiAgcHJlcGFyZVNlYXJjaE9wdGlvbnMoc2VhcmNoVmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHJlc3VsdHM6IENhc2NhZGVyT3B0aW9uW10gPSBbXTsgLy8gU2VhcmNoIHJlc3VsdHMgb25seSBoYXZlIG9uZSBsYXllci5cbiAgICBjb25zdCBwYXRoOiBDYXNjYWRlck9wdGlvbltdID0gW107XG4gICAgY29uc3QgZGVmYXVsdEZpbHRlcjogTnpDYXNjYWRlckZpbHRlciA9IChpLCBwKSA9PiB7XG4gICAgICByZXR1cm4gcC5zb21lKG8gPT4ge1xuICAgICAgICBjb25zdCBsYWJlbCA9IHRoaXMuZ2V0T3B0aW9uTGFiZWwobyk7XG4gICAgICAgIHJldHVybiAhIWxhYmVsICYmIGxhYmVsLmluZGV4T2YoaSkgIT09IC0xO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICBjb25zdCBzaG93U2VhcmNoID0gdGhpcy5jYXNjYWRlckNvbXBvbmVudC5uelNob3dTZWFyY2g7XG4gICAgY29uc3QgZmlsdGVyID0gaXNTaG93U2VhcmNoT2JqZWN0KHNob3dTZWFyY2gpICYmIHNob3dTZWFyY2guZmlsdGVyID8gc2hvd1NlYXJjaC5maWx0ZXIgOiBkZWZhdWx0RmlsdGVyO1xuICAgIGNvbnN0IHNvcnRlciA9IGlzU2hvd1NlYXJjaE9iamVjdChzaG93U2VhcmNoKSAmJiBzaG93U2VhcmNoLnNvcnRlciA/IHNob3dTZWFyY2guc29ydGVyIDogbnVsbDtcbiAgICBjb25zdCBsb29wQ2hpbGQgPSAobm9kZTogQ2FzY2FkZXJPcHRpb24sIGZvcmNlRGlzYWJsZWQgPSBmYWxzZSkgPT4ge1xuICAgICAgcGF0aC5wdXNoKG5vZGUpO1xuICAgICAgY29uc3QgY1BhdGggPSBBcnJheS5mcm9tKHBhdGgpO1xuICAgICAgaWYgKGZpbHRlcihzZWFyY2hWYWx1ZSwgY1BhdGgpKSB7XG4gICAgICAgIGNvbnN0IGRpc2FibGVkID0gZm9yY2VEaXNhYmxlZCB8fCBub2RlLmRpc2FibGVkO1xuICAgICAgICBjb25zdCBvcHRpb246IENhc2NhZGVyU2VhcmNoT3B0aW9uID0ge1xuICAgICAgICAgIGRpc2FibGVkLFxuICAgICAgICAgIGlzTGVhZjogdHJ1ZSxcbiAgICAgICAgICBwYXRoOiBjUGF0aCxcbiAgICAgICAgICBbdGhpcy5jYXNjYWRlckNvbXBvbmVudC5uekxhYmVsUHJvcGVydHldOiBjUGF0aC5tYXAocCA9PiB0aGlzLmdldE9wdGlvbkxhYmVsKHApKS5qb2luKCcgLyAnKVxuICAgICAgICB9O1xuICAgICAgICByZXN1bHRzLnB1c2gob3B0aW9uKTtcbiAgICAgIH1cbiAgICAgIHBhdGgucG9wKCk7XG4gICAgfTtcbiAgICBjb25zdCBsb29wUGFyZW50ID0gKG5vZGU6IENhc2NhZGVyT3B0aW9uLCBmb3JjZURpc2FibGVkID0gZmFsc2UpID0+IHtcbiAgICAgIGNvbnN0IGRpc2FibGVkID0gZm9yY2VEaXNhYmxlZCB8fCBub2RlLmRpc2FibGVkO1xuICAgICAgcGF0aC5wdXNoKG5vZGUpO1xuICAgICAgbm9kZS5jaGlsZHJlbiEuZm9yRWFjaChzTm9kZSA9PiB7XG4gICAgICAgIGlmICghc05vZGUucGFyZW50KSB7XG4gICAgICAgICAgc05vZGUucGFyZW50ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXNOb2RlLmlzTGVhZikge1xuICAgICAgICAgIGxvb3BQYXJlbnQoc05vZGUsIGRpc2FibGVkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc05vZGUuaXNMZWFmIHx8ICFzTm9kZS5jaGlsZHJlbiB8fCAhc05vZGUuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgICAgbG9vcENoaWxkKHNOb2RlLCBkaXNhYmxlZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcGF0aC5wb3AoKTtcbiAgICB9O1xuXG4gICAgaWYgKCF0aGlzLmNvbHVtbnNTbmFwc2hvdC5sZW5ndGgpIHtcbiAgICAgIHRoaXMuY29sdW1ucyA9IFtbXV07XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jb2x1bW5zU25hcHNob3RbMF0uZm9yRWFjaChvID0+IChpc0NoaWxkT3B0aW9uKG8pID8gbG9vcENoaWxkKG8pIDogbG9vcFBhcmVudChvKSkpO1xuXG4gICAgaWYgKHNvcnRlcikge1xuICAgICAgcmVzdWx0cy5zb3J0KChhLCBiKSA9PiBzb3J0ZXIoYS5wYXRoLCBiLnBhdGgsIHNlYXJjaFZhbHVlKSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb2x1bW5zID0gW3Jlc3VsdHNdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBzZWFyY2hpbmcgbW9kZSBieSBVSS4gSXQgZGVhbHMgd2l0aCB0aGluZ3Mgbm90IGRpcmVjdGx5IHJlbGF0ZWQgdG8gVUkuXG4gICAqIEBwYXJhbSB0b1NlYXJjaGluZyBJZiB0aGlzIGNhc2NhZGVyIGlzIGVudGVyaW5nIHNlYXJjaGluZyBtb2RlXG4gICAqL1xuICB0b2dnbGVTZWFyY2hpbmdNb2RlKHRvU2VhcmNoaW5nOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5pblNlYXJjaGluZ01vZGUgPSB0b1NlYXJjaGluZztcblxuICAgIGlmICh0b1NlYXJjaGluZykge1xuICAgICAgdGhpcy5hY3RpdmF0ZWRPcHRpb25zU25hcHNob3QgPSBbLi4udGhpcy5hY3RpdmF0ZWRPcHRpb25zXTtcbiAgICAgIHRoaXMuYWN0aXZhdGVkT3B0aW9ucyA9IFtdO1xuICAgICAgdGhpcy5zZWxlY3RlZE9wdGlvbnMgPSBbXTtcbiAgICAgIHRoaXMuJHJlZHJhdy5uZXh0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVzZXIgcXVpdCBzZWFyY2hpbmcgbW9kZSB3aXRob3V0IHNlbGVjdGluZyBhbiBvcHRpb24uXG4gICAgICB0aGlzLmFjdGl2YXRlZE9wdGlvbnMgPSBbLi4udGhpcy5hY3RpdmF0ZWRPcHRpb25zU25hcHNob3RdO1xuICAgICAgdGhpcy5zZWxlY3RlZE9wdGlvbnMgPSBbLi4udGhpcy5hY3RpdmF0ZWRPcHRpb25zXTtcbiAgICAgIHRoaXMuY29sdW1ucyA9IFsuLi50aGlzLmNvbHVtbnNTbmFwc2hvdF07XG4gICAgICB0aGlzLnN5bmNPcHRpb25zKCk7XG4gICAgICB0aGlzLiRyZWRyYXcubmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIHNldE9wdGlvblNlbGVjdGVkKG9wdGlvbjogQ2FzY2FkZXJPcHRpb24sIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjaGFuZ2VPbiA9IHRoaXMuY2FzY2FkZXJDb21wb25lbnQubnpDaGFuZ2VPbjtcbiAgICBjb25zdCBzaG91bGRQZXJmb3JtU2VsZWN0aW9uID0gKG86IENhc2NhZGVyT3B0aW9uLCBpOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgICAgIHJldHVybiB0eXBlb2YgY2hhbmdlT24gPT09ICdmdW5jdGlvbicgPyBjaGFuZ2VPbihvLCBpKSA6IGZhbHNlO1xuICAgIH07XG5cbiAgICBpZiAob3B0aW9uLmlzTGVhZiB8fCB0aGlzLmNhc2NhZGVyQ29tcG9uZW50Lm56Q2hhbmdlT25TZWxlY3QgfHwgc2hvdWxkUGVyZm9ybVNlbGVjdGlvbihvcHRpb24sIGluZGV4KSkge1xuICAgICAgdGhpcy5zZWxlY3RlZE9wdGlvbnMgPSBbLi4udGhpcy5hY3RpdmF0ZWRPcHRpb25zXTtcbiAgICAgIHRoaXMucHJlcGFyZUVtaXRWYWx1ZSgpO1xuICAgICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICAgIHRoaXMuJG9wdGlvblNlbGVjdGVkLm5leHQoeyBvcHRpb24sIGluZGV4IH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBzZWxlY3RlZCBvcHRpb25zLlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZXMgPSBbXTtcbiAgICB0aGlzLnNlbGVjdGVkT3B0aW9ucyA9IFtdO1xuICAgIHRoaXMuYWN0aXZhdGVkT3B0aW9ucyA9IFtdO1xuICAgIHRoaXMuZHJvcEJlaGluZENvbHVtbnMoMCk7XG4gICAgdGhpcy5wcmVwYXJlRW1pdFZhbHVlKCk7XG4gICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICB0aGlzLiRvcHRpb25TZWxlY3RlZC5uZXh0KG51bGwpO1xuICB9XG5cbiAgZ2V0T3B0aW9uTGFiZWwobzogQ2FzY2FkZXJPcHRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBvW3RoaXMuY2FzY2FkZXJDb21wb25lbnQubnpMYWJlbFByb3BlcnR5IHx8ICdsYWJlbCddIGFzIHN0cmluZztcbiAgfVxuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgZ2V0T3B0aW9uVmFsdWUobzogQ2FzY2FkZXJPcHRpb24pOiBhbnkge1xuICAgIHJldHVybiBvW3RoaXMuY2FzY2FkZXJDb21wb25lbnQubnpWYWx1ZVByb3BlcnR5IHx8ICd2YWx1ZSddO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyeSB0byBpbnNlcnQgb3B0aW9ucyBpbnRvIGEgY29sdW1uLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIHRvIGluc2VydFxuICAgKiBAcGFyYW0gY29sdW1uSW5kZXggUG9zaXRpb25cbiAgICovXG4gIHByaXZhdGUgc2V0Q29sdW1uRGF0YShvcHRpb25zOiBDYXNjYWRlck9wdGlvbltdLCBjb2x1bW5JbmRleDogbnVtYmVyLCBwYXJlbnQ6IENhc2NhZGVyT3B0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmdPcHRpb25zID0gdGhpcy5jb2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICBpZiAoIWFycmF5c0VxdWFsKGV4aXN0aW5nT3B0aW9ucywgb3B0aW9ucykpIHtcbiAgICAgIG9wdGlvbnMuZm9yRWFjaChvID0+IChvLnBhcmVudCA9IHBhcmVudCkpO1xuICAgICAgdGhpcy5jb2x1bW5zW2NvbHVtbkluZGV4XSA9IG9wdGlvbnM7XG4gICAgICB0aGlzLmRyb3BCZWhpbmRDb2x1bW5zKGNvbHVtbkluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IGFsbCBhbmNlc3RvciBvcHRpb25zIGFzIGFjdGl2YXRlZC5cbiAgICovXG4gIHByaXZhdGUgdHJhY2tBbmNlc3RvckFjdGl2YXRlZE9wdGlvbnMoc3RhcnRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2YXRlZE9wdGlvbnNbaV0pIHtcbiAgICAgICAgdGhpcy5hY3RpdmF0ZWRPcHRpb25zW2ldID0gdGhpcy5hY3RpdmF0ZWRPcHRpb25zW2kgKyAxXS5wYXJlbnQhO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZHJvcEJlaGluZEFjdGl2YXRlZE9wdGlvbnMobGFzdFJlc2VydmVJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmF0ZWRPcHRpb25zID0gdGhpcy5hY3RpdmF0ZWRPcHRpb25zLnNwbGljZSgwLCBsYXN0UmVzZXJ2ZUluZGV4ICsgMSk7XG4gIH1cblxuICBwcml2YXRlIGRyb3BCZWhpbmRDb2x1bW5zKGxhc3RSZXNlcnZlSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChsYXN0UmVzZXJ2ZUluZGV4IDwgdGhpcy5jb2x1bW5zLmxlbmd0aCAtIDEpIHtcbiAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5zbGljZSgwLCBsYXN0UmVzZXJ2ZUluZGV4ICsgMSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgY2hpbGRyZW4gb2YgYW4gb3B0aW9uIGFzeW5jaHJvbm91c2x5LlxuICAgKi9cbiAgbG9hZENoaWxkcmVuKFxuICAgIG9wdGlvbjogQ2FzY2FkZXJPcHRpb24gfCBhbnksIC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBzdWNjZXNzPzogVm9pZEZ1bmN0aW9uLFxuICAgIGZhaWx1cmU/OiBWb2lkRnVuY3Rpb25cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbG9hZEZuID0gdGhpcy5jYXNjYWRlckNvbXBvbmVudC5uekxvYWREYXRhO1xuXG4gICAgaWYgKGxvYWRGbikge1xuICAgICAgLy8gSWYgdGhlcmUgaXNuJ3QgYW55IG9wdGlvbiBpbiBjb2x1bW5zLlxuICAgICAgdGhpcy4kbG9hZGluZy5uZXh0KGNvbHVtbkluZGV4IDwgMCk7XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09PSAnb2JqZWN0Jykge1xuICAgICAgICBvcHRpb24ubG9hZGluZyA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGxvYWRGbihvcHRpb24sIGNvbHVtbkluZGV4KS50aGVuKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgb3B0aW9uLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAob3B0aW9uLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICB0aGlzLnNldENvbHVtbkRhdGEob3B0aW9uLmNoaWxkcmVuLCBjb2x1bW5JbmRleCArIDEsIG9wdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgICBzdWNjZXNzKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuJGxvYWRpbmcubmV4dChmYWxzZSk7XG4gICAgICAgICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIG9wdGlvbi5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgb3B0aW9uLmlzTGVhZiA9IHRydWU7XG4gICAgICAgICAgaWYgKGZhaWx1cmUpIHtcbiAgICAgICAgICAgIGZhaWx1cmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy4kcmVkcmF3Lm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzTG9hZGVkKGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb2x1bW5zW2luZGV4XSAmJiB0aGlzLmNvbHVtbnNbaW5kZXhdLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhIG9wdGlvbiB0aGF0IGhhcyBhIGdpdmVuIHZhbHVlIGluIGEgZ2l2ZW4gY29sdW1uLlxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kT3B0aW9uV2l0aFZhbHVlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgdmFsdWU6IENhc2NhZGVyT3B0aW9uIHwgYW55IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG4gICk6IENhc2NhZGVyT3B0aW9uIHwgbnVsbCB7XG4gICAgY29uc3QgdGFyZ2V0Q29sdW1uID0gdGhpcy5jb2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICBpZiAodGFyZ2V0Q29sdW1uKSB7XG4gICAgICBjb25zdCB2ID0gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyA/IHRoaXMuZ2V0T3B0aW9uVmFsdWUodmFsdWUpIDogdmFsdWU7XG4gICAgICByZXR1cm4gdGFyZ2V0Q29sdW1uLmZpbmQobyA9PiB2ID09PSB0aGlzLmdldE9wdGlvblZhbHVlKG8pKSE7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlRW1pdFZhbHVlKCk6IHZvaWQge1xuICAgIHRoaXMudmFsdWVzID0gdGhpcy5zZWxlY3RlZE9wdGlvbnMubWFwKG8gPT4gdGhpcy5nZXRPcHRpb25WYWx1ZShvKSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBCQUNLU1BBQ0UsIERPV05fQVJST1csIEVOVEVSLCBFU0NBUEUsIExFRlRfQVJST1csIFJJR0hUX0FSUk9XLCBVUF9BUlJPVyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9rZXljb2Rlcyc7XG5pbXBvcnQgeyBDZGtDb25uZWN0ZWRPdmVybGF5LCBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UsIENvbm5lY3Rpb25Qb3NpdGlvblBhaXIgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge1xuICBmb3J3YXJkUmVmLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0LFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDaGlsZHJlbixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIHNsaWRlTW90aW9uLFxuICB0b0FycmF5LFxuICBERUZBVUxUX0RST1BET1dOX1BPU0lUSU9OUyxcbiAgSW5wdXRCb29sZWFuLFxuICBOZ0NsYXNzVHlwZSxcbiAgTnpOb0FuaW1hdGlvbkRpcmVjdGl2ZVxufSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUnO1xuXG5pbXBvcnQge1xuICBDYXNjYWRlck9wdGlvbixcbiAgQ2FzY2FkZXJTZWFyY2hPcHRpb24sXG4gIE56Q2FzY2FkZXJDb21wb25lbnRBc1NvdXJjZSxcbiAgTnpDYXNjYWRlckV4cGFuZFRyaWdnZXIsXG4gIE56Q2FzY2FkZXJTaXplLFxuICBOekNhc2NhZGVyVHJpZ2dlclR5cGUsXG4gIE56U2hvd1NlYXJjaE9wdGlvbnNcbn0gZnJvbSAnLi9uei1jYXNjYWRlci1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBOekNhc2NhZGVyT3B0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9uei1jYXNjYWRlci1saS5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpDYXNjYWRlclNlcnZpY2UgfSBmcm9tICcuL256LWNhc2NhZGVyLnNlcnZpY2UnO1xuXG5jb25zdCBkZWZhdWx0RGlzcGxheVJlbmRlciA9IChsYWJlbHM6IHN0cmluZ1tdKSA9PiBsYWJlbHMuam9pbignIC8gJyk7XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1jYXNjYWRlcixbbnotY2FzY2FkZXJdJyxcbiAgZXhwb3J0QXM6ICduekNhc2NhZGVyJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHRlbXBsYXRlVXJsOiAnLi9uei1jYXNjYWRlci5jb21wb25lbnQuaHRtbCcsXG4gIGFuaW1hdGlvbnM6IFtzbGlkZU1vdGlvbl0sXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTnpDYXNjYWRlckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH0sXG4gICAgTnpDYXNjYWRlclNlcnZpY2VcbiAgXSxcbiAgaG9zdDoge1xuICAgICdbYXR0ci50YWJJbmRleF0nOiAnXCIwXCInLFxuICAgICdbY2xhc3MuYW50LWNhc2NhZGVyLWxnXSc6ICduelNpemUgPT09IFwibGFyZ2VcIicsXG4gICAgJ1tjbGFzcy5hbnQtY2FzY2FkZXItc21dJzogJ256U2l6ZSA9PT0gXCJzbWFsbFwiJyxcbiAgICAnW2NsYXNzLmFudC1jYXNjYWRlci1waWNrZXItZGlzYWJsZWRdJzogJ256RGlzYWJsZWQnLFxuICAgICdbY2xhc3MuYW50LWNhc2NhZGVyLXBpY2tlci1vcGVuXSc6ICdtZW51VmlzaWJsZScsXG4gICAgJ1tjbGFzcy5hbnQtY2FzY2FkZXItcGlja2VyLXdpdGgtdmFsdWVdJzogJyEhaW5wdXRWYWx1ZScsXG4gICAgJ1tjbGFzcy5hbnQtY2FzY2FkZXItZm9jdXNlZF0nOiAnaXNGb2N1c2VkJ1xuICB9LFxuICBzdHlsZXM6IFtcbiAgICBgXG4gICAgICAuYW50LWNhc2NhZGVyLW1lbnVzIHtcbiAgICAgICAgbWFyZ2luLXRvcDogNHB4O1xuICAgICAgICBtYXJnaW4tYm90dG9tOiA0cHg7XG4gICAgICAgIHRvcDogMTAwJTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgIH1cbiAgICBgXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTnpDYXNjYWRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE56Q2FzY2FkZXJDb21wb25lbnRBc1NvdXJjZSwgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQFZpZXdDaGlsZCgnaW5wdXQnKSBpbnB1dDogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnbWVudScpIG1lbnU6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoQ2RrQ29ubmVjdGVkT3ZlcmxheSkgb3ZlcmxheTogQ2RrQ29ubmVjdGVkT3ZlcmxheTtcbiAgQFZpZXdDaGlsZHJlbihOekNhc2NhZGVyT3B0aW9uQ29tcG9uZW50KSBjYXNjYWRlckl0ZW1zOiBRdWVyeUxpc3Q8TnpDYXNjYWRlck9wdGlvbkNvbXBvbmVudD47XG5cbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56U2hvd0lucHV0ID0gdHJ1ZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56U2hvd0Fycm93ID0gdHJ1ZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56QWxsb3dDbGVhciA9IHRydWU7XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekF1dG9Gb2N1cyA9IGZhbHNlO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpDaGFuZ2VPblNlbGVjdCA9IGZhbHNlO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpEaXNhYmxlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBuekNvbHVtbkNsYXNzTmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSBuekV4cGFuZFRyaWdnZXI6IE56Q2FzY2FkZXJFeHBhbmRUcmlnZ2VyID0gJ2NsaWNrJztcbiAgQElucHV0KCkgbnpWYWx1ZVByb3BlcnR5ID0gJ3ZhbHVlJztcbiAgQElucHV0KCkgbnpMYWJlbFJlbmRlcjogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIG56TGFiZWxQcm9wZXJ0eSA9ICdsYWJlbCc7XG4gIEBJbnB1dCgpIG56Tm90Rm91bmRDb250ZW50OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx2b2lkPjtcbiAgQElucHV0KCkgbnpTaXplOiBOekNhc2NhZGVyU2l6ZSA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgbnpTaG93U2VhcmNoOiBib29sZWFuIHwgTnpTaG93U2VhcmNoT3B0aW9ucztcbiAgQElucHV0KCkgbnpQbGFjZUhvbGRlciA9ICdQbGVhc2Ugc2VsZWN0JzsgLy8gVE9ETzogaTE4bj9cbiAgQElucHV0KCkgbnpNZW51Q2xhc3NOYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIG56TWVudVN0eWxlOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuICBASW5wdXQoKSBuek1vdXNlRW50ZXJEZWxheTogbnVtYmVyID0gMTUwOyAvLyBtc1xuICBASW5wdXQoKSBuek1vdXNlTGVhdmVEZWxheTogbnVtYmVyID0gMTUwOyAvLyBtc1xuICBASW5wdXQoKSBuelRyaWdnZXJBY3Rpb246IE56Q2FzY2FkZXJUcmlnZ2VyVHlwZSB8IE56Q2FzY2FkZXJUcmlnZ2VyVHlwZVtdID0gWydjbGljayddIGFzIE56Q2FzY2FkZXJUcmlnZ2VyVHlwZVtdO1xuICBASW5wdXQoKSBuekNoYW5nZU9uOiAob3B0aW9uOiBDYXNjYWRlck9wdGlvbiwgbGV2ZWw6IG51bWJlcikgPT4gYm9vbGVhbjtcbiAgQElucHV0KCkgbnpMb2FkRGF0YTogKG5vZGU6IENhc2NhZGVyT3B0aW9uLCBpbmRleD86IG51bWJlcikgPT4gUHJvbWlzZUxpa2U8YW55PjsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1hbnlcblxuICBASW5wdXQoKVxuICBnZXQgbnpPcHRpb25zKCk6IENhc2NhZGVyT3B0aW9uW10gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jYXNjYWRlclNlcnZpY2UubnpPcHRpb25zO1xuICB9XG5cbiAgc2V0IG56T3B0aW9ucyhvcHRpb25zOiBDYXNjYWRlck9wdGlvbltdIHwgbnVsbCkge1xuICAgIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLndpdGhPcHRpb25zKG9wdGlvbnMpO1xuICB9XG5cbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56U2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxDYXNjYWRlck9wdGlvbltdPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPHsgb3B0aW9uOiBDYXNjYWRlck9wdGlvbjsgaW5kZXg6IG51bWJlciB9IHwgbnVsbD4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56Q2xlYXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuelZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7IC8vIE5vdCBleHBvc2VkLCBvbmx5IGZvciB0ZXN0XG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTsgLy8gTm90IGV4cG9zZWQsIG9ubHkgZm9yIHRlc3RcblxuICBlbDogSFRNTEVsZW1lbnQ7XG4gIGRyb3BEb3duUG9zaXRpb24gPSAnYm90dG9tJztcbiAgbWVudVZpc2libGUgPSBmYWxzZTtcbiAgaXNMb2FkaW5nID0gZmFsc2U7XG4gIGxhYmVsUmVuZGVyVGV4dDogc3RyaW5nO1xuICBsYWJlbFJlbmRlckNvbnRleHQgPSB7fTtcbiAgb25DaGFuZ2UgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIG9uVG91Y2hlZCA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbiAgcG9zaXRpb25zOiBDb25uZWN0aW9uUG9zaXRpb25QYWlyW10gPSBbLi4uREVGQVVMVF9EUk9QRE9XTl9QT1NJVElPTlNdO1xuICBkcm9wZG93bldpZHRoU3R5bGU6IHN0cmluZztcbiAgaXNGb2N1c2VkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSAkZGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgaW5wdXRTdHJpbmcgPSAnJztcbiAgcHJpdmF0ZSBpc09wZW5pbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBkZWxheU1lbnVUaW1lcjogbnVtYmVyIHwgbnVsbDtcbiAgcHJpdmF0ZSBkZWxheVNlbGVjdFRpbWVyOiBudW1iZXIgfCBudWxsO1xuXG4gIGdldCBpblNlYXJjaGluZ01vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLmluU2VhcmNoaW5nTW9kZTtcbiAgfVxuXG4gIHNldCBpbnB1dFZhbHVlKGlucHV0VmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuaW5wdXRTdHJpbmcgPSBpbnB1dFZhbHVlO1xuICAgIHRoaXMudG9nZ2xlU2VhcmNoaW5nTW9kZSghIWlucHV0VmFsdWUpO1xuICB9XG5cbiAgZ2V0IGlucHV0VmFsdWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pbnB1dFN0cmluZztcbiAgfVxuXG4gIGdldCBtZW51Q2xzKCk6IE5nQ2xhc3NUeXBlIHtcbiAgICByZXR1cm4geyBbYCR7dGhpcy5uek1lbnVDbGFzc05hbWV9YF06ICEhdGhpcy5uek1lbnVDbGFzc05hbWUgfTtcbiAgfVxuXG4gIGdldCBtZW51Q29sdW1uQ2xzKCk6IE5nQ2xhc3NUeXBlIHtcbiAgICByZXR1cm4geyBbYCR7dGhpcy5uekNvbHVtbkNsYXNzTmFtZX1gXTogISF0aGlzLm56Q29sdW1uQ2xhc3NOYW1lIH07XG4gIH1cblxuICBwcml2YXRlIGdldCBoYXNJbnB1dCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmlucHV0VmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGdldCBoYXNWYWx1ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jYXNjYWRlclNlcnZpY2UudmFsdWVzICYmIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnZhbHVlcy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IHNob3dQbGFjZWhvbGRlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLmhhc0lucHV0IHx8IHRoaXMuaGFzVmFsdWUpO1xuICB9XG5cbiAgZ2V0IGNsZWFySWNvblZpc2libGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubnpBbGxvd0NsZWFyICYmICF0aGlzLm56RGlzYWJsZWQgJiYgKHRoaXMuaGFzVmFsdWUgfHwgdGhpcy5oYXNJbnB1dCk7XG4gIH1cblxuICBnZXQgaXNMYWJlbFJlbmRlclRlbXBsYXRlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMubnpMYWJlbFJlbmRlcjtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBjYXNjYWRlclNlcnZpY2U6IE56Q2FzY2FkZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEhvc3QoKSBAT3B0aW9uYWwoKSBwdWJsaWMgbm9BbmltYXRpb24/OiBOek5vQW5pbWF0aW9uRGlyZWN0aXZlXG4gICkge1xuICAgIHRoaXMuZWwgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5jYXNjYWRlclNlcnZpY2Uud2l0aENvbXBvbmVudCh0aGlzKTtcbiAgICByZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdhbnQtY2FzY2FkZXInKTtcbiAgICByZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdhbnQtY2FzY2FkZXItcGlja2VyJyk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCBzcnYgPSB0aGlzLmNhc2NhZGVyU2VydmljZTtcblxuICAgIHNydi4kcmVkcmF3LnBpcGUodGFrZVVudGlsKHRoaXMuJGRlc3Ryb3kpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgLy8gVGhlc2Ugb3BlcmF0aW9ucyB3b3VsZCBub3QgbXV0YXRlIGRhdGEuXG4gICAgICB0aGlzLmNoZWNrQ2hpbGRyZW4oKTtcbiAgICAgIHRoaXMuYnVpbGREaXNwbGF5TGFiZWwoKTtcbiAgICAgIHRoaXMucmVwb3NpdGlvbigpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG5cbiAgICBzcnYuJGxvYWRpbmcucGlwZSh0YWtlVW50aWwodGhpcy4kZGVzdHJveSkpLnN1YnNjcmliZShsb2FkaW5nID0+IHtcbiAgICAgIHRoaXMuaXNMb2FkaW5nID0gbG9hZGluZztcbiAgICB9KTtcblxuICAgIHNydi4kb3B0aW9uU2VsZWN0ZWQucGlwZSh0YWtlVW50aWwodGhpcy4kZGVzdHJveSkpLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgIGlmICghZGF0YSkge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKFtdKTtcbiAgICAgICAgdGhpcy5uelNlbGVjdC5lbWl0KG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgeyBvcHRpb24sIGluZGV4IH0gPSBkYXRhO1xuICAgICAgICBjb25zdCBzaG91bGRDbG9zZSA9IG9wdGlvbi5pc0xlYWY7XG4gICAgICAgIGlmIChzaG91bGRDbG9zZSkge1xuICAgICAgICAgIHRoaXMuZGVsYXlTZXRNZW51VmlzaWJsZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLmNhc2NhZGVyU2VydmljZS52YWx1ZXMpO1xuICAgICAgICB0aGlzLm56U2VsZWN0aW9uQ2hhbmdlLmVtaXQodGhpcy5jYXNjYWRlclNlcnZpY2Uuc2VsZWN0ZWRPcHRpb25zKTtcbiAgICAgICAgdGhpcy5uelNlbGVjdC5lbWl0KHsgb3B0aW9uLCBpbmRleCB9KTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBzcnYuJHF1aXRTZWFyY2hpbmcucGlwZSh0YWtlVW50aWwodGhpcy4kZGVzdHJveSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmlucHV0U3RyaW5nID0gJyc7XG4gICAgICB0aGlzLmRyb3Bkb3duV2lkdGhTdHlsZSA9ICcnO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy4kZGVzdHJveS5uZXh0KCk7XG4gICAgdGhpcy4kZGVzdHJveS5jb21wbGV0ZSgpO1xuICAgIHRoaXMuY2xlYXJEZWxheU1lbnVUaW1lcigpO1xuICAgIHRoaXMuY2xlYXJEZWxheVNlbGVjdFRpbWVyKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnZhbHVlcyA9IHRvQXJyYXkodmFsdWUpO1xuICAgIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnN5bmNPcHRpb25zKHRydWUpO1xuICB9XG5cbiAgZGVsYXlTZXRNZW51VmlzaWJsZSh2aXNpYmxlOiBib29sZWFuLCBkZWxheTogbnVtYmVyID0gMTAwLCBzZXRPcGVuaW5nOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyRGVsYXlNZW51VGltZXIoKTtcbiAgICBpZiAoZGVsYXkpIHtcbiAgICAgIGlmICh2aXNpYmxlICYmIHNldE9wZW5pbmcpIHtcbiAgICAgICAgdGhpcy5pc09wZW5pbmcgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWxheU1lbnVUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNldE1lbnVWaXNpYmxlKHZpc2libGUpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuY2xlYXJEZWxheU1lbnVUaW1lcigpO1xuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc09wZW5pbmcgPSBmYWxzZTtcbiAgICAgICAgICB9LCAxMDApO1xuICAgICAgICB9XG4gICAgICB9LCBkZWxheSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0TWVudVZpc2libGUodmlzaWJsZSk7XG4gICAgfVxuICB9XG5cbiAgc2V0TWVudVZpc2libGUodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLm56RGlzYWJsZWQgfHwgdGhpcy5tZW51VmlzaWJsZSA9PT0gdmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmlzaWJsZSkge1xuICAgICAgdGhpcy5jYXNjYWRlclNlcnZpY2Uuc3luY09wdGlvbnMoKTtcbiAgICB9XG5cbiAgICB0aGlzLm1lbnVWaXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLm56VmlzaWJsZUNoYW5nZS5lbWl0KHZpc2libGUpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJEZWxheU1lbnVUaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kZWxheU1lbnVUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZGVsYXlNZW51VGltZXIpO1xuICAgICAgdGhpcy5kZWxheU1lbnVUaW1lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgY2xlYXJTZWxlY3Rpb24oZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIHRoaXMubGFiZWxSZW5kZXJUZXh0ID0gJyc7XG4gICAgdGhpcy5sYWJlbFJlbmRlckNvbnRleHQgPSB7fTtcbiAgICB0aGlzLmlucHV0VmFsdWUgPSAnJztcbiAgICB0aGlzLnNldE1lbnVWaXNpYmxlKGZhbHNlKTtcbiAgICB0aGlzLmNhc2NhZGVyU2VydmljZS5jbGVhcigpO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBnZXRTdWJtaXRWYWx1ZSgpOiBhbnlbXSB7XG4gICAgcmV0dXJuIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnNlbGVjdGVkT3B0aW9ucy5tYXAobyA9PiB0aGlzLmNhc2NhZGVyU2VydmljZS5nZXRPcHRpb25WYWx1ZShvKSk7XG4gIH1cblxuICBmb2N1cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNGb2N1c2VkKSB7XG4gICAgICAodGhpcy5pbnB1dCA/IHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudCA6IHRoaXMuZWwpLmZvY3VzKCk7XG4gICAgICB0aGlzLmlzRm9jdXNlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgYmx1cigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0ZvY3VzZWQpIHtcbiAgICAgICh0aGlzLmlucHV0ID8gdGhpcy5pbnB1dC5uYXRpdmVFbGVtZW50IDogdGhpcy5lbCkuYmx1cigpO1xuICAgICAgdGhpcy5pc0ZvY3VzZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVJbnB1dEJsdXIoKTogdm9pZCB7XG4gICAgdGhpcy5tZW51VmlzaWJsZSA/IHRoaXMuZm9jdXMoKSA6IHRoaXMuYmx1cigpO1xuICB9XG5cbiAgaGFuZGxlSW5wdXRGb2N1cygpOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcbiAgb25LZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XG5cbiAgICBpZiAoXG4gICAgICBrZXlDb2RlICE9PSBET1dOX0FSUk9XICYmXG4gICAgICBrZXlDb2RlICE9PSBVUF9BUlJPVyAmJlxuICAgICAga2V5Q29kZSAhPT0gTEVGVF9BUlJPVyAmJlxuICAgICAga2V5Q29kZSAhPT0gUklHSFRfQVJST1cgJiZcbiAgICAgIGtleUNvZGUgIT09IEVOVEVSICYmXG4gICAgICBrZXlDb2RlICE9PSBCQUNLU1BBQ0UgJiZcbiAgICAgIGtleUNvZGUgIT09IEVTQ0FQRVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFByZXNzIGFueSBrZXlzIGFib3ZlIHRvIHJlb3BlbiBtZW51LlxuICAgIGlmICghdGhpcy5tZW51VmlzaWJsZSAmJiBrZXlDb2RlICE9PSBCQUNLU1BBQ0UgJiYga2V5Q29kZSAhPT0gRVNDQVBFKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRNZW51VmlzaWJsZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHRoZXNlIGtleXMgd29yayBhcyBkZWZhdWx0IGluIHNlYXJjaGluZyBtb2RlLlxuICAgIGlmICh0aGlzLmluU2VhcmNoaW5nTW9kZSAmJiAoa2V5Q29kZSA9PT0gQkFDS1NQQUNFIHx8IGtleUNvZGUgPT09IExFRlRfQVJST1cgfHwga2V5Q29kZSA9PT0gUklHSFRfQVJST1cpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSW50ZXJhY3Qgd2l0aCB0aGUgY29tcG9uZW50LlxuICAgIGlmICh0aGlzLm1lbnVWaXNpYmxlKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGtleUNvZGUgPT09IERPV05fQVJST1cpIHtcbiAgICAgICAgdGhpcy5tb3ZlVXBPckRvd24oZmFsc2UpO1xuICAgICAgfSBlbHNlIGlmIChrZXlDb2RlID09PSBVUF9BUlJPVykge1xuICAgICAgICB0aGlzLm1vdmVVcE9yRG93bih0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAoa2V5Q29kZSA9PT0gTEVGVF9BUlJPVykge1xuICAgICAgICB0aGlzLm1vdmVMZWZ0KCk7XG4gICAgICB9IGVsc2UgaWYgKGtleUNvZGUgPT09IFJJR0hUX0FSUk9XKSB7XG4gICAgICAgIHRoaXMubW92ZVJpZ2h0KCk7XG4gICAgICB9IGVsc2UgaWYgKGtleUNvZGUgPT09IEVOVEVSKSB7XG4gICAgICAgIHRoaXMub25FbnRlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJylcbiAgb25UcmlnZ2VyQ2xpY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpEaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5uelNob3dTZWFyY2gpIHtcbiAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNBY3Rpb25UcmlnZ2VyKCdjbGljaycpKSB7XG4gICAgICB0aGlzLmRlbGF5U2V0TWVudVZpc2libGUoIXRoaXMubWVudVZpc2libGUsIDEwMCk7XG4gICAgfVxuICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcbiAgb25UcmlnZ2VyTW91c2VFbnRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uekRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmlzQWN0aW9uVHJpZ2dlcignaG92ZXInKSkge1xuICAgICAgdGhpcy5kZWxheVNldE1lbnVWaXNpYmxlKHRydWUsIHRoaXMubnpNb3VzZUVudGVyRGVsYXksIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBbJyRldmVudCddKVxuICBvblRyaWdnZXJNb3VzZUxlYXZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpEaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMubWVudVZpc2libGUgfHwgdGhpcy5pc09wZW5pbmcpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmlzQWN0aW9uVHJpZ2dlcignaG92ZXInKSkge1xuICAgICAgY29uc3QgbW91c2VUYXJnZXQgPSBldmVudC5yZWxhdGVkVGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgY29uc3QgaG9zdEVsID0gdGhpcy5lbDtcbiAgICAgIGNvbnN0IG1lbnVFbCA9IHRoaXMubWVudSAmJiAodGhpcy5tZW51Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpO1xuICAgICAgaWYgKGhvc3RFbC5jb250YWlucyhtb3VzZVRhcmdldCkgfHwgKG1lbnVFbCAmJiBtZW51RWwuY29udGFpbnMobW91c2VUYXJnZXQpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmRlbGF5U2V0TWVudVZpc2libGUoZmFsc2UsIHRoaXMubnpNb3VzZUxlYXZlRGVsYXkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNBY3Rpb25UcmlnZ2VyKGFjdGlvbjogJ2NsaWNrJyB8ICdob3ZlcicpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMubnpUcmlnZ2VyQWN0aW9uID09PSAnc3RyaW5nJ1xuICAgICAgPyB0aGlzLm56VHJpZ2dlckFjdGlvbiA9PT0gYWN0aW9uXG4gICAgICA6IHRoaXMubnpUcmlnZ2VyQWN0aW9uLmluZGV4T2YoYWN0aW9uKSAhPT0gLTE7XG4gIH1cblxuICBvbk9wdGlvbkNsaWNrKG9wdGlvbjogQ2FzY2FkZXJPcHRpb24sIGNvbHVtbkluZGV4OiBudW1iZXIsIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbiAmJiBvcHRpb24uZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbC5mb2N1cygpO1xuICAgIHRoaXMuaW5TZWFyY2hpbmdNb2RlXG4gICAgICA/IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnNldFNlYXJjaE9wdGlvblNlbGVjdGVkKG9wdGlvbiBhcyBDYXNjYWRlclNlYXJjaE9wdGlvbilcbiAgICAgIDogdGhpcy5jYXNjYWRlclNlcnZpY2Uuc2V0T3B0aW9uQWN0aXZhdGVkKG9wdGlvbiwgY29sdW1uSW5kZXgsIHRydWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkVudGVyKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbkluZGV4ID0gTWF0aC5tYXgodGhpcy5jYXNjYWRlclNlcnZpY2UuYWN0aXZhdGVkT3B0aW9ucy5sZW5ndGggLSAxLCAwKTtcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLmNhc2NhZGVyU2VydmljZS5hY3RpdmF0ZWRPcHRpb25zW2NvbHVtbkluZGV4XTtcbiAgICBpZiAob3B0aW9uICYmICFvcHRpb24uZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuaW5TZWFyY2hpbmdNb2RlXG4gICAgICAgID8gdGhpcy5jYXNjYWRlclNlcnZpY2Uuc2V0U2VhcmNoT3B0aW9uU2VsZWN0ZWQob3B0aW9uIGFzIENhc2NhZGVyU2VhcmNoT3B0aW9uKVxuICAgICAgICA6IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnNldE9wdGlvbkFjdGl2YXRlZChvcHRpb24sIGNvbHVtbkluZGV4LCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vdmVVcE9yRG93bihpc1VwOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uSW5kZXggPSBNYXRoLm1heCh0aGlzLmNhc2NhZGVyU2VydmljZS5hY3RpdmF0ZWRPcHRpb25zLmxlbmd0aCAtIDEsIDApO1xuICAgIGNvbnN0IGFjdGl2ZU9wdGlvbiA9IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLmFjdGl2YXRlZE9wdGlvbnNbY29sdW1uSW5kZXhdO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmNhc2NhZGVyU2VydmljZS5jb2x1bW5zW2NvbHVtbkluZGV4XSB8fCBbXTtcbiAgICBjb25zdCBsZW5ndGggPSBvcHRpb25zLmxlbmd0aDtcbiAgICBsZXQgbmV4dEluZGV4ID0gLTE7XG4gICAgaWYgKCFhY3RpdmVPcHRpb24pIHtcbiAgICAgIC8vIE5vdCBzZWxlY3RlZCBvcHRpb25zIGluIHRoaXMgY29sdW1uXG4gICAgICBuZXh0SW5kZXggPSBpc1VwID8gbGVuZ3RoIDogLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5leHRJbmRleCA9IG9wdGlvbnMuaW5kZXhPZihhY3RpdmVPcHRpb24pO1xuICAgIH1cblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBuZXh0SW5kZXggPSBpc1VwID8gbmV4dEluZGV4IC0gMSA6IG5leHRJbmRleCArIDE7XG4gICAgICBpZiAobmV4dEluZGV4IDwgMCB8fCBuZXh0SW5kZXggPj0gbGVuZ3RoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29uc3QgbmV4dE9wdGlvbiA9IG9wdGlvbnNbbmV4dEluZGV4XTtcbiAgICAgIGlmICghbmV4dE9wdGlvbiB8fCBuZXh0T3B0aW9uLmRpc2FibGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5jYXNjYWRlclNlcnZpY2Uuc2V0T3B0aW9uQWN0aXZhdGVkKG5leHRPcHRpb24sIGNvbHVtbkluZGV4KTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW92ZUxlZnQoKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLmFjdGl2YXRlZE9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICBvcHRpb25zLnBvcCgpOyAvLyBSZW1vdmUgdGhlIGxhc3Qgb25lXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlUmlnaHQoKTogdm9pZCB7XG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy5jYXNjYWRlclNlcnZpY2UuYWN0aXZhdGVkT3B0aW9ucy5sZW5ndGg7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLmNvbHVtbnNbbGVuZ3RoXTtcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV4dE9wdCA9IG9wdGlvbnMuZmluZChvID0+ICFvLmRpc2FibGVkKTtcbiAgICAgIGlmIChuZXh0T3B0KSB7XG4gICAgICAgIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnNldE9wdGlvbkFjdGl2YXRlZChuZXh0T3B0LCBsZW5ndGgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uT3B0aW9uTW91c2VFbnRlcihvcHRpb246IENhc2NhZGVyT3B0aW9uLCBjb2x1bW5JbmRleDogbnVtYmVyLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmICh0aGlzLm56RXhwYW5kVHJpZ2dlciA9PT0gJ2hvdmVyJyAmJiAhb3B0aW9uLmlzTGVhZikge1xuICAgICAgdGhpcy5kZWxheVNlbGVjdE9wdGlvbihvcHRpb24sIGNvbHVtbkluZGV4LCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBvbk9wdGlvbk1vdXNlTGVhdmUob3B0aW9uOiBDYXNjYWRlck9wdGlvbiwgY29sdW1uSW5kZXg6IG51bWJlciwgZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAodGhpcy5uekV4cGFuZFRyaWdnZXIgPT09ICdob3ZlcicgJiYgIW9wdGlvbi5pc0xlYWYpIHtcbiAgICAgIHRoaXMuZGVsYXlTZWxlY3RPcHRpb24ob3B0aW9uLCBjb2x1bW5JbmRleCwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJEZWxheVNlbGVjdFRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRlbGF5U2VsZWN0VGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRlbGF5U2VsZWN0VGltZXIpO1xuICAgICAgdGhpcy5kZWxheVNlbGVjdFRpbWVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlbGF5U2VsZWN0T3B0aW9uKG9wdGlvbjogQ2FzY2FkZXJPcHRpb24sIGluZGV4OiBudW1iZXIsIGRvU2VsZWN0OiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhckRlbGF5U2VsZWN0VGltZXIoKTtcbiAgICBpZiAoZG9TZWxlY3QpIHtcbiAgICAgIHRoaXMuZGVsYXlTZWxlY3RUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmNhc2NhZGVyU2VydmljZS5zZXRPcHRpb25BY3RpdmF0ZWQob3B0aW9uLCBpbmRleCk7XG4gICAgICAgIHRoaXMuZGVsYXlTZWxlY3RUaW1lciA9IG51bGw7XG4gICAgICB9LCAxNTApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdG9nZ2xlU2VhcmNoaW5nTW9kZSh0b1NlYXJjaGluZzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmluU2VhcmNoaW5nTW9kZSAhPT0gdG9TZWFyY2hpbmcpIHtcbiAgICAgIHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnRvZ2dsZVNlYXJjaGluZ01vZGUodG9TZWFyY2hpbmcpO1xuICAgICAgdGhpcy5kcm9wZG93bldpZHRoU3R5bGUgPSB0b1NlYXJjaGluZyA/IGAke3RoaXMuaW5wdXQubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aH1weGAgOiAnJztcbiAgICB9XG4gICAgaWYgKHRoaXMuaW5TZWFyY2hpbmdNb2RlKSB7XG4gICAgICB0aGlzLmNhc2NhZGVyU2VydmljZS5wcmVwYXJlU2VhcmNoT3B0aW9ucyh0aGlzLmlucHV0VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGlzT3B0aW9uQWN0aXZhdGVkKG9wdGlvbjogQ2FzY2FkZXJPcHRpb24sIGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBhY3RpdmVPcHQgPSB0aGlzLmNhc2NhZGVyU2VydmljZS5hY3RpdmF0ZWRPcHRpb25zW2luZGV4XTtcbiAgICByZXR1cm4gYWN0aXZlT3B0ID09PSBvcHRpb247XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoaXNEaXNhYmxlZCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnUoKTtcbiAgICB9XG4gICAgdGhpcy5uekRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIGNsb3NlTWVudSgpOiB2b2lkIHtcbiAgICB0aGlzLmJsdXIoKTtcbiAgICB0aGlzLmNsZWFyRGVsYXlNZW51VGltZXIoKTtcbiAgICB0aGlzLnNldE1lbnVWaXNpYmxlKGZhbHNlKTtcbiAgfVxuXG4gIG9uUG9zaXRpb25DaGFuZ2UocG9zaXRpb246IENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSk6IHZvaWQge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gcG9zaXRpb24uY29ubmVjdGlvblBhaXIub3JpZ2luWSA9PT0gJ2JvdHRvbScgPyAnYm90dG9tJyA6ICd0b3AnO1xuICAgIGlmICh0aGlzLmRyb3BEb3duUG9zaXRpb24gIT09IG5ld1ZhbHVlKSB7XG4gICAgICB0aGlzLmRyb3BEb3duUG9zaXRpb24gPSBuZXdWYWx1ZTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVwb3NpdGlvbiB0aGUgY2FzY2FkZXIgcGFuZWwuIFdoZW4gYSBtZW51IG9wZW5zLCB0aGUgY2FzY2FkZXIgZXhwYW5kc1xuICAgKiBhbmQgbWF5IGV4Y2VlZCB0aGUgYm91bmRhcnkgb2YgYnJvd3NlcidzIHdpbmRvdy5cbiAgICovXG4gIHByaXZhdGUgcmVwb3NpdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vdmVybGF5ICYmIHRoaXMub3ZlcmxheS5vdmVybGF5UmVmICYmIHRoaXMubWVudVZpc2libGUpIHtcbiAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLm92ZXJsYXkub3ZlcmxheVJlZi51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBjYXNjYWRlciBvcHRpb25zIGlzIGNoYW5nZWQsIGEgY2hpbGQgbmVlZHMgdG8ga25vdyB0aGF0IGl0IHNob3VsZCByZS1yZW5kZXIuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrQ2hpbGRyZW4oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FzY2FkZXJJdGVtcykge1xuICAgICAgdGhpcy5jYXNjYWRlckl0ZW1zLmZvckVhY2goaXRlbSA9PiBpdGVtLm1hcmtGb3JDaGVjaygpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRGlzcGxheUxhYmVsKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkT3B0aW9ucyA9IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLnNlbGVjdGVkT3B0aW9ucztcbiAgICBjb25zdCBsYWJlbHM6IHN0cmluZ1tdID0gc2VsZWN0ZWRPcHRpb25zLm1hcChvID0+IHRoaXMuY2FzY2FkZXJTZXJ2aWNlLmdldE9wdGlvbkxhYmVsKG8pKTtcblxuICAgIGlmICh0aGlzLmlzTGFiZWxSZW5kZXJUZW1wbGF0ZSkge1xuICAgICAgdGhpcy5sYWJlbFJlbmRlckNvbnRleHQgPSB7IGxhYmVscywgc2VsZWN0ZWRPcHRpb25zIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGFiZWxSZW5kZXJUZXh0ID0gZGVmYXVsdERpc3BsYXlSZW5kZXIuY2FsbCh0aGlzLCBsYWJlbHMsIHNlbGVjdGVkT3B0aW9ucyk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgT3ZlcmxheU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE56Tm9BbmltYXRpb25Nb2R1bGUsIE56T3ZlcmxheU1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZSc7XG5pbXBvcnQgeyBOekVtcHR5TW9kdWxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9lbXB0eSc7XG5pbXBvcnQgeyBOekljb25Nb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2ljb24nO1xuaW1wb3J0IHsgTnpJbnB1dE1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaW5wdXQnO1xuXG5pbXBvcnQgeyBOekNhc2NhZGVyT3B0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9uei1jYXNjYWRlci1saS5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpDYXNjYWRlckNvbXBvbmVudCB9IGZyb20gJy4vbnotY2FzY2FkZXIuY29tcG9uZW50JztcblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBPdmVybGF5TW9kdWxlLFxuICAgIE56SW5wdXRNb2R1bGUsXG4gICAgTnpJY29uTW9kdWxlLFxuICAgIE56RW1wdHlNb2R1bGUsXG4gICAgTnpPdmVybGF5TW9kdWxlLFxuICAgIE56Tm9BbmltYXRpb25Nb2R1bGVcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbTnpDYXNjYWRlckNvbXBvbmVudCwgTnpDYXNjYWRlck9wdGlvbkNvbXBvbmVudF0sXG4gIGV4cG9ydHM6IFtOekNhc2NhZGVyQ29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBOekNhc2NhZGVyTW9kdWxlIHt9XG4iXSwibmFtZXMiOlsiQ29tcG9uZW50IiwiQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kiLCJWaWV3RW5jYXBzdWxhdGlvbiIsIkRvbVNhbml0aXplciIsIkNoYW5nZURldGVjdG9yUmVmIiwiRWxlbWVudFJlZiIsIlJlbmRlcmVyMiIsIklucHV0IiwiQmVoYXZpb3JTdWJqZWN0IiwiU3ViamVjdCIsImFycmF5c0VxdWFsIiwiSW5qZWN0YWJsZSIsIkV2ZW50RW1pdHRlciIsIkRFRkFVTFRfRFJPUERPV05fUE9TSVRJT05TIiwidGFrZVVudGlsIiwidG9BcnJheSIsIkRPV05fQVJST1ciLCJVUF9BUlJPVyIsIkxFRlRfQVJST1ciLCJSSUdIVF9BUlJPVyIsIkVOVEVSIiwiQkFDS1NQQUNFIiwiRVNDQVBFIiwic2xpZGVNb3Rpb24iLCJOR19WQUxVRV9BQ0NFU1NPUiIsImZvcndhcmRSZWYiLCJOek5vQW5pbWF0aW9uRGlyZWN0aXZlIiwiSG9zdCIsIk9wdGlvbmFsIiwiVmlld0NoaWxkIiwiQ2RrQ29ubmVjdGVkT3ZlcmxheSIsIlZpZXdDaGlsZHJlbiIsIk91dHB1dCIsIkhvc3RMaXN0ZW5lciIsInRzbGliXzEuX19kZWNvcmF0ZSIsIklucHV0Qm9vbGVhbiIsIk5nTW9kdWxlIiwiQ29tbW9uTW9kdWxlIiwiRm9ybXNNb2R1bGUiLCJPdmVybGF5TW9kdWxlIiwiTnpJbnB1dE1vZHVsZSIsIk56SWNvbk1vZHVsZSIsIk56RW1wdHlNb2R1bGUiLCJOek92ZXJsYXlNb2R1bGUiLCJOek5vQW5pbWF0aW9uTW9kdWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQXFDQSxhQUFnQixrQkFBa0IsQ0FBQyxPQUFzQztRQUN2RSxPQUFPLE9BQU8sT0FBTyxLQUFLLFNBQVMsQ0FBQztJQUN0QyxD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