UNPKG

ng-zorro-antd

Version:

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

702 lines 76.4 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common'), require('@angular/common/http'), require('@angular/core'), require('@angular/platform-browser'), require('@ant-design/icons-angular'), require('@ant-design/icons-angular/icons'), require('@angular/cdk/platform'), require('ng-zorro-antd/core')) :
    typeof define === 'function' && define.amd ? define('ng-zorro-antd/icon', ['exports', '@angular/common', '@angular/common/http', '@angular/core', '@angular/platform-browser', '@ant-design/icons-angular', '@ant-design/icons-angular/icons', '@angular/cdk/platform', 'ng-zorro-antd/core'], factory) :
    (factory((global['ng-zorro-antd'] = global['ng-zorro-antd'] || {}, global['ng-zorro-antd'].icon = {}),global.ng.common,global.ng.common.http,global.ng.core,global.ng.platformBrowser,global.iconsAngular,global.icons,global.ng.cdk.platform,global['ng-zorro-antd'].core));
}(this, (function (exports,i3,i2,i0,i1,iconsAngular,icons,platform,core) { 'use strict';

    /*! *****************************************************************************
    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.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (b.hasOwnProperty(p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    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
     */
    /** @type {?} */
    var NZ_ICONS = new i0.InjectionToken('nz_icons');
    /** @type {?} */
    var NZ_ICON_DEFAULT_TWOTONE_COLOR = new i0.InjectionToken('nz_icon_default_twotone_color');
    /** @type {?} */
    var DEFAULT_TWOTONE_COLOR = '#1890ff';
    /** @type {?} */
    var NZ_ICONS_USED_BY_ZORRO = [
        icons.BarsOutline,
        icons.CalendarOutline,
        icons.CaretUpFill,
        icons.CaretUpOutline,
        icons.CaretDownFill,
        icons.CaretDownOutline,
        icons.CheckCircleFill,
        icons.CheckCircleOutline,
        icons.CheckOutline,
        icons.ClockCircleOutline,
        icons.CloseCircleOutline,
        icons.CloseCircleFill,
        icons.CloseOutline,
        icons.DoubleLeftOutline,
        icons.DoubleRightOutline,
        icons.DownOutline,
        icons.EllipsisOutline,
        icons.ExclamationCircleFill,
        icons.ExclamationCircleOutline,
        icons.EyeOutline,
        icons.FileFill,
        icons.FileOutline,
        icons.FilterFill,
        icons.InfoCircleFill,
        icons.InfoCircleOutline,
        icons.LeftOutline,
        icons.LoadingOutline,
        icons.PaperClipOutline,
        icons.QuestionCircleOutline,
        icons.RightOutline,
        icons.StarFill,
        icons.SearchOutline,
        icons.StarFill,
        icons.UploadOutline,
        icons.UpOutline
    ];
    /**
     * It should be a global singleton, otherwise registered icons could not be found.
     */
    var NzIconService = /** @class */ (function (_super) {
        __extends(NzIconService, _super);
        function NzIconService(rendererFactory, sanitizer, handler, document, icons$$1, defaultColor) {
            var _this = _super.call(this, rendererFactory, handler, document, sanitizer) || this;
            _this.rendererFactory = rendererFactory;
            _this.sanitizer = sanitizer;
            _this.handler = handler;
            _this.document = document;
            _this.icons = icons$$1;
            _this.defaultColor = defaultColor;
            _this.iconfontCache = new Set();
            _this.warnedAboutAPI = false;
            _this.warnedAboutCross = false;
            _this.warnedAboutVertical = false;
            _this.addIcon.apply(_this, __spread(NZ_ICONS_USED_BY_ZORRO, (_this.icons || [])));
            /** @type {?} */
            var primaryColor = DEFAULT_TWOTONE_COLOR;
            if (_this.defaultColor) {
                if (_this.defaultColor.startsWith('#')) {
                    primaryColor = _this.defaultColor;
                }
                else {
                    console.warn('[NG-ZORRO]: twotone color must be a hex color!');
                }
            }
            _this.twoToneColor = { primaryColor: primaryColor };
            return _this;
        }
        /**
         * @param {?} type
         * @return {?}
         */
        NzIconService.prototype.warnAPI = /**
         * @param {?} type
         * @return {?}
         */
            function (type) {
                if (type === 'old' && !this.warnedAboutAPI) {
                    console.warn("<i class=\"anticon\"></i> would be deprecated soon. Please use <i nz-icon type=\"\"></i> API.");
                    this.warnedAboutAPI = true;
                }
                if (type === 'cross' && !this.warnedAboutCross) {
                    console.warn("'cross' icon is replaced by 'close' icon.");
                    this.warnedAboutCross = true;
                }
                if (type === 'vertical' && !this.warnedAboutVertical) {
                    console.warn("'verticle' is misspelled, would be corrected in the next major version.");
                    this.warnedAboutVertical = true;
                }
            };
        /**
         * @param {?} svg
         * @return {?}
         */
        NzIconService.prototype.normalizeSvgElement = /**
         * @param {?} svg
         * @return {?}
         */
            function (svg) {
                if (!svg.getAttribute('viewBox')) {
                    this._renderer.setAttribute(svg, 'viewBox', '0 0 1024 1024');
                }
                if (!svg.getAttribute('width') || !svg.getAttribute('height')) {
                    this._renderer.setAttribute(svg, 'width', '1em');
                    this._renderer.setAttribute(svg, 'height', '1em');
                }
                if (!svg.getAttribute('fill')) {
                    this._renderer.setAttribute(svg, 'fill', 'currentColor');
                }
            };
        /**
         * @param {?} opt
         * @return {?}
         */
        NzIconService.prototype.fetchFromIconfont = /**
         * @param {?} opt
         * @return {?}
         */
            function (opt) {
                var scriptUrl = opt.scriptUrl;
                if (this.document && !this.iconfontCache.has(scriptUrl)) {
                    /** @type {?} */
                    var script = this._renderer.createElement('script');
                    this._renderer.setAttribute(script, 'src', scriptUrl);
                    this._renderer.setAttribute(script, 'data-namespace', scriptUrl.replace(/^(https?|http):/g, ''));
                    this._renderer.appendChild(this.document.body, script);
                    this.iconfontCache.add(scriptUrl);
                }
            };
        /**
         * @param {?} type
         * @return {?}
         */
        NzIconService.prototype.createIconfontIcon = /**
         * @param {?} type
         * @return {?}
         */
            function (type) {
                return this._createSVGElementFromString("<svg><use xlink:href=\"" + type + "\"></svg>");
            };
        NzIconService.decorators = [
            { type: i0.Injectable, args: [{
                        providedIn: 'root'
                    },] }
        ];
        /** @nocollapse */
        NzIconService.ctorParameters = function () {
            return [
                { type: i0.RendererFactory2 },
                { type: i1.DomSanitizer },
                { type: i2.HttpBackend, decorators: [{ type: i0.Optional }] },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [i3.DOCUMENT,] }] },
                { type: Array, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [NZ_ICONS,] }] },
                { type: String, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [NZ_ICON_DEFAULT_TWOTONE_COLOR,] }] }
            ];
        };
        /** @nocollapse */ NzIconService.ngInjectableDef = i0.defineInjectable({ factory: function NzIconService_Factory() { return new NzIconService(i0.inject(i0.RendererFactory2), i0.inject(i1.DomSanitizer), i0.inject(i2.HttpBackend, 8), i0.inject(i3.DOCUMENT, 8), i0.inject(NZ_ICONS, 8), i0.inject(NZ_ICON_DEFAULT_TWOTONE_COLOR, 8)); }, token: NzIconService, providedIn: "root" });
        return NzIconService;
    }(iconsAngular.IconService));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var iconTypeRE = /^anticon\-\w/;
    /** @type {?} */
    var getIconTypeClass = ( /**
     * @param {?} className
     * @return {?}
     */function (className) {
        if (!className) {
            return undefined;
        }
        else {
            /** @type {?} */
            var classArr = className.split(/\s/);
            /** @type {?} */
            var index = classArr.findIndex(( /**
             * @param {?} cls
             * @return {?}
             */function (cls) { return cls !== 'anticon' && cls !== 'anticon-spin' && !!cls.match(iconTypeRE); }));
            return index === -1 ? undefined : { name: classArr[index], index: index };
        }
    });
    /** @type {?} */
    var normalizeType = ( /**
     * @param {?} rawType
     * @return {?}
     */function (rawType) {
        /** @type {?} */
        var ret = { type: rawType, crossError: false, verticalError: false };
        ret.type = rawType ? rawType.replace('anticon-', '') : '';
        if (ret.type.includes('verticle')) {
            ret.type = 'up';
            ret.verticalError = true;
        }
        if (ret.type.startsWith('cross')) {
            ret.type = 'close';
            ret.crossError = true;
        }
        return ret;
    });
    /**
     * This directive extends IconDirective to provide:
     *
     * - IconFont support
     * - spinning
     * - old API compatibility
     *
     * \@break-changes
     *
     * - old API compatibility, icon class names would not be supported.
     * - properties that not started with `nz`.
     */
    var NzIconDirective = /** @class */ (function (_super) {
        __extends(NzIconDirective, _super);
        function NzIconDirective(iconService, elementRef, renderer, platform$$1) {
            var _this = _super.call(this, iconService, elementRef, renderer) || this;
            _this.iconService = iconService;
            _this.elementRef = elementRef;
            _this.renderer = renderer;
            _this.platform = platform$$1;
            _this.nzRotate = 0;
            /**
             * @deprecated 8.0.0 avoid exposing low layer API.
             */
            _this.spin = false;
            _this.el = _this.elementRef.nativeElement;
            return _this;
        }
        Object.defineProperty(NzIconDirective.prototype, "nzSpin", {
            /** Properties with `nz` prefix. */
            set: /**
             * Properties with `nz` prefix.
             * @param {?} value
             * @return {?}
             */ function (value) {
                this.spin = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzIconDirective.prototype, "nzType", {
            set: /**
             * @param {?} value
             * @return {?}
             */ function (value) {
                this.type = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzIconDirective.prototype, "nzTheme", {
            set: /**
             * @param {?} value
             * @return {?}
             */ function (value) {
                this.theme = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzIconDirective.prototype, "nzTwotoneColor", {
            set: /**
             * @param {?} value
             * @return {?}
             */ function (value) {
                this.twoToneColor = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzIconDirective.prototype, "nzIconfont", {
            set: /**
             * @param {?} value
             * @return {?}
             */ function (value) {
                this.iconfont = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NzIconDirective.prototype, "type", {
            get: /**
             * @return {?}
             */ function () {
                return this._type;
            },
            set: /**
             * @param {?} value
             * @return {?}
             */ function (value) {
                if (value && value.startsWith('anticon')) {
                    /** @type {?} */
                    var rawClass = getIconTypeClass(value);
                    /** @type {?} */
                    var type = rawClass ? normalizeType(rawClass.name).type : '';
                    if (type && this.type !== type) {
                        this._type = type;
                    }
                }
                else {
                    this._type = value;
                }
            },
            enumerable: true,
            configurable: true
        });
        /**
         * Replacement of `changeIcon` for more modifications.
         * @param oldAPI
         */
        /**
         * Replacement of `changeIcon` for more modifications.
         * @private
         * @param {?=} oldAPI
         * @return {?}
         */
        NzIconDirective.prototype.changeIcon2 = /**
         * Replacement of `changeIcon` for more modifications.
         * @private
         * @param {?=} oldAPI
         * @return {?}
         */
            function (oldAPI) {
                var _this = this;
                if (oldAPI === void 0) {
                    oldAPI = false;
                }
                if (!oldAPI) {
                    this.setClassName();
                }
                this._changeIcon().then(( /**
                 * @param {?} svg
                 * @return {?}
                 */function (svg) {
                    _this.setSVGData(svg);
                    if (!oldAPI && svg) {
                        _this.handleSpin(svg);
                        _this.handleRotate(svg);
                    }
                }));
            };
        /**
         * @private
         * @param {?} className
         * @return {?}
         */
        NzIconDirective.prototype.classChangeHandler = /**
         * @private
         * @param {?} className
         * @return {?}
         */
            function (className) {
                /** @type {?} */
                var ret = getIconTypeClass(className);
                if (ret) {
                    var _a = normalizeType(ret.name), type = _a.type, crossError = _a.crossError, verticalError = _a.verticalError;
                    if (crossError) {
                        this.iconService.warnAPI('cross');
                    }
                    if (verticalError) {
                        this.iconService.warnAPI('vertical');
                    }
                    if (this.type !== type) {
                        this._type = type;
                        this.changeIcon2(true);
                    }
                }
            };
        /**
         * @private
         * @param {?} svg
         * @return {?}
         */
        NzIconDirective.prototype.handleSpin = /**
         * @private
         * @param {?} svg
         * @return {?}
         */
            function (svg) {
                if ((this.spin || this.type === 'loading') && !this.elementRef.nativeElement.classList.contains('anticon-spin')) {
                    this.renderer.addClass(svg, 'anticon-spin');
                }
                else {
                    this.renderer.removeClass(svg, 'anticon-spin');
                }
            };
        /**
         * @private
         * @param {?} svg
         * @return {?}
         */
        NzIconDirective.prototype.handleRotate = /**
         * @private
         * @param {?} svg
         * @return {?}
         */
            function (svg) {
                if (this.nzRotate) {
                    this.renderer.setAttribute(svg, 'style', "transform: rotate(" + this.nzRotate + "deg)");
                }
                else {
                    this.renderer.removeAttribute(svg, 'style');
                }
            };
        /**
         * @private
         * @return {?}
         */
        NzIconDirective.prototype.setClassName = /**
         * @private
         * @return {?}
         */
            function () {
                if (typeof this.type === 'string') {
                    /** @type {?} */
                    var iconClassNameArr = this.el.className.split(/\s/);
                    /** @type {?} */
                    var ret = getIconTypeClass(this.el.className);
                    if (ret) {
                        iconClassNameArr.splice(ret.index, 1, "anticon-" + this.type);
                        this.renderer.setAttribute(this.el, 'class', iconClassNameArr.join(' '));
                    }
                    else {
                        this.renderer.addClass(this.el, "anticon-" + this.type);
                    }
                }
            };
        /**
         * @private
         * @param {?} svg
         * @return {?}
         */
        NzIconDirective.prototype.setSVGData = /**
         * @private
         * @param {?} svg
         * @return {?}
         */
            function (svg) {
                if (typeof this.type === 'string' && svg) {
                    this.renderer.setAttribute(svg, 'data-icon', this.type);
                    this.renderer.setAttribute(svg, 'aria-hidden', 'true');
                }
            };
        /**
         * @param {?} changes
         * @return {?}
         */
        NzIconDirective.prototype.ngOnChanges = /**
         * @param {?} changes
         * @return {?}
         */
            function (changes) {
                var type = changes.type, nzType = changes.nzType, nzTwotoneColor = changes.nzTwotoneColor, twoToneColor = changes.twoToneColor, spin = changes.spin, nzSpin = changes.nzSpin, theme = changes.theme, nzTheme = changes.nzTheme, nzRotate = changes.nzRotate;
                if (type || nzType || nzTwotoneColor || twoToneColor || spin || nzSpin || theme || nzTheme) {
                    this.changeIcon2();
                }
                else if (nzRotate) {
                    this.handleRotate(this.el.firstChild);
                }
                else {
                    this._setSVGElement(this.iconService.createIconfontIcon("#" + this.iconfont));
                }
            };
        /**
         * @return {?}
         */
        NzIconDirective.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                // If `this.type` is not specified and `classList` contains `anticon`, it should be an icon using old API.
                if (!this.type && this.el.classList.contains('anticon')) {
                    this.iconService.warnAPI('old');
                    // Get `type` from `className`. If not, initial rendering would be missed.
                    this.classChangeHandler(this.el.className);
                    if (this.platform.isBrowser) {
                        // Add `class` mutation observer.
                        this.classNameObserver = new MutationObserver(( /**
                         * @param {?} mutations
                         * @return {?}
                         */function (mutations) {
                            mutations
                                .filter(( /**
                         * @param {?} mutation
                         * @return {?}
                         */function (mutation) { return mutation.attributeName === 'class'; }))
                                .forEach(( /**
                         * @param {?} mutation
                         * @return {?}
                         */function (mutation) { return _this.classChangeHandler((( /** @type {?} */(mutation.target))).className); }));
                        }));
                        this.classNameObserver.observe(this.el, { attributes: true });
                    }
                }
                // If `classList` does not contain `anticon`, add it before other class names.
                if (!this.el.classList.contains('anticon')) {
                    this.renderer.setAttribute(this.el, 'class', ("anticon " + this.el.className).trim());
                }
            };
        /**
         * @return {?}
         */
        NzIconDirective.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                if (this.classNameObserver) {
                    this.classNameObserver.disconnect();
                }
            };
        /**
         * If custom content is provided, try to normalize SVG elements.
         */
        /**
         * If custom content is provided, try to normalize SVG elements.
         * @return {?}
         */
        NzIconDirective.prototype.ngAfterContentChecked = /**
         * If custom content is provided, try to normalize SVG elements.
         * @return {?}
         */
            function () {
                /** @type {?} */
                var children = this.el.children;
                /** @type {?} */
                var length = children.length;
                if (!this.type && children.length) {
                    while (length--) {
                        /** @type {?} */
                        var child = children[length];
                        if (child.tagName.toLowerCase() === 'svg') {
                            this.iconService.normalizeSvgElement(( /** @type {?} */(child)));
                        }
                    }
                }
            };
        NzIconDirective.decorators = [
            { type: i0.Directive, args: [{
                        selector: 'i.anticon, [nz-icon]',
                        exportAs: 'nzIcon'
                    },] }
        ];
        /** @nocollapse */
        NzIconDirective.ctorParameters = function () {
            return [
                { type: NzIconService },
                { type: i0.ElementRef },
                { type: i0.Renderer2 },
                { type: platform.Platform }
            ];
        };
        NzIconDirective.propDecorators = {
            nzSpin: [{ type: i0.Input }],
            nzRotate: [{ type: i0.Input }],
            nzType: [{ type: i0.Input }],
            nzTheme: [{ type: i0.Input }],
            nzTwotoneColor: [{ type: i0.Input }],
            nzIconfont: [{ type: i0.Input }],
            spin: [{ type: i0.Input }],
            iconfont: [{ type: i0.Input }],
            type: [{ type: i0.Input }]
        };
        __decorate([
            core.InputBoolean(),
            __metadata("design:type", Boolean),
            __metadata("design:paramtypes", [Boolean])
        ], NzIconDirective.prototype, "nzSpin", null);
        return NzIconDirective;
    }(iconsAngular.IconDirective));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NzIconModule = /** @class */ (function () {
        function NzIconModule() {
        }
        NzIconModule.decorators = [
            { type: i0.NgModule, args: [{
                        exports: [NzIconDirective],
                        declarations: [NzIconDirective]
                    },] }
        ];
        return NzIconModule;
    }());

    /**
     * @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.NzIconModule = NzIconModule;
    exports.NzIconDirective = NzIconDirective;
    exports.NZ_ICONS = NZ_ICONS;
    exports.NZ_ICON_DEFAULT_TWOTONE_COLOR = NZ_ICON_DEFAULT_TWOTONE_COLOR;
    exports.DEFAULT_TWOTONE_COLOR = DEFAULT_TWOTONE_COLOR;
    exports.NZ_ICONS_USED_BY_ZORRO = NZ_ICONS_USED_BY_ZORRO;
    exports.NzIconService = NzIconService;

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

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctem9ycm8tYW50ZC1pY29uLnVtZC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCJuZzovL25nLXpvcnJvLWFudGQvaWNvbi9uei1pY29uLnNlcnZpY2UudHMiLCJuZzovL25nLXpvcnJvLWFudGQvaWNvbi9uei1pY29uLmRpcmVjdGl2ZS50cyIsIm5nOi8vbmctem9ycm8tYW50ZC9pY29uL256LWljb24ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXHJcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXHJcbkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcblxyXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRURcclxuV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSxcclxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cclxuXHJcblNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xyXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMClcclxuICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBleHBvcnRzKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmICghZXhwb3J0cy5oYXNPd25Qcm9wZXJ0eShwKSkgZXhwb3J0c1twXSA9IG1bcF07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl0sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcclxuICAgIHJlc3VsdC5kZWZhdWx0ID0gbW9kO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEh0dHBCYWNrZW5kIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiwgT3B0aW9uYWwsIFJlbmRlcmVyRmFjdG9yeTIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgSWNvbkRlZmluaXRpb24sIEljb25TZXJ2aWNlIH0gZnJvbSAnQGFudC1kZXNpZ24vaWNvbnMtYW5ndWxhcic7XG5pbXBvcnQge1xuICBCYXJzT3V0bGluZSxcbiAgQ2FsZW5kYXJPdXRsaW5lLFxuICBDYXJldERvd25GaWxsLFxuICBDYXJldERvd25PdXRsaW5lLFxuICBDYXJldFVwRmlsbCxcbiAgQ2FyZXRVcE91dGxpbmUsXG4gIENoZWNrQ2lyY2xlRmlsbCxcbiAgQ2hlY2tDaXJjbGVPdXRsaW5lLFxuICBDaGVja091dGxpbmUsXG4gIENsb2NrQ2lyY2xlT3V0bGluZSxcbiAgQ2xvc2VDaXJjbGVGaWxsLFxuICBDbG9zZUNpcmNsZU91dGxpbmUsXG4gIENsb3NlT3V0bGluZSxcbiAgRG91YmxlTGVmdE91dGxpbmUsXG4gIERvdWJsZVJpZ2h0T3V0bGluZSxcbiAgRG93bk91dGxpbmUsXG4gIEVsbGlwc2lzT3V0bGluZSxcbiAgRXhjbGFtYXRpb25DaXJjbGVGaWxsLFxuICBFeGNsYW1hdGlvbkNpcmNsZU91dGxpbmUsXG4gIEV5ZU91dGxpbmUsXG4gIEZpbGVGaWxsLFxuICBGaWxlT3V0bGluZSxcbiAgRmlsdGVyRmlsbCxcbiAgSW5mb0NpcmNsZUZpbGwsXG4gIEluZm9DaXJjbGVPdXRsaW5lLFxuICBMZWZ0T3V0bGluZSxcbiAgTG9hZGluZ091dGxpbmUsXG4gIFBhcGVyQ2xpcE91dGxpbmUsXG4gIFF1ZXN0aW9uQ2lyY2xlT3V0bGluZSxcbiAgUmlnaHRPdXRsaW5lLFxuICBTZWFyY2hPdXRsaW5lLFxuICBTdGFyRmlsbCxcbiAgVXBsb2FkT3V0bGluZSxcbiAgVXBPdXRsaW5lXG59IGZyb20gJ0BhbnQtZGVzaWduL2ljb25zLWFuZ3VsYXIvaWNvbnMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE56SWNvbmZvbnRPcHRpb24ge1xuICBzY3JpcHRVcmw6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IE5aX0lDT05TID0gbmV3IEluamVjdGlvblRva2VuKCduel9pY29ucycpO1xuZXhwb3J0IGNvbnN0IE5aX0lDT05fREVGQVVMVF9UV09UT05FX0NPTE9SID0gbmV3IEluamVjdGlvblRva2VuKCduel9pY29uX2RlZmF1bHRfdHdvdG9uZV9jb2xvcicpO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVFdPVE9ORV9DT0xPUiA9ICcjMTg5MGZmJztcbmV4cG9ydCBjb25zdCBOWl9JQ09OU19VU0VEX0JZX1pPUlJPOiBJY29uRGVmaW5pdGlvbltdID0gW1xuICBCYXJzT3V0bGluZSxcbiAgQ2FsZW5kYXJPdXRsaW5lLFxuICBDYXJldFVwRmlsbCxcbiAgQ2FyZXRVcE91dGxpbmUsXG4gIENhcmV0RG93bkZpbGwsXG4gIENhcmV0RG93bk91dGxpbmUsXG4gIENoZWNrQ2lyY2xlRmlsbCxcbiAgQ2hlY2tDaXJjbGVPdXRsaW5lLFxuICBDaGVja091dGxpbmUsXG4gIENsb2NrQ2lyY2xlT3V0bGluZSxcbiAgQ2xvc2VDaXJjbGVPdXRsaW5lLFxuICBDbG9zZUNpcmNsZUZpbGwsXG4gIENsb3NlT3V0bGluZSxcbiAgRG91YmxlTGVmdE91dGxpbmUsXG4gIERvdWJsZVJpZ2h0T3V0bGluZSxcbiAgRG93bk91dGxpbmUsXG4gIEVsbGlwc2lzT3V0bGluZSxcbiAgRXhjbGFtYXRpb25DaXJjbGVGaWxsLFxuICBFeGNsYW1hdGlvbkNpcmNsZU91dGxpbmUsXG4gIEV5ZU91dGxpbmUsXG4gIEZpbGVGaWxsLFxuICBGaWxlT3V0bGluZSxcbiAgRmlsdGVyRmlsbCxcbiAgSW5mb0NpcmNsZUZpbGwsXG4gIEluZm9DaXJjbGVPdXRsaW5lLFxuICBMZWZ0T3V0bGluZSxcbiAgTG9hZGluZ091dGxpbmUsXG4gIFBhcGVyQ2xpcE91dGxpbmUsXG4gIFF1ZXN0aW9uQ2lyY2xlT3V0bGluZSxcbiAgUmlnaHRPdXRsaW5lLFxuICBTdGFyRmlsbCxcbiAgU2VhcmNoT3V0bGluZSxcbiAgU3RhckZpbGwsXG4gIFVwbG9hZE91dGxpbmUsXG4gIFVwT3V0bGluZVxuXTtcblxuLyoqXG4gKiBJdCBzaG91bGQgYmUgYSBnbG9iYWwgc2luZ2xldG9uLCBvdGhlcndpc2UgcmVnaXN0ZXJlZCBpY29ucyBjb3VsZCBub3QgYmUgZm91bmQuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE56SWNvblNlcnZpY2UgZXh0ZW5kcyBJY29uU2VydmljZSB7XG4gIHByaXZhdGUgaWNvbmZvbnRDYWNoZSA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIHdhcm5lZEFib3V0QVBJID0gZmFsc2U7XG4gIHByaXZhdGUgd2FybmVkQWJvdXRDcm9zcyA9IGZhbHNlO1xuICBwcml2YXRlIHdhcm5lZEFib3V0VmVydGljYWwgPSBmYWxzZTtcblxuICB3YXJuQVBJKHR5cGU6ICdvbGQnIHwgJ2Nyb3NzJyB8ICd2ZXJ0aWNhbCcpOiB2b2lkIHtcbiAgICBpZiAodHlwZSA9PT0gJ29sZCcgJiYgIXRoaXMud2FybmVkQWJvdXRBUEkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgPGkgY2xhc3M9XCJhbnRpY29uXCI+PC9pPiB3b3VsZCBiZSBkZXByZWNhdGVkIHNvb24uIFBsZWFzZSB1c2UgPGkgbnotaWNvbiB0eXBlPVwiXCI+PC9pPiBBUEkuYCk7XG4gICAgICB0aGlzLndhcm5lZEFib3V0QVBJID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09ICdjcm9zcycgJiYgIXRoaXMud2FybmVkQWJvdXRDcm9zcykge1xuICAgICAgY29uc29sZS53YXJuKGAnY3Jvc3MnIGljb24gaXMgcmVwbGFjZWQgYnkgJ2Nsb3NlJyBpY29uLmApO1xuICAgICAgdGhpcy53YXJuZWRBYm91dENyb3NzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09ICd2ZXJ0aWNhbCcgJiYgIXRoaXMud2FybmVkQWJvdXRWZXJ0aWNhbCkge1xuICAgICAgY29uc29sZS53YXJuKGAndmVydGljbGUnIGlzIG1pc3NwZWxsZWQsIHdvdWxkIGJlIGNvcnJlY3RlZCBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uLmApO1xuICAgICAgdGhpcy53YXJuZWRBYm91dFZlcnRpY2FsID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBub3JtYWxpemVTdmdFbGVtZW50KHN2ZzogU1ZHRWxlbWVudCk6IHZvaWQge1xuICAgIGlmICghc3ZnLmdldEF0dHJpYnV0ZSgndmlld0JveCcpKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc3ZnLCAndmlld0JveCcsICcwIDAgMTAyNCAxMDI0Jyk7XG4gICAgfVxuICAgIGlmICghc3ZnLmdldEF0dHJpYnV0ZSgnd2lkdGgnKSB8fCAhc3ZnLmdldEF0dHJpYnV0ZSgnaGVpZ2h0JykpIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICd3aWR0aCcsICcxZW0nKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdoZWlnaHQnLCAnMWVtJyk7XG4gICAgfVxuICAgIGlmICghc3ZnLmdldEF0dHJpYnV0ZSgnZmlsbCcpKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc3ZnLCAnZmlsbCcsICdjdXJyZW50Q29sb3InKTtcbiAgICB9XG4gIH1cblxuICBmZXRjaEZyb21JY29uZm9udChvcHQ6IE56SWNvbmZvbnRPcHRpb24pOiB2b2lkIHtcbiAgICBjb25zdCB7IHNjcmlwdFVybCB9ID0gb3B0O1xuICAgIGlmICh0aGlzLmRvY3VtZW50ICYmICF0aGlzLmljb25mb250Q2FjaGUuaGFzKHNjcmlwdFVybCkpIHtcbiAgICAgIGNvbnN0IHNjcmlwdCA9IHRoaXMuX3JlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHNjcmlwdCwgJ3NyYycsIHNjcmlwdFVybCk7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc2NyaXB0LCAnZGF0YS1uYW1lc3BhY2UnLCBzY3JpcHRVcmwucmVwbGFjZSgvXihodHRwcz98aHR0cCk6L2csICcnKSk7XG4gICAgICB0aGlzLl9yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmRvY3VtZW50LmJvZHksIHNjcmlwdCk7XG4gICAgICB0aGlzLmljb25mb250Q2FjaGUuYWRkKHNjcmlwdFVybCk7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlSWNvbmZvbnRJY29uKHR5cGU6IHN0cmluZyk6IFNWR0VsZW1lbnQge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVTVkdFbGVtZW50RnJvbVN0cmluZyhgPHN2Zz48dXNlIHhsaW5rOmhyZWY9XCIke3R5cGV9XCI+PC9zdmc+YCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLFxuICAgIHByb3RlY3RlZCBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBAT3B0aW9uYWwoKSBwcm90ZWN0ZWQgaGFuZGxlcjogSHR0cEJhY2tlbmQsXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRE9DVU1FTlQpIHByb3RlY3RlZCBkb2N1bWVudDogYW55LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTlpfSUNPTlMpIHByaXZhdGUgaWNvbnM6IEljb25EZWZpbml0aW9uW10sXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChOWl9JQ09OX0RFRkFVTFRfVFdPVE9ORV9DT0xPUikgcHJpdmF0ZSBkZWZhdWx0Q29sb3I6IHN0cmluZ1xuICApIHtcbiAgICBzdXBlcihyZW5kZXJlckZhY3RvcnksIGhhbmRsZXIsIGRvY3VtZW50LCBzYW5pdGl6ZXIpO1xuXG4gICAgdGhpcy5hZGRJY29uKC4uLk5aX0lDT05TX1VTRURfQllfWk9SUk8sIC4uLih0aGlzLmljb25zIHx8IFtdKSk7XG5cbiAgICBsZXQgcHJpbWFyeUNvbG9yID0gREVGQVVMVF9UV09UT05FX0NPTE9SO1xuICAgIGlmICh0aGlzLmRlZmF1bHRDb2xvcikge1xuICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbG9yLnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgICBwcmltYXJ5Q29sb3IgPSB0aGlzLmRlZmF1bHRDb2xvcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybignW05HLVpPUlJPXTogdHdvdG9uZSBjb2xvciBtdXN0IGJlIGEgaGV4IGNvbG9yIScpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnR3b1RvbmVDb2xvciA9IHsgcHJpbWFyeUNvbG9yIH07XG4gIH1cbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJY29uRGlyZWN0aXZlLCBUaGVtZVR5cGUgfSBmcm9tICdAYW50LWRlc2lnbi9pY29ucy1hbmd1bGFyJztcbmltcG9ydCB7IElucHV0Qm9vbGVhbiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZSc7XG5pbXBvcnQgeyBOekljb25TZXJ2aWNlIH0gZnJvbSAnLi9uei1pY29uLnNlcnZpY2UnO1xuXG5jb25zdCBpY29uVHlwZVJFID0gL15hbnRpY29uXFwtXFx3LztcblxuY29uc3QgZ2V0SWNvblR5cGVDbGFzcyA9IChjbGFzc05hbWU6IHN0cmluZyk6IHsgbmFtZTogc3RyaW5nOyBpbmRleDogbnVtYmVyIH0gfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoIWNsYXNzTmFtZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgY2xhc3NBcnIgPSBjbGFzc05hbWUuc3BsaXQoL1xccy8pO1xuICAgIGNvbnN0IGluZGV4ID0gY2xhc3NBcnIuZmluZEluZGV4KGNscyA9PiBjbHMgIT09ICdhbnRpY29uJyAmJiBjbHMgIT09ICdhbnRpY29uLXNwaW4nICYmICEhY2xzLm1hdGNoKGljb25UeXBlUkUpKTtcbiAgICByZXR1cm4gaW5kZXggPT09IC0xID8gdW5kZWZpbmVkIDogeyBuYW1lOiBjbGFzc0FycltpbmRleF0sIGluZGV4IH07XG4gIH1cbn07XG5cbmNvbnN0IG5vcm1hbGl6ZVR5cGUgPSAocmF3VHlwZTogc3RyaW5nKTogeyB0eXBlOiBzdHJpbmc7IGNyb3NzRXJyb3I6IGJvb2xlYW47IHZlcnRpY2FsRXJyb3I6IGJvb2xlYW4gfSA9PiB7XG4gIGNvbnN0IHJldCA9IHsgdHlwZTogcmF3VHlwZSwgY3Jvc3NFcnJvcjogZmFsc2UsIHZlcnRpY2FsRXJyb3I6IGZhbHNlIH07XG4gIHJldC50eXBlID0gcmF3VHlwZSA/IHJhd1R5cGUucmVwbGFjZSgnYW50aWNvbi0nLCAnJykgOiAnJztcbiAgaWYgKHJldC50eXBlLmluY2x1ZGVzKCd2ZXJ0aWNsZScpKSB7XG4gICAgcmV0LnR5cGUgPSAndXAnO1xuICAgIHJldC52ZXJ0aWNhbEVycm9yID0gdHJ1ZTtcbiAgfVxuICBpZiAocmV0LnR5cGUuc3RhcnRzV2l0aCgnY3Jvc3MnKSkge1xuICAgIHJldC50eXBlID0gJ2Nsb3NlJztcbiAgICByZXQuY3Jvc3NFcnJvciA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cbi8qKlxuICogVGhpcyBkaXJlY3RpdmUgZXh0ZW5kcyBJY29uRGlyZWN0aXZlIHRvIHByb3ZpZGU6XG4gKlxuICogLSBJY29uRm9udCBzdXBwb3J0XG4gKiAtIHNwaW5uaW5nXG4gKiAtIG9sZCBBUEkgY29tcGF0aWJpbGl0eVxuICpcbiAqIEBicmVhay1jaGFuZ2VzXG4gKlxuICogLSBvbGQgQVBJIGNvbXBhdGliaWxpdHksIGljb24gY2xhc3MgbmFtZXMgd291bGQgbm90IGJlIHN1cHBvcnRlZC5cbiAqIC0gcHJvcGVydGllcyB0aGF0IG5vdCBzdGFydGVkIHdpdGggYG56YC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnaS5hbnRpY29uLCBbbnotaWNvbl0nLFxuICBleHBvcnRBczogJ256SWNvbidcbn0pXG5leHBvcnQgY2xhc3MgTnpJY29uRGlyZWN0aXZlIGV4dGVuZHMgSWNvbkRpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudENoZWNrZWQge1xuICAvKiogUHJvcGVydGllcyB3aXRoIGBuemAgcHJlZml4LiAqL1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgc2V0IG56U3Bpbih2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuc3BpbiA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpIG56Um90YXRlOiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBzZXQgbnpUeXBlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnR5cGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKSBzZXQgbnpUaGVtZSh2YWx1ZTogVGhlbWVUeXBlKSB7XG4gICAgdGhpcy50aGVtZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpIHNldCBuelR3b3RvbmVDb2xvcih2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy50d29Ub25lQ29sb3IgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKSBzZXQgbnpJY29uZm9udCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5pY29uZm9udCA9IHZhbHVlO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIDguMC4wIGF2b2lkIGV4cG9zaW5nIGxvdyBsYXllciBBUEkuICovXG4gIEBJbnB1dCgpIHNwaW4gPSBmYWxzZTtcblxuICAvKiogQGRlcHJlY2F0ZWQgOC4wLjAgYXZvaWQgZXhwb3NpbmcgbG93IGxheWVyIEFQSS4gKi9cbiAgQElucHV0KCkgaWNvbmZvbnQ6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBzZXQgdHlwZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgaWYgKHZhbHVlICYmIHZhbHVlLnN0YXJ0c1dpdGgoJ2FudGljb24nKSkge1xuICAgICAgY29uc3QgcmF3Q2xhc3MgPSBnZXRJY29uVHlwZUNsYXNzKHZhbHVlKTtcbiAgICAgIGNvbnN0IHR5cGUgPSByYXdDbGFzcyA/IG5vcm1hbGl6ZVR5cGUocmF3Q2xhc3MubmFtZSkudHlwZSA6ICcnO1xuICAgICAgaWYgKHR5cGUgJiYgdGhpcy50eXBlICE9PSB0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90eXBlID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHR5cGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgY2xhc3NOYW1lT2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XG4gIHByaXZhdGUgZWwgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgcHJpdmF0ZSBfdHlwZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZXBsYWNlbWVudCBvZiBgY2hhbmdlSWNvbmAgZm9yIG1vcmUgbW9kaWZpY2F0aW9ucy5cbiAgICogQHBhcmFtIG9sZEFQSVxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VJY29uMihvbGRBUEk6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICghb2xkQVBJKSB7XG4gICAgICB0aGlzLnNldENsYXNzTmFtZSgpO1xuICAgIH1cbiAgICB0aGlzLl9jaGFuZ2VJY29uKCkudGhlbihzdmcgPT4ge1xuICAgICAgdGhpcy5zZXRTVkdEYXRhKHN2Zyk7XG4gICAgICBpZiAoIW9sZEFQSSAmJiBzdmcpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVTcGluKHN2Zyk7XG4gICAgICAgIHRoaXMuaGFuZGxlUm90YXRlKHN2Zyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsYXNzQ2hhbmdlSGFuZGxlcihjbGFzc05hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHJldCA9IGdldEljb25UeXBlQ2xhc3MoY2xhc3NOYW1lKTtcbiAgICBpZiAocmV0KSB7XG4gICAgICBjb25zdCB7IHR5cGUsIGNyb3NzRXJyb3IsIHZlcnRpY2FsRXJyb3IgfSA9IG5vcm1hbGl6ZVR5cGUocmV0Lm5hbWUpO1xuICAgICAgaWYgKGNyb3NzRXJyb3IpIHtcbiAgICAgICAgdGhpcy5pY29uU2VydmljZS53YXJuQVBJKCdjcm9zcycpO1xuICAgICAgfVxuICAgICAgaWYgKHZlcnRpY2FsRXJyb3IpIHtcbiAgICAgICAgdGhpcy5pY29uU2VydmljZS53YXJuQVBJKCd2ZXJ0aWNhbCcpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudHlwZSAhPT0gdHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jaGFuZ2VJY29uMih0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVNwaW4oc3ZnOiBTVkdFbGVtZW50KTogdm9pZCB7XG4gICAgaWYgKCh0aGlzLnNwaW4gfHwgdGhpcy50eXBlID09PSAnbG9hZGluZycpICYmICF0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2FudGljb24tc3BpbicpKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHN2ZywgJ2FudGljb24tc3BpbicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHN2ZywgJ2FudGljb24tc3BpbicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlUm90YXRlKHN2ZzogU1ZHRWxlbWVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm56Um90YXRlKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdzdHlsZScsIGB0cmFuc2Zvcm06IHJvdGF0ZSgke3RoaXMubnpSb3RhdGV9ZGVnKWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUF0dHJpYnV0ZShzdmcsICdzdHlsZScpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0Q2xhc3NOYW1lKCk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgdGhpcy50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgaWNvbkNsYXNzTmFtZUFyciA9IHRoaXMuZWwuY2xhc3NOYW1lLnNwbGl0KC9cXHMvKTtcbiAgICAgIGNvbnN0IHJldCA9IGdldEljb25UeXBlQ2xhc3ModGhpcy5lbC5jbGFzc05hbWUpO1xuICAgICAgaWYgKHJldCkge1xuICAgICAgICBpY29uQ2xhc3NOYW1lQXJyLnNwbGljZShyZXQuaW5kZXgsIDEsIGBhbnRpY29uLSR7dGhpcy50eXBlfWApO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0aGlzLmVsLCAnY2xhc3MnLCBpY29uQ2xhc3NOYW1lQXJyLmpvaW4oJyAnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWwsIGBhbnRpY29uLSR7dGhpcy50eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U1ZHRGF0YShzdmc6IFNWR0VsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnR5cGUgPT09ICdzdHJpbmcnICYmIHN2Zykge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc3ZnLCAnZGF0YS1pY29uJywgdGhpcy50eXBlKTtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaWNvblNlcnZpY2U6IE56SWNvblNlcnZpY2UsXG4gICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHVibGljIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm1cbiAgKSB7XG4gICAgc3VwZXIoaWNvblNlcnZpY2UsIGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IHR5cGUsIG56VHlwZSwgbnpUd290b25lQ29sb3IsIHR3b1RvbmVDb2xvciwgc3BpbiwgbnpTcGluLCB0aGVtZSwgbnpUaGVtZSwgbnpSb3RhdGUgfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAodHlwZSB8fCBuelR5cGUgfHwgbnpUd290b25lQ29sb3IgfHwgdHdvVG9uZUNvbG9yIHx8IHNwaW4gfHwgbnpTcGluIHx8IHRoZW1lIHx8IG56VGhlbWUpIHtcbiAgICAgIHRoaXMuY2hhbmdlSWNvbjIoKTtcbiAgICB9IGVsc2UgaWYgKG56Um90YXRlKSB7XG4gICAgICB0aGlzLmhhbmRsZVJvdGF0ZSh0aGlzLmVsLmZpcnN0Q2hpbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXRTVkdFbGVtZW50KHRoaXMuaWNvblNlcnZpY2UuY3JlYXRlSWNvbmZvbnRJY29uKGAjJHt0aGlzLmljb25mb250fWApKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBJZiBgdGhpcy50eXBlYCBpcyBub3Qgc3BlY2lmaWVkIGFuZCBgY2xhc3NMaXN0YCBjb250YWlucyBgYW50aWNvbmAsIGl0IHNob3VsZCBiZSBhbiBpY29uIHVzaW5nIG9sZCBBUEkuXG4gICAgaWYgKCF0aGlzLnR5cGUgJiYgdGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoJ2FudGljb24nKSkge1xuICAgICAgdGhpcy5pY29uU2VydmljZS53YXJuQVBJKCdvbGQnKTtcbiAgICAgIC8vIEdldCBgdHlwZWAgZnJvbSBgY2xhc3NOYW1lYC4gSWYgbm90LCBpbml0aWFsIHJlbmRlcmluZyB3b3VsZCBiZSBtaXNzZWQuXG4gICAgICB0aGlzLmNsYXNzQ2hhbmdlSGFuZGxlcih0aGlzLmVsLmNsYXNzTmFtZSk7XG4gICAgICBpZiAodGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgICAgLy8gQWRkIGBjbGFzc2AgbXV0YXRpb24gb2JzZXJ2ZXIuXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zOiBNdXRhdGlvblJlY29yZFtdKSA9PiB7XG4gICAgICAgICAgbXV0YXRpb25zXG4gICAgICAgICAgICAuZmlsdGVyKChtdXRhdGlvbjogTXV0YXRpb25SZWNvcmQpID0+IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWUgPT09ICdjbGFzcycpXG4gICAgICAgICAgICAuZm9yRWFjaCgobXV0YXRpb246IE11dGF0aW9uUmVjb3JkKSA9PiB0aGlzLmNsYXNzQ2hhbmdlSGFuZGxlcigobXV0YXRpb24udGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbGFzc05hbWUpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2xhc3NOYW1lT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsLCB7IGF0dHJpYnV0ZXM6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIElmIGBjbGFzc0xpc3RgIGRvZXMgbm90IGNvbnRhaW4gYGFudGljb25gLCBhZGQgaXQgYmVmb3JlIG90aGVyIGNsYXNzIG5hbWVzLlxuICAgIGlmICghdGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoJ2FudGljb24nKSkge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5lbCwgJ2NsYXNzJywgYGFudGljb24gJHt0aGlzLmVsLmNsYXNzTmFtZX1gLnRyaW0oKSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lT2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBjdXN0b20gY29udGVudCBpcyBwcm92aWRlZCwgdHJ5IHRvIG5vcm1hbGl6ZSBTVkcgZWxlbWVudHMuXG4gICAqL1xuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKTogdm9pZCB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmVsLmNoaWxkcmVuO1xuICAgIGxldCBsZW5ndGggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgaWYgKCF0aGlzLnR5cGUgJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltsZW5ndGhdO1xuICAgICAgICBpZiAoY2hpbGQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnc3ZnJykge1xuICAgICAgICAgIHRoaXMuaWNvblNlcnZpY2Uubm9ybWFsaXplU3ZnRWxlbWVudChjaGlsZCBhcyBTVkdFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOekljb25EaXJlY3RpdmUgfSBmcm9tICcuL256LWljb24uZGlyZWN0aXZlJztcblxuQE5nTW9kdWxlKHtcbiAgZXhwb3J0czogW056SWNvbkRpcmVjdGl2ZV0sXG4gIGRlY2xhcmF0aW9uczogW056SWNvbkRpcmVjdGl2ZV1cbn0pXG5leHBvcnQgY2xhc3MgTnpJY29uTW9kdWxlIHt9XG4iXSwibmFtZXMiOlsiSW5qZWN0aW9uVG9rZW4iLCJCYXJzT3V0bGluZSIsIkNhbGVuZGFyT3V0bGluZSIsIkNhcmV0VXBGaWxsIiwiQ2FyZXRVcE91dGxpbmUiLCJDYXJldERvd25GaWxsIiwiQ2FyZXREb3duT3V0bGluZSIsIkNoZWNrQ2lyY2xlRmlsbCIsIkNoZWNrQ2lyY2xlT3V0bGluZSIsIkNoZWNrT3V0bGluZSIsIkNsb2NrQ2lyY2xlT3V0bGluZSIsIkNsb3NlQ2lyY2xlT3V0bGluZSIsIkNsb3NlQ2lyY2xlRmlsbCIsIkNsb3NlT3V0bGluZSIsIkRvdWJsZUxlZnRPdXRsaW5lIiwiRG91YmxlUmlnaHRPdXRsaW5lIiwiRG93bk91dGxpbmUiLCJFbGxpcHNpc091dGxpbmUiLCJFeGNsYW1hdGlvbkNpcmNsZUZpbGwiLCJFeGNsYW1hdGlvbkNpcmNsZU91dGxpbmUiLCJFeWVPdXRsaW5lIiwiRmlsZUZpbGwiLCJGaWxlT3V0bGluZSIsIkZpbHRlckZpbGwiLCJJbmZvQ2lyY2xlRmlsbCIsIkluZm9DaXJjbGVPdXRsaW5lIiwiTGVmdE91dGxpbmUiLCJMb2FkaW5nT3V0bGluZSIsIlBhcGVyQ2xpcE91dGxpbmUiLCJRdWVzdGlvbkNpcmNsZU91dGxpbmUiLCJSaWdodE91dGxpbmUiLCJTdGFyRmlsbCIsIlNlYXJjaE91dGxpbmUiLCJVcGxvYWRPdXRsaW5lIiwiVXBPdXRsaW5lIiwidHNsaWJfMS5fX2V4dGVuZHMiLCJpY29ucyIsIkluamVjdGFibGUiLCJSZW5kZXJlckZhY3RvcnkyIiwiRG9tU2FuaXRpemVyIiwiSHR0cEJhY2tlbmQiLCJPcHRpb25hbCIsIkluamVjdCIsIkRPQ1VNRU5UIiwiSWNvblNlcnZpY2UiLCJwbGF0Zm9ybSIsIkRpcmVjdGl2ZSIsIkVsZW1lbnRSZWYiLCJSZW5kZXJlcjIiLCJQbGF0Zm9ybSIsIklucHV0IiwidHNsaWJfMS5fX2RlY29yYXRlIiwiSW5wdXRCb29sZWFuIiwiSWNvbkRpcmVjdGl2ZSIsIk5nTW9kdWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFBQTs7Ozs7Ozs7Ozs7Ozs7SUFjQTtJQUVBLElBQUksYUFBYSxHQUFHLFVBQVMsQ0FBQyxFQUFFLENBQUM7UUFDN0IsYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjO2FBQ2hDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzVFLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUM7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