@covalent/core
Version:
Core Teradata UI Platform for layouts, icons, custom components and themes. This should be added as a dependency for any project that wants to use layouts, icons and themes for Angular Material.
217 lines • 31.1 kB
JavaScript
import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, Optional, } from '@angular/core';
import { Dir } from '@angular/cdk/bidi';
import { tdCollapseAnimation } from './collapse.animation';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/bidi";
import * as i2 from "@angular/material/icon";
import * as i3 from "@angular/common";
import * as i4 from "@angular/material/tooltip";
export class TdJsonFormatterComponent {
constructor(_changeDetectorRef, _dir) {
this._changeDetectorRef = _changeDetectorRef;
this._dir = _dir;
this._open = false;
this._levelsOpen = 0;
}
/**
* levelsOpen?: number
* Levels opened by default when JS object is formatted and rendered.
*/
set levelsOpen(levelsOpen) {
if (!Number.isInteger(levelsOpen)) {
throw new Error('[levelsOpen] needs to be an integer.');
}
this._levelsOpen = levelsOpen;
this._open = levelsOpen > 0;
}
get levelsOpen() {
return this._levelsOpen;
}
get open() {
return this._open;
}
/**
* key?: string
* Tag to be displayed next to formatted object.
*/
set key(key) {
this._key = key;
}
get key() {
const elipsis = this._key && this._key.length > TdJsonFormatterComponent.KEY_MAX_LENGTH
? '…'
: '';
return this._key
? this._key.substring(0, TdJsonFormatterComponent.KEY_MAX_LENGTH) +
elipsis
: this._key ?? '';
}
/**
* data: any
* JS object to be formatted.
*/
set data(data) {
this._data = data;
this.parseChildren();
}
get data() {
return this._data;
}
get children() {
return this._children ?? [];
}
get isRTL() {
if (this._dir) {
return this._dir.dir === 'rtl';
}
return false;
}
/**
* Refreshes json-formatter and rerenders [data]
*/
refresh() {
this._changeDetectorRef.markForCheck();
}
/**
* Toggles collapse/expanded state of component.
*/
toggle() {
this._open = !this._open;
}
isObject() {
return this.getType(this._data) === 'object';
}
isArray() {
return Array.isArray(this._data);
}
hasChildren() {
return (this._children && this._children.length > 0) ?? false;
}
/**
* Gets parsed value depending on value type.
*/
getValue(value) {
const type = this.getType(value);
if (type === 'undefined' || type === 'null') {
return type;
}
else if (type === 'date') {
value = new Date(value).toString();
}
else if (type === 'string') {
value = '"' + value + '"';
}
else if (type === 'function') {
// Remove content of the function
return (value
.toString()
.replace(/[\r\n]/g, '')
.replace(/\{.*\}/, '') + '{…}');
}
else if (Array.isArray(value)) {
return this.getObjectName() + ' [' + value.length + ']';
}
return value;
}
/**
* Gets type of object.
* returns 'null' if object is null and 'date' if value is object and can be parsed to a date.
*/
getType(object) {
if (typeof object === 'object') {
if (!object) {
return 'null';
}
if (Array.isArray(object)) {
return 'object';
}
const date = new Date(object);
if (Object.prototype.toString.call(date) === '[object Date]' &&
!Number.isNaN(date.getTime())) {
return 'date';
}
}
return typeof object;
}
/**
* Generates string representation depending if its an object or function.
* see: http://stackoverflow.com/a/332429
*/
getObjectName() {
const object = this._data;
if (this.isObject() && !object.constructor) {
return 'Object';
}
const funcNameRegex = /function (.{1,})\(/;
const results = funcNameRegex.exec(object.constructor.toString());
if (results && results.length > 1) {
return results[1];
}
else {
return '';
}
}
/**
* Creates preview of nodes children to render in tooltip depending if its an array or an object.
*/
getPreview() {
let previewData;
let startChar = '{ ';
let endChar = ' }';
if (this.isArray()) {
const previewArray = Object.entries(this._data).slice(0, TdJsonFormatterComponent.PREVIEW_LIMIT) ?? [];
previewData = previewArray.map((obj) => {
return this.getValue(obj);
});
startChar = '[';
endChar = ']';
}
else {
const previewKeys = this._children?.slice(0, TdJsonFormatterComponent.PREVIEW_LIMIT) ?? [];
previewData = previewKeys.map((key) => {
return key + ': ' + this.getValue(this._data[key] ?? undefined);
});
}
const previewString = previewData.join(', ');
const ellipsis = previewData.length >= TdJsonFormatterComponent.PREVIEW_LIMIT ||
previewString.length > TdJsonFormatterComponent.PREVIEW_STRING_MAX_LENGTH
? '…'
: '';
return (startChar +
previewString.substring(0, TdJsonFormatterComponent.PREVIEW_STRING_MAX_LENGTH) +
ellipsis +
endChar);
}
parseChildren() {
if (this.isObject()) {
this._children = Object.keys(this._data ?? {});
}
}
}
/**
* Max length for property names. Any names bigger than this get trunctated.
*/
TdJsonFormatterComponent.KEY_MAX_LENGTH = 30;
/**
* Max length for preview string. Any names bigger than this get trunctated.
*/
TdJsonFormatterComponent.PREVIEW_STRING_MAX_LENGTH = 80;
/**
* Max tooltip preview elements.
*/
TdJsonFormatterComponent.PREVIEW_LIMIT = 5;
TdJsonFormatterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TdJsonFormatterComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.Dir, optional: true }], target: i0.ɵɵFactoryTarget.Component });
TdJsonFormatterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: TdJsonFormatterComponent, selector: "td-json-formatter", inputs: { levelsOpen: "levelsOpen", key: "key", data: "data" }, ngImport: i0, template: "<div class=\"td-json-formatter-wrapper\">\n <a\n class=\"td-key\"\n [class.td-key-node]=\"hasChildren()\"\n [class.td-key-leaf]=\"!hasChildren()\"\n [tabIndex]=\"isObject() ? 0 : -1\"\n (keydown.enter)=\"toggle()\"\n (click)=\"toggle()\"\n >\n <mat-icon class=\"td-node-icon\" *ngIf=\"hasChildren()\">\n {{\n open\n ? 'keyboard_arrow_down'\n : isRTL\n ? 'keyboard_arrow_left'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n <span *ngIf=\"key\" class=\"key\">{{ key }}:</span>\n <span class=\"value\">\n <span\n [class.td-empty]=\"!hasChildren()\"\n *ngIf=\"isObject()\"\n [matTooltip]=\"getPreview()\"\n matTooltipPosition=\"after\"\n >\n <span class=\"td-object-name\">{{ getObjectName() }}</span>\n <span class=\"td-array-length\" *ngIf=\"isArray()\"\n >[{{ data['length'] }}]</span\n >\n </span>\n <span *ngIf=\"!isObject()\" [class]=\"getType(data)\">{{\n getValue(data)\n }}</span>\n </span>\n </a>\n <div class=\"td-object-children\" [@tdCollapse]=\"!(hasChildren() && open)\">\n <ng-template let-key ngFor [ngForOf]=\"children\">\n <td-json-formatter\n [key]=\"key\"\n [data]=\"data[key]\"\n [levelsOpen]=\"levelsOpen - 1\"\n ></td-json-formatter>\n </ng-template>\n </div>\n</div>\n", styles: [":host{display:block}.td-json-formatter-wrapper{padding-top:2px;padding-bottom:2px}.td-json-formatter-wrapper .td-key{box-sizing:border-box;display:flex;flex-direction:row;align-items:flex-start;align-content:center;max-width:100%;justify-content:flex-start}.td-json-formatter-wrapper .td-key.td-key-node:hover{cursor:pointer}.td-json-formatter-wrapper .td-object-children.ng-animating{overflow:hidden}.td-json-formatter-wrapper .td-object-children .td-key,.td-json-formatter-wrapper .td-object-children .td-object-children{padding-left:24px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-key,::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-object-children{padding-right:24px;padding-left:0}.td-json-formatter-wrapper .td-object-children .td-key.td-key-leaf,.td-json-formatter-wrapper .td-object-children .td-object-children.td-key-leaf{padding-left:48px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-key.td-key-leaf,::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-object-children.td-key-leaf{padding-right:48px;padding-left:0}.td-json-formatter-wrapper .value{margin-left:5px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .value{padding-right:5px;padding-left:0}.td-json-formatter-wrapper .value .td-empty{opacity:.5;text-decoration:line-through}.td-json-formatter-wrapper .value .string,.td-json-formatter-wrapper .value .date{word-break:break-word}\n"], components: [{ type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: TdJsonFormatterComponent, selector: "td-json-formatter", inputs: ["levelsOpen", "key", "data"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], animations: [tdCollapseAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TdJsonFormatterComponent, decorators: [{
type: Component,
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'td-json-formatter', animations: [tdCollapseAnimation], template: "<div class=\"td-json-formatter-wrapper\">\n <a\n class=\"td-key\"\n [class.td-key-node]=\"hasChildren()\"\n [class.td-key-leaf]=\"!hasChildren()\"\n [tabIndex]=\"isObject() ? 0 : -1\"\n (keydown.enter)=\"toggle()\"\n (click)=\"toggle()\"\n >\n <mat-icon class=\"td-node-icon\" *ngIf=\"hasChildren()\">\n {{\n open\n ? 'keyboard_arrow_down'\n : isRTL\n ? 'keyboard_arrow_left'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n <span *ngIf=\"key\" class=\"key\">{{ key }}:</span>\n <span class=\"value\">\n <span\n [class.td-empty]=\"!hasChildren()\"\n *ngIf=\"isObject()\"\n [matTooltip]=\"getPreview()\"\n matTooltipPosition=\"after\"\n >\n <span class=\"td-object-name\">{{ getObjectName() }}</span>\n <span class=\"td-array-length\" *ngIf=\"isArray()\"\n >[{{ data['length'] }}]</span\n >\n </span>\n <span *ngIf=\"!isObject()\" [class]=\"getType(data)\">{{\n getValue(data)\n }}</span>\n </span>\n </a>\n <div class=\"td-object-children\" [@tdCollapse]=\"!(hasChildren() && open)\">\n <ng-template let-key ngFor [ngForOf]=\"children\">\n <td-json-formatter\n [key]=\"key\"\n [data]=\"data[key]\"\n [levelsOpen]=\"levelsOpen - 1\"\n ></td-json-formatter>\n </ng-template>\n </div>\n</div>\n", styles: [":host{display:block}.td-json-formatter-wrapper{padding-top:2px;padding-bottom:2px}.td-json-formatter-wrapper .td-key{box-sizing:border-box;display:flex;flex-direction:row;align-items:flex-start;align-content:center;max-width:100%;justify-content:flex-start}.td-json-formatter-wrapper .td-key.td-key-node:hover{cursor:pointer}.td-json-formatter-wrapper .td-object-children.ng-animating{overflow:hidden}.td-json-formatter-wrapper .td-object-children .td-key,.td-json-formatter-wrapper .td-object-children .td-object-children{padding-left:24px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-key,::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-object-children{padding-right:24px;padding-left:0}.td-json-formatter-wrapper .td-object-children .td-key.td-key-leaf,.td-json-formatter-wrapper .td-object-children .td-object-children.td-key-leaf{padding-left:48px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-key.td-key-leaf,::ng-deep [dir=rtl] .td-json-formatter-wrapper .td-object-children .td-object-children.td-key-leaf{padding-right:48px;padding-left:0}.td-json-formatter-wrapper .value{margin-left:5px}::ng-deep [dir=rtl] .td-json-formatter-wrapper .value{padding-right:5px;padding-left:0}.td-json-formatter-wrapper .value .td-empty{opacity:.5;text-decoration:line-through}.td-json-formatter-wrapper .value .string,.td-json-formatter-wrapper .value .date{word-break:break-word}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.Dir, decorators: [{
type: Optional
}] }]; }, propDecorators: { levelsOpen: [{
type: Input
}], key: [{
type: Input
}], data: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1mb3JtYXR0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyL2pzb24tZm9ybWF0dGVyL3NyYy9qc29uLWZvcm1hdHRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvanNvbi1mb3JtYXR0ZXIvc3JjL2pzb24tZm9ybWF0dGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsUUFBUSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7Ozs7O0FBUzNELE1BQU0sT0FBTyx3QkFBd0I7SUFxRm5DLFlBQ1Usa0JBQXFDLEVBQ3pCLElBQVM7UUFEckIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFtQjtRQUN6QixTQUFJLEdBQUosSUFBSSxDQUFLO1FBcEV2QixVQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ2QsZ0JBQVcsR0FBRyxDQUFDLENBQUM7SUFvRXJCLENBQUM7SUFsRUo7OztPQUdHO0lBQ0gsSUFDSSxVQUFVLENBQUMsVUFBa0I7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQ3pEO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7UUFDOUIsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFDRCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJ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LHdCQUF3QixDQUFDLGFBQWE7WUFDNUQsYUFBYSxDQUFDLE1BQU0sR0FBRyx3QkFBd0IsQ0FBQyx5QkFBeUI7WUFDdkUsQ0FBQyxDQUFDLEdBQUc7WUFDTCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1QsT0FBTyxDQUNMLFNBQVM7WUFDVCxhQUFhLENBQUMsU0FBUyxDQUNyQixDQUFDLEVBQ0Qsd0JBQXdCLENBQUMseUJBQXlCLENBQ25EO1lBQ0QsUUFBUTtZQUNSLE9BQU8sQ0FDUixDQUFDO0lBQ0osQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7U0FDaEQ7SUFDSCxDQUFDOztBQW5PRDs7R0FFRztBQUNZLHVDQUFjLEdBQUcsRUFBRyxDQUFBO0FBRW5DOztHQUVHO0FBQ1ksa0RBQXlCLEdBQUcsRUFBRyxDQUFBO0FBRTlDOztHQUVHO0FBQ1ksc0NBQWEsR0FBRyxDQUFFLENBQUE7cUhBZHRCLHdCQUF3Qjt5R0FBeEIsd0JBQXdCLHlIQ2pCckMsazRDQThDQSwra0REN0JhLHdCQUF3Qiw2V0FGdkIsQ0FBQyxtQkFBbUIsQ0FBQzsyRkFFdEIsd0JBQXdCO2tCQVBwQyxTQUFTO3NDQUNTLHVCQUF1QixDQUFDLE1BQU0sWUFDckMsbUJBQW1CLGNBR2pCLENBQUMsbUJBQW1CLENBQUM7OzBCQXlGOUIsUUFBUTs0Q0E1RFAsVUFBVTtzQkFEYixLQUFLO2dCQXFCRixHQUFHO3NCQUROLEtBQUs7Z0JBb0JGLElBQUk7c0JBRFAsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgT3B0aW9uYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGlyIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHsgdGRDb2xsYXBzZUFuaW1hdGlvbiB9IGZyb20gJy4vY29sbGFwc2UuYW5pbWF0aW9uJztcblxuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzZWxlY3RvcjogJ3RkLWpzb24tZm9ybWF0dGVyJyxcbiAgc3R5bGVVcmxzOiBbJy4vanNvbi1mb3JtYXR0ZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2pzb24tZm9ybWF0dGVyLmNvbXBvbmVudC5odG1sJyxcbiAgYW5pbWF0aW9uczogW3RkQ29sbGFwc2VBbmltYXRpb25dLFxufSlcbmV4cG9ydCBjbGFzcyBUZEpzb25Gb3JtYXR0ZXJDb21wb25lbnQge1xuICAvKipcbiAgICogTWF4IGxlbmd0aCBmb3IgcHJvcGVydHkgbmFtZXMuIEFueSBuYW1lcyBiaWdnZXIgdGhhbiB0aGlzIGdldCB0cnVuY3RhdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgS0VZX01BWF9MRU5HVEggPSAzMDtcblxuICAvKipcbiAgICogTWF4IGxlbmd0aCBmb3IgcHJldmlldyBzdHJpbmcuIEFueSBuYW1lcyBiaWdnZXIgdGhhbiB0aGlzIGdldCB0cnVuY3RhdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgUFJFVklFV19TVFJJTkdfTUFYX0xFTkdUSCA9IDgwO1xuXG4gIC8qKlxuICAgKiBNYXggdG9vbHRpcCBwcmV2aWV3IGVsZW1lbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgUFJFVklFV19MSU1JVCA9IDU7XG5cbiAgcHJpdmF0ZSBfa2V5Pzogc3RyaW5nO1xuICBwcml2YXRlIF9kYXRhITogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgcHJpdmF0ZSBfY2hpbGRyZW4/OiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSBfb3BlbiA9IGZhbHNlO1xuICBwcml2YXRlIF9sZXZlbHNPcGVuID0gMDtcblxuICAvKipcbiAgICogbGV2ZWxzT3Blbj86IG51bWJlclxuICAgKiBMZXZlbHMgb3BlbmVkIGJ5IGRlZmF1bHQgd2hlbiBKUyBvYmplY3QgaXMgZm9ybWF0dGVkIGFuZCByZW5kZXJlZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBsZXZlbHNPcGVuKGxldmVsc09wZW46IG51bWJlcikge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihsZXZlbHNPcGVuKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbbGV2ZWxzT3Blbl0gbmVlZHMgdG8gYmUgYW4gaW50ZWdlci4nKTtcbiAgICB9XG4gICAgdGhpcy5fbGV2ZWxzT3BlbiA9IGxldmVsc09wZW47XG4gICAgdGhpcy5fb3BlbiA9IGxldmVsc09wZW4gPiAwO1xuICB9XG4gIGdldCBsZXZlbHNPcGVuKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2xldmVsc09wZW47XG4gIH1cblxuICBnZXQgb3BlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3BlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBrZXk/OiBzdHJpbmdcbiAgICogVGFnIHRvIGJlIGRpc3BsYXllZCBuZXh0IHRvIGZvcm1hdHRlZCBvYmplY3QuXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQga2V5KGtleTogc3RyaW5nKSB7XG4gICAgdGhpcy5fa2V5ID0ga2V5O1xuICB9XG4gIGdldCBrZXkoKTogc3RyaW5nIHtcbiAgICBjb25zdCBlbGlwc2lzOiBzdHJpbmcgPVxuICAgICAgdGhpcy5fa2V5ICYmIHRoaXMuX2tleS5sZW5ndGggPiBUZEpzb25Gb3JtYXR0ZXJDb21wb25lbnQuS0VZX01BWF9MRU5HVEhcbiAgICAgICAgPyAn4oCmJ1xuICAgICAgICA6ICcnO1xuICAgIHJldHVybiB0aGlzLl9rZXlcbiAgICAgID8gdGhpcy5fa2V5LnN1YnN0cmluZygwLCBUZEpzb25Gb3JtYXR0ZXJDb21wb25lbnQuS0VZX01BWF9MRU5HVEgpICtcbiAgICAgICAgICBlbGlwc2lzXG4gICAgICA6IHRoaXMuX2tleSA/PyAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBkYXRhOiBhbnlcbiAgICogSlMgb2JqZWN0IHRvIGJlIGZvcm1hdHRlZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBkYXRhKGRhdGE6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICB0aGlzLnBhcnNlQ2hpbGRyZW4oKTtcbiAgfVxuICBnZXQgZGF0YSgpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgfVxuXG4gIGdldCBjaGlsZHJlbigpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuID8/IFtdO1xuICB9XG5cbiAgZ2V0IGlzUlRMKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9kaXIpIHtcbiAgICAgIHJldHVybiB0aGlzLl9kaXIuZGlyID09PSAncnRsJztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgX2RpcjogRGlyXG4gICkge31cblxuICAvKipcbiAgICogUmVmcmVzaGVzIGpzb24tZm9ybWF0dGVyIGFuZCByZXJlbmRlcnMgW2RhdGFdXG4gICAqL1xuICByZWZyZXNoKCk6IHZvaWQge1xuICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgY29sbGFwc2UvZXhwYW5kZWQgc3RhdGUgb2YgY29tcG9uZW50LlxuICAgKi9cbiAgdG9nZ2xlKCk6IHZvaWQge1xuICAgIHRoaXMuX29wZW4gPSAhdGhpcy5fb3BlbjtcbiAgfVxuXG4gIGlzT2JqZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdldFR5cGUodGhpcy5fZGF0YSkgPT09ICdvYmplY3QnO1xuICB9XG5cbiAgaXNBcnJheSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh0aGlzLl9kYXRhKTtcbiAgfVxuXG4gIGhhc0NoaWxkcmVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5fY2hpbGRyZW4gJiYgdGhpcy5fY2hpbGRyZW4ubGVuZ3RoID4gMCkgPz8gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBwYXJzZWQgdmFsdWUgZGVwZW5kaW5nIG9uIHZhbHVlIHR5cGUuXG4gICAqL1xuICBnZXRWYWx1ZSh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICBjb25zdCB0eXBlOiBzdHJpbmcgPSB0aGlzLmdldFR5cGUodmFsdWUpO1xuICAgIGlmICh0eXBlID09PSAndW5kZWZpbmVkJyB8fCB0eXBlID09PSAnbnVsbCcpIHtcbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2RhdGUnKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKS50b1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gJ1wiJyArIHZhbHVlICsgJ1wiJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIFJlbW92ZSBjb250ZW50IG9mIHRoZSBmdW5jdGlvblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgdmFsdWVcbiAgICAgICAgICAudG9TdHJpbmcoKVxuICAgICAgICAgIC5yZXBsYWNlKC9bXFxyXFxuXS9nLCAnJylcbiAgICAgICAgICAucmVwbGFjZSgvXFx7LipcXH0vLCAnJykgKyAne+KApn0nXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdE5hbWUoKSArICcgWycgKyB2YWx1ZS5sZW5ndGggKyAnXSc7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHR5cGUgb2Ygb2JqZWN0LlxuICAgKiByZXR1cm5zICdudWxsJyBpZiBvYmplY3QgaXMgbnVsbCBhbmQgJ2RhdGUnIGlmIHZhbHVlIGlzIG9iamVjdCBhbmQgY2FuIGJlIHBhcnNlZCB0byBhIGRhdGUuXG4gICAqL1xuICBnZXRUeXBlKG9iamVjdDogYW55KTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgICB9XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBuZXcgRGF0ZShvYmplY3QpO1xuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0ZSkgPT09ICdbb2JqZWN0IERhdGVdJyAmJlxuICAgICAgICAhTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiAnZGF0ZSc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBzdHJpbmcgcmVwcmVzZW50YXRpb24gZGVwZW5kaW5nIGlmIGl0cyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24uXG4gICAqIHNlZTogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzMyNDI5XG4gICAqL1xuICBnZXRPYmplY3ROYW1lKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgb2JqZWN0OiBhbnkgPSB0aGlzLl9kYXRhO1xuICAgIGlmICh0aGlzLmlzT2JqZWN0KCkgJiYgIW9iamVjdC5jb25zdHJ1Y3Rvcikge1xuICAgICAgcmV0dXJuICdPYmplY3QnO1xuICAgIH1cbiAgICBjb25zdCBmdW5jTmFtZVJlZ2V4ID0gL2Z1bmN0aW9uICguezEsfSlcXCgvO1xuICAgIGNvbnN0IHJlc3VsdHMgPSBmdW5jTmFtZVJlZ2V4LmV4ZWMob2JqZWN0LmNvbnN0cnVjdG9yLnRvU3RyaW5nKCkpO1xuICAgIGlmIChyZXN1bHRzICYmIHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHJlc3VsdHNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBwcmV2aWV3IG9mIG5vZGVzIGNoaWxkcmVuIHRvIHJlbmRlciBpbiB0b29sdGlwIGRlcGVuZGluZyBpZiBpdHMgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LlxuICAgKi9cbiAgZ2V0UHJldmlldygpOiBzdHJpbmcge1xuICAgIGxldCBwcmV2aWV3RGF0YTogc3RyaW5nW107XG4gICAgbGV0IHN0YXJ0Q2hhciA9ICd7ICc7XG4gICAgbGV0IGVuZENoYXIgPSAnIH0nO1xuICAgIGlmICh0aGlzLmlzQXJyYXkoKSkge1xuICAgICAgY29uc3QgcHJldmlld0FycmF5OiBhbnlbXSA9XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHRoaXMuX2RhdGEpLnNsaWNlKFxuICAgICAgICAgIDAsXG4gICAgICAgICAgVGRKc29uRm9ybWF0dGVyQ29tcG9uZW50LlBSRVZJRVdfTElNSVRcbiAgICAgICAgKSA/PyBbXTtcbiAgICAgIHByZXZpZXdEYXRhID0gcHJldmlld0FycmF5Lm1hcCgob2JqOiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUob2JqKTtcbiAgICAgIH0pO1xuICAgICAgc3RhcnRDaGFyID0gJ1snO1xuICAgICAgZW5kQ2hhciA9ICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcHJldmlld0tleXM6IHN0cmluZ1tdID1cbiAgICAgICAgdGhpcy5fY2hpbGRyZW4/LnNsaWNlKDAsIFRkSnNvbkZvcm1hdHRlckNvbXBvbmVudC5QUkVWSUVXX0xJTUlUKSA/PyBbXTtcbiAgICAgIHByZXZpZXdEYXRhID0gcHJldmlld0tleXMubWFwKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICByZXR1cm4ga2V5ICsgJzogJyArIHRoaXMuZ2V0VmFsdWUodGhpcy5fZGF0YVtrZXldID8/IHVuZGVmaW5lZCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgcHJldmlld1N0cmluZzogc3RyaW5nID0gcHJldmlld0RhdGEuam9pbignLCAnKTtcbiAgICBjb25zdCBlbGxpcHNpczogc3RyaW5nID1cbiAgICAgIHByZXZpZXdEYXRhLmxlbmd0aCA+PSBUZEpzb25Gb3JtYXR0ZXJDb21wb25lbnQuUFJFVklFV19MSU1JVCB8fFxuICAgICAgcHJldmlld1N0cmluZy5sZW5ndGggPiBUZEpzb25Gb3JtYXR0ZXJDb21wb25lbnQuUFJFVklFV19TVFJJTkdfTUFYX0xFTkdUSFxuICAgICAgICA/ICfigKYnXG4gICAgICAgIDogJyc7XG4gICAgcmV0dXJuIChcbiAgICAgIHN0YXJ0Q2hhciArXG4gICAgICBwcmV2aWV3U3RyaW5nLnN1YnN0cmluZyhcbiAgICAgICAgMCxcbiAgICAgICAgVGRKc29uRm9ybWF0dGVyQ29tcG9uZW50LlBSRVZJRVdfU1RSSU5HX01BWF9MRU5HVEhcbiAgICAgICkgK1xuICAgICAgZWxsaXBzaXMgK1xuICAgICAgZW5kQ2hhclxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ2hpbGRyZW4oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPYmplY3QoKSkge1xuICAgICAgdGhpcy5fY2hpbGRyZW4gPSBPYmplY3Qua2V5cyh0aGlzLl9kYXRhID8/IHt9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJ0ZC1qc29uLWZvcm1hdHRlci13cmFwcGVyXCI+XG4gIDxhXG4gICAgY2xhc3M9XCJ0ZC1rZXlcIlxuICAgIFtjbGFzcy50ZC1rZXktbm9kZV09XCJoYXNDaGlsZHJlbigpXCJcbiAgICBbY2xhc3MudGQta2V5LWxlYWZdPVwiIWhhc0NoaWxkcmVuKClcIlxuICAgIFt0YWJJbmRleF09XCJpc09iamVjdCgpID8gMCA6IC0xXCJcbiAgICAoa2V5ZG93bi5lbnRlcik9XCJ0b2dnbGUoKVwiXG4gICAgKGNsaWNrKT1cInRvZ2dsZSgpXCJcbiAgPlxuICAgIDxtYXQtaWNvbiBjbGFzcz1cInRkLW5vZGUtaWNvblwiICpuZ0lmPVwiaGFzQ2hpbGRyZW4oKVwiPlxuICAgICAge3tcbiAgICAgICAgb3BlblxuICAgICAgICAgID8gJ2tleWJvYXJkX2Fycm93X2Rvd24nXG4gICAgICAgICAgOiBpc1JUTFxuICAgICAgICAgID8gJ2tleWJvYXJkX2Fycm93X2xlZnQnXG4gICAgICAgICAgOiAna2V5Ym9hcmRfYXJyb3dfcmlnaHQnXG4gICAgICB9fVxuICAgIDwvbWF0LWljb24+XG4gICAgPHNwYW4gKm5nSWY9XCJrZXlcIiBjbGFzcz1cImtleVwiPnt7IGtleSB9fTo8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJ2YWx1ZVwiPlxuICAgICAgPHNwYW5cbiAgICAgICAgW2NsYXNzLnRkLWVtcHR5XT1cIiFoYXNDaGlsZHJlbigpXCJcbiAgICAgICAgKm5nSWY9XCJpc09iamVjdCgpXCJcbiAgICAgICAgW21hdFRvb2x0aXBdPVwiZ2V0UHJldmlldygpXCJcbiAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWZ0ZXJcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRkLW9iamVjdC1uYW1lXCI+e3sgZ2V0T2JqZWN0TmFtZSgpIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRkLWFycmF5LWxlbmd0aFwiICpuZ0lmPVwiaXNBcnJheSgpXCJcbiAgICAgICAgICA+W3t7IGRhdGFbJ2xlbmd0aCddIH19XTwvc3BhblxuICAgICAgICA+XG4gICAgICA8L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cIiFpc09iamVjdCgpXCIgW2NsYXNzXT1cImdldFR5cGUoZGF0YSlcIj57e1xuICAgICAgICBnZXRWYWx1ZShkYXRhKVxuICAgICAgfX08L3NwYW4+XG4gICAgPC9zcGFuPlxuICA8L2E+XG4gIDxkaXYgY2xhc3M9XCJ0ZC1vYmplY3QtY2hpbGRyZW5cIiBbQHRkQ29sbGFwc2VdPVwiIShoYXNDaGlsZHJlbigpICYmIG9wZW4pXCI+XG4gICAgPG5nLXRlbXBsYXRlIGxldC1rZXkgbmdGb3IgW25nRm9yT2ZdPVwiY2hpbGRyZW5cIj5cbiAgICAgIDx0ZC1qc29uLWZvcm1hdHRlclxuICAgICAgICBba2V5XT1cImtleVwiXG4gICAgICAgIFtkYXRhXT1cImRhdGFba2V5XVwiXG4gICAgICAgIFtsZXZlbHNPcGVuXT1cImxldmVsc09wZW4gLSAxXCJcbiAgICAgID48L3RkLWpzb24tZm9ybWF0dGVyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=