@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
121 lines • 20.9 kB
JavaScript
import { Component, forwardRef, Input } from '@angular/core';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { StaticAssetsModalService } from '../static-assets-modal.service';
import { StaticAssetsService } from '@c8y/ngx-components/static-assets/data';
import { CoreModule } from '@c8y/ngx-components';
import * as i0 from "@angular/core";
import * as i1 from "../static-assets-modal.service";
import * as i2 from "@c8y/ngx-components/static-assets/data";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@angular/common";
import * as i5 from "ngx-bootstrap/tooltip";
export class StaticAssetsFilePickerComponent {
constructor(staticAssetsModal, staticAssets) {
this.staticAssetsModal = staticAssetsModal;
this.staticAssets = staticAssets;
this.isCSSURL = false;
this.staticAssetType = 'branding';
this.supportedFileExtensions = [];
this.layout = 'grid';
this.size = 48;
this.loading = false;
this.currentFile = undefined;
}
writeValue(value) {
if (/^url\('.*'\)$/.test(value)) {
value = value.replace(/^url\('/, '').replace(/'\)$/, '');
}
if (/^url\(.*\)$/.test(value)) {
value = value.replace(/^url\(/, '').replace(/\)$/, '');
}
this.currentValue = value;
this.loadFileDetails(value);
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
async loadFileDetails(currentUrl) {
if (!currentUrl) {
this.currentFile = undefined;
return;
}
this.loading = true;
try {
const fileList = await this.staticAssets.listFilesCached(this.staticAssetType);
const foundFile = fileList.find(file => currentUrl.includes(file.path));
this.currentFile = foundFile;
if (!foundFile) {
const filePresent = await this.ensureFileExists(currentUrl);
if (filePresent) {
this.currentFile = {
path: currentUrl,
fileName: currentUrl.split('/').pop(),
originalFileName: currentUrl.split('/').pop()
};
}
}
}
catch (e) { }
this.loading = false;
}
clear() {
this.onChange('');
this.currentFile = undefined;
this.currentValue = '';
this.onTouched();
}
async openFilePicker() {
try {
const res = await this.staticAssetsModal.pickStaticAsset({
layout: this.layout,
assetType: this.staticAssetType,
supportedFileExtensions: this.supportedFileExtensions
});
const value = this.isCSSURL ? `url(${res.path})` : res.path;
this.onChange(value);
this.currentFile = res;
this.currentValue = value;
this.onTouched();
}
catch (e) {
// modal closed
}
}
async ensureFileExists(url) {
const response = await fetch(url);
return response.status === 200;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StaticAssetsFilePickerComponent, deps: [{ token: i1.StaticAssetsModalService }, { token: i2.StaticAssetsService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StaticAssetsFilePickerComponent, isStandalone: true, selector: "c8y-static-assets-file-picker", inputs: { isCSSURL: "isCSSURL", staticAssetType: "staticAssetType", supportedFileExtensions: "supportedFileExtensions", layout: "layout", size: "size" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StaticAssetsFilePickerComponent),
multi: true
}
], ngImport: i0, template: "\n<div class=\"d-flex a-i-center gap-8\">\n <div *ngIf=\"!currentValue else fileSelected\" class=\"d-contents\">\n <i c8yIcon=\"no-image\" class=\"icon-48 text-muted\"></i>\n <p class=\"m-r-auto text-muted\"><em translate>No file selected.</em></p>\n </div>\n\n <ng-template #fileSelected>\n <c8y-loading *ngIf=\"loading\"></c8y-loading>\n <div *ngIf=\"!loading && !currentFile\">\n <p translate>Unable to locate file: \"{{ currentValue }}\"</p>\n </div>\n\n <div *ngIf=\"!loading && currentFile\" style=\"min-height: 48px\" class=\"d-flex a-i-center\">\n <img *ngIf=\"currentFile\" [src]=\"currentFile.path\" class=\"img-responsive\" [ngStyle]=\"{'width.px': size}\" alt=\"{{currentFile?.fileName }}\">\n </div>\n <span class=\"text-truncate\" title=\"{{ currentFile?.fileName || currentValue }}\">{{ currentFile?.fileName || currentValue }}</span>\n <button class=\" m-l-auto btn btn-dot btn-dot--danger\"\n type=\"button\" (click)=\"clear()\"\n [delay]=\"500\"\n [attr.aria-label]=\"'Remove' | translate\"\n placement=\"top\"\n tooltip=\"{{'Remove' | translate}}\">\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </ng-template>\n\n <button (click)=\"openFilePicker()\" class=\"btn btn-default btn-sm\">\n <span *ngIf=\"!currentFile\">\n {{'Select' | translate}}\n </span>\n <span *ngIf=\"currentFile\">\n {{'Replace' | translate}}\n </span>\n </button>\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StaticAssetsFilePickerComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-static-assets-file-picker', standalone: true, imports: [CoreModule, TooltipModule], providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StaticAssetsFilePickerComponent),
multi: true
}
], template: "\n<div class=\"d-flex a-i-center gap-8\">\n <div *ngIf=\"!currentValue else fileSelected\" class=\"d-contents\">\n <i c8yIcon=\"no-image\" class=\"icon-48 text-muted\"></i>\n <p class=\"m-r-auto text-muted\"><em translate>No file selected.</em></p>\n </div>\n\n <ng-template #fileSelected>\n <c8y-loading *ngIf=\"loading\"></c8y-loading>\n <div *ngIf=\"!loading && !currentFile\">\n <p translate>Unable to locate file: \"{{ currentValue }}\"</p>\n </div>\n\n <div *ngIf=\"!loading && currentFile\" style=\"min-height: 48px\" class=\"d-flex a-i-center\">\n <img *ngIf=\"currentFile\" [src]=\"currentFile.path\" class=\"img-responsive\" [ngStyle]=\"{'width.px': size}\" alt=\"{{currentFile?.fileName }}\">\n </div>\n <span class=\"text-truncate\" title=\"{{ currentFile?.fileName || currentValue }}\">{{ currentFile?.fileName || currentValue }}</span>\n <button class=\" m-l-auto btn btn-dot btn-dot--danger\"\n type=\"button\" (click)=\"clear()\"\n [delay]=\"500\"\n [attr.aria-label]=\"'Remove' | translate\"\n placement=\"top\"\n tooltip=\"{{'Remove' | translate}}\">\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </ng-template>\n\n <button (click)=\"openFilePicker()\" class=\"btn btn-default btn-sm\">\n <span *ngIf=\"!currentFile\">\n {{'Select' | translate}}\n </span>\n <span *ngIf=\"currentFile\">\n {{'Replace' | translate}}\n </span>\n </button>\n</div>\n\n" }]
}], ctorParameters: () => [{ type: i1.StaticAssetsModalService }, { type: i2.StaticAssetsService }], propDecorators: { isCSSURL: [{
type: Input
}], staticAssetType: [{
type: Input
}], supportedFileExtensions: [{
type: Input
}], layout: [{
type: Input
}], size: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zdGF0aWMtYXNzZXRzL3N0YXRpYy1hc3NldHMtZmlsZS1waWNrZXIvc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zdGF0aWMtYXNzZXRzL3N0YXRpYy1hc3NldHMtZmlsZS1waWNrZXIvc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RELE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMxRSxPQUFPLEVBQWUsbUJBQW1CLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMxRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7Ozs7QUFnQmpELE1BQU0sT0FBTywrQkFBK0I7SUFhMUMsWUFDVSxpQkFBMkMsRUFDM0MsWUFBaUM7UUFEakMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUEwQjtRQUMzQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFkbEMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixvQkFBZSxHQUE0QyxVQUFVLENBQUM7UUFDdEUsNEJBQXVCLEdBQTBELEVBQUUsQ0FBQztRQUNwRixXQUFNLEdBQXlDLE1BQU0sQ0FBQztRQUN0RCxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ25CLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsZ0JBQVcsR0FBNEIsU0FBUyxDQUFDO0lBUzlDLENB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O3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGZvcndhcmRSZWYsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC90b29sdGlwJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN0YXRpY0Fzc2V0c01vZGFsU2VydmljZSB9IGZyb20gJy4uL3N0YXRpYy1hc3NldHMtbW9kYWwuc2VydmljZSc7XG5pbXBvcnQgeyBTdGF0aWNBc3NldCwgU3RhdGljQXNzZXRzU2VydmljZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvc3RhdGljLWFzc2V0cy9kYXRhJztcbmltcG9ydCB7IENvcmVNb2R1bGUgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB0eXBlIHsgU3RhdGljQXNzZXRzTW9kYWxDb21wb25lbnQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL3N0YXRpYy1hc3NldHMvbW9kYWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdGF0aWMtYXNzZXRzLWZpbGUtcGlja2VyLmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvcmVNb2R1bGUsIFRvb2x0aXBNb2R1bGVdLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFN0YXRpY0Fzc2V0c0ZpbGVQaWNrZXJDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgU3RhdGljQXNzZXRzRmlsZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQElucHV0KCkgaXNDU1NVUkwgPSBmYWxzZTtcbiAgQElucHV0KCkgc3RhdGljQXNzZXRUeXBlOiBTdGF0aWNBc3NldHNNb2RhbENvbXBvbmVudFsnYXNzZXRUeXBlJ10gPSAnYnJhbmRpbmcnO1xuICBASW5wdXQoKSBzdXBwb3J0ZWRGaWxlRXh0ZW5zaW9uczogU3RhdGljQXNzZXRzTW9kYWxDb21wb25lbnRbJ3N1cHBvcnRlZEZpbGVFeHRlbnNpb25zJ10gPSBbXTtcbiAgQElucHV0KCkgbGF5b3V0OiBTdGF0aWNBc3NldHNNb2RhbENvbXBvbmVudFsnbGF5b3V0J10gPSAnZ3JpZCc7XG4gIEBJbnB1dCgpIHNpemUgPSA0ODtcbiAgbG9hZGluZyA9IGZhbHNlO1xuICBjdXJyZW50RmlsZTogU3RhdGljQXNzZXQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIGN1cnJlbnRWYWx1ZTogc3RyaW5nO1xuXG4gIHByaXZhdGUgb25DaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICBwcml2YXRlIG9uVG91Y2hlZDogKCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHN0YXRpY0Fzc2V0c01vZGFsOiBTdGF0aWNBc3NldHNNb2RhbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzdGF0aWNBc3NldHM6IFN0YXRpY0Fzc2V0c1NlcnZpY2VcbiAgKSB7fVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICgvXnVybFxcKCcuKidcXCkkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9edXJsXFwoJy8sICcnKS5yZXBsYWNlKC8nXFwpJC8sICcnKTtcbiAgICB9XG4gICAgaWYgKC9edXJsXFwoLipcXCkkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9edXJsXFwoLywgJycpLnJlcGxhY2UoL1xcKSQvLCAnJyk7XG4gICAgfVxuICAgIHRoaXMuY3VycmVudFZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sb2FkRmlsZURldGFpbHModmFsdWUpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBhc3luYyBsb2FkRmlsZURldGFpbHMoY3VycmVudFVybDogc3RyaW5nKSB7XG4gICAgaWYgKCFjdXJyZW50VXJsKSB7XG4gICAgICB0aGlzLmN1cnJlbnRGaWxlID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlTGlzdCA9IGF3YWl0IHRoaXMuc3RhdGljQXNzZXRzLmxpc3RGaWxlc0NhY2hlZCh0aGlzLnN0YXRpY0Fzc2V0VHlwZSk7XG4gICAgICBjb25zdCBmb3VuZEZpbGUgPSBmaWxlTGlzdC5maW5kKGZpbGUgPT4gY3VycmVudFVybC5pbmNsdWRlcyhmaWxlLnBhdGgpKTtcbiAgICAgIHRoaXMuY3VycmVudEZpbGUgPSBmb3VuZEZpbGU7XG4gICAgICBpZiAoIWZvdW5kRmlsZSkge1xuICAgICAgICBjb25zdCBmaWxlUHJlc2VudCA9IGF3YWl0IHRoaXMuZW5zdXJlRmlsZUV4aXN0cyhjdXJyZW50VXJsKTtcbiAgICAgICAgaWYgKGZpbGVQcmVzZW50KSB7XG4gICAgICAgICAgdGhpcy5jdXJyZW50RmlsZSA9IHtcbiAgICAgICAgICAgIHBhdGg6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgICBmaWxlTmFtZTogY3VycmVudFVybC5zcGxpdCgnLycpLnBvcCgpLFxuICAgICAgICAgICAgb3JpZ2luYWxGaWxlTmFtZTogY3VycmVudFVybC5zcGxpdCgnLycpLnBvcCgpXG4gICAgICAgICAgfSBhcyBhbnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICB0aGlzLm9uQ2hhbmdlKCcnKTtcbiAgICB0aGlzLmN1cnJlbnRGaWxlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY3VycmVudFZhbHVlID0gJyc7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgfVxuXG4gIGFzeW5jIG9wZW5GaWxlUGlja2VyKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnN0YXRpY0Fzc2V0c01vZGFsLnBpY2tTdGF0aWNBc3NldCh7XG4gICAgICAgIGxheW91dDogdGhpcy5sYXlvdXQsXG4gICAgICAgIGFzc2V0VHlwZTogdGhpcy5zdGF0aWNBc3NldFR5cGUsXG4gICAgICAgIHN1cHBvcnRlZEZpbGVFeHRlbnNpb25zOiB0aGlzLnN1cHBvcnRlZEZpbGVFeHRlbnNpb25zXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5pc0NTU1VSTCA/IGB1cmwoJHtyZXMucGF0aH0pYCA6IHJlcy5wYXRoO1xuICAgICAgdGhpcy5vbkNoYW5nZSh2YWx1ZSk7XG4gICAgICB0aGlzLmN1cnJlbnRGaWxlID0gcmVzO1xuICAgICAgdGhpcy5jdXJyZW50VmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gbW9kYWwgY2xvc2VkXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVGaWxlRXhpc3RzKHVybDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgIHJldHVybiByZXNwb25zZS5zdGF0dXMgPT09IDIwMDtcbiAgfVxufVxuIiwiXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXIgZ2FwLThcIj5cbiAgPGRpdiAqbmdJZj1cIiFjdXJyZW50VmFsdWUgZWxzZSBmaWxlU2VsZWN0ZWRcIiBjbGFzcz1cImQtY29udGVudHNcIj5cbiAgICA8aSBjOHlJY29uPVwibm8taW1hZ2VcIiBjbGFzcz1cImljb24tNDggdGV4dC1tdXRlZFwiPjwvaT5cbiAgICA8cCBjbGFzcz1cIm0tci1hdXRvIHRleHQtbXV0ZWRcIj48ZW0gdHJhbnNsYXRlPk5vIGZpbGUgc2VsZWN0ZWQuPC9lbT48L3A+XG4gIDwvZGl2PlxuXG4gIDxuZy10ZW1wbGF0ZSAjZmlsZVNlbGVjdGVkPlxuICAgIDxjOHktbG9hZGluZyAqbmdJZj1cImxvYWRpbmdcIj48L2M4eS1sb2FkaW5nPlxuICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiAhY3VycmVudEZpbGVcIj5cbiAgICAgIDxwIHRyYW5zbGF0ZT5VbmFibGUgdG8gbG9jYXRlIGZpbGU6IFwie3sgY3VycmVudFZhbHVlIH19XCI8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICpuZ0lmPVwiIWxvYWRpbmcgJiYgY3VycmVudEZpbGVcIiBzdHlsZT1cIm1pbi1oZWlnaHQ6IDQ4cHhcIiBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyXCI+XG4gICAgICA8aW1nICpuZ0lmPVwiY3VycmVudEZpbGVcIiBbc3JjXT1cImN1cnJlbnRGaWxlLnBhdGhcIiBjbGFzcz1cImltZy1yZXNwb25zaXZlXCIgW25nU3R5bGVdPVwieyd3aWR0aC5weCc6IHNpemV9XCIgYWx0PVwie3tjdXJyZW50RmlsZT8uZmlsZU5hbWUgfX1cIj5cbiAgICA8L2Rpdj5cbiAgICA8c3BhbiBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIiB0aXRsZT1cInt7IGN1cnJlbnRGaWxlPy5maWxlTmFtZSB8fCBjdXJyZW50VmFsdWUgfX1cIj57eyBjdXJyZW50RmlsZT8uZmlsZU5hbWUgfHwgY3VycmVudFZhbHVlIH19PC9zcGFuPlxuICAgIDxidXR0b24gY2xhc3M9XCIgbS1sLWF1dG8gYnRuIGJ0bi1kb3QgYnRuLWRvdC0tZGFuZ2VyXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xlYXIoKVwiXG4gICAgICBbZGVsYXldPVwiNTAwXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1JlbW92ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgcGxhY2VtZW50PVwidG9wXCJcbiAgICAgIHRvb2x0aXA9XCJ7eydSZW1vdmUnIHwgdHJhbnNsYXRlfX1cIj5cbiAgICAgIDxpIGM4eUljb249XCJtaW51cy1jaXJjbGVcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPGJ1dHRvbiAoY2xpY2spPVwib3BlbkZpbGVQaWNrZXIoKVwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbVwiPlxuICAgIDxzcGFuICpuZ0lmPVwiIWN1cnJlbnRGaWxlXCI+XG4gICAgICB7eydTZWxlY3QnIHwgdHJhbnNsYXRlfX1cbiAgICA8L3NwYW4+XG4gICAgPHNwYW4gKm5nSWY9XCJjdXJyZW50RmlsZVwiPlxuICAgICAge3snUmVwbGFjZScgfCB0cmFuc2xhdGV9fVxuICAgIDwvc3Bhbj5cbiAgPC9idXR0b24+XG48L2Rpdj5cblxuIl19