@firestitch/system 12.5.3 → 12.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/firestitch-system.umd.js +1 -1
- package/bundles/firestitch-system.umd.js.map +1 -1
- package/esm2015/app/modules/query-logs/components/query-log/query-log.component.js +2 -2
- package/fesm2015/firestitch-system.js +1 -1
- package/fesm2015/firestitch-system.js.map +1 -1
- package/package.json +1 -1
|
@@ -48,7 +48,7 @@ export class QueryLogComponent {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
QueryLogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: QueryLogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
51
|
-
QueryLogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\">\n\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n </div>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <fs-label-field>\n <fs-label>Select List Subqueries</fs-label>\n </fs-label-field>\n\n <ng-container *ngFor=\"let selectListSubquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [selectListSubquery.queryBlock] }}\"></ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:bold}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], components: [{ type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode"] }, { type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i3.FsLabelComponent, selector: "fs-label" }, { type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby"], exportAs: ["matTab"] }, { type: i5.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content"] }, { type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "fsFormatTruncate": i9.FsFormatTruncatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
51
|
+
QueryLogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock, selectId: queryBlock.selectId, costInfo: queryBlock.costInfo }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\" let-selectId=\"selectId\" let-costInfo=\"costInfo\">\n <ng-container *ngIf=\"selectId\">\n <h1>Select {{selectId}}</h1>\n </ng-container>\n \n <div class=\"fs-row.gap-large\">\n <ng-container *ngIf=\"costInfo?.queryCost\">\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{costInfo.queryCost}}\n </fs-label-field>\n </ng-container>\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.table\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [ queryBlock ]} }\"></ng-container>\n \n <ng-container *ngIf=\"queryBlock.table.attachedSubqueries\"> \n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.table.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container> \n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n <th>Cost</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n <ng-container *ngIf=\"item.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"item.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n </td>\n <td> \n <fs-popover [template]=\"tableCostPopover\" [data]=\"item.table?.costInfo\">\n {{item.table?.costInfo.prefixCost}}\n </fs-popover>\n <ng-template #tableCostPopover let-data=\"data\">\n <div>Eval Cost: {{data.evalCost}}</div>\n <div>Read Cost: {{data.readCost}}</div>\n <div>Prefix Cost: {{data.prefixCost}}</div>\n <div>Data Read Per Join: {{data.dataReadPerJoin}}</div>\n </ng-template>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n \n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <br>\n <fs-label>Select List Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container>\n<!-- \n <ng-container *ngIf=\"queryBlock.queryBlockattachedSubqueries\">\n <br>\n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n </ng-container>\n </ng-container> -->\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:bold}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], components: [{ type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode"] }, { type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i3.FsLabelComponent, selector: "fs-label" }, { type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby"], exportAs: ["matTab"] }, { type: i5.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content"] }, { type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "fsFormatTruncate": i9.FsFormatTruncatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
52
52
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: QueryLogComponent, decorators: [{
|
|
53
53
|
type: Component,
|
|
54
54
|
args: [{
|
|
@@ -60,4 +60,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
60
60
|
type: Inject,
|
|
61
61
|
args: [MAT_DIALOG_DATA]
|
|
62
62
|
}] }, { type: i1.MatDialog }]; } });
|
|
63
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9xdWVyeS1sb2dzL2NvbXBvbmVudHMvcXVlcnktbG9nL3F1ZXJ5LWxvZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvcXVlcnktbG9ncy9jb21wb25lbnRzL3F1ZXJ5LWxvZy9xdWVyeS1sb2cuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7Ozs7Ozs7Ozs7O0FBUTlDLE1BQU0sT0FBTyxpQkFBaUI7SUFpQjVCLFlBQ21DLEtBQVUsRUFDbkMsT0FBa0I7UUFETyxVQUFLLEdBQUwsS0FBSyxDQUFLO1FBQ25DLFlBQU8sR0FBUCxPQUFPLENBQVc7UUFoQnJCLGdCQUFXLEdBQUc7WUFDbkIsSUFBSSxFQUFFLDRKQUE0SjtZQUNsSyxNQUFNLEVBQUUsb0NBQW9DO1lBQzVDLEtBQUssRUFBRSwySUFBMkk7WUFDbEosTUFBTSxFQUFFLHdKQUF3SjtZQUNoSyxHQUFHLEVBQUUsaU5BQWlOO1lBQ3ROLFFBQVEsRUFBRSxzREFBc0Q7WUFDaEUsS0FBSyxFQUFFLGtSQUFrUjtZQUN6UixXQUFXLEVBQUUsc09BQXNPO1lBQ25QLEtBQUssRUFBRSx5SUFBeUk7WUFDaEosZUFBZSxFQUFFLEVBQUU7WUFDbkIsR0FBRyxFQUFFLG1EQUFtRDtTQUN6RCxDQUFDO1FBTUEsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQ2pDLENBQUM7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ2xDLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO1NBQ2hDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBVyxVQUFVOztRQUNuQixPQUFPLE1BQUEsSUFBSSxDQUFDLE9BQU8sMENBQUUsVUFBVSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxJQUFXLGlCQUFpQjs7UUFDMUIsT0FBTyxNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFFLGlCQUFpQixDQUFDO0lBQzVDLENBQUM7OytHQXhDVSxpQkFBaUIsa0JBa0JsQixlQUFlO21HQWxCZCxpQkFBaUIsb0RDYjlCLGdtTkFtTWM7NEZEdExELGlCQUFpQjtrQkFMN0IsU0FBUzttQkFBQztvQkFDVCxXQUFXLEVBQUUsNEJBQTRCO29CQUN6QyxTQUFTLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQztvQkFDekMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07aUJBQ2hEOzswQkFtQkksTUFBTTsyQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcblxuXG5pbXBvcnQgeyBFeHBsYWluQ29tcG9uZW50IH0gZnJvbSAnLi4vZXhwbGFpbic7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9xdWVyeS1sb2cuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9xdWVyeS1sb2cuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFF1ZXJ5TG9nQ29tcG9uZW50IHtcblxuICBwdWJsaWMgcXVlcnlMb2c7XG4gIHB1YmxpYyBhY2Nlc3NUeXBlcyA9IHtcbiAgICBOVUxMOiAnVGhpcyBhY2Nlc3MgbWV0aG9kIG1lYW5zIE15U1FMIGNhbiByZXNvbHZlIHRoZSBxdWVyeSBkdXJpbmcgdGhlIG9wdGltaXphdGlvbiBwaGFzZSBhbmQgd2lsbCBub3QgZXZlbiBhY2Nlc3MgdGhlIHRhYmxlIG9yIGluZGV4IGR1cmluZyB0aGUgZXhlY3V0aW9uIHN0YWdlLicsXG4gICAgc3lzdGVtOiAnVGhlIHRhYmxlIGlzIGVtcHR5IG9yIGhhcyBvbmUgcm93LicsXG4gICAgY29uc3Q6ICdUaGUgdmFsdWUgb2YgdGhlIGNvbHVtbiBjYW4gYmUgdHJlYXRlZCBhcyBhIGNvbnN0YW50ICh0aGVyZSBpcyBvbmUgcm93IG1hdGNoaW5nIHRoZSBxdWVyeSkuIE5vdGU6IFByaW1hcnkgS2V5IExvb2t1cCwgVW5pcXVlIEluZGV4IExvb2t1cCcsXG4gICAgZXFfcmVmOiAnVGhlIGluZGV4IGlzIGNsdXN0ZXJlZCBhbmQgaXMgYmVpbmcgdXNlZCBieSB0aGUgb3BlcmF0aW9uIChlaXRoZXIgdGhlIGluZGV4IGlzIGEgUFJJTUFSWSBLRVkgb3IgVU5JUVVFIElOREVYIHdpdGggYWxsIGtleSBjb2x1bW5zIGRlZmluZWQgYXMgTk9UIE5VTEwpJyxcbiAgICByZWY6ICdUaGUgaW5kZXhlZCBjb2x1bW4gd2FzIGFjY2Vzc2VkIHVzaW5nIGFuIGVxdWFsaXR5IG9wZXJhdG9yIE5vdGU6IFRoZSByZWZfb3JfbnVsbCBhY2Nlc3MgdHlwZSBpcyBhIHZhcmlhdGlvbiBvbiByZWYuIEl0IG1lYW5zIE15U1FMIG11c3QgZG8gYSBzZWNvbmQgbG9va3VwIHRvIGZpbmQgTlVMTCBlbnRyaWVzIGFmdGVyIGRvaW5nIHRoZSBpbml0aWFsIGxvb2t1cC4nLFxuICAgIGZ1bGx0ZXh0OiAnT3BlcmF0aW9uIChKT0lOKSBpcyB1c2luZyB0aGUgdGFibGXigJlzIGZ1bGx0ZXh0IGluZGV4JyxcbiAgICBpbmRleDogJ1RoZSBlbnRpcmUgaW5kZXggaXMgc2Nhbm5lZCB0byBmaW5kIGEgbWF0Y2ggZm9yIHRoZSBxdWVyeS4gTm90ZTogVGhlIG1haW4gYWR2YW50YWdlIGlzIHRoYXQgdGhpcyBhdm9pZHMgc29ydGluZy4gVGhlIGJpZ2dlc3QgZGlzYWR2YW50YWdlIGlzIHRoZSBjb3N0IG9mIHJlYWRpbmcgYW4gZW50aXJlIHRhYmxlIGluIGluZGV4IG9yZGVyLiBUaGlzIHVzdWFsbHkgbWVhbnMgYWNjZXNzaW5nIHRoZSByb3dzIGluIHJhbmRvbSBvcmRlciwgd2hpY2ggaXMgdmVyeSBleHBlbnNpdmUuJyxcbiAgICBpbmRleF9tZXJnZTogJ1RoaXMgam9pbiB0eXBlIGluZGljYXRlcyB0aGF0IHRoZSBJbmRleCBNZXJnZSBvcHRpbWl6YXRpb24gaXMgdXNlZC4gSW4gdGhpcyBjYXNlLCB0aGUga2V5IGNvbHVtbiBpbiB0aGUgb3V0cHV0IHJvdyBjb250YWlucyBhIGxpc3Qgb2YgaW5kZXhlcyB1c2VkLiBJdCBpbmRpY2F0ZXMgYSBxdWVyeSBjYW4gbWFrZSBsaW1pdGVkIHVzZSBvZiBtdWx0aXBsZSBpbmRleGVzIG9uIGEgc2luZ2xlIHRhYmxlLicsXG4gICAgcmFuZ2U6ICdUaGlzIHR5cGUgcmVwbGFjZXMgZXFfcmVmIGZvciBzb21lIElOIHN1YnF1ZXJpZXMgb2YgdGhlIGZvbGxvd2luZyBmb3JtOiB2YWx1ZSBJTiAoU0VMRUNUIHByaW1hcnlfa2V5IEZST00gc2luZ2xlX3RhYmxlIFdIRVJFIHNvbWVfZXhwciknLFxuICAgIHVuaXF1ZV9zdWJxdWVyeTogJycsXG4gICAgQUxMOiAnTXlTUUwgc2NhbnMgdGhlIGVudGlyZSB0YWJsZSB0byBzYXRpc2Z5IHRoZSBxdWVyeScsXG4gIH07XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHByaXZhdGUgX2RhdGE6IGFueSxcbiAgICBwcml2YXRlIF9kaWFsb2c6IE1hdERpYWxvZyxcbiAgKSB7XG4gICAgdGhpcy5xdWVyeUxvZyA9IF9kYXRhLnF1ZXJ5TG9nO1xuICB9XG5cbiAgcHVibGljIG9wZW5FeHBsYWluKCkge1xuICAgIHRoaXMuX2RpYWxvZy5vcGVuKEV4cGxhaW5Db21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgZXhwbGFpbjogdGhpcy5leHBsYWluIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGV4cGxhaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlMb2cuZXhwbGFpbjtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgcXVlcnlCbG9jaygpIHtcbiAgICByZXR1cm4gdGhpcy5leHBsYWluPy5xdWVyeUJsb2NrO1xuICB9XG5cbiAgcHVibGljIGdldCBvcmRlcmluZ09wZXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeUJsb2NrPy5vcmRlcmluZ09wZXJhdGlvbjtcbiAgfVxufVxuIiwiPGZzLWRpYWxvZz5cbiAgPGgxIG1hdC1kaWFsb2ctdGl0bGU+UXVlcnkgTG9nPC9oMT5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1sYXJnZVwiPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+RHVyYXRpb248L2ZzLWxhYmVsPlxuICAgICAgICB7e3F1ZXJ5TG9nLmR1cmF0aW9ufX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPk9wdGltaXplZDwvZnMtbGFiZWw+XG4gICAgICAgIHt7cXVlcnlMb2cub3B0aW1pemVkID8gJ1llcycgOiAnTm8nfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlF1ZXJ5IENvc3Q8L2ZzLWxhYmVsPlxuICAgICAgICB7e3F1ZXJ5TG9nLnF1ZXJ5Q29zdH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuXG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5SYXcgRXhwbGFpbjwvZnMtbGFiZWw+XG4gICAgICAgIDxhIChjbGljayk9XCJvcGVuRXhwbGFpbigpXCI+VmlldzwvYT5cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlVSTDwvZnMtbGFiZWw+XG4gICAgICAgIHt7cXVlcnlMb2cucGF0aCB8IGZzRm9ybWF0VHJ1bmNhdGU6IDUwfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgIDxtYXQtdGFiIGxhYmVsPVwiUXVlcnlcIj5cbiAgICAgICAgPGZzLWNsaXBib2FyZC1idXR0b25cbiAgICAgICAgICBbY29udGVudF09XCJxdWVyeUxvZy5wcmV0dHlRdWVyeVwiPlxuICAgICAgICA8L2ZzLWNsaXBib2FyZC1idXR0b24+XG4gICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJxdWVyeUxvZy5wcmV0dHlRdWVyeVwiIGNsYXNzPVwicXVlcnlcIj48L2Rpdj5cbiAgICAgIDwvbWF0LXRhYj5cbiAgICAgIFxuICAgICAgPG1hdC10YWIgbGFiZWw9XCJFeHBsYWluXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwibmVzdGVkTG9vcFwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHF1ZXJ5QmxvY2s6IHF1ZXJ5QmxvY2sgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9tYXQtdGFiPlxuICAgIDwvbWF0LXRhYi1ncm91cD5cblxuICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cInVuZGVmaW5lZFwiPlxuICAgICAgRG9uZVxuICAgIDwvYnV0dG9uPlxuICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbjwvZnMtZGlhbG9nPlxuXG48bmctdGVtcGxhdGUgI25lc3RlZExvb3AgbGV0LXF1ZXJ5QmxvY2s9XCJxdWVyeUJsb2NrXCI+XG5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay5uZXN0ZWRMb29wXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwiZnMtbGlzdC10YWJsZSBzdHlsZS1saW5lXCI+XG4gICAgICAgPHRoZWFkPlxuICAgICAgICAgPHRyPlxuICAgICAgICAgICA8dGg+VGFibGU8L3RoPlxuICAgICAgICAgICA8dGg+VHlwZTwvdGg+XG4gICAgICAgICAgIDx0aD5LZXlzPC90aD5cbiAgICAgICAgICAgPHRoPlJlZjwvdGg+XG4gICAgICAgICAgIDx0aD5Sb3dzPC90aD5cbiAgICAgICAgICAgPHRoPkZpbHRlcmVkPC90aD5cbiAgICAgICAgICAgPHRoPkV4dHJhPC90aD5cbiAgICAgICAgIDwvdHI+XG4gICAgICAgPC90aGVhZD5cbiAgICAgICA8dGJvZHk+XG4gICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHF1ZXJ5QmxvY2submVzdGVkTG9vcDsgbGV0IGluZGV4ID0gaW5kZXhcIj5cbiAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIHt7aXRlbS50YWJsZS50YWJsZU5hbWV9fVxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgPGZzLXBvcG92ZXIgW3RlbXBsYXRlXT1cImFjY2Vzc1R5cGVQb3BvdmVyXCIgW2RhdGFdPVwiaXRlbS50YWJsZS5hY2Nlc3NUeXBlXCI+XG4gICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWNjZXNzLXR5cGVcIiBbbmdDbGFzc109XCJpdGVtLnRhYmxlLmFjY2Vzc1R5cGVcIj57e2l0ZW0udGFibGUuYWNjZXNzVHlwZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgPC9mcy1wb3BvdmVyPiAgICAgICAgICAgIFxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgPGZzLXBvcG92ZXIgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgW3RlbXBsYXRlXT1cImtleXNQb3BvdmVyXCJcbiAgICAgICAgICAgICAgICAgICBbbWF4V2lkdGhdPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgW2RhdGFdPVwieyBwb3NzaWJsZUtleXM6IGl0ZW0udGFibGUucG9zc2libGVLZXlzLCBrZXk6IGl0ZW0udGFibGUua2V5IH1cIj5cbiAgICAgICAgICAgICAgICAge3tpdGVtLnRhYmxlLmtleX19XG4gICAgICAgICAgICAgICA8L2ZzLXBvcG92ZXI+XG4gICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtZGVsaW1pdFwiPlxuICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByZWYgb2YgaXRlbS50YWJsZS5yZWZcIj5cbiAgICAgICAgICAgICAgICAgICA8c3Bhbj57e3JlZn19PC9zcGFuPlxuICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAge3tpdGVtLnRhYmxlLnJvd3NFeGFtaW5lZFBlclNjYW59fVxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAge3tpdGVtLnRhYmxlLmZpbHRlcmVkfX1cbiAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1kZWxpbWl0XCI+XG4gICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnRhYmxlLmluZGV4Q29uZGl0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICA8ZnMtcG9wb3ZlciBcbiAgICAgICAgICAgICAgICAgICAgICAgICBbdGVtcGxhdGVdPVwidXNpbmdJbmRleENvbmRpdGlvblwiIFxuICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJpdGVtLnRhYmxlLmluZGV4Q29uZGl0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgIFVzaW5nIEluZGV4IENvbmRpdGlvblxuICAgICAgICAgICAgICAgICAgICAgPC9mcy1wb3BvdmVyPlxuICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnRhYmxlLmF0dGFjaGVkQ29uZGl0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICA8ZnMtcG9wb3ZlciBcbiAgICAgICAgICAgICAgICAgICAgICAgICBbdGVtcGxhdGVdPVwidXNpbmdXaGVyZVwiIFxuICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJpdGVtLnRhYmxlLmF0dGFjaGVkQ29uZGl0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgIFVzaW5nIFdoZXJlXG4gICAgICAgICAgICAgICAgICAgICA8L2ZzLXBvcG92ZXI+XG4gICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udGFibGUudXNpbmdJbmRleFwiPlxuICAgICAgICAgICAgICAgICAgIDxzcGFuPlVzaW5nIEluZGV4PC9zcGFuPlxuICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgPC90cj5cbiAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgIDwvdGJvZHk+XG4gICAgIDwvdGFibGU+XG4gICAgIDxicj5cbiAgIDwvbmctY29udGFpbmVyPiAgXG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2sub3JkZXJpbmdPcGVyYXRpb25cIj5cbiAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWw+T3JkZXJpbmcgT3BlcmF0aW9uPC9mcy1sYWJlbD5cbiAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwicXVlcnlCbG9ja0NyaXRpY2FsXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogcXVlcnlCbG9jay5vcmRlcmluZ09wZXJhdGlvbiB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5lc3RlZExvb3BcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBxdWVyeUJsb2NrLm9yZGVyaW5nT3BlcmF0aW9uIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2suZ3JvdXBpbmdPcGVyYXRpb25cIj5cbiAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWw+R3JvdXBpbmcgT3BlcmF0aW9uPC9mcy1sYWJlbD5cbiAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwicXVlcnlCbG9ja0NyaXRpY2FsXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogcXVlcnlCbG9jay5ncm91cGluZ09wZXJhdGlvbiB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5lc3RlZExvb3BcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBxdWVyeUJsb2NrLmdyb3VwaW5nT3BlcmF0aW9uIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2suc2VsZWN0TGlzdFN1YnF1ZXJpZXNcIj5cbiAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWw+U2VsZWN0IExpc3QgU3VicXVlcmllczwvZnMtbGFiZWw+XG4gICAgPC9mcy1sYWJlbC1maWVsZD5cblxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHNlbGVjdExpc3RTdWJxdWVyeSBvZiBxdWVyeUJsb2NrLnNlbGVjdExpc3RTdWJxdWVyaWVzXCI+XG4gICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5lc3RlZExvb3BcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiB7IG5lc3RlZExvb3A6IFtzZWxlY3RMaXN0U3VicXVlcnkucXVlcnlCbG9ja10gfX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2tleXNQb3BvdmVyIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8ZGl2IGNsYXNzPVwiZnMtZGVsaW1pdFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHBvc3NpYmxlS2V5IG9mIGRhdGEucG9zc2libGVLZXlzXCI+XG4gICAgICA8c3BhbiBbbmdDbGFzc109XCJ7ICdxdWVyeS1sb2ctdXNlZC1rZXknOiBwb3NzaWJsZUtleSA9PT0gZGF0YS5rZXkgfVwiPnt7cG9zc2libGVLZXl9fTwvc3Bhbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3VzaW5nV2hlcmUgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIHt7ZGF0YX19XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3VzaW5nSW5kZXhDb25kaXRpb24gbGV0LWRhdGE9XCJkYXRhXCI+XG4gIHt7ZGF0YX19XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2FjY2Vzc1R5cGVQb3BvdmVyIGxldC1kYXRhPVwiZGF0YVwiPlxuICB7e2FjY2Vzc1R5cGVzW2RhdGFdfX1cbjwvbmctdGVtcGxhdGU+XG5cblxuPG5nLXRlbXBsYXRlICNxdWVyeUJsb2NrQ3JpdGljYWwgbGV0LXF1ZXJ5QmxvY2s9XCJxdWVyeUJsb2NrXCI+XG4gIDxkaXYgY2xhc3M9XCJmcy1kZWxpbWl0XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2sudXNpbmdGaWxlc29ydFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcml0aWNhbFwiPlVzaW5nIEZpbGUgU29ydDwvc3Bhbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICBcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay51c2luZ1RlbXBvcmFyeVRhYmxlXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cImNyaXRpY2FsXCI+VGVtcG9yYXJ5IFRhYmxlPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+Il19
|
|
63
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9xdWVyeS1sb2dzL2NvbXBvbmVudHMvcXVlcnktbG9nL3F1ZXJ5LWxvZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvcXVlcnktbG9ncy9jb21wb25lbnRzL3F1ZXJ5LWxvZy9xdWVyeS1sb2cuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7Ozs7Ozs7Ozs7O0FBUTlDLE1BQU0sT0FBTyxpQkFBaUI7SUFpQjVCLFlBQ21DLEtBQVUsRUFDbkMsT0FBa0I7UUFETyxVQUFLLEdBQUwsS0FBSyxDQUFLO1FBQ25DLFlBQU8sR0FBUCxPQUFPLENBQVc7UUFoQnJCLGdCQUFXLEdBQUc7WUFDbkIsSUFBSSxFQUFFLDRKQUE0SjtZQUNsSyxNQUFNLEVBQUUsb0NBQW9DO1lBQzVDLEtBQUssRUFBRSwySUFBMkk7WUFDbEosTUFBTSxFQUFFLHdKQUF3SjtZQUNoSyxHQUFHLEVBQUUsaU5BQWlOO1lBQ3ROLFFBQVEsRUFBRSxzREFBc0Q7WUFDaEUsS0FBSyxFQUFFLGtSQUFrUjtZQUN6UixXQUFXLEVBQUUsc09BQXNPO1lBQ25QLEtBQUssRUFBRSx5SUFBeUk7WUFDaEosZUFBZSxFQUFFLEVBQUU7WUFDbkIsR0FBRyxFQUFFLG1EQUFtRDtTQUN6RCxDQUFDO1FBTUEsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQ2pDLENBQUM7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ2xDLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO1NBQ2hDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBVyxVQUFVOztRQUNuQixPQUFPLE1BQUEsSUFBSSxDQUFDLE9BQU8sMENBQUUsVUFBVSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxJQUFXLGlCQUFpQjs7UUFDMUIsT0FBTyxNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFFLGlCQUFpQixDQUFDO0lBQzVDLENBQUM7OytHQXhDVSxpQkFBaUIsa0JBa0JsQixlQUFlO21HQWxCZCxpQkFBaUIsb0RDYjlCLGlsVEEwUGM7NEZEN09ELGlCQUFpQjtrQkFMN0IsU0FBUzttQkFBQztvQkFDVCxXQUFXLEVBQUUsNEJBQTRCO29CQUN6QyxTQUFTLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQztvQkFDekMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07aUJBQ2hEOzswQkFtQkksTUFBTTsyQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcblxuXG5pbXBvcnQgeyBFeHBsYWluQ29tcG9uZW50IH0gZnJvbSAnLi4vZXhwbGFpbic7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9xdWVyeS1sb2cuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9xdWVyeS1sb2cuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFF1ZXJ5TG9nQ29tcG9uZW50IHtcblxuICBwdWJsaWMgcXVlcnlMb2c7XG4gIHB1YmxpYyBhY2Nlc3NUeXBlcyA9IHtcbiAgICBOVUxMOiAnVGhpcyBhY2Nlc3MgbWV0aG9kIG1lYW5zIE15U1FMIGNhbiByZXNvbHZlIHRoZSBxdWVyeSBkdXJpbmcgdGhlIG9wdGltaXphdGlvbiBwaGFzZSBhbmQgd2lsbCBub3QgZXZlbiBhY2Nlc3MgdGhlIHRhYmxlIG9yIGluZGV4IGR1cmluZyB0aGUgZXhlY3V0aW9uIHN0YWdlLicsXG4gICAgc3lzdGVtOiAnVGhlIHRhYmxlIGlzIGVtcHR5IG9yIGhhcyBvbmUgcm93LicsXG4gICAgY29uc3Q6ICdUaGUgdmFsdWUgb2YgdGhlIGNvbHVtbiBjYW4gYmUgdHJlYXRlZCBhcyBhIGNvbnN0YW50ICh0aGVyZSBpcyBvbmUgcm93IG1hdGNoaW5nIHRoZSBxdWVyeSkuIE5vdGU6IFByaW1hcnkgS2V5IExvb2t1cCwgVW5pcXVlIEluZGV4IExvb2t1cCcsXG4gICAgZXFfcmVmOiAnVGhlIGluZGV4IGlzIGNsdXN0ZXJlZCBhbmQgaXMgYmVpbmcgdXNlZCBieSB0aGUgb3BlcmF0aW9uIChlaXRoZXIgdGhlIGluZGV4IGlzIGEgUFJJTUFSWSBLRVkgb3IgVU5JUVVFIElOREVYIHdpdGggYWxsIGtleSBjb2x1bW5zIGRlZmluZWQgYXMgTk9UIE5VTEwpJyxcbiAgICByZWY6ICdUaGUgaW5kZXhlZCBjb2x1bW4gd2FzIGFjY2Vzc2VkIHVzaW5nIGFuIGVxdWFsaXR5IG9wZXJhdG9yIE5vdGU6IFRoZSByZWZfb3JfbnVsbCBhY2Nlc3MgdHlwZSBpcyBhIHZhcmlhdGlvbiBvbiByZWYuIEl0IG1lYW5zIE15U1FMIG11c3QgZG8gYSBzZWNvbmQgbG9va3VwIHRvIGZpbmQgTlVMTCBlbnRyaWVzIGFmdGVyIGRvaW5nIHRoZSBpbml0aWFsIGxvb2t1cC4nLFxuICAgIGZ1bGx0ZXh0OiAnT3BlcmF0aW9uIChKT0lOKSBpcyB1c2luZyB0aGUgdGFibGXigJlzIGZ1bGx0ZXh0IGluZGV4JyxcbiAgICBpbmRleDogJ1RoZSBlbnRpcmUgaW5kZXggaXMgc2Nhbm5lZCB0byBmaW5kIGEgbWF0Y2ggZm9yIHRoZSBxdWVyeS4gTm90ZTogVGhlIG1haW4gYWR2YW50YWdlIGlzIHRoYXQgdGhpcyBhdm9pZHMgc29ydGluZy4gVGhlIGJpZ2dlc3QgZGlzYWR2YW50YWdlIGlzIHRoZSBjb3N0IG9mIHJlYWRpbmcgYW4gZW50aXJlIHRhYmxlIGluIGluZGV4IG9yZGVyLiBUaGlzIHVzdWFsbHkgbWVhbnMgYWNjZXNzaW5nIHRoZSByb3dzIGluIHJhbmRvbSBvcmRlciwgd2hpY2ggaXMgdmVyeSBleHBlbnNpdmUuJyxcbiAgICBpbmRleF9tZXJnZTogJ1RoaXMgam9pbiB0eXBlIGluZGljYXRlcyB0aGF0IHRoZSBJbmRleCBNZXJnZSBvcHRpbWl6YXRpb24gaXMgdXNlZC4gSW4gdGhpcyBjYXNlLCB0aGUga2V5IGNvbHVtbiBpbiB0aGUgb3V0cHV0IHJvdyBjb250YWlucyBhIGxpc3Qgb2YgaW5kZXhlcyB1c2VkLiBJdCBpbmRpY2F0ZXMgYSBxdWVyeSBjYW4gbWFrZSBsaW1pdGVkIHVzZSBvZiBtdWx0aXBsZSBpbmRleGVzIG9uIGEgc2luZ2xlIHRhYmxlLicsXG4gICAgcmFuZ2U6ICdUaGlzIHR5cGUgcmVwbGFjZXMgZXFfcmVmIGZvciBzb21lIElOIHN1YnF1ZXJpZXMgb2YgdGhlIGZvbGxvd2luZyBmb3JtOiB2YWx1ZSBJTiAoU0VMRUNUIHByaW1hcnlfa2V5IEZST00gc2luZ2xlX3RhYmxlIFdIRVJFIHNvbWVfZXhwciknLFxuICAgIHVuaXF1ZV9zdWJxdWVyeTogJycsXG4gICAgQUxMOiAnTXlTUUwgc2NhbnMgdGhlIGVudGlyZSB0YWJsZSB0byBzYXRpc2Z5IHRoZSBxdWVyeScsXG4gIH07XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHByaXZhdGUgX2RhdGE6IGFueSxcbiAgICBwcml2YXRlIF9kaWFsb2c6IE1hdERpYWxvZyxcbiAgKSB7XG4gICAgdGhpcy5xdWVyeUxvZyA9IF9kYXRhLnF1ZXJ5TG9nO1xuICB9XG5cbiAgcHVibGljIG9wZW5FeHBsYWluKCkge1xuICAgIHRoaXMuX2RpYWxvZy5vcGVuKEV4cGxhaW5Db21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgZXhwbGFpbjogdGhpcy5leHBsYWluIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGV4cGxhaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlMb2cuZXhwbGFpbjtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgcXVlcnlCbG9jaygpIHtcbiAgICByZXR1cm4gdGhpcy5leHBsYWluPy5xdWVyeUJsb2NrO1xuICB9XG5cbiAgcHVibGljIGdldCBvcmRlcmluZ09wZXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeUJsb2NrPy5vcmRlcmluZ09wZXJhdGlvbjtcbiAgfVxufVxuIiwiPGZzLWRpYWxvZz5cbiAgPGgxIG1hdC1kaWFsb2ctdGl0bGU+UXVlcnkgTG9nPC9oMT5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1sYXJnZVwiPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+RHVyYXRpb248L2ZzLWxhYmVsPlxuICAgICAgICB7e3F1ZXJ5TG9nLmR1cmF0aW9ufX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPk9wdGltaXplZDwvZnMtbGFiZWw+XG4gICAgICAgIHt7cXVlcnlMb2cub3B0aW1pemVkID8gJ1llcycgOiAnTm8nfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlF1ZXJ5IENvc3Q8L2ZzLWxhYmVsPlxuICAgICAgICB7e3F1ZXJ5TG9nLnF1ZXJ5Q29zdH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuXG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5SYXcgRXhwbGFpbjwvZnMtbGFiZWw+XG4gICAgICAgIDxhIChjbGljayk9XCJvcGVuRXhwbGFpbigpXCI+VmlldzwvYT5cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlVSTDwvZnMtbGFiZWw+XG4gICAgICAgIHt7cXVlcnlMb2cucGF0aCB8IGZzRm9ybWF0VHJ1bmNhdGU6IDUwfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgIDxtYXQtdGFiIGxhYmVsPVwiUXVlcnlcIj5cbiAgICAgICAgPGZzLWNsaXBib2FyZC1idXR0b25cbiAgICAgICAgICBbY29udGVudF09XCJxdWVyeUxvZy5wcmV0dHlRdWVyeVwiPlxuICAgICAgICA8L2ZzLWNsaXBib2FyZC1idXR0b24+XG4gICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJxdWVyeUxvZy5wcmV0dHlRdWVyeVwiIGNsYXNzPVwicXVlcnlcIj48L2Rpdj5cbiAgICAgIDwvbWF0LXRhYj5cbiAgICAgIFxuICAgICAgPG1hdC10YWIgbGFiZWw9XCJFeHBsYWluXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwibmVzdGVkTG9vcFwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHF1ZXJ5QmxvY2s6IHF1ZXJ5QmxvY2ssIHNlbGVjdElkOiBxdWVyeUJsb2NrLnNlbGVjdElkLCBjb3N0SW5mbzogcXVlcnlCbG9jay5jb3N0SW5mbyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L21hdC10YWI+XG4gICAgPC9tYXQtdGFiLWdyb3VwPlxuXG4gIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgW21hdC1kaWFsb2ctY2xvc2VdPVwidW5kZWZpbmVkXCI+XG4gICAgICBEb25lXG4gICAgPC9idXR0b24+XG4gIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuPC9mcy1kaWFsb2c+XG5cbjxuZy10ZW1wbGF0ZSAjbmVzdGVkTG9vcCBsZXQtcXVlcnlCbG9jaz1cInF1ZXJ5QmxvY2tcIiBsZXQtc2VsZWN0SWQ9XCJzZWxlY3RJZFwiIGxldC1jb3N0SW5mbz1cImNvc3RJbmZvXCI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RJZFwiPlxuICAgIDxoMT5TZWxlY3Qge3tzZWxlY3RJZH19PC9oMT5cbiAgPC9uZy1jb250YWluZXI+XG4gIFxuICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1sYXJnZVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb3N0SW5mbz8ucXVlcnlDb3N0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5RdWVyeSBDb3N0PC9mcy1sYWJlbD5cbiAgICAgICAge3tjb3N0SW5mby5xdWVyeUNvc3R9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay5vcmRlcmluZ09wZXJhdGlvblwiPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+T3JkZXJpbmcgT3BlcmF0aW9uPC9mcy1sYWJlbD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJxdWVyeUJsb2NrQ3JpdGljYWxcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBxdWVyeUJsb2NrLm9yZGVyaW5nT3BlcmF0aW9uIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay5ncm91cGluZ09wZXJhdGlvblwiPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+R3JvdXBpbmcgT3BlcmF0aW9uPC9mcy1sYWJlbD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJxdWVyeUJsb2NrQ3JpdGljYWxcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBxdWVyeUJsb2NrLmdyb3VwaW5nT3BlcmF0aW9uIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJxdWVyeUJsb2NrLm9yZGVyaW5nT3BlcmF0aW9uXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJuZXN0ZWRMb29wXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogcXVlcnlCbG9jay5vcmRlcmluZ09wZXJhdGlvbiB9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJxdWVyeUJsb2NrLmdyb3VwaW5nT3BlcmF0aW9uXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJuZXN0ZWRMb29wXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogcXVlcnlCbG9jay5ncm91cGluZ09wZXJhdGlvbiB9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJxdWVyeUJsb2NrLnRhYmxlXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJuZXN0ZWRMb29wXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogeyBuZXN0ZWRMb29wOiBbIHF1ZXJ5QmxvY2sgXX0gfVwiPjwvbmctY29udGFpbmVyPlxuICBcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay50YWJsZS5hdHRhY2hlZFN1YnF1ZXJpZXNcIj4gIFxuICAgICAgPGZzLWxhYmVsPkF0dGFjaGVkIFN1YnF1ZXJpZXM8L2ZzLWxhYmVsPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VicXVlcnkgb2YgcXVlcnlCbG9jay50YWJsZS5hdHRhY2hlZFN1YnF1ZXJpZXNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJxdWVyeUJsb2NrQ3JpdGljYWxcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBzdWJxdWVyeS5xdWVyeUJsb2NrIH1cIj48L25nLWNvbnRhaW5lcj4gXG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwibmVzdGVkTG9vcFwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHF1ZXJ5QmxvY2s6IHN1YnF1ZXJ5LnF1ZXJ5QmxvY2ssIHNlbGVjdElkOiBzdWJxdWVyeS5xdWVyeUJsb2NrLnNlbGVjdElkLCBjb3N0SW5mbzogc3VicXVlcnkucXVlcnlCbG9jay5jb3N0SW5mbyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj4gICAgXG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJxdWVyeUJsb2NrLm5lc3RlZExvb3BcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJmcy1saXN0LXRhYmxlIHN0eWxlLWxpbmVcIj5cbiAgICAgICA8dGhlYWQ+XG4gICAgICAgICA8dHI+XG4gICAgICAgICAgIDx0aD5UYWJsZTwvdGg+XG4gICAgICAgICAgIDx0aD5UeXBlPC90aD5cbiAgICAgICAgICAgPHRoPktleXM8L3RoPlxuICAgICAgICAgICA8dGg+UmVmPC90aD5cbiAgICAgICAgICAgPHRoPlJvd3M8L3RoPlxuICAgICAgICAgICA8dGg+RmlsdGVyZWQ8L3RoPlxuICAgICAgICAgICA8dGg+RXh0cmE8L3RoPlxuICAgICAgICAgICA8dGg+Q29zdDwvdGg+XG4gICAgICAgICA8L3RyPlxuICAgICAgIDwvdGhlYWQ+XG4gICAgICAgPHRib2R5PlxuICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBxdWVyeUJsb2NrLm5lc3RlZExvb3A7IGxldCBpbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICB7e2l0ZW0udGFibGUudGFibGVOYW1lfX1cbiAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIDxmcy1wb3BvdmVyIFt0ZW1wbGF0ZV09XCJhY2Nlc3NUeXBlUG9wb3ZlclwiIFtkYXRhXT1cIml0ZW0udGFibGUuYWNjZXNzVHlwZVwiPlxuICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjY2Vzcy10eXBlXCIgW25nQ2xhc3NdPVwiaXRlbS50YWJsZS5hY2Nlc3NUeXBlXCI+e3tpdGVtLnRhYmxlLmFjY2Vzc1R5cGV9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgIDwvZnMtcG9wb3Zlcj4gICAgICAgICAgICBcbiAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIDxmcy1wb3BvdmVyICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgIFt0ZW1wbGF0ZV09XCJrZXlzUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgW21heFdpZHRoXT1cIm51bGxcIlxuICAgICAgICAgICAgICAgICAgIFtkYXRhXT1cInsgcG9zc2libGVLZXlzOiBpdGVtLnRhYmxlLnBvc3NpYmxlS2V5cywga2V5OiBpdGVtLnRhYmxlLmtleSB9XCI+XG4gICAgICAgICAgICAgICAgIHt7aXRlbS50YWJsZS5rZXl9fVxuICAgICAgICAgICAgICAgPC9mcy1wb3BvdmVyPlxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWRlbGltaXRcIj5cbiAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcmVmIG9mIGl0ZW0udGFibGUucmVmXCI+XG4gICAgICAgICAgICAgICAgICAgPHNwYW4+e3tyZWZ9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIHt7aXRlbS50YWJsZS5yb3dzRXhhbWluZWRQZXJTY2FufX1cbiAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgIHt7aXRlbS50YWJsZS5maWx0ZXJlZH19XG4gICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtZGVsaW1pdFwiPlxuICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50YWJsZS5pbmRleENvbmRpdGlvblwiPlxuICAgICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgPGZzLXBvcG92ZXIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgW3RlbXBsYXRlXT1cInVzaW5nSW5kZXhDb25kaXRpb25cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4V2lkdGhdPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwiaXRlbS50YWJsZS5pbmRleENvbmRpdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICBVc2luZyBJbmRleCBDb25kaXRpb25cbiAgICAgICAgICAgICAgICAgICAgIDwvZnMtcG9wb3Zlcj5cbiAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50YWJsZS5hdHRhY2hlZENvbmRpdGlvblwiPlxuICAgICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgPGZzLXBvcG92ZXIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgW3RlbXBsYXRlXT1cInVzaW5nV2hlcmVcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4V2lkdGhdPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwiaXRlbS50YWJsZS5hdHRhY2hlZENvbmRpdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICBVc2luZyBXaGVyZVxuICAgICAgICAgICAgICAgICAgICAgPC9mcy1wb3BvdmVyPlxuICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnVzaW5nSW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICA8c3Bhbj5Vc2luZyBJbmRleDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+ICAgIFxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnVzaW5nRmlsZXNvcnRcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3JpdGljYWxcIj5Vc2luZyBGaWxlIFNvcnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udXNpbmdUZW1wb3JhcnlUYWJsZVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcml0aWNhbFwiPlRlbXBvcmFyeSBUYWJsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgPHRkPiAgICAgXG4gICAgICAgICAgICAgIDxmcy1wb3BvdmVyIFt0ZW1wbGF0ZV09XCJ0YWJsZUNvc3RQb3BvdmVyXCIgW2RhdGFdPVwiaXRlbS50YWJsZT8uY29zdEluZm9cIj5cbiAgICAgICAgICAgICAgICB7e2l0ZW0udGFibGU/LmNvc3RJbmZvLnByZWZpeENvc3R9fVxuICAgICAgICAgICAgICA8L2ZzLXBvcG92ZXI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjdGFibGVDb3N0UG9wb3ZlciBsZXQtZGF0YT1cImRhdGFcIj5cbiAgICAgICAgICAgICAgICA8ZGl2PkV2YWwgQ29zdDoge3tkYXRhLmV2YWxDb3N0fX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2PlJlYWQgQ29zdDoge3tkYXRhLnJlYWRDb3N0fX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2PlByZWZpeCBDb3N0OiB7e2RhdGEucHJlZml4Q29zdH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdj5EYXRhIFJlYWQgUGVyIEpvaW46IHt7ZGF0YS5kYXRhUmVhZFBlckpvaW59fTwvZGl2PlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgIDwvdHI+XG4gICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICA8L3Rib2R5PlxuICAgICA8L3RhYmxlPlxuICAgICA8YnI+XG4gICA8L25nLWNvbnRhaW5lcj4gIFxuICBcbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2suc2VsZWN0TGlzdFN1YnF1ZXJpZXNcIj5cbiAgICA8YnI+XG4gICAgPGZzLWxhYmVsPlNlbGVjdCBMaXN0IFN1YnF1ZXJpZXM8L2ZzLWxhYmVsPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1YnF1ZXJ5IG9mIHF1ZXJ5QmxvY2suc2VsZWN0TGlzdFN1YnF1ZXJpZXNcIj5cbiAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwicXVlcnlCbG9ja0NyaXRpY2FsXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogc3VicXVlcnkucXVlcnlCbG9jayB9XCI+PC9uZy1jb250YWluZXI+IFxuICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJuZXN0ZWRMb29wXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgcXVlcnlCbG9jazogc3VicXVlcnkucXVlcnlCbG9jaywgc2VsZWN0SWQ6IHN1YnF1ZXJ5LnF1ZXJ5QmxvY2suc2VsZWN0SWQsIGNvc3RJbmZvOiBzdWJxdWVyeS5xdWVyeUJsb2NrLmNvc3RJbmZvIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48IS0tIFxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay5xdWVyeUJsb2NrYXR0YWNoZWRTdWJxdWVyaWVzXCI+XG4gICAgPGJyPlxuICAgIDxmcy1sYWJlbD5BdHRhY2hlZCBTdWJxdWVyaWVzPC9mcy1sYWJlbD5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWJxdWVyeSBvZiBxdWVyeUJsb2NrLmF0dGFjaGVkU3VicXVlcmllc1wiPlxuICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJxdWVyeUJsb2NrQ3JpdGljYWxcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBxdWVyeUJsb2NrOiBzdWJxdWVyeS5xdWVyeUJsb2NrIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwibmVzdGVkTG9vcFwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHF1ZXJ5QmxvY2s6IHN1YnF1ZXJ5LnF1ZXJ5QmxvY2sgfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj4gLS0+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2tleXNQb3BvdmVyIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8ZGl2IGNsYXNzPVwiZnMtZGVsaW1pdFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHBvc3NpYmxlS2V5IG9mIGRhdGEucG9zc2libGVLZXlzXCI+XG4gICAgICA8c3BhbiBbbmdDbGFzc109XCJ7ICdxdWVyeS1sb2ctdXNlZC1rZXknOiBwb3NzaWJsZUtleSA9PT0gZGF0YS5rZXkgfVwiPnt7cG9zc2libGVLZXl9fTwvc3Bhbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3VzaW5nV2hlcmUgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIHt7ZGF0YX19XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3VzaW5nSW5kZXhDb25kaXRpb24gbGV0LWRhdGE9XCJkYXRhXCI+XG4gIHt7ZGF0YX19XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2FjY2Vzc1R5cGVQb3BvdmVyIGxldC1kYXRhPVwiZGF0YVwiPlxuICB7e2FjY2Vzc1R5cGVzW2RhdGFdfX1cbjwvbmctdGVtcGxhdGU+XG5cblxuPG5nLXRlbXBsYXRlICNxdWVyeUJsb2NrQ3JpdGljYWwgbGV0LXF1ZXJ5QmxvY2s9XCJxdWVyeUJsb2NrXCI+XG4gIDxkaXYgY2xhc3M9XCJmcy1kZWxpbWl0XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInF1ZXJ5QmxvY2sudXNpbmdGaWxlc29ydFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcml0aWNhbFwiPlVzaW5nIEZpbGUgU29ydDwvc3Bhbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICBcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicXVlcnlCbG9jay51c2luZ1RlbXBvcmFyeVRhYmxlXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cImNyaXRpY2FsXCI+VGVtcG9yYXJ5IFRhYmxlPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+Il19
|
|
@@ -116,7 +116,7 @@ class QueryLogComponent {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
QueryLogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: QueryLogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
119
|
-
QueryLogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\">\n\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n </div>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <fs-label-field>\n <fs-label>Select List Subqueries</fs-label>\n </fs-label-field>\n\n <ng-container *ngFor=\"let selectListSubquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [selectListSubquery.queryBlock] }}\"></ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:bold}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], components: [{ type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode"] }, { type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i3.FsLabelComponent, selector: "fs-label" }, { type: i3$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { type: i3$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby"], exportAs: ["matTab"] }, { type: i2$1.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content"] }, { type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "fsFormatTruncate": i9.FsFormatTruncatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
119
|
+
QueryLogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock, selectId: queryBlock.selectId, costInfo: queryBlock.costInfo }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\" let-selectId=\"selectId\" let-costInfo=\"costInfo\">\n <ng-container *ngIf=\"selectId\">\n <h1>Select {{selectId}}</h1>\n </ng-container>\n \n <div class=\"fs-row.gap-large\">\n <ng-container *ngIf=\"costInfo?.queryCost\">\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{costInfo.queryCost}}\n </fs-label-field>\n </ng-container>\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.table\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [ queryBlock ]} }\"></ng-container>\n \n <ng-container *ngIf=\"queryBlock.table.attachedSubqueries\"> \n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.table.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container> \n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n <th>Cost</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n <ng-container *ngIf=\"item.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"item.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n </td>\n <td> \n <fs-popover [template]=\"tableCostPopover\" [data]=\"item.table?.costInfo\">\n {{item.table?.costInfo.prefixCost}}\n </fs-popover>\n <ng-template #tableCostPopover let-data=\"data\">\n <div>Eval Cost: {{data.evalCost}}</div>\n <div>Read Cost: {{data.readCost}}</div>\n <div>Prefix Cost: {{data.prefixCost}}</div>\n <div>Data Read Per Join: {{data.dataReadPerJoin}}</div>\n </ng-template>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n \n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <br>\n <fs-label>Select List Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container>\n<!-- \n <ng-container *ngIf=\"queryBlock.queryBlockattachedSubqueries\">\n <br>\n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n </ng-container>\n </ng-container> -->\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:bold}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], components: [{ type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode"] }, { type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i3.FsLabelComponent, selector: "fs-label" }, { type: i3$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { type: i3$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby"], exportAs: ["matTab"] }, { type: i2$1.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content"] }, { type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "fsFormatTruncate": i9.FsFormatTruncatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
120
120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: QueryLogComponent, decorators: [{
|
|
121
121
|
type: Component,
|
|
122
122
|
args: [{
|