UNPKG

@ptsecurity/mosaic

Version:
114 lines 21.3 kB
// tslint:disable:no-magic-numbers import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, ViewEncapsulation, NgZone } from '@angular/core'; import { take } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * An internal class that represents the data corresponding to a single calendar cell. * @docs-private */ export class McCalendarCell { constructor(value, displayValue, ariaLabel, enabled, cssClasses) { this.value = value; this.displayValue = displayValue; this.ariaLabel = ariaLabel; this.enabled = enabled; this.cssClasses = cssClasses; } } /** * An internal component used to display calendar data in a table. * @docs-private */ export class McCalendarBody { constructor(elementRef, ngZone) { this.elementRef = elementRef; this.ngZone = ngZone; /** The number of columns in the table. */ this.numCols = 7; /** The cell number of the active cell in the table. */ this.activeCell = 0; /** * The aspect ratio (width / height) to use for the cells in the table. This aspect ratio will be * maintained even as the table resizes. */ this.cellAspectRatio = 1; /** Emits when a new value is selected. */ this.selectedValueChange = new EventEmitter(); } cellClicked(cell) { if (cell.enabled) { this.selectedValueChange.emit(cell.value); } } ngOnChanges(changes) { const columnChanges = changes.numCols; // tslint:disable-next-line:no-this-assignment const { rows, numCols } = this; if (changes.rows || columnChanges) { this.firstRowOffset = rows && rows.length && rows[0].length ? numCols - rows[0].length : 0; } if (changes.cellAspectRatio || columnChanges || !this.cellPadding) { this.cellPadding = `${this.cellAspectRatio * 50 / numCols}%`; } if (columnChanges || !this.cellWidth) { this.cellWidth = `${100 / numCols}%`; } } isActiveCell(rowIndex, colIndex) { let cellNumber = rowIndex * this.numCols + colIndex; // Account for the fact that the first row may not have as many cells. if (rowIndex) { cellNumber -= this.firstRowOffset; } return cellNumber === this.activeCell; } /** Focuses the active cell after the microtask queue is empty. */ focusActiveCell() { this.ngZone.runOutsideAngular(() => { this.ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { const activeCell = this.elementRef.nativeElement.querySelector('.mc-calendar__body_active'); if (activeCell) { activeCell.focus(); } }); }); } } /** @nocollapse */ McCalendarBody.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: McCalendarBody, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ McCalendarBody.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: McCalendarBody, selector: "[mc-calendar-body]", inputs: { label: "label", rows: "rows", todayValue: "todayValue", selectedValue: "selectedValue", labelMinRequiredCells: "labelMinRequiredCells", numCols: "numCols", activeCell: "activeCell", cellAspectRatio: "cellAspectRatio" }, outputs: { selectedValueChange: "selectedValueChange" }, host: { attributes: { "role": "grid", "aria-readonly": "true" }, classAttribute: "mc-calendar__body" }, exportAs: ["mcCalendarBody"], usesOnChanges: true, ngImport: i0, template: "<!--\n If there's not enough space in the first row, create a separate label row. We mark this row as\n aria-hidden because we don't want it to be read out as one of the weeks in the month.\n-->\n<tr *ngIf=\"firstRowOffset < labelMinRequiredCells\">\n <td class=\"mc-calendar__body-label\" [attr.colspan]=\"numCols\">\n {{ label }}\n </td>\n</tr>\n\n<!-- Create the first row separately so we can include a special spacer cell. -->\n<tr *ngFor=\"let row of rows; let rowIndex = index\">\n <!--\n We mark this cell as aria-hidden so it doesn't get read out as one of the days in the week.\n The aspect ratio of the table cells is maintained by setting the top and bottom padding as a\n percentage of the width (a variant of the trick described here:\n https://www.w3schools.com/howto/howto_css_aspect_ratio.asp).\n -->\n <td *ngIf=\"rowIndex === 0 && firstRowOffset\"\n class=\"mc-calendar__body-label\"\n [attr.colspan]=\"firstRowOffset\">\n {{ firstRowOffset >= labelMinRequiredCells ? label : '' }}\n </td>\n <td *ngFor=\"let item of row; let colIndex = index\"\n class=\"mc-calendar__body-cell\"\n [ngClass]=\"item.cssClasses\"\n [tabindex]=\"isActiveCell(rowIndex, colIndex) ? 0 : -1\"\n [class.mc-calendar__body_disabled]=\"!item.enabled\"\n [class.mc-calendar__body_active]=\"isActiveCell(rowIndex, colIndex)\"\n (click)=\"cellClicked(item)\"\n [style.width]=\"cellWidth\"\n [style.paddingTop]=\"cellPadding\"\n [style.paddingBottom]=\"cellPadding\">\n <div class=\"mc-calendar__body-cell-content\"\n [class.mc-selected]=\"selectedValue === item.value\"\n [class.mc-calendar__body-today]=\"todayValue === item.value\">\n {{ item.displayValue }}\n </div>\n </td>\n</tr>\n", styles: [".mc-calendar__body{min-width:calc(7 * $datepicker-body-size-cell-min-size);min-width:calc(7 * var(--mc-datepicker-body-size-cell-min-size, $datepicker-body-size-cell-min-size))}.mc-calendar__body-label{text-align:left;padding:8px 28px 12px 12px;padding:var(--mc-datepicker-body-size-label-paddings, 8px 28px 12px 12px)}.mc-calendar__body-cell{position:relative;height:0;line-height:0;text-align:center;outline:none;cursor:pointer}.mc-calendar__body_disabled{cursor:default}.mc-calendar__body-cell-content{position:absolute;top:5%;top:var(--mc-datepicker-body-size-cell-margin, 5%);left:5%;left:var(--mc-datepicker-body-size-cell-margin, 5%);padding:8px;padding:var(--mc-datepicker-body-size-cell-padding, 8px);display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:90%;height:90%;line-height:1;border-width:1px;border-width:var(--mc-datepicker-body-size-cell-border-width, 1px);border-style:solid}.cdk-high-contrast-active .mc-calendar__body-cell-content{border:none}.cdk-high-contrast-active :host .mc-calendar__body-cell-content{border:none}mc-month-view .mc-calendar__body-cell-content{justify-content:flex-end}mc-multi-year-view .mc-calendar__body-cell-content,mc-year-view .mc-calendar__body-cell-content{justify-content:center}.cdk-high-contrast-active .mc-datepicker__popup:not(:empty),.cdk-high-contrast-active .mc-selected{outline:solid 1px}.cdk-high-contrast-active .mc-calendar__body-today{outline:dotted 1px}.cdk-high-contrast-active :host .mc-datepicker__popup:not(:empty),.cdk-high-contrast-active :host .mc-selected{outline:solid 1px}.cdk-high-contrast-active :host .mc-calendar__body-today{outline:dotted 1px}[dir=rtl] .mc-calendar__body-label{text-align:right}\n"], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: McCalendarBody, decorators: [{ type: Component, args: [{ selector: '[mc-calendar-body]', exportAs: 'mcCalendarBody', templateUrl: 'calendar-body.html', styleUrls: ['calendar-body.scss'], host: { class: 'mc-calendar__body', role: 'grid', 'aria-readonly': 'true' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { label: [{ type: Input }], rows: [{ type: Input }], todayValue: [{ type: Input }], selectedValue: [{ type: Input }], labelMinRequiredCells: [{ type: Input }], numCols: [{ type: Input }], activeCell: [{ type: Input }], cellAspectRatio: [{ type: Input }], selectedValueChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9tb3NhaWMvZGF0ZXBpY2tlci9jYWxlbmRhci1ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3BhY2thZ2VzL21vc2FpYy9kYXRlcGlja2VyL2NhbGVuZGFyLWJvZHkuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxrQ0FBa0M7QUFDbEMsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLGlCQUFpQixFQUNqQixNQUFNLEVBR1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFRdEM7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFDdkIsWUFDVyxLQUFhLEVBQ2IsWUFBb0IsRUFDcEIsU0FBaUIsRUFDakIsT0FBZ0IsRUFDaEIsVUFBcUM7UUFKckMsVUFBSyxHQUFMLEtBQUssQ0FBUTtRQUNiLGlCQUFZLEdBQVosWUFBWSxDQUFRO1FBQ3BCLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFDakIsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNoQixlQUFVLEdBQVYsVUFBVSxDQUEyQjtJQUM3QyxDQUFDO0NBQ1A7QUFHRDs7O0dBR0c7QUFjSCxNQUFNLE9BQU8sY0FBYztJQXdDdkIsWUFBNkIsVUFBbUMsRUFBbUIsTUFBYztRQUFwRSxlQUFVLEdBQVYsVUFBVSxDQUF5QjtRQUFtQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBeEJqRywwQ0FBMEM7UUFDakMsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUVyQix1REFBdUQ7UUFDOUMsZUFBVSxHQUFHLENBQUMsQ0FBQztRQUV4Qjs7O1dBR0c7UUFDTSxvQkFBZSxHQUFHLENBQUMsQ0FBQztRQUU3QiwwQ0FBMEM7UUFDdkIsd0JB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QXFCO3NCQUE3QixLQUFLO2dCQUdHLE9BQU87c0JBQWYsS0FBSztnQkFHRyxVQUFVO3NCQUFsQixLQUFLO2dCQU1HLGVBQWU7c0JBQXZCLEtBQUs7Z0JBR2EsbUJBQW1CO3NCQUFyQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGU6bm8tbWFnaWMtbnVtYmVyc1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSW5wdXQsXG4gICAgT3V0cHV0LFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxuICAgIE5nWm9uZSxcbiAgICBPbkNoYW5nZXMsXG4gICAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cblxuLyoqXG4gKiBFeHRyYSBDU1MgY2xhc3NlcyB0aGF0IGNhbiBiZSBhc3NvY2lhdGVkIHdpdGggYSBjYWxlbmRhciBjZWxsLlxuICovXG5leHBvcnQgdHlwZSBNY0NhbGVuZGFyQ2VsbENzc0NsYXNzZXMgPSBzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxzdHJpbmc+IHwgeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcblxuLyoqXG4gKiBBbiBpbnRlcm5hbCBjbGFzcyB0aGF0IHJlcHJlc2VudHMgdGhlIGRhdGEgY29ycmVzcG9uZGluZyB0byBhIHNpbmdsZSBjYWxlbmRhciBjZWxsLlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgTWNDYWxlbmRhckNlbGwge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgdmFsdWU6IG51bWJlcixcbiAgICAgICAgcHVibGljIGRpc3BsYXlWYWx1ZTogc3RyaW5nLFxuICAgICAgICBwdWJsaWMgYXJpYUxhYmVsOiBzdHJpbmcsXG4gICAgICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuLFxuICAgICAgICBwdWJsaWMgY3NzQ2xhc3Nlcz86IE1jQ2FsZW5kYXJDZWxsQ3NzQ2xhc3Nlc1xuICAgICkge31cbn1cblxuXG4vKipcbiAqIEFuIGludGVybmFsIGNvbXBvbmVudCB1c2VkIHRvIGRpc3BsYXkgY2FsZW5kYXIgZGF0YSBpbiBhIHRhYmxlLlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ1ttYy1jYWxlbmRhci1ib2R5XScsXG4gICAgZXhwb3J0QXM6ICdtY0NhbGVuZGFyQm9keScsXG4gICAgdGVtcGxhdGVVcmw6ICdjYWxlbmRhci1ib2R5Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWydjYWxlbmRhci1ib2R5LnNjc3MnXSxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAnbWMtY2FsZW5kYXJfX2JvZHknLFxuICAgICAgICByb2xlOiAnZ3JpZCcsXG4gICAgICAgICdhcmlhLXJlYWRvbmx5JzogJ3RydWUnXG4gICAgfSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE1jQ2FsZW5kYXJCb2R5IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgICAvKiogVGhlIGxhYmVsIGZvciB0aGUgdGFibGUuIChlLmcuIFwiSmFuIDIwMTdcIikuICovXG4gICAgQElucHV0KCkgbGFiZWw6IHN0cmluZztcblxuICAgIC8qKiBUaGUgY2VsbHMgdG8gZGlzcGxheSBpbiB0aGUgdGFibGUuICovXG4gICAgQElucHV0KCkgcm93czogTWNDYWxlbmRhckNlbGxbXVtdO1xuXG4gICAgLyoqIFRoZSB2YWx1ZSBpbiB0aGUgdGFibGUgdGhhdCBjb3JyZXNwb25kcyB0byB0b2RheS4gKi9cbiAgICBASW5wdXQoKSB0b2RheVZhbHVlOiBudW1iZXI7XG5cbiAgICAvKiogVGhlIHZhbHVlIGluIHRoZSB0YWJsZSB0aGF0IGlzIGN1cnJlbnRseSBzZWxlY3RlZC4gKi9cbiAgICBASW5wdXQoKSBzZWxlY3RlZFZhbHVlOiBudW1iZXI7XG5cbiAgICAvKiogVGhlIG1pbmltdW0gbnVtYmVyIG9mIGZyZWUgY2VsbHMgbmVlZGVkIHRvIGZpdCB0aGUgbGFiZWwgaW4gdGhlIGZpcnN0IHJvdy4gKi9cbiAgICBASW5wdXQoKSBsYWJlbE1pblJlcXVpcmVkQ2VsbHM6IG51bWJlcjtcblxuICAgIC8qKiBUaGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHRhYmxlLiAqL1xuICAgIEBJbnB1dCgpIG51bUNvbHMgPSA3O1xuXG4gICAgLyoqIFRoZSBjZWxsIG51bWJlciBvZiB0aGUgYWN0aXZlIGNlbGwgaW4gdGhlIHRhYmxlLiAqL1xuICAgIEBJbnB1dCgpIGFjdGl2ZUNlbGwgPSAwO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFzcGVjdCByYXRpbyAod2lkdGggLyBoZWlnaHQpIHRvIHVzZSBmb3IgdGhlIGNlbGxzIGluIHRoZSB0YWJsZS4gVGhpcyBhc3BlY3QgcmF0aW8gd2lsbCBiZVxuICAgICAqIG1haW50YWluZWQgZXZlbiBhcyB0aGUgdGFibGUgcmVzaXplcy5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBjZWxsQXNwZWN0UmF0aW8gPSAxO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gYSBuZXcgdmFsdWUgaXMgc2VsZWN0ZWQuICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IHNlbGVjdGVkVmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKiogVGhlIG51bWJlciBvZiBibGFuayBjZWxscyB0byBwdXQgYXQgdGhlIGJlZ2lubmluZyBmb3IgdGhlIGZpcnN0IHJvdy4gKi9cbiAgICBmaXJzdFJvd09mZnNldDogbnVtYmVyO1xuXG4gICAgLyoqIFBhZGRpbmcgZm9yIHRoZSBpbmRpdmlkdWFsIGRhdGUgY2VsbHMuICovXG4gICAgY2VsbFBhZGRpbmc6IHN0cmluZztcblxuICAgIC8qKiBXaWR0aCBvZiBhbiBpbmRpdmlkdWFsIGNlbGwuICovXG4gICAgY2VsbFdpZHRoOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LCBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lKSB7fVxuXG4gICAgY2VsbENsaWNrZWQoY2VsbDogTWNDYWxlbmRhckNlbGwpOiB2b2lkIHtcbiAgICAgICAgaWYgKGNlbGwuZW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFZhbHVlQ2hhbmdlLmVtaXQoY2VsbC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGNvbnN0IGNvbHVtbkNoYW5nZXMgPSBjaGFuZ2VzLm51bUNvbHM7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby10aGlzLWFzc2lnbm1lbnRcbiAgICAgICAgY29uc3QgeyByb3dzLCBudW1Db2xzIH0gPSB0aGlzO1xuXG4gICAgICAgIGlmIChjaGFuZ2VzLnJvd3MgfHwgY29sdW1uQ2hhbmdlcykge1xuICAgICAgICAgICAgdGhpcy5maXJzdFJvd09mZnNldCA9IHJvd3MgJiYgcm93cy5sZW5ndGggJiYgcm93c1swXS5sZW5ndGggPyBudW1Db2xzIC0gcm93c1swXS5sZW5ndGggOiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYW5nZXMuY2VsbEFzcGVjdFJhdGlvIHx8IGNvbHVtbkNoYW5nZXMgfHwgIXRoaXMuY2VsbFBhZGRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuY2VsbFBhZGRpbmcgPSBgJHt0aGlzLmNlbGxBc3BlY3RSYXRpbyAqIDUwIC8gbnVtQ29sc30lYDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb2x1bW5DaGFuZ2VzIHx8ICF0aGlzLmNlbGxXaWR0aCkge1xuICAgICAgICAgICAgdGhpcy5jZWxsV2lkdGggPSBgJHsxMDAgLyBudW1Db2xzfSVgO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaXNBY3RpdmVDZWxsKHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGNlbGxOdW1iZXIgPSByb3dJbmRleCAqIHRoaXMubnVtQ29scyArIGNvbEluZGV4O1xuXG4gICAgICAgIC8vIEFjY291bnQgZm9yIHRoZSBmYWN0IHRoYXQgdGhlIGZpcnN0IHJvdyBtYXkgbm90IGhhdmUgYXMgbWFueSBjZWxscy5cbiAgICAgICAgaWYgKHJvd0luZGV4KSB7XG4gICAgICAgICAgICBjZWxsTnVtYmVyIC09IHRoaXMuZmlyc3RSb3dPZmZzZXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2VsbE51bWJlciA9PT0gdGhpcy5hY3RpdmVDZWxsO1xuICAgIH1cblxuICAgIC8qKiBGb2N1c2VzIHRoZSBhY3RpdmUgY2VsbCBhZnRlciB0aGUgbWljcm90YXNrIHF1ZXVlIGlzIGVtcHR5LiAqL1xuICAgIGZvY3VzQWN0aXZlQ2VsbCgpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5uZ1pvbmUub25TdGFibGUuYXNPYnNlcnZhYmxlKCkucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUNlbGw6IEhUTUxFbGVtZW50IHwgbnVsbCA9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tYy1jYWxlbmRhcl9fYm9keV9hY3RpdmUnKTtcblxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVDZWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUNlbGwuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiPCEtLVxuICBJZiB0aGVyZSdzIG5vdCBlbm91Z2ggc3BhY2UgaW4gdGhlIGZpcnN0IHJvdywgY3JlYXRlIGEgc2VwYXJhdGUgbGFiZWwgcm93LiBXZSBtYXJrIHRoaXMgcm93IGFzXG4gIGFyaWEtaGlkZGVuIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCBpdCB0byBiZSByZWFkIG91dCBhcyBvbmUgb2YgdGhlIHdlZWtzIGluIHRoZSBtb250aC5cbi0tPlxuPHRyICpuZ0lmPVwiZmlyc3RSb3dPZmZzZXQgPCBsYWJlbE1pblJlcXVpcmVkQ2VsbHNcIj5cbiAgICA8dGQgY2xhc3M9XCJtYy1jYWxlbmRhcl9fYm9keS1sYWJlbFwiIFthdHRyLmNvbHNwYW5dPVwibnVtQ29sc1wiPlxuICAgICAgICB7eyBsYWJlbCB9fVxuICAgIDwvdGQ+XG48L3RyPlxuXG48IS0tIENyZWF0ZSB0aGUgZmlyc3Qgcm93IHNlcGFyYXRlbHkgc28gd2UgY2FuIGluY2x1ZGUgYSBzcGVjaWFsIHNwYWNlciBjZWxsLiAtLT5cbjx0ciAqbmdGb3I9XCJsZXQgcm93IG9mIHJvd3M7IGxldCByb3dJbmRleCA9IGluZGV4XCI+XG4gICAgPCEtLVxuICAgICAgV2UgbWFyayB0aGlzIGNlbGwgYXMgYXJpYS1oaWRkZW4gc28gaXQgZG9lc24ndCBnZXQgcmVhZCBvdXQgYXMgb25lIG9mIHRoZSBkYXlzIGluIHRoZSB3ZWVrLlxuICAgICAgVGhlIGFzcGVjdCByYXRpbyBvZiB0aGUgdGFibGUgY2VsbHMgaXMgbWFpbnRhaW5lZCBieSBzZXR0aW5nIHRoZSB0b3AgYW5kIGJvdHRvbSBwYWRkaW5nIGFzIGFcbiAgICAgIHBlcmNlbnRhZ2Ugb2YgdGhlIHdpZHRoIChhIHZhcmlhbnQgb2YgdGhlIHRyaWNrIGRlc2NyaWJlZCBoZXJlOlxuICAgICAgaHR0cHM6Ly93d3cudzNzY2hvb2xzLmNvbS9ob3d0by9ob3d0b19jc3NfYXNwZWN0X3JhdGlvLmFzcCkuXG4gICAgLS0+XG4gICAgPHRkICpuZ0lmPVwicm93SW5kZXggPT09IDAgJiYgZmlyc3RSb3dPZmZzZXRcIlxuICAgICAgICBjbGFzcz1cIm1jLWNhbGVuZGFyX19ib2R5LWxhYmVsXCJcbiAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJmaXJzdFJvd09mZnNldFwiPlxuICAgICAgICB7eyBmaXJzdFJvd09mZnNldCA+PSBsYWJlbE1pblJlcXVpcmVkQ2VsbHMgPyBsYWJlbCA6ICcnIH19XG4gICAgPC90ZD5cbiAgICA8dGQgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygcm93OyBsZXQgY29sSW5kZXggPSBpbmRleFwiXG4gICAgICAgIGNsYXNzPVwibWMtY2FsZW5kYXJfX2JvZHktY2VsbFwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIml0ZW0uY3NzQ2xhc3Nlc1wiXG4gICAgICAgIFt0YWJpbmRleF09XCJpc0FjdGl2ZUNlbGwocm93SW5kZXgsIGNvbEluZGV4KSA/IDAgOiAtMVwiXG4gICAgICAgIFtjbGFzcy5tYy1jYWxlbmRhcl9fYm9keV9kaXNhYmxlZF09XCIhaXRlbS5lbmFibGVkXCJcbiAgICAgICAgW2NsYXNzLm1jLWNhbGVuZGFyX19ib2R5X2FjdGl2ZV09XCJpc0FjdGl2ZUNlbGwocm93SW5kZXgsIGNvbEluZGV4KVwiXG4gICAgICAgIChjbGljayk9XCJjZWxsQ2xpY2tlZChpdGVtKVwiXG4gICAgICAgIFtzdHlsZS53aWR0aF09XCJjZWxsV2lkdGhcIlxuICAgICAgICBbc3R5bGUucGFkZGluZ1RvcF09XCJjZWxsUGFkZGluZ1wiXG4gICAgICAgIFtzdHlsZS5wYWRkaW5nQm90dG9tXT1cImNlbGxQYWRkaW5nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtYy1jYWxlbmRhcl9fYm9keS1jZWxsLWNvbnRlbnRcIlxuICAgICAgICAgICAgIFtjbGFzcy5tYy1zZWxlY3RlZF09XCJzZWxlY3RlZFZhbHVlID09PSBpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICBbY2xhc3MubWMtY2FsZW5kYXJfX2JvZHktdG9kYXldPVwidG9kYXlWYWx1ZSA9PT0gaXRlbS52YWx1ZVwiPlxuICAgICAgICAgICAge3sgaXRlbS5kaXNwbGF5VmFsdWUgfX1cbiAgICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbjwvdHI+XG4iXX0=