UNPKG

ngx-masonry-layout

Version:
315 lines (314 loc) 31.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, ElementRef, HostListener, Input, Output, EventEmitter } from '@angular/core'; /** * @record */ export function Image() { } /** @type {?} */ Image.prototype.path; /** @type {?} */ Image.prototype.width; /** @type {?} */ Image.prototype.height; /** @type {?|undefined} */ Image.prototype.computedHeight; /** @type {?|undefined} */ Image.prototype.computedWidth; /** @type {?|undefined} */ Image.prototype.margin; ; /** * @record */ export function Images() { } var MasonryLayoutComponent = /** @class */ (function () { function MasonryLayoutComponent(elementRef) { this.elementRef = elementRef; this.GUTTER = 0; this.savedNodeDimensions = []; this.gridState = 'not started'; this.ENABLE_MASONRY = true; this.MAX_HEIGHT = 400; this.events = new EventEmitter(); this.elem = this.elementRef.nativeElement; } Object.defineProperty(MasonryLayoutComponent.prototype, "gutter", { set: /** * @param {?} value * @return {?} */ function (value) { this.GUTTER = value / 2; }, enumerable: true, configurable: true }); Object.defineProperty(MasonryLayoutComponent.prototype, "isMobile", { get: /** * @return {?} */ function () { /** @type {?} */ var check = false; (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; })(navigator.userAgent || navigator.vendor); return check; }, enumerable: true, configurable: true }); ; /** * @param {?} event * @return {?} */ MasonryLayoutComponent.prototype.onWindowResize = /** * @param {?} event * @return {?} */ function (event) { var _this = this; clearTimeout(this.resizeTimer); this.resizeTimer = setTimeout(function () { _this.gridState = 'not started'; _this.buildGrid(); }, 250); }; /** * @return {?} */ MasonryLayoutComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.buildGrid(); }; /** * @return {?} */ MasonryLayoutComponent.prototype.ngOnChanges = /** * @return {?} */ function () { var _this = this; clearTimeout(this.changesTimer); this.changesTimer = setTimeout(function () { _this.gridState = 'not started'; _this.buildGrid(); }, 250); }; /** * @return {?} */ MasonryLayoutComponent.prototype.buildGrid = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var parentWidth = Math.floor(this.elem.parentNode.offsetWidth); /** @type {?} */ var totalRowWidth = 0; /** @type {?} */ var row = { startIndex: 0, endIndex: 0, length: 0, totalWidth: 0 }; if (!this.images || !this.images.length) { return; } this.elem.style.width = parentWidth + 'px'; this.elem.style.display = 'table'; this.images.forEach(function (node, index) { if (row.totalWidth === 0) { row.startIndex = index; row.length = 0; } row.length++; row.totalWidth += _this.getComputedWidth(index); if (row.totalWidth >= parentWidth || _this.isLastChild(index)) { row.endIndex = index; /** @type {?} */ var scaling = row.totalWidth / parentWidth; _this.setColDimensions(scaling, row); row.totalWidth = 0; } }); }; /** * @param {?} scaling * @param {?} row * @return {?} */ MasonryLayoutComponent.prototype.setColDimensions = /** * @param {?} scaling * @param {?} row * @return {?} */ function (scaling, row) { var _this = this; /** @type {?} */ var totalRowWidth = 0; /** @type {?} */ var parentWidth = this.elem.parentNode.offsetWidth; scaling = (scaling < 1) ? 1 : scaling; this.images.forEach(function (node, index) { if (!_this.ENABLE_MASONRY) { node.computedHeight = _this.MAX_HEIGHT + 'px'; node.computedWidth = _this.getComputedWidth(index) + 'px'; node.margin = _this.getNodeMargin(parentWidth); return; } if (index >= row.startIndex && index <= row.endIndex) { /** @type {?} */ var nodeWidth = void 0; // last image if (index === row.endIndex && scaling > 1) { nodeWidth = (100 - totalRowWidth) - ((_this.GUTTER * 2) / parentWidth * 100); node.computedWidth = 'calc(' + nodeWidth + '%)'; if (_this.gridState === 'not started') { _this.gridState = 'pre-building'; setTimeout(function () { _this.buildGrid(); }, 100); } } else { nodeWidth = ((_this.getComputedWidth(index) / scaling) / parentWidth * 100) - ((row.length * (_this.GUTTER * 2)) * (_this.getComputedWidth(index) / scaling) / parentWidth) / parentWidth * 100; node.computedWidth = 'calc(' + nodeWidth + '%)'; totalRowWidth += nodeWidth; totalRowWidth += (_this.GUTTER / parentWidth * 100) * 2; } // last row and last image if (index === row.endIndex && row.length === 1 && _this.isMobile) { nodeWidth = 100 - ((_this.GUTTER * 2) / parentWidth * 100); /** @type {?} */ var height = node.height * (parentWidth * (nodeWidth / 100) / node.width); if (height / 2 < _this.MAX_HEIGHT) { node.computedWidth = 'calc(' + nodeWidth + '%)'; } } node.margin = _this.getNodeMargin(parentWidth); node.computedHeight = node.height * (parentWidth * (nodeWidth / 100) / node.width) + 'px'; } }); }; /** * @param {?} index * @return {?} */ MasonryLayoutComponent.prototype.getComputedWidth = /** * @param {?} index * @return {?} */ function (index) { return this.images[index].width / (this.images[index].height / this.MAX_HEIGHT); }; /** * @param {?} index * @return {?} */ MasonryLayoutComponent.prototype.isLastChild = /** * @param {?} index * @return {?} */ function (index) { return index + 1 === this.images.length; }; /** * @param {?} parentWidth * @return {?} */ MasonryLayoutComponent.prototype.getNodeMargin = /** * @param {?} parentWidth * @return {?} */ function (parentWidth) { return 'calc(' + this.GUTTER / parentWidth * 100 + '%)'; }; /** * @param {?} image * @param {?} i * @return {?} */ MasonryLayoutComponent.prototype.clickOnImage = /** * @param {?} image * @param {?} i * @return {?} */ function (image, i) { this.events.emit({ type: 'click-on-image', image: image, index: i }); }; /** * @param {?} elem * @return {?} */ MasonryLayoutComponent.prototype.onImageLoaded = /** * @param {?} elem * @return {?} */ function (elem) { elem.style.opacity = 1; }; MasonryLayoutComponent.decorators = [ { type: Component, args: [{ selector: 'masonry-layout', template: "<div \n\t[ngClass]=\"CLASS_NAME\"\n\t*ngFor=\"let image of images; let i = index;\"\n [style.width]=\"image.computedWidth\"\n [style.height]=\"image.computedHeight\"\n [style.float]=\"'left'\"\n [style.margin]=\"image.margin\"\n [style.background]=\"'#eeeeee'\"\n [style.lineHeight]=\"0\">\n\t<img \n #imageElem\n [src]=\"image.path\" \n [style.width.%]=\"100\" \n [style.height]=\"'auto'\"\n [style.opacity]=\"0\"\n (click)=\"clickOnImage(image, i)\"\n (load)=\"onImageLoaded(imageElem)\" />\n</div>", },] }, ]; /** @nocollapse */ MasonryLayoutComponent.ctorParameters = function () { return [ { type: ElementRef } ]; }; MasonryLayoutComponent.propDecorators = { images: [{ type: Input, args: ['images',] }], ENABLE_MASONRY: [{ type: Input, args: ['masonry',] }], MAX_HEIGHT: [{ type: Input, args: ['max-height',] }], CLASS_NAME: [{ type: Input, args: ['class-name',] }], gutter: [{ type: Input, args: ['gutter',] }], events: [{ type: Output }], onWindowResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }] }; return MasonryLayoutComponent; }()); export { MasonryLayoutComponent }; if (false) { /** @type {?} */ MasonryLayoutComponent.prototype.GUTTER; /** @type {?} */ MasonryLayoutComponent.prototype.nodes; /** @type {?} */ MasonryLayoutComponent.prototype.elem; /** @type {?} */ MasonryLayoutComponent.prototype.savedNodeDimensions; /** @type {?} */ MasonryLayoutComponent.prototype.observer; /** @type {?} */ MasonryLayoutComponent.prototype.gridState; /** @type {?} */ MasonryLayoutComponent.prototype.resizeTimer; /** @type {?} */ MasonryLayoutComponent.prototype.changesTimer; /** @type {?} */ MasonryLayoutComponent.prototype.images; /** @type {?} */ MasonryLayoutComponent.prototype.ENABLE_MASONRY; /** @type {?} */ MasonryLayoutComponent.prototype.MAX_HEIGHT; /** @type {?} */ MasonryLayoutComponent.prototype.CLASS_NAME; /** @type {?} */ MasonryLayoutComponent.prototype.events; /** @type {?} */ MasonryLayoutComponent.prototype.elementRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzb25yeS1sYXlvdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW1hc29ucnktbGF5b3V0LyIsInNvdXJjZXMiOlsibGliL21hc29ucnktbGF5b3V0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQXFCLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTbkgsQ0FBQzs7Ozs7O0lBc0RFLGdDQUFvQixVQUFzQjtRQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO3NCQTNCekIsQ0FBQzttQ0FHUyxFQUFFO3lCQUVULGFBQWE7OEJBS1csSUFBSTswQkFDTixHQUFHO3NCQVFQLElBQUksWUFBWSxFQUFPO1FBU3pELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7S0FDN0M7SUFmRCxzQkFDSSwwQ0FBTTs7Ozs7UUFEVixVQUNXLEtBQWE7WUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1NBQzNCOzs7T0FBQTtJQUlELHNCQUFJLDRDQUFROzs7O1FBQVo7O1lBQ0ksSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ2xCLENBQUMsVUFBUyxDQUFDLElBQUUsRUFBRSxDQUFBLENBQUMsMFRBQTBULENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFFLHlrREFBeWtELENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxFQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxJQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxK0QsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNoQjs7O09BQUE7SUFBQSxDQUFDOzs7OztJQU9GLCtDQUFjOzs7O0lBRGQsVUFDZSxLQUFLO1FBRHBCLGlCQVFDO1FBTkcsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUvQixJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztZQUMxQixLQUFJLENBQUMsU0FBUyxHQUFHLGFBQWEsQ0FBQztZQUMvQixLQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNYOzs7O0lBRUQseUNBQVE7OztJQUFSO1FBQ0ksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0tBQ3BCOzs7O0lBRUQsNENBQVc7OztJQUFYO1FBQUEsaUJBT0M7UUFORyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWhDLElBQUksQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDO1lBQzNCLEtBQUksQ0FBQyxTQUFTLEdBQUcsYUFBYSxDQUFDO1lBQy9CLEtBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ1g7Ozs7SUFFRCwwQ0FBUzs7O0lBQVQ7UUFBQSxpQkFrQ0M7O1FBakNHLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7O1FBQy9ELElBQUksYUFBYSxHQUFRLENBQUMsQ0FBQzs7UUFDM0IsSUFBSSxHQUFHLEdBQVE7WUFDWCxVQUFVLEVBQUUsQ0FBQztZQUNiLFFBQVEsRUFBRSxDQUFDO1lBQ1gsTUFBTSxFQUFFLENBQUM7WUFDVCxVQUFVLEVBQUUsQ0FBQztTQUNoQixDQUFDO1FBRUYsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQSxDQUFDO1lBQ3JDLE1BQU0sQ0FBQztTQUNWO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFdBQVcsR0FBRSxJQUFJLENBQUM7UUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUVsQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUksRUFBRSxLQUFLO1lBQzVCLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEtBQUssQ0FBQyxDQUFDLENBQUEsQ0FBQztnQkFDdEIsR0FBRyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7Z0JBQ3ZCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2FBQ2xCO1lBRUQsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2IsR0FBRyxDQUFDLFVBQVUsSUFBSSxLQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFL0MsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxXQUFXLElBQUksS0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBLENBQUM7Z0JBQzFELEdBQUcsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDOztnQkFDckIsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsR0FBQyxXQUFXLENBQUM7Z0JBRXpDLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3BDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO2FBQ3RCO1NBQ0osQ0FBQyxDQUFDO0tBQ047Ozs7OztJQUVELGlEQUFnQjs7Ozs7SUFBaEIsVUFBaUIsT0FBZSxFQUFFLEdBQVE7UUFBMUMsaUJBbURDOztRQWxERyxJQUFJLGFBQWEsR0FBUSxDQUFDLENBQUM7O1FBQzNCLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQztRQUNuRCxPQUFPLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBRXRDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQUMsSUFBSSxFQUFFLEtBQUs7WUFDNUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsY0FBYyxDQUFDLENBQUEsQ0FBQztnQkFDdEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztnQkFDN0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDO2dCQUN6RCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzlDLE1BQU0sQ0FBQzthQUNWO1lBRUQsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksS0FBSyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQSxDQUFDOztnQkFDbEQsSUFBSSxTQUFTLFVBQUM7O2dCQUdkLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxHQUFHLENBQUMsUUFBUSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQSxDQUFDO29CQUN2QyxTQUFTLEdBQUcsQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsV0FBVyxHQUFHLEdBQUcsQ0FBQyxDQUFDO29CQUM1RSxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sR0FBQyxTQUFTLEdBQUMsSUFBSSxDQUFDO29CQUU1QyxFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsU0FBUyxLQUFLLGFBQWEsQ0FBQyxDQUFBLENBQUM7d0JBQ2xDLEtBQUksQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDO3dCQUVoQyxVQUFVLENBQUM7NEJBQ1AsS0FBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO3lCQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDO3FCQUNYO2lCQUNKO2dCQUNELElBQUksQ0FBQyxDQUFDO29CQUNGLFNBQVMsR0FBRyxDQUFDLENBQUMsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLFdBQVcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEtBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxXQUFXLENBQUMsR0FBRyxXQUFXLEdBQUcsR0FBRyxDQUFDO29CQUM3TCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sR0FBQyxTQUFTLEdBQUMsSUFBSSxDQUFDO29CQUU1QyxhQUFhLElBQUksU0FBUyxDQUFDO29CQUMzQixhQUFhLElBQUksQ0FBQyxLQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQzFEOztnQkFHRCxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxLQUFJLENBQUMsUUFBUSxDQUFDLENBQUEsQ0FBQztvQkFDaEUsU0FBUyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxXQUFXLEdBQUcsR0FBRyxDQUFDLENBQUM7O29CQUN2RCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUUsV0FBVyxHQUFHLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFFM0UsRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFDLENBQUMsR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLENBQUEsQ0FBQzt3QkFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLEdBQUMsU0FBUyxHQUFDLElBQUksQ0FBQztxQkFDL0M7aUJBQ0o7Z0JBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUM5QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBRSxXQUFXLEdBQUcsQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQzthQUM5RjtTQUNKLENBQUMsQ0FBQztLQUNOOzs7OztJQUVELGlEQUFnQjs7OztJQUFoQixVQUFpQixLQUFhO1FBQzFCLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztLQUNuRjs7Ozs7SUFFRCw0Q0FBVzs7OztJQUFYLFVBQVksS0FBYTtRQUNyQixNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztLQUMzQzs7Ozs7SUFFRCw4Q0FBYTs7OztJQUFiLFVBQWMsV0FBbUI7UUFDN0IsTUFBTSxDQUFDLE9BQU8sR0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsR0FBRyxHQUFHLEdBQUMsSUFBSSxDQUFDO0tBQ3ZEOzs7Ozs7SUFFRCw2Q0FBWTs7Ozs7SUFBWixVQUFhLEtBQVUsRUFBRSxDQUFTO1FBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ2IsSUFBSSxFQUFFLGdCQUFnQjtZQUN0QixLQUFLLEVBQUUsS0FBSztZQUNaLEtBQUssRUFBRSxDQUFDO1NBQ1gsQ0FBQyxDQUFDO0tBQ047Ozs7O0lBRUQsOENBQWE7Ozs7SUFBYixVQUFjLElBQUk7UUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7S0FDMUI7O2dCQTVMSixTQUFTLFNBQUM7b0JBQ1AsUUFBUSxFQUFFLGdCQUFnQjtvQkFDMUIsUUFBUSxFQUFFLHlqQkFpQlA7aUJBQ047Ozs7Z0JBakNtQixVQUFVOzs7eUJBNkN6QixLQUFLLFNBQUMsUUFBUTtpQ0FDZCxLQUFLLFNBQUMsU0FBUzs2QkFDZixLQUFLLFNBQUMsWUFBWTs2QkFDbEIsS0FBSyxTQUFDLFlBQVk7eUJBRWxCLEtBQUssU0FBQyxRQUFRO3lCQUtkLE1BQU07aUNBWU4sWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7aUNBbkU3Qzs7U0FtQ2Esc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPdXRwdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBJbWFnZSB7XG4gICAgcGF0aDogc3RyaW5nOyBcbiAgICB3aWR0aDogbnVtYmVyOyBcbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICBjb21wdXRlZEhlaWdodD86IHN0cmluZztcbiAgICBjb21wdXRlZFdpZHRoPzogc3RyaW5nO1xuICAgIG1hcmdpbj86IHN0cmluZztcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VzIGV4dGVuZHMgQXJyYXk8SW1hZ2U+e31cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdtYXNvbnJ5LWxheW91dCcsIFxuICAgIHRlbXBsYXRlOiBgPGRpdiBcblx0W25nQ2xhc3NdPVwiQ0xBU1NfTkFNRVwiXG5cdCpuZ0Zvcj1cImxldCBpbWFnZSBvZiBpbWFnZXM7IGxldCBpID0gaW5kZXg7XCJcbiAgICBbc3R5bGUud2lkdGhdPVwiaW1hZ2UuY29tcHV0ZWRXaWR0aFwiXG4gICAgW3N0eWxlLmhlaWdodF09XCJpbWFnZS5jb21wdXRlZEhlaWdodFwiXG4gICAgW3N0eWxlLmZsb2F0XT1cIidsZWZ0J1wiXG4gICAgW3N0eWxlLm1hcmdpbl09XCJpbWFnZS5tYXJnaW5cIlxuICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cIicjZWVlZWVlJ1wiXG4gICAgW3N0eWxlLmxpbmVIZWlnaHRdPVwiMFwiPlxuXHQ8aW1nIFxuICAgICAgICAjaW1hZ2VFbGVtXG4gICAgICAgIFtzcmNdPVwiaW1hZ2UucGF0aFwiIFxuICAgICAgICBbc3R5bGUud2lkdGguJV09XCIxMDBcIiBcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCInYXV0bydcIlxuICAgICAgICBbc3R5bGUub3BhY2l0eV09XCIwXCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrT25JbWFnZShpbWFnZSwgaSlcIlxuICAgICAgICAobG9hZCk9XCJvbkltYWdlTG9hZGVkKGltYWdlRWxlbSlcIiAvPlxuPC9kaXY+YCxcbn0pXG5cbmV4cG9ydCBjbGFzcyBNYXNvbnJ5TGF5b3V0Q29tcG9uZW50IHtcbiAgICBHVVRURVI6IG51bWJlciA9IDA7XG4gICAgbm9kZXM6IGFueTtcbiAgICBlbGVtOiBhbnk7XG4gICAgc2F2ZWROb2RlRGltZW5zaW9uczogYW55ID0gW107XG4gICAgb2JzZXJ2ZXI6IGFueTtcbiAgICBncmlkU3RhdGU6IHN0cmluZyA9ICdub3Qgc3RhcnRlZCc7XG4gICAgcmVzaXplVGltZXI6IGFueTtcbiAgICBjaGFuZ2VzVGltZXI6IGFueTtcblxuICAgIEBJbnB1dCgnaW1hZ2VzJykgaW1hZ2VzOiBJbWFnZXM7IFxuICAgIEBJbnB1dCgnbWFzb25yeScpIEVOQUJMRV9NQVNPTlJZOiBib29sZWFuID0gdHJ1ZTsgXG4gICAgQElucHV0KCdtYXgtaGVpZ2h0JykgTUFYX0hFSUdIVDogbnVtYmVyID0gNDAwOyBcbiAgICBASW5wdXQoJ2NsYXNzLW5hbWUnKSBDTEFTU19OQU1FOiBzdHJpbmcgfCB7IFtrZXk6IHN0cmluZ106IGFueTsgfTtcblxuICAgIEBJbnB1dCgnZ3V0dGVyJylcbiAgICBzZXQgZ3V0dGVyKHZhbHVlOiBudW1iZXIpe1xuICAgICAgICB0aGlzLkdVVFRFUiA9IHZhbHVlIC8gMjtcbiAgICB9XG5cbiAgICBAT3V0cHV0KCkgZXZlbnRzOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAgICBcbiAgICBnZXQgaXNNb2JpbGUoKTpib29sZWFuIHtcbiAgICAgICAgdmFyIGNoZWNrID0gZmFsc2U7XG4gICAgICAgIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSkgY2hlY2sgPSB0cnVlO30pKG5hdmlnYXRvci51c2VyQWdlbnR8fG5hdmlnYXRvci52ZW5kb3IpO1xuICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgfTtcbiAgICAgXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKXtcbiAgICAgICAgdGhpcy5lbGVtID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25XaW5kb3dSZXNpemUoZXZlbnQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXplVGltZXIpO1xuXG4gICAgICAgIHRoaXMucmVzaXplVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKCl7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNoYW5nZXNUaW1lcik7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VzVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIGJ1aWxkR3JpZCgpe1xuICAgICAgICBsZXQgcGFyZW50V2lkdGggPSBNYXRoLmZsb29yKHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoKTtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7IFxuICAgICAgICBsZXQgcm93OiBhbnkgPSB7XG4gICAgICAgICAgICBzdGFydEluZGV4OiAwLFxuICAgICAgICAgICAgZW5kSW5kZXg6IDAsXG4gICAgICAgICAgICBsZW5ndGg6IDAsXG4gICAgICAgICAgICB0b3RhbFdpZHRoOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCF0aGlzLmltYWdlcyB8fCAhdGhpcy5pbWFnZXMubGVuZ3RoKXtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWxlbS5zdHlsZS53aWR0aCA9IHBhcmVudFdpZHRoICsncHgnO1xuICAgICAgICB0aGlzLmVsZW0uc3R5bGUuZGlzcGxheSA9ICd0YWJsZSc7XG5cbiAgICAgICAgdGhpcy5pbWFnZXMuZm9yRWFjaCgobm9kZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGlmIChyb3cudG90YWxXaWR0aCA9PT0gMCl7XG4gICAgICAgICAgICAgICAgcm93LnN0YXJ0SW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICByb3cubGVuZ3RoID0gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcm93Lmxlbmd0aCsrO1xuICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggKz0gdGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKHJvdy50b3RhbFdpZHRoID49IHBhcmVudFdpZHRoIHx8IHRoaXMuaXNMYXN0Q2hpbGQoaW5kZXgpKXtcbiAgICAgICAgICAgICAgICByb3cuZW5kSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICBsZXQgc2NhbGluZyA9IHJvdy50b3RhbFdpZHRoL3BhcmVudFdpZHRoO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb2xEaW1lbnNpb25zKHNjYWxpbmcsIHJvdyk7XG4gICAgICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggPSAwOyBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2V0Q29sRGltZW5zaW9ucyhzY2FsaW5nOiBudW1iZXIsIHJvdzogYW55KXtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7XG4gICAgICAgIGxldCBwYXJlbnRXaWR0aCA9IHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoO1xuICAgICAgICBzY2FsaW5nID0gKHNjYWxpbmcgPCAxKSA/IDEgOiBzY2FsaW5nO1xuXG4gICAgICAgIHRoaXMuaW1hZ2VzLmZvckVhY2goKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuRU5BQkxFX01BU09OUlkpe1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRIZWlnaHQgPSB0aGlzLk1BWF9IRUlHSFQgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9IHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUubWFyZ2luID0gdGhpcy5nZXROb2RlTWFyZ2luKHBhcmVudFdpZHRoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+PSByb3cuc3RhcnRJbmRleCAmJiBpbmRleCA8PSByb3cuZW5kSW5kZXgpe1xuICAgICAgICAgICAgICAgIGxldCBub2RlV2lkdGg7XG5cbiAgICAgICAgICAgICAgICAvLyBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgc2NhbGluZyA+IDEpeyBcbiAgICAgICAgICAgICAgICAgICAgbm9kZVdpZHRoID0gKDEwMCAtIHRvdGFsUm93V2lkdGgpIC0gKCh0aGlzLkdVVFRFUiAqIDIpIC8gcGFyZW50V2lkdGggKiAxMDApO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmdyaWRTdGF0ZSA9PT0gJ25vdCBzdGFydGVkJyl7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWRTdGF0ZSA9ICdwcmUtYnVpbGRpbmcnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVXaWR0aCA9ICgodGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KSAvIHNjYWxpbmcpIC8gcGFyZW50V2lkdGggKiAxMDApIC0gKChyb3cubGVuZ3RoICogKHRoaXMuR1VUVEVSICogMikpICogKHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgLyBzY2FsaW5nKSAvIHBhcmVudFdpZHRoKSAvIHBhcmVudFdpZHRoICogMTAwO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdG90YWxSb3dXaWR0aCArPSBub2RlV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHRvdGFsUm93V2lkdGggKz0gKHRoaXMuR1VUVEVSIC8gcGFyZW50V2lkdGggKiAxMDApICogMjsgIFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGxhc3Qgcm93IGFuZCBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgcm93Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzTW9iaWxlKXtcbiAgICAgICAgICAgICAgICBcdG5vZGVXaWR0aCA9IDEwMCAtICgodGhpcy5HVVRURVIgKiAyKSAvIHBhcmVudFdpZHRoICogMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGhlaWdodC8yIDwgdGhpcy5NQVhfSEVJR0hUKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9ICdjYWxjKCcrbm9kZVdpZHRoKyclKSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBub2RlLm1hcmdpbiA9IHRoaXMuZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aCk7XG4gICAgICAgICAgICAgICAgbm9kZS5jb21wdXRlZEhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCkgKyAncHgnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRDb21wdXRlZFdpZHRoKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXNbaW5kZXhdLndpZHRoIC8gKHRoaXMuaW1hZ2VzW2luZGV4XS5oZWlnaHQgLyB0aGlzLk1BWF9IRUlHSFQpO1xuICAgIH1cblxuICAgIGlzTGFzdENoaWxkKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gaW5kZXggKyAxID09PSB0aGlzLmltYWdlcy5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aDogbnVtYmVyKXtcbiAgICAgICAgcmV0dXJuICdjYWxjKCcrdGhpcy5HVVRURVIgLyBwYXJlbnRXaWR0aCAqIDEwMCsnJSknO1xuICAgIH1cblxuICAgIGNsaWNrT25JbWFnZShpbWFnZTogYW55LCBpOiBudW1iZXIpe1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICdjbGljay1vbi1pbWFnZScsXG4gICAgICAgICAgICBpbWFnZTogaW1hZ2UsXG4gICAgICAgICAgICBpbmRleDogaVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkltYWdlTG9hZGVkKGVsZW0pe1xuICAgICAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAxO1xuICAgIH1cbn0iXX0=