@hestia-earth/ui-components 0.25.0 → 0.25.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/engine/index.d.ts +0 -1
- package/esm2022/engine/engine-models-version-link/engine-models-version-link.component.mjs +2 -2
- package/esm2022/engine/index.mjs +1 -2
- package/esm2022/files/files-error.model.mjs +20 -4
- package/esm2022/node/index.mjs +2 -1
- package/esm2022/node/node-logs-models/node-logs-models.component.mjs +4 -10
- package/esm2022/node/node-model-version.mjs +26 -0
- package/esm2022/schema/schema-validation.model.mjs +1 -1
- package/fesm2022/hestia-earth-ui-components.mjs +685 -675
- package/fesm2022/hestia-earth-ui-components.mjs.map +1 -1
- package/node/index.d.ts +1 -0
- package/node/node-logs-models/node-logs-models.component.d.ts +0 -2
- package/package.json +1 -1
- package/schema/schema-validation.model.d.ts +1 -1
- package/esm2022/engine/engine-models-version-link/engine-models-version-link.model.mjs +0 -26
- /package/{engine/engine-models-version-link/engine-models-version-link.model.d.ts → node/node-model-version.d.ts} +0 -0
|
@@ -10,10 +10,10 @@ import { DataState } from '@hestia-earth/api';
|
|
|
10
10
|
import { BlankNodesKey } from '../../common/node-utils';
|
|
11
11
|
import { baseUrl, isExternal, typeaheadFocus } from '../../common/utils';
|
|
12
12
|
import { LogStatus, groupLogsByModel, groupLogsByTerm, modelCount, computeTerms, logValueArray, groupdLogsByKey, computeKeys } from './node-logs-models.model';
|
|
13
|
+
import { nodeVersion } from '../node-model-version';
|
|
13
14
|
import { findOrchestratorModel } from '../../engine/engine.service';
|
|
14
15
|
import { matchExactQuery, matchId, matchTermType, matchType } from '../../search/search.model';
|
|
15
16
|
import { termTypeLabel } from '../../terms/terms.model';
|
|
16
|
-
import { nodeVersion } from '../../engine';
|
|
17
17
|
import * as i0 from "@angular/core";
|
|
18
18
|
import * as i1 from "../node.service";
|
|
19
19
|
import * as i2 from "../../search/search.service";
|
|
@@ -314,12 +314,6 @@ export class NodeLogsModelsComponent {
|
|
|
314
314
|
trackByBlankNode(_index, node) {
|
|
315
315
|
return node.termId || node.key;
|
|
316
316
|
}
|
|
317
|
-
termChanged(value) {
|
|
318
|
-
this.term.set(value);
|
|
319
|
-
}
|
|
320
|
-
onlyRequiredChanged(value) {
|
|
321
|
-
this.onlyRequired.set(value);
|
|
322
|
-
}
|
|
323
317
|
methodName({ methodId, model }) {
|
|
324
318
|
return this.methodsById()?.[methodId]?.name || methodIdLabel(methodId, model);
|
|
325
319
|
}
|
|
@@ -335,11 +329,11 @@ export class NodeLogsModelsComponent {
|
|
|
335
329
|
});
|
|
336
330
|
}
|
|
337
331
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeLogsModelsComponent, deps: [{ token: i1.HeNodeService }, { token: i2.HeSearchService }, { token: i3.HeEngineService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
338
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", filterTermTypesLabel: "filterTermTypesLabel", logsKey: "logsKey", noDataMessage: "noDataMessage" }, ngImport: i0, template: "<div\n *ngIf=\"showOutdatedLogs() || engineModelVersion() === currentModelVersion(); else showOutdatedLogsWarning\"\n class=\"is-px-3 is-pb-3\">\n <div class=\"has-text-right is-mb-2\" *ngIf=\"!isExternal && logsUrl()\">\n <a class=\"is-size-7\" [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\" 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\" *ngIf=\"enableFilterByTerm()\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"termChanged($event.item)\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"termChanged('')\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes()\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per </span>\n <span [ngSwitch]=\"functionalUnit()\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes()\">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>{{ _noDataMessage() || '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\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\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 is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <ng-template #showBlankNodeKey>\n <span>{{ blankNode.key }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.key; else showBlankNodeKey\">\n <a\n *ngIf=\"_nodeKey() === 'completeness'\"\n [href]=\"baseUrl + '/schema/Completeness#' + blankNode.key\"\n target=\"_blank\">\n <span>{{ blankNode.key | keyToLabel }}</span>\n </a>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" [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]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </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]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></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\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></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 [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes()\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </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 *ngIf=\"isBlankNodes()\">-</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 [class.is-sub-row]=\"blankNode.canOpen\">\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\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes()\">-</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\" (click)=\"showLegend = !showLegend\">\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\n type=\"checkbox\"\n class=\"selector\"\n [ngModel]=\"onlyRequired\"\n (change)=\"onlyRequiredChanged($event.target.checked)\"\n [disabled]=\"!!term()\" />\n <span class=\"ml-2\">\n Show only {{ filteredType() | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #showOutdatedLogsWarning>\n <div class=\"is-3 has-text-centered\">\n <p class=\"is-mb-2\">\n <fa-icon class=\"is-pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>These logs might be incorrect as the calculations are outdated.</span>\n </p>\n <p class=\"is-underlined is-size-7\"><a (click)=\"showOutdatedLogs.set(true)\">View logs anyway.</a></p>\n </div>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount()\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\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-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\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 <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"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 </div>\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\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\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 </td>\n </tr>\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-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *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\n <code class=\"is-mx-1\">{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code class=\"is-mx-1\">{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\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 .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\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", "selectOnExact", "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", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "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", "small"] }, { 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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
332
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", filterTermTypesLabel: "filterTermTypesLabel", logsKey: "logsKey", noDataMessage: "noDataMessage" }, ngImport: i0, template: "<div\n *ngIf=\"showOutdatedLogs() || engineModelVersion() === currentModelVersion(); else showOutdatedLogsWarning\"\n class=\"is-px-3 is-pb-3\">\n <div class=\"has-text-right is-mb-2\" *ngIf=\"!isExternal && logsUrl()\">\n <a class=\"is-size-7\" [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\" 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\" *ngIf=\"enableFilterByTerm()\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set('')\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes()\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per </span>\n <span [ngSwitch]=\"functionalUnit()\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes()\">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>{{ _noDataMessage() || '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\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\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 is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <ng-template #showBlankNodeKey>\n <span>{{ blankNode.key }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.key; else showBlankNodeKey\">\n <a\n *ngIf=\"_nodeKey() === 'completeness'\"\n [href]=\"baseUrl + '/schema/Completeness#' + blankNode.key\"\n target=\"_blank\">\n <span>{{ blankNode.key | keyToLabel }}</span>\n </a>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" [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]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </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]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></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\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></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 [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes()\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </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 *ngIf=\"isBlankNodes()\">-</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 [class.is-sub-row]=\"blankNode.canOpen\">\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\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes()\">-</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\" (click)=\"showLegend = !showLegend\">\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\n type=\"checkbox\"\n class=\"selector\"\n [ngModel]=\"onlyRequired\"\n (change)=\"onlyRequired.set($event.target.checked)\"\n [disabled]=\"!!term()\" />\n <span class=\"ml-2\">\n Show only {{ filteredType() | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #showOutdatedLogsWarning>\n <div class=\"is-3 has-text-centered\">\n <p class=\"is-mb-2\">\n <fa-icon class=\"is-pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>These logs might be incorrect as the calculations are outdated.</span>\n </p>\n <p class=\"is-underlined is-size-7\"><a (click)=\"showOutdatedLogs.set(true)\">View logs anyway.</a></p>\n </div>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount()\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\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-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\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 <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"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 </div>\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\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\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 </td>\n </tr>\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-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *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\n <code class=\"is-mx-1\">{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code class=\"is-mx-1\">{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\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 .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\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", "selectOnExact", "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", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "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", "small"] }, { 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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
339
333
|
}
|
|
340
334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
|
|
341
335
|
type: Component,
|
|
342
|
-
args: [{ selector: 'he-node-logs-models', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"showOutdatedLogs() || engineModelVersion() === currentModelVersion(); else showOutdatedLogsWarning\"\n class=\"is-px-3 is-pb-3\">\n <div class=\"has-text-right is-mb-2\" *ngIf=\"!isExternal && logsUrl()\">\n <a class=\"is-size-7\" [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\" 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\" *ngIf=\"enableFilterByTerm()\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"termChanged($event.item)\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"termChanged('')\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes()\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per </span>\n <span [ngSwitch]=\"functionalUnit()\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes()\">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>{{ _noDataMessage() || '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\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\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 is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <ng-template #showBlankNodeKey>\n <span>{{ blankNode.key }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.key; else showBlankNodeKey\">\n <a\n *ngIf=\"_nodeKey() === 'completeness'\"\n [href]=\"baseUrl + '/schema/Completeness#' + blankNode.key\"\n target=\"_blank\">\n <span>{{ blankNode.key | keyToLabel }}</span>\n </a>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" [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]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </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]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></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\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></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 [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes()\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </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 *ngIf=\"isBlankNodes()\">-</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 [class.is-sub-row]=\"blankNode.canOpen\">\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\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes()\">-</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\" (click)=\"showLegend = !showLegend\">\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\n type=\"checkbox\"\n class=\"selector\"\n [ngModel]=\"onlyRequired\"\n (change)=\"onlyRequiredChanged($event.target.checked)\"\n [disabled]=\"!!term()\" />\n <span class=\"ml-2\">\n Show only {{ filteredType() | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #showOutdatedLogsWarning>\n <div class=\"is-3 has-text-centered\">\n <p class=\"is-mb-2\">\n <fa-icon class=\"is-pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>These logs might be incorrect as the calculations are outdated.</span>\n </p>\n <p class=\"is-underlined is-size-7\"><a (click)=\"showOutdatedLogs.set(true)\">View logs anyway.</a></p>\n </div>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount()\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\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-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\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 <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"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 </div>\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\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\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 </td>\n </tr>\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-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *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\n <code class=\"is-mx-1\">{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code class=\"is-mx-1\">{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\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 .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"] }]
|
|
336
|
+
args: [{ selector: 'he-node-logs-models', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"showOutdatedLogs() || engineModelVersion() === currentModelVersion(); else showOutdatedLogsWarning\"\n class=\"is-px-3 is-pb-3\">\n <div class=\"has-text-right is-mb-2\" *ngIf=\"!isExternal && logsUrl()\">\n <a class=\"is-size-7\" [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\" 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\" *ngIf=\"enableFilterByTerm()\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set('')\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes()\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per </span>\n <span [ngSwitch]=\"functionalUnit()\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes()\">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>{{ _noDataMessage() || '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\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\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 is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <ng-template #showBlankNodeKey>\n <span>{{ blankNode.key }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.key; else showBlankNodeKey\">\n <a\n *ngIf=\"_nodeKey() === 'completeness'\"\n [href]=\"baseUrl + '/schema/Completeness#' + blankNode.key\"\n target=\"_blank\">\n <span>{{ blankNode.key | keyToLabel }}</span>\n </a>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" [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]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </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]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></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\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></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 [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes()\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </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 *ngIf=\"isBlankNodes()\">-</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 [class.is-sub-row]=\"blankNode.canOpen\">\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\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes()\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes()\">-</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\" (click)=\"showLegend = !showLegend\">\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\n type=\"checkbox\"\n class=\"selector\"\n [ngModel]=\"onlyRequired\"\n (change)=\"onlyRequired.set($event.target.checked)\"\n [disabled]=\"!!term()\" />\n <span class=\"ml-2\">\n Show only {{ filteredType() | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #showOutdatedLogsWarning>\n <div class=\"is-3 has-text-centered\">\n <p class=\"is-mb-2\">\n <fa-icon class=\"is-pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>These logs might be incorrect as the calculations are outdated.</span>\n </p>\n <p class=\"is-underlined is-size-7\"><a (click)=\"showOutdatedLogs.set(true)\">View logs anyway.</a></p>\n </div>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount()\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\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-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\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 <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"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 </div>\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\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\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 </td>\n </tr>\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-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *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\n <code class=\"is-mx-1\">{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code class=\"is-mx-1\">{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\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 .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"] }]
|
|
343
337
|
}], ctorParameters: function () { return [{ type: i1.HeNodeService }, { type: i2.HeSearchService }, { type: i3.HeEngineService }]; }, propDecorators: { node: [{
|
|
344
338
|
type: Input
|
|
345
339
|
}], nodeKey: [{
|
|
@@ -359,4 +353,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
|
|
|
359
353
|
}], noDataMessage: [{
|
|
360
354
|
type: Input
|
|
361
355
|
}] } });
|
|
362
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVHLE9BQU8sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEUsT0FBTyxFQUFjLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkgsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixrQkFBa0IsRUFJbEIsUUFBUSxFQUNSLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsNEJBQTRCLEVBQzVCLHVCQUF1QixFQUN4QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFOUMsT0FBTyxFQUE0RCxhQUFhLEVB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LEtBQUs7Z0JBT0Ysa0JBQWtCO3NCQURyQixLQUFLO2dCQU9GLEtBQUs7c0JBRFIsS0FBSztnQkFPRixlQUFlO3NCQURsQixLQUFLO2dCQU9GLG9CQUFvQjtzQkFEdkIsS0FBSztnQkFPRixPQUFPO3NCQURWLEtBQUs7Z0JBT0YsYUFBYTtzQkFEaEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0LCBTaWduYWwsIGNvbXB1dGVkLCBlZmZlY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdG9TaWduYWwsIHRvT2JzZXJ2YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luLCBmcm9tLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3QsIGZpbHRlciwgcmVkdWNlLCB0b0FycmF5LCBtYXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtZXJnZU1hcCwgdGFwLCBtZXJnZUFsbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIEN5Y2xlRnVuY3Rpb25hbFVuaXQsXG4gIEVtaXNzaW9uTWV0aG9kVGllcixcbiAgSUN5Y2xlSlNPTkxELFxuICBJVGVybUpTT05MRCxcbiAgSlNPTkxELFxuICBOb2RlVHlwZSxcbiAgVGVybVRlcm1UeXBlLFxuICBlbWlzc2lvblRlcm1UZXJtVHlwZSxcbiAgaW1wYWN0QXNzZXNzbWVudFRlcm1UZXJtVHlwZSxcbiAgbWVhc3VyZW1lbnRUZXJtVGVybVR5cGVcbn0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsga2V5VG9MYWJlbCwgdW5pcXVlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscyc7XG5pbXBvcnQgeyBwcm9wZXJ0eVZhbHVlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscy9kaXN0L3Rlcm0nO1xuaW1wb3J0IHsgbG9hZFJlc291cmNlS2V5IH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9nbG9zc2FyeSc7XG5pbXBvcnQgeyBEYXRhU3RhdGUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL2FwaSc7XG5cbmltcG9ydCB7IGJsYW5rTm9kZSwgbm9uQmxhbmtOb2RlLCBibGFua05vZGVzS2V5LCBub25CbGFua05vZGVzS2V5LCBCbGFua05vZGVzS2V5IH0gZnJvbSAnLi4vLi4vY29tbW9uL25vZGUtdXRpbHMnO1xuaW1wb3J0IHsgYmFzZVVybCwgaXNFeHRlcm5hbCwgdHlwZWFoZWFkRm9jdXMgfSBmcm9tICcuLi8uLi9jb21tb24vdXRpbHMnO1xuaW1wb3J0IHtcbiAgSUJsYW5rTm9kZUxvZ1N1YlZhbHVlLFxuICBJQmxhbmtOb2RlTG9nLFxuICBMb2dTdGF0dXMsXG4gIElDb25maWdNb2RlbCxcbiAgZ3JvdXBMb2dzQnlNb2RlbCxcbiAgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LFxuICBjb21wdXRlVGVybXMsXG4gIGxvZ1ZhbHVlQXJyYXksXG4gIElOb2RlVGVybUxvZ3MsXG4gIElOb2RlTG9ncyxcbiAgZ3JvdXBkTG9nc0J5S2V5LFxuICBJTm9uQmxhbmtOb2RlTG9nLFxuICBJTG9nLFxuICBjb21wdXRlS2V5c1xufSBmcm9tICcuL25vZGUtbG9ncy1tb2RlbHMubW9kZWwnO1xuaW1wb3J0IHsgSUpTT05Ob2RlLCBIZU5vZGVTZXJ2aWNlIH0gZnJvbSAnLi4vbm9kZS5zZXJ2aWNlJztcbmltcG9ydCB7IEhlRW5naW5lU2VydmljZSwgSU1vZGVsLCBJT3JjaGVzdHJhdG9yQ29uZmlnLCBmaW5kT3JjaGVzdHJhdG9yTW9kZWwgfSBmcm9tICcuLi8uLi9lbmdpbmUvZW5naW5lLnNlcnZpY2UnO1xuaW1wb3J0IHsgbWF0Y2hFeGFjdFF1ZXJ5LCBtYXRjaElkLCBtYXRjaFRlcm1UeXBlLCBtYXRjaFR5cGUgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLm1vZGVsJztcbmltcG9ydCB7IEhlU2VhcmNoU2VydmljZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2guc2VydmljZSc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuaW1wb3J0IHsgbm9kZVZlcnNpb24gfSBmcm9tICcuLi8uLi9lbmdpbmUnO1xuXG5pbnRlcmZhY2UgSVRlcm1zQnlJZE1hcHBpbmcge1xuICBbaWQ6IHN0cmluZ106IElUZXJtSlNPTkxEO1xufVxuXG5jb25zdCBub2RlVHlwZSA9IChub2RlPzogSUpTT05Ob2RlKSA9PiBub2RlPy5bJ0B0eXBlJ10gfHwgbm9kZT8udHlwZTtcbmNvbnN0IG5vZGVJZCA9IChub2RlPzogSUpTT05Ob2RlKSA9PiBub2RlPy5bJ0BpZCddIHx8IG5vZGU/LmlkO1xuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdkb3QtY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaycsXG4gIFtMb2dTdGF0dXMubm90UmVxdWlyZWRdOiAnZ3JleSdcbn07XG5cbmNvbnN0IHNob3VsZFNob3dCbGFua05vZGUgPSAoYmxhbmtOb2RlTG9nOiBJQmxhbmtOb2RlTG9nKSA9PlxuICBbXG4gICAgYmxhbmtOb2RlTG9nPy5jb25maWdNb2RlbHM/Lmxlbmd0aCxcbiAgICBibGFua05vZGVMb2c/LmtleXM/Lmxlbmd0aCxcbiAgICBibGFua05vZGVMb2c/LnN1YlZhbHVlcz8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8ub3JpZ2luYWw/Lmxlbmd0aCxcbiAgICBibGFua05vZGVMb2c/LnJlY2FsY3VsYXRlZD8ubGVuZ3RoXG4gIF0uc29tZShCb29sZWFuKTtcblxuY29uc3QgbWV0aG9kSWRMYWJlbCA9IChtZXRob2RJZDogc3RyaW5nLCBfbW9kZWw/OiBJTW9kZWwpID0+XG4gIChtZXRob2RJZFxuICAgID8ge1xuICAgICAgICAnY3ljbGUvdHJhbnNmb3JtYXRpb24nOiAnRGF0YSBGcm9tIFRyYW5zZm9ybWF0aW9uJyxcbiAgICAgICAgaW1wYWN0X2Fzc2Vzc21lbnQ6ICdEYXRhIEZyb20gQ3ljbGUnXG4gICAgICB9W21ldGhvZElkXVxuICAgIDogJycpIHx8IChtZXRob2RJZC5pbmNsdWRlcygnLycpID8gbWV0aG9kSWQuc3BsaXQoJy8nKVswXSA6IGtleVRvTGFiZWwobWV0aG9kSWQpKTtcblxuY29uc3QgZ2V0TW9kZWxzQXQgPSAobG9nOiBJQmxhbmtOb2RlTG9nU3ViVmFsdWUgfCBJQmxhbmtOb2RlTG9nLCBpbmRleDogbnVtYmVyKSA9PlxuICAoJ21vZGVsc0luU3ViVmFsdWVzJyBpbiBsb2cgPyAhbG9nLm1vZGVsc0luU3ViVmFsdWVzIHx8ICFsb2cuaXNPcGVuIDogdHJ1ZSkgJiYgbG9nLmNvbmZpZ01vZGVsc1tpbmRleF07XG5cbmNvbnN0IHJlcXVpcmVtZW50S2V5cyA9IChyZXF1aXJlbWVudHM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pID0+XG4gIE9iamVjdC5rZXlzKHJlcXVpcmVtZW50cykuZmlsdGVyKGsgPT4gIW5vZGVUeXBlc0xvd2VyQ2FzZS5pbmNsdWRlcyhrKSk7XG5cbmNvbnN0IHJlcXVpcmVtZW50Q29sb3IgPSAodmFsdWU6IGFueSkgPT4gKCF2YWx1ZSB8fCBbJ05vbmUnLCAnRmFsc2UnLCAnMCcsICcwLjAnXS5pbmNsdWRlcyh2YWx1ZSkgPyAnZGFuZ2VyJyA6ICd3aGl0ZScpO1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleToge1xuICBba2V5OiBzdHJpbmddOiAodmFsdWU6IHN0cmluZykgPT4gUGFydGlhbDxKU09OTEQ8Tm9kZVR5cGU+Pjtcbn0gPSB7XG4gIHJlbGF0ZWRfY3ljbGVzOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgY3ljbGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBpbXBhY3RfYXNzZXNzbWVudF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5JbXBhY3RBc3Nlc3NtZW50LCAnQGlkJzogdiB9KSxcbiAgc2l0ZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5TaXRlLCAnQGlkJzogdiB9KSxcbiAgc291cmNlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNvdXJjZSwgJ0BpZCc6IHYgfSksXG4gIHByb3BlcnR5X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pLFxuICBpbnB1dF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLCAnQGlkJzogdiB9KSxcbiAgcHJvZHVjdF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLCAnQGlkJzogdiB9KSxcbiAgcHJhY3RpY2VfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSwgJ0BpZCc6IHYgfSlcbn07XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT5cbiAga2V5IGluIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5ICYmIFsnTm9uZScsICcnLCBudWxsXS5pbmNsdWRlcyh2YWx1ZSkgJiYgcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXlba2V5XSh2YWx1ZSk7XG5cbmNvbnN0IGlzU3lzdGVtQm91bmRhcnkgPVxuICAodGVybUlkPzogc3RyaW5nKSA9PlxuICAoeyBpc1JlY2FsY3VsYXRlZCwgaXNSZXF1aXJlZCB9OiBQaWNrPElMb2cgfCBJQmxhbmtOb2RlTG9nU3ViVmFsdWUsICdpc1JlY2FsY3VsYXRlZCcgfCAnaXNSZXF1aXJlZCc+KSA9PiB7XG4gICAgLy8gb25seSBleGlzdHMgZm9yIHNvbWUgdGVybXNcbiAgICBjb25zdCBpblN5c3RlbUJvdW5kYXJ5ID0gbG9hZFJlc291cmNlS2V5KCdpbkhlc3RpYURlZmF1bHRTeXN0ZW1Cb3VuZGFyeS5qc29uJywgdGVybUlkKTtcbiAgICByZXR1cm4gIWluU3lzdGVtQm91bmRhcnkgPyBbaXNSZWNhbGN1bGF0ZWQsIGlzUmVxdWlyZWRdLnNvbWUoQm9vbGVhbikgOiBgJHtpblN5c3RlbUJvdW5kYXJ5fWAgPT09ICd0cnVlJztcbiAgfTtcblxuY29uc3QgaXNHZW5lcmljVGVybSA9ICh0ZXJtSWQ6IHN0cmluZykgPT4gW3Rlcm1JZC5zdGFydHNXaXRoKCdleGNyZXRhJyldLmV2ZXJ5KEJvb2xlYW4pO1xuXG5jb25zdCBleHRyYVRlcm1JZHNGcm9tQ29uZmlnID0gKGNvbmZpZzogSU9yY2hlc3RyYXRvckNvbmZpZywga2V5OiBibGFua05vZGVzS2V5LCBsb2dzOiBJTm9kZUxvZ3MgfCBJTm9kZVRlcm1Mb2dzKSA9PlxuICB1bmlxdWUoW1xuICAgIC4uLihjb25maWc/Lm1vZGVscyB8fCBbXSlcbiAgICAgIC5mbGF0KClcbiAgICAgIC5maWx0ZXIobSA9PiBtLmtleSA9PT0ga2V5KVxuICAgICAgLm1hcChtID0+IG0udmFsdWUpXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAuZmlsdGVyKHYgPT4gIWlzR2VuZXJpY1Rlcm0odikpLFxuICAgIC8vIG1hdGNoIGxvZ3Mgd2l0aCBhIGNvbmZpZ3VyYXRpb25cbiAgICAuLi5PYmplY3QuZW50cmllcyhsb2dzIHx8IHt9KVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKFtfaWQsIHZhbHVlXSkgPT5cbiAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgT2JqZWN0LmVudHJpZXModmFsdWUpLnNvbWUoKFttb2RlbCwgdl06IFttb2RlbDogc3RyaW5nLCB2YWx1ZTogYW55XSkgPT5cbiAgICAgICAgICAgIGZpbmRPcmNoZXN0cmF0b3JNb2RlbChjb25maWcsIHsga2V5LCBtb2RlbCwgdmFsdWU6IHYubW9kZWxfa2V5IH0pXG4gICAgICAgICAgKVxuICAgICAgKVxuICAgICAgLm1hcCgoW2tleV0pID0+IGtleSlcbiAgXSk7XG5cbmNvbnN0IG1hdGNoVGVybVR5cGVGcm9tS2V5OiB7XG4gIFtrZXkgaW4gQmxhbmtOb2Rlc0tleV0/OiBUZXJtVGVybVR5cGVbXTtcbn0gPSB7XG4gIFtCbGFua05vZGVzS2V5LmVtaXNzaW9uc106IGVtaXNzaW9uVGVybVRlcm1UeXBlLnRlcm0sXG4gIFtCbGFua05vZGVzS2V5Lm1lYXN1cmVtZW50c106IG1lYXN1cmVtZW50VGVybVRlcm1UeXBlLnRlcm0sXG4gIC8vIEltcGFjdEFzc2Vzc21lbnRcbiAgLy8gZGlzYWJsZWQgYXMgaXQgd2lsbCBzaG93IHRlcm1zIGluIGJvdGggYGVtaXNzaW9uc2AgYW5kIGByZXNvdXJjZVVzZWAgY2F0ZWdvcmllcywgc2VlIGlzc3VlICMyNzNcbiAgLy8gZW1pc3Npb25zUmVzb3VyY2VVc2U6IGltcGFjdEFzc2Vzc21lbnRUZXJtVGVybVR5cGUuZW1pc3Npb25zUmVzb3VyY2VVc2UudGVybSxcbiAgW0JsYW5rTm9kZXNLZXkuaW1wYWN0c106IGltcGFjdEFzc2Vzc21lbnRUZXJtVGVybVR5cGUuaW1wYWN0cy50ZXJtLFxuICBbQmxhbmtOb2Rlc0tleS5lbmRwb2ludHNdOiBpbXBhY3RBc3Nlc3NtZW50VGVybVRlcm1UeXBlLmVuZHBvaW50cy50ZXJtXG59O1xuXG5jb25zdCBmaWx0ZXJCbGFua05vZGUgPSAoXG4gIHsgdGVybTogeyBuYW1lLCAnQGlkJzogaWQgfSwgc3ViVmFsdWVzLCAuLi5sb2cgfTogSUJsYW5rTm9kZUxvZyxcbiAgc2VsZWN0ZWRUZXJtPzogc3RyaW5nLFxuICBmaWx0ZXJUZXJtVHlwZXM/OiBUZXJtVGVybVR5cGVbXSxcbiAgb25seVJlcXVpcmVkPzogYm9vbGVhblxuKSA9PlxuICBzZWxlY3RlZFRlcm1cbiAgICA/IG5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWxlY3RlZFRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICA6ICFmaWx0ZXJUZXJtVHlwZXM/Lmxlbmd0aCB8fCAhb25seVJlcXVpcmVkIHx8IGlzU3lzdGVtQm91bmRhcnkoaWQpKGxvZykgfHwgc3ViVmFsdWVzLnNvbWUoaXNTeXN0ZW1Cb3VuZGFyeShpZCkpO1xuXG5jb25zdCB0ZXJtU2VhcmNoID0gKHRlcm0gPSAnJykgPT4gdGVybS5yZXBsYWNlKC9bLFxcc10vZywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbmNvbnN0IGxpc3RUZXJtSWQgPSAodGVybXM6IElUZXJtSlNPTkxEW10pID0+XG4gIHRlcm1zXG4gICAgLm1hcCgoeyBuYW1lIH0pID0+IG5hbWUpXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKCcsJyk7XG5cbmNvbnN0IGNvbXBsZXRlbmVzc0NvbXBsZXRlU3VmZml4ID0gJ19jb21wbGV0ZSc7XG5jb25zdCBjb21wbGV0ZW5lc3NJbmNvbXBsZXRlU3VmZml4ID0gJ19pbmNvbXBsZXRlJztcbmNvbnN0IHBhcnNlTG9nQ29tcGxldGVuZXNzID0gKGtleTogc3RyaW5nKSA9PlxuICBbXG4gICAga2V5LnN0YXJ0c1dpdGgoJ3Rlcm1fdHlwZV8nKSxcbiAgICBrZXkuZW5kc1dpdGgoY29tcGxldGVuZXNzQ29tcGxldGVTdWZmaXgpIHx8IGtleS5lbmRzV2l0aChjb21wbGV0ZW5lc3NJbmNvbXBsZXRlU3VmZml4KVxuICBdLmV2ZXJ5KEJvb2xlYW4pXG4gICAgPyB7XG4gICAgICAgIGtleToga2V5XG4gICAgICAgICAgLnJlcGxhY2UoJ3Rlcm1fdHlwZV8nLCAnJylcbiAgICAgICAgICAucmVwbGFjZShjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeCwgJycpXG4gICAgICAgICAgLnJlcGxhY2UoY29tcGxldGVuZXNzSW5jb21wbGV0ZVN1ZmZpeCwgJycpLFxuICAgICAgICB2YWx1ZToga2V5LmVuZHNXaXRoKGNvbXBsZXRlbmVzc0NvbXBsZXRlU3VmZml4KVxuICAgICAgfVxuICAgIDogbnVsbDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaGUtbm9kZS1sb2dzLW1vZGVscycsXG4gIHRlbXBsYXRlVXJsOiAnLi9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBOb2RlTG9nc01vZGVsc0NvbXBvbmVudCB7XG4gIHByaXZhdGUgX25vZGUgPSBzaWduYWwodW5kZWZpbmVkIGFzIElKU09OTm9kZSk7XG4gIEBJbnB1dCgpXG4gIHNldCBub2RlKHZhbHVlOiBJSlNPTk5vZGUpIHtcbiAgICB0aGlzLl9ub2RlLnNldCh2YWx1ZSk7XG4gICAgdmFsdWUgJiYgdGhpcy5sb2FkTG9ncyh2YWx1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX25vZGVLZXkgPSBzaWduYWwodW5kZWZpbmVkIGFzIGJsYW5rTm9kZXNLZXkgfCBub25CbGFua05vZGVzS2V5KTtcbiAgQElucHV0KClcbiAgc2V0IG5vZGVLZXkodmFsdWU6IGJsYW5rTm9kZXNLZXkgfCBub25CbGFua05vZGVzS2V5KSB7XG4gICAgdGhpcy5fbm9kZUtleS5zZXQodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3JpZ2luYWxWYWx1ZXMgPSBzaWduYWwoW10gYXMgYmxhbmtOb2RlW10gfCBub25CbGFua05vZGUpO1xuICBASW5wdXQoKVxuICBzZXQgb3JpZ2luYWxWYWx1ZXModmFsdWU6IGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlKSB7XG4gICAgdGhpcy5fb3JpZ2luYWxWYWx1ZXMuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlY2FsY3VsYXRlZFZhbHVlcyA9IHNpZ25hbChbXSBhcyBibGFua05vZGVbXSB8IG5vbkJsYW5rTm9kZSk7XG4gIEBJbnB1dCgpXG4gIHNldCByZWNhbGN1bGF0ZWRWYWx1ZXModmFsdWU6IGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlKSB7XG4gICAgdGhpcy5fcmVjYWxjdWxhdGVkVmFsdWVzLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF90ZXJtcyA9IHNpZ25hbChbXSBhcyBJVGVybUpTT05MRFtdKTtcbiAgQElucHV0KClcbiAgc2V0IHRlcm1zKHZhbHVlOiBJVGVybUpTT05MRFtdKSB7XG4gICAgdGhpcy5fdGVybXMuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2ZpbHRlclRlcm1UeXBlcyA9IHNpZ25hbChbXSBhcyBUZXJtVGVybVR5cGVbXSk7XG4gIEBJbnB1dCgpXG4gIHNldCBmaWx0ZXJUZXJtVHlwZXModmFsdWU6IFRlcm1UZXJtVHlwZVtdKSB7XG4gICAgdGhpcy5fZmlsdGVyVGVybVR5cGVzLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9maWx0ZXJUZXJtVHlwZXNMYWJlbCA9IHNpZ25hbCgnJyk7XG4gIEBJbnB1dCgpXG4gIHNldCBmaWx0ZXJUZXJtVHlwZXNMYWJlbCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fZmlsdGVyVGVybVR5cGVzTGFiZWwuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvZ3NLZXkgPSBzaWduYWwoJycpO1xuICBASW5wdXQoKVxuICBzZXQgbG9nc0tleSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fbG9nc0tleS5zZXQodmFsdWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9ub0RhdGFNZXNzYWdlID0gc2lnbmFsKCcnKTtcbiAgQElucHV0KClcbiAgc2V0IG5vRGF0YU1lc3NhZ2UodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX25vRGF0YU1lc3NhZ2Uuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwcm90ZWN0ZWQgaXNFeHRlcm5hbCA9IGlzRXh0ZXJuYWwoKTtcbiAgcHJvdGVjdGVkIEN5Y2xlRnVuY3Rpb25hbFVuaXQgPSBDeWNsZUZ1bmN0aW9uYWxVbml0O1xuICBwcm90ZWN0ZWQgRW1pc3Npb25NZXRob2RUaWVyID0gRW1pc3Npb25NZXRob2RUaWVyO1xuICBwcm90ZWN0ZWQgTG9nU3RhdHVzID0gTG9nU3RhdHVzO1xuICBwcm90ZWN0ZWQgbG9nSWNvbiA9IGxvZ0ljb247XG4gIHByb3RlY3RlZCBsb2dDb2xvciA9IGxvZ0NvbG9yO1xuICBwcm90ZWN0ZWQgcHJvcGVydHlWYWx1ZSA9IHByb3BlcnR5VmFsdWU7XG4gIHByb3RlY3RlZCBnZXRNb2RlbHNBdCA9IGdldE1vZGVsc0F0O1xuICBwcm90ZWN0ZWQgcmVxdWlyZW1lbnRLZXlzID0gcmVxdWlyZW1lbnRLZXlzO1xuICBwcm90ZWN0ZWQgcmVxdWlyZW1lbnRDb2xvciA9IHJlcXVpcmVtZW50Q29sb3I7XG4gIHByb3RlY3RlZCBsb2dWYWx1ZUFycmF5ID0gbG9nVmFsdWVBcnJheTtcbiAgcHJvdGVjdGVkIHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IHJlcXVpcmVtZW50TGlua2VkTm9kZTtcbiAgcHJvdGVjdGVkIGlzU3lzdGVtQm91bmRhcnkgPSBpc1N5c3RlbUJvdW5kYXJ5O1xuICBwcm90ZWN0ZWQgcGFyc2VMb2dDb21wbGV0ZW5lc3MgPSBwYXJzZUxvZ0NvbXBsZXRlbmVzcztcbiAgcHJvdGVjdGVkIGxvYWRpbmcgPSBzaWduYWwodHJ1ZSk7XG4gIHByb3RlY3RlZCBzaG93TGVnZW5kID0gdHJ1ZTtcblxuICBwcm90ZWN0ZWQgb25seVJlcXVpcmVkID0gc2lnbmFsKHRydWUpO1xuXG4gIHByb3RlY3RlZCBmaWx0ZXJlZFR5cGUgPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLl9maWx0ZXJUZXJtVHlwZXNMYWJlbCgpIHx8IHRoaXMuX2ZpbHRlclRlcm1UeXBlcygpPy5tYXAodGVybVR5cGVMYWJlbCkuam9pbignICYgJylcbiAgKTtcbiAgcHJvdGVjdGVkIGZ1bmN0aW9uYWxVbml0ID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMuX25vZGUoKSBhcyBJQ3ljbGVKU09OTEQpPy5mdW5jdGlvbmFsVW5pdCk7XG5cbiAgcHJvdGVjdGVkIGxvZ3NVcmwgPSBjb21wdXRlZCgoKSA9PiB0aGlzLm5vZGVTZXJ2aWNlLm5vZGVMb2dzVXJsKHRoaXMuX25vZGUoKSkpO1xuICBwcm90ZWN0ZWQgbm9kZVR5cGUgPSBjb21wdXRlZCgoKSA9PiBub2RlVHlwZSh0aGlzLl9ub2RlKCkpKTtcbiAgcHJpdmF0ZSBub2RlSWQgPSBjb21wdXRlZCgoKSA9PiBub2RlSWQodGhpcy5fbm9kZSgpKSk7XG4gIHByaXZhdGUgY29uZmlnID0gc2lnbmFsKHVuZGVmaW5lZCBhcyBJT3JjaGVzdHJhdG9yQ29uZmlnKTtcblxuICBwcml2YXRlIGFsbExvZ3MgPSBzaWduYWwoJycpO1xuICBwcml2YXRlIGdyb3VwZWRMb2dzID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMuYWxsTG9ncygpID8gZ3JvdXBMb2dzQnlNb2RlbCh0aGlzLmFsbExvZ3MoKSkgOiB7fSkpO1xuICBwcml2YXRlIGxvZ3MgPSBjb21wdXRlZCgoKSA9PiAodGhpcy5fbG9nc0tleSgpID8gdGhpcy5ncm91cGVkTG9ncygpPy5bdGhpcy5fbG9nc0tleSgpXSA6IHRoaXMuZ3JvdXBlZExvZ3MoKSkgfHwge30pO1xuXG4gIHByaXZhdGUgYWxsQmxhbmtOb2RlcyA9IHNpZ25hbChbXSBhcyAoSUJsYW5rTm9kZUxvZyB8IElOb25CbGFua05vZGVMb2cpW10pO1xuICBwcm90ZWN0ZWQgYmxhbmtOb2RlcyA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5hbGxCbGFua05vZGVzKCkuZmlsdGVyKFxuICAgICAgbG9nID0+ICEoJ3Rlcm0nIGluIGxvZykgfHwgZmlsdGVyQmxhbmtOb2RlKGxvZywgdGhpcy50ZXJtKCksIHRoaXMuX2ZpbHRlclRlcm1UeXBlcygpLCB0aGlzLm9ubHlSZXF1aXJlZCgpKVxuICAgIClcbiAgKTtcblxuICBwcm90ZWN0ZWQgaXNCbGFua05vZGVzID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gQXJyYXkuaXNBcnJheSh0aGlzLl9vcmlnaW5hbFZhbHVlcygpKSB8fCBBcnJheS5pc0FycmF5KHRoaXMuX3JlY2FsY3VsYXRlZFZhbHVlcygpKVxuICApO1xuICBwcm90ZWN0ZWQgbWV0aG9kTW9kZWxzQ291bnQgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuYWxsQmxhbmtOb2RlcygpPy5sZW5ndGggJiYgJ3Rlcm0nIGluIHRoaXMuYWxsQmxhbmtOb2RlcygpWzBdXG4gICAgICA/IG1vZGVsQ291bnQodGhpcy5hbGxCbGFua05vZGVzKCkgYXMgSUJsYW5rTm9kZUxvZ1tdKVxuICAgICAgOiAxXG4gICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBleHRyYVRlcm1zSWRzJCA9IGZvcmtKb2luKHtcbiAgICBjb25maWc6IHRvT2JzZXJ2YWJsZSh0aGlzLmNvbmZpZyksXG4gICAgbm9kZUtleTogdG9PYnNlcnZhYmxlKHRoaXMuX25vZGVLZXkgYXMgU2lnbmFsPGJsYW5rTm9kZXNLZXk+KSxcbiAgICBsb2dzOiB0b09ic2VydmFibGUodGhpcy5sb2dzKVxuICB9KS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICBwcml2YXRlIGV4dHJhVGVybXNCeUlkcyA9IHNpZ25hbChbXSBhcyBJVGVybUpTT05MRFtdKTtcbiAgcHJpdmF0ZSByZWFkb25seSBleHRyYVRlcm1UeXBlcyQgPSBmb3JrSm9pbih7XG4gICAgbm9kZUtleTogdG9PYnNlcnZhYmxlKHRoaXMuX25vZGVLZXkpLFxuICAgIHRlcm1UeXBlczogdG9PYnNlcnZhYmxlKHRoaXMuX2ZpbHRlclRlcm1UeXBlcylcbiAgfSkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgcHJpdmF0ZSBleHRyYVRlcm1zQnlUZXJtVHlwZXMgPSBzaWduYWwoW10gYXMgSVRlcm1KU09OTERbXSk7XG4gIHByaXZhdGUgZXh0cmFUZXJtcyA9IGNvbXB1dGVkKCgpID0+IFsuLi50aGlzLmV4dHJhVGVybXNCeUlkcygpLCAuLi50aGlzLmV4dHJhVGVybXNCeVRlcm1UeXBlcygpXSk7XG4gIHByaXZhdGUgYWxsVGVybXMgPSBjb21wdXRlZCgoKSA9PlxuICAgIGNvbXB1dGVUZXJtcyhcbiAgICAgIHRoaXMuX29yaWdpbmFsVmFsdWVzKCkgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLl9yZWNhbGN1bGF0ZWRWYWx1ZXMoKSBhcyBibGFua05vZGVbXSxcbiAgICAgIHRoaXMuX3Rlcm1zKCksXG4gICAgICB0aGlzLl9maWx0ZXJUZXJtVHlwZXMoKSxcbiAgICAgIHRoaXMuZXh0cmFUZXJtcygpXG4gICAgKVxuICApO1xuXG4gIHByaXZhdGUgbWV0aG9kc0J5SWQgPSB0b1NpZ25hbChcbiAgICB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgIGJvb2w6IHtcbiAgICAgICAgbXVzdDogW21hdGNoVHlwZShOb2RlVHlwZS5UZXJtKSwgbWF0Y2hUZXJtVHlwZShUZXJtVGVybVR5cGUubW9kZWwpXVxuICAgICAgfVxuICAgIH0pLnBpcGUoXG4gICAgICBtZXJnZUFsbCgpLFxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcbiAgICAgIGRpc3RpbmN0KHYgPT4gdlsnQGlkJ10pLFxuICAgICAgcmVkdWNlKChwcmV2LCBjdXJyKSA9PiAoeyAuLi5wcmV2LCBbY3VyclsnQGlkJ11dOiBjdXJyIH0pLCB7fSBhcyBJVGVybXNCeUlkTWFwcGluZylcbiAgICApXG4gICk7XG5cbiAgcHJpdmF0ZSB0ZXJtc0J5SWQgPSBzaWduYWwoe30gYXMgSVRlcm1zQnlJZE1hcHBpbmcpO1xuXG4gIC8vIGZyb20gYG1vZGVsLWxpbmtzLmpzb25gIGZpbGVcbiAgcHJpdmF0ZSBlbmdpbmVNb2RlbHMgPSB0b1NpZ25hbCh0aGlzLmVuZ2luZVNlcnZpY2UuYWxsTW9kZWxzJCgpKTtcblxuICBwcm90ZWN0ZWQgZW5naW5lTW9kZWxWZXJzaW9uID0gdG9TaWduYWwodGhpcy5lbmdpbmVTZXJ2aWNlLmxhdGVzdFZlcnNpb24kKTtcbiAgcHJvdGVjdGVkIGN1cnJlbnRNb2RlbFZlcnNpb24gPSBjb21wdXRlZCgoKSA9PiBub2RlVmVyc2lvbih0aGlzLl9ub2RlKCkpKTtcbiAgcHJvdGVjdGVkIHNob3dPdXRkYXRlZExvZ3MgPSBzaWduYWwoZmFsc2UpO1xuXG4gIC8vIGZpbHRlciBsaXN0IG9mIHJlc3VsdHMgYnkgYSBzaW5nbGUgVGVybVxuICBwcm90ZWN0ZWQgdGVybSA9IHNpZ25hbCgnJyk7XG4gIHByb3RlY3RlZCBlbmFibGVGaWx0ZXJCeVRlcm0gPSBjb21wdXRlZCgoKSA9PiB0aGlzLmFsbFRlcm1zKCk/Lmxlbmd0aCA+IDApO1xuICBwcm90ZWN0ZWQgc3VnZ2VzdFRlcm0gPSAodGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPikgPT5cbiAgICB0ZXh0JC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIG1hcCh2ID0+IHRoaXMuc3VnZ2VzdEJ5VGVybSh2KSlcbiAgICApO1xuXG4gIHByb3RlY3RlZCB0eXBlYWhlYWRGb2N1cyA9IHR5cGVhaGVhZEZvY3VzO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IEhlTm9kZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZWFyY2hTZXJ2aWNlOiBIZVNlYXJjaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmdpbmVTZXJ2aWNlOiBIZUVuZ2luZVNlcnZpY2VcbiAgKSB7XG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aGlzLmV4dHJhVGVybVR5cGVzJFxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgbWFwKCh7IG5vZGVLZXksIHRlcm1UeXBlcyB9KSA9PiBbLi4uKG1hdGNoVGVybVR5cGVGcm9tS2V5W25vZGVLZXldIHx8IFtdKSwgLi4uKHRlcm1UeXBlcyB8fCBbXSldKSxcbiAgICAgICAgICAgIG1lcmdlTWFwKHZhbHVlcyA9PlxuICAgICAgICAgICAgICB2YWx1ZXMubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICAgICAgICAgICAgICAgIGJvb2w6IHtcbiAgICAgICAgICAgICAgICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pXSxcbiAgICAgICAgICAgICAgICAgICAgICBzaG91bGQ6IHZhbHVlcy5tYXAobWF0Y2hUZXJtVHlwZSksXG4gICAgICAgICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICA6IG9mKFtdKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuc3Vic2NyaWJlKHZhbHVlcyA9PiB0aGlzLmV4dHJhVGVybXNCeVRlcm1UeXBlcy5zZXQodmFsdWVzKSk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XG4gICAgKTtcblxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhpcy5leHRyYVRlcm1zSWRzJFxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgbWFwKCh7IGNvbmZpZywgbm9kZUtleSwgbG9ncyB9KSA9PiBleHRyYVRlcm1JZHNGcm9tQ29uZmlnKGNvbmZpZywgbm9kZUtleSwgbG9ncykpLFxuICAgICAgICAgICAgbWVyZ2VNYXAodmFsdWVzID0+XG4gICAgICAgICAgICAgIHZhbHVlcy5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgPyB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgICAgICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgICAgICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSldLFxuICAgICAgICAgICAgICAgICAgICAgIHNob3VsZDogdmFsdWVzLm1hcChtYXRjaElkKSxcbiAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIDogb2YoW10pXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUodmFsdWVzID0+IHRoaXMuZXh0cmFUZXJtc0J5SWRzLnNldCh2YWx1ZXMpKTtcbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBvZih0aGlzLmlzQmxhbmtOb2RlcygpKVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgICAgIG1lcmdlTWFwKGlzQmxhbmtOb2RlcyA9PiAoaXNCbGFua05vZGVzID8gdGhpcy5sb2FkQmxhbmtOb2RlcygpIDogdGhpcy5sb2FkTm9uQmxhbmtOb2RlcygpKSlcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSh2YWx1ZXMgPT4gdGhpcy5hbGxCbGFua05vZGVzLnNldCh2YWx1ZXMpKTtcbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkTG9ncyhub2RlOiBJSlNPTk5vZGUpIHtcbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuXG4gICAgZm9ya0pvaW4oe1xuICAgICAgbG9nczogdGhpcy5ub2RlU2VydmljZS5nZXRMb2coeyAuLi5ub2RlLCBkYXRhU3RhdGU6IERhdGFTdGF0ZS5yZWNhbGN1bGF0ZWQgfSksXG4gICAgICBjb25maWc6IHRoaXMuZW5naW5lU2VydmljZS5vY2hlc3RyYXRvckNvbmZpZyQobm9kZVR5cGUobm9kZSksIG5vZGVJZChub2RlKSlcbiAgICB9KVxuICAgICAgLnBpcGUodGFwKCgpID0+IHRoaXMubG9hZGluZy5zZXQoZmFsc2UpKSlcbiAgICAgIC5zdWJzY3JpYmUoKHsgbG9ncywgY29uZmlnIH0pID0+IHtcbiAgICAgICAgdGhpcy5jb25maWcuc2V0KGNvbmZpZyk7XG4gICAgICAgIHRoaXMuYWxsTG9ncy5zZXQobG9ncyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEJsYW5rTm9kZXMoKSB7XG4gICAgcmV0dXJuIG9mKHRoaXMuYWxsVGVybXMoKSkucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChwcmV2LCBjdXJyKSA9PiBsaXN0VGVybUlkKHByZXYpICE9PSBsaXN0VGVybUlkKGN1cnIpKSxcbiAgICAgIG1lcmdlQWxsKCksXG4gICAgICBtYXAoXG4gICAgICAgIGdyb3VwTG9nc0J5VGVybShcbiAgICAgICAgICB0aGlzLm5vZGVUeXBlKCksXG4gICAgICAgICAgdGhpcy5sb2dzKCksXG4gICAgICAgICAgdGhpcy5lbmdpbmVNb2RlbHMoKSxcbiAgICAgICAgICB0aGlzLmNvbmZpZygpLFxuICAgICAgICAgIHRoaXMuX29yaWdpbmFsVmFsdWVzKCkgYXMgYmxhbmtOb2RlW10sXG4gICAgICAgICAgdGhpcy5fcmVjYWxjdWxhdGVkVmFsdWVzKCkgYXMgYmxhbmtOb2RlW10sXG4gICAgICAgICAgdGhpcy5fbm9kZUtleSgpIGFzIGJsYW5rTm9kZXNLZXlcbiAgICAgICAgKVxuICAgICAgKSxcbiAgICAgIGZpbHRlcihzaG91bGRTaG93QmxhbmtOb2RlKSxcbiAgICAgIHRvQXJyYXkoKSxcbiAgICAgIG1lcmdlTWFwKHZhbHVlcyA9PiB0aGlzLmZldGNoVGVybUlkcyh2YWx1ZXMpLnBpcGUobWFwKCgpID0+IHZhbHVlcykpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvYWROb25CbGFua05vZGVzKCkge1xuICAgIGNvbnN0IG1hcEZ1bmMgPSBncm91cGRMb2dzQnlLZXkoXG4gICAgICB0aGlzLm5vZGVUeXBlKCksXG4gICAgICB0aGlzLl9ub2RlS2V5KCkgYXMgbm9uQmxhbmtOb2Rlc0tleSxcbiAgICAgIHRoaXMubG9ncygpLFxuICAgICAgdGhpcy5lbmdpbmVNb2RlbHMoKSxcbiAgICAgIHRoaXMuX29yaWdpbmFsVmFsdWVzKCkgYXMgbm9uQmxhbmtOb2RlLFxuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVkVmFsdWVzKCkgYXMgbm9uQmxhbmtOb2RlXG4gICAgKTtcbiAgICBjb25zdCBrZXlzID0gY29tcHV0ZUtleXModGhpcy5fb3JpZ2luYWxWYWx1ZXMoKSBhcyBub25CbGFua05vZGUsIHRoaXMuX3JlY2FsY3VsYXRlZFZhbHVlcygpIGFzIG5vbkJsYW5rTm9kZSk7XG4gICAgcmV0dXJuIGZyb20oa2V5cykucGlwZShtYXAobWFwRnVuYyksIHRvQXJyYXkoKSk7XG4gIH1cblxuICBwcml2YXRlIGZldGNoVGVybUlkcyh2YWx1ZXM6IElCbGFua05vZGVMb2dbXSkge1xuICAgIHJldHVybiBvZih2YWx1ZXMpLnBpcGUoXG4gICAgICBtZXJnZU1hcCh2ID0+IHYuZmxhdE1hcCh2diA9PiB2di5zdWJWYWx1ZXMpKSxcbiAgICAgIG1hcCh2ID0+IHYuaWQpLFxuICAgICAgZGlzdGluY3QoKSxcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICB0b0FycmF5KCksXG4gICAgICBtZXJnZU1hcCgoaWRzOiBzdHJpbmdbXSkgPT5cbiAgICAgICAgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgbXVzdDogW21hdGNoVHlwZShOb2RlVHlwZS5UZXJtKV0sXG4gICAgICAgICAgICBzaG91bGQ6IGlkcy5tYXAoaWQgPT4gbWF0Y2hFeGFjdFF1ZXJ5KCdAaWQnLCBpZCkpLFxuICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApLFxuICAgICAgcmVkdWNlKChwcmV2LCBjdXJyKSA9PiAoeyAuLi5wcmV2LCBbY3VyclsnQGlkJ11dOiBjdXJyIH0pLCB7fSBhcyBJVGVybXNCeUlkTWFwcGluZyksXG4gICAgICB0YXAodmFsdWVzID0+IHRoaXMudGVybXNCeUlkLnNldCh2YWx1ZXMpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN1Z2dlc3RCeVRlcm0odGVybTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsVGVybXMoKVxuICAgICAgLm1hcCgoeyBuYW1lIH0pID0+IG5hbWUpXG4gICAgICAuZmlsdGVyKHYgPT4gdGVybVNlYXJjaCh2KS5pbmNsdWRlcyh0ZXJtU2VhcmNoKHRlcm0pKSk7XG4gIH1cblxuICBwcml2YXRlIHNlYXJjaFRlcm1zKHF1ZXJ5OiBhbnkpIHtcbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgIHJldHVybiB0aGlzLnNlYXJjaFNlcnZpY2VcbiAgICAgIC5zZWFyY2gkPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICAgIGZpZWxkczogWydAdHlwZScsICdAaWQnLCAnbmFtZSddLFxuICAgICAgICBsaW1pdDogMTAwMDAsXG4gICAgICAgIHF1ZXJ5XG4gICAgICB9KVxuXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKCgpID0+IHRoaXMubG9hZGluZy5zZXQoZmFsc2UpKSxcbiAgICAgICAgbWFwKCh7IHJlc3VsdHMgfSkgPT4gcmVzdWx0cylcbiAgICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdHJhY2tCeUJsYW5rTm9kZShfaW5kZXg6IG51bWJlciwgbm9kZTogYW55KSB7XG4gICAgcmV0dXJuIG5vZGUudGVybUlkIHx8IG5vZGUua2V5O1xuICB9XG5cbiAgcHJvdGVjdGVkIHRlcm1DaGFuZ2VkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnRlcm0uc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbmx5UmVxdWlyZWRDaGFuZ2VkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5vbmx5UmVxdWlyZWQuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkKCk/LlttZXRob2RJZF0/Lm5hbWUgfHwgbWV0aG9kSWRMYWJlbChtZXRob2RJZCwgbW9kZWwpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhc01ldGhvZFRpZXIodmFsdWVzOiBibGFua05vZGVbXSwgbWV0aG9kVGllcjogRW1pc3Npb25NZXRob2RUaWVyKSB7XG4gICAgcmV0dXJuIHZhbHVlcy5zb21lKHYgPT4gJ21ldGhvZFRpZXInIGluIHYgJiYgdi5tZXRob2RUaWVyID09PSBtZXRob2RUaWVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0ZXJtQnlJZChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMudGVybXNCeUlkKCk/LltpZF0gfHxcbiAgICAgICh7XG4gICAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAgICdAaWQnOiBpZCxcbiAgICAgICAgbmFtZTogdGVybVR5cGVMYWJlbChpZClcbiAgICAgIH0gYXMgSVRlcm1KU09OTEQpXG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdlxuICAqbmdJZj1cInNob3dPdXRkYXRlZExvZ3MoKSB8fCBlbmdpbmVNb2RlbFZlcnNpb24oKSA9PT0gY3VycmVudE1vZGVsVmVyc2lvbigpOyBlbHNlIHNob3dPdXRkYXRlZExvZ3NXYXJuaW5nXCJcbiAgY2xhc3M9XCJpcy1weC0zIGlzLXBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IGlzLW1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsICYmIGxvZ3NVcmwoKVwiPlxuICAgIDxhIGNsYXNzPVwiaXMtc2l6ZS03XCIgW2hyZWZdPVwibG9nc1VybCgpXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgbWF4SGVpZ2h0PVwiMzIwXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIGlzLW5hcnJvdyBpcy1zdHJpcGVkXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiICpuZ0lmPVwiZW5hYmxlRmlsdGVyQnlUZXJtKClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wgaXMtZXhwYW5kZWQgaGFzLWljb25zLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0ZXJtKClcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRlcm1cIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgZW50cnkgYnkgbmFtZVwiXG4gICAgICAgICAgICAgICAgICBbbmdiVHlwZWFoZWFkXT1cInN1Z2dlc3RUZXJtXCJcbiAgICAgICAgICAgICAgICAgIFtmb2N1c0ZpcnN0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cInR5cGVhaGVhZEZvY3VzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwidGVybUNoYW5nZWQoJGV2ZW50Lml0ZW0pXCIgLz5cbiAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImljb24gaXMtc21hbGwgaXMtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiF0ZXJtKClcIiAoY2xpY2spPVwidGVybUNoYW5nZWQoJycpXCI+XG4gICAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwidGltZXNcIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPlVuaXRzPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+KHBlciZuYnNwOzwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIFtuZ1N3aXRjaF09XCJmdW5jdGlvbmFsVW5pdCgpXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkN5Y2xlRnVuY3Rpb25hbFVuaXRbJzEgaGEnXVwiPmhlY3RhcmU8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0PmtnIHByb2R1Y3Q8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPik8L3NwYW4+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8dGg+T3JpZ2luYWw8L3RoPlxuICAgICAgICAgIDx0aD5SZWNhbGN1bGF0ZWQ8L3RoPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50KCkgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPih7eyBpICsgMSB9fSk8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyICpuZ0lmPVwibG9hZGluZygpXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZygpICYmIGJsYW5rTm9kZXMoKS5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8c3Bhbj57eyBfbm9EYXRhTWVzc2FnZSgpIHx8ICdObyBkYXRhJyB9fTwvc3Bhbj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBibGFua05vZGUgb2YgYmxhbmtOb2RlcygpOyB0cmFja0J5OiB0cmFja0J5QmxhbmtOb2RlXCI+XG4gICAgICAgICAgPHRyIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLmNhbk9wZW5cIiBbY2xhc3MuaXMtb3Blbl09XCJibGFua05vZGUuaXNPcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0/Lm5hbWUgfHwgYmxhbmtOb2RlLmtleVwiPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0yIG9wZW4tbm9kZVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImJsYW5rTm9kZS5pc09wZW4gPSAhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cImJsYW5rTm9kZS5pc09wZW5cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGhlLW5vZGUtbGluayBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1wcmUtd3JhcFwiICpuZ0lmPVwiYmxhbmtOb2RlLnRlcm1cIiBbbm9kZV09XCJibGFua05vZGUudGVybVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzaG93QmxhbmtOb2RlS2V5PlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUua2V5OyBlbHNlIHNob3dCbGFua05vZGVLZXlcIj5cbiAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJfbm9kZUtleSgpID09PSAnY29tcGxldGVuZXNzJ1wiXG4gICAgICAgICAgICAgICAgICBbaHJlZl09XCJiYXNlVXJsICsgJy9zY2hlbWEvQ29tcGxldGVuZXNzIycgKyBibGFua05vZGUua2V5XCJcbiAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLmtleSB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXMoKVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcFwiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRPcmlnaW5hbFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYmxhbmtOb2RlLmlzT3JpZ2luYWwgfHwgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXMoKVwiIGNsYXNzPVwiaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdERlbHRhVmFsdWU+XG4gICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsLmxlbmd0aCAmJiBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm9WYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgIFtvcmlnaW5hbFZhbHVlXT1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlXCI+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHREZWx0YVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICBlbHNlIG5vVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDogeyBkYXRhOiBibGFua05vZGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1zdWItcm93XT1cImJsYW5rTm9kZS5jYW5PcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zIHByLTEgZmllbGQtbm9kZVwiPkZpZWxkOjwvc3Bhbj5cblxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLXByZS13cmFwXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS50eXBlXCJcbiAgICAgICAgICAgICAgICBbaHJlZl09XCJiYXNlVXJsICsgJy9zY2hlbWEvJyArIGJsYW5rTm9kZS50eXBlICsgJyMnICsgc3ViVmFsdWUua2V5XCJcbiAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wXCIgKm5nSWY9XCIhYmxhbmtOb2RlLnR5cGVcIj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5pc1JlY2FsY3VsYXRlZCB8fCBzdWJWYWx1ZS5rZXkgPT09ICdpbXBhY3RBc3Nlc3NtZW50JzsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHsgZGF0YTogc3ViVmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUuc3ViVmFsdWVzXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgW2NsYXNzLmlzLXN1Yi1yb3ddPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcGwtM1wiPnt7IHN1YlZhbHVlLmtleSB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN1YlZhbHVlLmlkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMVwiPjo8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nU3dpdGNoQ2FzZT1cIidiYWNrZ3JvdW5kRGF0YSdcIj57eyBzdWJWYWx1ZS5pZCB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rXG4gICAgICAgICAgICAgICAgICAgICpuZ1N3aXRjaERlZmF1bHRcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ibG9jayBwbC00XCJcbiAgICAgICAgICAgICAgICAgICAgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySHRtbF09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZCkubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwXCIgKm5nSWY9XCJzdWJWYWx1ZS5zaG93VW5pdHNcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+LTwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7IGRhdGE6IHN1YlZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9oZS1kYXRhLXRhYmxlPlxuXG4gIDxkaXYgY2xhc3M9XCJpcy1zaXplLTcgaXMtaXRhbGljXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbnMgaXMtdmFyaWFibGUgaXMtMSBteS0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGlzLW5hcnJvd1wiPlxuICAgICAgICA8cD5cbiAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBwci0yXCIgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7IGxvZ0NvbG9yW3N0YXR1cy52YWx1ZV0gfX1cIj5cbiAgICAgICAgICAgICAgPGZhLWljb24gW2ljb25dPVwibG9nSWNvbltzdGF0dXMudmFsdWVdXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj57eyBzdGF0dXMudmFsdWUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGhhcy10ZXh0LXJpZ2h0XCIgKm5nSWY9XCJmaWx0ZXJlZFR5cGUoKVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICBjbGFzcz1cInNlbGVjdG9yXCJcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cIm9ubHlSZXF1aXJlZENoYW5nZWQoJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtKClcIiAvPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlxuICAgICAgICAgICAgU2hvdyBvbmx5IHt7IGZpbHRlcmVkVHlwZSgpIHwgcGx1cmFsaXplIH19IGluY2x1ZGVkIGluIHRoZSBkZWZhdWx0IEhlc3RpYSBzeXN0ZW0gYm91bmRhcnlcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNzaG93T3V0ZGF0ZWRMb2dzV2FybmluZz5cbiAgPGRpdiBjbGFzcz1cImlzLTMgaGFzLXRleHQtY2VudGVyZWRcIj5cbiAgICA8cCBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxmYS1pY29uIGNsYXNzPVwiaXMtcHItMlwiIGljb249XCJleGNsYW1hdGlvbi10cmlhbmdsZVwiPjwvZmEtaWNvbj5cbiAgICAgIDxzcGFuPlRoZXNlIGxvZ3MgbWlnaHQgYmUgaW5jb3JyZWN0IGFzIHRoZSBjYWxjdWxhdGlvbnMgYXJlIG91dGRhdGVkLjwvc3Bhbj5cbiAgICA8L3A+XG4gICAgPHAgY2xhc3M9XCJpcy11bmRlcmxpbmVkIGlzLXNpemUtN1wiPjxhIChjbGljayk9XCJzaG93T3V0ZGF0ZWRMb2dzLnNldCh0cnVlKVwiPlZpZXcgbG9ncyBhbnl3YXkuPC9hPjwvcD5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPG5nLXRlbXBsYXRlICNub3RJblN5c3RlbUJvdW5kYXJ5PlxuICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIm1ldGhvZE1vZGVsc0NvdW50KClcIj5cbiAgICAgIDxzcGFuPk5vdCBpbiBIZXN0aWEgc3lzdGVtIGJvdW5kYXJ5PC9zcGFuPlxuICAgIDwvdGQ+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzU3lzdGVtQm91bmRhcnkoZGF0YSk7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgIDx0ZCBjbGFzcz1cImJsYW5rLW5vZGUtaW5kZXgte3sgaSB9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50KCkgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldE1vZGVsc0F0KGRhdGEsIGkpOyBsZXQgbW9kZWxzOyBlbHNlOiBub1ZhbHVlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbW9kZWxTZXJpZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWw6IG1vZGVscywgZGF0YSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJtb2RlbHMgfCBpc0FycmF5OyBlbHNlIG1vZGVsU2VyaWVcIj5cbiAgICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWwsIGRhdGEgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3RkPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjYmxhbmtOb2RlTW9kZWwgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHNwYW5cbiAgICBjbGFzcz1cImlzLW5vd3JhcFwiXG4gICAgW2NsYXNzLnRyaWdnZXItcG9wb3Zlcl09XCJtb2RlbC5zaG93TG9nc1wiXG4gICAgW25nYlBvcG92ZXJdPVwibG9nRGV0YWlsc1wiXG4gICAgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIlxuICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIlxuICAgICNwPVwibmdiUG9wb3ZlclwiXG4gICAgcGxhY2VtZW50PVwibGVmdFwiXG4gICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiBtb2RlbC5zaG93TG9ncyA/IHAub3Blbih7IGxvZ3M6IG1vZGVsLmxvZ3MgfSkgOiBudWxsXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7IG1ldGhvZE5hbWUobW9kZWwpIH19PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncz8ubWV0aG9kVGllciB8fCBtb2RlbC5tb2RlbD8ubWV0aG9kVGllclwiPlxuICAgICAgW3t7IG1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXIgfX1dXG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW5cbiAgICAgIGNsYXNzPVwicGwtMSBoYXMtdGV4dC17eyBsb2dDb2xvclttb2RlbC5zdGF0dXNdIH19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCJcbiAgICAgIFthdXRvQ2xvc2VdPVwiJ291dHNpZGUnXCJcbiAgICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgICB0cmlnZ2Vycz1cIm1hbnVhbFwiXG4gICAgICAjcDE9XCJuZ2JQb3BvdmVyXCJcbiAgICAgIHBsYWNlbWVudD1cImxlZnRcIlxuICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBwMS5pc09wZW4oKSA/IHAxLmNsb3NlKCkgOiBwMS5vcGVuKHsgbW9kZWwsIGRhdGEgfSlcIj5cbiAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bbW9kZWwuc3RhdHVzXVwiPjwvZmEtaWNvbj5cbiAgICA8L3NwYW4+XG5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLm1vZGVsXCI+XG4gICAgICAoXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZG9jc0xpbms7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBtb2RlbC5tb2RlbCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICApXG4gICAgPC9zcGFuPlxuICA8L3NwYW4+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vVmFsdWU+LTwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbm90UmVjYWxjdWxhdGVkPm5vdCByZWNhbGN1bGF0ZWQ8L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0RldGFpbHMgbGV0LWxvZ3M9XCJsb2dzXCI+XG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXJcIiAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGhcIj5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LnJlcXVpcmVtZW50c1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiByZXF1aXJlbWVudEtleXMobG9ncy5yZXF1aXJlbWVudHMpXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZTsgY29udGV4dDogeyBrZXksIHZhbHVlOiBsb2dzLnJlcXVpcmVtZW50c1trZXldIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LmxvZ3NcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgbG9ncy5sb2dzIHwga2V5c1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6IGtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPGRpdiBjbGFzcz1cIml0LW10LTJcIiAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGggaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5GaWxlbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Db2x1bW4gVGl0bGU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+Um93ICh0ZXJtLmlkKTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGxvZ3MubWlzc2luZ0xvb2t1cHNcIj5cbiAgICAgICAgICAgICAgPHRkPnt7IGRhdGEuZmlsZW5hbWUgfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS5jb2x1bW4gfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS50ZXJtSWQgfX08L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lVmFsdWUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFZhbHVlPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiPnt7IHZhbHVlIH19PC9zcGFuPlxuICA8L25nLXRlbXBsYXRlPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVxdWlyZW1lbnRMaW5rZWROb2RlKGtleSwgdmFsdWUpOyBsZXQgbGlua2VkTm9kZTsgZWxzZTogZGVmYXVsdFZhbHVlXCI+XG4gICAgPGhlLW5vZGUtbGlua1xuICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCJcbiAgICAgIGxpbmtDbGFzcz1cImlzLWRhcmtcIlxuICAgICAgW25vZGVdPVwibGlua2VkTm9kZVwiXG4gICAgICBbc2hvd0V4dGVybmFsTGlua109XCJ0cnVlXCI+PC9oZS1ub2RlLWxpbms+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8dHI+XG4gICAgPHRkIGNsYXNzPVwiaGFzLWJvcmRlci1yaWdodCBjb3B5LWxvZ1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdE1lc3NhZ2U+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+e3sga2V5IHwga2V5VG9MYWJlbCB9fTwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvcGVydHlfaWQnXCI+UHJvcGVydHkgVGVybSBAaWQ8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9kdWN0X2lkJ1wiPlByb2R1Y3QgVGVybSBAaWQ8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidpbnB1dF9pZCdcIj5JbnB1dCBUZXJtIEBpZDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbm9kZV90eXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5Ob2RlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2l0ZVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+SXMgdGhlIGN1cnJlbnQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnNpdGVUeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvZHVjdF9pZF9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BcmUgYW55IG9mIHRoZSBQcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5AaWQ8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIFByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXRfaWRfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QXJlIGFueSBvZiB0aGUgSW5wdXQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPkBpZDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIElucHV0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8IS0tIERlcHJlY2F0ZWQgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X2lkX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+QGlkPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+dGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2dlb3NwYXRpYWxfZGF0YSdcIj5cbiAgICAgICAgICAgICAgSGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5cbiAgICAgICAgICAgICAgSGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2N1cnJlbnRfc2l6ZSdcIj5DdXJyZW50IHBvbHlnb24gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ21heF9hcmVhX3NpemUnXCI+TWF4aW11bSBwb2x5Z29uIGFyZWEgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3JlZ2lvbl9mYWN0b3InXCI+RmFjdG9yIGZyb20gcmVnaW9uIGxvb2t1cDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5DeWNsZSBjb250YWluczwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+cGVzdGljaWRlQUk8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPklucHV0czwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2FsbF9wZXN0aWNpZGVBSV9oYXZlX2xvb2t1cF92YWx1ZSdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QWxsPC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5wZXN0aWNpZGVBSTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+SW5wdXRzIGhhdmUgYSBsb29rdXAgdmFsdWU8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19jcm9wX3Jlc2lkdWVfYnVybnQnXCI+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+aXMgcHJlc2VudCBhcyBQcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidsaXF1aWRfc2x1cnJ5X3NsdWRnZV9QJ1wiPkxpcXVpZCwgU2x1cnJ5LCBhbmQgU2x1ZGdlIFA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGFyc2VMb2dDb21wbGV0ZW5lc3Moa2V5KTsgbGV0IGNvbXBsZXRlbmVzczsgZWxzZTogZGVmYXVsdE1lc3NhZ2VcIj5cbiAgICAgICAgICA8c3Bhbj5EYXRhIGNvbXBsZXRlbmVzcyBmb3I8L3NwYW4+XG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+e3sgY29tcGxldGVuZXNzLmtleSB9fTwvY29kZT5cbiAgICAgICAgICA8c3Bhbj5tdXN0IGJlPC9zcGFuPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IGNvbXBsZXRlbmVzcy52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3NwYW4+XG4gICAgICA8aGUtY2xpcGJvYXJkXG4gICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiXG4gICAgICAgIGNsaXBib2FyZENsYXNzPVwiaXMtc2l6ZS03IGlzLXAtMVwiXG4gICAgICAgIFtpY29uXT1cIlsnZmFyJywgJ2Nsb25lJ11cIlxuICAgICAgICBbdmFsdWVdPVwia2V5XCJcbiAgICAgICAgW2hpZGVUZXh0XT1cInRydWVcIj48L2hlLWNsaXBib2FyZD5cbiAgICA8L3RkPlxuICAgIDx0ZD5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlVmFsdWU+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lVmFsdWU7IGNvbnRleHQ6IHsga2V5LCB2YWx1ZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cImxvZ1ZhbHVlQXJyYXkodmFsdWUpOyBsZXQgdmFsdWVBcnJheTsgZWxzZTogc2luZ2xlVmFsdWVcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1ib3JkZXJlZCBpcy1zdHJpcGVkXCI+XG4gICAgICAgICAgPHRoZWFkICpuZ0lmPVwidmFsdWVBcnJheVswXSB8IGlzT2JqZWN0XCI+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVswXSB8IGtleXNcIj57eyB2LmtleSB9fTwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzaW5nbGVBcnJheVZhbHVlPlxuICAgICAgICAgICAgICAgIDx0ZD57eyB2IH19PC90ZD5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInYgfCBpc09iamVjdDsgZWxzZSBzaW5nbGVBcnJheVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCB2diBvZiB2IHwga2V5c1wiPnt7IHZ2LnZhbHVlIH19PC90ZD5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L3RkPlxuICA8L3RyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dTdGF0dXNEZXRhaWxzIGxldC1tb2RlbD1cIm1vZGVsXCIgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIDxuZy1jb250YWluZXIgKmJpbmRPbmNlPVwibW9kZWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiPlxuICAgICAgPHNwYW4+U3RhdHVzOjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLnN0YXR1cyB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5zdGF0dXMgPT09IExvZ1N0YXR1cy5ub3RSZXF1aXJlZCAmJiBtb2RlbC5sb2dzPy5pc19ub3RfcmVsZXZhbnQgPT09ICdUcnVlJ1wiPlxuICAgICAgPHVsIGNsYXNzPVwiaXMtcGwtMyBpcy1saXN0LXN0eWxlLWRpc2NcIj5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5zaXRlVHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgVGhlXG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+c2l0ZS5zaXRlVHlwZTwvY29kZT5cbiAgICAgICAgICBpcyBub3QgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucHJvZHVjdF9pZF9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgTm9uZSBvZiB0aGVcbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5Qcm9kdWN0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0uQGlkPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LnByb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIE5vbmUgb2YgdGhlXG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+UHJvZHVjdDwvY29kZT5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj50ZXJtLnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LmlucHV0X2lkX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBOb25lIG9mIHRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPklucHV0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0uQGlkPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LmlucHV0X3Rlcm1UeXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBOb25lIG9mIHRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPklucHV0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0udGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgaXMgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLWNvbnRhaW5lclxuICAgICAgKm5nSWY9XCJtb2RlbC5sb2dzICYmIG1vZGVsLnN0YXR1cyAhPT0gTG9nU3RhdHVzLm5vdFJlcXVpcmVkICYmIG1vZGVsLnN0YXR1cyAhPT0gTG9nU3RhdHVzLnNraXBIaWVyYXJjaHlcIj5cbiAgICAgIDx1bCBjbGFzcz1cImlzLXBsLTMgaXMtbGlzdC1zdHlsZS1kaXNjXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjc2hvd1J1bk9yY2hlc3RyYXRvcj5cbiAgICAgICAgICA8bGkgY2xhc3M9XCJpcy1ydW4tb3JjaGVzdHJhdG9yXCI+XG4gICAgICAgICAgICA8cCAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1blwiPkFsbCB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbWV0IHRvIHJ1biB0aGUgbW9kZWwuPC9wPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5cbiAgICAgICAgICAgICAgPHA+U29tZSBvZiB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbm90IG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgICAgICAgPHA+WW91IGNhbiBjbGljayBvbiB0aGUgbW9kZWwgbmFtZSBvbiB0aGUgbGVmdCB0byB2aWV3IHRoZSBkZWJ1Z2dpbmcgbG9ncy48L3A+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5sb2dzPy5sb2dzPy5lcnJvclwiPlxuICAgICAgICAgICAgICA8cD5UaGUgbW9kZWwgZmFpbGVkIHRvIHJ1biBmb3IgdGhlIGZvbGxvd2luZyByZWFzb246PC9wPlxuICAgICAgICAgICAgICA8cD5cbiAgICAgICAgICAgICAgICA8Y29kZT57eyBtb2RlbC5sb2dzLmxvZ3MuZXJyb3IgfX08L2NvZGU+XG4gICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPGxpXG4gICAgICAgICAgY2xhc3M9XCJpcy1uby1ydW4tb3JjaGVzdHJhdG9yXCJcbiAgICAgICAgICAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1bk9yY2hlc3RyYXRvciA9PT0gZmFsc2U7IGVsc2Ugc2hvd1J1bk9yY2hlc3RyYXRvclwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwubG9ncy5ydW5SZXF1aXJlZFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ydW4tbm9kZS10eXBlLW5vdC1hbGxvd2VkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/Lm5vZGVfdHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgICAgIFRoaXMgbW9kZWwgc2hvdWxkIG5vdCBydW4gZm9yIHt7IG5vZGVUeXBlKCkgfCBwbHVyYWxpemU6IDAgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcnVuTm9Db25maWc+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICAgICAgVGhlIHt7IGRhdGEudHlwZSB8fCAnYmxhbmsgbm9kZScgfX0gd2l0aCBUZXJtXG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IGRhdGEudGVybUlkIH19PC9jb2RlPlxuICAgICAgICAgICAgICBpcyBhbHJlYWR5IHByZXNlbnQgb3IgYWxyZWFkeSBhZGRlZCBieSBhbm90aGVyIG1vZGVsLlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuY29uZmlnOyBlbHNlIHJ1bk5vQ29uZmlnXCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImlzLXJ1bi1zdHJhdGVneS17eyBtb2RlbC5jb25maWcucnVuU3RyYXRlZ3kgfX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWx3YXlzJ1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfa2V5X2lmX21pc3NpbmcnXCI+V2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfYmxhbmtfbm9kZV9pZl9taXNzaW5nJ1wiPldlIG9ubHkgZ2FwLWZpbGwgdGhpcyBCbGFuayBOb2RlIGlmIG5vdCBwcmVzZW50Ljwvc3Bhbj5cbiAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgPHAgY2xhc3M9XCJpcy1tdC0xXCI+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ydW4td2l0aC1tZWFzdXJlZFwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgIG1vZGVsLmNvbmZpZy5ydW5BcmdzPy5ydW5Ob25NZWFzdXJlZCAmJiBoYXNNZXRob2RUaWVyKGRhdGEub3JpZ2luYWwsIEVtaXNzaW9uTWV0aG9kVGllci5tZWFzdXJlZClcbiAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICBUaGVcbiAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj57eyBtb2RlbC5jb25maWcudmFsdWUgfX08L2NvZGU+XG4gICAgICAgICAgICAgICAgd2FzIHJlcG9ydGVkIGFzIG1lYXN1cmVkLlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncz8ucmVwbGFjZUxvd2VyVGllciAhPT0gdW5kZWZpbmVkXCI+XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICBUaGUgcmVjYWxjdWxhdGVkXG4gICAgICAgICAgICA8Yj5tZXRob2RUaWVyPC9iPlxuICAgICAgICAgICAgd2FzXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMSBpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCIhbW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTEgaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+aGlnaGVyIHRoYW4gb3IgZXF1YWwgdG88L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+XG4gICAgICAgICAgICB0aGUgb3JpZ2luYWxcbiAgICAgICAgICAgIDxiPm1ldGhvZFRpZXI8L2I+XG4gICAgICAgICAgICAuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuXG4gICAgICAgIDxsaSBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VMb3dlclRpZXJcIiAqbmdJZj1cIm1vZGVsLmxvZ3MucmVwbGFjZUxvd2VyVGllclwiPlxuICAgICAgICAgIDxzcGFuPlRoZSByZWNhbGN1bGF0ZWQ8L3NwYW4+XG4gICAgICAgICAgPGIgY2xhc3M9XCJpcy1wbC0xXCI+e3sgbW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnIH19PC9iPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPndhczwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc/Lm1lcmdlQXJnc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXVuZGVybGluZWRcIiAqbmdJZj1cIiFtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5sZXNzIHRoYW48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+bW9yZSB0aGFuIG9yIGVxdWFsIHRvPC9zcGFuPlxuICAgICAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDAgfX0lPC9iPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwiIW1vZGVsLmxvZ3MucmVwbGFjZVRocmVzaG9sZFwiPm5vdCBzdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+c3VmZmljaWVudGx5PC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbDwvc3Bhbj5cbiAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWc/Lm1lcmdlQXJncz8ucmVwbGFjZVRocmVzaG9sZD8uWzBdIHx8ICd2YWx1ZScgfX0uPC9iPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2RvY3NMaW5rIGxldC1tb2RlbD5cbiAgPGEgW2hyZWZdPVwibW9kZWwuYXBpRG9jc1BhdGggfHwgbW9kZWwuZG9jUGF0aCB8fCBtb2RlbC5wYXRoXCIgdGFyZ2V0PVwiX2JsYW5rXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxzcGFuPkRvY3M8L3NwYW4+XG4gICAgPGZhLWljb24gY2xhc3M9XCJtbC0xXCIgaWNvbj1cImV4dGVybmFsLWxpbmstYWx0XCIgc2l6ZT1cInNtXCI+PC9mYS1pY29uPlxuICA8L2E+XG48L25nLXRlbXBsYXRlPlxuIl19
|
|
356
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVHLE9BQU8sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEUsT0FBTyxFQUFjLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkgsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixrQkFBa0IsRUFJbEIsUUFBUSxFQUNSLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsNEJBQTRCLEVBQzVCLHVCQUF1QixFQUN4QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFOUMsT0FBTyxFQUE0RCxhQUFhLEVB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WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBJbnB1dCwgU2lnbmFsLCBjb21wdXRlZCwgZWZmZWN0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRvU2lnbmFsLCB0b09ic2VydmFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmb3JrSm9pbiwgZnJvbSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0LCBmaWx0ZXIsIHJlZHVjZSwgdG9BcnJheSwgbWFwLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWVyZ2VNYXAsIHRhcCwgbWVyZ2VBbGwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDeWNsZUZ1bmN0aW9uYWxVbml0LFxuICBFbWlzc2lvbk1ldGhvZFRpZXIsXG4gIElDeWNsZUpTT05MRCxcbiAgSVRlcm1KU09OTEQsXG4gIEpTT05MRCxcbiAgTm9kZVR5cGUsXG4gIFRlcm1UZXJtVHlwZSxcbiAgZW1pc3Npb25UZXJtVGVybVR5cGUsXG4gIGltcGFjdEFzc2Vzc21lbnRUZXJtVGVybVR5cGUsXG4gIG1lYXN1cmVtZW50VGVybVRlcm1UeXBlXG59IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IGtleVRvTGFiZWwsIHVuaXF1ZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMnO1xuaW1wb3J0IHsgcHJvcGVydHlWYWx1ZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMvZGlzdC90ZXJtJztcbmltcG9ydCB7IGxvYWRSZXNvdXJjZUtleSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvZ2xvc3NhcnknO1xuaW1wb3J0IHsgRGF0YVN0YXRlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9hcGknO1xuXG5pbXBvcnQgeyBibGFua05vZGUsIG5vbkJsYW5rTm9kZSwgYmxhbmtOb2Rlc0tleSwgbm9uQmxhbmtOb2Rlc0tleSwgQmxhbmtOb2Rlc0tleSB9IGZyb20gJy4uLy4uL2NvbW1vbi9ub2RlLXV0aWxzJztcbmltcG9ydCB7IGJhc2VVcmwsIGlzRXh0ZXJuYWwsIHR5cGVhaGVhZEZvY3VzIH0gZnJvbSAnLi4vLi4vY29tbW9uL3V0aWxzJztcbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSxcbiAgSUJsYW5rTm9kZUxvZyxcbiAgTG9nU3RhdHVzLFxuICBJQ29uZmlnTW9kZWwsXG4gIGdyb3VwTG9nc0J5TW9kZWwsXG4gIGdyb3VwTG9nc0J5VGVybSxcbiAgbW9kZWxDb3VudCxcbiAgY29tcHV0ZVRlcm1zLFxuICBsb2dWYWx1ZUFycmF5LFxuICBJTm9kZVRlcm1Mb2dzLFxuICBJTm9kZUxvZ3MsXG4gIGdyb3VwZExvZ3NCeUtleSxcbiAgSU5vbkJsYW5rTm9kZUxvZyxcbiAgSUxvZyxcbiAgY29tcHV0ZUtleXNcbn0gZnJvbSAnLi9ub2RlLWxvZ3MtbW9kZWxzLm1vZGVsJztcbmltcG9ydCB7IElKU09OTm9kZSwgSGVOb2RlU2VydmljZSB9IGZyb20gJy4uL25vZGUuc2VydmljZSc7XG5pbXBvcnQgeyBub2RlVmVyc2lvbiB9IGZyb20gJy4uL25vZGUtbW9kZWwtdmVyc2lvbic7XG5pbXBvcnQgeyBIZUVuZ2luZVNlcnZpY2UsIElNb2RlbCwgSU9yY2hlc3RyYXRvckNvbmZpZywgZmluZE9yY2hlc3RyYXRvck1vZGVsIH0gZnJvbSAnLi4vLi4vZW5naW5lL2VuZ2luZS5zZXJ2aWNlJztcbmltcG9ydCB7IG1hdGNoRXhhY3RRdWVyeSwgbWF0Y2hJZCwgbWF0Y2hUZXJtVHlwZSwgbWF0Y2hUeXBlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5tb2RlbCc7XG5pbXBvcnQgeyBIZVNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgdGVybVR5cGVMYWJlbCB9IGZyb20gJy4uLy4uL3Rlcm1zL3Rlcm1zLm1vZGVsJztcblxuaW50ZXJmYWNlIElUZXJtc0J5SWRNYXBwaW5nIHtcbiAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbn1cblxuY29uc3Qgbm9kZVR5cGUgPSAobm9kZT86IElKU09OTm9kZSkgPT4gbm9kZT8uWydAdHlwZSddIHx8IG5vZGU/LnR5cGU7XG5jb25zdCBub2RlSWQgPSAobm9kZT86IElKU09OTm9kZSkgPT4gbm9kZT8uWydAaWQnXSB8fCBub2RlPy5pZDtcbmNvbnN0IG5vZGVUeXBlc0xvd2VyQ2FzZSA9IE9iamVjdC52YWx1ZXMoTm9kZVR5cGUpLm1hcCh2ID0+IHYudG9Mb3dlckNhc2UoKSk7XG5cbmNvbnN0IGxvZ0ljb246IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nIHwgc3RyaW5nW107XG59ID0ge1xuICBbTG9nU3RhdHVzLnN1Y2Nlc3NdOiAnY2hlY2snLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ3RpbWVzJyxcbiAgW0xvZ1N0YXR1cy5za2lwSGllcmFyY2h5XTogWydmYXInLCAnY2lyY2xlJ10sXG4gIFtMb2dTdGF0dXMuZGF0YVByb3ZpZGVkXTogJ2NpcmNsZScsXG4gIFtMb2dTdGF0dXMubm90UmVxdWlyZWRdOiAnZG90LWNpcmNsZSdcbn07XG5cbmNvbnN0IGxvZ0NvbG9yOiB7XG4gIFtzdGF0dXMgaW4gTG9nU3RhdHVzXT86IHN0cmluZztcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdzdWNjZXNzJyxcbiAgW0xvZ1N0YXR1cy5lcnJvcl06ICdkYW5nZXInLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiAnZGFyaycsXG4gIFtMb2dTdGF0dXMuZGF0YVByb3ZpZGVkXTogJ2RhcmsnLFxuICBbTG9nU3RhdHVzLm5vdFJlcXVpcmVkXTogJ2dyZXknXG59O1xuXG5jb25zdCBzaG91bGRTaG93QmxhbmtOb2RlID0gKGJsYW5rTm9kZUxvZzogSUJsYW5rTm9kZUxvZykgPT5cbiAgW1xuICAgIGJsYW5rTm9kZUxvZz8uY29uZmlnTW9kZWxzPy5sZW5ndGgsXG4gICAgYmxhbmtOb2RlTG9nPy5rZXlzPy5sZW5ndGgsXG4gICAgYmxhbmtOb2RlTG9nPy5zdWJWYWx1ZXM/Lmxlbmd0aCxcbiAgICBibGFua05vZGVMb2c/Lm9yaWdpbmFsPy5sZW5ndGgsXG4gICAgYmxhbmtOb2RlTG9nPy5yZWNhbGN1bGF0ZWQ/Lmxlbmd0aFxuICBdLnNvbWUoQm9vbGVhbik7XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgX21vZGVsPzogSU1vZGVsKSA9PlxuICAobWV0aG9kSWRcbiAgICA/IHtcbiAgICAgICAgJ2N5Y2xlL3RyYW5zZm9ybWF0aW9uJzogJ0RhdGEgRnJvbSBUcmFuc2Zvcm1hdGlvbicsXG4gICAgICAgIGltcGFjdF9hc3Nlc3NtZW50OiAnRGF0YSBGcm9tIEN5Y2xlJ1xuICAgICAgfVttZXRob2RJZF1cbiAgICA6ICcnKSB8fCAobWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKSk7XG5cbmNvbnN0IGdldE1vZGVsc0F0ID0gKGxvZzogSUJsYW5rTm9kZUxvZ1N1YlZhbHVlIHwgSUJsYW5rTm9kZUxvZywgaW5kZXg6IG51bWJlcikgPT5cbiAgKCdtb2RlbHNJblN1YlZhbHVlcycgaW4gbG9nID8gIWxvZy5tb2RlbHNJblN1YlZhbHVlcyB8fCAhbG9nLmlzT3BlbiA6IHRydWUpICYmIGxvZy5jb25maWdNb2RlbHNbaW5kZXhdO1xuXG5jb25zdCByZXF1aXJlbWVudEtleXMgPSAocmVxdWlyZW1lbnRzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSA9PlxuICBPYmplY3Qua2V5cyhyZXF1aXJlbWVudHMpLmZpbHRlcihrID0+ICFub2RlVHlwZXNMb3dlckNhc2UuaW5jbHVkZXMoaykpO1xuXG5jb25zdCByZXF1aXJlbWVudENvbG9yID0gKHZhbHVlOiBhbnkpID0+ICghdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnKTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXk6IHtcbiAgW2tleTogc3RyaW5nXTogKHZhbHVlOiBzdHJpbmcpID0+IFBhcnRpYWw8SlNPTkxEPE5vZGVUeXBlPj47XG59ID0ge1xuICByZWxhdGVkX2N5Y2xlczogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGN5Y2xlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgaW1wYWN0X2Fzc2Vzc21lbnRfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuSW1wYWN0QXNzZXNzbWVudCwgJ0BpZCc6IHYgfSksXG4gIHNpdGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU2l0ZSwgJ0BpZCc6IHYgfSksXG4gIHNvdXJjZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5Tb3VyY2UsICdAaWQnOiB2IH0pLFxuICBwcm9wZXJ0eV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLCAnQGlkJzogdiB9KSxcbiAgaW5wdXRfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSwgJ0BpZCc6IHYgfSksXG4gIHByb2R1Y3RfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSwgJ0BpZCc6IHYgfSksXG4gIHByYWN0aWNlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pXG59O1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGUgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+XG4gIGtleSBpbiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleSAmJiBbJ05vbmUnLCAnJywgbnVsbF0uaW5jbHVkZXModmFsdWUpICYmIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5W2tleV0odmFsdWUpO1xuXG5jb25zdCBpc1N5c3RlbUJvdW5kYXJ5ID1cbiAgKHRlcm1JZD86IHN0cmluZykgPT5cbiAgKHsgaXNSZWNhbGN1bGF0ZWQsIGlzUmVxdWlyZWQgfTogUGljazxJTG9nIHwgSUJsYW5rTm9kZUxvZ1N1YlZhbHVlLCAnaXNSZWNhbGN1bGF0ZWQnIHwgJ2lzUmVxdWlyZWQnPikgPT4ge1xuICAgIC8vIG9ubHkgZXhpc3RzIGZvciBzb21lIHRlcm1zXG4gICAgY29uc3QgaW5TeXN0ZW1Cb3VuZGFyeSA9IGxvYWRSZXNvdXJjZUtleSgnaW5IZXN0aWFEZWZhdWx0U3lzdGVtQm91bmRhcnkuanNvbicsIHRlcm1JZCk7XG4gICAgcmV0dXJuICFpblN5c3RlbUJvdW5kYXJ5ID8gW2lzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkXS5zb21lKEJvb2xlYW4pIDogYCR7aW5TeXN0ZW1Cb3VuZGFyeX1gID09PSAndHJ1ZSc7XG4gIH07XG5cbmNvbnN0IGlzR2VuZXJpY1Rlcm0gPSAodGVybUlkOiBzdHJpbmcpID0+IFt0ZXJtSWQuc3RhcnRzV2l0aCgnZXhjcmV0YScpXS5ldmVyeShCb29sZWFuKTtcblxuY29uc3QgZXh0cmFUZXJtSWRzRnJvbUNvbmZpZyA9IChjb25maWc6IElPcmNoZXN0cmF0b3JDb25maWcsIGtleTogYmxhbmtOb2Rlc0tleSwgbG9nczogSU5vZGVMb2dzIHwgSU5vZGVUZXJtTG9ncykgPT5cbiAgdW5pcXVlKFtcbiAgICAuLi4oY29uZmlnPy5tb2RlbHMgfHwgW10pXG4gICAgICAuZmxhdCgpXG4gICAgICAuZmlsdGVyKG0gPT4gbS5rZXkgPT09IGtleSlcbiAgICAgIC5tYXAobSA9PiBtLnZhbHVlKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmZpbHRlcih2ID0+ICFpc0dlbmVyaWNUZXJtKHYpKSxcbiAgICAvLyBtYXRjaCBsb2dzIHdpdGggYSBjb25maWd1cmF0aW9uXG4gICAgLi4uT2JqZWN0LmVudHJpZXMobG9ncyB8fCB7fSlcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChbX2lkLCB2YWx1ZV0pID0+XG4gICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5zb21lKChbbW9kZWwsIHZdOiBbbW9kZWw6IHN0cmluZywgdmFsdWU6IGFueV0pID0+XG4gICAgICAgICAgICBmaW5kT3JjaGVzdHJhdG9yTW9kZWwoY29uZmlnLCB7IGtleSwgbW9kZWwsIHZhbHVlOiB2Lm1vZGVsX2tleSB9KVxuICAgICAgICAgIClcbiAgICAgIClcbiAgICAgIC5tYXAoKFtrZXldKSA9PiBrZXkpXG4gIF0pO1xuXG5jb25zdCBtYXRjaFRlcm1UeXBlRnJvbUtleToge1xuICBba2V5IGluIEJsYW5rTm9kZXNLZXldPzogVGVybVRlcm1UeXBlW107XG59ID0ge1xuICBbQmxhbmtOb2Rlc0tleS5lbWlzc2lvbnNdOiBlbWlzc2lvblRlcm1UZXJtVHlwZS50ZXJtLFxuICBbQmxhbmtOb2Rlc0tleS5tZWFzdXJlbWVudHNdOiBtZWFzdXJlbWVudFRlcm1UZXJtVHlwZS50ZXJtLFxuICAvLyBJbXBhY3RBc3Nlc3NtZW50XG4gIC8vIGRpc2FibGVkIGFzIGl0IHdpbGwgc2hvdyB0ZXJtcyBpbiBib3RoIGBlbWlzc2lvbnNgIGFuZCBgcmVzb3VyY2VVc2VgIGNhdGVnb3JpZXMsIHNlZSBpc3N1ZSAjMjczXG4gIC8vIGVtaXNzaW9uc1Jlc291cmNlVXNlOiBpbXBhY3RBc3Nlc3NtZW50VGVybVRlcm1UeXBlLmVtaXNzaW9uc1Jlc291cmNlVXNlLnRlcm0sXG4gIFtCbGFua05vZGVzS2V5LmltcGFjdHNdOiBpbXBhY3RBc3Nlc3NtZW50VGVybVRlcm1UeXBlLmltcGFjdHMudGVybSxcbiAgW0JsYW5rTm9kZXNLZXkuZW5kcG9pbnRzXTogaW1wYWN0QXNzZXNzbWVudFRlcm1UZXJtVHlwZS5lbmRwb2ludHMudGVybVxufTtcblxuY29uc3QgZmlsdGVyQmxhbmtOb2RlID0gKFxuICB7IHRlcm06IHsgbmFtZSwgJ0BpZCc6IGlkIH0sIHN1YlZhbHVlcywgLi4ubG9nIH06IElCbGFua05vZGVMb2csXG4gIHNlbGVjdGVkVGVybT86IHN0cmluZyxcbiAgZmlsdGVyVGVybVR5cGVzPzogVGVybVRlcm1UeXBlW10sXG4gIG9ubHlSZXF1aXJlZD86IGJvb2xlYW5cbikgPT5cbiAgc2VsZWN0ZWRUZXJtXG4gICAgPyBuYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VsZWN0ZWRUZXJtLnRvTG93ZXJDYXNlKCkpXG4gICAgOiAhZmlsdGVyVGVybVR5cGVzPy5sZW5ndGggfHwgIW9ubHlSZXF1aXJlZCB8fCBpc1N5c3RlbUJvdW5kYXJ5KGlkKShsb2cpIHx8IHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkoaWQpKTtcblxuY29uc3QgdGVybVNlYXJjaCA9ICh0ZXJtID0gJycpID0+IHRlcm0ucmVwbGFjZSgvWyxcXHNdL2csICcnKS50b0xvd2VyQ2FzZSgpO1xuXG5jb25zdCBsaXN0VGVybUlkID0gKHRlcm1zOiBJVGVybUpTT05MRFtdKSA9PlxuICB0ZXJtc1xuICAgIC5tYXAoKHsgbmFtZSB9KSA9PiBuYW1lKVxuICAgIC5zb3J0KClcbiAgICAuam9pbignLCcpO1xuXG5jb25zdCBjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeCA9ICdfY29tcGxldGUnO1xuY29uc3QgY29tcGxldGVuZXNzSW5jb21wbGV0ZVN1ZmZpeCA9ICdfaW5jb21wbGV0ZSc7XG5jb25zdCBwYXJzZUxvZ0NvbXBsZXRlbmVzcyA9IChrZXk6IHN0cmluZykgPT5cbiAgW1xuICAgIGtleS5zdGFydHNXaXRoKCd0ZXJtX3R5cGVfJyksXG4gICAga2V5LmVuZHNXaXRoKGNvbXBsZXRlbmVzc0NvbXBsZXRlU3VmZml4KSB8fCBrZXkuZW5kc1dpdGgoY29tcGxldGVuZXNzSW5jb21wbGV0ZVN1ZmZpeClcbiAgXS5ldmVyeShCb29sZWFuKVxuICAgID8ge1xuICAgICAgICBrZXk6IGtleVxuICAgICAgICAgIC5yZXBsYWNlKCd0ZXJtX3R5cGVfJywgJycpXG4gICAgICAgICAgLnJlcGxhY2UoY29tcGxldGVuZXNzQ29tcGxldGVTdWZmaXgsICcnKVxuICAgICAgICAgIC5yZXBsYWNlKGNvbXBsZXRlbmVzc0luY29tcGxldGVTdWZmaXgsICcnKSxcbiAgICAgICAgdmFsdWU6IGtleS5lbmRzV2l0aChjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeClcbiAgICAgIH1cbiAgICA6IG51bGw7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLW5vZGUtbG9ncy1tb2RlbHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTm9kZUxvZ3NNb2RlbHNDb21wb25lbnQge1xuICBwcml2YXRlIF9ub2RlID0gc2lnbmFsKHVuZGVmaW5lZCBhcyBJSlNPTk5vZGUpO1xuICBASW5wdXQoKVxuICBzZXQgbm9kZSh2YWx1ZTogSUpTT05Ob2RlKSB7XG4gICAgdGhpcy5fbm9kZS5zZXQodmFsdWUpO1xuICAgIHZhbHVlICYmIHRoaXMubG9hZExvZ3ModmFsdWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9ub2RlS2V5ID0gc2lnbmFsKHVuZGVmaW5lZCBhcyBibGFua05vZGVzS2V5IHwgbm9uQmxhbmtOb2Rlc0tleSk7XG4gIEBJbnB1dCgpXG4gIHNldCBub2RlS2V5KHZhbHVlOiBibGFua05vZGVzS2V5IHwgbm9uQmxhbmtOb2Rlc0tleSkge1xuICAgIHRoaXMuX25vZGVLZXkuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX29yaWdpbmFsVmFsdWVzID0gc2lnbmFsKFtdIGFzIGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlKTtcbiAgQElucHV0KClcbiAgc2V0IG9yaWdpbmFsVmFsdWVzKHZhbHVlOiBibGFua05vZGVbXSB8IG5vbkJsYW5rTm9kZSkge1xuICAgIHRoaXMuX29yaWdpbmFsVmFsdWVzLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWNhbGN1bGF0ZWRWYWx1ZXMgPSBzaWduYWwoW10gYXMgYmxhbmtOb2RlW10gfCBub25CbGFua05vZGUpO1xuICBASW5wdXQoKVxuICBzZXQgcmVjYWxjdWxhdGVkVmFsdWVzKHZhbHVlOiBibGFua05vZGVbXSB8IG5vbkJsYW5rTm9kZSkge1xuICAgIHRoaXMuX3JlY2FsY3VsYXRlZFZhbHVlcy5zZXQodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdGVybXMgPSBzaWduYWwoW10gYXMgSVRlcm1KU09OTERbXSk7XG4gIEBJbnB1dCgpXG4gIHNldCB0ZXJtcyh2YWx1ZTogSVRlcm1KU09OTERbXSkge1xuICAgIHRoaXMuX3Rlcm1zLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9maWx0ZXJUZXJtVHlwZXMgPSBzaWduYWwoW10gYXMgVGVybVRlcm1UeXBlW10pO1xuICBASW5wdXQoKVxuICBzZXQgZmlsdGVyVGVybVR5cGVzKHZhbHVlOiBUZXJtVGVybVR5cGVbXSkge1xuICAgIHRoaXMuX2ZpbHRlclRlcm1UeXBlcy5zZXQodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZmlsdGVyVGVybVR5cGVzTGFiZWwgPSBzaWduYWwoJycpO1xuICBASW5wdXQoKVxuICBzZXQgZmlsdGVyVGVybVR5cGVzTGFiZWwodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2ZpbHRlclRlcm1UeXBlc0xhYmVsLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9sb2dzS2V5ID0gc2lnbmFsKCcnKTtcbiAgQElucHV0KClcbiAgc2V0IGxvZ3NLZXkodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ3NLZXkuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfbm9EYXRhTWVzc2FnZSA9IHNpZ25hbCgnJyk7XG4gIEBJbnB1dCgpXG4gIHNldCBub0RhdGFNZXNzYWdlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9ub0RhdGFNZXNzYWdlLnNldCh2YWx1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYmFzZVVybCA9IGJhc2VVcmwoKTtcbiAgcHJvdGVjdGVkIGlzRXh0ZXJuYWwgPSBpc0V4dGVybmFsKCk7XG4gIHByb3RlY3RlZCBDeWNsZUZ1bmN0aW9uYWxVbml0ID0gQ3ljbGVGdW5jdGlvbmFsVW5pdDtcbiAgcHJvdGVjdGVkIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHJvdGVjdGVkIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHJvdGVjdGVkIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwcm90ZWN0ZWQgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHJvdGVjdGVkIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwcm90ZWN0ZWQgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHJvdGVjdGVkIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHJvdGVjdGVkIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwcm90ZWN0ZWQgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHByb3RlY3RlZCByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHByb3RlY3RlZCBpc1N5c3RlbUJvdW5kYXJ5ID0gaXNTeXN0ZW1Cb3VuZGFyeTtcbiAgcHJvdGVjdGVkIHBhcnNlTG9nQ29tcGxldGVuZXNzID0gcGFyc2VMb2dDb21wbGV0ZW5lc3M7XG4gIHByb3RlY3RlZCBsb2FkaW5nID0gc2lnbmFsKHRydWUpO1xuICBwcm90ZWN0ZWQgc2hvd0xlZ2VuZCA9IHRydWU7XG5cbiAgcHJvdGVjdGVkIG9ubHlSZXF1aXJlZCA9IHNpZ25hbCh0cnVlKTtcblxuICBwcm90ZWN0ZWQgZmlsdGVyZWRUeXBlID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gdGhpcy5fZmlsdGVyVGVybVR5cGVzTGFiZWwoKSB8fCB0aGlzLl9maWx0ZXJUZXJtVHlwZXMoKT8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpXG4gICk7XG4gIHByb3RlY3RlZCBmdW5jdGlvbmFsVW5pdCA9IGNvbXB1dGVkKCgpID0+ICh0aGlzLl9ub2RlKCkgYXMgSUN5Y2xlSlNPTkxEKT8uZnVuY3Rpb25hbFVuaXQpO1xuXG4gIHByb3RlY3RlZCBsb2dzVXJsID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5ub2RlU2VydmljZS5ub2RlTG9nc1VybCh0aGlzLl9ub2RlKCkpKTtcbiAgcHJvdGVjdGVkIG5vZGVUeXBlID0gY29tcHV0ZWQoKCkgPT4gbm9kZVR5cGUodGhpcy5fbm9kZSgpKSk7XG4gIHByaXZhdGUgbm9kZUlkID0gY29tcHV0ZWQoKCkgPT4gbm9kZUlkKHRoaXMuX25vZGUoKSkpO1xuICBwcml2YXRlIGNvbmZpZyA9IHNpZ25hbCh1bmRlZmluZWQgYXMgSU9yY2hlc3RyYXRvckNvbmZpZyk7XG5cbiAgcHJpdmF0ZSBhbGxMb2dzID0gc2lnbmFsKCcnKTtcbiAgcHJpdmF0ZSBncm91cGVkTG9ncyA9IGNvbXB1dGVkKCgpID0+ICh0aGlzLmFsbExvZ3MoKSA/IGdyb3VwTG9nc0J5TW9kZWwodGhpcy5hbGxMb2dzKCkpIDoge30pKTtcbiAgcHJpdmF0ZSBsb2dzID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMuX2xvZ3NLZXkoKSA/IHRoaXMuZ3JvdXBlZExvZ3MoKT8uW3RoaXMuX2xvZ3NLZXkoKV0gOiB0aGlzLmdyb3VwZWRMb2dzKCkpIHx8IHt9KTtcblxuICBwcml2YXRlIGFsbEJsYW5rTm9kZXMgPSBzaWduYWwoW10gYXMgKElCbGFua05vZGVMb2cgfCBJTm9uQmxhbmtOb2RlTG9nKVtdKTtcbiAgcHJvdGVjdGVkIGJsYW5rTm9kZXMgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuYWxsQmxhbmtOb2RlcygpLmZpbHRlcihcbiAgICAgIGxvZyA9PiAhKCd0ZXJtJyBpbiBsb2cpIHx8IGZpbHRlckJsYW5rTm9kZShsb2csIHRoaXMudGVybSgpLCB0aGlzLl9maWx0ZXJUZXJtVHlwZXMoKSwgdGhpcy5vbmx5UmVxdWlyZWQoKSlcbiAgICApXG4gICk7XG5cbiAgcHJvdGVjdGVkIGlzQmxhbmtOb2RlcyA9IGNvbXB1dGVkKFxuICAgICgpID0+IEFycmF5LmlzQXJyYXkodGhpcy5fb3JpZ2luYWxWYWx1ZXMoKSkgfHwgQXJyYXkuaXNBcnJheSh0aGlzLl9yZWNhbGN1bGF0ZWRWYWx1ZXMoKSlcbiAgKTtcbiAgcHJvdGVjdGVkIG1ldGhvZE1vZGVsc0NvdW50ID0gY29tcHV0ZWQoKCkgPT5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMoKT8ubGVuZ3RoICYmICd0ZXJtJyBpbiB0aGlzLmFsbEJsYW5rTm9kZXMoKVswXVxuICAgICAgPyBtb2RlbENvdW50KHRoaXMuYWxsQmxhbmtOb2RlcygpIGFzIElCbGFua05vZGVMb2dbXSlcbiAgICAgIDogMVxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZXh0cmFUZXJtc0lkcyQgPSBmb3JrSm9pbih7XG4gICAgY29uZmlnOiB0b09ic2VydmFibGUodGhpcy5jb25maWcpLFxuICAgIG5vZGVLZXk6IHRvT2JzZXJ2YWJsZSh0aGlzLl9ub2RlS2V5IGFzIFNpZ25hbDxibGFua05vZGVzS2V5PiksXG4gICAgbG9nczogdG9PYnNlcnZhYmxlKHRoaXMubG9ncylcbiAgfSkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgcHJpdmF0ZSBleHRyYVRlcm1zQnlJZHMgPSBzaWduYWwoW10gYXMgSVRlcm1KU09OTERbXSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXh0cmFUZXJtVHlwZXMkID0gZm9ya0pvaW4oe1xuICAgIG5vZGVLZXk6IHRvT2JzZXJ2YWJsZSh0aGlzLl9ub2RlS2V5KSxcbiAgICB0ZXJtVHlwZXM6IHRvT2JzZXJ2YWJsZSh0aGlzLl9maWx0ZXJUZXJtVHlwZXMpXG4gIH0pLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gIHByaXZhdGUgZXh0cmFUZXJtc0J5VGVybVR5cGVzID0gc2lnbmFsKFtdIGFzIElUZXJtSlNPTkxEW10pO1xuICBwcml2YXRlIGV4dHJhVGVybXMgPSBjb21wdXRlZCgoKSA9PiBbLi4udGhpcy5leHRyYVRlcm1zQnlJZHMoKSwgLi4udGhpcy5leHRyYVRlcm1zQnlUZXJtVHlwZXMoKV0pO1xuICBwcml2YXRlIGFsbFRlcm1zID0gY29tcHV0ZWQoKCkgPT5cbiAgICBjb21wdXRlVGVybXMoXG4gICAgICB0aGlzLl9vcmlnaW5hbFZhbHVlcygpIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5fcmVjYWxjdWxhdGVkVmFsdWVzKCkgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLl90ZXJtcygpLFxuICAgICAgdGhpcy5fZmlsdGVyVGVybVR5cGVzKCksXG4gICAgICB0aGlzLmV4dHJhVGVybXMoKVxuICAgIClcbiAgKTtcblxuICBwcml2YXRlIG1ldGhvZHNCeUlkID0gdG9TaWduYWwoXG4gICAgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksIG1hdGNoVGVybVR5cGUoVGVybVRlcm1UeXBlLm1vZGVsKV1cbiAgICAgIH1cbiAgICB9KS5waXBlKFxuICAgICAgbWVyZ2VBbGwoKSxcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICBkaXN0aW5jdCh2ID0+IHZbJ0BpZCddKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30gYXMgSVRlcm1zQnlJZE1hcHBpbmcpXG4gICAgKVxuICApO1xuXG4gIHByaXZhdGUgdGVybXNCeUlkID0gc2lnbmFsKHt9IGFzIElUZXJtc0J5SWRNYXBwaW5nKTtcblxuICAvLyBmcm9tIGBtb2RlbC1saW5rcy5qc29uYCBmaWxlXG4gIHByaXZhdGUgZW5naW5lTW9kZWxzID0gdG9TaWduYWwodGhpcy5lbmdpbmVTZXJ2aWNlLmFsbE1vZGVscyQoKSk7XG5cbiAgcHJvdGVjdGVkIGVuZ2luZU1vZGVsVmVyc2lvbiA9IHRvU2lnbmFsKHRoaXMuZW5naW5lU2VydmljZS5sYXRlc3RWZXJzaW9uJCk7XG4gIHByb3RlY3RlZCBjdXJyZW50TW9kZWxWZXJzaW9uID0gY29tcHV0ZWQoKCkgPT4gbm9kZVZlcnNpb24odGhpcy5fbm9kZSgpKSk7XG4gIHByb3RlY3RlZCBzaG93T3V0ZGF0ZWRMb2dzID0gc2lnbmFsKGZhbHNlKTtcblxuICAvLyBmaWx0ZXIgbGlzdCBvZiByZXN1bHRzIGJ5IGEgc2luZ2xlIFRlcm1cbiAgcHJvdGVjdGVkIHRlcm0gPSBzaWduYWwoJycpO1xuICBwcm90ZWN0ZWQgZW5hYmxlRmlsdGVyQnlUZXJtID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5hbGxUZXJtcygpPy5sZW5ndGggPiAwKTtcbiAgcHJvdGVjdGVkIHN1Z2dlc3RUZXJtID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pID0+XG4gICAgdGV4dCQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBtYXAodiA9PiB0aGlzLnN1Z2dlc3RCeVRlcm0odikpXG4gICAgKTtcblxuICBwcm90ZWN0ZWQgdHlwZWFoZWFkRm9jdXMgPSB0eXBlYWhlYWRGb2N1cztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBIZU5vZGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2VhcmNoU2VydmljZTogSGVTZWFyY2hTZXJ2aWNlLFxuICAgIHByaXZhdGUgZW5naW5lU2VydmljZTogSGVFbmdpbmVTZXJ2aWNlXG4gICkge1xuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhpcy5leHRyYVRlcm1UeXBlcyRcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIG1hcCgoeyBub2RlS2V5LCB0ZXJtVHlwZXMgfSkgPT4gWy4uLihtYXRjaFRlcm1UeXBlRnJvbUtleVtub2RlS2V5XSB8fCBbXSksIC4uLih0ZXJtVHlwZXMgfHwgW10pXSksXG4gICAgICAgICAgICBtZXJnZU1hcCh2YWx1ZXMgPT5cbiAgICAgICAgICAgICAgdmFsdWVzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgICAgICAgICAgICAgICBib29sOiB7XG4gICAgICAgICAgICAgICAgICAgICAgbXVzdDogW21hdGNoVHlwZShOb2RlVHlwZS5UZXJtKV0sXG4gICAgICAgICAgICAgICAgICAgICAgc2hvdWxkOiB2YWx1ZXMubWFwKG1hdGNoVGVybVR5cGUpLFxuICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgOiBvZihbXSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSh2YWx1ZXMgPT4gdGhpcy5leHRyYVRlcm1zQnlUZXJtVHlwZXMuc2V0KHZhbHVlcykpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG5cbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuZXh0cmFUZXJtc0lkcyRcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIG1hcCgoeyBjb25maWcsIG5vZGVLZXksIGxvZ3MgfSkgPT4gZXh0cmFUZXJtSWRzRnJvbUNvbmZpZyhjb25maWcsIG5vZGVLZXksIGxvZ3MpKSxcbiAgICAgICAgICAgIG1lcmdlTWFwKHZhbHVlcyA9PlxuICAgICAgICAgICAgICB2YWx1ZXMubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICAgICAgICAgICAgICAgIGJvb2w6IHtcbiAgICAgICAgICAgICAgICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pXSxcbiAgICAgICAgICAgICAgICAgICAgICBzaG91bGQ6IHZhbHVlcy5tYXAobWF0Y2hJZCksXG4gICAgICAgICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICA6IG9mKFtdKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuc3Vic2NyaWJlKHZhbHVlcyA9PiB0aGlzLmV4dHJhVGVybXNCeUlkcy5zZXQodmFsdWVzKSk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XG4gICAgKTtcblxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgb2YodGhpcy5pc0JsYW5rTm9kZXMoKSlcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICBtZXJnZU1hcChpc0JsYW5rTm9kZXMgPT4gKGlzQmxhbmtOb2RlcyA/IHRoaXMubG9hZEJsYW5rTm9kZXMoKSA6IHRoaXMubG9hZE5vbkJsYW5rTm9kZXMoKSkpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUodmFsdWVzID0+IHRoaXMuYWxsQmxhbmtOb2Rlcy5zZXQodmFsdWVzKSk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZExvZ3Mobm9kZTogSUpTT05Ob2RlKSB7XG4gICAgdGhpcy5sb2FkaW5nLnNldCh0cnVlKTtcblxuICAgIGZvcmtKb2luKHtcbiAgICAgIGxvZ3M6IHRoaXMubm9kZVNlcnZpY2UuZ2V0TG9nKHsgLi4ubm9kZSwgZGF0YVN0YXRlOiBEYXRhU3RhdGUucmVjYWxjdWxhdGVkIH0pLFxuICAgICAgY29uZmlnOiB0aGlzLmVuZ2luZVNlcnZpY2Uub2NoZXN0cmF0b3JDb25maWckKG5vZGVUeXBlKG5vZGUpLCBub2RlSWQobm9kZSkpXG4gICAgfSlcbiAgICAgIC5waXBlKHRhcCgoKSA9PiB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKSkpXG4gICAgICAuc3Vic2NyaWJlKCh7IGxvZ3MsIGNvbmZpZyB9KSA9PiB7XG4gICAgICAgIHRoaXMuY29uZmlnLnNldChjb25maWcpO1xuICAgICAgICB0aGlzLmFsbExvZ3Muc2V0KGxvZ3MpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRCbGFua05vZGVzKCkge1xuICAgIHJldHVybiBvZih0aGlzLmFsbFRlcm1zKCkpLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgocHJldiwgY3VycikgPT4gbGlzdFRlcm1JZChwcmV2KSAhPT0gbGlzdFRlcm1JZChjdXJyKSksXG4gICAgICBtZXJnZUFsbCgpLFxuICAgICAgbWFwKFxuICAgICAgICBncm91cExvZ3NCeVRlcm0oXG4gICAgICAgICAgdGhpcy5ub2RlVHlwZSgpLFxuICAgICAgICAgIHRoaXMubG9ncygpLFxuICAgICAgICAgIHRoaXMuZW5naW5lTW9kZWxzKCksXG4gICAgICAgICAgdGhpcy5jb25maWcoKSxcbiAgICAgICAgICB0aGlzLl9vcmlnaW5hbFZhbHVlcygpIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgICAgIHRoaXMuX3JlY2FsY3VsYXRlZFZhbHVlcygpIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgICAgIHRoaXMuX25vZGVLZXkoKSBhcyBibGFua05vZGVzS2V5XG4gICAgICAgIClcbiAgICAgICksXG4gICAgICBmaWx0ZXIoc2hvdWxkU2hvd0JsYW5rTm9kZSksXG4gICAgICB0b0FycmF5KCksXG4gICAgICBtZXJnZU1hcCh2YWx1ZXMgPT4gdGhpcy5mZXRjaFRlcm1JZHModmFsdWVzKS5waXBlKG1hcCgoKSA9PiB2YWx1ZXMpKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkTm9uQmxhbmtOb2RlcygpIHtcbiAgICBjb25zdCBtYXBGdW5jID0gZ3JvdXBkTG9nc0J5S2V5KFxuICAgICAgdGhpcy5ub2RlVHlwZSgpLFxuICAgICAgdGhpcy5fbm9kZUtleSgpIGFzIG5vbkJsYW5rTm9kZXNLZXksXG4gICAgICB0aGlzLmxvZ3MoKSxcbiAgICAgIHRoaXMuZW5naW5lTW9kZWxzKCksXG4gICAgICB0aGlzLl9vcmlnaW5hbFZhbHVlcygpIGFzIG5vbkJsYW5rTm9kZSxcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlZFZhbHVlcygpIGFzIG5vbkJsYW5rTm9kZVxuICAgICk7XG4gICAgY29uc3Qga2V5cyA9IGNvbXB1dGVLZXlzKHRoaXMuX29yaWdpbmFsVmFsdWVzKCkgYXMgbm9uQmxhbmtOb2RlLCB0aGlzLl9yZWNhbGN1bGF0ZWRWYWx1ZXMoKSBhcyBub25CbGFua05vZGUpO1xuICAgIHJldHVybiBmcm9tKGtleXMpLnBpcGUobWFwKG1hcEZ1bmMpLCB0b0FycmF5KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaFRlcm1JZHModmFsdWVzOiBJQmxhbmtOb2RlTG9nW10pIHtcbiAgICByZXR1cm4gb2YodmFsdWVzKS5waXBlKFxuICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICBtYXAodiA9PiB2LmlkKSxcbiAgICAgIGRpc3RpbmN0KCksXG4gICAgICBmaWx0ZXIodiA9PiAhIXYpLFxuICAgICAgdG9BcnJheSgpLFxuICAgICAgbWVyZ2VNYXAoKGlkczogc3RyaW5nW10pID0+XG4gICAgICAgIHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgICAgIGJvb2w6IHtcbiAgICAgICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSldLFxuICAgICAgICAgICAgc2hvdWxkOiBpZHMubWFwKGlkID0+IG1hdGNoRXhhY3RRdWVyeSgnQGlkJywgaWQpKSxcbiAgICAgICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30gYXMgSVRlcm1zQnlJZE1hcHBpbmcpLFxuICAgICAgdGFwKHZhbHVlcyA9PiB0aGlzLnRlcm1zQnlJZC5zZXQodmFsdWVzKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWdnZXN0QnlUZXJtKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFsbFRlcm1zKClcbiAgICAgIC5tYXAoKHsgbmFtZSB9KSA9PiBuYW1lKVxuICAgICAgLmZpbHRlcih2ID0+IHRlcm1TZWFyY2godikuaW5jbHVkZXModGVybVNlYXJjaCh0ZXJtKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgdGhpcy5sb2FkaW5nLnNldCh0cnVlKTtcbiAgICByZXR1cm4gdGhpcy5zZWFyY2hTZXJ2aWNlXG4gICAgICAuc2VhcmNoJDxJVGVybUpTT05MRCwgTm9kZVR5cGUuVGVybT4oe1xuICAgICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgICAgbGltaXQ6IDEwMDAwLFxuICAgICAgICBxdWVyeVxuICAgICAgfSlcblxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgoKSA9PiB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKSksXG4gICAgICAgIG1hcCgoeyByZXN1bHRzIH0pID0+IHJlc3VsdHMpXG4gICAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRyYWNrQnlCbGFua05vZGUoX2luZGV4OiBudW1iZXIsIG5vZGU6IGFueSkge1xuICAgIHJldHVybiBub2RlLnRlcm1JZCB8fCBub2RlLmtleTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkKCk/LlttZXRob2RJZF0/Lm5hbWUgfHwgbWV0aG9kSWRMYWJlbChtZXRob2RJZCwgbW9kZWwpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhc01ldGhvZFRpZXIodmFsdWVzOiBibGFua05vZGVbXSwgbWV0aG9kVGllcjogRW1pc3Npb25NZXRob2RUaWVyKSB7XG4gICAgcmV0dXJuIHZhbHVlcy5zb21lKHYgPT4gJ21ldGhvZFRpZXInIGluIHYgJiYgdi5tZXRob2RUaWVyID09PSBtZXRob2RUaWVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0ZXJtQnlJZChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMudGVybXNCeUlkKCk/LltpZF0gfHxcbiAgICAgICh7XG4gICAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAgICdAaWQnOiBpZCxcbiAgICAgICAgbmFtZTogdGVybVR5cGVMYWJlbChpZClcbiAgICAgIH0gYXMgSVRlcm1KU09OTEQpXG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdlxuICAqbmdJZj1cInNob3dPdXRkYXRlZExvZ3MoKSB8fCBlbmdpbmVNb2RlbFZlcnNpb24oKSA9PT0gY3VycmVudE1vZGVsVmVyc2lvbigpOyBlbHNlIHNob3dPdXRkYXRlZExvZ3NXYXJuaW5nXCJcbiAgY2xhc3M9XCJpcy1weC0zIGlzLXBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IGlzLW1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsICYmIGxvZ3NVcmwoKVwiPlxuICAgIDxhIGNsYXNzPVwiaXMtc2l6ZS03XCIgW2hyZWZdPVwibG9nc1VybCgpXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgbWF4SGVpZ2h0PVwiMzIwXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIGlzLW5hcnJvdyBpcy1zdHJpcGVkXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiICpuZ0lmPVwiZW5hYmxlRmlsdGVyQnlUZXJtKClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wgaXMtZXhwYW5kZWQgaGFzLWljb25zLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0ZXJtKClcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRlcm1cIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgZW50cnkgYnkgbmFtZVwiXG4gICAgICAgICAgICAgICAgICBbbmdiVHlwZWFoZWFkXT1cInN1Z2dlc3RUZXJtXCJcbiAgICAgICAgICAgICAgICAgIFtmb2N1c0ZpcnN0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cInR5cGVhaGVhZEZvY3VzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwidGVybS5zZXQoJGV2ZW50Lml0ZW0pXCIgLz5cbiAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImljb24gaXMtc21hbGwgaXMtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiF0ZXJtKClcIiAoY2xpY2spPVwidGVybS5zZXQoJycpXCI+XG4gICAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwidGltZXNcIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPlVuaXRzPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+KHBlciZuYnNwOzwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIFtuZ1N3aXRjaF09XCJmdW5jdGlvbmFsVW5pdCgpXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkN5Y2xlRnVuY3Rpb25hbFVuaXRbJzEgaGEnXVwiPmhlY3RhcmU8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0PmtnIHByb2R1Y3Q8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPik8L3NwYW4+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8dGg+T3JpZ2luYWw8L3RoPlxuICAgICAgICAgIDx0aD5SZWNhbGN1bGF0ZWQ8L3RoPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50KCkgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPih7eyBpICsgMSB9fSk8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyICpuZ0lmPVwibG9hZGluZygpXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZygpICYmIGJsYW5rTm9kZXMoKS5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8c3Bhbj57eyBfbm9EYXRhTWVzc2FnZSgpIHx8ICdObyBkYXRhJyB9fTwvc3Bhbj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBibGFua05vZGUgb2YgYmxhbmtOb2RlcygpOyB0cmFja0J5OiB0cmFja0J5QmxhbmtOb2RlXCI+XG4gICAgICAgICAgPHRyIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLmNhbk9wZW5cIiBbY2xhc3MuaXMtb3Blbl09XCJibGFua05vZGUuaXNPcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0/Lm5hbWUgfHwgYmxhbmtOb2RlLmtleVwiPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0yIG9wZW4tbm9kZVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImJsYW5rTm9kZS5pc09wZW4gPSAhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cImJsYW5rTm9kZS5pc09wZW5cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGhlLW5vZGUtbGluayBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1wcmUtd3JhcFwiICpuZ0lmPVwiYmxhbmtOb2RlLnRlcm1cIiBbbm9kZV09XCJibGFua05vZGUudGVybVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzaG93QmxhbmtOb2RlS2V5PlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUua2V5OyBlbHNlIHNob3dCbGFua05vZGVLZXlcIj5cbiAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJfbm9kZUtleSgpID09PSAnY29tcGxldGVuZXNzJ1wiXG4gICAgICAgICAgICAgICAgICBbaHJlZl09XCJiYXNlVXJsICsgJy9zY2hlbWEvQ29tcGxldGVuZXNzIycgKyBibGFua05vZGUua2V5XCJcbiAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLmtleSB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXMoKVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcFwiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRPcmlnaW5hbFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYmxhbmtOb2RlLmlzT3JpZ2luYWwgfHwgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXMoKVwiIGNsYXNzPVwiaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdERlbHRhVmFsdWU+XG4gICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsLmxlbmd0aCAmJiBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm9WYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgIFtvcmlnaW5hbFZhbHVlXT1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlXCI+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHREZWx0YVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICBlbHNlIG5vVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDogeyBkYXRhOiBibGFua05vZGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1zdWItcm93XT1cImJsYW5rTm9kZS5jYW5PcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zIHByLTEgZmllbGQtbm9kZVwiPkZpZWxkOjwvc3Bhbj5cblxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLXByZS13cmFwXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS50eXBlXCJcbiAgICAgICAgICAgICAgICBbaHJlZl09XCJiYXNlVXJsICsgJy9zY2hlbWEvJyArIGJsYW5rTm9kZS50eXBlICsgJyMnICsgc3ViVmFsdWUua2V5XCJcbiAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wXCIgKm5nSWY9XCIhYmxhbmtOb2RlLnR5cGVcIj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5pc1JlY2FsY3VsYXRlZCB8fCBzdWJWYWx1ZS5rZXkgPT09ICdpbXBhY3RBc3Nlc3NtZW50JzsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzKClcIj4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHsgZGF0YTogc3ViVmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUuc3ViVmFsdWVzXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgW2NsYXNzLmlzLXN1Yi1yb3ddPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcGwtM1wiPnt7IHN1YlZhbHVlLmtleSB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN1YlZhbHVlLmlkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMVwiPjo8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nU3dpdGNoQ2FzZT1cIidiYWNrZ3JvdW5kRGF0YSdcIj57eyBzdWJWYWx1ZS5pZCB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rXG4gICAgICAgICAgICAgICAgICAgICpuZ1N3aXRjaERlZmF1bHRcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ibG9jayBwbC00XCJcbiAgICAgICAgICAgICAgICAgICAgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySHRtbF09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZCkubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwXCIgKm5nSWY9XCJzdWJWYWx1ZS5zaG93VW5pdHNcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2RlcygpXCI+LTwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7IGRhdGE6IHN1YlZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9oZS1kYXRhLXRhYmxlPlxuXG4gIDxkaXYgY2xhc3M9XCJpcy1zaXplLTcgaXMtaXRhbGljXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbnMgaXMtdmFyaWFibGUgaXMtMSBteS0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGlzLW5hcnJvd1wiPlxuICAgICAgICA8cD5cbiAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBwci0yXCIgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7IGxvZ0NvbG9yW3N0YXR1cy52YWx1ZV0gfX1cIj5cbiAgICAgICAgICAgICAgPGZhLWljb24gW2ljb25dPVwibG9nSWNvbltzdGF0dXMudmFsdWVdXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj57eyBzdGF0dXMudmFsdWUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGhhcy10ZXh0LXJpZ2h0XCIgKm5nSWY9XCJmaWx0ZXJlZFR5cGUoKVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICBjbGFzcz1cInNlbGVjdG9yXCJcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cIm9ubHlSZXF1aXJlZC5zZXQoJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtKClcIiAvPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlxuICAgICAgICAgICAgU2hvdyBvbmx5IHt7IGZpbHRlcmVkVHlwZSgpIHwgcGx1cmFsaXplIH19IGluY2x1ZGVkIGluIHRoZSBkZWZhdWx0IEhlc3RpYSBzeXN0ZW0gYm91bmRhcnlcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNzaG93T3V0ZGF0ZWRMb2dzV2FybmluZz5cbiAgPGRpdiBjbGFzcz1cImlzLTMgaGFzLXRleHQtY2VudGVyZWRcIj5cbiAgICA8cCBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxmYS1pY29uIGNsYXNzPVwiaXMtcHItMlwiIGljb249XCJleGNsYW1hdGlvbi10cmlhbmdsZVwiPjwvZmEtaWNvbj5cbiAgICAgIDxzcGFuPlRoZXNlIGxvZ3MgbWlnaHQgYmUgaW5jb3JyZWN0IGFzIHRoZSBjYWxjdWxhdGlvbnMgYXJlIG91dGRhdGVkLjwvc3Bhbj5cbiAgICA8L3A+XG4gICAgPHAgY2xhc3M9XCJpcy11bmRlcmxpbmVkIGlzLXNpemUtN1wiPjxhIChjbGljayk9XCJzaG93T3V0ZGF0ZWRMb2dzLnNldCh0cnVlKVwiPlZpZXcgbG9ncyBhbnl3YXkuPC9hPjwvcD5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPG5nLXRlbXBsYXRlICNub3RJblN5c3RlbUJvdW5kYXJ5PlxuICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIm1ldGhvZE1vZGVsc0NvdW50KClcIj5cbiAgICAgIDxzcGFuPk5vdCBpbiBIZXN0aWEgc3lzdGVtIGJvdW5kYXJ5PC9zcGFuPlxuICAgIDwvdGQ+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzU3lzdGVtQm91bmRhcnkoZGF0YSk7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgIDx0ZCBjbGFzcz1cImJsYW5rLW5vZGUtaW5kZXgte3sgaSB9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50KCkgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldE1vZGVsc0F0KGRhdGEsIGkpOyBsZXQgbW9kZWxzOyBlbHNlOiBub1ZhbHVlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbW9kZWxTZXJpZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWw6IG1vZGVscywgZGF0YSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJtb2RlbHMgfCBpc0FycmF5OyBlbHNlIG1vZGVsU2VyaWVcIj5cbiAgICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWwsIGRhdGEgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3RkPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjYmxhbmtOb2RlTW9kZWwgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHNwYW5cbiAgICBjbGFzcz1cImlzLW5vd3JhcFwiXG4gICAgW2NsYXNzLnRyaWdnZXItcG9wb3Zlcl09XCJtb2RlbC5zaG93TG9nc1wiXG4gICAgW25nYlBvcG92ZXJdPVwibG9nRGV0YWlsc1wiXG4gICAgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIlxuICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIlxuICAgICNwPVwibmdiUG9wb3ZlclwiXG4gICAgcGxhY2VtZW50PVwibGVmdFwiXG4gICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiBtb2RlbC5zaG93TG9ncyA/IHAub3Blbih7IGxvZ3M6IG1vZGVsLmxvZ3MgfSkgOiBudWxsXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7IG1ldGhvZE5hbWUobW9kZWwpIH19PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncz8ubWV0aG9kVGllciB8fCBtb2RlbC5tb2RlbD8ubWV0aG9kVGllclwiPlxuICAgICAgW3t7IG1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXIgfX1dXG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW5cbiAgICAgIGNsYXNzPVwicGwtMSBoYXMtdGV4dC17eyBsb2dDb2xvclttb2RlbC5zdGF0dXNdIH19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCJcbiAgICAgIFthdXRvQ2xvc2VdPVwiJ291dHNpZGUnXCJcbiAgICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgICB0cmlnZ2Vycz1cIm1hbnVhbFwiXG4gICAgICAjcDE9XCJuZ2JQb3BvdmVyXCJcbiAgICAgIHBsYWNlbWVudD1cImxlZnRcIlxuICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBwMS5pc09wZW4oKSA/IHAxLmNsb3NlKCkgOiBwMS5vcGVuKHsgbW9kZWwsIGRhdGEgfSlcIj5cbiAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bbW9kZWwuc3RhdHVzXVwiPjwvZmEtaWNvbj5cbiAgICA8L3NwYW4+XG5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLm1vZGVsXCI+XG4gICAgICAoXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZG9jc0xpbms7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBtb2RlbC5tb2RlbCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICApXG4gICAgPC9zcGFuPlxuICA8L3NwYW4+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vVmFsdWU+LTwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbm90UmVjYWxjdWxhdGVkPm5vdCByZWNhbGN1bGF0ZWQ8L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0RldGFpbHMgbGV0LWxvZ3M9XCJsb2dzXCI+XG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXJcIiAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGhcIj5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LnJlcXVpcmVtZW50c1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiByZXF1aXJlbWVudEtleXMobG9ncy5yZXF1aXJlbWVudHMpXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZTsgY29udGV4dDogeyBrZXksIHZhbHVlOiBsb2dzLnJlcXVpcmVtZW50c1trZXldIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LmxvZ3NcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgbG9ncy5sb2dzIHwga2V5c1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6IGtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPGRpdiBjbGFzcz1cIml0LW10LTJcIiAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGggaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5GaWxlbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Db2x1bW4gVGl0bGU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+Um93ICh0ZXJtLmlkKTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGxvZ3MubWlzc2luZ0xvb2t1cHNcIj5cbiAgICAgICAgICAgICAgPHRkPnt7IGRhdGEuZmlsZW5hbWUgfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS5jb2x1bW4gfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS50ZXJtSWQgfX08L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lVmFsdWUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFZhbHVlPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiPnt7IHZhbHVlIH19PC9zcGFuPlxuICA8L25nLXRlbXBsYXRlPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVxdWlyZW1lbnRMaW5rZWROb2RlKGtleSwgdmFsdWUpOyBsZXQgbGlua2VkTm9kZTsgZWxzZTogZGVmYXVsdFZhbHVlXCI+XG4gICAgPGhlLW5vZGUtbGlua1xuICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCJcbiAgICAgIGxpbmtDbGFzcz1cImlzLWRhcmtcIlxuICAgICAgW25vZGVdPVwibGlua2VkTm9kZVwiXG4gICAgICBbc2hvd0V4dGVybmFsTGlua109XCJ0cnVlXCI+PC9oZS1ub2RlLWxpbms+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8dHI+XG4gICAgPHRkIGNsYXNzPVwiaGFzLWJvcmRlci1yaWdodCBjb3B5LWxvZ1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdE1lc3NhZ2U+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+e3sga2V5IHwga2V5VG9MYWJlbCB9fTwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvcGVydHlfaWQnXCI+UHJvcGVydHkgVGVybSBAaWQ8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9kdWN0X2lkJ1wiPlByb2R1Y3QgVGVybSBAaWQ8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidpbnB1dF9pZCdcIj5JbnB1dCBUZXJtIEBpZDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbm9kZV90eXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5Ob2RlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2l0ZVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+SXMgdGhlIGN1cnJlbnQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnNpdGVUeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvZHVjdF9pZF9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BcmUgYW55IG9mIHRoZSBQcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5AaWQ8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIFByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXRfaWRfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QXJlIGFueSBvZiB0aGUgSW5wdXQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPkBpZDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIElucHV0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8IS0tIERlcHJlY2F0ZWQgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X2lkX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+QGlkPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+dGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2dlb3NwYXRpYWxfZGF0YSdcIj5cbiAgICAgICAgICAgICAgSGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5cbiAgICAgICAgICAgICAgSGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2N1cnJlbnRfc2l6ZSdcIj5DdXJyZW50IHBvbHlnb24gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ21heF9hcmVhX3NpemUnXCI+TWF4aW11bSBwb2x5Z29uIGFyZWEgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3JlZ2lvbl9mYWN0b3InXCI+RmFjdG9yIGZyb20gcmVnaW9uIGxvb2t1cDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5DeWNsZSBjb250YWluczwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+cGVzdGljaWRlQUk8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPklucHV0czwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2FsbF9wZXN0aWNpZGVBSV9oYXZlX2xvb2t1cF92YWx1ZSdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QWxsPC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5wZXN0aWNpZGVBSTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+SW5wdXRzIGhhdmUgYSBsb29rdXAgdmFsdWU8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19jcm9wX3Jlc2lkdWVfYnVybnQnXCI+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+aXMgcHJlc2VudCBhcyBQcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidsaXF1aWRfc2x1cnJ5X3NsdWRnZV9QJ1wiPkxpcXVpZCwgU2x1cnJ5LCBhbmQgU2x1ZGdlIFA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGFyc2VMb2dDb21wbGV0ZW5lc3Moa2V5KTsgbGV0IGNvbXBsZXRlbmVzczsgZWxzZTogZGVmYXVsdE1lc3NhZ2VcIj5cbiAgICAgICAgICA8c3Bhbj5EYXRhIGNvbXBsZXRlbmVzcyBmb3I8L3NwYW4+XG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+e3sgY29tcGxldGVuZXNzLmtleSB9fTwvY29kZT5cbiAgICAgICAgICA8c3Bhbj5tdXN0IGJlPC9zcGFuPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IGNvbXBsZXRlbmVzcy52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3NwYW4+XG4gICAgICA8aGUtY2xpcGJvYXJkXG4gICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiXG4gICAgICAgIGNsaXBib2FyZENsYXNzPVwiaXMtc2l6ZS03IGlzLXAtMVwiXG4gICAgICAgIFtpY29uXT1cIlsnZmFyJywgJ2Nsb25lJ11cIlxuICAgICAgICBbdmFsdWVdPVwia2V5XCJcbiAgICAgICAgW2hpZGVUZXh0XT1cInRydWVcIj48L2hlLWNsaXBib2FyZD5cbiAgICA8L3RkPlxuICAgIDx0ZD5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlVmFsdWU+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lVmFsdWU7IGNvbnRleHQ6IHsga2V5LCB2YWx1ZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cImxvZ1ZhbHVlQXJyYXkodmFsdWUpOyBsZXQgdmFsdWVBcnJheTsgZWxzZTogc2luZ2xlVmFsdWVcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1ib3JkZXJlZCBpcy1zdHJpcGVkXCI+XG4gICAgICAgICAgPHRoZWFkICpuZ0lmPVwidmFsdWVBcnJheVswXSB8IGlzT2JqZWN0XCI+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVswXSB8IGtleXNcIj57eyB2LmtleSB9fTwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzaW5nbGVBcnJheVZhbHVlPlxuICAgICAgICAgICAgICAgIDx0ZD57eyB2IH19PC90ZD5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInYgfCBpc09iamVjdDsgZWxzZSBzaW5nbGVBcnJheVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCB2diBvZiB2IHwga2V5c1wiPnt7IHZ2LnZhbHVlIH19PC90ZD5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L3RkPlxuICA8L3RyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dTdGF0dXNEZXRhaWxzIGxldC1tb2RlbD1cIm1vZGVsXCIgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIDxuZy1jb250YWluZXIgKmJpbmRPbmNlPVwibW9kZWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiPlxuICAgICAgPHNwYW4+U3RhdHVzOjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLnN0YXR1cyB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5zdGF0dXMgPT09IExvZ1N0YXR1cy5ub3RSZXF1aXJlZCAmJiBtb2RlbC5sb2dzPy5pc19ub3RfcmVsZXZhbnQgPT09ICdUcnVlJ1wiPlxuICAgICAgPHVsIGNsYXNzPVwiaXMtcGwtMyBpcy1saXN0LXN0eWxlLWRpc2NcIj5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5zaXRlVHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgVGhlXG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+c2l0ZS5zaXRlVHlwZTwvY29kZT5cbiAgICAgICAgICBpcyBub3QgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucHJvZHVjdF9pZF9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgTm9uZSBvZiB0aGVcbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5Qcm9kdWN0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0uQGlkPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LnByb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIE5vbmUgb2YgdGhlXG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+UHJvZHVjdDwvY29kZT5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj50ZXJtLnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LmlucHV0X2lkX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBOb25lIG9mIHRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPklucHV0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0uQGlkPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LmlucHV0X3Rlcm1UeXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBOb25lIG9mIHRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPklucHV0PC9jb2RlPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXItMVwiPnRlcm0udGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgaXMgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLWNvbnRhaW5lclxuICAgICAgKm5nSWY9XCJtb2RlbC5sb2dzICYmIG1vZGVsLnN0YXR1cyAhPT0gTG9nU3RhdHVzLm5vdFJlcXVpcmVkICYmIG1vZGVsLnN0YXR1cyAhPT0gTG9nU3RhdHVzLnNraXBIaWVyYXJjaHlcIj5cbiAgICAgIDx1bCBjbGFzcz1cImlzLXBsLTMgaXMtbGlzdC1zdHlsZS1kaXNjXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjc2hvd1J1bk9yY2hlc3RyYXRvcj5cbiAgICAgICAgICA8bGkgY2xhc3M9XCJpcy1ydW4tb3JjaGVzdHJhdG9yXCI+XG4gICAgICAgICAgICA8cCAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1blwiPkFsbCB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbWV0IHRvIHJ1biB0aGUgbW9kZWwuPC9wPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5cbiAgICAgICAgICAgICAgPHA+U29tZSBvZiB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbm90IG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgICAgICAgPHA+WW91IGNhbiBjbGljayBvbiB0aGUgbW9kZWwgbmFtZSBvbiB0aGUgbGVmdCB0byB2aWV3IHRoZSBkZWJ1Z2dpbmcgbG9ncy48L3A+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5sb2dzPy5sb2dzPy5lcnJvclwiPlxuICAgICAgICAgICAgICA8cD5UaGUgbW9kZWwgZmFpbGVkIHRvIHJ1biBmb3IgdGhlIGZvbGxvd2luZyByZWFzb246PC9wPlxuICAgICAgICAgICAgICA8cD5cbiAgICAgICAgICAgICAgICA8Y29kZT57eyBtb2RlbC5sb2dzLmxvZ3MuZXJyb3IgfX08L2NvZGU+XG4gICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPGxpXG4gICAgICAgICAgY2xhc3M9XCJpcy1uby1ydW4tb3JjaGVzdHJhdG9yXCJcbiAgICAgICAgICAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1bk9yY2hlc3RyYXRvciA9PT0gZmFsc2U7IGVsc2Ugc2hvd1J1bk9yY2hlc3RyYXRvclwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwubG9ncy5ydW5SZXF1aXJlZFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ydW4tbm9kZS10eXBlLW5vdC1hbGxvd2VkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/Lm5vZGVfdHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgICAgIFRoaXMgbW9kZWwgc2hvdWxkIG5vdCBydW4gZm9yIHt7IG5vZGVUeXBlKCkgfCBwbHVyYWxpemU6IDAgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcnVuTm9Db25maWc+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICAgICAgVGhlIHt7IGRhdGEudHlwZSB8fCAnYmxhbmsgbm9kZScgfX0gd2l0aCBUZXJtXG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IGRhdGEudGVybUlkIH19PC9jb2RlPlxuICAgICAgICAgICAgICBpcyBhbHJlYWR5IHByZXNlbnQgb3IgYWxyZWFkeSBhZGRlZCBieSBhbm90aGVyIG1vZGVsLlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuY29uZmlnOyBlbHNlIHJ1bk5vQ29uZmlnXCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImlzLXJ1bi1zdHJhdGVneS17eyBtb2RlbC5jb25maWcucnVuU3RyYXRlZ3kgfX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWx3YXlzJ1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfa2V5X2lmX21pc3NpbmcnXCI+V2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfYmxhbmtfbm9kZV9pZl9taXNzaW5nJ1wiPldlIG9ubHkgZ2FwLWZpbGwgdGhpcyBCbGFuayBOb2RlIGlmIG5vdCBwcmVzZW50Ljwvc3Bhbj5cbiAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgPHAgY2xhc3M9XCJpcy1tdC0xXCI+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ydW4td2l0aC1tZWFzdXJlZFwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgIG1vZGVsLmNvbmZpZy5ydW5BcmdzPy5ydW5Ob25NZWFzdXJlZCAmJiBoYXNNZXRob2RUaWVyKGRhdGEub3JpZ2luYWwsIEVtaXNzaW9uTWV0aG9kVGllci5tZWFzdXJlZClcbiAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICBUaGVcbiAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj57eyBtb2RlbC5jb25maWcudmFsdWUgfX08L2NvZGU+XG4gICAgICAgICAgICAgICAgd2FzIHJlcG9ydGVkIGFzIG1lYXN1cmVkLlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncz8ucmVwbGFjZUxvd2VyVGllciAhPT0gdW5kZWZpbmVkXCI+XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICBUaGUgcmVjYWxjdWxhdGVkXG4gICAgICAgICAgICA8Yj5tZXRob2RUaWVyPC9iPlxuICAgICAgICAgICAgd2FzXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMSBpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCIhbW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTEgaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+aGlnaGVyIHRoYW4gb3IgZXF1YWwgdG88L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+XG4gICAgICAgICAgICB0aGUgb3JpZ2luYWxcbiAgICAgICAgICAgIDxiPm1ldGhvZFRpZXI8L2I+XG4gICAgICAgICAgICAuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuXG4gICAgICAgIDxsaSBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VMb3dlclRpZXJcIiAqbmdJZj1cIm1vZGVsLmxvZ3MucmVwbGFjZUxvd2VyVGllclwiPlxuICAgICAgICAgIDxzcGFuPlRoZSByZWNhbGN1bGF0ZWQ8L3NwYW4+XG4gICAgICAgICAgPGIgY2xhc3M9XCJpcy1wbC0xXCI+e3sgbW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnIH19PC9iPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPndhczwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc/Lm1lcmdlQXJnc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXVuZGVybGluZWRcIiAqbmdJZj1cIiFtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5sZXNzIHRoYW48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+bW9yZSB0aGFuIG9yIGVxdWFsIHRvPC9zcGFuPlxuICAgICAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDAgfX0lPC9iPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwiIW1vZGVsLmxvZ3MucmVwbGFjZVRocmVzaG9sZFwiPm5vdCBzdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+c3VmZmljaWVudGx5PC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbDwvc3Bhbj5cbiAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWc/Lm1lcmdlQXJncz8ucmVwbGFjZVRocmVzaG9sZD8uWzBdIHx8ICd2YWx1ZScgfX0uPC9iPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2RvY3NMaW5rIGxldC1tb2RlbD5cbiAgPGEgW2hyZWZdPVwibW9kZWwuYXBpRG9jc1BhdGggfHwgbW9kZWwuZG9jUGF0aCB8fCBtb2RlbC5wYXRoXCIgdGFyZ2V0PVwiX2JsYW5rXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxzcGFuPkRvY3M8L3NwYW4+XG4gICAgPGZhLWljb24gY2xhc3M9XCJtbC0xXCIgaWNvbj1cImV4dGVybmFsLWxpbmstYWx0XCIgc2l6ZT1cInNtXCI+PC9mYS1pY29uPlxuICA8L2E+XG48L25nLXRlbXBsYXRlPlxuIl19
|