UNPKG

@dotcms/angular

Version:

Official Angular Components library to render a dotCMS page.

126 lines 19.2 kB
import { AsyncPipe, NgComponentOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, HostBinding, Input, computed, inject, signal } from '@angular/core'; import { NoComponent } from '../../components/no-component/no-component.component'; import { PageContextService } from '../../services/dotcms-context/page-context.service'; import { getContainersData } from '../../utils'; import { ContentletComponent } from '../contentlet/contentlet.component'; import * as i0 from "@angular/core"; /** * This component is responsible to display a container with contentlets. * * @export * @class ContainerComponent * @implements {OnChanges} */ export class ContainerComponent { constructor() { this.pageContextService = inject(PageContextService); this.NoComponent = NoComponent; this.$isInsideEditor = signal(false); this.$contentlets = signal([]); this.$dotContainer = signal(null); this.$dotContainerAsString = computed(() => JSON.stringify(this.$dotContainer())); /** * The accept types for the container component. * * @type {(string | null)} * @memberof ContainerComponent */ this.acceptTypes = null; /** * The identifier for the container component. * * @type {(string | null)} * @memberof ContainerComponent */ this.identifier = null; /** * The max contentlets for the container component. * * @type {(number | null)} * @memberof ContainerComponent */ this.maxContentlets = null; /** * The uuid for the container component. * * @type {(string | null)} * @memberof ContainerComponent */ this.uuid = null; /** * The class for the container component. * * @type {(string | null)} * @memberof ContainerComponent */ this.class = null; /** * The dot object for the container component. * * @type {(string | null)} * @memberof ContainerComponent */ this.dotObject = null; /** * The data-testid attribute used for identifying the component during testing. * * @memberof ContainerComponent */ this.testId = 'dot-container'; } ngOnChanges() { const { pageAsset, components, isInsideEditor } = this.pageContextService.context; const { acceptTypes, maxContentlets, variantId, path, contentlets } = getContainersData(pageAsset.containers, this.container); const { identifier, uuid } = this.container; this.componentsMap = components; this.$isInsideEditor.set(isInsideEditor); this.$contentlets.set(contentlets); this.$dotContainer.set({ identifier: path ?? identifier, acceptTypes, maxContentlets, variantId, uuid }); if (this.$isInsideEditor()) { this.acceptTypes = acceptTypes; this.identifier = identifier; this.maxContentlets = maxContentlets; this.uuid = uuid; this.class = this.$contentlets().length ? null : 'empty-container'; this.dotObject = 'container'; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContainerComponent, isStandalone: true, selector: "dotcms-container", inputs: { container: "container" }, host: { properties: { "attr.data-dot-accept-types": "this.acceptTypes", "attr.data-dot-identifier": "this.identifier", "attr.data-max-contentlets": "this.maxContentlets", "attr.data-dot-uuid": "this.uuid", "class": "this.class", "attr.data-dot-object": "this.dotObject", "attr.data-testid": "this.testId" } }, usesOnChanges: true, ngImport: i0, template: "@if ($isInsideEditor()) {\n @if ($contentlets().length) {\n @for (contentlet of $contentlets(); track $index) {\n <dotcms-contentlet-wrapper\n [contentlet]=\"contentlet\"\n [container]=\"$dotContainerAsString()\">\n <ng-container\n *ngComponentOutlet=\"\n (componentsMap[contentlet.contentType] || componentsMap['CustomNoComponent']\n | async) || NoComponent;\n inputs: { contentlet }\n \" />\n </dotcms-contentlet-wrapper>\n }\n } @else {\n This container is empty.\n }\n} @else {\n @for (contentlet of $contentlets(); track $index) {\n <ng-container\n *ngComponentOutlet=\"\n componentsMap[contentlet.contentType] | async;\n inputs: { contentlet }\n \" />\n }\n}\n", styles: [":host.empty-container{width:100%;background-color:#ecf0fd;display:flex;justify-content:center;align-items:center;color:#030e32;height:10rem}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: ContentletComponent, selector: "dotcms-contentlet-wrapper", inputs: ["contentlet", "container"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, decorators: [{ type: Component, args: [{ selector: 'dotcms-container', standalone: true, imports: [AsyncPipe, NgComponentOutlet, NoComponent, ContentletComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if ($isInsideEditor()) {\n @if ($contentlets().length) {\n @for (contentlet of $contentlets(); track $index) {\n <dotcms-contentlet-wrapper\n [contentlet]=\"contentlet\"\n [container]=\"$dotContainerAsString()\">\n <ng-container\n *ngComponentOutlet=\"\n (componentsMap[contentlet.contentType] || componentsMap['CustomNoComponent']\n | async) || NoComponent;\n inputs: { contentlet }\n \" />\n </dotcms-contentlet-wrapper>\n }\n } @else {\n This container is empty.\n }\n} @else {\n @for (contentlet of $contentlets(); track $index) {\n <ng-container\n *ngComponentOutlet=\"\n componentsMap[contentlet.contentType] | async;\n inputs: { contentlet }\n \" />\n }\n}\n", styles: [":host.empty-container{width:100%;background-color:#ecf0fd;display:flex;justify-content:center;align-items:center;color:#030e32;height:10rem}\n"] }] }], propDecorators: { container: [{ type: Input, args: [{ required: true }] }], acceptTypes: [{ type: HostBinding, args: ['attr.data-dot-accept-types'] }], identifier: [{ type: HostBinding, args: ['attr.data-dot-identifier'] }], maxContentlets: [{ type: HostBinding, args: ['attr.data-max-contentlets'] }], uuid: [{ type: HostBinding, args: ['attr.data-dot-uuid'] }], class: [{ type: HostBinding, args: ['class'] }], dotObject: [{ type: HostBinding, args: ['attr.data-dot-object'] }], testId: [{ type: HostBinding, args: ['attr.data-testid'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc2RrL2FuZ3VsYXIvc3JjL2xpYi9sYXlvdXQvY29udGFpbmVyL2NvbnRhaW5lci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3Nkay9hbmd1bGFyL3NyYy9saWIvbGF5b3V0L2NvbnRhaW5lci9jb250YWluZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9ELE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFdBQVcsRUFDWCxLQUFLLEVBRUwsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNEQUFzRCxDQUFDO0FBR25GLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9EQUFvRCxDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7QUFVekU7Ozs7OztHQU1HO0FBU0gsTUFBTSxPQUFPLGtCQUFrQjtJQVIvQjtRQWlCcUIsdUJBQWtCLEdBQXVCLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xFLGdCQUFXLEdBQUcsV0FBVyxDQUFDO1FBQzFCLG9CQUFlLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBR2xELGlCQUFZLEdBQUcsTUFBTSxDQUFxQixFQUFFLENBQUMsQ0FBQztRQUM5QyxrQkFBYSxHQUFHLE1BQU0sQ0FBc0IsSUFBSSxDQUFDLENBQUM7UUFDbEQsMEJBQXFCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxD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Y1BpcGUsIE5nQ29tcG9uZW50T3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBjb21wdXRlZCxcbiAgICBpbmplY3QsXG4gICAgc2lnbmFsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBOb0NvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvbm8tY29tcG9uZW50L25vLWNvbXBvbmVudC5jb21wb25lbnQnO1xuaW1wb3J0IHsgRHluYW1pY0NvbXBvbmVudEVudGl0eSB9IGZyb20gJy4uLy4uL21vZGVscyc7XG5pbXBvcnQgeyBEb3RDTVNDb250YWluZXIsIERvdENNU0NvbnRlbnRsZXQgfSBmcm9tICcuLi8uLi9tb2RlbHMvZG90Y21zLm1vZGVsJztcbmltcG9ydCB7IFBhZ2VDb250ZXh0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RvdGNtcy1jb250ZXh0L3BhZ2UtY29udGV4dC5zZXJ2aWNlJztcbmltcG9ydCB7IGdldENvbnRhaW5lcnNEYXRhIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQ29udGVudGxldENvbXBvbmVudCB9IGZyb20gJy4uL2NvbnRlbnRsZXQvY29udGVudGxldC5jb21wb25lbnQnO1xuXG5pbnRlcmZhY2UgRG90Q29udGFpbmVyIHtcbiAgICBhY2NlcHRUeXBlczogc3RyaW5nO1xuICAgIGlkZW50aWZpZXI6IHN0cmluZztcbiAgICBtYXhDb250ZW50bGV0czogbnVtYmVyO1xuICAgIHV1aWQ6IHN0cmluZztcbiAgICB2YXJpYW50SWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhpcyBjb21wb25lbnQgaXMgcmVzcG9uc2libGUgdG8gZGlzcGxheSBhIGNvbnRhaW5lciB3aXRoIGNvbnRlbnRsZXRzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBDb250YWluZXJDb21wb25lbnRcbiAqIEBpbXBsZW1lbnRzIHtPbkNoYW5nZXN9XG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZG90Y21zLWNvbnRhaW5lcicsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbQXN5bmNQaXBlLCBOZ0NvbXBvbmVudE91dGxldCwgTm9Db21wb25lbnQsIENvbnRlbnRsZXRDb21wb25lbnRdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jb250YWluZXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsOiAnLi9jb250YWluZXIuY29tcG9uZW50LmNzcycsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgQ29udGFpbmVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgICAvKipcbiAgICAgKiBUaGUgY29udGFpbmVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb250ZW50bGV0cy5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtEb3RDTVNDb250YWluZXJ9XG4gICAgICogQG1lbWJlcm9mIENvbnRhaW5lckNvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGNvbnRhaW5lciE6IERvdENNU0NvbnRhaW5lcjtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGFnZUNvbnRleHRTZXJ2aWNlOiBQYWdlQ29udGV4dFNlcnZpY2UgPSBpbmplY3QoUGFnZUNvbnRleHRTZXJ2aWNlKTtcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgTm9Db21wb25lbnQgPSBOb0NvbXBvbmVudDtcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGlzSW5zaWRlRWRpdG9yID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICAgIHByb3RlY3RlZCBjb21wb25lbnRzTWFwITogUmVjb3JkPHN0cmluZywgRHluYW1pY0NvbXBvbmVudEVudGl0eT47XG4gICAgcHJvdGVjdGVkICRjb250ZW50bGV0cyA9IHNpZ25hbDxEb3RDTVNDb250ZW50bGV0W10+KFtdKTtcbiAgICBwcm90ZWN0ZWQgJGRvdENvbnRhaW5lciA9IHNpZ25hbDxEb3RDb250YWluZXIgfCBudWxsPihudWxsKTtcbiAgICBwcm90ZWN0ZWQgJGRvdENvbnRhaW5lckFzU3RyaW5nID0gY29tcHV0ZWQoKCkgPT4gSlNPTi5zdHJpbmdpZnkodGhpcy4kZG90Q29udGFpbmVyKCkpKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBhY2NlcHQgdHlwZXMgZm9yIHRoZSBjb250YWluZXIgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogQHR5cGUgeyhzdHJpbmcgfCBudWxsKX1cbiAgICAgKiBAbWVtYmVyb2YgQ29udGFpbmVyQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtZG90LWFjY2VwdC10eXBlcycpIGFjY2VwdFR5cGVzOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpZGVudGlmaWVyIGZvciB0aGUgY29udGFpbmVyIGNvbXBvbmVudC5cbiAgICAgKlxuICAgICAqIEB0eXBlIHsoc3RyaW5nIHwgbnVsbCl9XG4gICAgICogQG1lbWJlcm9mIENvbnRhaW5lckNvbXBvbmVudFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLWRvdC1pZGVudGlmaWVyJykgaWRlbnRpZmllcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgLyoqXG4gICAgICogVGhlIG1heCBjb250ZW50bGV0cyBmb3IgdGhlIGNvbnRhaW5lciBjb21wb25lbnQuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7KG51bWJlciB8IG51bGwpfVxuICAgICAqIEBtZW1iZXJvZiBDb250YWluZXJDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1tYXgtY29udGVudGxldHMnKSBtYXhDb250ZW50bGV0czogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgLyoqXG4gICAgICogVGhlIHV1aWQgZm9yIHRoZSBjb250YWluZXIgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogQHR5cGUgeyhzdHJpbmcgfCBudWxsKX1cbiAgICAgKiBAbWVtYmVyb2YgQ29udGFpbmVyQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtZG90LXV1aWQnKSB1dWlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgY2xhc3MgZm9yIHRoZSBjb250YWluZXIgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogQHR5cGUgeyhzdHJpbmcgfCBudWxsKX1cbiAgICAgKiBAbWVtYmVyb2YgQ29udGFpbmVyQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcycpIGNsYXNzOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgZG90IG9iamVjdCBmb3IgdGhlIGNvbnRhaW5lciBjb21wb25lbnQuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7KHN0cmluZyB8IG51bGwpfVxuICAgICAqIEBtZW1iZXJvZiBDb250YWluZXJDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1kb3Qtb2JqZWN0JykgZG90T2JqZWN0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YS10ZXN0aWQgYXR0cmlidXRlIHVzZWQgZm9yIGlkZW50aWZ5aW5nIHRoZSBjb21wb25lbnQgZHVyaW5nIHRlc3RpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgQ29udGFpbmVyQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtdGVzdGlkJykgdGVzdElkID0gJ2RvdC1jb250YWluZXInO1xuXG4gICAgbmdPbkNoYW5nZXMoKSB7XG4gICAgICAgIGNvbnN0IHsgcGFnZUFzc2V0LCBjb21wb25lbnRzLCBpc0luc2lkZUVkaXRvciB9ID0gdGhpcy5wYWdlQ29udGV4dFNlcnZpY2UuY29udGV4dDtcbiAgICAgICAgY29uc3QgeyBhY2NlcHRUeXBlcywgbWF4Q29udGVudGxldHMsIHZhcmlhbnRJZCwgcGF0aCwgY29udGVudGxldHMgfSA9IGdldENvbnRhaW5lcnNEYXRhKFxuICAgICAgICAgICAgcGFnZUFzc2V0LmNvbnRhaW5lcnMsXG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclxuICAgICAgICApO1xuICAgICAgICBjb25zdCB7IGlkZW50aWZpZXIsIHV1aWQgfSA9IHRoaXMuY29udGFpbmVyO1xuXG4gICAgICAgIHRoaXMuY29tcG9uZW50c01hcCA9IGNvbXBvbmVudHM7XG5cbiAgICAgICAgdGhpcy4kaXNJbnNpZGVFZGl0b3Iuc2V0KGlzSW5zaWRlRWRpdG9yKTtcbiAgICAgICAgdGhpcy4kY29udGVudGxldHMuc2V0KGNvbnRlbnRsZXRzKTtcbiAgICAgICAgdGhpcy4kZG90Q29udGFpbmVyLnNldCh7XG4gICAgICAgICAgICBpZGVudGlmaWVyOiBwYXRoID8/IGlkZW50aWZpZXIsXG4gICAgICAgICAgICBhY2NlcHRUeXBlcyxcbiAgICAgICAgICAgIG1heENvbnRlbnRsZXRzLFxuICAgICAgICAgICAgdmFyaWFudElkLFxuICAgICAgICAgICAgdXVpZFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy4kaXNJbnNpZGVFZGl0b3IoKSkge1xuICAgICAgICAgICAgdGhpcy5hY2NlcHRUeXBlcyA9IGFjY2VwdFR5cGVzO1xuICAgICAgICAgICAgdGhpcy5pZGVudGlmaWVyID0gaWRlbnRpZmllcjtcbiAgICAgICAgICAgIHRoaXMubWF4Q29udGVudGxldHMgPSBtYXhDb250ZW50bGV0cztcbiAgICAgICAgICAgIHRoaXMudXVpZCA9IHV1aWQ7XG4gICAgICAgICAgICB0aGlzLmNsYXNzID0gdGhpcy4kY29udGVudGxldHMoKS5sZW5ndGggPyBudWxsIDogJ2VtcHR5LWNvbnRhaW5lcic7XG4gICAgICAgICAgICB0aGlzLmRvdE9iamVjdCA9ICdjb250YWluZXInO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiQGlmICgkaXNJbnNpZGVFZGl0b3IoKSkge1xuICAgIEBpZiAoJGNvbnRlbnRsZXRzKCkubGVuZ3RoKSB7XG4gICAgICAgIEBmb3IgKGNvbnRlbnRsZXQgb2YgJGNvbnRlbnRsZXRzKCk7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgPGRvdGNtcy1jb250ZW50bGV0LXdyYXBwZXJcbiAgICAgICAgICAgICAgICBbY29udGVudGxldF09XCJjb250ZW50bGV0XCJcbiAgICAgICAgICAgICAgICBbY29udGFpbmVyXT1cIiRkb3RDb250YWluZXJBc1N0cmluZygpXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdDb21wb25lbnRPdXRsZXQ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjb21wb25lbnRzTWFwW2NvbnRlbnRsZXQuY29udGVudFR5cGVdIHx8IGNvbXBvbmVudHNNYXBbJ0N1c3RvbU5vQ29tcG9uZW50J11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFzeW5jKSB8fCBOb0NvbXBvbmVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0czogeyBjb250ZW50bGV0IH1cbiAgICAgICAgICAgICAgICAgICAgXCIgLz5cbiAgICAgICAgICAgIDwvZG90Y21zLWNvbnRlbnRsZXQtd3JhcHBlcj5cbiAgICAgICAgfVxuICAgIH0gQGVsc2Uge1xuICAgICAgICBUaGlzIGNvbnRhaW5lciBpcyBlbXB0eS5cbiAgICB9XG59IEBlbHNlIHtcbiAgICBAZm9yIChjb250ZW50bGV0IG9mICRjb250ZW50bGV0cygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgKm5nQ29tcG9uZW50T3V0bGV0PVwiXG4gICAgICAgICAgICAgICAgY29tcG9uZW50c01hcFtjb250ZW50bGV0LmNvbnRlbnRUeXBlXSB8IGFzeW5jO1xuICAgICAgICAgICAgICAgIGlucHV0czogeyBjb250ZW50bGV0IH1cbiAgICAgICAgICAgIFwiIC8+XG4gICAgfVxufVxuIl19