@hestia-earth/ui-components 0.11.2 → 0.11.3

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.
@@ -174,10 +174,10 @@ export class NodeLogsModelsComponent {
174
174
  }
175
175
  }
176
176
  NodeLogsModelsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: NodeLogsModelsComponent, deps: [{ token: i1.HeNodeService }, { token: i2.HeSearchService }, { token: i3.HeEngineService }], target: i0.ɵɵFactoryTarget.Component });
177
- NodeLogsModelsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{blankNode.originalValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{blankNode.recalculatedValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: blankNode}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{subValue.key | keyToLabel}}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{subValue.id | keyToLabel}}</span>\n <he-node-link *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\"\n (click)=\"showLegend = !showLegend\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{logColor[status.value]}}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{status.value}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <td class=\"blank-node-index-{{i}}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model:models, data}\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model, data}\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <ng-container *bindOnce=\"logs\">\n <ng-container *ngIf=\"logs?.requirements\">\n <div class=\"is-requirement\" *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context:{key, value:logs.requirements[key]}\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.logs\">\n <div class=\"is-log\" *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context:key\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.missingLookups?.length\">\n <p class=\"mt-2\">Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-fullwidth mb-0\">\n <thead>\n <tr>\n <th>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{data.filename}}</td>\n <td>{{data.column}}</td>\n <td>{{data.termId}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{value}}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else defaultValue\">\n <he-node-link class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_aboveGroundCropResidueBurnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [hideText]=\"true\"></he-clipboard>\n <span class=\"is-pr-1 is-inline-block is-align-middle\">:</span>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context:{key,value}\"></ng-container>\n </ng-template>\n <div class=\"is-inline-block is-align-middle\" *ngIf=\"logValueArray(value); let valueArray; else singleValue\">\n <table class=\"table is-bordered has-background-secondary has-text-white\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{v.key}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{v}}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{vv.value}}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{model.status}}</span>\n </div>\n\n <ng-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{nodeType | pluralize:0}}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{data.type || 'blank node'}} with Term <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep tr.has-sub-rows td{border-bottom-style:dotted}::ng-deep td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep td he-node-link{width:150px}}::ng-deep td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep td .open-node+he-node-link{width:130px}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: i6.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i8.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "component", type: i9.BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType"] }, { kind: "component", type: i10.ClipboardComponent, selector: "he-clipboard", inputs: ["value", "disabled", "hideText", "icon", "size", "rotate", "clipboardClass"] }, { kind: "component", type: i11.DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "nbRows", "small", "height", "width"] }, { kind: "component", type: i12.NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink", "linkClass"] }, { kind: "pipe", type: i13.CompoundPipe, name: "compound" }, { kind: "pipe", type: i14.DefaultPipe, name: "default" }, { kind: "pipe", type: i15.KeysPipe, name: "keys" }, { kind: "pipe", type: i16.PluralizePipe, name: "pluralize" }, { kind: "pipe", type: i17.KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: i18.PrecisionPipe, name: "precision" }, { kind: "pipe", type: i19.TimesPipe, name: "times" }, { kind: "pipe", type: i20.IsArrayPipe, name: "isArray" }, { kind: "pipe", type: i21.IsObjectPipe, name: "isObject" }] });
177
+ NodeLogsModelsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{blankNode.originalValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{blankNode.recalculatedValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: blankNode}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{subValue.key | keyToLabel}}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{subValue.id | keyToLabel}}</span>\n <he-node-link *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\"\n (click)=\"showLegend = !showLegend\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{logColor[status.value]}}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{status.value}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <td class=\"blank-node-index-{{i}}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model:models, data}\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model, data}\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <ng-container *bindOnce=\"logs\">\n <ng-container *ngIf=\"logs?.requirements\">\n <div class=\"is-requirement\" *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context:{key, value:logs.requirements[key]}\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.logs\">\n <div class=\"is-log\" *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context:key\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.missingLookups?.length\">\n <p class=\"mt-2\">Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-fullwidth mb-0\">\n <thead>\n <tr>\n <th>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{data.filename}}</td>\n <td>{{data.column}}</td>\n <td>{{data.termId}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{value}}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else defaultValue\">\n <he-node-link class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [hideText]=\"true\"></he-clipboard>\n <span class=\"is-pr-1 is-inline-block is-align-middle\">:</span>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context:{key,value}\"></ng-container>\n </ng-template>\n <div class=\"is-inline-block is-align-middle\" *ngIf=\"logValueArray(value); let valueArray; else singleValue\">\n <table class=\"table is-bordered has-background-secondary has-text-white\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{v.key}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{v}}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{vv.value}}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{model.status}}</span>\n </div>\n\n <ng-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{nodeType | pluralize:0}}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{data.type || 'blank node'}} with Term <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep tr.has-sub-rows td{border-bottom-style:dotted}::ng-deep td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep td he-node-link{width:150px}}::ng-deep td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep td .open-node+he-node-link{width:130px}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: i6.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i8.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "component", type: i9.BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType"] }, { kind: "component", type: i10.ClipboardComponent, selector: "he-clipboard", inputs: ["value", "disabled", "hideText", "icon", "size", "rotate", "clipboardClass"] }, { kind: "component", type: i11.DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "nbRows", "small", "height", "width"] }, { kind: "component", type: i12.NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink", "linkClass"] }, { kind: "pipe", type: i13.CompoundPipe, name: "compound" }, { kind: "pipe", type: i14.DefaultPipe, name: "default" }, { kind: "pipe", type: i15.KeysPipe, name: "keys" }, { kind: "pipe", type: i16.PluralizePipe, name: "pluralize" }, { kind: "pipe", type: i17.KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: i18.PrecisionPipe, name: "precision" }, { kind: "pipe", type: i19.TimesPipe, name: "times" }, { kind: "pipe", type: i20.IsArrayPipe, name: "isArray" }, { kind: "pipe", type: i21.IsObjectPipe, name: "isObject" }] });
178
178
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
179
179
  type: Component,
180
- args: [{ selector: 'he-node-logs-models', template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{blankNode.originalValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{blankNode.recalculatedValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: blankNode}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{subValue.key | keyToLabel}}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{subValue.id | keyToLabel}}</span>\n <he-node-link *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\"\n (click)=\"showLegend = !showLegend\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{logColor[status.value]}}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{status.value}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <td class=\"blank-node-index-{{i}}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model:models, data}\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model, data}\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <ng-container *bindOnce=\"logs\">\n <ng-container *ngIf=\"logs?.requirements\">\n <div class=\"is-requirement\" *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context:{key, value:logs.requirements[key]}\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.logs\">\n <div class=\"is-log\" *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context:key\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.missingLookups?.length\">\n <p class=\"mt-2\">Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-fullwidth mb-0\">\n <thead>\n <tr>\n <th>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{data.filename}}</td>\n <td>{{data.column}}</td>\n <td>{{data.termId}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{value}}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else defaultValue\">\n <he-node-link class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_aboveGroundCropResidueBurnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [hideText]=\"true\"></he-clipboard>\n <span class=\"is-pr-1 is-inline-block is-align-middle\">:</span>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context:{key,value}\"></ng-container>\n </ng-template>\n <div class=\"is-inline-block is-align-middle\" *ngIf=\"logValueArray(value); let valueArray; else singleValue\">\n <table class=\"table is-bordered has-background-secondary has-text-white\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{v.key}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{v}}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{vv.value}}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{model.status}}</span>\n </div>\n\n <ng-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{nodeType | pluralize:0}}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{data.type || 'blank node'}} with Term <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep tr.has-sub-rows td{border-bottom-style:dotted}::ng-deep td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep td he-node-link{width:150px}}::ng-deep td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep td .open-node+he-node-link{width:130px}}\n"] }]
180
+ args: [{ selector: 'he-node-logs-models', template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{blankNode.originalValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{blankNode.recalculatedValue | precision:3 | default:'-'}}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: blankNode}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{subValue.key | keyToLabel}}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{subValue.id | keyToLabel}}</span>\n <he-node-link *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: {data: subValue}\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\"\n (click)=\"showLegend = !showLegend\"\n >\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{logColor[status.value]}}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{status.value}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <td class=\"blank-node-index-{{i}}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model:models, data}\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: {model, data}\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <ng-container *bindOnce=\"logs\">\n <ng-container *ngIf=\"logs?.requirements\">\n <div class=\"is-requirement\" *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context:{key, value:logs.requirements[key]}\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.logs\">\n <div class=\"is-log\" *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context:key\"></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"logs?.missingLookups?.length\">\n <p class=\"mt-2\">Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-fullwidth mb-0\">\n <thead>\n <tr>\n <th>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{data.filename}}</td>\n <td>{{data.column}}</td>\n <td>{{data.termId}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{value}}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else defaultValue\">\n <he-node-link class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [hideText]=\"true\"></he-clipboard>\n <span class=\"is-pr-1 is-inline-block is-align-middle\">:</span>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context:{key,value}\"></ng-container>\n </ng-template>\n <div class=\"is-inline-block is-align-middle\" *ngIf=\"logValueArray(value); let valueArray; else singleValue\">\n <table class=\"table is-bordered has-background-secondary has-text-white\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{v.key}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{v}}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{vv.value}}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{model.status}}</span>\n </div>\n\n <ng-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{nodeType | pluralize:0}}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{data.type || 'blank node'}} with Term <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep tr.has-sub-rows td{border-bottom-style:dotted}::ng-deep td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep td he-node-link{width:150px}}::ng-deep td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep td .open-node+he-node-link{width:130px}}\n"] }]
181
181
  }], ctorParameters: function () { return [{ type: i1.HeNodeService }, { type: i2.HeSearchService }, { type: i3.HeEngineService }]; }, propDecorators: { node: [{
182
182
  type: Input
183
183
  }], nodeKey: [{
@@ -193,4 +193,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
193
193
  }], logsKey: [{
194
194
  type: Input
195
195
  }] } });
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQVMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGtCQUFrQixFQUF1QixRQUFRLEVBQVEsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0csT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQ2lDLFNBQVMsRUFBMkIsZ0JBQWdCLEVBQUUsZUFBZSxFQUMzRyxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDeEMsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0RixPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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QUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUk7WUFDM0IsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJO1lBQ3RCLEtBQUssRUFBRSxFQUFFO1lBQ1QsSUFBSSxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7U0FDVCxDQUFDO0lBQ25CLENBQUM7O29IQS9LVSx1QkFBdUI7d0dBQXZCLHVCQUF1Qiw2UENwRnBDLDR1cUJBc2JBOzJGRGxXYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCO2dLQWdCdkIsSUFBSTtzQkFEWCxLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSztnQkFHRSxjQUFjO3NCQURyQixLQUFLO2dCQUdFLGtCQUFrQjtzQkFEekIsS0FBSztnQkFHRSxLQUFLO3NCQURaLEtBQUs7Z0JBR0UsZUFBZTtzQkFEdEIsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG1lcmdlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3QsIGZpbHRlciwgcmVkdWNlLCB0b0FycmF5LCBtYXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzd2l0Y2hNYXAsIG1lcmdlTWFwLCBtZXJnZUFsbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEVtaXNzaW9uTWV0aG9kVGllciwgSVRlcm1KU09OTEQsIEpTT05MRCwgTm9kZVR5cGUsIFRlcm0sIFRlcm1UZXJtVHlwZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IGtleVRvTGFiZWwgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcbmltcG9ydCB7IHByb3BlcnR5VmFsdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzL2Rpc3QvdGVybSc7XG5cbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSwgSUJsYW5rTm9kZUxvZywgTG9nU3RhdHVzLCBJQ29uZmlnTW9kZWwsIGJsYW5rTm9kZSwgZ3JvdXBMb2dzQnlNb2RlbCwgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LCBjb21wdXRlVGVybXMsIGxvZ1ZhbHVlQXJyYXlcbn0gZnJvbSAnLi9ub2RlLWxvZ3MtbW9kZWxzLm1vZGVsJztcbmltcG9ydCB7IElKU09OTm9kZSwgSGVOb2RlU2VydmljZSB9IGZyb20gJy4uL25vZGUuc2VydmljZSc7XG5pbXBvcnQgeyBIZUVuZ2luZVNlcnZpY2UsIElNb2RlbCB9IGZyb20gJy4uLy4uL2VuZ2luZS9lbmdpbmUuc2VydmljZSc7XG5pbXBvcnQgeyBtYXRjaEV4YWN0UXVlcnksIG1hdGNoVGVybVR5cGUsIG1hdGNoVHlwZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2gubW9kZWwnO1xuaW1wb3J0IHsgSGVTZWFyY2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5zZXJ2aWNlJztcbmltcG9ydCB7IGJhc2VVcmwsIGlzRXh0ZXJuYWwgfSBmcm9tICcuLi8uLi9jb21tb24vdXRpbHMnO1xuaW1wb3J0IHsgdGVybVR5cGVMYWJlbCB9IGZyb20gJy4uLy4uL3Rlcm1zL3Rlcm1zLm1vZGVsJztcblxuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaydcbn07XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgbW9kZWw/OiBJTW9kZWwpID0+XG4gIChcbiAgICBtZXRob2RJZFxuICAgICAgPyAoe1xuICAgICAgICAnY3ljbGUvdHJhbnNmb3JtYXRpb24nOiAnRGF0YSBGcm9tIFRyYW5zZm9ybWF0aW9uJyxcbiAgICAgICAgaW1wYWN0X2Fzc2Vzc21lbnQ6ICdEYXRhIEZyb20gQ3ljbGUnXG4gICAgICB9KVttZXRob2RJZF1cbiAgICAgIDogJydcbiAgKSB8fCAoXG4gICAgbWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKVxuICApO1xuXG5jb25zdCBnZXRNb2RlbHNBdCA9IChsb2c6IElCbGFua05vZGVMb2dTdWJWYWx1ZSB8IElCbGFua05vZGVMb2csIGluZGV4OiBudW1iZXIpID0+XG4gICgnbW9kZWxzSW5TdWJWYWx1ZXMnIGluIGxvZyA/ICFsb2cubW9kZWxzSW5TdWJWYWx1ZXMgfHwgIWxvZy5pc09wZW4gOiB0cnVlKSAmJiBsb2cuY29uZmlnTW9kZWxzW2luZGV4XTtcblxuY29uc3QgcmVxdWlyZW1lbnRLZXlzID0gKHJlcXVpcmVtZW50czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkgPT5cbiAgT2JqZWN0LmtleXMocmVxdWlyZW1lbnRzKS5maWx0ZXIoayA9PiAhbm9kZVR5cGVzTG93ZXJDYXNlLmluY2x1ZGVzKGspKTtcblxuY29uc3QgcmVxdWlyZW1lbnRDb2xvciA9ICh2YWx1ZTogYW55KSA9PiAhdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnO1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleToge1xuICBba2V5OiBzdHJpbmddOiAodmFsdWU6IHN0cmluZykgPT4gUGFydGlhbDxKU09OTEQ8Tm9kZVR5cGU+Pjtcbn0gPSB7XG4gIHJlbGF0ZWRfY3ljbGVzOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgY3ljbGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBpbXBhY3RfYXNzZXNzbWVudF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5JbXBhY3RBc3Nlc3NtZW50LCAnQGlkJzogdiB9KSxcbiAgc2l0ZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5TaXRlLCAnQGlkJzogdiB9KSxcbiAgc291cmNlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNvdXJjZSwgJ0BpZCc6IHYgfSlcbn07XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT5cbiAga2V5IGluIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5ICYmXG4gIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5W2tleV0odmFsdWUpO1xuXG5jb25zdCBpc1N5c3RlbUJvdW5kYXJ5ID0gKFxuICB7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUJsYW5rTm9kZUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz5cbikgPT4gW1xuICBpc1JlY2FsY3VsYXRlZCxcbiAgaXNSZXF1aXJlZFxuXS5zb21lKEJvb2xlYW4pO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoZS1ub2RlLWxvZ3MtbW9kZWxzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTm9kZUxvZ3NNb2RlbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGxvZ3M6IHN0cmluZztcbiAgcHJpdmF0ZSBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5Pzogc3RyaW5nO1xuICBASW5wdXQoKVxuICBwcml2YXRlIG9yaWdpbmFsVmFsdWVzOiBibGFua05vZGVbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHJlY2FsY3VsYXRlZFZhbHVlczogYmxhbmtOb2RlW10gPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSB0ZXJtczogSVRlcm1KU09OTERbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGZpbHRlclRlcm1UeXBlcz86IFRlcm1UZXJtVHlwZVtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGxvZ3NLZXk/OiBzdHJpbmc7XG5cbiAgcHVibGljIGxvZ3NVcmw/OiBzdHJpbmc7XG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgaXNFeHRlcm5hbCA9IGlzRXh0ZXJuYWwoKTtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBsb2FkaW5nID0gdHJ1ZTtcbiAgcHVibGljIG5vZGVUeXBlOiBOb2RlVHlwZTtcbiAgcHVibGljIGJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwdWJsaWMgbWV0aG9kTW9kZWxzQ291bnQgPSAwO1xuICBwdWJsaWMgcm93c0NvdW50ID0gMDtcbiAgcHVibGljIG9ubHlSZXF1aXJlZCA9IHRydWU7XG4gIHB1YmxpYyBzaG93TGVnZW5kID0gdHJ1ZTtcblxuICBwdWJsaWMgdGVybT86IHN0cmluZztcbiAgcHVibGljIHN1Z2dlc3RUZXJtID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pID0+XG4gICAgdGV4dCQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzd2l0Y2hNYXAodiA9PiB0aGlzLnN1Z2dlc3RCeVRlcm0odikpLFxuICAgICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBub2RlU2VydmljZTogSGVOb2RlU2VydmljZSxcbiAgICBwcml2YXRlIHNlYXJjaFNlcnZpY2U6IEhlU2VhcmNoU2VydmljZSxcbiAgICBwcml2YXRlIGVuZ2luZVNlcnZpY2U6IEhlRW5naW5lU2VydmljZVxuICApIHsgfVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUpO1xuXG4gICAgY29uc3QgbW9kZWxzID0gYXdhaXQgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFtcbiAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksXG4gICAgICAgICAgbWF0Y2hUZXJtVHlwZShUZXJtVGVybVR5cGUubW9kZWwpXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubWV0aG9kc0J5SWQgPSBhd2FpdCBmcm9tKG1vZGVscykucGlwZShcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICBkaXN0aW5jdCh2ID0+IHZbJ0BpZCddKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIC8vIGZyb20gYG1vZGVsLWxpbmtzLmpzb25gIGZpbGVcbiAgICBjb25zdCBlbmdpbmVNb2RlbHMgPSBhd2FpdCB0aGlzLmVuZ2luZVNlcnZpY2UubW9kZWxzKCk7XG5cbiAgICB0aGlzLmFsbFRlcm1zID0gYXdhaXQgY29tcHV0ZVRlcm1zKHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLnRlcm1zLCB0aGlzLmZpbHRlclRlcm1UeXBlcyk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAoXG4gICAgICBncm91cExvZ3NCeVRlcm0odGhpcy5ub2RlVHlwZSwgbG9ncywgZW5naW5lTW9kZWxzLCBjb25maWcsIHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLm5vZGVLZXkpXG4gICAgKTtcbiAgICB0aGlzLm1ldGhvZE1vZGVsc0NvdW50ID0gbW9kZWxDb3VudCh0aGlzLmFsbEJsYW5rTm9kZXMpO1xuICAgIHRoaXMucm93c0NvdW50ID0gdGhpcy5hbGxCbGFua05vZGVzLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIDEgKyBjdXJyLnN1YlZhbHVlcy5sZW5ndGggKyBjdXJyLmtleXMubGVuZ3RoLCAwKTtcblxuICAgIHRoaXMudGVybXNCeUlkID0gYXdhaXQgb2YodGhpcy5hbGxCbGFua05vZGVzKS5waXBlKFxuICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICBtYXAodiA9PiB2LmlkKSxcbiAgICAgIGRpc3RpbmN0KCksXG4gICAgICB0b0FycmF5KCksXG4gICAgICBtZXJnZU1hcChpZHMgPT4gZnJvbSh0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgYm9vbDoge1xuICAgICAgICAgIG11c3Q6IFtcbiAgICAgICAgICAgIG1hdGNoVHlwZShOb2RlVHlwZS5UZXJtKVxuICAgICAgICAgIF0sXG4gICAgICAgICAgc2hvdWxkOiBpZHMubWFwKGlkID0+IG1hdGNoRXhhY3RRdWVyeSgnQGlkJywgaWQpKSxcbiAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICB9XG4gICAgICB9KSkpLFxuICAgICAgbWVyZ2VBbGwoKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIHRoaXMuZmlsdGVyUmVzdWx0cygpO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGdldExvZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZVNlcnZpY2UuZ2V0TG9nKHRoaXMubm9kZSkudG9Qcm9taXNlKCk7XG4gIH1cblxuICBwcml2YXRlIHN1Z2dlc3RCeVRlcm0odGVybTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGZyb20odGhpcy5hbGxUZXJtcykucGlwZShcbiAgICAgIG1hcCh2ID0+IHYubmFtZSksXG4gICAgICBmaWx0ZXIodiA9PiB2LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybS50b0xvd2VyQ2FzZSgpKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwdWJsaWMgdHJhY2tCeUJsYW5rTm9kZShfaW5kZXg6IG51bWJlciwgbm9kZTogSUJsYW5rTm9kZUxvZykge1xuICAgIHJldHVybiBub2RlLnRlcm1JZDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZmlsdGVyZWRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRlcm1UeXBlcz8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlclJlc3VsdHMoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmJsYW5rTm9kZXMgPSB0aGlzLmFsbEJsYW5rTm9kZXMuZmlsdGVyKCh7IHRlcm06IHsgbmFtZSB9LCBzdWJWYWx1ZXMsIC4uLmxvZyB9KSA9PlxuICAgICAgICB0aGlzLnRlcm1cbiAgICAgICAgICA/IG5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLnRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICA6IChcbiAgICAgICAgICAgICF0aGlzLmZpbHRlclRlcm1UeXBlcz8ubGVuZ3RoIHx8XG4gICAgICAgICAgICAhdGhpcy5vbmx5UmVxdWlyZWQgfHwgaXNTeXN0ZW1Cb3VuZGFyeShsb2cpIHx8IHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkpXG4gICAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkW21ldGhvZElkXT8ubmFtZSB8fCBtZXRob2RJZExhYmVsKG1ldGhvZElkLCBtb2RlbCk7XG4gIH1cblxuICBwdWJsaWMgaGFzTWV0aG9kVGllcih2YWx1ZXM6IGJsYW5rTm9kZVtdLCBtZXRob2RUaWVyOiBFbWlzc2lvbk1ldGhvZFRpZXIpIHtcbiAgICByZXR1cm4gdmFsdWVzLnNvbWUodiA9PiAnbWV0aG9kVGllcicgaW4gdiAmJiB2Lm1ldGhvZFRpZXIgPT09IG1ldGhvZFRpZXIpO1xuICB9XG5cbiAgcHVibGljIHRlcm1CeUlkKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50ZXJtc0J5SWRbaWRdIHx8IHtcbiAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAnQGlkJzogaWQsXG4gICAgICBuYW1lOiB0ZXJtVHlwZUxhYmVsKGlkKVxuICAgIH0gYXMgSVRlcm1KU09OTEQ7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweC0zIHBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IG1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsXCI+XG4gICAgPGEgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cImxvZ3NVcmxcIiBbaHJlZl09XCJsb2dzVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgW25iUm93c109XCJyb3dzQ291bnRcIiBtYXhIZWlnaHQ9XCIzMjBcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1mdWxsd2lkdGggaXMtbmFycm93IGlzLXN0cmlwZWRcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250cm9sIGlzLWV4cGFuZGVkIGhhcy1pY29ucy1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRlcm1cIiBuYW1lPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkZpbHRlciBieSBuYW1lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ2JUeXBlYWhlYWRdPVwic3VnZ2VzdFRlcm1cIlxuICAgICAgICAgICAgICAgICAgW2ZvY3VzRmlyc3RdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwiZmlsdGVyUmVzdWx0cygpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJpY29uIGlzLXNtYWxsIGlzLXJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXRlcm1cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRlcm0gPSAnJzsgZmlsdGVyUmVzdWx0cygpO1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInRpbWVzXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5Vbml0czwvdGg+XG4gICAgICAgICAgPHRoPk9yaWdpbmFsPC90aD5cbiAgICAgICAgICA8dGg+UmVjYWxjdWxhdGVkPC90aD5cbiAgICAgICAgICA8dGg+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj4oe3tpICsgMX19KTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZyAmJiBibGFua05vZGVzLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxzcGFuPk5vIGRhdGE8L3NwYW4+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYmxhbmtOb2RlIG9mIGJsYW5rTm9kZXM7IHRyYWNrQnk6IHRyYWNrQnlCbGFua05vZGVcIj5cbiAgICAgICAgICA8dHIgW2NsYXNzLmhhcy1zdWItcm93c109XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMiBvcGVuLW5vZGVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJibGFua05vZGUuaXNPcGVuID0gIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLmNhbk9wZW5cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgW25vZGVdPVwiYmxhbmtOb2RlLnRlcm1cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcCBoYXMtdGV4dC1lbGxpcHNpc1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7YmxhbmtOb2RlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdE9yaWdpbmFsVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFibGFua05vZGUuaXNPcmlnaW5hbCB8fCBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWU+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57e2JsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJpcy1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVsdGFWYWx1ZT5cbiAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YSAqbmdJZj1cImJsYW5rTm9kZS5vcmlnaW5hbC5sZW5ndGggJiYgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbb3JpZ2luYWxWYWx1ZV09XCJibGFua05vZGUub3JpZ2luYWxWYWx1ZVwiXG4gICAgICAgICAgICAgICAgPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0RGVsdGFWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgIDxoZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbCAmJiBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiXG4gICAgICAgICAgICAgICAgICA+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7ZGF0YTogYmxhbmtOb2RlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTMgcHItMSBmaWVsZC1ub2RlXCI+RmllbGQ6PC9zcGFuPlxuXG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nSWY9XCJibGFua05vZGUudHlwZVwiXG4gICAgICAgICAgICAgICAgW2hyZWZdPVwiYmFzZVVybCArICcvc2NoZW1hLycgKyBibGFua05vZGUudHlwZSArICcjJyArIHN1YlZhbHVlLmtleVwiIHRhcmdldD1cIl9ibGFua1wiIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIj57e3N1YlZhbHVlLmtleX19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcFwiICpuZ0lmPVwiIWJsYW5rTm9kZS50eXBlXCI+e3tzdWJWYWx1ZS5rZXl9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj57e3N1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkIHx8IHN1YlZhbHVlLmtleSA9PT0gJ2ltcGFjdEFzc2Vzc21lbnQnOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7c3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHtkYXRhOiBzdWJWYWx1ZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLnN1YlZhbHVlc1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTNcIj57e3N1YlZhbHVlLmtleSB8IGtleVRvTGFiZWx9fTwvc3Bhbj5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3ViVmFsdWUuaWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0xXCI+Ojwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInN1YlZhbHVlLmtleVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiAqbmdTd2l0Y2hDYXNlPVwiJ2JhY2tncm91bmREYXRhJ1wiPnt7c3ViVmFsdWUuaWQgfCBrZXlUb0xhYmVsfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rICpuZ1N3aXRjaERlZmF1bHQgY2xhc3M9XCJpcy1ibG9jayBwbC00XCIgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCIgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIiBbaW5uZXJIdG1sXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLnNob3dVbml0c1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPnt7c3ViVmFsdWUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3tzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPi08L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDoge2RhdGE6IHN1YlZhbHVlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2hlLWRhdGEtdGFibGU+XG5cbiAgPGRpdiBjbGFzcz1cImlzLXNpemUtNyBpcy1pdGFsaWNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1ucyBpcy12YXJpYWJsZSBpcy0xIG15LTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaXMtbmFycm93XCI+XG4gICAgICAgIDxwPlxuICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIHByLTJcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7bG9nQ29sb3Jbc3RhdHVzLnZhbHVlXX19XCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bc3RhdHVzLnZhbHVlXVwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+e3tzdGF0dXMudmFsdWV9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaGFzLXRleHQtcmlnaHRcIiAqbmdJZj1cImZpbHRlcmVkVHlwZVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJzZWxlY3RvclwiXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cImZpbHRlclJlc3VsdHMoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2hvdyBvbmx5IHt7ZmlsdGVyZWRUeXBlIHwgcGx1cmFsaXplfX0gaW5jbHVkZWQgaW4gdGhlIGRlZmF1bHQgSGVzdGlhIHN5c3RlbSBib3VuZGFyeTwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHRkIGNsYXNzPVwiYmxhbmstbm9kZS1pbmRleC17e2l9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0TW9kZWxzQXQoZGF0YSwgaSk7IGxldCBtb2RlbHM7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgPG5nLXRlbXBsYXRlICNtb2RlbFNlcmllPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHttb2RlbDptb2RlbHMsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cIm1vZGVscyB8IGlzQXJyYXk7IGVsc2UgbW9kZWxTZXJpZVwiPlxuICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7bW9kZWwsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3RkPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbCBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8c3BhblxuICAgIFtjbGFzcy50cmlnZ2VyLXBvcG92ZXJdPVwibW9kZWwuc2hvd0xvZ3NcIlxuICAgIFtuZ2JQb3BvdmVyXT1cImxvZ0RldGFpbHNcIiBbYXV0b0Nsb3NlXT1cIidvdXRzaWRlJ1wiIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcD1cIm5nYlBvcG92ZXJcIiBwbGFjZW1lbnQ9XCJsZWZ0XCIgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiAobW9kZWwuc2hvd0xvZ3MgPyBwLm9wZW4oeyBsb2dzOiBtb2RlbC5sb2dzIH0pIDogbnVsbClcIlxuICA+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7bWV0aG9kTmFtZShtb2RlbCl9fTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXJcIj5be3ttb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyfX1dPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xIGhhcy10ZXh0LXt7bG9nQ29sb3JbbW9kZWwuc3RhdHVzXX19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCIgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIiBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcDE9XCJuZ2JQb3BvdmVyXCIgcGxhY2VtZW50PVwibGVmdFwiIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcDEuaXNPcGVuKCkgPyBwMS5jbG9zZSgpIDogcDEub3Blbih7IG1vZGVsLCBkYXRhIH0pXCJcbiAgICA+XG4gICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW21vZGVsLnN0YXR1c11cIj48L2ZhLWljb24+XG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5tb2RlbFwiPlxuICAgICAgKDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkb2NzTGluazsgY29udGV4dDogeyRpbXBsaWNpdDogbW9kZWwubW9kZWx9XCI+PC9uZy1jb250YWluZXI+KVxuICAgIDwvc3Bhbj5cbiAgPC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub1ZhbHVlPi08L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vdFJlY2FsY3VsYXRlZD5ub3QgcmVjYWxjdWxhdGVkPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dEZXRhaWxzIGxldC1sb2dzPVwibG9nc1wiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9ncz8ucmVxdWlyZW1lbnRzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtcmVxdWlyZW1lbnRcIiAqbmdGb3I9XCJsZXQga2V5IG9mIHJlcXVpcmVtZW50S2V5cyhsb2dzLnJlcXVpcmVtZW50cylcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6e2tleSwgdmFsdWU6bG9ncy5yZXF1aXJlbWVudHNba2V5XX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5sb2dzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtbG9nXCIgKm5nRm9yPVwibGV0IGtleSBvZiBsb2dzLmxvZ3MgfCBrZXlzXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OmtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwIGNsYXNzPVwibXQtMlwiPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIG1iLTBcIj5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aD5cbiAgICAgICAgICAgICAgICA8c3Bhbj5GaWxlbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxzcGFuPkNvbHVtbiBUaXRsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxzcGFuPlJvdyAodGVybS5pZCk8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5IGNsYXNzPVwiaGFzLWJhY2tncm91bmQtYmxhY2sgaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgZGF0YSBvZiBsb2dzLm1pc3NpbmdMb29rdXBzXCI+XG4gICAgICAgICAgICAgIDx0ZD57e2RhdGEuZmlsZW5hbWV9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57e2RhdGEuY29sdW1ufX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3tkYXRhLnRlcm1JZH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nTGluZVZhbHVlIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8bmctdGVtcGxhdGUgI2RlZmF1bHRWYWx1ZT5cbiAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIj57e3ZhbHVlfX08L3NwYW4+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJyZXF1aXJlbWVudExpbmtlZE5vZGUoa2V5LCB2YWx1ZSk7IGxldCBsaW5rZWROb2RlOyBlbHNlIGRlZmF1bHRWYWx1ZVwiPlxuICAgIDxoZS1ub2RlLWxpbmsgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCIgbGlua0NsYXNzPVwiaXMtZGFya1wiIFtub2RlXT1cImxpbmtlZE5vZGVcIiBbc2hvd0V4dGVybmFsTGlua109XCJ0cnVlXCI+PC9oZS1ub2RlLWxpbms+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0Pnt7a2V5IHwga2V5VG9MYWJlbH19PC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbm9kZV90eXBlX2FsbG93ZWQnXCI+SXMgdGhlIGN1cnJlbnQgPGNvZGU+Tm9kZTwvY29kZT4gYWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzaXRlVHlwZV9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IDxjb2RlPnNpdGVUeXBlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF9pZF9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdCA8Y29kZT5AaWQ8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+SXMgdGhlIGN1cnJlbnQgcHJpbWFyeSBwcm9kdWN0IDxjb2RlPnRlcm1UeXBlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInZ2Vvc3BhdGlhbF9kYXRhJ1wiPkhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5IYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidjdXJyZW50X3NpemUnXCI+Q3VycmVudCBwb2x5Z29uIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbWF4X2FyZWFfc2l6ZSdcIj5NYXhpbXVtIHBvbHlnb24gYXJlYSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidyZWdpb25fZmFjdG9yJ1wiPkZhY3RvciBmcm9tIHJlZ2lvbiBsb29rdXA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwZXN0aWNpZGVzX2NvbXBsZXRlJ1wiPlBlc3RpY2lkZSBkYXRhIGFyZSA8Y29kZT5jb21wbGV0ZTwvY29kZT48L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPkN5Y2xlIGNvbnRhaW5zIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPiBJbnB1dHM8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYWxsX3Blc3RpY2lkZUFJX2hhdmVfbG9va3VwX3ZhbHVlJ1wiPkFsbCA8Y29kZT5wZXN0aWNpZGVBSTwvY29kZT4gSW5wdXRzIGhhdmUgYSBsb29rdXAgdmFsdWU8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfYWJvdmVHcm91bmRDcm9wUmVzaWR1ZUJ1cm50J1wiPjxjb2RlPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT4gaXMgcHJlc2VudCBhcyBQcm9kdWN0PC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbGlxdWlkX3NsdXJyeV9zbHVkZ2VfUCdcIj5MaXF1aWQsIFNsdXJyeSwgYW5kIFNsdWRnZSBQPC9uZy1jb250YWluZXI+XG4gIDwvc3Bhbj5cbiAgPGhlLWNsaXBib2FyZCBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBjbGlwYm9hcmRDbGFzcz1cImlzLXNpemUtNyBpcy1wLTFcIiBbaWNvbl09XCJbJ2ZhcicsICdjbG9uZSddXCIgW3ZhbHVlXT1cImtleVwiIFtoaWRlVGV4dF09XCJ0cnVlXCI+PC9oZS1jbGlwYm9hcmQ+XG4gIDxzcGFuIGNsYXNzPVwiaXMtcHItMSBpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+Ojwvc3Bhbj5cbiAgPG5nLXRlbXBsYXRlICNzaW5nbGVWYWx1ZT5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZVZhbHVlOyBjb250ZXh0OntrZXksdmFsdWV9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxkaXYgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCIgKm5nSWY9XCJsb2dWYWx1ZUFycmF5KHZhbHVlKTsgbGV0IHZhbHVlQXJyYXk7IGVsc2Ugc2luZ2xlVmFsdWVcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1ib3JkZXJlZCBoYXMtYmFja2dyb3VuZC1zZWNvbmRhcnkgaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgIDx0aGVhZCAqbmdJZj1cInZhbHVlQXJyYXlbMF0gfCBpc09iamVjdFwiPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIiAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5WzBdIHwga2V5c1wiPnt7di5rZXl9fTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVwiPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlQXJyYXlWYWx1ZT5cbiAgICAgICAgICAgIDx0ZD57e3Z9fTwvdGQ+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidiB8IGlzT2JqZWN0OyBlbHNlIHNpbmdsZUFycmF5VmFsdWVcIj5cbiAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgdnYgb2YgdiB8IGtleXNcIj57e3Z2LnZhbHVlfX08L3RkPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nU3RhdHVzRGV0YWlscyBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cIm1vZGVsXCI+XG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxzcGFuPlN0YXR1czo8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57e21vZGVsLnN0YXR1c319PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICNzaG93UnVuT3JjaGVzdHJhdG9yPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLXJ1bi1vcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgPHAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5BbGwgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgPHAgKm5nSWY9XCIhbW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+XG4gICAgICAgICAgU29tZSBvZiB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbm90IG1ldCB0byBydW4gdGhlIG1vZGVsLlxuICAgICAgICAgIFlvdSBjYW4gY2xpY2sgb24gdGhlIG1vZGVsIG5hbWUgb24gdGhlIGxlZnQgdG8gdmlldyB0aGUgZGVidWdnaW5nIGxvZ3MuXG4gICAgICAgIDwvcD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVsLmxvZ3M/LmxvZ3M/LmVycm9yXCI+XG4gICAgICAgICAgPHA+VGhlIG1vZGVsIGZhaWxlZCB0byBydW4gZm9yIHRoZSBmb2xsb3dpbmcgcmVhc29uOjwvcD5cbiAgICAgICAgICA8cD48Y29kZT57e21vZGVsLmxvZ3MubG9ncy5lcnJvcn19PC9jb2RlPjwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLXJ1bi1vcmNoZXN0cmF0b3JcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1bk9yY2hlc3RyYXRvciA9PT0gZmFsc2U7IGVsc2Ugc2hvd1J1bk9yY2hlc3RyYXRvclwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzLnJ1blJlcXVpcmVkXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vZGUtdHlwZS1ub3QtYWxsb3dlZFwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5ub2RlX3R5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIFRoaXMgbW9kZWwgc2hvdWxkIG5vdCBydW4gZm9yIHt7bm9kZVR5cGUgfCBwbHVyYWxpemU6MH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctdGVtcGxhdGUgI3J1bk5vQ29uZmlnPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGUge3tkYXRhLnR5cGUgfHwgJ2JsYW5rIG5vZGUnfX0gd2l0aCBUZXJtIDxjb2RlPnt7ZGF0YS50ZXJtSWR9fTwvY29kZT4gaXMgYWxyZWFkeSBwcmVzZW50IG9yIGFscmVhZHkgYWRkZWQgYnkgYW5vdGhlciBtb2RlbC5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmNvbmZpZzsgZWxzZSBydW5Ob0NvbmZpZ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaXMtcnVuLXN0cmF0ZWd5LXt7bW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5fX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhbHdheXMnXCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWRkX2tleV9pZl9taXNzaW5nJ1wiPlxuICAgICAgICAgICAgV2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudFxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9ibGFua19ub2RlX2lmX21pc3NpbmcnXCI+XG4gICAgICAgICAgICBXZSBvbmx5IGdhcC1maWxsIHRoaXMgQmxhbmsgTm9kZSBpZiBub3QgcHJlc2VudC5cbiAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi13aXRoLW1lYXN1cmVkXCIgKm5nSWY9XCJtb2RlbC5jb25maWcucnVuQXJncz8ucnVuTm9uTWVhc3VyZWQgJiYgaGFzTWV0aG9kVGllcihkYXRhLm9yaWdpbmFsLCBFbWlzc2lvbk1ldGhvZFRpZXIubWVhc3VyZWQpXCI+XG4gICAgICAgICAgICBUaGUgPGNvZGU+e3ttb2RlbC5jb25maWcudmFsdWV9fTwvY29kZT4gd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXMgbWVhc3VyZWQuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLW1lcmdlLW9yY2hlc3RyYXRvclwiICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkTWVyZ2UgPT09IGZhbHNlXCI+XG4gICAgICA8cCBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VUaHJlc2hvbGRcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucmVwbGFjZVRocmVzaG9sZFwiPlxuICAgICAgICA8c3Bhbj5UaGU8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmZyb20gdGhpcyBtb2RlbCB3YXM8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bGVzcyB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZVRocmVzaG9sZCA9PT0gJ1RydWUnXCI+bW9yZSB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+e3ttb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDB9fSU8L3NwYW4+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bm90IHN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VUaHJlc2hvbGQgPT09ICdUcnVlJ1wiPnN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5kaWZmZXJlbnQgZnJvbSB0aGUgb3JpZ2luYWw8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX0uPC9zcGFuPlxuICAgICAgPC9wPlxuICAgIDwvZGl2PlxuICAgIDxwIGNsYXNzPVwiaXMtbWVyZ2UtcmVwbGFjZUxvd2VyVGllclwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5yZXBsYWNlTG93ZXJUaWVyXCI+XG4gICAgICA8c3Bhbj5UaGUgbW9kZWwgPGNvZGU+bWV0aG9kVGllcjwvY29kZT4gd2FzPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ0ZhbHNlJ1wiPmhpZ2hlciB0aGFuPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ1RydWUnXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnRoZSBvcmlnaW5hbCA8Y29kZT5tZXRob2RUaWVyPC9jb2RlPjwvc3Bhbj5cbiAgICA8L3A+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNkb2NzTGluayBsZXQtbW9kZWw+XG4gIDxhIFtocmVmXT1cIm1vZGVsLmFwaURvY3NQYXRoIHx8IG1vZGVsLmRvY1BhdGggfHwgbW9kZWwucGF0aFwiIHRhcmdldD1cIl9ibGFua1wiXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gID5cbiAgICA8c3Bhbj5Eb2NzPC9zcGFuPlxuICAgIDxmYS1pY29uIGNsYXNzPVwibWwtMVwiIGljb249XCJleHRlcm5hbC1saW5rLWFsdFwiIHNpemU9XCJzbVwiPjwvZmEtaWNvbj5cbiAgPC9hPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
196
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQVMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGtCQUFrQixFQUF1QixRQUFRLEVBQVEsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0csT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQ2lDLFNBQVMsRUFBMkIsZ0JBQWdCLEVBQUUsZUFBZSxFQUMzRyxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDeEMsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0RixPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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QUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUk7WUFDM0IsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJO1lBQ3RCLEtBQUssRUFBRSxFQUFFO1lBQ1QsSUFBSSxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7U0FDVCxDQUFDO0lBQ25CLENBQUM7O29IQS9LVSx1QkFBdUI7d0dBQXZCLHVCQUF1Qiw2UENwRnBDLG11cUJBc2JBOzJGRGxXYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCO2dLQWdCdkIsSUFBSTtzQkFEWCxLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSztnQkFHRSxjQUFjO3NCQURyQixLQUFLO2dCQUdFLGtCQUFrQjtzQkFEekIsS0FBSztnQkFHRSxLQUFLO3NCQURaLEtBQUs7Z0JBR0UsZUFBZTtzQkFEdEIsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG1lcmdlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3QsIGZpbHRlciwgcmVkdWNlLCB0b0FycmF5LCBtYXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzd2l0Y2hNYXAsIG1lcmdlTWFwLCBtZXJnZUFsbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEVtaXNzaW9uTWV0aG9kVGllciwgSVRlcm1KU09OTEQsIEpTT05MRCwgTm9kZVR5cGUsIFRlcm0sIFRlcm1UZXJtVHlwZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IGtleVRvTGFiZWwgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcbmltcG9ydCB7IHByb3BlcnR5VmFsdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzL2Rpc3QvdGVybSc7XG5cbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSwgSUJsYW5rTm9kZUxvZywgTG9nU3RhdHVzLCBJQ29uZmlnTW9kZWwsIGJsYW5rTm9kZSwgZ3JvdXBMb2dzQnlNb2RlbCwgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LCBjb21wdXRlVGVybXMsIGxvZ1ZhbHVlQXJyYXlcbn0gZnJvbSAnLi9ub2RlLWxvZ3MtbW9kZWxzLm1vZGVsJztcbmltcG9ydCB7IElKU09OTm9kZSwgSGVOb2RlU2VydmljZSB9IGZyb20gJy4uL25vZGUuc2VydmljZSc7XG5pbXBvcnQgeyBIZUVuZ2luZVNlcnZpY2UsIElNb2RlbCB9IGZyb20gJy4uLy4uL2VuZ2luZS9lbmdpbmUuc2VydmljZSc7XG5pbXBvcnQgeyBtYXRjaEV4YWN0UXVlcnksIG1hdGNoVGVybVR5cGUsIG1hdGNoVHlwZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2gubW9kZWwnO1xuaW1wb3J0IHsgSGVTZWFyY2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5zZXJ2aWNlJztcbmltcG9ydCB7IGJhc2VVcmwsIGlzRXh0ZXJuYWwgfSBmcm9tICcuLi8uLi9jb21tb24vdXRpbHMnO1xuaW1wb3J0IHsgdGVybVR5cGVMYWJlbCB9IGZyb20gJy4uLy4uL3Rlcm1zL3Rlcm1zLm1vZGVsJztcblxuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaydcbn07XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgbW9kZWw/OiBJTW9kZWwpID0+XG4gIChcbiAgICBtZXRob2RJZFxuICAgICAgPyAoe1xuICAgICAgICAnY3ljbGUvdHJhbnNmb3JtYXRpb24nOiAnRGF0YSBGcm9tIFRyYW5zZm9ybWF0aW9uJyxcbiAgICAgICAgaW1wYWN0X2Fzc2Vzc21lbnQ6ICdEYXRhIEZyb20gQ3ljbGUnXG4gICAgICB9KVttZXRob2RJZF1cbiAgICAgIDogJydcbiAgKSB8fCAoXG4gICAgbWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKVxuICApO1xuXG5jb25zdCBnZXRNb2RlbHNBdCA9IChsb2c6IElCbGFua05vZGVMb2dTdWJWYWx1ZSB8IElCbGFua05vZGVMb2csIGluZGV4OiBudW1iZXIpID0+XG4gICgnbW9kZWxzSW5TdWJWYWx1ZXMnIGluIGxvZyA/ICFsb2cubW9kZWxzSW5TdWJWYWx1ZXMgfHwgIWxvZy5pc09wZW4gOiB0cnVlKSAmJiBsb2cuY29uZmlnTW9kZWxzW2luZGV4XTtcblxuY29uc3QgcmVxdWlyZW1lbnRLZXlzID0gKHJlcXVpcmVtZW50czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkgPT5cbiAgT2JqZWN0LmtleXMocmVxdWlyZW1lbnRzKS5maWx0ZXIoayA9PiAhbm9kZVR5cGVzTG93ZXJDYXNlLmluY2x1ZGVzKGspKTtcblxuY29uc3QgcmVxdWlyZW1lbnRDb2xvciA9ICh2YWx1ZTogYW55KSA9PiAhdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnO1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleToge1xuICBba2V5OiBzdHJpbmddOiAodmFsdWU6IHN0cmluZykgPT4gUGFydGlhbDxKU09OTEQ8Tm9kZVR5cGU+Pjtcbn0gPSB7XG4gIHJlbGF0ZWRfY3ljbGVzOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgY3ljbGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBpbXBhY3RfYXNzZXNzbWVudF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5JbXBhY3RBc3Nlc3NtZW50LCAnQGlkJzogdiB9KSxcbiAgc2l0ZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5TaXRlLCAnQGlkJzogdiB9KSxcbiAgc291cmNlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNvdXJjZSwgJ0BpZCc6IHYgfSlcbn07XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT5cbiAga2V5IGluIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5ICYmXG4gIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5W2tleV0odmFsdWUpO1xuXG5jb25zdCBpc1N5c3RlbUJvdW5kYXJ5ID0gKFxuICB7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUJsYW5rTm9kZUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz5cbikgPT4gW1xuICBpc1JlY2FsY3VsYXRlZCxcbiAgaXNSZXF1aXJlZFxuXS5zb21lKEJvb2xlYW4pO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoZS1ub2RlLWxvZ3MtbW9kZWxzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTm9kZUxvZ3NNb2RlbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGxvZ3M6IHN0cmluZztcbiAgcHJpdmF0ZSBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5Pzogc3RyaW5nO1xuICBASW5wdXQoKVxuICBwcml2YXRlIG9yaWdpbmFsVmFsdWVzOiBibGFua05vZGVbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHJlY2FsY3VsYXRlZFZhbHVlczogYmxhbmtOb2RlW10gPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSB0ZXJtczogSVRlcm1KU09OTERbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGZpbHRlclRlcm1UeXBlcz86IFRlcm1UZXJtVHlwZVtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGxvZ3NLZXk/OiBzdHJpbmc7XG5cbiAgcHVibGljIGxvZ3NVcmw/OiBzdHJpbmc7XG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgaXNFeHRlcm5hbCA9IGlzRXh0ZXJuYWwoKTtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBsb2FkaW5nID0gdHJ1ZTtcbiAgcHVibGljIG5vZGVUeXBlOiBOb2RlVHlwZTtcbiAgcHVibGljIGJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwdWJsaWMgbWV0aG9kTW9kZWxzQ291bnQgPSAwO1xuICBwdWJsaWMgcm93c0NvdW50ID0gMDtcbiAgcHVibGljIG9ubHlSZXF1aXJlZCA9IHRydWU7XG4gIHB1YmxpYyBzaG93TGVnZW5kID0gdHJ1ZTtcblxuICBwdWJsaWMgdGVybT86IHN0cmluZztcbiAgcHVibGljIHN1Z2dlc3RUZXJtID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pID0+XG4gICAgdGV4dCQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzd2l0Y2hNYXAodiA9PiB0aGlzLnN1Z2dlc3RCeVRlcm0odikpLFxuICAgICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBub2RlU2VydmljZTogSGVOb2RlU2VydmljZSxcbiAgICBwcml2YXRlIHNlYXJjaFNlcnZpY2U6IEhlU2VhcmNoU2VydmljZSxcbiAgICBwcml2YXRlIGVuZ2luZVNlcnZpY2U6IEhlRW5naW5lU2VydmljZVxuICApIHsgfVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUpO1xuXG4gICAgY29uc3QgbW9kZWxzID0gYXdhaXQgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFtcbiAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksXG4gICAgICAgICAgbWF0Y2hUZXJtVHlwZShUZXJtVGVybVR5cGUubW9kZWwpXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubWV0aG9kc0J5SWQgPSBhd2FpdCBmcm9tKG1vZGVscykucGlwZShcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICBkaXN0aW5jdCh2ID0+IHZbJ0BpZCddKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIC8vIGZyb20gYG1vZGVsLWxpbmtzLmpzb25gIGZpbGVcbiAgICBjb25zdCBlbmdpbmVNb2RlbHMgPSBhd2FpdCB0aGlzLmVuZ2luZVNlcnZpY2UubW9kZWxzKCk7XG5cbiAgICB0aGlzLmFsbFRlcm1zID0gYXdhaXQgY29tcHV0ZVRlcm1zKHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLnRlcm1zLCB0aGlzLmZpbHRlclRlcm1UeXBlcyk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAoXG4gICAgICBncm91cExvZ3NCeVRlcm0odGhpcy5ub2RlVHlwZSwgbG9ncywgZW5naW5lTW9kZWxzLCBjb25maWcsIHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLm5vZGVLZXkpXG4gICAgKTtcbiAgICB0aGlzLm1ldGhvZE1vZGVsc0NvdW50ID0gbW9kZWxDb3VudCh0aGlzLmFsbEJsYW5rTm9kZXMpO1xuICAgIHRoaXMucm93c0NvdW50ID0gdGhpcy5hbGxCbGFua05vZGVzLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIDEgKyBjdXJyLnN1YlZhbHVlcy5sZW5ndGggKyBjdXJyLmtleXMubGVuZ3RoLCAwKTtcblxuICAgIHRoaXMudGVybXNCeUlkID0gYXdhaXQgb2YodGhpcy5hbGxCbGFua05vZGVzKS5waXBlKFxuICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICBtYXAodiA9PiB2LmlkKSxcbiAgICAgIGRpc3RpbmN0KCksXG4gICAgICB0b0FycmF5KCksXG4gICAgICBtZXJnZU1hcChpZHMgPT4gZnJvbSh0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgYm9vbDoge1xuICAgICAgICAgIG11c3Q6IFtcbiAgICAgICAgICAgIG1hdGNoVHlwZShOb2RlVHlwZS5UZXJtKVxuICAgICAgICAgIF0sXG4gICAgICAgICAgc2hvdWxkOiBpZHMubWFwKGlkID0+IG1hdGNoRXhhY3RRdWVyeSgnQGlkJywgaWQpKSxcbiAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICB9XG4gICAgICB9KSkpLFxuICAgICAgbWVyZ2VBbGwoKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIHRoaXMuZmlsdGVyUmVzdWx0cygpO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGdldExvZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZVNlcnZpY2UuZ2V0TG9nKHRoaXMubm9kZSkudG9Qcm9taXNlKCk7XG4gIH1cblxuICBwcml2YXRlIHN1Z2dlc3RCeVRlcm0odGVybTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGZyb20odGhpcy5hbGxUZXJtcykucGlwZShcbiAgICAgIG1hcCh2ID0+IHYubmFtZSksXG4gICAgICBmaWx0ZXIodiA9PiB2LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybS50b0xvd2VyQ2FzZSgpKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwdWJsaWMgdHJhY2tCeUJsYW5rTm9kZShfaW5kZXg6IG51bWJlciwgbm9kZTogSUJsYW5rTm9kZUxvZykge1xuICAgIHJldHVybiBub2RlLnRlcm1JZDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZmlsdGVyZWRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRlcm1UeXBlcz8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlclJlc3VsdHMoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmJsYW5rTm9kZXMgPSB0aGlzLmFsbEJsYW5rTm9kZXMuZmlsdGVyKCh7IHRlcm06IHsgbmFtZSB9LCBzdWJWYWx1ZXMsIC4uLmxvZyB9KSA9PlxuICAgICAgICB0aGlzLnRlcm1cbiAgICAgICAgICA/IG5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLnRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICA6IChcbiAgICAgICAgICAgICF0aGlzLmZpbHRlclRlcm1UeXBlcz8ubGVuZ3RoIHx8XG4gICAgICAgICAgICAhdGhpcy5vbmx5UmVxdWlyZWQgfHwgaXNTeXN0ZW1Cb3VuZGFyeShsb2cpIHx8IHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkpXG4gICAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkW21ldGhvZElkXT8ubmFtZSB8fCBtZXRob2RJZExhYmVsKG1ldGhvZElkLCBtb2RlbCk7XG4gIH1cblxuICBwdWJsaWMgaGFzTWV0aG9kVGllcih2YWx1ZXM6IGJsYW5rTm9kZVtdLCBtZXRob2RUaWVyOiBFbWlzc2lvbk1ldGhvZFRpZXIpIHtcbiAgICByZXR1cm4gdmFsdWVzLnNvbWUodiA9PiAnbWV0aG9kVGllcicgaW4gdiAmJiB2Lm1ldGhvZFRpZXIgPT09IG1ldGhvZFRpZXIpO1xuICB9XG5cbiAgcHVibGljIHRlcm1CeUlkKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50ZXJtc0J5SWRbaWRdIHx8IHtcbiAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAnQGlkJzogaWQsXG4gICAgICBuYW1lOiB0ZXJtVHlwZUxhYmVsKGlkKVxuICAgIH0gYXMgSVRlcm1KU09OTEQ7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweC0zIHBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IG1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsXCI+XG4gICAgPGEgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cImxvZ3NVcmxcIiBbaHJlZl09XCJsb2dzVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgW25iUm93c109XCJyb3dzQ291bnRcIiBtYXhIZWlnaHQ9XCIzMjBcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1mdWxsd2lkdGggaXMtbmFycm93IGlzLXN0cmlwZWRcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250cm9sIGlzLWV4cGFuZGVkIGhhcy1pY29ucy1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRlcm1cIiBuYW1lPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkZpbHRlciBieSBuYW1lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ2JUeXBlYWhlYWRdPVwic3VnZ2VzdFRlcm1cIlxuICAgICAgICAgICAgICAgICAgW2ZvY3VzRmlyc3RdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwiZmlsdGVyUmVzdWx0cygpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJpY29uIGlzLXNtYWxsIGlzLXJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXRlcm1cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRlcm0gPSAnJzsgZmlsdGVyUmVzdWx0cygpO1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInRpbWVzXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5Vbml0czwvdGg+XG4gICAgICAgICAgPHRoPk9yaWdpbmFsPC90aD5cbiAgICAgICAgICA8dGg+UmVjYWxjdWxhdGVkPC90aD5cbiAgICAgICAgICA8dGg+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj4oe3tpICsgMX19KTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZyAmJiBibGFua05vZGVzLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxzcGFuPk5vIGRhdGE8L3NwYW4+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYmxhbmtOb2RlIG9mIGJsYW5rTm9kZXM7IHRyYWNrQnk6IHRyYWNrQnlCbGFua05vZGVcIj5cbiAgICAgICAgICA8dHIgW2NsYXNzLmhhcy1zdWItcm93c109XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMiBvcGVuLW5vZGVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJibGFua05vZGUuaXNPcGVuID0gIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLmNhbk9wZW5cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgW25vZGVdPVwiYmxhbmtOb2RlLnRlcm1cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcCBoYXMtdGV4dC1lbGxpcHNpc1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7YmxhbmtOb2RlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdE9yaWdpbmFsVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFibGFua05vZGUuaXNPcmlnaW5hbCB8fCBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWU+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57e2JsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJpcy1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVsdGFWYWx1ZT5cbiAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YSAqbmdJZj1cImJsYW5rTm9kZS5vcmlnaW5hbC5sZW5ndGggJiYgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbb3JpZ2luYWxWYWx1ZV09XCJibGFua05vZGUub3JpZ2luYWxWYWx1ZVwiXG4gICAgICAgICAgICAgICAgPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0RGVsdGFWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgIDxoZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbCAmJiBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiXG4gICAgICAgICAgICAgICAgICA+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7ZGF0YTogYmxhbmtOb2RlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTMgcHItMSBmaWVsZC1ub2RlXCI+RmllbGQ6PC9zcGFuPlxuXG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nSWY9XCJibGFua05vZGUudHlwZVwiXG4gICAgICAgICAgICAgICAgW2hyZWZdPVwiYmFzZVVybCArICcvc2NoZW1hLycgKyBibGFua05vZGUudHlwZSArICcjJyArIHN1YlZhbHVlLmtleVwiIHRhcmdldD1cIl9ibGFua1wiIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIj57e3N1YlZhbHVlLmtleX19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcFwiICpuZ0lmPVwiIWJsYW5rTm9kZS50eXBlXCI+e3tzdWJWYWx1ZS5rZXl9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj57e3N1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkIHx8IHN1YlZhbHVlLmtleSA9PT0gJ2ltcGFjdEFzc2Vzc21lbnQnOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7c3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHtkYXRhOiBzdWJWYWx1ZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLnN1YlZhbHVlc1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTNcIj57e3N1YlZhbHVlLmtleSB8IGtleVRvTGFiZWx9fTwvc3Bhbj5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3ViVmFsdWUuaWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0xXCI+Ojwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInN1YlZhbHVlLmtleVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiAqbmdTd2l0Y2hDYXNlPVwiJ2JhY2tncm91bmREYXRhJ1wiPnt7c3ViVmFsdWUuaWQgfCBrZXlUb0xhYmVsfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rICpuZ1N3aXRjaERlZmF1bHQgY2xhc3M9XCJpcy1ibG9jayBwbC00XCIgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCIgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIiBbaW5uZXJIdG1sXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLnNob3dVbml0c1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPnt7c3ViVmFsdWUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3tzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPi08L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDoge2RhdGE6IHN1YlZhbHVlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2hlLWRhdGEtdGFibGU+XG5cbiAgPGRpdiBjbGFzcz1cImlzLXNpemUtNyBpcy1pdGFsaWNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1ucyBpcy12YXJpYWJsZSBpcy0xIG15LTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaXMtbmFycm93XCI+XG4gICAgICAgIDxwPlxuICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIHByLTJcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7bG9nQ29sb3Jbc3RhdHVzLnZhbHVlXX19XCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bc3RhdHVzLnZhbHVlXVwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+e3tzdGF0dXMudmFsdWV9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaGFzLXRleHQtcmlnaHRcIiAqbmdJZj1cImZpbHRlcmVkVHlwZVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJzZWxlY3RvclwiXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cImZpbHRlclJlc3VsdHMoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2hvdyBvbmx5IHt7ZmlsdGVyZWRUeXBlIHwgcGx1cmFsaXplfX0gaW5jbHVkZWQgaW4gdGhlIGRlZmF1bHQgSGVzdGlhIHN5c3RlbSBib3VuZGFyeTwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHRkIGNsYXNzPVwiYmxhbmstbm9kZS1pbmRleC17e2l9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0TW9kZWxzQXQoZGF0YSwgaSk7IGxldCBtb2RlbHM7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgPG5nLXRlbXBsYXRlICNtb2RlbFNlcmllPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHttb2RlbDptb2RlbHMsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cIm1vZGVscyB8IGlzQXJyYXk7IGVsc2UgbW9kZWxTZXJpZVwiPlxuICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7bW9kZWwsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3RkPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbCBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8c3BhblxuICAgIFtjbGFzcy50cmlnZ2VyLXBvcG92ZXJdPVwibW9kZWwuc2hvd0xvZ3NcIlxuICAgIFtuZ2JQb3BvdmVyXT1cImxvZ0RldGFpbHNcIiBbYXV0b0Nsb3NlXT1cIidvdXRzaWRlJ1wiIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcD1cIm5nYlBvcG92ZXJcIiBwbGFjZW1lbnQ9XCJsZWZ0XCIgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiAobW9kZWwuc2hvd0xvZ3MgPyBwLm9wZW4oeyBsb2dzOiBtb2RlbC5sb2dzIH0pIDogbnVsbClcIlxuICA+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7bWV0aG9kTmFtZShtb2RlbCl9fTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXJcIj5be3ttb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyfX1dPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xIGhhcy10ZXh0LXt7bG9nQ29sb3JbbW9kZWwuc3RhdHVzXX19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCIgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIiBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcDE9XCJuZ2JQb3BvdmVyXCIgcGxhY2VtZW50PVwibGVmdFwiIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcDEuaXNPcGVuKCkgPyBwMS5jbG9zZSgpIDogcDEub3Blbih7IG1vZGVsLCBkYXRhIH0pXCJcbiAgICA+XG4gICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW21vZGVsLnN0YXR1c11cIj48L2ZhLWljb24+XG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5tb2RlbFwiPlxuICAgICAgKDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkb2NzTGluazsgY29udGV4dDogeyRpbXBsaWNpdDogbW9kZWwubW9kZWx9XCI+PC9uZy1jb250YWluZXI+KVxuICAgIDwvc3Bhbj5cbiAgPC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub1ZhbHVlPi08L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vdFJlY2FsY3VsYXRlZD5ub3QgcmVjYWxjdWxhdGVkPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dEZXRhaWxzIGxldC1sb2dzPVwibG9nc1wiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9ncz8ucmVxdWlyZW1lbnRzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtcmVxdWlyZW1lbnRcIiAqbmdGb3I9XCJsZXQga2V5IG9mIHJlcXVpcmVtZW50S2V5cyhsb2dzLnJlcXVpcmVtZW50cylcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6e2tleSwgdmFsdWU6bG9ncy5yZXF1aXJlbWVudHNba2V5XX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5sb2dzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtbG9nXCIgKm5nRm9yPVwibGV0IGtleSBvZiBsb2dzLmxvZ3MgfCBrZXlzXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OmtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwIGNsYXNzPVwibXQtMlwiPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIG1iLTBcIj5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aD5cbiAgICAgICAgICAgICAgICA8c3Bhbj5GaWxlbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxzcGFuPkNvbHVtbiBUaXRsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxzcGFuPlJvdyAodGVybS5pZCk8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5IGNsYXNzPVwiaGFzLWJhY2tncm91bmQtYmxhY2sgaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgZGF0YSBvZiBsb2dzLm1pc3NpbmdMb29rdXBzXCI+XG4gICAgICAgICAgICAgIDx0ZD57e2RhdGEuZmlsZW5hbWV9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57e2RhdGEuY29sdW1ufX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3tkYXRhLnRlcm1JZH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nTGluZVZhbHVlIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8bmctdGVtcGxhdGUgI2RlZmF1bHRWYWx1ZT5cbiAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIj57e3ZhbHVlfX08L3NwYW4+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJyZXF1aXJlbWVudExpbmtlZE5vZGUoa2V5LCB2YWx1ZSk7IGxldCBsaW5rZWROb2RlOyBlbHNlIGRlZmF1bHRWYWx1ZVwiPlxuICAgIDxoZS1ub2RlLWxpbmsgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCIgbGlua0NsYXNzPVwiaXMtZGFya1wiIFtub2RlXT1cImxpbmtlZE5vZGVcIiBbc2hvd0V4dGVybmFsTGlua109XCJ0cnVlXCI+PC9oZS1ub2RlLWxpbms+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0Pnt7a2V5IHwga2V5VG9MYWJlbH19PC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbm9kZV90eXBlX2FsbG93ZWQnXCI+SXMgdGhlIGN1cnJlbnQgPGNvZGU+Tm9kZTwvY29kZT4gYWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzaXRlVHlwZV9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IDxjb2RlPnNpdGVUeXBlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF9pZF9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdCA8Y29kZT5AaWQ8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+SXMgdGhlIGN1cnJlbnQgcHJpbWFyeSBwcm9kdWN0IDxjb2RlPnRlcm1UeXBlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInZ2Vvc3BhdGlhbF9kYXRhJ1wiPkhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5IYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidjdXJyZW50X3NpemUnXCI+Q3VycmVudCBwb2x5Z29uIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbWF4X2FyZWFfc2l6ZSdcIj5NYXhpbXVtIHBvbHlnb24gYXJlYSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidyZWdpb25fZmFjdG9yJ1wiPkZhY3RvciBmcm9tIHJlZ2lvbiBsb29rdXA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwZXN0aWNpZGVzX2NvbXBsZXRlJ1wiPlBlc3RpY2lkZSBkYXRhIGFyZSA8Y29kZT5jb21wbGV0ZTwvY29kZT48L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPkN5Y2xlIGNvbnRhaW5zIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPiBJbnB1dHM8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYWxsX3Blc3RpY2lkZUFJX2hhdmVfbG9va3VwX3ZhbHVlJ1wiPkFsbCA8Y29kZT5wZXN0aWNpZGVBSTwvY29kZT4gSW5wdXRzIGhhdmUgYSBsb29rdXAgdmFsdWU8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfY3JvcF9yZXNpZHVlX2J1cm50J1wiPjxjb2RlPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT4gaXMgcHJlc2VudCBhcyBQcm9kdWN0PC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbGlxdWlkX3NsdXJyeV9zbHVkZ2VfUCdcIj5MaXF1aWQsIFNsdXJyeSwgYW5kIFNsdWRnZSBQPC9uZy1jb250YWluZXI+XG4gIDwvc3Bhbj5cbiAgPGhlLWNsaXBib2FyZCBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBjbGlwYm9hcmRDbGFzcz1cImlzLXNpemUtNyBpcy1wLTFcIiBbaWNvbl09XCJbJ2ZhcicsICdjbG9uZSddXCIgW3ZhbHVlXT1cImtleVwiIFtoaWRlVGV4dF09XCJ0cnVlXCI+PC9oZS1jbGlwYm9hcmQ+XG4gIDxzcGFuIGNsYXNzPVwiaXMtcHItMSBpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+Ojwvc3Bhbj5cbiAgPG5nLXRlbXBsYXRlICNzaW5nbGVWYWx1ZT5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZVZhbHVlOyBjb250ZXh0OntrZXksdmFsdWV9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxkaXYgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCIgKm5nSWY9XCJsb2dWYWx1ZUFycmF5KHZhbHVlKTsgbGV0IHZhbHVlQXJyYXk7IGVsc2Ugc2luZ2xlVmFsdWVcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1ib3JkZXJlZCBoYXMtYmFja2dyb3VuZC1zZWNvbmRhcnkgaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgIDx0aGVhZCAqbmdJZj1cInZhbHVlQXJyYXlbMF0gfCBpc09iamVjdFwiPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIiAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5WzBdIHwga2V5c1wiPnt7di5rZXl9fTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVwiPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlQXJyYXlWYWx1ZT5cbiAgICAgICAgICAgIDx0ZD57e3Z9fTwvdGQ+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidiB8IGlzT2JqZWN0OyBlbHNlIHNpbmdsZUFycmF5VmFsdWVcIj5cbiAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgdnYgb2YgdiB8IGtleXNcIj57e3Z2LnZhbHVlfX08L3RkPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nU3RhdHVzRGV0YWlscyBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cIm1vZGVsXCI+XG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxzcGFuPlN0YXR1czo8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57e21vZGVsLnN0YXR1c319PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICNzaG93UnVuT3JjaGVzdHJhdG9yPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLXJ1bi1vcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgPHAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5BbGwgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgPHAgKm5nSWY9XCIhbW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+XG4gICAgICAgICAgU29tZSBvZiB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbm90IG1ldCB0byBydW4gdGhlIG1vZGVsLlxuICAgICAgICAgIFlvdSBjYW4gY2xpY2sgb24gdGhlIG1vZGVsIG5hbWUgb24gdGhlIGxlZnQgdG8gdmlldyB0aGUgZGVidWdnaW5nIGxvZ3MuXG4gICAgICAgIDwvcD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVsLmxvZ3M/LmxvZ3M/LmVycm9yXCI+XG4gICAgICAgICAgPHA+VGhlIG1vZGVsIGZhaWxlZCB0byBydW4gZm9yIHRoZSBmb2xsb3dpbmcgcmVhc29uOjwvcD5cbiAgICAgICAgICA8cD48Y29kZT57e21vZGVsLmxvZ3MubG9ncy5lcnJvcn19PC9jb2RlPjwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLXJ1bi1vcmNoZXN0cmF0b3JcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1bk9yY2hlc3RyYXRvciA9PT0gZmFsc2U7IGVsc2Ugc2hvd1J1bk9yY2hlc3RyYXRvclwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzLnJ1blJlcXVpcmVkXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vZGUtdHlwZS1ub3QtYWxsb3dlZFwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5ub2RlX3R5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIFRoaXMgbW9kZWwgc2hvdWxkIG5vdCBydW4gZm9yIHt7bm9kZVR5cGUgfCBwbHVyYWxpemU6MH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctdGVtcGxhdGUgI3J1bk5vQ29uZmlnPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGUge3tkYXRhLnR5cGUgfHwgJ2JsYW5rIG5vZGUnfX0gd2l0aCBUZXJtIDxjb2RlPnt7ZGF0YS50ZXJtSWR9fTwvY29kZT4gaXMgYWxyZWFkeSBwcmVzZW50IG9yIGFscmVhZHkgYWRkZWQgYnkgYW5vdGhlciBtb2RlbC5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmNvbmZpZzsgZWxzZSBydW5Ob0NvbmZpZ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaXMtcnVuLXN0cmF0ZWd5LXt7bW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5fX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhbHdheXMnXCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWRkX2tleV9pZl9taXNzaW5nJ1wiPlxuICAgICAgICAgICAgV2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudFxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9ibGFua19ub2RlX2lmX21pc3NpbmcnXCI+XG4gICAgICAgICAgICBXZSBvbmx5IGdhcC1maWxsIHRoaXMgQmxhbmsgTm9kZSBpZiBub3QgcHJlc2VudC5cbiAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi13aXRoLW1lYXN1cmVkXCIgKm5nSWY9XCJtb2RlbC5jb25maWcucnVuQXJncz8ucnVuTm9uTWVhc3VyZWQgJiYgaGFzTWV0aG9kVGllcihkYXRhLm9yaWdpbmFsLCBFbWlzc2lvbk1ldGhvZFRpZXIubWVhc3VyZWQpXCI+XG4gICAgICAgICAgICBUaGUgPGNvZGU+e3ttb2RlbC5jb25maWcudmFsdWV9fTwvY29kZT4gd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXMgbWVhc3VyZWQuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLW1lcmdlLW9yY2hlc3RyYXRvclwiICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkTWVyZ2UgPT09IGZhbHNlXCI+XG4gICAgICA8cCBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VUaHJlc2hvbGRcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucmVwbGFjZVRocmVzaG9sZFwiPlxuICAgICAgICA8c3Bhbj5UaGU8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmZyb20gdGhpcyBtb2RlbCB3YXM8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bGVzcyB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZVRocmVzaG9sZCA9PT0gJ1RydWUnXCI+bW9yZSB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+e3ttb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDB9fSU8L3NwYW4+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bm90IHN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VUaHJlc2hvbGQgPT09ICdUcnVlJ1wiPnN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5kaWZmZXJlbnQgZnJvbSB0aGUgb3JpZ2luYWw8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX0uPC9zcGFuPlxuICAgICAgPC9wPlxuICAgIDwvZGl2PlxuICAgIDxwIGNsYXNzPVwiaXMtbWVyZ2UtcmVwbGFjZUxvd2VyVGllclwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5yZXBsYWNlTG93ZXJUaWVyXCI+XG4gICAgICA8c3Bhbj5UaGUgbW9kZWwgPGNvZGU+bWV0aG9kVGllcjwvY29kZT4gd2FzPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ0ZhbHNlJ1wiPmhpZ2hlciB0aGFuPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ1RydWUnXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnRoZSBvcmlnaW5hbCA8Y29kZT5tZXRob2RUaWVyPC9jb2RlPjwvc3Bhbj5cbiAgICA8L3A+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNkb2NzTGluayBsZXQtbW9kZWw+XG4gIDxhIFtocmVmXT1cIm1vZGVsLmFwaURvY3NQYXRoIHx8IG1vZGVsLmRvY1BhdGggfHwgbW9kZWwucGF0aFwiIHRhcmdldD1cIl9ibGFua1wiXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gID5cbiAgICA8c3Bhbj5Eb2NzPC9zcGFuPlxuICAgIDxmYS1pY29uIGNsYXNzPVwibWwtMVwiIGljb249XCJleHRlcm5hbC1saW5rLWFsdFwiIHNpemU9XCJzbVwiPjwvZmEtaWNvbj5cbiAgPC9hPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==