ng-devui
Version:
DevUI components based on Angular
194 lines • 40 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, Output, QueryList, Renderer2, } from '@angular/core';
import { CarouselItemComponent } from './carousel-item.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class CarouselComponent {
constructor(el, renderer, cdr) {
this.el = el;
this.renderer = renderer;
this.cdr = cdr;
// 切换箭头的显示方式
this.arrowTrigger = 'hover';
// 是否自动播放
this.autoplay = false;
// 默认自动播放间隔时间
this.autoplaySpeed = 3000;
// 卡片切换动画速度,单位ms
this.transitionSpeed = 500;
// 卡片高度
this.height = '100%';
// 是否显示面板指示器
this.showDots = true;
// 面板指示器位置
this.dotPosition = 'bottom';
// 指示器触发滚动方式
this.dotTrigger = 'click';
// 当前激活面板索引,默认从0开始
this.activeIndex = 0;
// 卡片切换时,返回当前卡片索引,索引从0开始
this.activeIndexChange = new EventEmitter();
this.showArrow = false;
}
ngOnInit() {
this.showArrow = this.arrowTrigger === 'always';
this.itemContainer = this.el.nativeElement.querySelector('.devui-carousel-item-container');
}
ngOnChanges(changes) {
const { arrowTrigger, activeIndex } = changes;
if (arrowTrigger && !arrowTrigger.isFirstChange()) {
this.showArrow = this.arrowTrigger === 'always';
}
if (activeIndex && activeIndex.currentValue !== this.currentIndex && !activeIndex.isFirstChange()) {
this.translatePosition(this.activeIndex);
}
if (!this.autoplay || !this.autoplaySpeed) {
this.clearScheduledTransition();
}
else {
this.autoScheduleTransition();
}
}
// 切换箭头监听事件,用于处理hover方式
arrowMouseEvent(type) {
if (this.arrowTrigger !== 'hover') {
return;
}
if (type === 'enter') {
this.showArrow = true;
}
else {
this.showArrow = false;
}
}
// 向前切换
prev() {
this.goTo(this.activeIndex - 1);
}
// 向后切换
next() {
this.goTo(this.activeIndex + 1);
}
// 指定跳转位置
goTo(index) {
if (index === this.activeIndex) {
return;
}
this.renderer.setStyle(this.itemContainer, 'transition', `left ${this.transitionSpeed}ms ease`);
if (index < 0 && this.activeIndex === 0) {
// 第一个卡片向前切换
this.activeIndex = this.itemCount - 1;
const targetEl = this.el.nativeElement.querySelectorAll('d-carousel-item')[this.activeIndex];
this.adjustPosition(targetEl, true);
this.translatePosition(-1);
this.adjustTransition(targetEl);
}
else if (index >= this.itemCount && this.activeIndex === this.itemCount - 1) {
// 最后一个卡片向后切换
this.activeIndex = 0;
const targetEl = this.el.nativeElement.querySelectorAll('d-carousel-item')[this.activeIndex];
this.adjustPosition(targetEl, false);
this.translatePosition(this.itemCount);
this.adjustTransition(targetEl);
}
else {
const idx = index > this.itemCount - 1 ? this.itemCount - 1 : index;
this.activeIndex = index < 0 ? 0 : idx;
this.translatePosition(this.activeIndex);
}
this.activeIndexChange.emit(this.activeIndex);
this.currentIndex = this.activeIndex;
this.cdr.detectChanges();
this.autoScheduleTransition();
}
// 指示器触发切换函数
switchStep(index, type) {
if (type === this.dotTrigger) {
this.goTo(index);
}
}
// 调整首尾翻页后的动画
adjustTransition(targetEl) {
setTimeout(() => {
this.renderer.removeStyle(this.itemContainer, 'transition');
this.renderer.removeStyle(targetEl, 'transform');
this.translatePosition(this.activeIndex);
}, this.transitionSpeed);
}
// 调整首尾翻动时的位置
adjustPosition(targetEl, firstToLast) {
const wrapperRect = this.el.nativeElement.querySelector('.devui-carousel-item-wrapper').getBoundingClientRect();
this.renderer.setStyle(targetEl, 'transform', `translateX(${(firstToLast ? -this.itemCount : this.itemCount) * wrapperRect.width}px)`);
}
// 翻页位移
translatePosition(size) {
this.renderer.setStyle(this.itemContainer, 'left', `${-size * 100}%`);
}
// 初始化container的宽度
initCarouselWidth() {
this.itemCount = this.items.length;
this.renderer.setStyle(this.itemContainer, 'width', `${this.itemCount * 100}%`);
}
// 自动轮播调度任务
autoScheduleTransition() {
this.clearScheduledTransition();
if (this.autoplay && this.autoplaySpeed) {
this.scheduledId = setTimeout(() => {
this.next();
}, this.autoplaySpeed);
}
}
// 清除自动轮播任务
clearScheduledTransition() {
if (this.scheduledId) {
clearTimeout(this.scheduledId);
this.scheduledId = null;
}
}
ngAfterContentInit() {
this.initCarouselWidth();
this.translatePosition(this.activeIndex);
this.renderer.setStyle(this.itemContainer, 'transition', `left ${this.transitionSpeed}ms ease`);
// contentChildren 变化时,触发重新设置pane
this.items.changes.subscribe((items) => {
if (items.length !== this.itemCount) {
this.activeIndex = 0;
this.initCarouselWidth();
this.translatePosition(this.activeIndex);
}
});
}
ngOnDestroy() {
// 组件销毁时清理掉当前的定时任务
this.clearScheduledTransition();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CarouselComponent, selector: "d-carousel", inputs: { arrowTrigger: "arrowTrigger", autoplay: "autoplay", autoplaySpeed: "autoplaySpeed", transitionSpeed: "transitionSpeed", height: "height", showDots: "showDots", dotPosition: "dotPosition", dotTrigger: "dotTrigger", activeIndex: "activeIndex" }, outputs: { activeIndexChange: "activeIndexChange" }, queries: [{ propertyName: "items", predicate: CarouselItemComponent }], exportAs: ["dCarousel"], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"devui-carousel-container\"\n [style.height]=\"height\"\n (mouseenter)=\"arrowMouseEvent('enter')\"\n (mouseleave)=\"arrowMouseEvent('leave')\"\n>\n <!-- carousel arrow -->\n <div class=\"devui-carousel-arrow\" *ngIf=\"arrowTrigger !== 'never' && showArrow\">\n <button class=\"arrow-left\" (click)=\"prev()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n points=\"10.7071068 12.2928932 9.29289322 13.7071068 3.58578644 8 9.29289322 2.29289322 10.7071068 3.70710678 6.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n <button class=\"arrow-right\" (click)=\"next()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n transform=\"translate(8.146447, 8.000000) scale(-1, 1) translate(-8.146447, -8.000000) \"\n points=\"11.7071068 12.2928932 10.2928932 13.7071068 4.58578644 8 10.2928932 2.29289322 11.7071068 3.70710678 7.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n </div>\n <!-- carousel items -->\n <div class=\"devui-carousel-item-wrapper\">\n <div class=\"devui-carousel-item-container\">\n <ng-content select=\"d-carousel-item\"></ng-content>\n </div>\n </div>\n <!-- carousel dots -->\n <ul class=\"devui-carousel-dots {{ dotPosition }}\" *ngIf=\"items?.length > 1 && showDots\">\n <li\n class=\"dot-item\"\n (click)=\"switchStep(index, 'click')\"\n (mouseenter)=\"switchStep(index, 'hover')\"\n [ngClass]=\"{ active: activeIndex === index }\"\n *ngFor=\"let item of items; let index = index\"\n >\n <span class=\"dot-item-active-progress\" [ngStyle]=\"{ 'transition-duration': transitionSpeed + 'ms' }\"></span>\n </li>\n </ul>\n</div>\n", styles: [".devui-carousel-container{display:block;position:relative}.devui-carousel-container .devui-carousel-arrow{position:absolute;width:100%;top:50%}.devui-carousel-container .devui-carousel-arrow .arrow-left{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;left:10px}.devui-carousel-container .devui-carousel-arrow .arrow-left:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-left svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-arrow .arrow-right{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;right:10px}.devui-carousel-container .devui-carousel-arrow .arrow-right:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-right svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-item-wrapper{position:relative;overflow:hidden;height:100%}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container{display:flex;height:100%;position:relative}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container ::ng-deep d-carousel-item{flex:1;position:relative;height:100%}.devui-carousel-container .devui-carousel-dots{position:absolute;display:flex;justify-content:center;width:100%}.devui-carousel-container .devui-carousel-dots.bottom{bottom:8px}.devui-carousel-container .devui-carousel-dots.top{top:8px}.devui-carousel-container .devui-carousel-dots .dot-item{width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px);margin-right:8px;background:var(--devui-icon-fill, #595959);cursor:pointer}.devui-carousel-container .devui-carousel-dots .dot-item .dot-item-active-progress{width:0;display:inline-block;position:absolute}.devui-carousel-container .devui-carousel-dots .dot-item:hover{background:var(--devui-icon-fill-hover, #191919)}.devui-carousel-container .devui-carousel-dots .dot-item.active{width:24px;background-color:var(--devui-icon-fill, #595959);transition:all var(--devui-animation-duration-fast, .1s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-carousel-container .devui-carousel-dots .dot-item.active .dot-item-active-progress{width:24px;height:6px;background-color:var(--devui-icon-fill-active, #191919);border-radius:var(--devui-border-radius-feedback, 4px);transition-property:width;transition-timing-function:var(--devui-animation-ease-out, cubic-bezier(.16, .75, .5, 1))}.devui-carousel-container .devui-carousel-arrow .arrow-left,.devui-carousel-container .devui-carousel-arrow .arrow-right{transition:background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselComponent, decorators: [{
type: Component,
args: [{ selector: 'd-carousel', exportAs: 'dCarousel', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<div\n class=\"devui-carousel-container\"\n [style.height]=\"height\"\n (mouseenter)=\"arrowMouseEvent('enter')\"\n (mouseleave)=\"arrowMouseEvent('leave')\"\n>\n <!-- carousel arrow -->\n <div class=\"devui-carousel-arrow\" *ngIf=\"arrowTrigger !== 'never' && showArrow\">\n <button class=\"arrow-left\" (click)=\"prev()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n points=\"10.7071068 12.2928932 9.29289322 13.7071068 3.58578644 8 9.29289322 2.29289322 10.7071068 3.70710678 6.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n <button class=\"arrow-right\" (click)=\"next()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n transform=\"translate(8.146447, 8.000000) scale(-1, 1) translate(-8.146447, -8.000000) \"\n points=\"11.7071068 12.2928932 10.2928932 13.7071068 4.58578644 8 10.2928932 2.29289322 11.7071068 3.70710678 7.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n </div>\n <!-- carousel items -->\n <div class=\"devui-carousel-item-wrapper\">\n <div class=\"devui-carousel-item-container\">\n <ng-content select=\"d-carousel-item\"></ng-content>\n </div>\n </div>\n <!-- carousel dots -->\n <ul class=\"devui-carousel-dots {{ dotPosition }}\" *ngIf=\"items?.length > 1 && showDots\">\n <li\n class=\"dot-item\"\n (click)=\"switchStep(index, 'click')\"\n (mouseenter)=\"switchStep(index, 'hover')\"\n [ngClass]=\"{ active: activeIndex === index }\"\n *ngFor=\"let item of items; let index = index\"\n >\n <span class=\"dot-item-active-progress\" [ngStyle]=\"{ 'transition-duration': transitionSpeed + 'ms' }\"></span>\n </li>\n </ul>\n</div>\n", styles: [".devui-carousel-container{display:block;position:relative}.devui-carousel-container .devui-carousel-arrow{position:absolute;width:100%;top:50%}.devui-carousel-container .devui-carousel-arrow .arrow-left{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;left:10px}.devui-carousel-container .devui-carousel-arrow .arrow-left:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-left svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-arrow .arrow-right{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;right:10px}.devui-carousel-container .devui-carousel-arrow .arrow-right:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-right svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-item-wrapper{position:relative;overflow:hidden;height:100%}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container{display:flex;height:100%;position:relative}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container ::ng-deep d-carousel-item{flex:1;position:relative;height:100%}.devui-carousel-container .devui-carousel-dots{position:absolute;display:flex;justify-content:center;width:100%}.devui-carousel-container .devui-carousel-dots.bottom{bottom:8px}.devui-carousel-container .devui-carousel-dots.top{top:8px}.devui-carousel-container .devui-carousel-dots .dot-item{width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px);margin-right:8px;background:var(--devui-icon-fill, #595959);cursor:pointer}.devui-carousel-container .devui-carousel-dots .dot-item .dot-item-active-progress{width:0;display:inline-block;position:absolute}.devui-carousel-container .devui-carousel-dots .dot-item:hover{background:var(--devui-icon-fill-hover, #191919)}.devui-carousel-container .devui-carousel-dots .dot-item.active{width:24px;background-color:var(--devui-icon-fill, #595959);transition:all var(--devui-animation-duration-fast, .1s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-carousel-container .devui-carousel-dots .dot-item.active .dot-item-active-progress{width:24px;height:6px;background-color:var(--devui-icon-fill-active, #191919);border-radius:var(--devui-border-radius-feedback, 4px);transition-property:width;transition-timing-function:var(--devui-animation-ease-out, cubic-bezier(.16, .75, .5, 1))}.devui-carousel-container .devui-carousel-arrow .arrow-left,.devui-carousel-container .devui-carousel-arrow .arrow-right{transition:background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }], propDecorators: { arrowTrigger: [{
type: Input
}], autoplay: [{
type: Input
}], autoplaySpeed: [{
type: Input
}], transitionSpeed: [{
type: Input
}], height: [{
type: Input
}], showDots: [{
type: Input
}], dotPosition: [{
type: Input
}], dotTrigger: [{
type: Input
}], activeIndex: [{
type: Input
}], activeIndexChange: [{
type: Output
}], items: [{
type: ContentChildren,
args: [CarouselItemComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2dWkvY2Fyb3VzZWwvY2Fyb3VzZWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vZGV2dWkvY2Fyb3VzZWwvY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsR0FFVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBYWxFLE1BQU0sT0FBTyxpQkFBaUI7SUFnQzVCLFlBQW9CLEVBQWMsRUFBVSxRQUFtQixFQUFVLEdBQXNCO1FBQTNFLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUEvQi9GLFlBQVk7UUFDSCxpQkFBWSxHQUFpQixPQUFPLENBQUM7UUFDOUMsU0FBUztRQUNBLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDMUIsYUFBYTtRQUNKLGtCQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzlCLGdCQUFnQjtRQUNQLG9CQUFlLEdBQUcsR0FBRyxDQUFDO1FBQy9CLE9BQU87UUFDRSxXQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLFlBQVk7UUFDSCxhQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLFVBQVU7UUFDRCxnQkFBVyxHQUFnQixRQUFRLENBQUM7UUFDN0MsWUFBWTtRQUNILGVBQVUsR0FBZSxPQUFPLENBQUM7UUFDMUMsa0JBQWtCO1FBQ1QsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFDekIsd0JBQXdCO1FBQ2Qsc0JBQWlCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FB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LENBQUMsQ0FBQztnQkFDckIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDVCxrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7SUFDbEMsQ0FBQzsrR0EvS1UsaUJBQWlCO21HQUFqQixpQkFBaUIsMlhBcUJYLHFCQUFxQiwyRUNuRHhDLDZsRUFtREE7OzRGRHJCYSxpQkFBaUI7a0JBUjdCLFNBQVM7K0JBQ0UsWUFBWSxZQUNaLFdBQVcsbUJBR0osdUJBQXVCLENBQUMsTUFBTSx1QkFDMUIsS0FBSzt1SUFJakIsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBQ2lDLEtBQUs7c0JBQTVDLGVBQWU7dUJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlckNvbnRlbnRJbml0LFxyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBDb250ZW50Q2hpbGRyZW4sXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uRGVzdHJveSxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFF1ZXJ5TGlzdCxcclxuICBSZW5kZXJlcjIsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ2Fyb3VzZWxJdGVtQ29tcG9uZW50IH0gZnJvbSAnLi9jYXJvdXNlbC1pdGVtLmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgdHlwZSBBcnJvd1RyaWdnZXIgPSAnaG92ZXInIHwgJ25ldmVyJyB8ICdhbHdheXMnO1xyXG5leHBvcnQgdHlwZSBEb3RUcmlnZ2VyID0gJ2NsaWNrJyB8ICdob3Zlcic7XHJcbmV4cG9ydCB0eXBlIERvdFBvc2l0aW9uID0gJ2JvdHRvbScgfCAndG9wJztcclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkLWNhcm91c2VsJyxcclxuICBleHBvcnRBczogJ2RDYXJvdXNlbCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2Nhcm91c2VsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9jYXJvdXNlbC5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ2Fyb3VzZWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcclxuICAvLyDliIfmjaLnrq3lpLTnmoTmmL7npLrmlrnlvI9cclxuICBASW5wdXQoKSBhcnJvd1RyaWdnZXI6IEFycm93VHJpZ2dlciA9ICdob3Zlcic7XHJcbiAgLy8g5piv5ZCm6Ieq5Yqo5pKt5pS+XHJcbiAgQElucHV0KCkgYXV0b3BsYXkgPSBmYWxzZTtcclxuICAvLyDpu5jorqToh6rliqjmkq3mlL7pl7TpmpTml7bpl7RcclxuICBASW5wdXQoKSBhdXRvcGxheVNwZWVkID0gMzAwMDtcclxuICAvLyDljaHniYfliIfmjaLliqjnlLvpgJ/luqbvvIzljZXkvY1tc1xyXG4gIEBJbnB1dCgpIHRyYW5zaXRpb25TcGVlZCA9IDUwMDtcclxuICAvLyDljaHniYfpq5jluqZcclxuICBASW5wdXQoKSBoZWlnaHQgPSAnMTAwJSc7XHJcbiAgLy8g5piv5ZCm5pi+56S66Z2i5p2/5oyH56S65ZmoXHJcbiAgQElucHV0KCkgc2hvd0RvdHMgPSB0cnVlO1xyXG4gIC8vIOmdouadv+aMh+ekuuWZqOS9jee9rlxyXG4gIEBJbnB1dCgpIGRvdFBvc2l0aW9uOiBEb3RQb3NpdGlvbiA9ICdib3R0b20nO1xyXG4gIC8vIOaMh+ekuuWZqOinpuWPkea7muWKqOaWueW8j1xyXG4gIEBJbnB1dCgpIGRvdFRyaWdnZXI6IERvdFRyaWdnZXIgPSAnY2xpY2snO1xyXG4gIC8vIOW9k+WJjea/gOa0u+mdouadv+e0ouW8le+8jOm7mOiupOS7jjDlvIDlp4tcclxuICBASW5wdXQoKSBhY3RpdmVJbmRleCA9IDA7XHJcbiAgLy8g5Y2h54mH5YiH5o2i5pe277yM6L+U5Zue5b2T5YmN5Y2h54mH57Si5byV77yM57Si5byV5LuOMOW8gOWni1xyXG4gIEBPdXRwdXQoKSBhY3RpdmVJbmRleENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG4gIEBDb250ZW50Q2hpbGRyZW4oQ2Fyb3VzZWxJdGVtQ29tcG9uZW50KSBpdGVtczogUXVlcnlMaXN0PENhcm91c2VsSXRlbUNvbXBvbmVudD47XHJcblxyXG4gIHNob3dBcnJvdyA9IGZhbHNlO1xyXG4gIC8vIOWNoeeJh+WuueWZqFxyXG4gIHByaXZhdGUgaXRlbUNvbnRhaW5lcjtcclxuICAvLyDljaHniYfmlbDph49cclxuICBwcml2YXRlIGl0ZW1Db3VudDtcclxuICAvLyDoh6rliqjosIPluqZpZFxyXG4gIHByaXZhdGUgc2NoZWR1bGVkSWQ7XHJcbiAgLy8g6K6w5b2V5b2T5YmN6aG156CBXHJcbiAgcHJpdmF0ZSBjdXJyZW50SW5kZXg7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZiwgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLCBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5zaG93QXJyb3cgPSB0aGlzLmFycm93VHJpZ2dlciA9PT0gJ2Fsd2F5cyc7XHJcbiAgICB0aGlzLml0ZW1Db250YWluZXIgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmRldnVpLWNhcm91c2VsLWl0ZW0tY29udGFpbmVyJyk7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBjb25zdCB7IGFycm93VHJpZ2dlciwgYWN0aXZlSW5kZXggfSA9IGNoYW5nZXM7XHJcbiAgICBpZiAoYXJyb3dUcmlnZ2VyICYmICFhcnJvd1RyaWdnZXIuaXNGaXJzdENoYW5nZSgpKSB7XHJcbiAgICAgIHRoaXMuc2hvd0Fycm93ID0gdGhpcy5hcnJvd1RyaWdnZXIgPT09ICdhbHdheXMnO1xyXG4gICAgfVxyXG4gICAgaWYgKGFjdGl2ZUluZGV4ICYmIGFjdGl2ZUluZGV4LmN1cnJlbnRWYWx1ZSAhPT0gdGhpcy5jdXJyZW50SW5kZXggJiYgIWFjdGl2ZUluZGV4LmlzRmlyc3RDaGFuZ2UoKSkge1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZVBvc2l0aW9uKHRoaXMuYWN0aXZlSW5kZXgpO1xyXG4gICAgfVxyXG4gICAgaWYgKCF0aGlzLmF1dG9wbGF5IHx8ICF0aGlzLmF1dG9wbGF5U3BlZWQpIHtcclxuICAgICAgdGhpcy5jbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuYXV0b1NjaGVkdWxlVHJhbnNpdGlvbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8g5YiH5o2i566t5aS055uR5ZCs5LqL5Lu277yM55So5LqO5aSE55CGaG92ZXLmlrnlvI9cclxuICBhcnJvd01vdXNlRXZlbnQodHlwZSkge1xyXG4gICAgaWYgKHRoaXMuYXJyb3dUcmlnZ2VyICE9PSAnaG92ZXInKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0eXBlID09PSAnZW50ZXInKSB7XHJcbiAgICAgIHRoaXMuc2hvd0Fycm93ID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2hvd0Fycm93ID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDlkJHliY3liIfmjaJcclxuICBwcmV2KCkge1xyXG4gICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXggLSAxKTtcclxuICB9XHJcblxyXG4gIC8vIOWQkeWQjuWIh+aNolxyXG4gIG5leHQoKSB7XHJcbiAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCArIDEpO1xyXG4gIH1cclxuXHJcbiAgLy8g5oyH5a6a6Lez6L2s5L2N572uXHJcbiAgZ29UbyhpbmRleCkge1xyXG4gICAgaWYgKGluZGV4ID09PSB0aGlzLmFjdGl2ZUluZGV4KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pdGVtQ29udGFpbmVyLCAndHJhbnNpdGlvbicsIGBsZWZ0ICR7dGhpcy50cmFuc2l0aW9uU3BlZWR9bXMgZWFzZWApO1xyXG4gICAgaWYgKGluZGV4IDwgMCAmJiB0aGlzLmFjdGl2ZUluZGV4ID09PSAwKSB7XHJcbiAgICAgIC8vIOesrOS4gOS4quWNoeeJh+WQkeWJjeWIh+aNolxyXG4gICAgICB0aGlzLmFjdGl2ZUluZGV4ID0gdGhpcy5pdGVtQ291bnQgLSAxO1xyXG4gICAgICBjb25zdCB0YXJnZXRFbCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkLWNhcm91c2VsLWl0ZW0nKVt0aGlzLmFjdGl2ZUluZGV4XTtcclxuICAgICAgdGhpcy5hZGp1c3RQb3NpdGlvbih0YXJnZXRFbCwgdHJ1ZSk7XHJcbiAgICAgIHRoaXMudHJhbnNsYXRlUG9zaXRpb24oLTEpO1xyXG4gICAgICB0aGlzLmFkanVzdFRyYW5zaXRpb24odGFyZ2V0RWwpO1xyXG4gICAgfSBlbHNlIGlmIChpbmRleCA+PSB0aGlzLml0ZW1Db3VudCAmJiB0aGlzLmFjdGl2ZUluZGV4ID09PSB0aGlzLml0ZW1Db3VudCAtIDEpIHtcclxuICAgICAgLy8g5pyA5ZCO5LiA5Liq5Y2h54mH5ZCR5ZCO5YiH5o2iXHJcbiAgICAgIHRoaXMuYWN0aXZlSW5kZXggPSAwO1xyXG4gICAgICBjb25zdCB0YXJnZXRFbCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkLWNhcm91c2VsLWl0ZW0nKVt0aGlzLmFjdGl2ZUluZGV4XTtcclxuICAgICAgdGhpcy5hZGp1c3RQb3NpdGlvbih0YXJnZXRFbCwgZmFsc2UpO1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZVBvc2l0aW9uKHRoaXMuaXRlbUNvdW50KTtcclxuICAgICAgdGhpcy5hZGp1c3RUcmFuc2l0aW9uKHRhcmdldEVsKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGlkeCA9IGluZGV4ID4gdGhpcy5pdGVtQ291bnQgLSAxID8gdGhpcy5pdGVtQ291bnQgLSAxIDogaW5kZXg7XHJcbiAgICAgIHRoaXMuYWN0aXZlSW5kZXggPSBpbmRleCA8IDAgPyAwIDogaWR4O1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZVBvc2l0aW9uKHRoaXMuYWN0aXZlSW5kZXgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hY3RpdmVJbmRleENoYW5nZS5lbWl0KHRoaXMuYWN0aXZlSW5kZXgpO1xyXG4gICAgdGhpcy5jdXJyZW50SW5kZXggPSB0aGlzLmFjdGl2ZUluZGV4O1xyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgdGhpcy5hdXRvU2NoZWR1bGVUcmFuc2l0aW9uKCk7XHJcbiAgfVxyXG5cclxuICAvLyDmjIfnpLrlmajop6blj5HliIfmjaLlh73mlbBcclxuICBzd2l0Y2hTdGVwKGluZGV4LCB0eXBlKSB7XHJcbiAgICBpZiAodHlwZSA9PT0gdGhpcy5kb3RUcmlnZ2VyKSB7XHJcbiAgICAgIHRoaXMuZ29UbyhpbmRleCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDosIPmlbTpppblsL7nv7vpobXlkI7nmoTliqjnlLtcclxuICBwcml2YXRlIGFkanVzdFRyYW5zaXRpb24odGFyZ2V0RWwpIHtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMuaXRlbUNvbnRhaW5lciwgJ3RyYW5zaXRpb24nKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVTdHlsZSh0YXJnZXRFbCwgJ3RyYW5zZm9ybScpO1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZVBvc2l0aW9uKHRoaXMuYWN0aXZlSW5kZXgpO1xyXG4gICAgfSwgdGhpcy50cmFuc2l0aW9uU3BlZWQpO1xyXG4gIH1cclxuXHJcbiAgLy8g6LCD5pW06aaW5bC+57+75Yqo5pe255qE5L2N572uXHJcbiAgcHJpdmF0ZSBhZGp1c3RQb3NpdGlvbih0YXJnZXRFbCwgZmlyc3RUb0xhc3Q6IGJvb2xlYW4pIHtcclxuICAgIGNvbnN0IHdyYXBwZXJSZWN0ID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5kZXZ1aS1jYXJvdXNlbC1pdGVtLXdyYXBwZXInKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGFyZ2V0RWwsICd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlWCgkeyhmaXJzdFRvTGFzdCA/IC10aGlzLml0ZW1Db3VudCA6IHRoaXMuaXRlbUNvdW50KSAqIHdyYXBwZXJSZWN0LndpZHRofXB4KWApO1xyXG4gIH1cclxuXHJcbiAgLy8g57+76aG15L2N56e7XHJcbiAgcHJpdmF0ZSB0cmFuc2xhdGVQb3NpdGlvbihzaXplOiBudW1iZXIpIHtcclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pdGVtQ29udGFpbmVyLCAnbGVmdCcsIGAkey1zaXplICogMTAwfSVgKTtcclxuICB9XHJcblxyXG4gIC8vIOWIneWni+WMlmNvbnRhaW5lcueahOWuveW6plxyXG4gIHByaXZhdGUgaW5pdENhcm91c2VsV2lkdGgoKSB7XHJcbiAgICB0aGlzLml0ZW1Db3VudCA9IHRoaXMuaXRlbXMubGVuZ3RoO1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLml0ZW1Db250YWluZXIsICd3aWR0aCcsIGAke3RoaXMuaXRlbUNvdW50ICogMTAwfSVgKTtcclxuICB9XHJcblxyXG4gIC8vIOiHquWKqOi9ruaSreiwg+W6puS7u+WKoVxyXG4gIHByaXZhdGUgYXV0b1NjaGVkdWxlVHJhbnNpdGlvbigpIHtcclxuICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XHJcbiAgICBpZiAodGhpcy5hdXRvcGxheSAmJiB0aGlzLmF1dG9wbGF5U3BlZWQpIHtcclxuICAgICAgdGhpcy5zY2hlZHVsZWRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubmV4dCgpO1xyXG4gICAgICB9LCB0aGlzLmF1dG9wbGF5U3BlZWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8g5riF6Zmk6Ieq5Yqo6L2u5pKt5Lu75YqhXHJcbiAgcHJpdmF0ZSBjbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKSB7XHJcbiAgICBpZiAodGhpcy5zY2hlZHVsZWRJZCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5zY2hlZHVsZWRJZCk7XHJcbiAgICAgIHRoaXMuc2NoZWR1bGVkSWQgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgdGhpcy5pbml0Q2Fyb3VzZWxXaWR0aCgpO1xyXG4gICAgdGhpcy50cmFuc2xhdGVQb3NpdGlvbih0aGlzLmFjdGl2ZUluZGV4KTtcclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pdGVtQ29udGFpbmVyLCAndHJhbnNpdGlvbicsIGBsZWZ0ICR7dGhpcy50cmFuc2l0aW9uU3BlZWR9bXMgZWFzZWApO1xyXG4gICAgLy8gY29udGVudENoaWxkcmVuIOWPmOWMluaXtu+8jOinpuWPkemHjeaWsOiuvue9rnBhbmVcclxuICAgIHRoaXMuaXRlbXMuY2hhbmdlcy5zdWJzY3JpYmUoKGl0ZW1zKSA9PiB7XHJcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggIT09IHRoaXMuaXRlbUNvdW50KSB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVJbmRleCA9IDA7XHJcbiAgICAgICAgdGhpcy5pbml0Q2Fyb3VzZWxXaWR0aCgpO1xyXG4gICAgICAgIHRoaXMudHJhbnNsYXRlUG9zaXRpb24odGhpcy5hY3RpdmVJbmRleCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAvLyDnu4Tku7bplIDmr4Hml7bmuIXnkIbmjonlvZPliY3nmoTlrprml7bku7vliqFcclxuICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXZcbiAgY2xhc3M9XCJkZXZ1aS1jYXJvdXNlbC1jb250YWluZXJcIlxuICBbc3R5bGUuaGVpZ2h0XT1cImhlaWdodFwiXG4gIChtb3VzZWVudGVyKT1cImFycm93TW91c2VFdmVudCgnZW50ZXInKVwiXG4gIChtb3VzZWxlYXZlKT1cImFycm93TW91c2VFdmVudCgnbGVhdmUnKVwiXG4+XG4gIDwhLS0gY2Fyb3VzZWwgYXJyb3cgLS0+XG4gIDxkaXYgY2xhc3M9XCJkZXZ1aS1jYXJvdXNlbC1hcnJvd1wiICpuZ0lmPVwiYXJyb3dUcmlnZ2VyICE9PSAnbmV2ZXInICYmIHNob3dBcnJvd1wiPlxuICAgIDxidXR0b24gY2xhc3M9XCJhcnJvdy1sZWZ0XCIgKGNsaWNrKT1cInByZXYoKVwiPlxuICAgICAgPHN2ZyB3aWR0aD1cIjE4cHhcIiBoZWlnaHQ9XCIxOHB4XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIHZlcnNpb249XCIxLjFcIj5cbiAgICAgICAgPGcgc3Ryb2tlPVwibm9uZVwiIHN0cm9rZS13aWR0aD1cIjFcIiBmaWxsPVwibm9uZVwiIGZpbGwtcnVsZT1cImV2ZW5vZGRcIj5cbiAgICAgICAgICA8cG9seWdvblxuICAgICAgICAgICAgZmlsbD1cIiMyOTMwNDBcIlxuICAgICAgICAgICAgZmlsbC1ydWxlPVwibm9uemVyb1wiXG4gICAgICAgICAgICBwb2ludHM9XCIxMC43MDcxMDY4IDEyLjI5Mjg5MzIgOS4yOTI4OTMyMiAxMy43MDcxMDY4IDMuNTg1Nzg2NDQgOCA5LjI5Mjg5MzIyIDIuMjkyODkzMjIgMTAuNzA3MTA2OCAzLjcwNzEwNjc4IDYuNDE0MjEzNTYgOFwiXG4gICAgICAgICAgPjwvcG9seWdvbj5cbiAgICAgICAgPC9nPlxuICAgICAgPC9zdmc+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImFycm93LXJpZ2h0XCIgKGNsaWNrKT1cIm5leHQoKVwiPlxuICAgICAgPHN2ZyB3aWR0aD1cIjE4cHhcIiBoZWlnaHQ9XCIxOHB4XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIHZlcnNpb249XCIxLjFcIj5cbiAgICAgICAgPGcgc3Ryb2tlPVwibm9uZVwiIHN0cm9rZS13aWR0aD1cIjFcIiBmaWxsPVwibm9uZVwiIGZpbGwtcnVsZT1cImV2ZW5vZGRcIj5cbiAgICAgICAgICA8cG9seWdvblxuICAgICAgICAgICAgZmlsbD1cIiMyOTMwNDBcIlxuICAgICAgICAgICAgZmlsbC1ydWxlPVwibm9uemVyb1wiXG4gICAgICAgICAgICB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoOC4xNDY0NDcsIDguMDAwMDAwKSBzY2FsZSgtMSwgMSkgdHJhbnNsYXRlKC04LjE0NjQ0NywgLTguMDAwMDAwKSBcIlxuICAgICAgICAgICAgcG9pbnRzPVwiMTEuNzA3MTA2OCAxMi4yOTI4OTMyIDEwLjI5Mjg5MzIgMTMuNzA3MTA2OCA0LjU4NTc4NjQ0IDggMTAuMjkyODkzMiAyLjI5Mjg5MzIyIDExLjcwNzEwNjggMy43MDcxMDY3OCA3LjQxNDIxMzU2IDhcIlxuICAgICAgICAgID48L3BvbHlnb24+XG4gICAgICAgIDwvZz5cbiAgICAgIDwvc3ZnPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPCEtLSBjYXJvdXNlbCBpdGVtcyAtLT5cbiAgPGRpdiBjbGFzcz1cImRldnVpLWNhcm91c2VsLWl0ZW0td3JhcHBlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJkZXZ1aS1jYXJvdXNlbC1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiZC1jYXJvdXNlbC1pdGVtXCI+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPCEtLSBjYXJvdXNlbCBkb3RzIC0tPlxuICA8dWwgY2xhc3M9XCJkZXZ1aS1jYXJvdXNlbC1kb3RzIHt7IGRvdFBvc2l0aW9uIH19XCIgKm5nSWY9XCJpdGVtcz8ubGVuZ3RoID4gMSAmJiBzaG93RG90c1wiPlxuICAgIDxsaVxuICAgICAgY2xhc3M9XCJkb3QtaXRlbVwiXG4gICAgICAoY2xpY2spPVwic3dpdGNoU3RlcChpbmRleCwgJ2NsaWNrJylcIlxuICAgICAgKG1vdXNlZW50ZXIpPVwic3dpdGNoU3RlcChpbmRleCwgJ2hvdmVyJylcIlxuICAgICAgW25nQ2xhc3NdPVwieyBhY3RpdmU6IGFjdGl2ZUluZGV4ID09PSBpbmRleCB9XCJcbiAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgPlxuICAgICAgPHNwYW4gY2xhc3M9XCJkb3QtaXRlbS1hY3RpdmUtcHJvZ3Jlc3NcIiBbbmdTdHlsZV09XCJ7ICd0cmFuc2l0aW9uLWR1cmF0aW9uJzogdHJhbnNpdGlvblNwZWVkICsgJ21zJyB9XCI+PC9zcGFuPlxuICAgIDwvbGk+XG4gIDwvdWw+XG48L2Rpdj5cbiJdfQ==