@spartacus/storefront
Version:
Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.
110 lines • 13.9 kB
JavaScript
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "../../../cms-structure/outlet/outlet.service";
import * as i2 from "./config/table.config";
/**
* The table renderer service adds a component for each table cells (th and td)
* based on a fine grained configuration. Each table type can configure both global
* components for headers and cells as well as individual components for field
* specific cells.
*
* The components are added to the outlet slots for the corresponding cells. The table
* structure and data is added to the outlet context.
*/
export class TableRendererService {
constructor(outletService, componentFactoryResolver, config) {
this.outletService = outletService;
this.componentFactoryResolver = componentFactoryResolver;
this.config = config;
// keep a list of outletRefs to avoid recreation
this.outletRefs = new Map();
}
/**
* Adds the configured table component for the header and data.
*/
add(structure) {
var _a;
(_a = structure === null || structure === void 0 ? void 0 : structure.cells) === null || _a === void 0 ? void 0 : _a.forEach((field) => {
const thRenderer = this.getHeaderRenderer(structure, field);
if (thRenderer) {
const ref = this.getHeaderOutletRef(structure.type, field);
this.render(ref, thRenderer);
}
const tdRenderer = this.getDataRenderer(structure, field);
if (tdRenderer) {
const ref = this.getDataOutletRef(structure.type, field);
this.render(ref, tdRenderer);
}
});
}
render(outletRef, renderer) {
if (this.outletRefs.has(outletRef)) {
return;
}
this.outletRefs.set(outletRef, true);
const template = this.componentFactoryResolver.resolveComponentFactory(renderer);
this.outletService.add(outletRef, template);
}
/**
* Returns the header render component for the given field.
*/
getHeaderRenderer(structure, field) {
var _a, _b, _c, _d, _e;
return (((_c = (_b = (_a = structure.options) === null || _a === void 0 ? void 0 : _a.cells) === null || _b === void 0 ? void 0 : _b[field]) === null || _c === void 0 ? void 0 : _c.headerComponent) ||
((_d = structure.options) === null || _d === void 0 ? void 0 : _d.headerComponent) ||
((_e = this.config.tableOptions) === null || _e === void 0 ? void 0 : _e.headerComponent));
}
/**
* Returns the data render component for the given field.
*/
getDataRenderer(structure, field) {
var _a, _b, _c, _d, _e;
return (((_c = (_b = (_a = structure.options) === null || _a === void 0 ? void 0 : _a.cells) === null || _b === void 0 ? void 0 : _b[field]) === null || _c === void 0 ? void 0 : _c.dataComponent) ||
((_d = structure.options) === null || _d === void 0 ? void 0 : _d.dataComponent) ||
((_e = this.config.tableOptions) === null || _e === void 0 ? void 0 : _e.dataComponent));
}
/**
* Returns the header (th) outlet reference for the given field.
*
* The outlet reference is generated as:
* `table.[tableType].header.[field]`
*/
getHeaderOutletRef(type, field) {
return `table.${type}.header.${field}`;
}
/**
* Returns the header (th) outlet context for the given field.
*/
getHeaderOutletContext(type, options, i18nRoot, field) {
return {
_type: type,
_options: options,
_field: field,
_i18nRoot: i18nRoot,
};
}
/**
* Returns the data (td) outlet reference for the given field.
*
* The field is generated as:
* `table.[tableType].data.[tableField]`
*/
getDataOutletRef(type, field) {
return `table.${type}.data.${field}`;
}
/**
* Returns the data (td) outlet context for the given field.
*/
getDataOutletContext(type, options, i18nRoot, field, data) {
return Object.assign(Object.assign({}, data), { _type: type, _options: options, _field: field, _i18nRoot: i18nRoot });
}
}
TableRendererService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: TableRendererService, deps: [{ token: i1.OutletService }, { token: i0.ComponentFactoryResolver }, { token: i2.TableConfig }], target: i0.ɵɵFactoryTarget.Injectable });
TableRendererService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: TableRendererService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: TableRendererService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.OutletService }, { type: i0.ComponentFactoryResolver }, { type: i2.TableConfig }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtcmVuZGVyZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvc2hhcmVkL2NvbXBvbmVudHMvdGFibGUvdGFibGUtcmVuZGVyZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTRCLFVBQVUsRUFBUSxNQUFNLGVBQWUsQ0FBQzs7OztBQVUzRTs7Ozs7Ozs7R0FRRztBQUlILE1BQU0sT0FBTyxvQkFBb0I7SUFJL0IsWUFDWSxhQUE0QixFQUM1Qix3QkFBa0QsRUFDbEQsTUFBbUI7UUFGbkIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUNsRCxXQUFNLEdBQU4sTUFBTSxDQUFhO1FBTi9CLGdEQUFnRDtRQUN0QyxlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQU05QixDQUFDO0lBRUo7O09BRUc7SUFDSCxHQUFHLENBQUMsU0FBeUI7O1FBQzNCLE1BQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLEtBQUssMENBQUUsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM1RCxJQUFJLFVBQVUsRUFBRTtnQkFDZCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDM0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDOUI7WUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMxRCxJQUFJLFVBQVUsRUFBRTtnQkFDZCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDOUI7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxNQUFNLENBQUMsU0FBaUIsRUFBRSxRQUFtQjtRQUNyRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ2xDLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNyQyxNQUFNLFFBQVEsR0FDWixJQUFJLENBQUMsd0JBQXdCLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFPLFFBQVEsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNPLGlCQUFpQixDQUN6QixTQUF5QixFQUN6QixLQUFhOztRQUViLE9BQU8sQ0FDTCxDQUFBLE1BQUEsTUFBQSxNQUFBLFNBQVMsQ0FBQyxPQUFPLDBDQUFFLEtBQUssMENBQUcsS0FBSyxDQUFDLDBDQUFFLGVBQWU7YUFDbEQsTUFBQSxTQUFTLENBQUMsT0FBTywwQ0FBRSxlQUFlLENBQUE7YUFDbEMsTUFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksMENBQUUsZUFBZSxDQUFBLENBQzFDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDTyxlQUFlLENBQ3ZCLFNBQXlCLEVBQ3pCLEtBQWE7O1FBRWIsT0FBTyxDQUNMLENBQUEsTUFBQSxNQUFBLE1BQUEsU0FBUyxDQUFDLE9BQU8sMENBQUUsS0FBSywwQ0FBRyxLQUFLLENBQUMsMENBQUUsYUFBYTthQUNoRCxNQUFBLFNBQVMsQ0FBQyxPQUFPLDBDQUFFLGFBQWEsQ0FBQTthQUNoQyxNQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSwwQ0FBRSxhQUFhLENBQUEsQ0FDeEMsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGtCQUFrQixDQUFDLElBQVksRUFBRSxLQUFhO1FBQzVDLE9BQU8sU0FBUyxJQUFJLFdBQVcsS0FBSyxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsc0JBQXNCLENBQ3BCLElBQVksRUFDWixPQUFxQixFQUNyQixRQUFnQixFQUNoQixLQUFhO1FBRWIsT0FBTztZQUNMLEtBQUssRUFBRSxJQUFJO1lBQ1gsUUFBUSxFQUFFLE9BQU87WUFDakIsTUFBTSxFQUFFLEtBQUs7WUFDYixTQUFTLEVBQUUsUUFBUTtTQUNwQixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZ0JBQWdCLENBQUMsSUFBWSxFQUFFLEtBQWE7UUFDMUMsT0FBTyxTQUFTLElBQUksU0FBUyxLQUFLLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxvQkFBb0IsQ0FDbEIsSUFBWSxFQUNaLE9BQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLEtBQWEsRUFDYixJQUFTO1FBRVQsdUNBQ0ssSUFBSSxLQUNQLEtBQUssRUFBRSxJQUFJLEVBQ1gsUUFBUSxFQUFFLE9BQU8sRUFDakIsTUFBTSxFQUFFLEtBQUssRUFDYixTQUFTLEVBQUUsUUFBUSxJQUNuQjtJQUNKLENBQUM7O2lIQXhIVSxvQkFBb0I7cUhBQXBCLG9CQUFvQixjQUZuQixNQUFNOzJGQUVQLG9CQUFvQjtrQkFIaEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIEluamVjdGFibGUsIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE91dGxldFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9jbXMtc3RydWN0dXJlL291dGxldC9vdXRsZXQuc2VydmljZSc7XG5pbXBvcnQgeyBUYWJsZUNvbmZpZyB9IGZyb20gJy4vY29uZmlnL3RhYmxlLmNvbmZpZyc7XG5pbXBvcnQge1xuICBUYWJsZURhdGFPdXRsZXRDb250ZXh0LFxuICBUYWJsZUhlYWRlck91dGxldENvbnRleHQsXG4gIFRhYmxlT3B0aW9ucyxcbiAgVGFibGVTdHJ1Y3R1cmUsXG59IGZyb20gJy4vdGFibGUubW9kZWwnO1xuXG4vKipcbiAqIFRoZSB0YWJsZSByZW5kZXJlciBzZXJ2aWNlIGFkZHMgYSBjb21wb25lbnQgZm9yIGVhY2ggdGFibGUgY2VsbHMgKHRoIGFuZCB0ZClcbiAqIGJhc2VkIG9uIGEgZmluZSBncmFpbmVkIGNvbmZpZ3VyYXRpb24uIEVhY2ggdGFibGUgdHlwZSBjYW4gY29uZmlndXJlIGJvdGggZ2xvYmFsXG4gKiBjb21wb25lbnRzIGZvciBoZWFkZXJzIGFuZCBjZWxscyBhcyB3ZWxsIGFzIGluZGl2aWR1YWwgY29tcG9uZW50cyBmb3IgZmllbGRcbiAqIHNwZWNpZmljIGNlbGxzLlxuICpcbiAqIFRoZSBjb21wb25lbnRzIGFyZSBhZGRlZCB0byB0aGUgb3V0bGV0IHNsb3RzIGZvciB0aGUgY29ycmVzcG9uZGluZyBjZWxscy4gVGhlIHRhYmxlXG4gKiBzdHJ1Y3R1cmUgYW5kIGRhdGEgaXMgYWRkZWQgdG8gdGhlIG91dGxldCBjb250ZXh0LlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVSZW5kZXJlclNlcnZpY2Uge1xuICAvLyBrZWVwIGEgbGlzdCBvZiBvdXRsZXRSZWZzIHRvIGF2b2lkIHJlY3JlYXRpb25cbiAgcHJvdGVjdGVkIG91dGxldFJlZnMgPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIG91dGxldFNlcnZpY2U6IE91dGxldFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuICAgIHByb3RlY3RlZCBjb25maWc6IFRhYmxlQ29uZmlnXG4gICkge31cblxuICAvKipcbiAgICogQWRkcyB0aGUgY29uZmlndXJlZCB0YWJsZSBjb21wb25lbnQgZm9yIHRoZSBoZWFkZXIgYW5kIGRhdGEuXG4gICAqL1xuICBhZGQoc3RydWN0dXJlOiBUYWJsZVN0cnVjdHVyZSk6IHZvaWQge1xuICAgIHN0cnVjdHVyZT8uY2VsbHM/LmZvckVhY2goKGZpZWxkKSA9PiB7XG4gICAgICBjb25zdCB0aFJlbmRlcmVyID0gdGhpcy5nZXRIZWFkZXJSZW5kZXJlcihzdHJ1Y3R1cmUsIGZpZWxkKTtcbiAgICAgIGlmICh0aFJlbmRlcmVyKSB7XG4gICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuZ2V0SGVhZGVyT3V0bGV0UmVmKHN0cnVjdHVyZS50eXBlLCBmaWVsZCk7XG4gICAgICAgIHRoaXMucmVuZGVyKHJlZiwgdGhSZW5kZXJlcik7XG4gICAgICB9XG4gICAgICBjb25zdCB0ZFJlbmRlcmVyID0gdGhpcy5nZXREYXRhUmVuZGVyZXIoc3RydWN0dXJlLCBmaWVsZCk7XG4gICAgICBpZiAodGRSZW5kZXJlcikge1xuICAgICAgICBjb25zdCByZWYgPSB0aGlzLmdldERhdGFPdXRsZXRSZWYoc3RydWN0dXJlLnR5cGUsIGZpZWxkKTtcbiAgICAgICAgdGhpcy5yZW5kZXIocmVmLCB0ZFJlbmRlcmVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZW5kZXIob3V0bGV0UmVmOiBzdHJpbmcsIHJlbmRlcmVyOiBUeXBlPGFueT4pIHtcbiAgICBpZiAodGhpcy5vdXRsZXRSZWZzLmhhcyhvdXRsZXRSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub3V0bGV0UmVmcy5zZXQob3V0bGV0UmVmLCB0cnVlKTtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9XG4gICAgICB0aGlzLmNvbXBvbmVudEZhY3RvcnlSZXNvbHZlci5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShyZW5kZXJlcik7XG4gICAgdGhpcy5vdXRsZXRTZXJ2aWNlLmFkZChvdXRsZXRSZWYsIDxhbnk+dGVtcGxhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGhlYWRlciByZW5kZXIgY29tcG9uZW50IGZvciB0aGUgZ2l2ZW4gZmllbGQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0SGVhZGVyUmVuZGVyZXIoXG4gICAgc3RydWN0dXJlOiBUYWJsZVN0cnVjdHVyZSxcbiAgICBmaWVsZDogc3RyaW5nXG4gICk6IFR5cGU8YW55PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHN0cnVjdHVyZS5vcHRpb25zPy5jZWxscz8uW2ZpZWxkXT8uaGVhZGVyQ29tcG9uZW50IHx8XG4gICAgICBzdHJ1Y3R1cmUub3B0aW9ucz8uaGVhZGVyQ29tcG9uZW50IHx8XG4gICAgICB0aGlzLmNvbmZpZy50YWJsZU9wdGlvbnM/LmhlYWRlckNvbXBvbmVudFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZGF0YSByZW5kZXIgY29tcG9uZW50IGZvciB0aGUgZ2l2ZW4gZmllbGQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0RGF0YVJlbmRlcmVyKFxuICAgIHN0cnVjdHVyZTogVGFibGVTdHJ1Y3R1cmUsXG4gICAgZmllbGQ6IHN0cmluZ1xuICApOiBUeXBlPGFueT4ge1xuICAgIHJldHVybiAoXG4gICAgICBzdHJ1Y3R1cmUub3B0aW9ucz8uY2VsbHM/LltmaWVsZF0/LmRhdGFDb21wb25lbnQgfHxcbiAgICAgIHN0cnVjdHVyZS5vcHRpb25zPy5kYXRhQ29tcG9uZW50IHx8XG4gICAgICB0aGlzLmNvbmZpZy50YWJsZU9wdGlvbnM/LmRhdGFDb21wb25lbnRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGhlYWRlciAodGgpIG91dGxldCByZWZlcmVuY2UgZm9yIHRoZSBnaXZlbiBmaWVsZC5cbiAgICpcbiAgICogVGhlIG91dGxldCByZWZlcmVuY2UgaXMgZ2VuZXJhdGVkIGFzOlxuICAgKiBgdGFibGUuW3RhYmxlVHlwZV0uaGVhZGVyLltmaWVsZF1gXG4gICAqL1xuICBnZXRIZWFkZXJPdXRsZXRSZWYodHlwZTogc3RyaW5nLCBmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYHRhYmxlLiR7dHlwZX0uaGVhZGVyLiR7ZmllbGR9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBoZWFkZXIgKHRoKSBvdXRsZXQgY29udGV4dCBmb3IgdGhlIGdpdmVuIGZpZWxkLlxuICAgKi9cbiAgZ2V0SGVhZGVyT3V0bGV0Q29udGV4dChcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogVGFibGVPcHRpb25zLFxuICAgIGkxOG5Sb290OiBzdHJpbmcsXG4gICAgZmllbGQ6IHN0cmluZ1xuICApOiBUYWJsZUhlYWRlck91dGxldENvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogdHlwZSxcbiAgICAgIF9vcHRpb25zOiBvcHRpb25zLFxuICAgICAgX2ZpZWxkOiBmaWVsZCxcbiAgICAgIF9pMThuUm9vdDogaTE4blJvb3QsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBkYXRhICh0ZCkgb3V0bGV0IHJlZmVyZW5jZSBmb3IgdGhlIGdpdmVuIGZpZWxkLlxuICAgKlxuICAgKiBUaGUgZmllbGQgaXMgZ2VuZXJhdGVkIGFzOlxuICAgKiBgdGFibGUuW3RhYmxlVHlwZV0uZGF0YS5bdGFibGVGaWVsZF1gXG4gICAqL1xuICBnZXREYXRhT3V0bGV0UmVmKHR5cGU6IHN0cmluZywgZmllbGQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGB0YWJsZS4ke3R5cGV9LmRhdGEuJHtmaWVsZH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGRhdGEgKHRkKSBvdXRsZXQgY29udGV4dCBmb3IgdGhlIGdpdmVuIGZpZWxkLlxuICAgKi9cbiAgZ2V0RGF0YU91dGxldENvbnRleHQoXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFRhYmxlT3B0aW9ucyxcbiAgICBpMThuUm9vdDogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcsXG4gICAgZGF0YTogYW55XG4gICk6IFRhYmxlRGF0YU91dGxldENvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5kYXRhLFxuICAgICAgX3R5cGU6IHR5cGUsXG4gICAgICBfb3B0aW9uczogb3B0aW9ucyxcbiAgICAgIF9maWVsZDogZmllbGQsXG4gICAgICBfaTE4blJvb3Q6IGkxOG5Sb290LFxuICAgIH07XG4gIH1cbn1cbiJdfQ==